user_data: track user data across assignments
[smatch.git] / smatch_function_hashtable.h
blob0ccfc0ba5865629baf89c4818eb54f026028ad84
1 /*
2 * sparse/smatch_function_hashtable.c
4 * Copyright (C) 2010 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include "smatch.h"
14 #include "cwchash/hashtable.h"
16 static inline unsigned int djb2_hash(void *ky)
18 char *str = (char *)ky;
19 unsigned long hash = 5381;
20 int c;
22 while ((c = *str++))
23 hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
25 return hash;
28 static inline int equalkeys(void *k1, void *k2)
30 return !strcmp((char *)k1, (char *)k2);
33 #define DEFINE_FUNCTION_ADD_HOOK(_name, _item_type, _list_type) \
34 void add_##_name(struct hashtable *table, const char *look_for, _item_type *value) \
35 { \
36 _list_type *list; \
37 char *key; \
39 key = alloc_string(look_for); \
40 list = search_##_name(table, key); \
41 if (!list) { \
42 add_ptr_list(&list, value); \
43 } else { \
44 remove_##_name(table, key); \
45 add_ptr_list(&list, value); \
46 } \
47 insert_##_name(table, key, list); \
50 static inline struct hashtable *create_function_hashtable(int size)
52 return create_hashtable(size, djb2_hash, equalkeys);
55 static inline void destroy_function_hashtable(struct hashtable *table)
57 hashtable_destroy(table, 0);
60 #define DEFINE_FUNCTION_HASHTABLE(_name, _item_type, _list_type) \
61 DEFINE_HASHTABLE_INSERT(insert_##_name, char, _list_type); \
62 DEFINE_HASHTABLE_SEARCH(search_##_name, char, _list_type); \
63 DEFINE_HASHTABLE_REMOVE(remove_##_name, char, _list_type); \
64 DEFINE_FUNCTION_ADD_HOOK(_name, _item_type, _list_type);
66 #define DEFINE_FUNCTION_HASHTABLE_STATIC(_name, _item_type, _list_type) \
67 static DEFINE_HASHTABLE_INSERT(insert_##_name, char, _list_type); \
68 static DEFINE_HASHTABLE_SEARCH(search_##_name, char, _list_type); \
69 static DEFINE_HASHTABLE_REMOVE(remove_##_name, char, _list_type); \
70 static DEFINE_FUNCTION_ADD_HOOK(_name, _item_type, _list_type);
72 #define DEFINE_STRING_HASHTABLE_STATIC(_name) \
73 static DEFINE_HASHTABLE_INSERT(insert_##_name, char, int); \
74 static DEFINE_HASHTABLE_SEARCH(search_##_name, char, int); \
75 static struct hashtable *_name
77 static inline void load_hashtable_helper(const char *file, int (*insert_func)(struct hashtable *, char *, int *), struct hashtable *table)
79 char filename[256];
80 struct token *token;
81 char *name;
83 snprintf(filename, sizeof(filename), "%s.%s", option_project_str, file);
84 token = get_tokens_file(filename);
85 if (!token)
86 return;
87 if (token_type(token) != TOKEN_STREAMBEGIN)
88 return;
89 token = token->next;
90 while (token_type(token) != TOKEN_STREAMEND) {
91 if (token_type(token) != TOKEN_IDENT)
92 return;
93 name = alloc_string(show_ident(token->ident));
94 insert_func(table, name, (void *)1);
95 token = token->next;
97 clear_token_alloc();
100 #define load_strings(file, _table) load_hashtable_helper(file, insert_##_table, _table)