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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
ConfigDirectiveFree(void *ptr)
|
||||
ConfigDirectiveFree(ConfigDirective * directive)
|
||||
{
|
||||
ConfigDirective *directive = ptr;
|
||||
size_t i;
|
||||
|
||||
if (!directive)
|
||||
|
@ -113,6 +107,7 @@ ConfigDirectiveFree(void *ptr)
|
|||
}
|
||||
|
||||
ArrayFree(directive->values);
|
||||
|
||||
ConfigFree(directive->children);
|
||||
|
||||
free(directive);
|
||||
|
@ -121,7 +116,15 @@ ConfigDirectiveFree(void *ptr)
|
|||
void
|
||||
ConfigFree(HashMap * conf)
|
||||
{
|
||||
HashMapIterate(conf, ConfigDirectiveFree);
|
||||
char *key;
|
||||
void *value;
|
||||
|
||||
while (HashMapIterate(conf, &key, &value))
|
||||
{
|
||||
ConfigDirectiveFree((ConfigDirective *) value);
|
||||
free(key);
|
||||
}
|
||||
|
||||
HashMapFree(conf);
|
||||
}
|
||||
|
||||
|
@ -156,14 +159,23 @@ ConfigParserStateCreate(FILE * stream)
|
|||
static void
|
||||
ConfigParserStateFree(ConfigParserState * state)
|
||||
{
|
||||
char *key;
|
||||
void *value;
|
||||
|
||||
if (!state)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
free(state->token);
|
||||
|
||||
HashMapIterate(state->macroMap, free);
|
||||
while (HashMapIterate(state->macroMap, &key, &value))
|
||||
{
|
||||
free(key);
|
||||
free(value);
|
||||
}
|
||||
|
||||
HashMapFree(state->macroMap);
|
||||
|
||||
free(state);
|
||||
|
@ -432,7 +444,6 @@ ConfigParseBlock(ConfigParserState * state, int level)
|
|||
* NULL is sent to ConfigDirectiveFree(), making it a no-op.
|
||||
*/
|
||||
ConfigDirectiveFree(HashMapSet(block, name, directive));
|
||||
|
||||
}
|
||||
else if (ConfigExpect(state, TOKEN_MACRO_ASSIGNMENT))
|
||||
{
|
||||
|
@ -442,7 +453,7 @@ ConfigParseBlock(ConfigParserState * state, int level)
|
|||
char *valueCopy = malloc(strlen(state->token) + 1);
|
||||
|
||||
strcpy(valueCopy, state->token);
|
||||
free(HashMapSet(state->macroMap, name, state->token));
|
||||
free(HashMapSet(state->macroMap, name, valueCopy));
|
||||
ConfigTokenSeek(state);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -18,6 +18,7 @@ struct HashMap
|
|||
HashMapBucket **entries;
|
||||
|
||||
float maxLoad;
|
||||
size_t iterator;
|
||||
};
|
||||
|
||||
static uint32_t
|
||||
|
@ -112,6 +113,7 @@ HashMapCreate(void)
|
|||
map->maxLoad = 0.75;
|
||||
map->count = 0;
|
||||
map->capacity = 16;
|
||||
map->iterator = 0;
|
||||
|
||||
map->entries = calloc(map->capacity, sizeof(HashMapBucket *));
|
||||
if (!map->entries)
|
||||
|
@ -211,25 +213,37 @@ HashMapGet(HashMap * map, const char *key)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
HashMapIterate(HashMap * map, void (*iteratorFunc) (char *, void *))
|
||||
int
|
||||
HashMapIterate(HashMap * map, char **key, void **value)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
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)
|
||||
{
|
||||
iteratorFunc(bucket->key, bucket->value);
|
||||
*key = bucket->key;
|
||||
*value = bucket->value;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -304,3 +318,17 @@ HashMapSet(HashMap * map, char *key, void *value)
|
|||
|
||||
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_DEBUG, "Executing ConfigParse()");
|
||||
|
||||
/* Read config here */
|
||||
configParseResult = ConfigParse(configFile);
|
||||
|
||||
Log(lc, LOG_DEBUG, "Exitting ConfigParse()");
|
||||
|
||||
if (!ConfigParseResultOk(configParseResult))
|
||||
{
|
||||
Log(lc, LOG_ERROR, "Syntax error on line %d.",
|
||||
|
|
|
@ -69,8 +69,8 @@ extern void *
|
|||
extern void *
|
||||
HashMapDelete(HashMap * map, const char *key);
|
||||
|
||||
extern void
|
||||
HashMapIterate(HashMap * map, void (*iteratorFunc) (char *, void *));
|
||||
extern int
|
||||
HashMapIterate(HashMap * map, char **key, void **value);
|
||||
|
||||
/*
|
||||
* HashMapFree: Free the hash map, returning its memory to the operating
|
||||
|
@ -80,6 +80,6 @@ extern void
|
|||
* free the values using your own algorithm.
|
||||
*/
|
||||
extern void
|
||||
HashMapFree(HashMap * map);
|
||||
HashMapFree(HashMap *);
|
||||
|
||||
#endif /* TELODENDRIA_HASHMAP_H */
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
#include <HashMap.h>
|
||||
#include <Array.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
|
||||
typedef enum JsonType
|
||||
{
|
||||
JSON_OBJECT,
|
||||
|
@ -15,20 +18,7 @@ typedef enum JsonType
|
|||
JSON_NULL
|
||||
} JsonType;
|
||||
|
||||
typedef struct JsonValue
|
||||
{
|
||||
JsonType type;
|
||||
union as
|
||||
{
|
||||
HashMap *object;
|
||||
Array *array;
|
||||
char *string;
|
||||
int64_t integer;
|
||||
double floating;
|
||||
int boolean:1;
|
||||
};
|
||||
} JsonValue;
|
||||
|
||||
typedef struct JsonValue JsonValue;
|
||||
|
||||
extern JsonType
|
||||
JsonValueType(JsonValue * value);
|
||||
|
@ -60,9 +50,12 @@ extern JsonValue *
|
|||
extern JsonValue *
|
||||
JsonValueNull(void);
|
||||
|
||||
extern void *
|
||||
extern void
|
||||
JsonValueFree(JsonValue * value);
|
||||
|
||||
extern void
|
||||
JsonFree(HashMap * object);
|
||||
|
||||
extern int
|
||||
JsonEncode(HashMap * object, FILE * out);
|
||||
|
||||
|
|
Loading…
Reference in a new issue