Beispiel #1
0
static void IniTest()
{
    IniFile pNull((const char *)NULL);
    assert(pNull.sections.Count() == 0);

    IniFile pEmpty("");
    assert(pEmpty.sections.Count() == 1 && !pEmpty.sections.At(0)->name);
    assert(pEmpty.FindSection(NULL)->lines.Count() == 0);

    IniFile pNoNL1("key = value");
    assert(str::Eq(pNoNL1.sections.At(0)->lines.At(0).value, "value"));

    IniFile pNoNL2("[Section ]");
    assert(pNoNL2.FindSection("Section "));

    static const char *iniData = "\
; NULL section \n\
key1=value1\n\
[Section 1]\n\
  key2 = value2 \n\
  # comment \n\
  key3: \"quoted value\" \n\n\
[ Empty Section ]\n\n\
  ]Section 2 \n\
key without separator\n\
";
    IniLine verify[] = {
        IniLine(NULL, NULL), IniLine("key1", "value1"),
        IniLine("Section 1", NULL), IniLine("Key2", "value2"), IniLine("key3", "\"quoted value\""),
        IniLine(" Empty Section ", NULL),
        IniLine("Section 2", NULL), IniLine("key", "without separator"),
    };

    IniFile p(iniData);
    size_t idxSec = (size_t)-1, idxLine = (size_t)-1;
    for (int i = 0; i < dimof(verify); i++) {
        if (!verify[i].value) {
            if (idxSec != (size_t)-1) {
                assert(p.sections.At(idxSec)->lines.Count() == idxLine);
            }
            idxSec++;
            idxLine = 0;
            assert(p.FindSection(verify[i].key) == p.sections.At(idxSec));
            continue;
        }
        assert(idxSec < p.sections.Count() && idxLine < p.sections.At(idxSec)->lines.Count());
        IniLine *line = p.sections.At(idxSec)->FindLine(verify[i].key);
        assert(line && str::EqI(line->key, verify[i].key) && str::Eq(line->value, verify[i].value));
        idxLine++;
    }
    assert(p.sections.Count() == idxSec + 1 && p.sections.Last()->lines.Count() == idxLine);
    assert(p.FindSection("Section 1", 1) && p.FindSection("Section 2", 2));
    assert(!p.FindSection("missing") && !p.FindSection("Section 1", 2));
    assert(!p.FindSection("Section 1")->FindLine("missing"));
}
Beispiel #2
0
// process a single INI file
static int IniFProc(LPTSTR fname, INIFILE *InitData, unsigned int fIgnoreSection)
{
	LPTSTR arg;
	unsigned int line_num, SecFound = 0, CurrentSec = 0;
	int fh, nReturn = 0;
	TCHAR szBuffer[2048];
	LPTSTR errmsg;

	if ( ++nNestLevel > MAX_INI_NEST ) {
		ini_error( E_NEST, InitData, fname, 1, NULLSTR );
		nReturn = -1;
		goto IFProcExit;
	}


	// force ignore of sections that aren't ours
	fIgnoreSection |= 0x100;

	// open the INI file
	if ((fh = _sopen(fname, (O_RDONLY | O_BINARY), SH_DENYWR)) < 0) {
		nReturn = -1;
		goto IFProcExit;
	}

	// loop to process each line
	for ( line_num = 1; ( getline( fh, szBuffer, 2047, 0 ) > 0 ); line_num++ ) {

		// skip line if empty or all comment
		arg = skipspace( szBuffer );
		if ((*arg == _TEXT('\0')) || (*arg == _TEXT(';')))
			continue;

		// query if it was requested
		if ( InitData->INIQuery != 0 ) {

			WriteTTY(szBuffer);
			WriteTTY(INI_QUERY);
query_prompt:
			switch (GetKeystroke(EDIT_BIOS_KEY | EDIT_ECHO | EDIT_ECHO_CRLF | EDIT_UC_SHIFT)) {
			case YES_CHAR:
				break;
			case NO_CHAR:
				continue;
			case INI_QUIT_CHAR:
				goto ini_done;
			case REST_CHAR:
				InitData->INIQuery = 0;
				break;
			case INI_EDIT_CHAR:
				egets( szBuffer, 2047, EDIT_BIOS_KEY | EDIT_ECHO );
				break;
			default:
				qputc( STDOUT, BS );
				honk();
				goto query_prompt;
			}

		}

		// process the line, holler if any error
		if ((nReturn = IniLine(szBuffer, InitData, (fIgnoreSection & CurrentSec), 0, &errmsg)) > 0)
			ini_error( errmsg, InitData, fname, line_num , szBuffer );

		// if no error, see if we have an included file to process
		else if (nReturn == -1) {

			// call ourselves recursively to process the included file
			if ( is_file( szBuffer ))
				(void)IniFProc( szBuffer, InitData, fIgnoreSection);
			else
				ini_error( E_INCL, InitData, fname, line_num, szBuffer );

		// if no error, see if we found a section name
		} else if (nReturn < 0) {

			CurrentSec = -nReturn;

			// save section bit if section is one of ours
			if (CurrentSec & 0xFF)
				SecFound |= CurrentSec;
		}
	}


ini_done:

	InitData->SecFlag = SecFound;    // save sections found
	_close(fh);

	nReturn = 0;

IFProcExit:
	--nNestLevel;
	return nReturn;
}