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;
}
/*
* 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

View file

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

View file

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

View file

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

View file

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