2017年12月20日 星期三

狀態機方式分析INI檔案

使用狀態機方式來拆分INI檔案,取出Group、Key Name、 Key Value等值
可用於字串解析
其中,註解以;開始,CRLF結束
INI範例:
; for 16-bit app support
[fonts]

[extensions]

[mci extensions]

[files]

[MCI Extensions.BAK]
aif=MPEGVideo
aifc=MPEGVideo

[annie]
CaptureFile=
VideoDevice=0
AudioDevice=0
FrameRate=333333

[SciCalc]
layout=0
static void ini_parse (char* buffer, char comment_char, char delim_char)
{
    char* p = buffer;
    char* group_start = NULL;
    char* key_start   = NULL;
    char* value_start = NULL;

    // 解析用的狀態
    enum _State
    {
        STAT_NONE = 0,
        STAT_GROUP,
        STAT_KEY,
        STAT_VALUE,
        STAT_COMMENT
    }state = STAT_NONE;

    // 掃描整個文件內容
    for(p = buffer; *p != '/0'; p++)
    {
        switch(state)
        {
            case STAT_NONE:
            {
                if(*p == '[')
                {
                    // 進入Group狀態
                    state = STAT_GROUP;
                    group_start = p + 1;
                }
                else if(*p == comment_char)
                {
                    // 注釋字元
                    state = STAT_COMMENT;
                }
                else if(!isspace(*p))
                {
                    // 掃到Key值
                    state = STAT_KEY;
                    key_start = p;
                }
                break;
            }
            case STAT_GROUP:
            {
                // Group狀態結束
                if(*p == ']')
                {
                    *p = '/0';
                    state = STAT_NONE;
                    strtrim(group_start);
                    printf("[%s]/n", group_start);
                }
                break;
            }
            case STAT_COMMENT:
            {
                // 注釋狀態結束
                if(*p == '/n')
                {
                    state = STAT_NONE;
                    break;
                }
                break;
            }
            case STAT_KEY:
            {
                // Key名稱讀取完成,開始讀取其值
                if(*p == delim_char || (delim_char == ' ' && *p == '/t'))
                {
                    *p = '/0';
                    state = STAT_VALUE;
                    value_start = p + 1;
                }
                break;
            }
            case STAT_VALUE:
            {
                // 讀取Key值
                if(*p == '/n' || *p == '/r')
                {
                    *p = '/0';
                    state = STAT_NONE;
                    strtrim(key_start);
                    strtrim(value_start);
                    printf("%s%c%s/n", key_start, delim_char, value_start);
                }
                break;
            }
            default:break;
        }
    }

    if(state == STAT_VALUE)
    {
        strtrim(key_start);
        strtrim(value_start);
        printf("%s%c%s/n", key_start, delim_char, value_start);
    }

    return;
}
​

XC8 MCC使用注意事項

使用MCC設定Timer時,不要使用Callback function,以免轉跳後工作太多造成Uart接收逾時 使用MCC產生EE, Flash操作時,生成的Code有錯,變更NVMREG後沒切回來,會造成程式錯誤 NVMCON1bits.NVMREG = 0 ; NV...