⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
    UINT err_line;
    HINF hinf;
    DWORD err;
    LONG ret;

    for (i = 0; i < sizeof(section_names)/sizeof(section_names[0]); i++)
    {
        SetLastError( 0xdeadbeef );
        hinf = test_file_contents( section_names[i].data, &err_line );
        ok( hinf != INVALID_HANDLE_VALUE, "line %u: open failed err %lx\n", i, GetLastError() );
        if (hinf == INVALID_HANDLE_VALUE) continue;

        ret = SetupGetLineCountA( hinf, section_names[i].section );
        err = GetLastError();
        trace( "hinf=%p ret=%ld err=%lx\n", hinf, ret, err );
        if (ret != -1)
        {
            ok( !section_names[i].error, "line %u: section name %s found\n",
                i, section_names[i].section );
            ok( !err, "line %u: bad error code %lx\n", i, err );
        }
        else
        {
            ok( section_names[i].error, "line %u: section name %s not found\n",
                i, section_names[i].section );
            ok( err == section_names[i].error, "line %u: bad error %lx/%lx\n",
                i, err, section_names[i].error );
        }
        SetupCloseInfFile( hinf );
    }
}


/* Test various key and value names */

static const struct
{
    const char *data;
    const char *key;
    const char *fields[10];
} key_names[] =
{
/* file contents          expected key       expected fields */
 { "ab=cd",                "ab",            { "cd" } },
 { "ab=cd,ef,gh,ij",       "ab",            { "cd", "ef", "gh", "ij" } },
 { "ab",                   "ab",            { "ab" } },
 { "ab,cd",                NULL,            { "ab", "cd" } },
 { "ab,cd=ef",             NULL,            { "ab", "cd=ef" } },
 { "=abcd,ef",             "",              { "abcd", "ef" } },
 /* backslashes */
 { "ba\\\ncd=ef",          "bacd",          { "ef" } },
 { "ab  \\  \ncd=ef",      "abcd",          { "ef" } },
 { "ab\\\ncd,ef",          NULL,            { "abcd", "ef" } },
 { "ab  \\ ;cc\ncd=ef",    "abcd",          { "ef" } },
 { "ab \\ \\ \ncd=ef",     "abcd",          { "ef" } },
 { "ba \\ dc=xx",          "ba \\ dc",      { "xx" } },
 { "ba \\\\ \nc=d",        "bac",           { "d" } },
 { "a=b\\\\c",             "a",             { "b\\\\c" } },
 { "ab=cd \\ ",            "ab",            { "cd" } },
 { "ba=c \\ \n \\ \n a",   "ba",            { "ca" } },
 { "ba=c \\ \n \\ a",      "ba",            { "c\\ a" } },
 { "  \\ a= \\ b",         "\\ a",          { "\\ b" } },
 /* quotes */
 { "Ab\"Cd\"=Ef",          "AbCd",          { "Ef" } },
 { "Ab\"Cd=Ef\"",          "AbCd=Ef",       { "AbCd=Ef" } },
 { "ab\"\"\"cd,ef=gh\"",   "ab\"cd,ef=gh",  { "ab\"cd,ef=gh" } },
 { "ab\"\"cd=ef",          "abcd",          { "ef" } },
 { "ab\"\"cd=ef,gh",       "abcd",          { "ef", "gh" } },
 { "ab=cd\"\"ef",          "ab",            { "cdef" } },
 { "ab=cd\",\"ef",         "ab",            { "cd,ef" } },
 { "ab=cd\",ef",           "ab",            { "cd,ef" } },
 { "ab=cd\",ef\\\nab",     "ab",            { "cd,ef\\" } },
 /* spaces */
 { " a b = c , d \n",      "a b",           { "c", "d" } },
 { " a b = c ,\" d\" \n",  "a b",           { "c", " d" } },
 { " a b\r = c\r\n",       "a b",           { "c" } },
 /* empty fields */
 { "a=b,,,c,,,d",          "a",             { "b", "", "", "c", "", "", "d" } },
 { "a=b,\"\",c,\" \",d",   "a",             { "b", "", "c", " ", "d" } },
 { "=,,b",                 "",              { "", "", "b" } },
 { ",=,,b",                NULL,            { "", "=", "", "b" } },
 { "a=\n",                 "a",             { "" } },
 { "=",                    "",              { "" } },
 /* eof */
 { "ab=c\032d",            "ab",            { "c" } },
 { "ab\032=cd",            "ab",            { "ab" } },
 /* nulls */
 { "abcd=ef\x0gh",         "abcd",          { "ef" } },
 /* multiple sections with same name */
 { "[Test2]\nab\n[Test]\nee=ff\n",  "ee",    { "ff" } },
 /* string substitution */
 { "%foo%=%bar%\n" STR_SECTION,     "aaa",   { "bbb" } },
 { "%foo%xx=%bar%yy\n" STR_SECTION, "aaaxx", { "bbbyy" } },
 { "%% %foo%=%bar%\n" STR_SECTION,  "% aaa", { "bbb" } },
 { "%f\"o\"o%=ccc\n" STR_SECTION,   "aaa",   { "ccc" } },
 { "abc=%bar;bla%\n" STR_SECTION,   "abc",   { "%bar" } },
 { "loop=%loop%\n" STR_SECTION,     "loop",  { "%loop2%" } },
 { "%per%%cent%=100\n" STR_SECTION, "12",    { "100" } },
 { "a=%big%\n" STR_SECTION,         "a",     { A400 } },
 { "a=%verybig%\n" STR_SECTION,     "a",     { A511 } },  /* truncated to 511 */
 { "a=%big%%big%%big%%big%\n" STR_SECTION,   "a", { A400 A400 A400 A400 } },
 { "a=%big%%big%%big%%big%%big%%big%%big%%big%%big%\n" STR_SECTION,   "a", { A400 A400 A400 A400 A400 A400 A400 A400 A400 } },
 { "a=%big%%big%%big%%big%%big%%big%%big%%big%%big%%big%%big%\n" STR_SECTION,   "a", { A4097 /*MAX_INF_STRING_LENGTH+1*/ } },
};

/* check the key of a certain line */
static const char *check_key( INFCONTEXT *context, const char *wanted )
{
    const char *key = get_string_field( context, 0 );
    DWORD err = GetLastError();

    if (!key)
    {
        ok( !wanted, "missing key %s\n", wanted );
        ok( err == 0 || err == ERROR_INVALID_PARAMETER, "last error set to %lx\n", err );
    }
    else
    {
        ok( !strcmp( key, wanted ), "bad key %s/%s\n", key, wanted );
        ok( err == 0, "last error set to %lx\n", err );
    }
    return key;
}

static void test_key_names(void)
{
    char buffer[MAX_INF_STRING_LENGTH+32];
    const char *key, *line;
    unsigned int i, index, count;
    UINT err_line;
    HINF hinf;
    DWORD err;
    BOOL ret;
    INFCONTEXT context;

    for (i = 0; i < sizeof(key_names)/sizeof(key_names[0]); i++)
    {
        strcpy( buffer, STD_HEADER "[Test]\n" );
        strcat( buffer, key_names[i].data );
        SetLastError( 0xdeadbeef );
        hinf = test_file_contents( buffer, &err_line );
        ok( hinf != INVALID_HANDLE_VALUE, "line %u: open failed err %lx\n", i, GetLastError() );
        if (hinf == INVALID_HANDLE_VALUE) continue;

        ret = SetupFindFirstLineA( hinf, "Test", 0, &context );
        assert( ret );

        key = check_key( &context, key_names[i].key );

        buffer[0] = buffer[1] = 0;  /* build the full line */
        for (index = 0; ; index++)
        {
            const char *field = get_string_field( &context, index + 1 );
            err = GetLastError();
            if (field)
            {
                ok( err == 0, "line %u: bad error %lx\n", i, GetLastError() );
                if (key_names[i].fields[index])
                    ok( !strcmp( field, key_names[i].fields[index] ), "line %u: bad field %s/%s\n",
                        i, field, key_names[i].fields[index] );
                else
                    ok( 0, "line %u: got extra field %s\n", i, field );
                strcat( buffer, "," );
                strcat( buffer, field );
            }
            else
            {
                ok( err == 0 || err == ERROR_INVALID_PARAMETER,
                    "line %u: bad error %lx\n", i, GetLastError() );
                if (key_names[i].fields[index])
                    ok( 0, "line %u: missing field %s\n", i, key_names[i].fields[index] );
            }
            if (!key_names[i].fields[index]) break;
        }
        count = SetupGetFieldCount( &context );
        ok( count == index, "line %u: bad count %d/%d\n", i, index, count );

        line = get_line_text( &context );
        ok( line != NULL, "line %u: SetupGetLineText failed\n", i );
        if (line) ok( !strcmp( line, buffer+1 ), "line %u: bad text %s/%s\n", i, line, buffer+1 );

        SetupCloseInfFile( hinf );
    }

}

static void test_SetupCloseInfFile(void)
{
    /* try to close with invalid handles */
    SetupCloseInfFile( NULL );
    SetupCloseInfFile( INVALID_HANDLE_VALUE );
}

START_TEST(parser)
{
    test_invalid_files();
    test_section_names();
    test_key_names();
    test_SetupCloseInfFile();
    DeleteFileA( tmpfile );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -