Compare commits

...

10 Commits

  1. 161
      configfile.c
  2. 22
      configfile.h
  3. 130
      configmodel.c
  4. 8
      configmodel.h
  5. 40
      main.c
  6. 25
      sectionstore.c
  7. 2
      sectionstore.h
  8. 17
      smakefile
  9. 37
      testapp/configfile.h
  10. BIN
      testapp/containerkit.library
  11. 103
      testapp/main.c
  12. 22
      testapp/smakefile
  13. BIN
      testapp/testapp
  14. 41
      testapp/testconfig.cfg
  15. 2
      types.h

@ -21,7 +21,7 @@ STATIC LINEPTR configFileReadLine(BPTR file);
// - STRUCTS -----------------------------------------------------------------------------
struct ConfigFile
{
CONST_STRPTR filename;
STRPTR filename;
SECTIONSTOREPTR sectionStore;
};
@ -38,121 +38,88 @@ VOID ConfigFileFree(CONFIGFILEPTR abstractConfigFile)
{
SectionStoreFree(configFile->sectionStore);
}
if( configFile->filename != NULL )
{
FreeVec(configFile->filename);
}
FreeVec(configFile);
}
}
CONFIGFILEPTR ConfigFileRead(CONST_STRPTR filename)
CONFIGFILEPTR ConfigFileReadName(CONST_STRPTR filename)
{
struct ConfigFile* result = NULL;
BPTR configFile = Open(filename, MODE_OLDFILE);
if( configFile != ZERO )
{
result = ConfigFileRead(configFile);
Close(configFile);
}
LINEPTR line = NULL;
result = AllocVec(sizeof(struct ConfigFile), MEMF_CLEAR);
result->sectionStore = SectionStoreNew();
while( (line = configFileReadLine(configFile)) != NULL )
return result;
}
CONFIGFILEPTR ConfigFileRead(BPTR configFile)
{
struct ConfigFile* result = NULL;
LINEPTR line = NULL;
if( configFile != 0 )
{
UBYTE buffer[256];
if(NameFromFH(configFile, buffer, 256))// if we opened with a filename this is a waste, if not its necessary
{
SectionStoreAddLineToCurrentSection(result->sectionStore, line);
//LineDump(line);
result = AllocVec(sizeof(struct ConfigFile), MEMF_CLEAR);
result->sectionStore = SectionStoreNew();
result->filename = AllocVec(strlen(buffer)+1, MEMF_CLEAR);
CopyMem(buffer, result->filename, strlen(buffer));
while( (line = configFileReadLine(configFile)) != NULL )
{
SectionStoreAddLineToCurrentSection(result->sectionStore, line);
//LineDump(line);
}
}
Close(configFile);
}
return result;
}
VOID ConfigFileSaveOverwrite(CONFIGFILEPTR abstractConfigFile)
{
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile;
ConfigFileSaveCopyTo(abstractConfigFile, configFile->filename);
}
// a key is "foo.bar.baz.blah" where "foo" is the primary section name
// "bar.baz" is the secondary section name and "blah" is the variable name.
// this splits foo.bar.baz.blah into foo, bar.baz amd blah.
// section, subsection and variable.
// we'll get empty strings for the parts that arent present
StringArray ConfigFileSplitKeyCompletely(CONST_STRPTR key)
VOID ConfigFileSaveCopyTo(CONFIGFILEPTR abstractConfigFile, STRPTR newFilename)
{
StringArray result = StringArrayNew();
StringArray parts = StringArrayNew();
ULONG numberOfParts = 0;
STRPTR token = NULL;
// we need to make a copy of the key because strtok modifies it.
STRPTR keyCopy = AllocVec(strlen(key)+1, MEMF_CLEAR);
CopyMem(key, keyCopy, strlen(key));
token = strtok(keyCopy, ".");
while (token != NULL)
{
StringArrayAppendAndRetain(parts, token);
token = strtok(NULL, ".");
}
FreeVec(keyCopy);
// now we join all but the first and last part
numberOfParts = SizeOfArray(parts);
if( numberOfParts == 1 ) //just a variable ["","","var"]
BPTR file = Open(newFilename, MODE_NEWFILE);
if( file != 0 )
{
StringArrayAppendAndRetain(result, "");
StringArrayAppendAndRetain(result, "");
StringArrayAppendAndRetain(result, (STRPTR)ArrayBackValue(STRPTR, parts));
ConfigFileWrite(abstractConfigFile, file);
Close(file);
}
else if( numberOfParts == 2 ) // section and variable ["section","","var"]
{
StringArrayAppendAndRetain(result, StringArrayValues(parts)[0]);
StringArrayAppendAndRetain(result, "");
StringArrayAppendAndRetain(result, StringArrayValues(parts)[1]);
}
else if( numberOfParts == 3 ) // section and subsection and variable ["section","subsec","var"]
{
StringArrayAppendAndRetain(result, StringArrayValues(parts)[0]);
StringArrayAppendAndRetain(result, StringArrayValues(parts)[1]);
StringArrayAppendAndRetain(result, StringArrayValues(parts)[2]);
}
else if( numberOfParts > 3 ) // subsections needs dotted ["section", "subsec1.subsec2", "var""]
{
StringArrayAppendAndRetain(result, StringArrayValues(parts)[0]); //section
}
// start at index 1, and add (size -2 (start+end)) parts
StringArrayAppend(result, StringArrayJoinedParts(parts, '.', 1, SizeOfArray(parts)-2));
StringArrayAppendAndRetain(result, (STRPTR)ArrayBackValue(STRPTR, parts)); // variable
VOID ConfigFileWrite(CONFIGFILEPTR abstractConfigFile, BPTR file)
{
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);
SectionWrite(section, file);
}
}
StringArrayFree(parts, TRUE);
return result;
}
StringArray ConfigFileSplitKeyForVar(CONST_STRPTR key)
StringArray ConfigFileSubsectionsForSection(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR primarySection)
{
// a key is "foo.bar.baz.blah" where "foo" is the primary section name
// "bar.baz" is the secondary section name and "blah" is the variable name.
// In this case we'll just break it down into the canonical section name,
// foo.bar.baz and the variable name blah.
StringArray result = StringArrayNew();
StringArray parts = StringArrayNew();
STRPTR sectionPart = NULL;
STRPTR varPart = NULL;
STRPTR token = NULL;
// we need to make a copy of the key because strtok modifies it.
STRPTR keyCopy = AllocVec(strlen(key)+1, MEMF_CLEAR);
CopyMem(key, keyCopy, strlen(key));
token = strtok(keyCopy, ".");
while (token != NULL)
{
StringArrayAppendAndRetain(parts, token);
token = strtok(NULL, ".");
}
FreeVec(keyCopy);
// now we join all but the last part
sectionPart = StringArrayJoinedParts(parts, '.', 0, SizeOfArray(parts)-1);
StringArrayAppend(result, sectionPart); // its been alloced so dont copy
varPart = (STRPTR)ArrayBackValue(STRPTR, parts);
StringArrayAppendAndRetain(result, varPart); // its a reference so copy
StringArrayFree(parts, TRUE);
return result;
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile;
return SectionStoreSubsectionsForSection(configFile->sectionStore, primarySection);
}
STRPTR ConfigFileGet(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey)
@ -161,7 +128,7 @@ STRPTR ConfigFileGet(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey)
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile;
if( configFile != NULL )
{
StringArray split = ConfigFileSplitKeyForVar(compoundKey);
StringArray split = CompoundKeySplitKeyForVar(compoundKey);
VARIABLEPTR var = SectionStoreGet(configFile->sectionStore, StringArrayValues(split)[0], StringArrayValues(split)[1]);
if( var != NULL )
{
@ -181,7 +148,7 @@ StringArray ConfigFileGetAll(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR comp
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile;
if( configFile != NULL )
{
StringArray split = ConfigFileSplitKeyForVar(compoundKey);
StringArray split = CompoundKeySplitKeyForVar(compoundKey);
VariableArray vars = SectionStoreGetAll(configFile->sectionStore, StringArrayValues(split)[0], StringArrayValues(split)[1]);
for( index = 0; index < SizeOfArray(vars); index++ )
{
@ -203,7 +170,7 @@ VOID ConfigFileAddVariable(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compou
CONST_STRPTR varLine = NULL;
LINEPTR line = NULL;
StringArray canonicalParts = ConfigFileSplitKeyForVar(compoundKey);
StringArray canonicalParts = CompoundKeySplitKeyForVar(compoundKey);
var = VariableCreate(StringArrayValues(canonicalParts)[1], stringValue);
varLine = VariableSerialize(var);
line = LineNew(varLine);
@ -224,7 +191,7 @@ BOOL ConfigFileSet(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey, C
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile;
if( configFile != NULL )
{
StringArray parts = ConfigFileSplitKeyForVar(compoundKey);
StringArray parts = CompoundKeySplitKeyForVar(compoundKey);
LineArray lines = SectionStoreFindLines(configFile->sectionStore, StringArrayValues(parts)[0], StringArrayValues(parts)[1]);
if( SizeOfArray(lines) == 0 )
{
@ -259,7 +226,7 @@ VOID ConfigFileReplaceAll(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoun
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile;
if( configFile != NULL )
{
StringArray parts = ConfigFileSplitKeyForVar(compoundKey);
StringArray parts = CompoundKeySplitKeyForVar(compoundKey);
SectionStoreRemoveLines(configFile->sectionStore, StringArrayValues(parts)[0], StringArrayValues(parts)[1]);
ConfigFileAddVariable( abstractConfigFile, compoundKey, stringValue);
StringArrayFree(parts, TRUE);
@ -271,7 +238,7 @@ VOID ConfigFileUnset(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey,
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile;
if( configFile != NULL )
{
StringArray parts = ConfigFileSplitKeyCompletely(compoundKey);
StringArray parts = CompoundKeySplitKeyCompletely(compoundKey);
StringArrayFree(parts, TRUE);
@ -283,7 +250,7 @@ VOID ConfigFileUnsetAll(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundK
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile;
if( configFile != NULL )
{
StringArray parts = ConfigFileSplitKeyCompletely(compoundKey);
StringArray parts = CompoundKeySplitKeyCompletely(compoundKey);
StringArrayFree(parts, TRUE);
}

@ -1,10 +1,18 @@
#ifndef __CONFIGFILE_H
#define __CONFIGFILE_H
#include "types.h"
CONFIGFILEPTR ConfigFileRead(CONST_STRPTR filename);
#include <exec/types.h>
#include <dos/dos.h>
#include <proto/containerkit.h>
typedef APTR CONFIGFILEPTR;
// added the BPTR version so we can use WorkspaceOpenFile.
// We still need a file name to be able to save though I should probably
// get that from the file
CONFIGFILEPTR ConfigFileRead(BPTR configFile);
CONFIGFILEPTR ConfigFileReadName(CONST_STRPTR filename);
VOID ConfigFileFree(CONFIGFILEPTR configFile);
StringArray ConfigFileGetAll(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey);
Array ConfigFileGetAll(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey);
STRPTR ConfigFileGet(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey);
BOOL ConfigFileSet(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey, CONST_STRPTR stringValue);
@ -24,6 +32,10 @@ VOID ConfigFileUnsetAll(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundK
VOID ConfigFileRemoveSection(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR canonicalName);
VOID ConfigFileDump(CONFIGFILEPTR configFile);
StringArray ConfigFileSplitKeyForVar(CONST_STRPTR key);
StringArray ConfigFileSplitKeyCompletely(CONST_STRPTR key);
VOID ConfigFileSaveOverwrite(CONFIGFILEPTR configFile);
VOID ConfigFileSaveCopyTo(CONFIGFILEPTR configFile, STRPTR newFilename);
VOID ConfigFileWrite(CONFIGFILEPTR abstractConfigFile, BPTR file);
Array ConfigFileSubsectionsForSection(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR primarySection);
#endif

@ -2,6 +2,7 @@
#include "containers/linearray.h"
#include "containers/sectionarray.h"
#include "containers/stringarray.h"
#include <proto/exec.h>
#include <proto/dos.h>
#include <string.h>
@ -50,18 +51,26 @@ LINEPTR LineNew(CONST_STRPTR buffer)
STATIC VOID lineDumpRecreate(LINEPTR abstractLine);
VOID LineDump(LINEPTR abstractLine)
VOID LineWrite(LINEPTR abstractLine, BPTR file)
{
struct Line* line = (struct Line*)abstractLine;
if( line != NULL )
{
if( line->rawText != NULL )
{
Printf("%s", line->rawText);
Write(file, line->rawText, strlen(line->rawText));
}
else
}
}
VOID LineDump(LINEPTR abstractLine)
{
struct Line* line = (struct Line*)abstractLine;
if( line != NULL )
{
if( line->rawText != NULL )
{
lineDumpRecreate(line);
Printf("%s", line->rawText);
}
}
}
@ -252,6 +261,19 @@ SECTIONPTR SectionCreateWithNameAndSubname(CONST_STRPTR primary, CONST_STRPTR se
return result;
}
BOOL SectionHasName(SECTIONPTR abstractSection, CONST_STRPTR primary)
{
struct Section* section = (struct Section*)abstractSection;
return (BOOL)(strcmp(primary, section->primary) == 0);
}
CONST_STRPTR SectionGetRawSubsectionName(SECTIONPTR abstractSection)
{
struct Section* section = (struct Section*)abstractSection;
return section->secondary;
}
VOID SectionAddSectionLine(SECTIONPTR abstractSection, LINEPTR abstractLine)
{
// sets self onto line and then adds line to the collection
@ -364,6 +386,14 @@ VOID SectionRemoveLinesForVariable(SECTIONPTR abstractSection, CONST_STRPTR varK
}
}
VOID SectionWrite(SECTIONPTR abstractSection, BPTR file)
{
struct Section* section = (struct Section*)abstractSection;
if( section != NULL && section->lines != NULL )
{
ArrayForEach(LINEPTR, aLine, section->lines, LineWrite(aLine,file););
}
}
VOID SectionDump(SECTIONPTR abstractSection)
{
@ -549,6 +579,98 @@ CONST_STRPTR VariableSerialize(VARIABLEPTR abstractVariable)
return (CONST_STRPTR)result;
}
// a key is "foo.bar.baz.blah" where "foo" is the primary section name
// "bar.baz" is the secondary section name and "blah" is the variable name.
// this splits foo.bar.baz.blah into foo, bar.baz amd blah.
// section, subsection and variable.
// we'll get empty strings for the parts that arent present
StringArray CompoundKeySplitKeyCompletely(CONST_STRPTR key)
{
StringArray result = StringArrayNew();
StringArray parts = StringArrayNew();
ULONG numberOfParts = 0;
STRPTR token = NULL;
// we need to make a copy of the key because strtok modifies it.
STRPTR keyCopy = AllocVec(strlen(key)+1, MEMF_CLEAR);
CopyMem(key, keyCopy, strlen(key));
token = strtok(keyCopy, ".");
while (token != NULL)
{
StringArrayAppendAndRetain(parts, token);
token = strtok(NULL, ".");
}
FreeVec(keyCopy);
// now we join all but the first and last part
numberOfParts = SizeOfArray(parts);
if( numberOfParts == 1 ) //just a variable ["","","var"]
{
StringArrayAppendAndRetain(result, "");
StringArrayAppendAndRetain(result, "");
StringArrayAppendAndRetain(result, (STRPTR)ArrayBackValue(STRPTR, parts));
}
else if( numberOfParts == 2 ) // section and variable ["section","","var"]
{
StringArrayAppendAndRetain(result, StringArrayValues(parts)[0]);
StringArrayAppendAndRetain(result, "");
StringArrayAppendAndRetain(result, StringArrayValues(parts)[1]);
}
else if( numberOfParts == 3 ) // section and subsection and variable ["section","subsec","var"]
{
StringArrayAppendAndRetain(result, StringArrayValues(parts)[0]);
StringArrayAppendAndRetain(result, StringArrayValues(parts)[1]);
StringArrayAppendAndRetain(result, StringArrayValues(parts)[2]);
}
else if( numberOfParts > 3 ) // subsections needs dotted ["section", "subsec1.subsec2", "var""]
{
StringArrayAppendAndRetain(result, StringArrayValues(parts)[0]); //section
// start at index 1, and add (size -2 (start+end)) parts
StringArrayAppend(result, StringArrayJoinedParts(parts, '.', 1, SizeOfArray(parts)-2));
StringArrayAppendAndRetain(result, (STRPTR)ArrayBackValue(STRPTR, parts)); // variable
}
StringArrayFree(parts, TRUE);
return result;
}
StringArray CompoundKeySplitKeyForVar(CONST_STRPTR key)
{
// a key is "foo.bar.baz.blah" where "foo" is the primary section name
// "bar.baz" is the secondary section name and "blah" is the variable name.
// In this case we'll just break it down into the canonical section name,
// foo.bar.baz and the variable name blah.
StringArray result = StringArrayNew();
StringArray parts = StringArrayNew();
STRPTR sectionPart = NULL;
STRPTR varPart = NULL;
STRPTR token = NULL;
// we need to make a copy of the key because strtok modifies it.
STRPTR keyCopy = AllocVec(strlen(key)+1, MEMF_CLEAR);
CopyMem(key, keyCopy, strlen(key));
token = strtok(keyCopy, ".");
while (token != NULL)
{
StringArrayAppendAndRetain(parts, token);
token = strtok(NULL, ".");
}
FreeVec(keyCopy);
// now we join all but the last part
sectionPart = StringArrayJoinedParts(parts, '.', 0, SizeOfArray(parts)-1);
StringArrayAppend(result, sectionPart); // its been alloced so dont copy
varPart = (STRPTR)ArrayBackValue(STRPTR, parts);
StringArrayAppendAndRetain(result, varPart); // its a reference so copy
StringArrayFree(parts, TRUE);
return result;
}
STATIC VOID downcaseString(STRPTR string)
{

@ -14,6 +14,7 @@ VOID LineSetInitialVariable(LINEPTR line, VARIABLEPTR variable);
VOID LineSetVariable(LINEPTR line, VARIABLEPTR variable);
BOOL LineHasVariable(LINEPTR line, CONST_STRPTR varKey);
BOOL LineIsBlank(LINEPTR line);
VOID LineWrite(LINEPTR abstractLine, BPTR file);
VOID LineDump(LINEPTR abstractLine);
@ -24,7 +25,10 @@ VOID SectionAddSectionLine(SECTIONPTR section, LINEPTR line);
VOID SectionAddLine(SECTIONPTR abstractSection, LINEPTR abstractLine, BOOL addBeforeBlanks);
CONST_STRPTR SectionCanonicalName(SECTIONPTR section);
VOID SectionDump(SECTIONPTR section);
VOID SectionWrite(SECTIONPTR section, BPTR file);
CONST_STRPTR SectionSerialize(SECTIONPTR section);
BOOL SectionHasName(SECTIONPTR section, CONST_STRPTR primary);
CONST_STRPTR SectionGetRawSubsectionName(SECTIONPTR section);
VOID SectionCollectLinesForVariable(SECTIONPTR section, CONST_STRPTR varKey, LineArray collecting);
VOID SectionRemoveLinesForVariable(SECTIONPTR section, CONST_STRPTR varKey);
@ -35,4 +39,8 @@ CONST_STRPTR VariableGetRawValue(VARIABLEPTR variable);
VOID VariableFree(VARIABLEPTR variable);
CONST_STRPTR VariableSerialize(VARIABLEPTR variable);
StringArray CompoundKeySplitKeyForVar(CONST_STRPTR key);
StringArray CompoundKeySplitKeyCompletely(CONST_STRPTR key);
#endif

@ -22,7 +22,7 @@ WORD DoTheWork(STRPTR filename)
WORD result = RETURN_OK;
if (ContainerkitBase)
{
CONFIGFILEPTR config = ConfigFileRead(filename);
CONFIGFILEPTR config = ConfigFileReadName(filename);
if( config != NULL )
{
StringArray values = NULL;
@ -40,25 +40,31 @@ WORD DoTheWork(STRPTR filename)
// ConfigFileSet(config, "branch.main.foob", "bar");
// ConfigFileSet(config, "branch.alan.foob", "bar");
ConfigFileSet(config, "branch.main.remote", "testing");
// ConfigFileSet(config, "branch.main.second", "testing");
ConfigFileSet(config, "branch.main.second", "testing");
// ConfigFileSet(config, "branch.main.third", "testing");
ConfigFileReplaceAll(config, "branch.main.alan", "hello");
ConfigFileAddVariable(config, "branch.main.newvar", "alan");
ConfigFileAddVariable(config, "branch.main.newvar", "alan2");
ConfigFileAddVariable(config, "branch.main.newvar", "alan3");
ConfigFileReplaceAll(config, "branch.main.newvar", "goodbye");
ConfigFileAddVariable(config, "branch.main.newvar1", "yay");
// ConfigFileReplaceAll(config, "branch.main.alan", "hello");
// ConfigFileAddVariable(config, "branch.main.newvar", "alan");
// ConfigFileAddVariable(config, "branch.main.newvar", "alan2");
// ConfigFileAddVariable(config, "branch.main.newvar", "alan3");
// ConfigFileReplaceAll(config, "branch.main.newvar", "goodbye");
// ConfigFileAddVariable(config, "branch.main.newvar1", "yay");
// ConfigFileAddVariable(config, "foo1", "alan");
// ConfigFileAddVariable(config, "test.foo1", "alan2");
// ConfigFileAddVariable(config, "test.foo.foo1", "alan3");
// ConfigFileAddVariable(config, "test.foo.bar.foo1", "alan4");
// ConfigFileAddVariable(config, "test.foo.bar.baz.foo1", "alan5");
// ConfigFileAddVariable(config, "test.foo.bar.baz.bat.foo1", "alan6");
// ConfigFileAddVariable(config, "test.section.jane.foo3", "alan3");
ConfigFileDump(config);
ConfigFileAddVariable(config, "foo1", "alan");
ConfigFileAddVariable(config, "test.foo1", "alan2");
ConfigFileAddVariable(config, "test.foo.foo1", "alan3");
ConfigFileAddVariable(config, "test.foo.bar.foo1", "alan4");
ConfigFileAddVariable(config, "test.foo.bar.baz.foo1", "alan5");
ConfigFileAddVariable(config, "test.foo.bar.baz.bat.foo1", "alan6");
ConfigFileAddVariable(config, "test.section.jane.foo3", "alan3");
values = ConfigFileSubsectionsForSection(config, "branch");
if( values )
{
StringArrayForEach(values, Printf("branch:[%s]\n",aString););
StringArrayFree(values, TRUE);
}
ConfigFileSaveOverwrite(config);
// ConfigFileFree(config);
ConfigFileFree(config);
}
else
{

@ -212,14 +212,35 @@ SECTIONPTR SectionStoreSectionAt(SECTIONSTOREPTR abstractSectionStore, ULONG ind
return result;
}
StringArray SectionStoreSubsectionsForSection(SECTIONSTOREPTR abstractSectionStore, CONST_STRPTR primarySection)
{
struct SectionStore* store = (struct SectionStore*)abstractSectionStore;
StringArray result = StringArrayNew();
ULONG index = 0;
for( index = 0; index < SizeOfArray(store->array); index++)
{
SECTIONPTR section = SectionArrayValues(store->array)[index];
if( SectionHasName(section, primarySection) )
{
CONST_STRPTR secondary = SectionGetRawSubsectionName(section);
if( secondary != NULL && strlen(secondary) > 0 )
{
StringArrayAppendAndRetain(result, secondary);
}
}
}
return result;
}
SECTIONPTR SectionStoreFindOrCreateSection(SECTIONSTOREPTR sectionStore, CONST_STRPTR compoundKey)
{
// now get the section
StringArray canonicalParts = ConfigFileSplitKeyForVar(compoundKey);
StringArray canonicalParts = CompoundKeySplitKeyForVar(compoundKey);
SECTIONPTR section = SectionStoreGetSection(sectionStore, StringArrayValues(canonicalParts)[0]);
if( section == NULL )
{
StringArray separateParts = ConfigFileSplitKeyCompletely(compoundKey);
StringArray separateParts = CompoundKeySplitKeyCompletely(compoundKey);
CONST_STRPTR sectionLineText = NULL;
LINEPTR sectionLine = NULL;

@ -22,4 +22,6 @@ VARIABLEPTR SectionStoreGet(SECTIONSTOREPTR sectionStore, CONST_STRPTR canonical
ULONG SectionStoreSectionCount(SECTIONSTOREPTR sectionStore);
SECTIONPTR SectionStoreSectionAt(SECTIONSTOREPTR sectionStore, ULONG index);
StringArray SectionStoreSubsectionsForSection(SECTIONSTOREPTR sectionStore, CONST_STRPTR primarySection);
#endif

@ -11,20 +11,23 @@ LIBS = lib:sc.lib lib:amiga.lib lib:debug.lib
###############################################################################
$(NAME) : main.o configfile.o configmodel.o sectionstore.o cregex/cregex.lib containers/containers.lib
slink lib:c.o main.o configfile.o configmodel.o sectionstore.o to $(NAME) noicons lib $(LIBS) cregex/cregex.lib containers/containers.lib $(LFLAGS)
$(NAME) : main.o configfile.lib configfile.h
slink lib:c.o main.o to $(NAME) noicons lib $(LIBS) configfile.lib $(LFLAGS)
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
configfile.lib : configfile.o configmodel.o sectionstore.o cregex/pattern.o cregex/cregex_compile.o cregex/cregex_parse.o cregex/cregex_vm.o containers/stringarray.o containers/linearray.o containers/sectionarray.o containers/sectionmap.o
JOIN configfile.o configmodel.o sectionstore.o cregex/pattern.o cregex/cregex_compile.o cregex/cregex_parse.o cregex/cregex_vm.o containers/stringarray.o containers/linearray.o containers/sectionarray.o containers/sectionmap.o AS configfile.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/sectionarray.o containers/sectionmap.o
JOIN containers/stringarray.o containers/linearray.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
cleanlibs:
delete containers/containers.lib containers/\#?.o cregex/cregex.lib cregex/\#?.o ALL QUIET
delete configfile.lib containers/\#?.o cregex/\#?.o ALL QUIET
###############################################################################

@ -0,0 +1,37 @@
#ifndef __CONFIGFILE_H
#define __CONFIGFILE_H
#include <exec/types.h>
#include <dos/dos.h>
#include <proto/containerkit.h>
typedef APTR CONFIGFILEPTR;
CONFIGFILEPTR ConfigFileRead(BPTR configFile, CONST_STRPTR saveName);
CONFIGFILEPTR ConfigFileReadName(CONST_STRPTR filename);
VOID ConfigFileFree(CONFIGFILEPTR configFile);
Array ConfigFileGetAll(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey);
STRPTR ConfigFileGet(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey);
BOOL ConfigFileSet(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey, CONST_STRPTR stringValue);
// --add
VOID ConfigFileAddVariable(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey, CONST_STRPTR stringValue);
// --replace-all
VOID ConfigFileReplaceAll(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey, CONST_STRPTR stringValue);
// --unset
VOID ConfigFileUnset(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey, CONST_STRPTR stringValue);
// --unset-all
VOID ConfigFileUnsetAll(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey, CONST_STRPTR stringValue);
// --remove-section
VOID ConfigFileRemoveSection(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR canonicalName);
VOID ConfigFileDump(CONFIGFILEPTR configFile);
VOID ConfigFileSave(CONFIGFILEPTR configFile);
VOID ConfigFileWrite(CONFIGFILEPTR abstractConfigFile, BPTR file);
Array ConfigFileSubsectionsForSection(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR primarySection);
#endif

Binary file not shown.

@ -0,0 +1,103 @@
// Printf("running (%ld bytes avail)\n", AvailMem(0));
#define __CLIB_PRAGMA_LIBCALL
#include <proto/exec.h>
#include <proto/dos.h>
#define __NOLIBBASE__
// #include "containers/stringarray.h"
// #include "containers/linearray.h"
#include "configfile.h"
//#include "configmodel.h"
#include <proto/containerkit.h>
WORD DoTheWork(STRPTR filename);
VOID ProcessFile(BPTR configFile);
char *vers="\0$VER: testapp (dd.mm.yyyy)";
char *stacksize = "$STACK:8192"; // only works when started from CLI
struct Library *ContainerkitBase;
WORD DoTheWork(STRPTR filename)
{
WORD result = RETURN_OK;
if (ContainerkitBase)
{
BPTR file = Open(filename, MODE_READWRITE);
CONFIGFILEPTR config = ConfigFileRead(file);
if( config != NULL )
{
Array values = NULL;
STRPTR var = NULL;
// values = ConfigFileGetAll(config, "branch.main.remote");
// StringArrayForEach(values, Printf("main %s\n", aString););
// StringArrayFree(values, TRUE);
// var = ConfigFileGet(config, "branch.config-file-parsing-from-book.remote");
// Printf("parse %s\n\n\n", var);
// FreeVec(var);
// ConfigFileDump(config);
// ConfigFileSet(config, "branch.main.foob", "bar");
// ConfigFileSet(config, "branch.alan.foob", "bar");
ConfigFileSet(config, "branch.main.remote", "testing");
ConfigFileSet(config, "branch.main.second", "testing");
// ConfigFileSet(config, "branch.main.third", "testing");
// ConfigFileReplaceAll(config, "branch.main.alan", "hello");
// ConfigFileAddVariable(config, "branch.main.newvar", "alan");
// ConfigFileAddVariable(config, "branch.main.newvar", "alan2");
// ConfigFileAddVariable(config, "branch.main.newvar", "alan3");
// ConfigFileReplaceAll(config, "branch.main.newvar", "goodbye");
// ConfigFileAddVariable(config, "branch.main.newvar1", "yay");
ConfigFileAddVariable(config, "foo1", "alan");
ConfigFileAddVariable(config, "test.foo1", "alan2");
ConfigFileAddVariable(config, "test.foo.foo1", "alan3");
ConfigFileAddVariable(config, "test.foo.bar.foo1", "alan4");
ConfigFileAddVariable(config, "test.foo.bar.baz.foo1", "alan5");
ConfigFileAddVariable(config, "test.foo.bar.baz.bat.foo1", "alan6");
ConfigFileAddVariable(config, "test.section.jane.foo3", "alan3");
values = ConfigFileSubsectionsForSection(config, "branch");
if( values )
{
ArrayForEach(STRPTR, aString, values, Printf("branch:[%s]\n",aString););
ArrayForEach(STRPTR, aString, values, FreeVec(aString););
DeleteArray(values);
}
ConfigFileSave(config);
ConfigFileFree(config);
}
else
{
Printf("could not read the file\n");
result = RETURN_ERROR;
}
}
return result;
}
WORD main(WORD argc, STRPTR *argv)
{
WORD result = RETURN_OK;
// this does nothing but the first call to Print drops a bunch of memory,
// I assume because of opening some resource so this means my start and
// end markers are "clean" and I can ensure I'm not leaking.
Printf("\n");
ContainerkitBase = OpenLibrary("containerkit.library", 1);
if( ContainerkitBase )
{
Printf("\n\nrunning (%ld bytes avail)\n\n", AvailMem(0));
result = DoTheWork(argv[1]);
Printf("\n\ndone (%ld bytes avail)\n\n", AvailMem(0));
CloseLibrary(ContainerkitBase);
}
else
{
Printf("failed to open library\n");
result = RETURN_ERROR;
}
return result;
}

@ -0,0 +1,22 @@
#
# :ts=8
#
###############################################################################
NAME = testapp
LFLAGS = addsym smallcode smalldata noicons batch
LIBS = lib:sc.lib lib:amiga.lib lib:debug.lib
###############################################################################
$(NAME) : main.o configfile.lib configfile.h
slink lib:c.o main.o to $(NAME) noicons lib $(LIBS) configfile.lib $(LFLAGS)
clean:
delete \#?.o $(NAME) ALL QUIET
###############################################################################
main.o : main.c

Binary file not shown.

@ -0,0 +1,41 @@
#this is a comment
foo1 = alan
foo1 = alan
[core]
repositoryformatversion = 0
precomposeunicode = true
[remote "origin.foo"] #this is also a coment
url = git@git.alancfrancis.com:acf/AmigaGit2.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
remote = testing
merge = refs/heads/main
alan = yes
alan = no
alan = sure
second = testing
[branch "config-file-parsing-from-book"]
remote = origin
merge = refs/heads/config-file-parsing-from-book
[test]
foo1 = alan2
foo1 = alan2
[test "foo"]
foo1 = alan3
foo1 = alan3
[test "foo.bar"]
foo1 = alan4
foo1 = alan4
[test "foo.bar.baz"]
foo1 = alan5
foo1 = alan5
[test "foo.bar.baz.bat"]
foo1 = alan6
foo1 = alan6
[test "section.jane"]
foo3 = alan3
foo3 = alan3

@ -2,13 +2,13 @@
#define __TYPES_H
#include <exec/types.h>
#include <dos/dos.h>
typedef APTR SECTIONSTOREPTR;
typedef APTR LINEPTR;
typedef APTR SECTIONPTR;
typedef APTR VARIABLEPTR;
typedef APTR CONFIGFILEPTR;
typedef APTR PATTERNPTR;

Loading…
Cancel
Save