/
var_hash.c
150 lines (133 loc) · 3.17 KB
/
var_hash.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
// For ptrdiff_t related definitions
#include <stdint.h>
#include "var_hash.h"
var_hash*
var_hash_init ( void )
{
var_hash* hash = NULL;
var_elem* new_elem ;
new_elem = (var_elem*) malloc(sizeof(var_elem));
strncpy( new_elem->name , "_HEAD_OF_UTHASH_", MAX_KEY_LEN - 1) ;
new_elem->dummy = 1;
var_hash_insert(&hash, new_elem);
return hash;
}
var_elem*
var_hash_add_name (var_hash** hash, char* name)
{
if (strlen(name) >= MAX_KEY_LEN - 1){
printf("ERROR: Variable name is too long: %s \n", name);
}
var_elem* result = NULL;
result = var_hash_find(hash, name);
if(result == NULL){
var_elem* new_elem = (var_elem*) malloc(sizeof(var_elem));
strncpy( new_elem->name, name, MAX_KEY_LEN - 1) ;
new_elem->dummy = 0;
var_hash_insert(hash, new_elem);
// printf("%s added", new_elem->name);
return new_elem;
}else{
return result;
}
}
var_elem*
var_hash_insert (var_hash** hash, var_elem* new_elem )
{
HASH_ADD_STR(*hash, name, new_elem );
return new_elem ;
}
var_elem*
var_hash_find (var_hash** hash, char* name)
{
var_elem* temp;
HASH_FIND_STR(*hash, name, temp);
return temp;
}
unsigned int
var_hash_size (var_hash** hash)
{
unsigned int size = HASH_COUNT( *hash );
return ( size - 1 ); // -1 because there's one dummy element.
}
char**
var_hash_names(var_hash** hash)
{
unsigned int hash_size = var_hash_size(hash);
// printf("hash size: %d\n", hash_size);
if(hash_size == 0){
// printf("No variables.\n");
return NULL;
}
char** hash_names;
if( hash_size < (unsigned int) (PTRDIFF_MAX / (int) sizeof(char*))){
hash_names = (char**) malloc( hash_size * sizeof(char*));
}else {
printf("ERROR: hash size is too large");
return NULL;
}
unsigned int idx = 0;
var_elem* elem;
for( elem = *hash ; elem != NULL; elem = elem->hh.next) {
if( (elem->dummy) != 1 ){
char* new_str = (char*) malloc(sizeof(char) * MAX_KEY_LEN);
strncpy( new_str, elem->name , MAX_KEY_LEN );
new_str[MAX_KEY_LEN - 1] = '\0';
hash_names[idx] = new_str ;
idx = idx + 1;
}
if ( idx > hash_size ){
printf("ERROR: hash size and real hash size mismatch.\n");
}
}
return hash_names;
}
void
var_hash_names_free( char** hash_names, int size )
{
int idx;
char* name;
for(idx = 0 ; idx < size ; ++idx){
name = hash_names[idx];
free(name);
}
free(hash_names);
}
void
var_hash_print_names(var_hash** hash)
{
printf("printing names in hash....\n");
char** names = var_hash_names(hash);
unsigned int size = var_hash_size(hash);
unsigned int idx;
for(idx = 0; idx < size; ++idx){
printf("%s \n", names[idx]);
}
var_hash_names_free(names, size);
}
void
var_hash_free(var_hash** hash){
var_elem* elem;
var_elem* temp;
/* When deleting elements of UTHASH, use both HASH_DEL() and free(). */
/* Without HASH_DEL(), some memory leak happens*/
HASH_ITER(hh, *hash, elem, temp) {
// printf("Delete %s\n", elem->name );
HASH_DEL(*hash, elem);
free(elem); /* Free structure & memory */
}
}
/*
int
main(int argc, char** argv)
{
var_hash* hash = var_hash_init ();
var_hash_add_name (&hash, "Hello1");
var_hash_add_name (&hash, "Hello2");
var_hash_print_names( &hash);
var_hash_free(&hash);
}
*/