forked from Telodendria/Telodendria
Rework HashMapIterate to be more flexible.
We now get the keys, and we don't have to operate within the confines of a callback function.
This commit is contained in:
parent
580b036d26
commit
ace2682dec
5 changed files with 73 additions and 37 deletions
33
src/Config.c
33
src/Config.c
|
@ -91,15 +91,9 @@ ConfigChildrenGet(ConfigDirective * directive)
|
||||||
return directive ? directive->children : NULL;
|
return directive ? directive->children : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Takes a void pointer because it is only used with
|
|
||||||
* HashMapIterate(), which requires a pointer to a function
|
|
||||||
* that takes a void pointer.
|
|
||||||
*/
|
|
||||||
static void
|
static void
|
||||||
ConfigDirectiveFree(void *ptr)
|
ConfigDirectiveFree(ConfigDirective * directive)
|
||||||
{
|
{
|
||||||
ConfigDirective *directive = ptr;
|
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if (!directive)
|
if (!directive)
|
||||||
|
@ -113,6 +107,7 @@ ConfigDirectiveFree(void *ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayFree(directive->values);
|
ArrayFree(directive->values);
|
||||||
|
|
||||||
ConfigFree(directive->children);
|
ConfigFree(directive->children);
|
||||||
|
|
||||||
free(directive);
|
free(directive);
|
||||||
|
@ -121,7 +116,15 @@ ConfigDirectiveFree(void *ptr)
|
||||||
void
|
void
|
||||||
ConfigFree(HashMap * conf)
|
ConfigFree(HashMap * conf)
|
||||||
{
|
{
|
||||||
HashMapIterate(conf, ConfigDirectiveFree);
|
char *key;
|
||||||
|
void *value;
|
||||||
|
|
||||||
|
while (HashMapIterate(conf, &key, &value))
|
||||||
|
{
|
||||||
|
ConfigDirectiveFree((ConfigDirective *) value);
|
||||||
|
free(key);
|
||||||
|
}
|
||||||
|
|
||||||
HashMapFree(conf);
|
HashMapFree(conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,14 +159,23 @@ ConfigParserStateCreate(FILE * stream)
|
||||||
static void
|
static void
|
||||||
ConfigParserStateFree(ConfigParserState * state)
|
ConfigParserStateFree(ConfigParserState * state)
|
||||||
{
|
{
|
||||||
|
char *key;
|
||||||
|
void *value;
|
||||||
|
|
||||||
if (!state)
|
if (!state)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
free(state->token);
|
free(state->token);
|
||||||
|
|
||||||
HashMapIterate(state->macroMap, free);
|
while (HashMapIterate(state->macroMap, &key, &value))
|
||||||
|
{
|
||||||
|
free(key);
|
||||||
|
free(value);
|
||||||
|
}
|
||||||
|
|
||||||
HashMapFree(state->macroMap);
|
HashMapFree(state->macroMap);
|
||||||
|
|
||||||
free(state);
|
free(state);
|
||||||
|
@ -432,7 +444,6 @@ ConfigParseBlock(ConfigParserState * state, int level)
|
||||||
* NULL is sent to ConfigDirectiveFree(), making it a no-op.
|
* NULL is sent to ConfigDirectiveFree(), making it a no-op.
|
||||||
*/
|
*/
|
||||||
ConfigDirectiveFree(HashMapSet(block, name, directive));
|
ConfigDirectiveFree(HashMapSet(block, name, directive));
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (ConfigExpect(state, TOKEN_MACRO_ASSIGNMENT))
|
else if (ConfigExpect(state, TOKEN_MACRO_ASSIGNMENT))
|
||||||
{
|
{
|
||||||
|
@ -442,7 +453,7 @@ ConfigParseBlock(ConfigParserState * state, int level)
|
||||||
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, valueCopy));
|
||||||
ConfigTokenSeek(state);
|
ConfigTokenSeek(state);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -18,6 +18,7 @@ struct HashMap
|
||||||
HashMapBucket **entries;
|
HashMapBucket **entries;
|
||||||
|
|
||||||
float maxLoad;
|
float maxLoad;
|
||||||
|
size_t iterator;
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
|
@ -112,6 +113,7 @@ HashMapCreate(void)
|
||||||
map->maxLoad = 0.75;
|
map->maxLoad = 0.75;
|
||||||
map->count = 0;
|
map->count = 0;
|
||||||
map->capacity = 16;
|
map->capacity = 16;
|
||||||
|
map->iterator = 0;
|
||||||
|
|
||||||
map->entries = calloc(map->capacity, sizeof(HashMapBucket *));
|
map->entries = calloc(map->capacity, sizeof(HashMapBucket *));
|
||||||
if (!map->entries)
|
if (!map->entries)
|
||||||
|
@ -211,25 +213,37 @@ HashMapGet(HashMap * map, const char *key)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
HashMapIterate(HashMap * map, void (*iteratorFunc) (char *, void *))
|
HashMapIterate(HashMap * map, char **key, void **value)
|
||||||
{
|
{
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (!map)
|
if (!map)
|
||||||
{
|
{
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < map->capacity; i++)
|
if (map->iterator >= map->capacity)
|
||||||
{
|
{
|
||||||
HashMapBucket *bucket = map->entries[i];
|
map->iterator = 0;
|
||||||
|
*key = NULL;
|
||||||
|
*value = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (map->iterator < map->capacity)
|
||||||
|
{
|
||||||
|
HashMapBucket *bucket = map->entries[map->iterator];
|
||||||
|
|
||||||
|
map->iterator++;
|
||||||
|
|
||||||
if (bucket)
|
if (bucket)
|
||||||
{
|
{
|
||||||
iteratorFunc(bucket->key, bucket->value);
|
*key = bucket->key;
|
||||||
|
*value = bucket->value;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -304,3 +318,17 @@ HashMapSet(HashMap * map, char *key, void *value)
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HashMapIterateFree(char *key, void *value)
|
||||||
|
{
|
||||||
|
if (key)
|
||||||
|
{
|
||||||
|
free(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
free(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -127,9 +127,13 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
Log(lc, LOG_MESSAGE, "Using configuration file '%s'.", configArg);
|
Log(lc, LOG_MESSAGE, "Using configuration file '%s'.", configArg);
|
||||||
|
|
||||||
|
Log(lc, LOG_DEBUG, "Executing ConfigParse()");
|
||||||
|
|
||||||
/* Read config here */
|
/* Read config here */
|
||||||
configParseResult = ConfigParse(configFile);
|
configParseResult = ConfigParse(configFile);
|
||||||
|
|
||||||
|
Log(lc, LOG_DEBUG, "Exitting ConfigParse()");
|
||||||
|
|
||||||
if (!ConfigParseResultOk(configParseResult))
|
if (!ConfigParseResultOk(configParseResult))
|
||||||
{
|
{
|
||||||
Log(lc, LOG_ERROR, "Syntax error on line %d.",
|
Log(lc, LOG_ERROR, "Syntax error on line %d.",
|
||||||
|
|
|
@ -69,8 +69,8 @@ extern void *
|
||||||
extern void *
|
extern void *
|
||||||
HashMapDelete(HashMap * map, const char *key);
|
HashMapDelete(HashMap * map, const char *key);
|
||||||
|
|
||||||
extern void
|
extern int
|
||||||
HashMapIterate(HashMap * map, void (*iteratorFunc) (char *, void *));
|
HashMapIterate(HashMap * map, char **key, void **value);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HashMapFree: Free the hash map, returning its memory to the operating
|
* HashMapFree: Free the hash map, returning its memory to the operating
|
||||||
|
@ -80,6 +80,6 @@ extern void
|
||||||
* free the values using your own algorithm.
|
* free the values using your own algorithm.
|
||||||
*/
|
*/
|
||||||
extern void
|
extern void
|
||||||
HashMapFree(HashMap * map);
|
HashMapFree(HashMap *);
|
||||||
|
|
||||||
#endif /* TELODENDRIA_HASHMAP_H */
|
#endif /* TELODENDRIA_HASHMAP_H */
|
||||||
|
|
|
@ -4,6 +4,9 @@
|
||||||
#include <HashMap.h>
|
#include <HashMap.h>
|
||||||
#include <Array.h>
|
#include <Array.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
typedef enum JsonType
|
typedef enum JsonType
|
||||||
{
|
{
|
||||||
JSON_OBJECT,
|
JSON_OBJECT,
|
||||||
|
@ -15,20 +18,7 @@ typedef enum JsonType
|
||||||
JSON_NULL
|
JSON_NULL
|
||||||
} JsonType;
|
} JsonType;
|
||||||
|
|
||||||
typedef struct JsonValue
|
typedef struct JsonValue JsonValue;
|
||||||
{
|
|
||||||
JsonType type;
|
|
||||||
union as
|
|
||||||
{
|
|
||||||
HashMap *object;
|
|
||||||
Array *array;
|
|
||||||
char *string;
|
|
||||||
int64_t integer;
|
|
||||||
double floating;
|
|
||||||
int boolean:1;
|
|
||||||
};
|
|
||||||
} JsonValue;
|
|
||||||
|
|
||||||
|
|
||||||
extern JsonType
|
extern JsonType
|
||||||
JsonValueType(JsonValue * value);
|
JsonValueType(JsonValue * value);
|
||||||
|
@ -60,9 +50,12 @@ extern JsonValue *
|
||||||
extern JsonValue *
|
extern JsonValue *
|
||||||
JsonValueNull(void);
|
JsonValueNull(void);
|
||||||
|
|
||||||
extern void *
|
extern void
|
||||||
JsonValueFree(JsonValue * value);
|
JsonValueFree(JsonValue * value);
|
||||||
|
|
||||||
|
extern void
|
||||||
|
JsonFree(HashMap * object);
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
JsonEncode(HashMap * object, FILE * out);
|
JsonEncode(HashMap * object, FILE * out);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue