📄 parser.c
字号:
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 + -