geany  1.38
About: Geany is a text editor (using GTK2) with basic features of an integrated development environment (syntax highlighting, code folding, symbol name auto-completion, ...). F: office T: editor programming GTK+ IDE
  Fossies Dox: geany-1.38.tar.bz2  ("unofficial" and yet experimental doxygen-generated source code documentation)  

keyword.c
Go to the documentation of this file.
1/*
2* Copyright (c) 1998-2002, Darren Hiebert
3*
4* This source code is released for free distribution under the terms of the
5* GNU General Public License version 2 or (at your option) any later version.
6*
7* Manages a keyword hash.
8*/
9
10/*
11* INCLUDE FILES
12*/
13#include "general.h" /* must always come first */
14
15#include <string.h>
16#include <ctype.h>
17
18#include "debug.h"
19#include "keyword.h"
20#include "keyword_p.h"
21#include "parse.h"
22#include "routines.h"
23
24/*
25* DATA DECLARATIONS
26*/
27typedef struct sHashEntry {
29 const char *string;
31 int value;
33
34/*
35* DATA DEFINITIONS
36*/
37static const unsigned int TableSize = 2039; /* prime */
39
40/*
41* FUNCTION DEFINITIONS
42*/
43
44static hashEntry **getHashTable (void)
45{
46 static bool allocated = false;
47
48 if (! allocated)
49 {
50 unsigned int i;
51
53
54 for (i = 0 ; i < TableSize ; ++i)
55 HashTable [i] = NULL;
56
57 allocated = true;
58 }
59 return HashTable;
60}
61
62static hashEntry *getHashTableEntry (unsigned long hashedValue)
63{
64 hashEntry **const table = getHashTable ();
66
67 Assert (hashedValue < TableSize);
68 entry = table [hashedValue];
69
70 return entry;
71}
72
73static unsigned int hashValue (const char *const string, langType language)
74{
75 const signed char *p;
76 unsigned int h = 5381;
77
78 Assert (string != NULL);
79
80 /* "djb" hash as used in g_str_hash() in glib */
81 for (p = (const signed char *)string; *p != '\0'; p++)
82 h = (h << 5) + h + tolower (*p);
83
84 /* consider language as an extra "character" and add it to the hash */
85 h = (h << 5) + h + language;
86
87 return h;
88}
89
91 const char *const string, langType language, int value)
92{
93 hashEntry *const entry = xMalloc (1, hashEntry);
94
95 entry->next = NULL;
96 entry->string = string;
97 entry->language = language;
98 entry->value = value;
99
100 return entry;
101}
102
103/* Note that it is assumed that a "value" of zero means an undefined keyword
104 * and clients of this function should observe this. Also, all keywords added
105 * should be added in lower case. If we encounter a case-sensitive language
106 * whose keywords are in upper case, we will need to redesign this.
107 */
108extern void addKeyword (const char *const string, langType language, int value)
109{
110 const unsigned int index = hashValue (string, language) % TableSize;
112
113 if (entry == NULL)
114 {
115 hashEntry **const table = getHashTable ();
116 table [index] = newEntry (string, language, value);
117 }
118 else
119 {
120 hashEntry *prev = NULL;
121
122 while (entry != NULL)
123 {
124 if (language == entry->language &&
125 strcmp (string, entry->string) == 0)
126 {
127 Assert (("Already in table" == NULL));
128 }
129 prev = entry;
130 entry = entry->next;
131 }
132 if (entry == NULL)
133 {
134 Assert (prev != NULL);
135 prev->next = newEntry (string, language, value);
136 }
137 }
138}
139
140static int lookupKeywordFull (const char *const string, bool caseSensitive, langType language)
141{
142 const unsigned int index = hashValue (string, language) % TableSize;
144 int result = KEYWORD_NONE;
145
146 while (entry != NULL)
147 {
148 if (language == entry->language &&
149 ((caseSensitive && strcmp (string, entry->string) == 0) ||
150 (!caseSensitive && strcasecmp (string, entry->string) == 0)))
151 {
152 result = entry->value;
153 break;
154 }
155 entry = entry->next;
156 }
157 return result;
158}
159
160extern int lookupKeyword (const char *const string, langType language)
161{
162 return lookupKeywordFull (string, true, language);
163}
164
165extern int lookupCaseKeyword (const char *const string, langType language)
166{
167 return lookupKeywordFull (string, false, language);
168}
169
170extern void freeKeywordTable (void)
171{
172 if (HashTable != NULL)
173 {
174 unsigned int i;
175
176 for (i = 0 ; i < TableSize ; ++i)
177 {
179
180 while (entry != NULL)
181 {
182 hashEntry *next = entry->next;
183 eFree (entry);
184 entry = next;
185 }
186 }
188 }
189}
190
191#ifdef DEBUG
192
193static void printEntry (const hashEntry *const entry)
194{
195 printf (" %-15s %-7s\n", entry->string, getLanguageName (entry->language));
196}
197
198static unsigned int printBucket (const unsigned int i)
199{
200 hashEntry **const table = getHashTable ();
201 hashEntry *entry = table [i];
202 unsigned int measure = 1;
203 bool first = true;
204
205 printf ("%2d:", i);
206 if (entry == NULL)
207 printf ("\n");
208 else while (entry != NULL)
209 {
210 if (! first)
211 printf (" ");
212 else
213 {
214 printf (" ");
215 first = false;
216 }
217 printEntry (entry);
218 entry = entry->next;
219 measure = 2 * measure;
220 }
221 return measure - 1;
222}
223
224extern void printKeywordTable (void)
225{
226 unsigned long emptyBucketCount = 0;
227 unsigned long measure = 0;
228 unsigned int i;
229
230 for (i = 0 ; i < TableSize ; ++i)
231 {
232 const unsigned int pass = printBucket (i);
233
234 measure += pass;
235 if (pass == 0)
236 ++emptyBucketCount;
237 }
238
239 printf ("spread measure = %ld\n", measure);
240 printf ("%ld empty buckets\n", emptyBucketCount);
241}
242
243#endif
244
245extern void dumpKeywordTable (FILE *fp)
246{
247 unsigned int i;
248 for (i = 0 ; i < TableSize ; ++i)
249 {
250 hashEntry **const table = getHashTable ();
251 hashEntry *entry = table [i];
252 while (entry != NULL)
253 {
254 fprintf(fp, "%s %s\n", entry->string, getLanguageName (entry->language));
255 entry = entry->next;
256 }
257 }
258}
259
260extern void addKeywordGroup (const struct keywordGroup *const groupdef,
262{
263 for (int i = 0; groupdef->keywords[i]; i++)
264 {
265 if (groupdef->addingUnlessExisting)
266 {
267 if (lookupKeyword (groupdef->keywords[i],
269 continue; /* already added */
270 }
271 else
272 Assert (lookupKeyword (groupdef->keywords[i],
274 addKeyword (groupdef->keywords[i], language, groupdef->value);
275 }
276}
gint index
Definition: build.c:2680
#define Assert(c)
Definition: debug.h:47
#define strcasecmp(s1, s2)
Definition: general.h:37
struct sHashEntry hashEntry
static hashEntry ** getHashTable(void)
Definition: keyword.c:44
int lookupCaseKeyword(const char *const string, langType language)
Definition: keyword.c:165
void addKeyword(const char *const string, langType language, int value)
Definition: keyword.c:108
static hashEntry * getHashTableEntry(unsigned long hashedValue)
Definition: keyword.c:62
static unsigned int hashValue(const char *const string, langType language)
Definition: keyword.c:73
static hashEntry ** HashTable
Definition: keyword.c:38
static int lookupKeywordFull(const char *const string, bool caseSensitive, langType language)
Definition: keyword.c:140
void addKeywordGroup(const struct keywordGroup *const groupdef, langType language)
Definition: keyword.c:260
static const unsigned int TableSize
Definition: keyword.c:37
static hashEntry * newEntry(const char *const string, langType language, int value)
Definition: keyword.c:90
int lookupKeyword(const char *const string, langType language)
Definition: keyword.c:160
void freeKeywordTable(void)
Definition: keyword.c:170
void dumpKeywordTable(FILE *fp)
Definition: keyword.c:245
#define KEYWORD_NONE
Definition: keyword.h:21
const char * getLanguageName(const langType language)
Definition: parse.c:284
#define NULL
Definition: rbtree.h:150
void eFree(void *const ptr)
Definition: routines.c:252
#define xMalloc(n, Type)
Definition: routines.h:23
GtkWidget * entry
Definition: search.c:118
int value
Definition: keyword.h:34
bool addingUnlessExisting
Definition: keyword.h:35
const char * keywords[]
Definition: keyword.h:36
int value
Definition: keyword.c:31
void * value
Definition: htable.c:37
struct sHashEntry * next
Definition: keyword.c:28
langType language
Definition: keyword.c:30
const char * string
Definition: keyword.c:29
hentry * next
Definition: htable.c:38
int langType
Definition: types.h:13