Browse Source

add new example of a (simple & not so safe) dictionary implementation from chapter 11

master
T. Meissner 9 years ago
parent
commit
95af873851
6 changed files with 192 additions and 1 deletions
  1. +5
    -1
      21st_century_c/chapter11/Makefile
  2. +84
    -0
      21st_century_c/chapter11/dict.c
  3. +17
    -0
      21st_century_c/chapter11/dict.h
  4. +23
    -0
      21st_century_c/chapter11/dict_use.c
  5. +53
    -0
      21st_century_c/chapter11/keyval.c
  6. +10
    -0
      21st_century_c/chapter11/keyval.h

+ 5
- 1
21st_century_c/chapter11/Makefile View File

@ -1,4 +1,4 @@
CFLAGS = -Wall -O3 --std=c11
CFLAGS = -Wall -O0 --std=c11 -g
simple_cplx : cplx.h complex.c simple_cplx.c
@ -10,6 +10,9 @@ seamlessone : seamlessone.c
seamlesstwo : seamlesstwo.c
$(CC) $(CFLAGS) -fms-extensions -Wno-microsoft $@.c -o $@
dict_use : keyval.h keyval.c dict.h dict.c dict_use.c
$(CC) $(CFLAGS) keyval.c dict.c $@.c -o $@
.PHONY : all
all : simple_cplx seamlessone seamlesstwo
@ -23,4 +26,5 @@ clean :
rm -f simple_cplx
rm -f seamlessone
rm -f seamlesstwo
rm -f dict_use
rm -rf *.dSYM

+ 84
- 0
21st_century_c/chapter11/dict.c View File

@ -0,0 +1,84 @@
#include <stdio.h>
#include <stdlib.h>
#include "dict.h"
void *dictionary_not_found;
dictionary *dictionary_new(void) {
static int dnf;
if (!dictionary_not_found) {
dictionary_not_found = &dnf;
}
dictionary *out = malloc(sizeof(dictionary));
if(out != NULL) {
*out = (dictionary) {};
} else {
fprintf(stderr, "Out of memory.\n");
abort();
}
return out;
}
static void dictionary_add_keyval(dictionary *in, keyval *kv) {
in->length++;
in->pairs = realloc(in->pairs, sizeof(keyval*) * in->length);
if(in->pairs != NULL) {
in->pairs[in->length-1] = kv;
} else {
fprintf(stderr, "Out of memory.\n");
abort();
}
}
void dictionary_add(dictionary *in, char *key, void *value) {
if(key == NULL) {
fprintf(stderr, "NULL is not a valid key.\n");
abort();
}
dictionary_add_keyval(in, keyval_new(key, value));
}
void *dictionary_find(const dictionary *in, const char *key) {
for (size_t i = 0; i < in->length; i++) {
if (keyval_matches(in->pairs[i], key)) {
return in->pairs[i]->value;
}
}
return dictionary_not_found;
}
dictionary *dictionary_copy(dictionary *in) {
dictionary *out = dictionary_new();
for (size_t i = 0; i < in->length; i++) {
dictionary_add_keyval(out, keyval_copy(in->pairs[i]));
}
return out;
}
void dictionary_free(dictionary *in) {
for (size_t i = 0; i < in->length; i++) {
keyval_free(in->pairs[i]);
}
free(in);
}

+ 17
- 0
21st_century_c/chapter11/dict.h View File

@ -0,0 +1,17 @@
#include "keyval.h"
extern void *dictionary_not_found;
typedef struct dictionary {
keyval **pairs;
size_t length;
} dictionary;
dictionary *dictionary_new(void);
dictionary *dictionary_copy(dictionary *in);
void dictionary_free(dictionary *in);
void dictionary_add(dictionary *in, char *key, void *value);
void *dictionary_find(const dictionary *in, const char *key);

+ 23
- 0
21st_century_c/chapter11/dict_use.c View File

@ -0,0 +1,23 @@
#include <stdio.h>
#include "dict.h"
int main() {
int zero = 0;
float one = 1.0;
char two[] = "two";
dictionary *d = dictionary_new();
dictionary_add(d, "an int", &zero);
dictionary_add(d, "a float", &one);
dictionary_add(d, "a string", &two);
printf("The integer I recorded was: %i\n", *(int*) dictionary_find(d, "an int"));
printf("The string I recorded was: %s\n", (char*) dictionary_find(d, "a string"));
dictionary_free(d);
}

+ 53
- 0
21st_century_c/chapter11/keyval.c View File

@ -0,0 +1,53 @@
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include "keyval.h"
/*
Create a new key/value pair.
*/
keyval *keyval_new(char *key, void *value) {
keyval *out = malloc(sizeof(keyval));
if(out != NULL) {
*out = (keyval){.key = key, .value = value};
} else {
fprintf(stderr, "Out of memory.\n");
abort();
}
return out;
}
/*
Copy a key/value pair. The new pair has pointers to
the values in the old pair, not copies of their data.
*/
keyval *keyval_copy(const keyval *in) {
keyval *out = malloc(sizeof(keyval));
if(out != NULL) {
*out = *in;
} else {
fprintf(stderr, "Out of memory.\n");
abort();
}
return out;
}
/*
Free a existing key/value pair.
*/
void keyval_free(keyval *in) {
if(in != NULL) {
free(in);
}
}
/*
Check if key of key/value pair matches given key.
*/
int keyval_matches(const keyval *in, const char *key) {
return !strcasecmp(in->key, key);
}

+ 10
- 0
21st_century_c/chapter11/keyval.h View File

@ -0,0 +1,10 @@
typedef struct keyval {
char *key;
void *value;
} keyval;
keyval *keyval_new(char *key, void *value);
keyval *keyval_copy(const keyval *in);
void keyval_free(keyval *in);
int keyval_matches(const keyval *in, const char *key);

Loading…
Cancel
Save