summaryrefslogtreecommitdiff
path: root/src/data/map.c
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2010-05-09 09:30:29 +0000
committerPaul Buetow <paul@buetow.org>2010-05-09 09:30:29 +0000
commita90467d4be3bcf91cab299b4521bf5f762abb1d5 (patch)
tree5171d406e6be467807a914ce42923ac997d74858 /src/data/map.c
added the scheme branch
Diffstat (limited to 'src/data/map.c')
-rw-r--r--src/data/map.c289
1 files changed, 289 insertions, 0 deletions
diff --git a/src/data/map.c b/src/data/map.c
new file mode 100644
index 0000000..3c95dc2
--- /dev/null
+++ b/src/data/map.c
@@ -0,0 +1,289 @@
+/*:*
+ *: File: ./src/data/map.c
+ *: A simple Fype interpreter
+ *:
+ *: WWW: http://fype.buetow.org
+ *: AUTHOR: http://paul.buetow.org
+ *: E-Mail: fype at dev.buetow.org
+ *:
+ *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow
+ *:
+ *: Redistribution and use in source and binary forms, with or without modi-
+ *: fication, are permitted provided that the following conditions are met:
+ *: * Redistributions of source code must retain the above copyright
+ *: notice, this list of conditions and the following disclaimer.
+ *: * Redistributions in binary form must reproduce the above copyright
+ *: notice, this list of conditions and the following disclaimer in the
+ *: documentation and/or other materials provided with the distribution.
+ *: * Neither the name of buetow.org nor the names of its contributors may
+ *: be used to endorse or promote products derived from this software
+ *: without specific prior written permission.
+ *:
+ *: THIS SOFTWARE IS PROVIDED BY PAUL C. BUETOW AS IS'' AND ANY EXPRESS OR
+ *: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *: WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *: DISCLAIMED. IN NO EVENT SHALL PAUL C. BUETOW BE LIABLE FOR ANY DIRECT,
+ *: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ *: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ *: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ *: IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *: POSSIBILITY OF SUCH DAMAGE.
+ *:*/
+
+#include "map.h"
+
+Map*
+map_new(int i_max_size) {
+ return (map_new_named(i_max_size, "noname"));
+}
+
+Map*
+map_new_named(int i_max_size, char *c_name) {
+ Map *p_map = malloc(sizeof(Map));
+
+ p_map->c_name = c_name;
+ p_map->pc_keys = calloc(i_max_size, sizeof(char*));
+ p_map->pp_vals = calloc(i_max_size, sizeof(void*));
+
+ for (int i = 0; i < i_max_size; ++i) {
+ p_map->pc_keys[i] = NULL;
+ p_map->pp_vals[i] = NULL;
+ }
+
+ p_map->i_size = 0;
+ p_map->i_max_size = i_max_size;
+
+ return (p_map);
+}
+
+_Bool
+map_empty(Map *p_map) {
+ return (p_map->i_size == 0);
+}
+
+_Bool
+map_full(Map *p_map) {
+ return (p_map->i_size == p_map->i_max_size);
+}
+
+int
+map_next_free_addr(Map *p_map) {
+ for (int i = 0; i < p_map->i_max_size; ++i)
+ if (p_map->pc_keys[i] == NULL)
+ return (i);
+
+ ERROR("No free space left in the map (%s)", p_map->c_name);
+
+ // This point should not be reached!
+ return (0);
+}
+
+_Bool
+map_insert(Map *p_map, char *c_key, void *p_val) {
+ int i_free_addr = map_next_free_addr(p_map);
+ int i_len = strlen(c_key);
+
+ p_map->pc_keys[i_free_addr] = STR_NEW(i_len+1);
+ strncpy(p_map->pc_keys[i_free_addr], c_key, i_len);
+ p_map->pp_vals[i_free_addr] = p_val;
+
+ ++p_map->i_size;
+ return (true);
+}
+
+_Bool
+map_insert2(Map *p_map, char *c_key1, char *c_key2, void *p_val) {
+ char c_key[HASH_MKEYLEN];
+ sprintf(c_key, "%s%s%s", c_key1, SEP, c_key2);
+ return (map_insert(p_map, c_key, p_val));
+}
+
+_Bool
+map_insert_if_not_exists(Map *p_map, char *c_key, void *p_val) {
+ void *p_void = map_get(p_map, c_key);
+
+ if (p_void)
+ return (false);
+
+ return (map_insert(p_map, c_key, p_val));
+
+ return (true);
+}
+
+void
+map_remove(Map *p_map, char *c_key) {
+ if (map_empty(p_map))
+ return;
+
+ int i_index = map_get_addr(p_map, c_key);
+ if (i_index < 0)
+ return;
+
+ free(p_map->pc_keys[i_index]);
+ p_map->pc_keys[i_index] = NULL;
+ p_map->pp_vals[i_index] = NULL;
+ --p_map->i_size;
+}
+
+void*
+map_get(Map *p_map, char *c_key) {
+ if (map_empty(p_map))
+ return (NULL);
+
+ int i_index = map_get_addr(p_map, c_key);
+ return (i_index >= 0 ? p_map->pp_vals[i_index] : NULL);
+}
+
+void*
+map_get2(Map *p_map, char *c_key1, char *c_key2) {
+ char c_key[HASH_MKEYLEN];
+ sprintf(c_key, "%s%s%s", c_key1, SEP, c_key2);
+ return (map_get(p_map, c_key));
+}
+
+
+_Bool
+map_exists(Map *p_map, char *c_key) {
+ if (map_empty(p_map))
+ return (false);
+
+ int i_index = map_get_addr(p_map, c_key);
+ return (i_index >= 0 ? true : false);
+}
+
+_Bool
+map_exists2(Map *p_map, char *c_key1, char *c_key2) {
+ if (map_empty(p_map))
+ return (false);
+
+ char c_key[HASH_MKEYLEN];
+ sprintf(c_key, "%s%s%s:", c_key1, SEP, c_key2);
+
+ int i_index = map_get_addr(p_map, c_key);
+ return i_index >= 0 ? true : false;
+}
+
+char*
+map_get_key(Map *p_map, void *p_val) {
+ if (map_empty(p_map))
+ return (NULL);
+
+ for (int i = 0; i < p_map->i_max_size; ++i)
+ if ((unsigned) p_map->pp_vals[i] == (unsigned) p_val)
+ return (p_map->pc_keys[i]);
+
+ return (NULL);
+}
+
+int
+map_get_addr(Map *p_map, char *c_key) {
+ if (map_empty(p_map))
+ return (-1);
+
+ for (int i = 0; i < p_map->i_max_size; ++i)
+ if (p_map->pc_keys[i] != NULL && strcmp(p_map->pc_keys[i], c_key) == 0)
+ return (i);
+
+ return (-1);
+}
+
+void
+map_clear(Map *p_map) {
+ for (int i = 0; i < p_map->i_max_size; ++i)
+ if (p_map->pc_keys[i] != NULL) {
+ free(p_map->pc_keys[i]);
+ p_map->pc_keys[i] = NULL;
+ p_map->pp_vals[i] = NULL;
+ }
+
+ p_map->i_size = 0;
+}
+
+void
+map_clear_and_free_vals(Map *p_map) {
+ for (int i = 0; i < p_map->i_max_size; ++i)
+ if (p_map->pc_keys[i] != NULL) {
+ free(p_map->pc_keys[i]);
+
+ if (p_map->pp_vals[i])
+ free(p_map->pp_vals[i]);
+
+ p_map->pc_keys[i] = NULL;
+ p_map->pp_vals[i] = NULL;
+ }
+
+ p_map->i_size = 0;
+}
+
+void
+map_delete(Map *p_map) {
+ map_clear(p_map);
+ free(p_map);
+}
+
+void
+map_delete_and_free_vals(Map *p_map) {
+ map_clear_and_free_vals(p_map);
+ free(p_map);
+}
+
+void
+map_print(Map *p_map) {
+ printf("Map<size=%d, max_size=%d>:",
+ map_get_size(p_map), map_get_max_size(p_map));
+ for (int i = 0; i < p_map->i_max_size; ++i)
+ if (p_map->pc_keys[i] != NULL)
+ printf("(%d,%s)", i, p_map->pc_keys[i]);
+ puts("");
+}
+
+void
+map_iterate(Map *p_map, void (*func) (void *)) {
+ for (int i = 0; i < p_map->i_max_size; ++i)
+ if (p_map->pc_keys[i] != NULL)
+ (*func) (p_map->pp_vals[i]);
+}
+
+void
+map_iterate_keys(Map *p_map, void (*func) (void *, char *)) {
+ for (int i = 0; i < p_map->i_max_size; ++i)
+ if (p_map->pc_keys[i] != NULL)
+ (*func) (p_map->pp_vals[i], p_map->pc_keys[i]);
+}
+
+void
+map_iterate2(Map *p_map, void (*func) (void *, void *), void *p_void) {
+ for (int i = 0; i < p_map->i_max_size; ++i)
+ if (p_map->pc_keys[i] != NULL)
+ (*func) (p_map->pp_vals[i], p_void);
+}
+
+void
+map_iterate2_keys(Map *p_map,
+ void (*func) (void *, void *, char *),
+ void *p_void) {
+ for (int i = 0; i < p_map->i_max_size; ++i)
+ if (p_map->pc_keys[i] != NULL)
+ (*func) (p_map->pp_vals[i], p_void, p_map->pc_keys[i]);
+}
+
+void
+map_iterate3(Map *p_map,
+ void (*func) (void *, void *, void *),
+ void *p_void1, void *p_void2) {
+ for (int i = 0; i < p_map->i_max_size; ++i)
+ if (p_map->pc_keys[i] != NULL)
+ (*func) (p_map->pp_vals[i], p_void1, p_void2);
+}
+
+void
+map_iterate3_keys(Map *p_map,
+ void (*func) (void *, void *, void *, char *),
+ void *p_void1, void *p_void2) {
+ for (int i = 0; i < p_map->i_max_size; ++i)
+ if (p_map->pc_keys[i] != NULL)
+ (*func) (p_map->pp_vals[i], p_void1, p_void2, p_map->pc_keys[i]);
+}
+