static int optimus_aml_sdc_burn_ini_parse_usr_cfg(const char* setName, const char* keyName, const char* usrKeyVal)
{
        int ret = 0;

        if(!strcmp(SET_BURN_PARTS, setName))
        {
                return parse_burn_parts(keyName, usrKeyVal);
        }
        if(!strcmp(SET_CUSTOM_PARA, setName))
        {
                return parse_set_custom_para(keyName, usrKeyVal);
        }
        if(!strcmp(SET_BURN_PARA_EX, setName))
        {
                return parse_set_burnEx(keyName, usrKeyVal);
        }

        return ret;
}
Esempio n. 2
0
//1, Read the whole file content to buffer
//2, parse file content to lines
//3, parse each valid line 
static int parse_ini_file(const char* filePath, u8* iniBuf, const unsigned bufSz)
{
    const int MaxLines = 1024;//
    const int MaxWordsALine = 32;

    char* lines[MaxLines];
    char* wordsALine[MaxWordsALine];
    int ret = 0;
    unsigned fileSz = 0;
    unsigned lineNum = 0; 
    int nwords = 0;
    int currentSetIndex = -1;
    int hFile = -1;
    unsigned readLen = 0;
    unsigned i = 0;
    unsigned lineIndex = 0; 

    fileSz = (unsigned)do_fat_get_fileSz(filePath);
    if(!fileSz){
        err("File %s not exist in sdcard??\n", filePath);
        return __LINE__;
    }
    if(fileSz >= bufSz){
        err("file size 0x%x illegal, buf size is 0x%x\n", fileSz, bufSz);
        return __LINE__;
    }
    DWN_MSG("ini sz 0x%xB\n", fileSz);

    hFile = do_fat_fopen(filePath);
    if(hFile < 0){
        err("Fail to open file %s\n", filePath);
        return __LINE__;
    }

    readLen = do_fat_fread(hFile, iniBuf, fileSz);
    if(readLen != fileSz){
        err("failed to load cfg file, want size 0x%x, but 0x%x\n", fileSz, readLen);
        do_fat_fclose(hFile);
        return __LINE__;
    }
    iniBuf[fileSz] = 0;

    do_fat_fclose(hFile);

    dbg("\\r is 0x%x\t, \\n is 0x%x\n", '\r', '\n');
    char* curLine = (char*)iniBuf;
    char* pTemp = curLine;

    //step1:first loop to seprate buffer to lines
    for (i = 0; i < fileSz ; i++, ++pTemp)
    {
        char c = *pTemp;
        int isFileEnd = i + 1 >= fileSz;

        if(MaxLines <= lineNum){
            err("total line number %d too many, at most %d lines!\n", lineNum, MaxLines);
            break;
        }

        if(isFileEnd)
        {
            lines[lineNum++] = curLine;
            break;//End to read file if file ended
        }

        if('\r' != c && '\n' != c) {
            continue;
        }
        *pTemp = 0;///

        dbg("%3d: %s\n", lineNum, curLine);
        if('\r' == c)//for DOS \r\n mode
        {
            if('\n' == pTemp[1])
            {
                lines[lineNum++] = curLine;

                ++pTemp;
                curLine = pTemp + 1;
                ++i;//skip '\n' which follows '\r'
            }
            else
            {
                err("Syntax error at line %d, DOS end \\r\\n, but \\r%x\n", lineNum + 1, pTemp[1]);
                return __LINE__;
            }
        }
        else if('\n' == c)//for UNIX '\n' mode
        {
            lines[lineNum++] = curLine;
            curLine = pTemp + 1;
        }
    }
    
    //step 2: abandon comment or space lines
    for (lineIndex = 0; lineIndex < lineNum ; lineIndex++)
    {
        int isSpaceLine = 1;
        char c = 0;
        curLine = lines[lineIndex];

        while(c = *curLine++, c)
        {
            //escape space and tab
            if (is_space_char(c))
            {
                continue;
            }
            
            isSpaceLine = 0;//no space line
            //test if frist char is comment delimeter
            if(';' == c)
            {
                lines[lineIndex] = NULL;//invalid comment lines
            }
        }

        //if all character is space or tab, also invlalid it 
        if (isSpaceLine)
        {
            lines[lineIndex] = NULL;
        }
    }

    dbg("\nvalid lines:\n");
    for (lineIndex = 0; lineIndex < lineNum ; lineIndex++)
    {
        int lineType = INI_LINE_TYPE_ERR;
        const char* iniKey = NULL;
        const char* iniVal = NULL;
        const char* iniSet = NULL;

        curLine = lines[lineIndex];

        if(!curLine)continue;

        if(!line_is_valid(curLine)) //only comment lines can contain non-ASCII letters
        {
            err("line %d contain invalid chars\n", lineIndex + 1);
            ret = __LINE__;
            break;
        }
        dbg("%3d: %s\n",lineIndex, curLine);

        nwords = line_2_words(curLine, wordsALine, MaxWordsALine);
        if(nwords <= 0){
            ret = __LINE__;
            break;
        }
        if(nwords > 3){
            err("line %d error: ini support at most 3 words, but %d\n", lineIndex + 1, nwords);
            ret = __LINE__;
            break;
        }

        switch (nwords)
        {
        case 3:
            {
                if (!strcmp("=", wordsALine[1]))//k/v pair
                {
                    lineType = INI_LINE_TYPE_KE_VALUE;
                    iniKey = wordsALine[0]; iniVal = wordsALine[2];
                    break;
                }
                else if(!strcmp("[" , wordsALine[0]) && !strcmp("]" , wordsALine[2]))//set line
                {
                    lineType = INI_LINE_TYPE_SET;
                    iniSet = wordsALine[1];
                    break;
                }
                else
                {
                    lineType = INI_LINE_TYPE_ERR;
                    err("Ini syntax error when parse line %d\n", lineIndex + 1);
                    ret = __LINE__; break;
                }
            }
        	break;

        case 2:
            {
                if('[' == wordsALine[0][0])//set like "[set ]" or "[ set]"
                {
                    if(!strcmp("]", wordsALine[1]))
                    {
                        lineType = INI_LINE_TYPE_SET;
                        iniSet = wordsALine[0] + 1;
                        break;
                    }
                    else if (']' == wordsALine[1][strlen(wordsALine[1]) - 1] && !strcmp("[", wordsALine[0]))
                    {
                        lineType = INI_LINE_TYPE_SET;
                        iniSet = wordsALine[1];
                        wordsALine[1][strlen(wordsALine[1]) - 1] = 0;
                        break;
                    }
                }
                else if(!strcmp("=", wordsALine[1]))//k/v pair like "key = " 
                {
                    lineType = INI_LINE_TYPE_KE_VALUE;
                    iniKey = wordsALine[0];
                    break;
                }
                else if('=' == wordsALine[1][0])//k/v pair like "key =v" or "key= v"
                {
                    lineType = INI_LINE_TYPE_KE_VALUE;
                    iniKey = wordsALine[0];
                    iniVal = wordsALine[1] + 1;
                    break;
                }
                else if ('=' == wordsALine[0][strlen(wordsALine[0]) - 1])//k/v pair like "key= v"
                {
                    wordsALine[0][strlen(wordsALine[0]) - 1] = 0;
                    lineType = INI_LINE_TYPE_KE_VALUE;
                    iniKey = wordsALine[0];
                    iniVal = wordsALine[1];
                }
            }
            break;

        case 1:
            {
                char* word = wordsALine[0];
                char firstChar = word[0];
                char lastChar  = word[strlen(word) - 1];

                if('[' == firstChar && ']' == lastChar)
                {
                    lineType = INI_LINE_TYPE_SET;
                    iniSet = word + 1;
                    word[strlen(word) - 1] = 0;
                    break;
                }
                else 
                {
                    char c = 0;

                    iniKey = word;
                    while(c = *word++, c)
                    {
                        if ('=' == c)//TODO: not assert only delimeter in a line yet
                        {
                            lineType = INI_LINE_TYPE_KE_VALUE;
                            *--word = 0;
                            iniVal = ++word;
                            iniVal = *iniVal ? iniVal : NULL;
                            break;
                        }
                    }
                }
            }
            break;

        default:
            break;
        }

        if (INI_LINE_TYPE_SET == lineType)
        {
            const char* setname = NULL;
            dbg("set line, set is %s\n", iniSet);
            
            currentSetIndex = -1;//set index to invalid

            for (i = 0; i < TOTAL_SET_NUM; i++)
            {
                setname = _iniSets[i];
                if (!strcmp(setname, iniSet))break;//set is useful for sdc burn
            }

            //set is useful
            if(i < TOTAL_SET_NUM)
            {
                if(!strcmp(setname, SET_BURN_PARTS))
                {
                    if(g_sdcBurnPara.setsBitMap.burnParts){
                        ret = __LINE__; goto _set_duplicated;
                    }
                    g_sdcBurnPara.setsBitMap.burnParts = 1;
                }

                if(!strcmp(setname, SET_BURN_PARA_EX))
                {
                    if(g_sdcBurnPara.setsBitMap.burnEx){
                        ret = __LINE__; goto _set_duplicated;
                    }
                    g_sdcBurnPara.setsBitMap.burnEx = 1;
                }

                if(!strcmp(setname, SET_CUSTOM_PARA))
                {
                    if(g_sdcBurnPara.setsBitMap.custom){
                        ret = __LINE__; goto _set_duplicated;
                    }
                    g_sdcBurnPara.setsBitMap.custom = 1;
                }

                currentSetIndex = i;//set set index to valid
            }

        }

        if(INI_LINE_TYPE_KE_VALUE == lineType)
        {
            dbg("k/v line, key (%s), val (%s)\n", iniKey, iniVal);

            if (currentSetIndex >= 0 && currentSetIndex < TOTAL_SET_NUM)//set is valid
            {
                const char* setName = _iniSets[currentSetIndex];

                if (!strcmp(setName, SET_BURN_PARTS))
                {
                    ret = parse_burn_parts(iniKey, iniVal);
                    if(ret){
                        ret = __LINE__; goto _line_err;
                    }
                }

                if (!strcmp(setName, SET_BURN_PARA_EX))
                {
                    ret = parse_set_burnEx(iniKey, iniVal);
                    if(ret){
                        ret = __LINE__; goto _line_err;
                    }
                }

                if (!strcmp(setName, SET_CUSTOM_PARA))
                {
                    ret = parse_set_custom_para(iniKey, iniVal);
                    if(ret){
                        ret = __LINE__; goto _line_err;
                    }
                }
            }
        }
    }


	return ret;

_line_err:
    err("Fail to parse line %d\n", lineIndex + 1);
    return ret;

_set_duplicated:
    err("line %d err:set is duplicated!!\n", lineIndex + 1);
    return ret;
}