diff --git a/configmodel.c b/configmodel.c index bc36223..87bfeb5 100644 --- a/configmodel.c +++ b/configmodel.c @@ -12,38 +12,10 @@ #define ZERO ((BPTR)0) -cregex_program_t* InitialisePattern(CONST_STRPTR pattern); -Array RunPattern(CONST_STRPTR text, cregex_program_t* patternProgram); - - -SECTIONPTR LineGetSection(LINEPTR abstractLine); -VARIABLEPTR LineGetVariable(LINEPTR abstractLine); -VOID LineDump(LINEPTR abstractLine); - -SECTIONPTR SectionCreateWithName(CONST_STRPTR primary); -SECTIONPTR SectionCreateWithNameAndSubname(CONST_STRPTR primary, CONST_STRPTR secondary); -VOID SectionFree(SECTIONPTR abstractSection); - -VARIABLEPTR VariableCreate(CONST_STRPTR key, CONST_STRPTR rawValue); -VOID VariableFree(VARIABLEPTR abstractVariable); - - -#define WHITESPACE "[ \\t\\n\\r\\f\\v]" -#define RX_BLANK_LINE "^[ \t\n\r\f\v]*($|#|;)" - -#define RX_SECTION_LINE "^[ \t\n\r\f\v]*\\[([a-z0-9]+)([ \t\n\r\f\v]*\"(.+)\")*\\][ \t\n\r\f\v]*($|#|;)" -#define RX_VARIABLE_LINE "^[ \t\n\r\f\v]*([a-z][a-z0-9]+)[ \t\n\r\f\v]*=[ \t\n\r\f\v]*(.+)[ \t\n\r\f\v]*($|#|;)" -#define RX_INTEGER "^-?[1-9][0-9]*$" - -STATIC cregex_program_t* sectionPatternProgram = NULL; -STATIC cregex_program_t* variablePatternProgram = NULL; -STATIC cregex_program_t* blankPatternProgram = NULL; -STATIC cregex_program_t* integerPatternProgram = NULL; - +// - STRUCTS ----------------------------------------------------------------------------- struct ConfigFile { CONST_STRPTR filename; - LineArray lines; SECTIONSTOREPTR sectionStore; }; @@ -80,16 +52,15 @@ struct Line struct Section* section; }; +// --------------------------------------------------------------------------------------- +// - CONFIG FILE ------------------------------------------------------------------------- +// --------------------------------------------------------------------------------------- VOID ConfigFileFree(CONFIGFILEPTR abstractConfigFile) { struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile; if( configFile != NULL ) { - if( configFile->lines != NULL ) - { - LineArrayFree(configFile->lines, TRUE); //also frees lines - } if( configFile->sectionStore != NULL ) { SectionStoreFree(configFile->sectionStore); @@ -98,6 +69,8 @@ VOID ConfigFileFree(CONFIGFILEPTR abstractConfigFile) } } +STATIC LINEPTR configFileReadLine(BPTR file); + CONFIGFILEPTR ConfigFileRead(CONST_STRPTR filename) { struct ConfigFile* result = AllocVec(sizeof(struct ConfigFile), MEMF_CLEAR); @@ -105,162 +78,193 @@ CONFIGFILEPTR ConfigFileRead(CONST_STRPTR filename) if( configFile != ZERO ) { LINEPTR line = NULL; - SECTIONPTR currentSection = NULL;//SectionCreateWithName(""); // initial empty section result->sectionStore = SectionStoreNew(); - result->lines = LineArrayNew(); - InitialisePatterns(); - while( (line = LineReadIncludingContinuation(configFile, result->sectionStore, currentSection)) != NULL ) + while( (line = configFileReadLine(configFile)) != NULL ) { - // add it to the flat list of lines - LineArrayAppend(result->lines, line); - LineDump(line); - - if( LineGetSection(line) != NULL ) - { - currentSection = LineGetSection(line); - } + SectionStoreAddLine(result->sectionStore, line); + //LineDump(line); } - ReleasePatterns(); Close(configFile); } return result; } -VOID ConfigFileSave(CONFIGFILEPTR config) +VOID SectionDump(SECTIONPTR abstractSection) { + struct Section* section = (struct Section*)abstractSection; + if( section != NULL && section->lines != NULL ) + { + ArrayForEach(LINEPTR, aLine, section->lines, LineDump(aLine);); + } } -LINEPTR LineCreate(CONST_STRPTR buffer, ULONG size, SECTIONSTOREPTR sectionStore) +VOID ConfigFileDump(CONFIGFILEPTR abstractConfigFile) { + ULONG index = 0; + ULONG count = 0; + struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile; + if( configFile != NULL ) + { + count = SectionStoreSectionCount(configFile->sectionStore); + for( index = 0; index < count; index++ ) + { + SECTIONPTR section = SectionStoreSectionAt(configFile->sectionStore, index); + SectionDump(section); + } + } +} + +STATIC LINEPTR configFileReadLine(BPTR file) +{ + UBYTE* buffer = AllocVec(512, MEMF_CLEAR); + ULONG bufLength = 512; + ULONG bytesReadTotal = 0; + UBYTE* read = NULL; struct Line* result = NULL; - StringArray matches = NULL; + + // read the whole line including continuation + do + { + read = FGets(file, &(buffer[bytesReadTotal]), bufLength-bytesReadTotal); + bytesReadTotal = strlen(buffer); + } + while( read != NULL && bytesReadTotal >= 2 && bytesReadTotal < bufLength && buffer[bytesReadTotal-1] == '\n' && buffer[bytesReadTotal-2] == '\\' ); + // make a line + if( bytesReadTotal > 0 ) + { + result = LineNew(buffer, bytesReadTotal); + } + + FreeVec(buffer); + return result; +} + +// --------------------------------------------------------------------------------------- +// - LINE -------------------------------------------------------------------------------- +// --------------------------------------------------------------------------------------- + +LINEPTR LineNew(CONST_STRPTR buffer, ULONG size) +{ + struct Line* result = NULL; if( size > 0 ) { result = AllocVec(sizeof(struct Line), MEMF_CLEAR); result->rawText = AllocVec(size, MEMF_CLEAR); CopyMem(buffer, result->rawText, size-1); // drop the \\n - - if( matches = RunPattern(result->rawText, sectionPatternProgram) ) - { - SECTIONPTR section = NULL; - if( SizeOfArray(matches) == 3 ) - { - section = SectionCreateWithName(StringArrayValues(matches)[1]); - } - else if( SizeOfArray(matches) == 5 ) - { - section = SectionCreateWithNameAndSubname(StringArrayValues(matches)[1], StringArrayValues(matches)[3]); - } - if( section != NULL ) - { - SectionStoreAddSection(sectionStore, section); - result->section = section; - } - StringArrayFree(matches); - } - else - { - - if( matches = RunPattern(result->rawText, variablePatternProgram) ) - { - result->variable = VariableCreate(StringArrayValues(matches)[1], StringArrayValues(matches)[2]); - StringArrayFree(matches); - } - else - { - if( matches = RunPattern(result->rawText, blankPatternProgram) ) - { - StringArrayFree(matches); - } - else - { - Printf("\nDIDNT MATCH ANYTHING %s\n", result->rawText); - } - } - } - } return result; } +STATIC VOID lineDumpRecreate(LINEPTR abstractLine); + VOID LineDump(LINEPTR abstractLine) { struct Line* line = (struct Line*)abstractLine; if( line != NULL ) { - Printf("> %s\n", line->rawText); + if( line->rawText != NULL ) + { + Printf("%s\n", line->rawText); + } + else + { + lineDumpRecreate(line); + } + } +} + +STATIC VOID lineDumpRecreate(LINEPTR abstractLine) +{ + struct Line* line = (struct Line*)abstractLine; + if( line != NULL ) + { + if( line->variable == NULL && line->section == NULL ) { - Printf("(blank)\n"); + // blank + Printf("# blank line\n"); } else if( line->variable == NULL && line->section != NULL ) { + // section struct Section* section = (struct Section*)LineGetSection(abstractLine); - CONST_STRPTR canonical = NULL; - Printf("(new section %s", section->primary); - if( section->secondary ) + if( section != NULL && section->primary != NULL ) { - Printf("[%s]", section->secondary); + if( strlen(section->primary) > 0 ) + { + Printf("[%s", section->primary); + if( section->secondary != NULL ) + { + Printf(" \"%s\"", section->secondary); + } + Printf("]\n"); + } } - Printf(")\n"); - canonical = SectionCanonicalName(section); - Printf("...((%s))...\n", canonical); - FreeVec((STRPTR)canonical); } else { - struct Section* section = (struct Section*)LineGetSection(abstractLine); struct Variable* var = (struct Variable*)LineGetVariable(abstractLine); - Printf("(variable in section %s", section->primary); - if( section->secondary ) - { - Printf("[%s]\n", section->secondary); - } - Printf(") %s = %s\n", var->key, var->value.stringValue); + Printf("%s = %s\n", var->key, var->value.stringValue); } } } -LINEPTR LineReadIncludingContinuation(BPTR file, SECTIONSTOREPTR sectionStore, SECTIONPTR currentSection) +VOID LineSetSection(LINEPTR abstractLine, SECTIONPTR abstractSection) { - UBYTE* buffer = AllocVec(512, MEMF_CLEAR); - ULONG bufLength = 512; - ULONG bytesReadTotal = 0; - UBYTE* read = NULL; - struct Line* result = NULL; + struct Line* line = (struct Line*)abstractLine; + if( line != NULL ) + { + // we dont own the section + line->section = abstractSection; + } +} - // read the whole line including continuation - do +SECTIONPTR LineGetSection(LINEPTR abstractLine) +{ + struct Line* line = (struct Line*)abstractLine; + if( line != NULL ) { - read = FGets(file, &(buffer[bytesReadTotal]), bufLength-bytesReadTotal); - bytesReadTotal = strlen(buffer); - } - while( read != NULL && bytesReadTotal >= 2 && bytesReadTotal < bufLength && buffer[bytesReadTotal-1] == '\n' && buffer[bytesReadTotal-2] == '\\' ); - - // make a line - if( bytesReadTotal > 0 ) + return line->section; + } + return NULL; +} + +// first time through we need to preserve rawText +VOID LineSetInitialVariable(LINEPTR abstractLine, VARIABLEPTR abstractVariable) +{ + struct Line* line = (struct Line*)abstractLine; + if( line != NULL ) { - result = LineCreate(buffer, bytesReadTotal, sectionStore); - if( result->variable != NULL && result->section == NULL ) + // we take ownership of the variable + if( line->variable != NULL ) { - result->section = currentSection; + VariableFree(line->variable); } + line->variable = abstractVariable; } - - FreeVec(buffer); - return result; } -SECTIONPTR LineGetSection(LINEPTR abstractLine) +// any further change to the variable means we wipe the raw text +VOID LineSetVariable(LINEPTR abstractLine, VARIABLEPTR abstractVariable) { struct Line* line = (struct Line*)abstractLine; if( line != NULL ) { - return line->section; + if( line->rawText != NULL ) + { + // if we change the variable we remove any original text + FreeVec(line->rawText); + line->rawText = NULL; + } + // we take ownership of the variable + if( line->variable != NULL ) + { + VariableFree(line->variable); + } + line->variable = abstractVariable; } - return NULL; } VARIABLEPTR LineGetVariable(LINEPTR abstractLine) @@ -304,6 +308,9 @@ CONST_STRPTR LineGetRawText(LINEPTR abstractLine) } } +// --------------------------------------------------------------------------------------- +// - SECTION ----------------------------------------------------------------------------- +// --------------------------------------------------------------------------------------- SECTIONPTR SectionCreateWithName(CONST_STRPTR primary) { @@ -334,6 +341,22 @@ SECTIONPTR SectionCreateWithNameAndSubname(CONST_STRPTR primary, CONST_STRPTR se return result; } +VOID SectionAddSectionLine(SECTIONPTR abstractSection, LINEPTR abstractLine) +{ + // sets self onto line and then adds line to the collection + LineSetSection(abstractLine, abstractSection); + SectionAddLine(abstractSection, abstractLine); +} + +VOID SectionAddLine(SECTIONPTR abstractSection, LINEPTR abstractLine) +{ + struct Section* section = (struct Section*)abstractSection; + if( section != NULL ) + { + LineArrayAppend(section->lines, abstractLine); + } +} + VOID SectionFree(SECTIONPTR abstractSection) { struct Section* section = (struct Section*)abstractSection; @@ -349,7 +372,7 @@ VOID SectionFree(SECTIONPTR abstractSection) } if( section->lines != NULL ) { - LineArrayFree(section->lines, FALSE); // dont free the lines they are only weak + LineArrayFree(section->lines, TRUE); // free the lines when we free the section } FreeVec(section); } @@ -379,6 +402,9 @@ CONST_STRPTR SectionCanonicalName(SECTIONPTR abstractSection) return result; } +// --------------------------------------------------------------------------------------- +// - VARIABLE ---------------------------------------------------------------------------- +// --------------------------------------------------------------------------------------- VARIABLEPTR VariableCreate(CONST_STRPTR key, CONST_STRPTR rawValue) { @@ -418,93 +444,3 @@ VOID VariableFree(VARIABLEPTR abstractVariable) } } - - - - - - - -// ---------------------------------------------------- -// ---------------------------------------------------- -// ---------------------------------------------------- -// ---------------------------------------------------- -// ---------------------------------------------------- -VOID InitialisePatterns(VOID) -{ - sectionPatternProgram = InitialisePattern(RX_SECTION_LINE); - variablePatternProgram = InitialisePattern(RX_VARIABLE_LINE); - blankPatternProgram = InitialisePattern(RX_BLANK_LINE); - integerPatternProgram = InitialisePattern(RX_INTEGER); -} - -VOID ReleasePatterns(VOID) -{ - if( sectionPatternProgram != NULL ) cregex_compile_free( sectionPatternProgram ); - if( variablePatternProgram != NULL ) cregex_compile_free( variablePatternProgram ); - if( blankPatternProgram != NULL ) cregex_compile_free( blankPatternProgram ); - if( integerPatternProgram != NULL ) cregex_compile_free( integerPatternProgram ); -} - -cregex_program_t* InitialisePattern(CONST_STRPTR pattern) -{ - cregex_program_t* result = NULL; - cregex_node_t* patternNode = cregex_parse(pattern); - if( patternNode ) - { - result = cregex_compile_node( patternNode ); - if( result != NULL ) - { - //Printf("successfully compiled %s\n", pattern); - } - else - { - Printf("failed to compile %s\n", pattern); - } - cregex_parse_free( patternNode ); - } - else - { - Printf("could not parse %s\n", pattern); - } - return result; -} - -Array RunPattern(CONST_STRPTR text, cregex_program_t* patternProgram) -{ - Array result = NULL; - char* localMatches[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - if (cregex_program_run(patternProgram, text, localMatches, 20) > 0) { - int j = 0; - int nmatches = 0; - - // count the matches - for (j = 0; j < 20; ++j) - if (localMatches[j]) - nmatches = j; - - if( nmatches > 0 ) - { - result = StringArrayNew(); - // loop the matches - for (j = 0; j <= nmatches; j += 2) { - if (localMatches[j] && localMatches[j + 1]) { - int len = (int)(localMatches[j + 1] - localMatches[j]); - STRPTR buffer = AllocVec(len+1, MEMF_CLEAR); // freed in the array - sprintf(buffer, "%.*s", len, localMatches[j]); - if( buffer[len-1] == '\n' ) - { - buffer[len-1] = '\0'; - } - StringArrayAppend(result, buffer); - } else { - //Printf("(NULL,NULL)\n"); - } - } - } - // end - } else { - //Printf("\"%s\": no match\n", text); - } - return result; -} diff --git a/configmodel.h b/configmodel.h index 92e2127..27430bb 100644 --- a/configmodel.h +++ b/configmodel.h @@ -4,23 +4,32 @@ #include CONFIGFILEPTR ConfigFileRead(CONST_STRPTR filename); -VOID ConfigFileFree(CONFIGFILEPTR abstractConfigFile); +VOID ConfigFileFree(CONFIGFILEPTR configFile); +VOID ConfigFileDump(CONFIGFILEPTR configFile); -VOID ConfigFileSave(CONFIGFILEPTR config); -VOID InitialisePatterns(VOID); -VOID ReleasePatterns(VOID); - -LINEPTR LineReadIncludingContinuation(BPTR file, SECTIONPTR currentSection, SECTIONSTOREPTR sectionStore); +LINEPTR LineNew(CONST_STRPTR buffer, ULONG size); VOID LineFree(LINEPTR abstractLine); + CONST_STRPTR LineGetRawText(LINEPTR line); +VOID LineSetSection(LINEPTR line, SECTIONPTR section); +SECTIONPTR LineGetSection(LINEPTR line); +VARIABLEPTR LineGetVariable(LINEPTR line); +VOID LineSetInitialVariable(LINEPTR line, VARIABLEPTR variable); +VOID LineSetVariable(LINEPTR line, VARIABLEPTR variable); + +VOID LineDump(LINEPTR abstractLine); + SECTIONPTR SectionCreateWithName(CONST_STRPTR primary); SECTIONPTR SectionCreateWithNameAndSubname(CONST_STRPTR primary, CONST_STRPTR secondary); VOID SectionFree(SECTIONPTR section); +VOID SectionAddSectionLine(SECTIONPTR section, LINEPTR line); +VOID SectionAddLine(SECTIONPTR section, LINEPTR line); CONST_STRPTR SectionCanonicalName(SECTIONPTR section); +VOID SectionDump(SECTIONPTR section); VARIABLEPTR VariableCreate(CONST_STRPTR key, CONST_STRPTR rawValue); -VOID VariableFree(VARIABLEPTR abstractVariable); +VOID VariableFree(VARIABLEPTR variable); #endif \ No newline at end of file diff --git a/containers/linearray.h b/containers/linearray.h index 5e5d59b..04557ac 100644 --- a/containers/linearray.h +++ b/containers/linearray.h @@ -6,8 +6,6 @@ #include #include "configmodel.h" -#define LineArray Array - LineArray LineArrayNew(VOID); VOID LineArrayAppend(LineArray array, LINEPTR value); VOID LineArrayFree(LineArray array, BOOL freeLines); diff --git a/containers/linemap.c b/containers/linemap.c deleted file mode 100644 index 21d08ca..0000000 --- a/containers/linemap.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "linemap.h" -#include "linearray.h" - -LineMap LineMapNew() -{ - LineMap result = NewMap(CNTKIT_KEY_STRING, - CNTKIT_CAPACITY, 8, - CNTKIT_VALUESIZE, 4, - TAG_DONE); - - return result; -} - -VOID LineMapFree(LineMap map) -{ - // doesnt seem to delete contents - DeleteMap(map); -} diff --git a/containers/linemap.h b/containers/linemap.h deleted file mode 100644 index df4bdf2..0000000 --- a/containers/linemap.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __LINEMAP_H -#define __LINEMAP_H - -#include -#include -#include "configmodel.h" - -#define LineMap Map - -LineMap LineMapNew(VOID); -VOID LineMapFree(LineMap map); - -#endif \ No newline at end of file diff --git a/containers/sectionarray.h b/containers/sectionarray.h index b07981c..da24872 100644 --- a/containers/sectionarray.h +++ b/containers/sectionarray.h @@ -4,7 +4,6 @@ #include #include #include "configmodel.h" -#define SectionArray Array SectionArray SectionArrayNew(VOID); VOID SectionArrayAppend(SectionArray array, SECTIONPTR value); diff --git a/containers/sectionmap.h b/containers/sectionmap.h index f3035bc..e058a96 100644 --- a/containers/sectionmap.h +++ b/containers/sectionmap.h @@ -5,8 +5,6 @@ #include #include "configmodel.h" -#define SectionMap Map // a map of string (canonical name) to Section - SectionMap SectionMapNew(VOID); VOID SectionMapSet(SectionMap map, CONST_STRPTR canonicalName, SECTIONPTR section); SECTIONPTR SectionMapGet(SectionMap map, CONST_STRPTR canonicalName); diff --git a/containers/stringarray.c b/containers/stringarray.c index 000b5d2..e2303ee 100644 --- a/containers/stringarray.c +++ b/containers/stringarray.c @@ -1,27 +1,28 @@ #include "stringarray.h" -#include "configmodel.h" + +#include #include #include -Array StringArrayNew(VOID) +StringArray StringArrayNew(VOID) { #define SIZE_STRPTR 2 return NewArray(SIZE_STRPTR); } -VOID StringArrayAppend(Array array, CONST_STRPTR value) +VOID StringArrayAppend(StringArray array, CONST_STRPTR value) { AppendToArray(CONST_STRPTR, array, value); } -VOID StringArrayAppendAndRetain(Array array, CONST_STRPTR value) +VOID StringArrayAppendAndRetain(StringArray array, CONST_STRPTR value) { STRPTR localCopy = AllocVec(strlen(value)+1, MEMF_CLEAR); CopyMem(value, localCopy, strlen(value)); StringArrayAppend(array, localCopy); } -VOID StringArrayFree(Array array) +VOID StringArrayFree(StringArray array) { if( array != NULL ) { @@ -30,7 +31,7 @@ VOID StringArrayFree(Array array) } } -CONST_STRPTR* StringArrayValues(Array array) +CONST_STRPTR* StringArrayValues(StringArray array) { return ArrayValues(CONST_STRPTR, array); } \ No newline at end of file diff --git a/containers/stringarray.h b/containers/stringarray.h index b60726e..49ff93c 100644 --- a/containers/stringarray.h +++ b/containers/stringarray.h @@ -1,10 +1,7 @@ #ifndef __STRINGARRAY_H #define __STRINGARRAY_H -#include -#include - -#define StringArray Array +#include "types.h" StringArray StringArrayNew(VOID); VOID StringArrayAppend(StringArray array, CONST_STRPTR value); diff --git a/cregex/pattern.c b/cregex/pattern.c new file mode 100644 index 0000000..0df35aa --- /dev/null +++ b/cregex/pattern.c @@ -0,0 +1,74 @@ +#include "pattern.h" +#include "cregex.h" +#include "containers/stringarray.h" +#include +#include + + +PATTERNPTR PatternNew(CONST_STRPTR pattern) +{ + cregex_program_t* result = NULL; + cregex_node_t* patternNode = cregex_parse(pattern); + if( patternNode ) + { + result = cregex_compile_node( patternNode ); + if( result != NULL ) + { + //Printf("successfully compiled %s\n", pattern); + } + else + { +// Printf("failed to compile %s\n", pattern); + } + cregex_parse_free( patternNode ); + } + else + { +// Printf("could not parse %s\n", pattern); + } + return result; +} + +VOID PatternFree(cregex_program_t* pattern) +{ + cregex_compile_free( pattern ); +} + +StringArray PatternRun(CONST_STRPTR text, cregex_program_t* patternProgram) +{ + StringArray result = NULL; + char* localMatches[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + if (cregex_program_run(patternProgram, text, localMatches, 20) > 0) { + int j = 0; + int nmatches = 0; + + // count the matches + for (j = 0; j < 20; ++j) + if (localMatches[j]) + nmatches = j; + + if( nmatches > 0 ) + { + result = StringArrayNew(); + // loop the matches + for (j = 0; j <= nmatches; j += 2) { + if (localMatches[j] && localMatches[j + 1]) { + int len = (int)(localMatches[j + 1] - localMatches[j]); + STRPTR buffer = AllocVec(len+1, MEMF_CLEAR); // freed in the array + sprintf(buffer, "%.*s", len, localMatches[j]); + if( buffer[len-1] == '\n' ) + { + buffer[len-1] = '\0'; + } + StringArrayAppend(result, buffer); + } else { + //Printf("(NULL,NULL)\n"); + } + } + } + // end + } else { + //Printf("\"%s\": no match\n", text); + } + return result; +} diff --git a/cregex/pattern.h b/cregex/pattern.h new file mode 100644 index 0000000..2690ace --- /dev/null +++ b/cregex/pattern.h @@ -0,0 +1,10 @@ +#ifndef __CONFIGREGEX_H +#define __CONFIGREGEX_H + +#include "types.h" + +PATTERNPTR PatternNew(CONST_STRPTR pattern); +VOID PatternFree(PATTERNPTR pattern); +StringArray PatternRun(CONST_STRPTR text, PATTERNPTR patternProgram); + +#endif \ No newline at end of file diff --git a/main.c b/main.c index c4ee1a9..d53f417 100644 --- a/main.c +++ b/main.c @@ -24,6 +24,9 @@ WORD DoTheWork(STRPTR filename) CONFIGFILEPTR config = ConfigFileRead(filename); if( config != NULL ) { + Printf("XXXXXXX\n"); + ConfigFileDump(config); + Printf("XXXXXXX\n"); ConfigFileFree(config); } else diff --git a/sectionstore.c b/sectionstore.c index b7c983a..dfa9a38 100644 --- a/sectionstore.c +++ b/sectionstore.c @@ -1,13 +1,35 @@ #include "sectionstore.h" #include "containers/sectionmap.h" #include "containers/sectionarray.h" +#include "containers/stringarray.h" +#include "cregex/pattern.h" #include +#include +#include +#include + +#define RX_SECTION_LINE "^[ \t\n\r\f\v]*\\[([a-z0-9]+)([ \t\n\r\f\v]*\"(.+)\")*\\][ \t\n\r\f\v]*($|#|;)" +#define RX_VARIABLE_LINE "^[ \t\n\r\f\v]*([a-z][a-z0-9]+)[ \t\n\r\f\v]*=[ \t\n\r\f\v]*(.+)[ \t\n\r\f\v]*($|#|;)" +#define RX_INTEGER "^-?[1-9][0-9]*$" +#define RX_BLANK_LINE "^[ \t\n\r\f\v]*($|#|;)" + +STATIC SECTIONPTR parseSection(LINEPTR line, PATTERNPTR sectionPatternProgram); +STATIC VARIABLEPTR parseVariable(LINEPTR line, PATTERNPTR variablePatternProgram); +STATIC BOOL parseBlank(LINEPTR line, PATTERNPTR blankPatternProgram); +STATIC BOOL parseBoolValue(CONST_STRPTR value, BOOL* outBool); +STATIC BOOL parseIntegerValue(CONST_STRPTR value, LONG* outInt, PATTERNPTR integerProgram); struct SectionStore { SectionMap map; SectionArray array; + + // here so we only create them once not each line + PATTERNPTR sectionPatternProgram; + PATTERNPTR variablePatternProgram; + PATTERNPTR blankPatternProgram; + PATTERNPTR integerPatternProgram; }; SECTIONSTOREPTR SectionStoreNew(VOID) @@ -15,7 +37,10 @@ SECTIONSTOREPTR SectionStoreNew(VOID) struct SectionStore* result = AllocVec(sizeof(struct SectionStore), MEMF_CLEAR); result->map = SectionMapNew(); result->array = SectionArrayNew(); - + result->sectionPatternProgram = PatternNew(RX_SECTION_LINE); + result->variablePatternProgram = PatternNew(RX_VARIABLE_LINE); + result->blankPatternProgram = PatternNew(RX_BLANK_LINE); + result->integerPatternProgram = PatternNew(RX_INTEGER); return result; } @@ -26,6 +51,10 @@ VOID SectionStoreFree(SECTIONSTOREPTR abstractSectionStore) struct SectionStore* store = (struct SectionStore*)abstractSectionStore; if( store->map != NULL ) SectionMapFree( store->map ); if( store->array != NULL ) SectionArrayFree( store->array ); + if( store->sectionPatternProgram != NULL ) PatternFree(store->sectionPatternProgram); + if( store->variablePatternProgram != NULL ) PatternFree(store->variablePatternProgram); + if( store->blankPatternProgram != NULL ) PatternFree(store->blankPatternProgram); + if( store->integerPatternProgram != NULL ) PatternFree(store->integerPatternProgram); FreeVec(store); } } @@ -56,3 +85,164 @@ SECTIONPTR SectionStoreGetSection(SECTIONSTOREPTR abstractSectionStore, CONST_ST return SectionMapGet(store->map, canonicalName); } } + +SECTIONPTR SectionStoreCurrentSection(SECTIONSTOREPTR abstractSectionStore) +{ + struct SectionStore* store = (struct SectionStore*)abstractSectionStore; + SECTIONPTR result = NULL; + if( store != NULL && SizeOfArray(store->array) > 0 ) + { + result = ArrayBackValue(SECTIONPTR, store->array); + } + return result; +} + +VOID SectionStoreAddLine(SECTIONSTOREPTR abstractSectionStore, LINEPTR line) +{ + struct SectionStore* store = (struct SectionStore*)abstractSectionStore; + if( store != NULL ) + { + // if its a new section, just add it and move on + SECTIONPTR section = parseSection(line, store->sectionPatternProgram); + if( section ) + { + SectionStoreAddSection(store, section); + SectionAddSectionLine(section, line); + } + else + { + // if its a variable or blank, parse it and add to current section + VARIABLEPTR variable = NULL; + section = SectionStoreCurrentSection(store); + // if no current section, we're adding variables at the state so create a blank section + if( section == NULL ) + { + section = SectionCreateWithName(""); + SectionStoreAddSection(store, section); + } + if( variable = parseVariable(line, store->variablePatternProgram) ) + { + LineSetInitialVariable(line, variable); + SectionAddLine(section, line); + } + else + { + if( parseBlank(line, store->blankPatternProgram) ) + { + SectionAddLine(section, line); + } + else + { + // wasnt a section, a variable or a comment so ignore it or complain + } + } + } + + } +} + +ULONG SectionStoreSectionCount(SECTIONSTOREPTR abstractSectionStore) +{ + ULONG result = 0; + struct SectionStore* store = (struct SectionStore*)abstractSectionStore; + if( store != NULL ) + { + return SizeOfArray(store->array); + } + return result; +} + +SECTIONPTR SectionStoreSectionAt(SECTIONSTOREPTR abstractSectionStore, ULONG index) +{ + SECTIONPTR result = NULL; + struct SectionStore* store = (struct SectionStore*)abstractSectionStore; + if( store != NULL ) + { + if( index < SizeOfArray(store->array) ) + { + result = SectionArrayValues(store->array)[index]; + } + } + return result; +} + + +// --------------------------------------------------------------------------------------- +// --------------------------------------------------------------------------------------- +// PRIVATE +// --------------------------------------------------------------------------------------- +// --------------------------------------------------------------------------------------- + +STATIC VARIABLEPTR parseVariable(LINEPTR line, PATTERNPTR variablePatternProgram) +{ + VARIABLEPTR result = NULL; + StringArray matches = NULL; + if( matches = PatternRun(LineGetRawText(line), variablePatternProgram) ) + { + result = VariableCreate(StringArrayValues(matches)[1], StringArrayValues(matches)[2]); + StringArrayFree(matches); + } + return result; +} + +STATIC SECTIONPTR parseSection(LINEPTR line, PATTERNPTR sectionPatternProgram) +{ + SECTIONPTR result = NULL; + StringArray matches = NULL; + if( matches = PatternRun(LineGetRawText(line), sectionPatternProgram) ) + { + if( SizeOfArray(matches) == 3 ) + { + result = SectionCreateWithName(StringArrayValues(matches)[1]); + } + else if( SizeOfArray(matches) == 5 ) + { + result = SectionCreateWithNameAndSubname(StringArrayValues(matches)[1], StringArrayValues(matches)[3]); + } + StringArrayFree(matches); + } + return result; +} + +STATIC BOOL parseBoolValue(CONST_STRPTR value, BOOL* outBool) +{ + BOOL result = FALSE; + if( strcmp(value, "yes") == 0 || strcmp(value, "true") == 0 || strcmp(value, "on") == 0 ) { + *outBool = TRUE; + result = TRUE; + } + if( strcmp(value, "no") == 0 || strcmp(value, "false") == 0 || strcmp(value, "off") == 0 ) { + *outBool = FALSE; + result = TRUE; + } + return result; +} + + +STATIC BOOL parseIntegerValue(CONST_STRPTR value, LONG* outInt, PATTERNPTR integerProgram) +{ + BOOL result = FALSE; + StringArray matches = NULL; + + if( matches = PatternRun(value, integerProgram) ) + { + StringArrayFree(matches); + *outInt = atol(value); + result = TRUE; + } + return result; +} + + +STATIC BOOL parseBlank(LINEPTR line, PATTERNPTR blankPatternProgram) +{ + BOOL result = FALSE; + StringArray matches = NULL; + if( matches = PatternRun(LineGetRawText(line), blankPatternProgram) ) + { + result = TRUE; + StringArrayFree(matches); + } + return result; +} + diff --git a/sectionstore.h b/sectionstore.h index a0b5e51..2cdffce 100644 --- a/sectionstore.h +++ b/sectionstore.h @@ -3,11 +3,16 @@ #include "types.h" -SECTIONPTR SectionStoreGetSection(SECTIONSTOREPTR sectionStore, CONST_STRPTR canonicalName); +SECTIONSTOREPTR SectionStoreNew(VOID); +VOID SectionStoreFree(SECTIONSTOREPTR sectionStore); VOID SectionStoreAddSection(SECTIONSTOREPTR sectionStore, SECTIONPTR section); +SECTIONPTR SectionStoreCurrentSection(SECTIONSTOREPTR sectionStore); +SECTIONPTR SectionStoreGetSection(SECTIONSTOREPTR sectionStore, CONST_STRPTR canonicalName); -SECTIONSTOREPTR SectionStoreNew(VOID); +VOID SectionStoreAddLine(SECTIONSTOREPTR sectionStore, LINEPTR line); + +ULONG SectionStoreSectionCount(SECTIONSTOREPTR sectionStore); +SECTIONPTR SectionStoreSectionAt(SECTIONSTOREPTR sectionStore, ULONG index); -VOID SectionStoreFree(SECTIONSTOREPTR sectionStore); #endif \ No newline at end of file diff --git a/smakefile b/smakefile index 14da6ba..522070d 100644 --- a/smakefile +++ b/smakefile @@ -14,11 +14,11 @@ LIBS = lib:sc.lib lib:amiga.lib lib:debug.lib $(NAME) : main.o configmodel.o sectionstore.o cregex/cregex.lib containers/containers.lib slink lib:c.o main.o configmodel.o sectionstore.o to $(NAME) noicons lib $(LIBS) cregex/cregex.lib containers/containers.lib $(LFLAGS) -cregex/cregex.lib : cregex/cregex_compile.o cregex/cregex_parse.o cregex/cregex_vm.o - JOIN cregex/cregex_compile.o cregex/cregex_parse.o cregex/cregex_vm.o AS cregex/cregex.lib +cregex/cregex.lib : cregex/pattern.o cregex/cregex_compile.o cregex/cregex_parse.o cregex/cregex_vm.o + JOIN cregex/pattern.o cregex/cregex_compile.o cregex/cregex_parse.o cregex/cregex_vm.o AS cregex/cregex.lib -containers/containers.lib : containers/stringarray.o containers/linearray.o containers/linemap.o containers/sectionarray.o containers/sectionmap.o - JOIN containers/stringarray.o containers/linearray.o containers/linemap.o containers/sectionarray.o containers/sectionmap.o AS containers/containers.lib +containers/containers.lib : containers/stringarray.o containers/linearray.o containers/sectionarray.o containers/sectionmap.o + JOIN containers/stringarray.o containers/linearray.o containers/sectionarray.o containers/sectionmap.o AS containers/containers.lib clean: delete \#?.o $(NAME) ALL QUIET @@ -30,14 +30,15 @@ cleanlibs: main.o : main.c configmodel.o : configmodel.c configmodel.h types.h +configregex.o : configregex.c configregex.h types.h sectionstore.o : sectionstore.c sectionstore.h types.h cregex/cregex_compile.o : cregex/cregex_compile.c cregex/cregex.h cregex/cregex_parse.o : cregex/cregex_parse.c cregex/cregex.h cregex/cregex_vm.o : cregex/cregex_vm.c cregex/cregex.h +cregex/pattern.o : cregex/pattern.c cregex/pattern.h cregex/cregex.h containers/stringarray.o : containers/stringarray.c containers/stringarray.h types.h containers/linearray.o : containers/linearray.c containers/linearray.h types.h -containers/linemap.o : containers/linemap.c containers/linemap.h types.h containers/sectionarray.o : containers/sectionarray.c containers/sectionarray.h types.h containers/sectionmap.o : containers/sectionmap.c containers/sectionmap.h types.h diff --git a/types.h b/types.h index 3485f2d..ed70dce 100644 --- a/types.h +++ b/types.h @@ -3,11 +3,20 @@ #include +typedef APTR SECTIONSTOREPTR; + typedef APTR LINEPTR; typedef APTR SECTIONPTR; typedef APTR VARIABLEPTR; typedef APTR CONFIGFILEPTR; -typedef APTR SECTIONSTOREPTR; + +typedef APTR PATTERNPTR; + +typedef APTR StringArray; +typedef APTR LineArray; +typedef APTR SectionArray; +typedef APTR SectionMap; // a map of string (canonical name) to Section +