You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
301 lines
8.4 KiB
301 lines
8.4 KiB
#include "types.h"
|
|
#include "configfile.h"
|
|
#include "configmodel.h"
|
|
#include "sectionstore.h"
|
|
|
|
#include "containers/stringarray.h"
|
|
#include "containers/sectionarray.h"
|
|
#include "containers/linearray.h"
|
|
#include <proto/exec.h>
|
|
#include <proto/dos.h>
|
|
#include <string.h>
|
|
// #include <stdio.h>
|
|
// #include <stdlib.h>
|
|
// #include <ctype.h>
|
|
|
|
#define ZERO ((BPTR)0)
|
|
|
|
STATIC LINEPTR configFileReadLine(BPTR file);
|
|
|
|
|
|
// - STRUCTS -----------------------------------------------------------------------------
|
|
struct ConfigFile
|
|
{
|
|
STRPTR filename;
|
|
SECTIONSTOREPTR sectionStore;
|
|
};
|
|
|
|
// ---------------------------------------------------------------------------------------
|
|
// - CONFIG FILE -------------------------------------------------------------------------
|
|
// ---------------------------------------------------------------------------------------
|
|
|
|
VOID ConfigFileFree(CONFIGFILEPTR abstractConfigFile)
|
|
{
|
|
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile;
|
|
if( configFile != NULL )
|
|
{
|
|
if( configFile->sectionStore != NULL )
|
|
{
|
|
SectionStoreFree(configFile->sectionStore);
|
|
}
|
|
if( configFile->filename != NULL )
|
|
{
|
|
FreeVec(configFile->filename);
|
|
}
|
|
FreeVec(configFile);
|
|
}
|
|
}
|
|
|
|
CONFIGFILEPTR ConfigFileReadName(CONST_STRPTR filename)
|
|
{
|
|
struct ConfigFile* result = NULL;
|
|
BPTR configFile = Open(filename, MODE_OLDFILE);
|
|
if( configFile != ZERO )
|
|
{
|
|
result = ConfigFileRead(configFile);
|
|
Close(configFile);
|
|
}
|
|
|
|
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
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
VOID ConfigFileSaveOverwrite(CONFIGFILEPTR abstractConfigFile)
|
|
{
|
|
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile;
|
|
ConfigFileSaveCopyTo(abstractConfigFile, configFile->filename);
|
|
}
|
|
|
|
VOID ConfigFileSaveCopyTo(CONFIGFILEPTR abstractConfigFile, STRPTR newFilename)
|
|
{
|
|
BPTR file = Open(newFilename, MODE_NEWFILE);
|
|
if( file != 0 )
|
|
{
|
|
ConfigFileWrite(abstractConfigFile, file);
|
|
Close(file);
|
|
}
|
|
}
|
|
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
StringArray ConfigFileSubsectionsForSection(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR primarySection)
|
|
{
|
|
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile;
|
|
return SectionStoreSubsectionsForSection(configFile->sectionStore, primarySection);
|
|
}
|
|
|
|
STRPTR ConfigFileGet(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey)
|
|
{
|
|
STRPTR result = NULL;
|
|
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile;
|
|
if( configFile != NULL )
|
|
{
|
|
StringArray split = CompoundKeySplitKeyForVar(compoundKey);
|
|
VARIABLEPTR var = SectionStoreGet(configFile->sectionStore, StringArrayValues(split)[0], StringArrayValues(split)[1]);
|
|
if( var != NULL )
|
|
{
|
|
CONST_STRPTR value = VariableGetRawValue(var);
|
|
result = AllocVec(strlen(value)+1, MEMF_CLEAR);
|
|
CopyMem(value, result, strlen(value));
|
|
}
|
|
StringArrayFree(split, 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 = CompoundKeySplitKeyForVar(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;
|
|
}
|
|
|
|
VOID ConfigFileAddVariable(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 = CompoundKeySplitKeyForVar(compoundKey);
|
|
var = VariableCreate(StringArrayValues(canonicalParts)[1], stringValue);
|
|
varLine = VariableSerialize(var);
|
|
line = LineNew(varLine);
|
|
LineSetInitialVariable(line, var);
|
|
FreeVec((STRPTR)varLine);
|
|
StringArrayFree(canonicalParts, TRUE);
|
|
|
|
// now get the section
|
|
section = SectionStoreFindOrCreateSection(configFile->sectionStore, compoundKey);
|
|
// add the line to the section
|
|
SectionAddLine(section, line, TRUE);
|
|
}
|
|
}
|
|
|
|
BOOL ConfigFileSet(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey, CONST_STRPTR stringValue)
|
|
{
|
|
BOOL result = FALSE;
|
|
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile;
|
|
if( configFile != NULL )
|
|
{
|
|
StringArray parts = CompoundKeySplitKeyForVar(compoundKey);
|
|
LineArray lines = SectionStoreFindLines(configFile->sectionStore, StringArrayValues(parts)[0], StringArrayValues(parts)[1]);
|
|
if( SizeOfArray(lines) == 0 )
|
|
{
|
|
ConfigFileAddVariable(abstractConfigFile, compoundKey, stringValue);
|
|
result = TRUE;
|
|
}
|
|
else if( SizeOfArray(lines) == 1 )
|
|
{
|
|
LINEPTR line = (LINEPTR)ArrayBackValue(LINEPTR, lines);
|
|
if( line )
|
|
{
|
|
VARIABLEPTR var = VariableCreate(StringArrayValues(parts)[1], stringValue);
|
|
if( var )
|
|
{
|
|
LineSetVariable(line, var);
|
|
result = TRUE;
|
|
}
|
|
}
|
|
}
|
|
else // more than one line, we error.
|
|
{
|
|
result = FALSE;
|
|
}
|
|
StringArrayFree(parts, TRUE);
|
|
LineArrayFree(lines, FALSE);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
VOID ConfigFileReplaceAll(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey, CONST_STRPTR stringValue)
|
|
{
|
|
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile;
|
|
if( configFile != NULL )
|
|
{
|
|
StringArray parts = CompoundKeySplitKeyForVar(compoundKey);
|
|
SectionStoreRemoveLines(configFile->sectionStore, StringArrayValues(parts)[0], StringArrayValues(parts)[1]);
|
|
ConfigFileAddVariable( abstractConfigFile, compoundKey, stringValue);
|
|
StringArrayFree(parts, TRUE);
|
|
}
|
|
}
|
|
|
|
VOID ConfigFileUnset(CONFIGFILEPTR abstractConfigFile, CONST_STRPTR compoundKey, CONST_STRPTR stringValue)
|
|
{
|
|
struct ConfigFile* configFile = (struct ConfigFile*)abstractConfigFile;
|
|
if( configFile != NULL )
|
|
{
|
|
StringArray parts = CompoundKeySplitKeyCompletely(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 = CompoundKeySplitKeyCompletely(compoundKey);
|
|
|
|
StringArrayFree(parts, TRUE);
|
|
}
|
|
}
|
|
|
|
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;
|
|
|
|
// 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 )
|
|
{
|
|
buffer[bytesReadTotal] = '\0';
|
|
result = LineNew(buffer);
|
|
}
|
|
|
|
FreeVec(buffer);
|
|
return result;
|
|
}
|
|
|