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:
Jordan Bancino 2022-07-25 21:31:09 -04:00
parent 580b036d26
commit ace2682dec
5 changed files with 73 additions and 37 deletions

View file

@ -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

View file

@ -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);
}
}

View file

@ -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.",

View file

@ -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 */

View file

@ -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);