diff --git a/configmodel.c b/configmodel.c index c24177e..fb629ff 100644 --- a/configmodel.c +++ b/configmodel.c @@ -4,11 +4,16 @@ #include "cregex/cregex.h" #include "containers/stringarray.h" #include "containers/linearray.h" +#include "containers/sectionarray.h" #include #include #include #include +#include +#include + +STATIC VOID downcaseString(STRPTR string); #define ZERO ((BPTR)0) @@ -37,6 +42,7 @@ struct Variable { enum VariableType type; CONST_STRPTR key; + CONST_STRPTR normalizedKey; union { CONST_STRPTR stringValue; @@ -120,7 +126,26 @@ StringArray ConfigFileSplitKey(CONST_STRPTR key) StringArrayAppend(result, sectionPart); // its been alloced so dont copy varPart = (STRPTR)ArrayBackValue(STRPTR, parts); StringArrayAppendAndRetain(result, varPart); // its a reference so copy - StringArrayFree(parts); + StringArrayFree(parts, TRUE); + return result; +} + +StringArray ConfigFileGetAll(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey) +{ + StringArray result = StringArrayNew(); + ULONG index = 0; + struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile; + if( configFile != NULL ) + { + StringArray split = ConfigFileSplitKey(compoundKey); + VariableArray vars = SectionStoreGetAll(configFile->sectionStore, StringArrayValues(split)[0], StringArrayValues(split)[1]); + for( index = 0; index < SizeOfArray(vars); index++ ) + { + StringArrayAppendAndRetain(result, VariableGetRawValue(VariableArrayValues(vars)[index])); + } + VariableArrayFree(vars, FALSE); + StringArrayFree(split, TRUE); + } return result; } @@ -302,6 +327,12 @@ VARIABLEPTR LineGetVariable(LINEPTR abstractLine) return NULL; } +BOOL LineHasVariable(LINEPTR line, CONST_STRPTR varKey) +{ + VARIABLEPTR var = LineGetVariable(line); + return (BOOL)(var != NULL && VariableHasKey(var, varKey)); +} + VOID LineFree(LINEPTR abstractLine) { struct Line* line = (struct Line*)abstractLine; @@ -382,6 +413,33 @@ VOID SectionAddLine(SECTIONPTR abstractSection, LINEPTR abstractLine) } } +VOID SectionCollectLinesForVariable(SECTIONPTR abstractSection, CONST_STRPTR varKey, LineArray collecting) +{ + struct Section* section = (struct Section*)abstractSection; + if( section != NULL ) + { + ULONG lineCount = SizeOfArray(section->lines); + ULONG index = 0; + STRPTR normalizedKey = AllocVec(strlen(varKey)+1, MEMF_CLEAR); + CopyMem(varKey, normalizedKey, strlen(varKey)); + downcaseString(normalizedKey); + + for( index = 0; index < lineCount; index++ ) + { + LINEPTR line = LineArrayValues(section->lines)[index]; + if( LineHasVariable(line, normalizedKey) ) + { + LineArrayAppend(collecting, line); + } + } + FreeVec(normalizedKey); + } + else + { + Printf("null section\n"); + } +} + VOID SectionDump(SECTIONPTR abstractSection) { struct Section* section = (struct Section*)abstractSection; @@ -449,6 +507,9 @@ VARIABLEPTR VariableCreate(CONST_STRPTR key, CONST_STRPTR rawValue) result = AllocVec(sizeof(struct Variable), MEMF_CLEAR); result->key = AllocVec(length+1, MEMF_CLEAR); CopyMem(key, (STRPTR)result->key, length); + result->normalizedKey = AllocVec(length+1, MEMF_CLEAR); + CopyMem(key, (STRPTR)result->normalizedKey, length); + downcaseString((STRPTR)result->normalizedKey); } result->type = TypeString; if( rawValue != NULL ) @@ -460,6 +521,29 @@ VARIABLEPTR VariableCreate(CONST_STRPTR key, CONST_STRPTR rawValue) return result; } +CONST_STRPTR VariableGetRawValue(VARIABLEPTR abstractVariable) +{ + struct Variable* variable = (struct Variable*)abstractVariable; + if( variable != NULL ) + { + return variable->value.stringValue; + } + return NULL; +} + +BOOL VariableHasKey(VARIABLEPTR abstractVariable, CONST_STRPTR varKey) +{ + struct Variable* variable = (struct Variable*)abstractVariable; + if( variable != NULL ) + { + if( strcmp(varKey, variable->normalizedKey) == 0 ) + { + return TRUE; + } + } + return FALSE; +} + VOID VariableFree(VARIABLEPTR abstractVariable) { struct Variable* variable = (struct Variable*)abstractVariable; @@ -469,6 +553,10 @@ VOID VariableFree(VARIABLEPTR abstractVariable) { FreeVec((STRPTR)variable->key); } + if( variable->normalizedKey != NULL ) + { + FreeVec((STRPTR)variable->normalizedKey); + } if( variable->type == TypeString && variable->value.stringValue != NULL ) { FreeVec((STRPTR)variable->value.stringValue); @@ -478,3 +566,12 @@ VOID VariableFree(VARIABLEPTR abstractVariable) } } + +STATIC VOID downcaseString(STRPTR string) +{ + BYTE* p = NULL; + for(p=string; *p; p++) + { + *p=tolower(*p); + } +} diff --git a/configmodel.h b/configmodel.h index 06fb5d8..b86cc8a 100644 --- a/configmodel.h +++ b/configmodel.h @@ -7,7 +7,7 @@ CONFIGFILEPTR ConfigFileRead(CONST_STRPTR filename); VOID ConfigFileFree(CONFIGFILEPTR configFile); VOID ConfigFileDump(CONFIGFILEPTR configFile); StringArray ConfigFileSplitKey(CONST_STRPTR key); - +StringArray ConfigFileGetAll(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey); LINEPTR LineNew(CONST_STRPTR buffer, ULONG size); VOID LineFree(LINEPTR abstractLine); @@ -19,6 +19,7 @@ SECTIONPTR LineGetSection(LINEPTR line); VARIABLEPTR LineGetVariable(LINEPTR line); VOID LineSetInitialVariable(LINEPTR line, VARIABLEPTR variable); VOID LineSetVariable(LINEPTR line, VARIABLEPTR variable); +BOOL LineHasVariable(LINEPTR line, CONST_STRPTR varKey); VOID LineDump(LINEPTR abstractLine); @@ -30,7 +31,11 @@ VOID SectionAddLine(SECTIONPTR section, LINEPTR line); CONST_STRPTR SectionCanonicalName(SECTIONPTR section); VOID SectionDump(SECTIONPTR section); +VOID SectionCollectLinesForVariable(SECTIONPTR section, CONST_STRPTR varKey, LineArray collecting); + VARIABLEPTR VariableCreate(CONST_STRPTR key, CONST_STRPTR rawValue); +BOOL VariableHasKey(VARIABLEPTR variable, CONST_STRPTR varKey); +CONST_STRPTR VariableGetRawValue(VARIABLEPTR variable); VOID VariableFree(VARIABLEPTR variable); #endif \ No newline at end of file diff --git a/containers/linearray.c b/containers/linearray.c index ea8d1aa..8ae0294 100644 --- a/containers/linearray.c +++ b/containers/linearray.c @@ -11,8 +11,8 @@ LineArray LineArrayNew(VOID) { - #define SIZE_LINEPTR 2 - return NewArray(SIZE_LINEPTR); + #define SIZE_APTR 2 + return NewArray(SIZE_APTR); } VOID LineArrayAppend(LineArray array, LINEPTR value) diff --git a/containers/sectionarray.c b/containers/sectionarray.c index 6e5dfe7..f6de047 100644 --- a/containers/sectionarray.c +++ b/containers/sectionarray.c @@ -2,22 +2,25 @@ #include #include -Array SectionArrayNew(VOID) +#define SIZE_APTR 2 +SectionArray SectionArrayNew(VOID) { - #define SIZE_STRPTR 2 - return NewArray(SIZE_STRPTR); + return NewArray(SIZE_APTR); } VOID SectionArrayAppend(SectionArray array, SECTIONPTR value) { - AppendToArray(CONST_STRPTR, array, value); + AppendToArray(SECTIONPTR, array, value); } -VOID SectionArrayFree(SectionArray array) +VOID SectionArrayFree(SectionArray array, BOOL freeSections) { if( array != NULL ) { - SectionArrayForEach(array, SectionFree(aSection);); + if( freeSections == TRUE ) + { + SectionArrayForEach(array, SectionFree(aSection);); + } DeleteArray(array); } } @@ -25,4 +28,33 @@ VOID SectionArrayFree(SectionArray array) SECTIONPTR* SectionArrayValues(SectionArray array) { return ArrayValues(SECTIONPTR, array); -} \ No newline at end of file +} + + +VariableArray VariableArrayNew(VOID) +{ + return NewArray(SIZE_APTR); +} + +VOID VariableArrayAppend(VariableArray array, VARIABLEPTR value) +{ + AppendToArray(VARIABLEPTR, array, value); +} + +VOID VariableArrayFree(VariableArray array, BOOL freeVars) +{ + if( array != NULL ) + { + if( freeVars == TRUE ) + { + VariableArrayForEach(array, VariableFree(aVariable);); + } + DeleteArray(array); + } +} + +VARIABLEPTR* VariableArrayValues(VariableArray array) +{ + return ArrayValues(VARIABLEPTR, array); +} + diff --git a/containers/sectionarray.h b/containers/sectionarray.h index da24872..237d2c5 100644 --- a/containers/sectionarray.h +++ b/containers/sectionarray.h @@ -7,10 +7,19 @@ SectionArray SectionArrayNew(VOID); VOID SectionArrayAppend(SectionArray array, SECTIONPTR value); -VOID SectionArrayFree(SectionArray array); +VOID SectionArrayFree(SectionArray array, BOOL freeSections); SECTIONPTR* SectionArrayValues(SectionArray array); #define SectionArrayForEach(array, block) do {SECTIONPTR *afe_123_p = (*(SECTIONPTR **)array); SECTIONPTR aSection = *afe_123_p; int afe_123_c = (((ULONG *)array)[1]);\ for (; afe_123_c--; aSection = *(++afe_123_p)) block} while (0); + +VariableArray VariableArrayNew(VOID); +VOID VariableArrayAppend(VariableArray array, VARIABLEPTR value); +VOID VariableArrayFree(VariableArray array, BOOL freeVars); +VARIABLEPTR* VariableArrayValues(VariableArray array); + +#define VariableArrayForEach(array, block) do {VARIABLEPTR *afe_123_p = (*(VARIABLEPTR **)array); SECTIONPTR aVariable = *afe_123_p; int afe_123_c = (((ULONG *)array)[1]);\ + for (; afe_123_c--; aVariable = *(++afe_123_p)) block} while (0); + #endif \ No newline at end of file diff --git a/containers/stringarray.c b/containers/stringarray.c index b19ec18..26d59d4 100644 --- a/containers/stringarray.c +++ b/containers/stringarray.c @@ -24,11 +24,14 @@ VOID StringArrayAppendAndRetain(StringArray array, CONST_STRPTR value) StringArrayAppend(array, localCopy); } -VOID StringArrayFree(StringArray array) +VOID StringArrayFree(StringArray array, BOOL freeStrings) { if( array != NULL ) { - StringArrayForEach(array, FreeVec(aString);); + if( freeStrings ) + { + StringArrayForEach(array, FreeVec(aString);); + } DeleteArray(array); } } diff --git a/containers/stringarray.h b/containers/stringarray.h index c7a52d7..fb7b948 100644 --- a/containers/stringarray.h +++ b/containers/stringarray.h @@ -6,7 +6,7 @@ StringArray StringArrayNew(VOID); VOID StringArrayAppend(StringArray array, CONST_STRPTR value); VOID StringArrayAppendAndRetain(StringArray array, CONST_STRPTR value); -VOID StringArrayFree(StringArray array); +VOID StringArrayFree(StringArray array, BOOL freeStrings); CONST_STRPTR* StringArrayValues(StringArray array); STRPTR StringArrayJoined(StringArray array, BYTE linkCharacter); diff --git a/main.c b/main.c index dcb7f03..10f1f16 100644 --- a/main.c +++ b/main.c @@ -22,26 +22,27 @@ WORD DoTheWork(STRPTR filename) STRPTR joined = NULL; if (ContainerkitBase) { - StringArray parts = ConfigFileSplitKey("foo.bar.baz.blah"); - StringArrayForEach(parts, Printf("[%s]\n",aString);); - -// joined = StringArrayJoined(parts, '>'); -// Printf("{%s}", joined); -// FreeVec(joined); - - StringArrayFree(parts); -// CONFIGFILEPTR config = ConfigFileRead(filename); -// if( config != NULL ) -// { -// Printf("XXXXXXX\n"); -// ConfigFileDump(config); -// Printf("XXXXXXX\n"); -// ConfigFileFree(config); -// } -// else -// { -// result = RETURN_ERROR; -// } + CONFIGFILEPTR config = ConfigFileRead(filename); + if( config != NULL ) + { + StringArray values = NULL; + + values = ConfigFileGetAll(config, "branch.main.remote"); + StringArrayForEach(values, Printf("main %s\n", aString);); + StringArrayFree(values, TRUE); + + values = ConfigFileGetAll(config, "branch.config-file-parsing-from-book.remote"); + StringArrayForEach(values, Printf("parse %s\n", aString);); + StringArrayFree(values, TRUE); + + + + ConfigFileFree(config); + } + else + { + result = RETURN_ERROR; + } } return result; } diff --git a/sectionstore.c b/sectionstore.c index dfa9a38..4e0cb96 100644 --- a/sectionstore.c +++ b/sectionstore.c @@ -2,6 +2,7 @@ #include "containers/sectionmap.h" #include "containers/sectionarray.h" #include "containers/stringarray.h" +#include "containers/linearray.h" #include "cregex/pattern.h" #include @@ -50,7 +51,7 @@ 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->array != NULL ) SectionArrayFree( store->array, TRUE );//free teh sections if( store->sectionPatternProgram != NULL ) PatternFree(store->sectionPatternProgram); if( store->variablePatternProgram != NULL ) PatternFree(store->variablePatternProgram); if( store->blankPatternProgram != NULL ) PatternFree(store->blankPatternProgram); @@ -97,6 +98,42 @@ SECTIONPTR SectionStoreCurrentSection(SECTIONSTOREPTR abstractSectionStore) return result; } +LineArray SectionStoreFindLines(SECTIONSTOREPTR sectionStore, CONST_STRPTR canonicalSectionName, CONST_STRPTR varKey) +{ + LineArray result = LineArrayNew(); + SECTIONPTR section = SectionStoreGetSection(sectionStore, canonicalSectionName); + if( section != NULL ) + { + SectionCollectLinesForVariable(section, varKey, result); + } + + return result; +} + +VariableArray SectionStoreGetAll(SECTIONSTOREPTR sectionStore, CONST_STRPTR canonicalSectionName, CONST_STRPTR varKey) +{ + VariableArray result = VariableArrayNew(); + LineArray lines = SectionStoreFindLines(sectionStore, canonicalSectionName, varKey); + ULONG index = 0; + for( index = 0; index < SizeOfArray(lines); index++) + { + LINEPTR line = LineArrayValues(lines)[index]; + VariableArrayAppend(result, LineGetVariable(line)); + } + LineArrayFree(lines, FALSE); + return result; +} + +VARIABLEPTR SectionStoreGet(SECTIONSTOREPTR sectionStore, CONST_STRPTR canonicalSectionName, CONST_STRPTR varKey) +{ + VARIABLEPTR result = NULL; + LineArray lines = SectionStoreFindLines(sectionStore, canonicalSectionName, varKey); + result = LineGetVariable((LINEPTR)ArrayBackValue(LINEPTR, lines)); + LineArrayFree(lines, FALSE); + return result; +} + + VOID SectionStoreAddLine(SECTIONSTOREPTR abstractSectionStore, LINEPTR line) { struct SectionStore* store = (struct SectionStore*)abstractSectionStore; @@ -180,7 +217,7 @@ STATIC VARIABLEPTR parseVariable(LINEPTR line, PATTERNPTR variablePatternProgram if( matches = PatternRun(LineGetRawText(line), variablePatternProgram) ) { result = VariableCreate(StringArrayValues(matches)[1], StringArrayValues(matches)[2]); - StringArrayFree(matches); + StringArrayFree(matches, TRUE); } return result; } @@ -199,7 +236,7 @@ STATIC SECTIONPTR parseSection(LINEPTR line, PATTERNPTR sectionPatternProgram) { result = SectionCreateWithNameAndSubname(StringArrayValues(matches)[1], StringArrayValues(matches)[3]); } - StringArrayFree(matches); + StringArrayFree(matches, TRUE); } return result; } @@ -226,7 +263,7 @@ STATIC BOOL parseIntegerValue(CONST_STRPTR value, LONG* outInt, PATTERNPTR integ if( matches = PatternRun(value, integerProgram) ) { - StringArrayFree(matches); + StringArrayFree(matches, TRUE); *outInt = atol(value); result = TRUE; } @@ -241,7 +278,7 @@ STATIC BOOL parseBlank(LINEPTR line, PATTERNPTR blankPatternProgram) if( matches = PatternRun(LineGetRawText(line), blankPatternProgram) ) { result = TRUE; - StringArrayFree(matches); + StringArrayFree(matches, TRUE); } return result; } diff --git a/sectionstore.h b/sectionstore.h index 2cdffce..be05fc9 100644 --- a/sectionstore.h +++ b/sectionstore.h @@ -12,6 +12,10 @@ SECTIONPTR SectionStoreGetSection(SECTIONSTOREPTR sectionStore, CONST_STRPTR can VOID SectionStoreAddLine(SECTIONSTOREPTR sectionStore, LINEPTR line); +LineArray SectionStoreFindLines(SECTIONSTOREPTR sectionStore, CONST_STRPTR canonicalSectionName, CONST_STRPTR varKey); +VariableArray SectionStoreGetAll(SECTIONSTOREPTR sectionStore, CONST_STRPTR canonicalSectionName, CONST_STRPTR varKey); +VARIABLEPTR SectionStoreGet(SECTIONSTOREPTR sectionStore, CONST_STRPTR canonicalSectionName, CONST_STRPTR varKey); + ULONG SectionStoreSectionCount(SECTIONSTOREPTR sectionStore); SECTIONPTR SectionStoreSectionAt(SECTIONSTOREPTR sectionStore, ULONG index); diff --git a/types.h b/types.h index ed70dce..896e760 100644 --- a/types.h +++ b/types.h @@ -15,6 +15,7 @@ typedef APTR PATTERNPTR; typedef APTR StringArray; typedef APTR LineArray; typedef APTR SectionArray; +typedef APTR VariableArray; typedef APTR SectionMap; // a map of string (canonical name) to Section