forked from Telodendria/Telodendria
Run indent(1) on all C source files.
This commit is contained in:
parent
ae2b853cc4
commit
aabb2a0203
6 changed files with 213 additions and 141 deletions
20
src/Array.c
20
src/Array.c
|
@ -7,14 +7,16 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
struct Array {
|
struct Array
|
||||||
void **entries; /* An array of void pointers, to store any data */
|
{
|
||||||
|
void **entries; /* An array of void pointers, to
|
||||||
|
* store any data */
|
||||||
size_t allocated; /* Elements allocated on the heap */
|
size_t allocated; /* Elements allocated on the heap */
|
||||||
size_t size; /* Elements actually filled */
|
size_t size; /* Elements actually filled */
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
ArrayAdd(Array *array, void *value)
|
ArrayAdd(Array * array, void *value)
|
||||||
{
|
{
|
||||||
if (!array)
|
if (!array)
|
||||||
{
|
{
|
||||||
|
@ -48,7 +50,7 @@ ArrayCreate(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
ArrayDelete(Array *array, size_t index)
|
ArrayDelete(Array * array, size_t index)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
void *element;
|
void *element;
|
||||||
|
@ -71,7 +73,7 @@ ArrayDelete(Array *array, size_t index)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ArrayFree(Array *array)
|
ArrayFree(Array * array)
|
||||||
{
|
{
|
||||||
if (array)
|
if (array)
|
||||||
{
|
{
|
||||||
|
@ -81,7 +83,7 @@ ArrayFree(Array *array)
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
ArrayGet(Array *array, size_t index)
|
ArrayGet(Array * array, size_t index)
|
||||||
{
|
{
|
||||||
if (!array)
|
if (!array)
|
||||||
{
|
{
|
||||||
|
@ -98,7 +100,7 @@ ArrayGet(Array *array, size_t index)
|
||||||
|
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
ArrayInsert(Array *array, void *value, size_t index)
|
ArrayInsert(Array * array, void *value, size_t index)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
@ -139,7 +141,7 @@ ArrayInsert(Array *array, void *value, size_t index)
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
ArraySize(Array *array)
|
ArraySize(Array * array)
|
||||||
{
|
{
|
||||||
if (!array)
|
if (!array)
|
||||||
{
|
{
|
||||||
|
@ -150,7 +152,7 @@ ArraySize(Array *array)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ArrayTrim(Array *array)
|
ArrayTrim(Array * array)
|
||||||
{
|
{
|
||||||
void **tmp;
|
void **tmp;
|
||||||
|
|
||||||
|
|
27
src/Base64.c
27
src/Base64.c
|
@ -3,7 +3,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
static const char Base64EncodeMap[] =
|
static const char Base64EncodeMap[] =
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
static const int Base64DecodeMap[] = {
|
static const int Base64DecodeMap[] = {
|
||||||
62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58,
|
62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58,
|
||||||
|
@ -43,10 +43,14 @@ Base64DecodedSize(const char *base64, size_t len)
|
||||||
|
|
||||||
ret = len / 4 * 3;
|
ret = len / 4 * 3;
|
||||||
|
|
||||||
for (i = len; i > 0; i--) {
|
for (i = len; i > 0; i--)
|
||||||
if (base64[i] == '=') {
|
{
|
||||||
|
if (base64[i] == '=')
|
||||||
|
{
|
||||||
ret--;
|
ret--;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,12 +90,17 @@ Base64Encode(const char *input, size_t len)
|
||||||
if (i + 1 < len)
|
if (i + 1 < len)
|
||||||
{
|
{
|
||||||
out[j + 2] = Base64EncodeMap[(v >> 6) & 0x3F];
|
out[j + 2] = Base64EncodeMap[(v >> 6) & 0x3F];
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
out[j + 2] = '=';
|
out[j + 2] = '=';
|
||||||
}
|
}
|
||||||
if (i + 2 < len) {
|
if (i + 2 < len)
|
||||||
|
{
|
||||||
out[j + 3] = Base64EncodeMap[v & 0x3F];
|
out[j + 3] = Base64EncodeMap[v & 0x3F];
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
out[j + 3] = '=';
|
out[j + 3] = '=';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,7 +156,8 @@ Base64Decode(const char *input, size_t len)
|
||||||
|
|
||||||
out[outLen] = '\0';
|
out[outLen] = '\0';
|
||||||
|
|
||||||
for (i = 0, j = 0; i < len; i += 4, j += 3) {
|
for (i = 0, j = 0; i < len; i += 4, j += 3)
|
||||||
|
{
|
||||||
v = Base64DecodeMap[input[i] - 43];
|
v = Base64DecodeMap[input[i] - 43];
|
||||||
v = (v << 6) | Base64DecodeMap[input[i + 1] - 43];
|
v = (v << 6) | Base64DecodeMap[input[i + 1] - 43];
|
||||||
v = input[i + 2] == '=' ? v << 6 : (v << 6) | Base64DecodeMap[input[i + 2] - 43];
|
v = input[i + 2] == '=' ? v << 6 : (v << 6) | Base64DecodeMap[input[i + 2] - 43];
|
||||||
|
@ -209,4 +219,3 @@ Base64Pad(char **base64Ptr, size_t length)
|
||||||
|
|
||||||
return newSize;
|
return newSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
178
src/Config.c
178
src/Config.c
|
@ -8,20 +8,24 @@
|
||||||
#define CONFIG_BUFFER_BLOCK 32
|
#define CONFIG_BUFFER_BLOCK 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct ConfigDirective {
|
struct ConfigDirective
|
||||||
|
{
|
||||||
Array *values;
|
Array *values;
|
||||||
HashMap *children;
|
HashMap *children;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ConfigParseResult {
|
struct ConfigParseResult
|
||||||
unsigned int ok : 1;
|
{
|
||||||
union {
|
unsigned int ok:1;
|
||||||
|
union
|
||||||
|
{
|
||||||
size_t lineNumber;
|
size_t lineNumber;
|
||||||
HashMap *confMap;
|
HashMap *confMap;
|
||||||
} data;
|
} data;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum ConfigToken {
|
typedef enum ConfigToken
|
||||||
|
{
|
||||||
TOKEN_UNKNOWN,
|
TOKEN_UNKNOWN,
|
||||||
TOKEN_NAME,
|
TOKEN_NAME,
|
||||||
TOKEN_MACRO_ASSIGNMENT,
|
TOKEN_MACRO_ASSIGNMENT,
|
||||||
|
@ -33,7 +37,8 @@ typedef enum ConfigToken {
|
||||||
TOKEN_EOF
|
TOKEN_EOF
|
||||||
} ConfigToken;
|
} ConfigToken;
|
||||||
|
|
||||||
typedef struct ConfigParserState {
|
typedef struct ConfigParserState
|
||||||
|
{
|
||||||
FILE *stream;
|
FILE *stream;
|
||||||
unsigned int line;
|
unsigned int line;
|
||||||
|
|
||||||
|
@ -47,25 +52,25 @@ typedef struct ConfigParserState {
|
||||||
} ConfigParserState;
|
} ConfigParserState;
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
ConfigParseResultOk(ConfigParseResult *result)
|
ConfigParseResultOk(ConfigParseResult * result)
|
||||||
{
|
{
|
||||||
return result ? result->ok : 0;
|
return result ? result->ok : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
ConfigParseResultLineNumber(ConfigParseResult *result)
|
ConfigParseResultLineNumber(ConfigParseResult * result)
|
||||||
{
|
{
|
||||||
return result && !result->ok ? result->data.lineNumber : 0;
|
return result && !result->ok ? result->data.lineNumber : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
HashMap *
|
HashMap *
|
||||||
ConfigParseResultGet(ConfigParseResult *result)
|
ConfigParseResultGet(ConfigParseResult * result)
|
||||||
{
|
{
|
||||||
return result && result->ok ? result->data.confMap : NULL;
|
return result && result->ok ? result->data.confMap : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ConfigParseResultFree(ConfigParseResult *result)
|
ConfigParseResultFree(ConfigParseResult * result)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Note that if the parse was valid, the hash map
|
* Note that if the parse was valid, the hash map
|
||||||
|
@ -75,13 +80,13 @@ ConfigParseResultFree(ConfigParseResult *result)
|
||||||
}
|
}
|
||||||
|
|
||||||
Array *
|
Array *
|
||||||
ConfigValuesGet(ConfigDirective *directive)
|
ConfigValuesGet(ConfigDirective * directive)
|
||||||
{
|
{
|
||||||
return directive ? directive->values : NULL;
|
return directive ? directive->values : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HashMap *
|
HashMap *
|
||||||
ConfigChildrenGet(ConfigDirective *directive)
|
ConfigChildrenGet(ConfigDirective * directive)
|
||||||
{
|
{
|
||||||
return directive ? directive->children : NULL;
|
return directive ? directive->children : NULL;
|
||||||
}
|
}
|
||||||
|
@ -114,7 +119,7 @@ ConfigDirectiveFree(void *ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ConfigFree(HashMap *conf)
|
ConfigFree(HashMap * conf)
|
||||||
{
|
{
|
||||||
HashMapIterate(conf, ConfigDirectiveFree);
|
HashMapIterate(conf, ConfigDirectiveFree);
|
||||||
HashMapFree(conf);
|
HashMapFree(conf);
|
||||||
|
@ -124,6 +129,7 @@ static ConfigParserState *
|
||||||
ConfigParserStateCreate(FILE * stream)
|
ConfigParserStateCreate(FILE * stream)
|
||||||
{
|
{
|
||||||
ConfigParserState *state = malloc(sizeof(ConfigParserState));
|
ConfigParserState *state = malloc(sizeof(ConfigParserState));
|
||||||
|
|
||||||
if (!state)
|
if (!state)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -148,7 +154,7 @@ ConfigParserStateCreate(FILE * stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ConfigParserStateFree(ConfigParserState *state)
|
ConfigParserStateFree(ConfigParserState * state)
|
||||||
{
|
{
|
||||||
if (!state)
|
if (!state)
|
||||||
{
|
{
|
||||||
|
@ -170,9 +176,10 @@ ConfigIsNameChar(int c)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char
|
static char
|
||||||
ConfigConsumeWhitespace(ConfigParserState *state)
|
ConfigConsumeWhitespace(ConfigParserState * state)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
while (isspace(c = fgetc(state->stream)))
|
while (isspace(c = fgetc(state->stream)))
|
||||||
{
|
{
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
|
@ -184,22 +191,24 @@ ConfigConsumeWhitespace(ConfigParserState *state)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ConfigConsumeLine(ConfigParserState *state)
|
ConfigConsumeLine(ConfigParserState * state)
|
||||||
{
|
{
|
||||||
while (fgetc(state->stream) != '\n');
|
while (fgetc(state->stream) != '\n');
|
||||||
state->line++;
|
state->line++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ConfigTokenSeek(ConfigParserState *state)
|
ConfigTokenSeek(ConfigParserState * state)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
/* If we already hit EOF, don't do anything */
|
/* If we already hit EOF, don't do anything */
|
||||||
if (state->tokenType == TOKEN_EOF) {
|
if (state->tokenType == TOKEN_EOF)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while ((c = ConfigConsumeWhitespace(state)) == '#') {
|
while ((c = ConfigConsumeWhitespace(state)) == '#')
|
||||||
|
{
|
||||||
ConfigConsumeLine(state);
|
ConfigConsumeLine(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,26 +217,31 @@ ConfigTokenSeek(ConfigParserState *state)
|
||||||
* token by looking at the next character
|
* token by looking at the next character
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (feof(state->stream)) {
|
if (feof(state->stream))
|
||||||
|
{
|
||||||
state->tokenType = TOKEN_EOF;
|
state->tokenType = TOKEN_EOF;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ConfigIsNameChar(c)) {
|
if (ConfigIsNameChar(c))
|
||||||
|
{
|
||||||
state->tokenLen = 0;
|
state->tokenLen = 0;
|
||||||
|
|
||||||
/* Read the key/macro into state->token */
|
/* Read the key/macro into state->token */
|
||||||
if (!state->token) {
|
if (!state->token)
|
||||||
|
{
|
||||||
state->tokenSize = CONFIG_BUFFER_BLOCK;
|
state->tokenSize = CONFIG_BUFFER_BLOCK;
|
||||||
state->token = malloc(CONFIG_BUFFER_BLOCK);
|
state->token = malloc(CONFIG_BUFFER_BLOCK);
|
||||||
}
|
}
|
||||||
state->token[state->tokenLen] = c;
|
state->token[state->tokenLen] = c;
|
||||||
state->tokenLen++;
|
state->tokenLen++;
|
||||||
|
|
||||||
while (ConfigIsNameChar((c = fgetc(state->stream)))) {
|
while (ConfigIsNameChar((c = fgetc(state->stream))))
|
||||||
|
{
|
||||||
state->token[state->tokenLen] = c;
|
state->token[state->tokenLen] = c;
|
||||||
state->tokenLen++;
|
state->tokenLen++;
|
||||||
|
|
||||||
if (state->tokenLen >= state->tokenSize) {
|
if (state->tokenLen >= state->tokenSize)
|
||||||
|
{
|
||||||
state->tokenSize += CONFIG_BUFFER_BLOCK;
|
state->tokenSize += CONFIG_BUFFER_BLOCK;
|
||||||
state->token = realloc(state->token,
|
state->token = realloc(state->token,
|
||||||
state->tokenSize);
|
state->tokenSize);
|
||||||
|
@ -237,18 +251,25 @@ ConfigTokenSeek(ConfigParserState *state)
|
||||||
state->token[state->tokenLen] = '\0';
|
state->token[state->tokenLen] = '\0';
|
||||||
state->tokenLen++;
|
state->tokenLen++;
|
||||||
|
|
||||||
if (!isspace(c)) {
|
if (!isspace(c))
|
||||||
|
{
|
||||||
state->tokenType = TOKEN_UNKNOWN;
|
state->tokenType = TOKEN_UNKNOWN;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
state->tokenType = TOKEN_NAME;
|
state->tokenType = TOKEN_NAME;
|
||||||
|
|
||||||
if (c == '\n') {
|
if (c == '\n')
|
||||||
|
{
|
||||||
state->line++;
|
state->line++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
}
|
||||||
switch (c) {
|
else
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
case '=':
|
case '=':
|
||||||
state->tokenType = TOKEN_MACRO_ASSIGNMENT;
|
state->tokenType = TOKEN_MACRO_ASSIGNMENT;
|
||||||
break;
|
break;
|
||||||
|
@ -257,22 +278,26 @@ ConfigTokenSeek(ConfigParserState *state)
|
||||||
state->tokenType = TOKEN_VALUE;
|
state->tokenType = TOKEN_VALUE;
|
||||||
|
|
||||||
/* read the value into state->curtok */
|
/* read the value into state->curtok */
|
||||||
while ((c = fgetc(state->stream)) != '"') {
|
while ((c = fgetc(state->stream)) != '"')
|
||||||
if (c == '\n') {
|
{
|
||||||
|
if (c == '\n')
|
||||||
|
{
|
||||||
state->line++;
|
state->line++;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* End of the stream reached without finding
|
* End of the stream reached without finding
|
||||||
* a closing quote
|
* a closing quote
|
||||||
*/
|
*/
|
||||||
if (feof(state->stream)) {
|
if (feof(state->stream))
|
||||||
|
{
|
||||||
state->tokenType = TOKEN_EOF;
|
state->tokenType = TOKEN_EOF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
state->token[state->tokenLen] = c;
|
state->token[state->tokenLen] = c;
|
||||||
state->tokenLen++;
|
state->tokenLen++;
|
||||||
|
|
||||||
if (state->tokenLen >= state->tokenSize) {
|
if (state->tokenLen >= state->tokenSize)
|
||||||
|
{
|
||||||
state->tokenSize += CONFIG_BUFFER_BLOCK;
|
state->tokenSize += CONFIG_BUFFER_BLOCK;
|
||||||
state->token = realloc(state->token,
|
state->token = realloc(state->token,
|
||||||
state->tokenSize);
|
state->tokenSize);
|
||||||
|
@ -293,11 +318,13 @@ ConfigTokenSeek(ConfigParserState *state)
|
||||||
case '$':
|
case '$':
|
||||||
state->tokenLen = 0;
|
state->tokenLen = 0;
|
||||||
/* read the macro name into state->curtok */
|
/* read the macro name into state->curtok */
|
||||||
while (ConfigIsNameChar(c = fgetc(state->stream))) {
|
while (ConfigIsNameChar(c = fgetc(state->stream)))
|
||||||
|
{
|
||||||
state->token[state->tokenLen] = c;
|
state->token[state->tokenLen] = c;
|
||||||
state->tokenLen++;
|
state->tokenLen++;
|
||||||
|
|
||||||
if (state->tokenLen >= state->tokenSize) {
|
if (state->tokenLen >= state->tokenSize)
|
||||||
|
{
|
||||||
state->tokenSize += CONFIG_BUFFER_BLOCK;
|
state->tokenSize += CONFIG_BUFFER_BLOCK;
|
||||||
state->token = realloc(state->token,
|
state->token = realloc(state->token,
|
||||||
state->tokenSize);
|
state->tokenSize);
|
||||||
|
@ -316,32 +343,36 @@ ConfigTokenSeek(ConfigParserState *state)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resize curtok to only use the bytes it needs */
|
/* Resize curtok to only use the bytes it needs */
|
||||||
if (state->tokenLen) {
|
if (state->tokenLen)
|
||||||
|
{
|
||||||
state->tokenSize = state->tokenLen;
|
state->tokenSize = state->tokenLen;
|
||||||
state->token = realloc(state->token, state->tokenSize);
|
state->token = realloc(state->token, state->tokenSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ConfigExpect(ConfigParserState *state, ConfigToken tokenType)
|
ConfigExpect(ConfigParserState * state, ConfigToken tokenType)
|
||||||
{
|
{
|
||||||
return state->tokenType == tokenType;
|
return state->tokenType == tokenType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static HashMap *
|
static HashMap *
|
||||||
ConfigParseBlock(ConfigParserState *state, int level)
|
ConfigParseBlock(ConfigParserState * state, int level)
|
||||||
{
|
{
|
||||||
HashMap *block = HashMapCreate();
|
HashMap *block = HashMapCreate();
|
||||||
|
|
||||||
ConfigTokenSeek(state);
|
ConfigTokenSeek(state);
|
||||||
|
|
||||||
while (ConfigExpect(state, TOKEN_NAME)) {
|
while (ConfigExpect(state, TOKEN_NAME))
|
||||||
|
{
|
||||||
char *name = malloc(state->tokenLen + 1);
|
char *name = malloc(state->tokenLen + 1);
|
||||||
|
|
||||||
strcpy(name, state->token);
|
strcpy(name, state->token);
|
||||||
|
|
||||||
ConfigTokenSeek(state);
|
ConfigTokenSeek(state);
|
||||||
if (ConfigExpect(state, TOKEN_VALUE) || ConfigExpect(state, TOKEN_MACRO)) {
|
if (ConfigExpect(state, TOKEN_VALUE) || ConfigExpect(state, TOKEN_MACRO))
|
||||||
|
{
|
||||||
ConfigDirective *directive;
|
ConfigDirective *directive;
|
||||||
|
|
||||||
directive = malloc(sizeof(ConfigDirective));
|
directive = malloc(sizeof(ConfigDirective));
|
||||||
|
@ -349,23 +380,31 @@ ConfigParseBlock(ConfigParserState *state, int level)
|
||||||
directive->values = ArrayCreate();
|
directive->values = ArrayCreate();
|
||||||
|
|
||||||
while (ConfigExpect(state, TOKEN_VALUE) ||
|
while (ConfigExpect(state, TOKEN_VALUE) ||
|
||||||
ConfigExpect(state, TOKEN_MACRO)) {
|
ConfigExpect(state, TOKEN_MACRO))
|
||||||
|
{
|
||||||
|
|
||||||
char *dval;
|
char *dval;
|
||||||
char *dvalCpy;
|
char *dvalCpy;
|
||||||
|
|
||||||
if (ConfigExpect(state, TOKEN_VALUE)) {
|
if (ConfigExpect(state, TOKEN_VALUE))
|
||||||
|
{
|
||||||
dval = state->token;
|
dval = state->token;
|
||||||
} else if (ConfigExpect(state, TOKEN_MACRO)) {
|
}
|
||||||
|
else if (ConfigExpect(state, TOKEN_MACRO))
|
||||||
|
{
|
||||||
dval = HashMapGet(state->macroMap, state->token);
|
dval = HashMapGet(state->macroMap, state->token);
|
||||||
if (!dval) {
|
if (!dval)
|
||||||
|
{
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
dval = NULL; /* Should never happen */
|
dval = NULL; /* Should never happen */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dval is a pointer which is overwritten with the next token. */
|
/* dval is a pointer which is overwritten with the next
|
||||||
|
* token. */
|
||||||
dvalCpy = malloc(strlen(dval) + 1);
|
dvalCpy = malloc(strlen(dval) + 1);
|
||||||
strcpy(dvalCpy, dval);
|
strcpy(dvalCpy, dval);
|
||||||
|
|
||||||
|
@ -373,10 +412,12 @@ ConfigParseBlock(ConfigParserState *state, int level)
|
||||||
ConfigTokenSeek(state);
|
ConfigTokenSeek(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ConfigExpect(state, TOKEN_BLOCK_OPEN)) {
|
if (ConfigExpect(state, TOKEN_BLOCK_OPEN))
|
||||||
|
{
|
||||||
/* token_seek(state); */
|
/* token_seek(state); */
|
||||||
directive->children = ConfigParseBlock(state, level + 1);
|
directive->children = ConfigParseBlock(state, level + 1);
|
||||||
if (!directive->children) {
|
if (!directive->children)
|
||||||
|
{
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -392,36 +433,49 @@ ConfigParseBlock(ConfigParserState *state, int level)
|
||||||
*/
|
*/
|
||||||
ConfigDirectiveFree(HashMapSet(block, name, directive));
|
ConfigDirectiveFree(HashMapSet(block, name, directive));
|
||||||
|
|
||||||
} else if (ConfigExpect(state, TOKEN_MACRO_ASSIGNMENT)) {
|
}
|
||||||
|
else if (ConfigExpect(state, TOKEN_MACRO_ASSIGNMENT))
|
||||||
|
{
|
||||||
ConfigTokenSeek(state);
|
ConfigTokenSeek(state);
|
||||||
if (ConfigExpect(state, TOKEN_VALUE)) {
|
if (ConfigExpect(state, TOKEN_VALUE))
|
||||||
char * valueCopy = malloc(strlen(state->token) + 1);
|
{
|
||||||
|
char *valueCopy = malloc(strlen(state->token) + 1);
|
||||||
|
|
||||||
strcpy(valueCopy, state->token);
|
strcpy(valueCopy, state->token);
|
||||||
free(HashMapSet(state->macroMap, name, state->token));
|
free(HashMapSet(state->macroMap, name, state->token));
|
||||||
ConfigTokenSeek(state);
|
ConfigTokenSeek(state);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ConfigExpect(state, TOKEN_SEMICOLON)) {
|
if (!ConfigExpect(state, TOKEN_SEMICOLON))
|
||||||
|
{
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
ConfigTokenSeek(state);
|
ConfigTokenSeek(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ConfigExpect(state, level ? TOKEN_BLOCK_CLOSE : TOKEN_EOF)) {
|
if (ConfigExpect(state, level ? TOKEN_BLOCK_CLOSE : TOKEN_EOF))
|
||||||
|
{
|
||||||
ConfigTokenSeek(state);
|
ConfigTokenSeek(state);
|
||||||
return block;
|
return block;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
/* Only free the very top level, because this will recurse */
|
/* Only free the very top level, because this will recurse */
|
||||||
if (!level) {
|
if (!level)
|
||||||
|
{
|
||||||
ConfigFree(block);
|
ConfigFree(block);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -438,10 +492,13 @@ ConfigParse(FILE * stream)
|
||||||
state = ConfigParserStateCreate(stream);
|
state = ConfigParserStateCreate(stream);
|
||||||
conf = ConfigParseBlock(state, 0);
|
conf = ConfigParseBlock(state, 0);
|
||||||
|
|
||||||
if (!conf) {
|
if (!conf)
|
||||||
|
{
|
||||||
result->ok = 0;
|
result->ok = 0;
|
||||||
result->data.lineNumber = state->line;
|
result->data.lineNumber = state->line;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
result->ok = 1;
|
result->ok = 1;
|
||||||
result->data.confMap = conf;
|
result->data.confMap = conf;
|
||||||
}
|
}
|
||||||
|
@ -449,4 +506,3 @@ ConfigParse(FILE * stream)
|
||||||
ConfigParserStateFree(state);
|
ConfigParserStateFree(state);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,14 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
typedef struct HashMapBucket {
|
typedef struct HashMapBucket
|
||||||
|
{
|
||||||
uint32_t hash;
|
uint32_t hash;
|
||||||
void *value;
|
void *value;
|
||||||
} HashMapBucket;
|
} HashMapBucket;
|
||||||
|
|
||||||
struct HashMap {
|
struct HashMap
|
||||||
|
{
|
||||||
size_t count;
|
size_t count;
|
||||||
size_t capacity;
|
size_t capacity;
|
||||||
HashMapBucket **entries;
|
HashMapBucket **entries;
|
||||||
|
@ -36,7 +38,7 @@ HashMapHashKey(const char *key)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
HashMapGrow(HashMap *map)
|
HashMapGrow(HashMap * map)
|
||||||
{
|
{
|
||||||
size_t oldCapacity;
|
size_t oldCapacity;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -100,6 +102,7 @@ HashMap *
|
||||||
HashMapCreate(void)
|
HashMapCreate(void)
|
||||||
{
|
{
|
||||||
HashMap *map = malloc(sizeof(HashMap));
|
HashMap *map = malloc(sizeof(HashMap));
|
||||||
|
|
||||||
if (!map)
|
if (!map)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -120,7 +123,7 @@ HashMapCreate(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
HashMapDelete(HashMap *map, const char *key)
|
HashMapDelete(HashMap * map, const char *key)
|
||||||
{
|
{
|
||||||
uint32_t hash;
|
uint32_t hash;
|
||||||
size_t index;
|
size_t index;
|
||||||
|
@ -155,7 +158,7 @@ HashMapDelete(HashMap *map, const char *key)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
HashMapFree(HashMap *map)
|
HashMapFree(HashMap * map)
|
||||||
{
|
{
|
||||||
if (map)
|
if (map)
|
||||||
{
|
{
|
||||||
|
@ -174,7 +177,7 @@ HashMapFree(HashMap *map)
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
HashMapGet(HashMap *map, const char *key)
|
HashMapGet(HashMap * map, const char *key)
|
||||||
{
|
{
|
||||||
uint32_t hash;
|
uint32_t hash;
|
||||||
size_t index;
|
size_t index;
|
||||||
|
@ -208,7 +211,7 @@ HashMapGet(HashMap *map, const char *key)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
HashMapIterate(HashMap *map, void (*iteratorFunc)(void *))
|
HashMapIterate(HashMap * map, void (*iteratorFunc) (void *))
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
@ -229,7 +232,7 @@ HashMapIterate(HashMap *map, void (*iteratorFunc)(void *))
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
HashMapMaxLoadSet(HashMap *map, float load)
|
HashMapMaxLoadSet(HashMap * map, float load)
|
||||||
{
|
{
|
||||||
if (!map)
|
if (!map)
|
||||||
{
|
{
|
||||||
|
@ -241,7 +244,7 @@ HashMapMaxLoadSet(HashMap *map, float load)
|
||||||
|
|
||||||
|
|
||||||
void *
|
void *
|
||||||
HashMapSet(HashMap *map, const char *key, void *value)
|
HashMapSet(HashMap * map, const char *key, void *value)
|
||||||
{
|
{
|
||||||
uint32_t hash;
|
uint32_t hash;
|
||||||
size_t index;
|
size_t index;
|
||||||
|
@ -288,6 +291,7 @@ HashMapSet(HashMap *map, const char *key, void *value)
|
||||||
if (bucket->hash == hash)
|
if (bucket->hash == hash)
|
||||||
{
|
{
|
||||||
void *oldValue = bucket->value;
|
void *oldValue = bucket->value;
|
||||||
|
|
||||||
bucket->value = value;
|
bucket->value = value;
|
||||||
return oldValue;
|
return oldValue;
|
||||||
}
|
}
|
||||||
|
@ -297,4 +301,3 @@ HashMapSet(HashMap *map, const char *key, void *value)
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
37
src/Log.c
37
src/Log.c
|
@ -8,7 +8,8 @@
|
||||||
|
|
||||||
#define LOG_TSBUFFER 64
|
#define LOG_TSBUFFER 64
|
||||||
|
|
||||||
struct LogConfig {
|
struct LogConfig
|
||||||
|
{
|
||||||
LogLevel level;
|
LogLevel level;
|
||||||
size_t indent;
|
size_t indent;
|
||||||
FILE *out;
|
FILE *out;
|
||||||
|
@ -17,7 +18,7 @@ struct LogConfig {
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
Log(LogConfig *config, LogLevel level, const char *msg, ...)
|
Log(LogConfig * config, LogLevel level, const char *msg,...)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int doColor;
|
int doColor;
|
||||||
|
@ -52,6 +53,7 @@ Log(LogConfig *config, LogLevel level, const char *msg, ...)
|
||||||
if (doColor)
|
if (doColor)
|
||||||
{
|
{
|
||||||
char *ansi;
|
char *ansi;
|
||||||
|
|
||||||
switch (level)
|
switch (level)
|
||||||
{
|
{
|
||||||
case LOG_ERROR:
|
case LOG_ERROR:
|
||||||
|
@ -140,10 +142,9 @@ Log(LogConfig *config, LogLevel level, const char *msg, ...)
|
||||||
fputc('\n', config->out);
|
fputc('\n', config->out);
|
||||||
va_end(argp);
|
va_end(argp);
|
||||||
|
|
||||||
/* If we are debugging, there might be something that's
|
/* If we are debugging, there might be something that's going to
|
||||||
* going to segfault the program coming up, so flush the
|
* segfault the program coming up, so flush the output stream
|
||||||
* output stream immediately.
|
* immediately. */
|
||||||
*/
|
|
||||||
if (config->level == LOG_DEBUG)
|
if (config->level == LOG_DEBUG)
|
||||||
{
|
{
|
||||||
fflush(config->out);
|
fflush(config->out);
|
||||||
|
@ -172,7 +173,7 @@ LogConfigCreate(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LogConfigFlagClear(LogConfig *config, int flags)
|
LogConfigFlagClear(LogConfig * config, int flags)
|
||||||
{
|
{
|
||||||
if (!config)
|
if (!config)
|
||||||
{
|
{
|
||||||
|
@ -183,7 +184,7 @@ LogConfigFlagClear(LogConfig *config, int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
LogConfigFlagGet(LogConfig *config, int flags)
|
LogConfigFlagGet(LogConfig * config, int flags)
|
||||||
{
|
{
|
||||||
if (!config)
|
if (!config)
|
||||||
{
|
{
|
||||||
|
@ -194,7 +195,7 @@ LogConfigFlagGet(LogConfig *config, int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LogConfigFlagSet(LogConfig *config, int flags)
|
LogConfigFlagSet(LogConfig * config, int flags)
|
||||||
{
|
{
|
||||||
if (!config)
|
if (!config)
|
||||||
{
|
{
|
||||||
|
@ -205,13 +206,13 @@ LogConfigFlagSet(LogConfig *config, int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LogConfigFree(LogConfig *config)
|
LogConfigFree(LogConfig * config)
|
||||||
{
|
{
|
||||||
free(config);
|
free(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LogConfigIndent(LogConfig *config)
|
LogConfigIndent(LogConfig * config)
|
||||||
{
|
{
|
||||||
if (config)
|
if (config)
|
||||||
{
|
{
|
||||||
|
@ -220,7 +221,7 @@ LogConfigIndent(LogConfig *config)
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
LogConfigIndentGet(LogConfig *config)
|
LogConfigIndentGet(LogConfig * config)
|
||||||
{
|
{
|
||||||
if (!config)
|
if (!config)
|
||||||
{
|
{
|
||||||
|
@ -231,7 +232,7 @@ LogConfigIndentGet(LogConfig *config)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LogConfigIndentSet(LogConfig *config, size_t indent)
|
LogConfigIndentSet(LogConfig * config, size_t indent)
|
||||||
{
|
{
|
||||||
if (!config)
|
if (!config)
|
||||||
{
|
{
|
||||||
|
@ -242,7 +243,7 @@ LogConfigIndentSet(LogConfig *config, size_t indent)
|
||||||
}
|
}
|
||||||
|
|
||||||
LogLevel
|
LogLevel
|
||||||
LogConfigLevelGet(LogConfig *config)
|
LogConfigLevelGet(LogConfig * config)
|
||||||
{
|
{
|
||||||
if (!config)
|
if (!config)
|
||||||
{
|
{
|
||||||
|
@ -253,7 +254,7 @@ LogConfigLevelGet(LogConfig *config)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LogConfigLevelSet(LogConfig *config, LogLevel level)
|
LogConfigLevelSet(LogConfig * config, LogLevel level)
|
||||||
{
|
{
|
||||||
if (!config)
|
if (!config)
|
||||||
{
|
{
|
||||||
|
@ -273,7 +274,7 @@ LogConfigLevelSet(LogConfig *config, LogLevel level)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LogConfigOutputSet(LogConfig *config, FILE *out)
|
LogConfigOutputSet(LogConfig * config, FILE * out)
|
||||||
{
|
{
|
||||||
if (!config)
|
if (!config)
|
||||||
{
|
{
|
||||||
|
@ -292,7 +293,7 @@ LogConfigOutputSet(LogConfig *config, FILE *out)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LogConfigTimeStampFormatSet(LogConfig *config, char *tsFmt)
|
LogConfigTimeStampFormatSet(LogConfig * config, char *tsFmt)
|
||||||
{
|
{
|
||||||
if (config)
|
if (config)
|
||||||
{
|
{
|
||||||
|
@ -301,7 +302,7 @@ LogConfigTimeStampFormatSet(LogConfig *config, char *tsFmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LogConfigUnindent(LogConfig *config)
|
LogConfigUnindent(LogConfig * config)
|
||||||
{
|
{
|
||||||
if (config && config->indent >= 2)
|
if (config && config->indent >= 2)
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,7 +15,7 @@ typedef enum ArgFlag
|
||||||
} ArgFlag;
|
} ArgFlag;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
TelodendriaPrintHeader(LogConfig *lc)
|
TelodendriaPrintHeader(LogConfig * lc)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_MESSAGE,
|
Log(lc, LOG_MESSAGE,
|
||||||
" _____ _ _ _ _");
|
" _____ _ _ _ _");
|
||||||
|
@ -37,7 +37,7 @@ TelodendriaPrintHeader(LogConfig *lc)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
TelodendriaPrintUsage(LogConfig *lc)
|
TelodendriaPrintUsage(LogConfig * lc)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_MESSAGE, "Usage:");
|
Log(lc, LOG_MESSAGE, "Usage:");
|
||||||
Log(lc, LOG_MESSAGE, " -c <file> Configuration file ('-' for stdin).");
|
Log(lc, LOG_MESSAGE, " -c <file> Configuration file ('-' for stdin).");
|
||||||
|
@ -45,7 +45,8 @@ TelodendriaPrintUsage(LogConfig *lc)
|
||||||
Log(lc, LOG_MESSAGE, " -h Print this usage, then exit.");
|
Log(lc, LOG_MESSAGE, " -h Print this usage, then exit.");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
LogConfig *lc;
|
LogConfig *lc;
|
||||||
int exit = EXIT_SUCCESS;
|
int exit = EXIT_SUCCESS;
|
||||||
|
|
Loading…
Reference in a new issue