|
|
|
@ -29,6 +29,7 @@ struct Section |
|
|
|
|
CONST_STRPTR primary; |
|
|
|
|
CONST_STRPTR secondary; |
|
|
|
|
LineArray lines; |
|
|
|
|
BOOL lastLineWasEmpty; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
enum VariableType
|
|
|
|
@ -43,7 +44,7 @@ struct Variable |
|
|
|
|
enum VariableType type; |
|
|
|
|
CONST_STRPTR key; |
|
|
|
|
CONST_STRPTR normalizedKey; |
|
|
|
|
union
|
|
|
|
|
struct
|
|
|
|
|
{ |
|
|
|
|
CONST_STRPTR stringValue; |
|
|
|
|
BOOL boolValue; |
|
|
|
@ -79,15 +80,17 @@ STATIC LINEPTR configFileReadLine(BPTR file); |
|
|
|
|
|
|
|
|
|
CONFIGFILEPTR ConfigFileRead(CONST_STRPTR filename) |
|
|
|
|
{ |
|
|
|
|
struct ConfigFile* result = AllocVec(sizeof(struct ConfigFile), MEMF_CLEAR); |
|
|
|
|
struct ConfigFile* result = NULL; |
|
|
|
|
BPTR configFile = Open(filename, MODE_OLDFILE); |
|
|
|
|
if( configFile != ZERO ) |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
LINEPTR line = NULL; |
|
|
|
|
result = AllocVec(sizeof(struct ConfigFile), MEMF_CLEAR); |
|
|
|
|
result->sectionStore = SectionStoreNew(); |
|
|
|
|
while( (line = configFileReadLine(configFile)) != NULL ) |
|
|
|
|
{ |
|
|
|
|
SectionStoreAddLine(result->sectionStore, line); |
|
|
|
|
SectionStoreAddLineToCurrentSection(result->sectionStore, line); |
|
|
|
|
//LineDump(line);
|
|
|
|
|
} |
|
|
|
|
Close(configFile); |
|
|
|
@ -96,7 +99,65 @@ CONFIGFILEPTR ConfigFileRead(CONST_STRPTR filename) |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
StringArray ConfigFileSplitKey(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.
|
|
|
|
|
// 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) |
|
|
|
|
{ |
|
|
|
|
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 ConfigFileSplitKeyForVar(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.
|
|
|
|
@ -122,7 +183,7 @@ StringArray ConfigFileSplitKey(CONST_STRPTR key) |
|
|
|
|
FreeVec(keyCopy); |
|
|
|
|
|
|
|
|
|
// now we join all but the last part
|
|
|
|
|
sectionPart = StringArrayJoinedParts(parts, '.', SizeOfArray(parts)-1); |
|
|
|
|
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
|
|
|
|
@ -136,7 +197,7 @@ STRPTR ConfigFileGet(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey) |
|
|
|
|
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile; |
|
|
|
|
if( configFile != NULL ) |
|
|
|
|
{ |
|
|
|
|
StringArray split = ConfigFileSplitKey(compoundKey); |
|
|
|
|
StringArray split = ConfigFileSplitKeyForVar(compoundKey); |
|
|
|
|
VARIABLEPTR var = SectionStoreGet(configFile->sectionStore, StringArrayValues(split)[0], StringArrayValues(split)[1]); |
|
|
|
|
if( var != NULL ) |
|
|
|
|
{ |
|
|
|
@ -156,7 +217,7 @@ StringArray ConfigFileGetAll(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR comp |
|
|
|
|
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile; |
|
|
|
|
if( configFile != NULL ) |
|
|
|
|
{ |
|
|
|
|
StringArray split = ConfigFileSplitKey(compoundKey); |
|
|
|
|
StringArray split = ConfigFileSplitKeyForVar(compoundKey); |
|
|
|
|
VariableArray vars = SectionStoreGetAll(configFile->sectionStore, StringArrayValues(split)[0], StringArrayValues(split)[1]); |
|
|
|
|
for( index = 0; index < SizeOfArray(vars); index++ ) |
|
|
|
|
{ |
|
|
|
@ -168,6 +229,97 @@ StringArray ConfigFileGetAll(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR comp |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
VOID ConfigFileAdd(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey, CONST_STRPTR stringValue) |
|
|
|
|
{ |
|
|
|
|
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile; |
|
|
|
|
if( configFile != NULL ) |
|
|
|
|
{ |
|
|
|
|
SECTIONPTR section = NULL; |
|
|
|
|
VARIABLEPTR var = NULL; |
|
|
|
|
CONST_STRPTR varLine = NULL; |
|
|
|
|
LINEPTR line = NULL; |
|
|
|
|
StringArray canonicalParts = NULL; |
|
|
|
|
|
|
|
|
|
// get canonical section name and var name
|
|
|
|
|
canonicalParts = ConfigFileSplitKeyForVar(compoundKey); |
|
|
|
|
|
|
|
|
|
// build a var line
|
|
|
|
|
var = VariableCreate(StringArrayValues(canonicalParts)[1], stringValue); |
|
|
|
|
varLine = VariableSerialize(var); |
|
|
|
|
line = LineNew(varLine); |
|
|
|
|
FreeVec((STRPTR)varLine); |
|
|
|
|
LineSetInitialVariable(line, var); |
|
|
|
|
|
|
|
|
|
// now get the section
|
|
|
|
|
section = SectionStoreGetSection(configFile->sectionStore, StringArrayValues(canonicalParts)[0]); |
|
|
|
|
if( section == NULL ) |
|
|
|
|
{ |
|
|
|
|
StringArray separateParts = ConfigFileSplitKeyCompletely(compoundKey); |
|
|
|
|
CONST_STRPTR sectionLineText = NULL; |
|
|
|
|
LINEPTR sectionLine = NULL; |
|
|
|
|
|
|
|
|
|
section = SectionCreateWithNameAndSubname(StringArrayValues(separateParts)[0], StringArrayValues(separateParts)[1]); |
|
|
|
|
sectionLineText = SectionSerialize(section); |
|
|
|
|
sectionLine = LineNew(sectionLineText); |
|
|
|
|
SectionAddSectionLine(section, sectionLine); |
|
|
|
|
FreeVec((STRPTR)sectionLineText); |
|
|
|
|
SectionDump(section); |
|
|
|
|
SectionStoreAddSection(configFile->sectionStore, section); //section store will free it for us
|
|
|
|
|
SectionDump(section); |
|
|
|
|
StringArrayFree(separateParts, TRUE); |
|
|
|
|
} |
|
|
|
|
// add the line to the section
|
|
|
|
|
SectionAddLine(section, line);
|
|
|
|
|
SectionDump(section); |
|
|
|
|
|
|
|
|
|
StringArrayFree(canonicalParts, TRUE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
VOID ConfigFileSet(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey, CONST_STRPTR stringValue) |
|
|
|
|
{ |
|
|
|
|
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile; |
|
|
|
|
if( configFile != NULL ) |
|
|
|
|
{ |
|
|
|
|
StringArray parts = ConfigFileSplitKeyCompletely(compoundKey); |
|
|
|
|
|
|
|
|
|
StringArrayFree(parts, TRUE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
VOID ConfigFileReplaceAll(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey, CONST_STRPTR stringValue) |
|
|
|
|
{ |
|
|
|
|
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile; |
|
|
|
|
if( configFile != NULL ) |
|
|
|
|
{ |
|
|
|
|
StringArray parts = ConfigFileSplitKeyCompletely(compoundKey); |
|
|
|
|
|
|
|
|
|
StringArrayFree(parts, TRUE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
VOID ConfigFileUnset(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey, CONST_STRPTR stringValue) |
|
|
|
|
{ |
|
|
|
|
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile; |
|
|
|
|
if( configFile != NULL ) |
|
|
|
|
{ |
|
|
|
|
StringArray parts = ConfigFileSplitKeyCompletely(compoundKey); |
|
|
|
|
|
|
|
|
|
StringArrayFree(parts, TRUE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
VOID ConfigFileUnsetAll(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey, CONST_STRPTR stringValue) |
|
|
|
|
{ |
|
|
|
|
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile; |
|
|
|
|
if( configFile != NULL ) |
|
|
|
|
{ |
|
|
|
|
StringArray parts = ConfigFileSplitKeyCompletely(compoundKey); |
|
|
|
|
|
|
|
|
|
StringArrayFree(parts, TRUE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
VOID ConfigFileDump(CONFIGFILEPTR abstractConfigFile) |
|
|
|
|
{ |
|
|
|
|
ULONG index = 0; |
|
|
|
@ -200,10 +352,12 @@ STATIC LINEPTR configFileReadLine(BPTR file) |
|
|
|
|
}
|
|
|
|
|
while( read != NULL && bytesReadTotal >= 2 && bytesReadTotal < bufLength && buffer[bytesReadTotal-1] == '\n' && buffer[bytesReadTotal-2] == '\\' ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// make a line
|
|
|
|
|
if( bytesReadTotal > 0 ) |
|
|
|
|
{ |
|
|
|
|
result = LineNew(buffer, bytesReadTotal); |
|
|
|
|
buffer[bytesReadTotal] = '\0'; |
|
|
|
|
result = LineNew(buffer); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
FreeVec(buffer); |
|
|
|
@ -214,14 +368,14 @@ STATIC LINEPTR configFileReadLine(BPTR file) |
|
|
|
|
// - LINE --------------------------------------------------------------------------------
|
|
|
|
|
// ---------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
LINEPTR LineNew(CONST_STRPTR buffer, ULONG size) |
|
|
|
|
LINEPTR LineNew(CONST_STRPTR buffer) |
|
|
|
|
{ |
|
|
|
|
struct Line* result = NULL; |
|
|
|
|
if( size > 0 ) |
|
|
|
|
if( buffer != 0 ) |
|
|
|
|
{ |
|
|
|
|
result = AllocVec(sizeof(struct Line), MEMF_CLEAR); |
|
|
|
|
result->rawText = AllocVec(size, MEMF_CLEAR); |
|
|
|
|
CopyMem(buffer, result->rawText, size-1); // drop the \\n
|
|
|
|
|
result->rawText = AllocVec(strlen(buffer)+1, MEMF_CLEAR); |
|
|
|
|
CopyMem(buffer, result->rawText, strlen(buffer));
|
|
|
|
|
} |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
@ -235,7 +389,7 @@ VOID LineDump(LINEPTR abstractLine) |
|
|
|
|
{ |
|
|
|
|
if( line->rawText != NULL ) |
|
|
|
|
{ |
|
|
|
|
Printf("%s\n", line->rawText);
|
|
|
|
|
Printf("%s", line->rawText);
|
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
@ -259,23 +413,16 @@ STATIC VOID lineDumpRecreate(LINEPTR abstractLine) |
|
|
|
|
{ |
|
|
|
|
// section
|
|
|
|
|
struct Section* section = (struct Section*)LineGetSection(abstractLine); |
|
|
|
|
if( section != NULL && section->primary != NULL ) |
|
|
|
|
{ |
|
|
|
|
if( strlen(section->primary) > 0 ) |
|
|
|
|
{ |
|
|
|
|
Printf("[%s", section->primary); |
|
|
|
|
if( section->secondary != NULL ) |
|
|
|
|
{ |
|
|
|
|
Printf(" \"%s\"", section->secondary); |
|
|
|
|
} |
|
|
|
|
Printf("]\n"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
STRPTR sectionText = SectionSerialize(section); |
|
|
|
|
Printf(sectionText); |
|
|
|
|
FreeVec(sectionText); |
|
|
|
|
} |
|
|
|
|
else
|
|
|
|
|
{ |
|
|
|
|
struct Variable* var = (struct Variable*)LineGetVariable(abstractLine); |
|
|
|
|
Printf("%s = %s\n", var->key, var->value.stringValue); |
|
|
|
|
STRPTR varText = VariableSerialize(var); |
|
|
|
|
Printf(varText); |
|
|
|
|
FreeVec(varText); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -361,7 +508,6 @@ VOID LineFree(LINEPTR abstractLine) |
|
|
|
|
{ |
|
|
|
|
FreeVec(line->rawText); |
|
|
|
|
} |
|
|
|
|
// we dont free the section as its stored in the section store
|
|
|
|
|
if( line->variable != NULL ) |
|
|
|
|
{ |
|
|
|
|
VariableFree(line->variable); |
|
|
|
@ -383,6 +529,26 @@ CONST_STRPTR LineGetRawText(LINEPTR abstractLine) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
BOOL LineIsEmpty(LINEPTR abstractLine) |
|
|
|
|
{ |
|
|
|
|
struct Line* line = (struct Line*)abstractLine; |
|
|
|
|
if( line != NULL ) |
|
|
|
|
{ |
|
|
|
|
STRPTR start = line->rawText; |
|
|
|
|
STRPTR end = start + strlen(line->rawText); |
|
|
|
|
while( start != end ) |
|
|
|
|
{ |
|
|
|
|
if(!isspace(*start))
|
|
|
|
|
{ |
|
|
|
|
return FALSE; |
|
|
|
|
} |
|
|
|
|
start++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return TRUE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------------------
|
|
|
|
|
// - SECTION -----------------------------------------------------------------------------
|
|
|
|
|
// ---------------------------------------------------------------------------------------
|
|
|
|
@ -400,10 +566,11 @@ SECTIONPTR SectionCreateWithNameAndSubname(CONST_STRPTR primary, CONST_STRPTR se |
|
|
|
|
{ |
|
|
|
|
ULONG length = strlen(primary); |
|
|
|
|
result = AllocVec(sizeof(struct Section), MEMF_CLEAR); |
|
|
|
|
result->lastLineWasEmpty = FALSE; |
|
|
|
|
result->primary = AllocVec(length+1, MEMF_CLEAR); |
|
|
|
|
CopyMem(primary, (STRPTR)result->primary, length); |
|
|
|
|
|
|
|
|
|
if( secondary != NULL ) |
|
|
|
|
if( secondary != NULL && strlen(secondary) > 0 ) |
|
|
|
|
{ |
|
|
|
|
ULONG length = strlen(secondary); |
|
|
|
|
result->secondary = AllocVec(length+1, MEMF_CLEAR); |
|
|
|
@ -423,12 +590,50 @@ VOID SectionAddSectionLine(SECTIONPTR abstractSection, LINEPTR abstractLine) |
|
|
|
|
SectionAddLine(abstractSection, abstractLine); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// we need to know if there are blank lines at the end and if this is a variable,
|
|
|
|
|
//insert this before them
|
|
|
|
|
//
|
|
|
|
|
// otherwise we go from
|
|
|
|
|
// [foo]
|
|
|
|
|
// bar = 1
|
|
|
|
|
//
|
|
|
|
|
// [baz]
|
|
|
|
|
// etc
|
|
|
|
|
// to
|
|
|
|
|
//
|
|
|
|
|
// [foo]
|
|
|
|
|
// bar = 1
|
|
|
|
|
//
|
|
|
|
|
// fubar = 1
|
|
|
|
|
// [baz]
|
|
|
|
|
// etc
|
|
|
|
|
|
|
|
|
|
VOID SectionAddLine(SECTIONPTR abstractSection, LINEPTR abstractLine) |
|
|
|
|
{ |
|
|
|
|
struct Section* section = (struct Section*)abstractSection; |
|
|
|
|
if( section != NULL ) |
|
|
|
|
{ |
|
|
|
|
LineArrayAppend(section->lines, abstractLine); |
|
|
|
|
//Printf("\n\SAD1 (%ld bytes avail)\n\n", AvailMem(0));
|
|
|
|
|
|
|
|
|
|
// if the last line is empty and new line is NOT, insert new line before the blank.
|
|
|
|
|
if( section->lastLineWasEmpty && !LineIsEmpty(abstractLine) ) |
|
|
|
|
{ |
|
|
|
|
LINEPTR lastLine = ArrayBackValue(LINEPTR, section->lines); |
|
|
|
|
ULONG lastIndex = SizeOfArray(section->lines)-1; |
|
|
|
|
//Printf("\n\SAD2 (%ld bytes avail)\n\n", AvailMem(0));
|
|
|
|
|
LineArrayValues(section->lines)[lastIndex] = abstractLine; |
|
|
|
|
LineArrayAppend(section->lines, lastLine);
|
|
|
|
|
//Printf("\n\SAD3 (%ld bytes avail)\n\n", AvailMem(0));
|
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
//Printf("\n\SAD4 (%ld bytes avail)\n\n", AvailMem(0));
|
|
|
|
|
LineArrayAppend(section->lines, abstractLine); |
|
|
|
|
//Printf("\n\SAD5 (%ld bytes avail)\n\n", AvailMem(0));
|
|
|
|
|
} |
|
|
|
|
//Printf("\n\SAD6 (%ld bytes avail)\n\n", AvailMem(0));
|
|
|
|
|
section->lastLineWasEmpty = LineIsEmpty(abstractLine); |
|
|
|
|
//Printf("\n\SAD7 (%ld bytes avail)\n\n", AvailMem(0));
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -468,6 +673,39 @@ VOID SectionDump(SECTIONPTR abstractSection) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
CONST_STRPTR SectionSerialize(SECTIONPTR abstractSection) |
|
|
|
|
{ |
|
|
|
|
struct Section* section = (struct Section*)abstractSection; |
|
|
|
|
STRPTR result = NULL; |
|
|
|
|
ULONG size = 0; |
|
|
|
|
if( section != NULL && section->primary != NULL ) |
|
|
|
|
{ |
|
|
|
|
if( strlen(section->primary) > 0 ) |
|
|
|
|
{
|
|
|
|
|
size += 1; // [
|
|
|
|
|
size += strlen(section->primary);
|
|
|
|
|
if( section->secondary != NULL ) |
|
|
|
|
{ |
|
|
|
|
size += 2; // ' \"'
|
|
|
|
|
size += strlen(section->secondary); |
|
|
|
|
size += 1; // \"
|
|
|
|
|
}
|
|
|
|
|
size += 2; // ]\n
|
|
|
|
|
|
|
|
|
|
result = AllocVec(size+1, MEMF_CLEAR); |
|
|
|
|
if( section->secondary == NULL ) |
|
|
|
|
{ |
|
|
|
|
sprintf(result, "[%s]\n", section->primary); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
sprintf(result, "[%s \"%s\"]\n", section->primary, section->secondary); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
VOID SectionFree(SECTIONPTR abstractSection) |
|
|
|
|
{ |
|
|
|
|
struct Section* section = (struct Section*)abstractSection; |
|
|
|
@ -583,9 +821,22 @@ VOID VariableFree(VARIABLEPTR abstractVariable) |
|
|
|
|
FreeVec(variable); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
CONST_STRPTR VariableSerialize(VARIABLEPTR abstractVariable) |
|
|
|
|
{ |
|
|
|
|
STRPTR result = NULL; |
|
|
|
|
struct Variable* variable = (struct Variable*)abstractVariable; |
|
|
|
|
if( variable != NULL && variable->key != NULL && variable->value.stringValue != NULL ) |
|
|
|
|
{ |
|
|
|
|
ULONG size = strlen(variable->key) + 3 + strlen(variable->value.stringValue) + 1; |
|
|
|
|
result = AllocVec(size, MEMF_CLEAR); |
|
|
|
|
sprintf(result, "\t%s = %s\n", variable->key, variable->value.stringValue); |
|
|
|
|
} |
|
|
|
|
return (CONST_STRPTR)result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
STATIC VOID downcaseString(STRPTR string) |
|
|
|
|
{ |
|
|
|
|
BYTE* p = NULL; |
|
|
|
|