aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/sqlite/unix/sqlite-3.5.1/tool/mkkeywordhash.c
diff options
context:
space:
mode:
authordan miller2007-10-20 02:49:29 +0000
committerdan miller2007-10-20 02:49:29 +0000
commite36d23a85ebff914d74bb541558c2b6082b78edb (patch)
tree54b58fdf162e78af64055282a6035c8d2443389d /libraries/sqlite/unix/sqlite-3.5.1/tool/mkkeywordhash.c
parent* Fixed an issue whereby avatar chat distances were being calculated against ... (diff)
downloadopensim-SC_OLD-e36d23a85ebff914d74bb541558c2b6082b78edb.zip
opensim-SC_OLD-e36d23a85ebff914d74bb541558c2b6082b78edb.tar.gz
opensim-SC_OLD-e36d23a85ebff914d74bb541558c2b6082b78edb.tar.bz2
opensim-SC_OLD-e36d23a85ebff914d74bb541558c2b6082b78edb.tar.xz
sqlite source (unix build) added to libraries
Diffstat (limited to 'libraries/sqlite/unix/sqlite-3.5.1/tool/mkkeywordhash.c')
-rw-r--r--libraries/sqlite/unix/sqlite-3.5.1/tool/mkkeywordhash.c559
1 files changed, 559 insertions, 0 deletions
diff --git a/libraries/sqlite/unix/sqlite-3.5.1/tool/mkkeywordhash.c b/libraries/sqlite/unix/sqlite-3.5.1/tool/mkkeywordhash.c
new file mode 100644
index 0000000..3a34224
--- /dev/null
+++ b/libraries/sqlite/unix/sqlite-3.5.1/tool/mkkeywordhash.c
@@ -0,0 +1,559 @@
1/*
2** Compile and run this standalone program in order to generate code that
3** implements a function that will translate alphabetic identifiers into
4** parser token codes.
5*/
6#include <stdio.h>
7#include <string.h>
8#include <stdlib.h>
9
10/*
11** A header comment placed at the beginning of generated code.
12*/
13static const char zHdr[] =
14 "/***** This file contains automatically generated code ******\n"
15 "**\n"
16 "** The code in this file has been automatically generated by\n"
17 "**\n"
18 "** $Header: /sqlite/sqlite/tool/mkkeywordhash.c,v 1.31 2007/07/30 18:26:20 rse Exp $\n"
19 "**\n"
20 "** The code in this file implements a function that determines whether\n"
21 "** or not a given identifier is really an SQL keyword. The same thing\n"
22 "** might be implemented more directly using a hand-written hash table.\n"
23 "** But by using this automatically generated code, the size of the code\n"
24 "** is substantially reduced. This is important for embedded applications\n"
25 "** on platforms with limited memory.\n"
26 "*/\n"
27;
28
29/*
30** All the keywords of the SQL language are stored as in a hash
31** table composed of instances of the following structure.
32*/
33typedef struct Keyword Keyword;
34struct Keyword {
35 char *zName; /* The keyword name */
36 char *zTokenType; /* Token value for this keyword */
37 int mask; /* Code this keyword if non-zero */
38 int id; /* Unique ID for this record */
39 int hash; /* Hash on the keyword */
40 int offset; /* Offset to start of name string */
41 int len; /* Length of this keyword, not counting final \000 */
42 int prefix; /* Number of characters in prefix */
43 int longestSuffix; /* Longest suffix that is a prefix on another word */
44 int iNext; /* Index in aKeywordTable[] of next with same hash */
45 int substrId; /* Id to another keyword this keyword is embedded in */
46 int substrOffset; /* Offset into substrId for start of this keyword */
47};
48
49/*
50** Define masks used to determine which keywords are allowed
51*/
52#ifdef SQLITE_OMIT_ALTERTABLE
53# define ALTER 0
54#else
55# define ALTER 0x00000001
56#endif
57#define ALWAYS 0x00000002
58#ifdef SQLITE_OMIT_ANALYZE
59# define ANALYZE 0
60#else
61# define ANALYZE 0x00000004
62#endif
63#ifdef SQLITE_OMIT_ATTACH
64# define ATTACH 0
65#else
66# define ATTACH 0x00000008
67#endif
68#ifdef SQLITE_OMIT_AUTOINCREMENT
69# define AUTOINCR 0
70#else
71# define AUTOINCR 0x00000010
72#endif
73#ifdef SQLITE_OMIT_CAST
74# define CAST 0
75#else
76# define CAST 0x00000020
77#endif
78#ifdef SQLITE_OMIT_COMPOUND_SELECT
79# define COMPOUND 0
80#else
81# define COMPOUND 0x00000040
82#endif
83#ifdef SQLITE_OMIT_CONFLICT_CLAUSE
84# define CONFLICT 0
85#else
86# define CONFLICT 0x00000080
87#endif
88#ifdef SQLITE_OMIT_EXPLAIN
89# define EXPLAIN 0
90#else
91# define EXPLAIN 0x00000100
92#endif
93#ifdef SQLITE_OMIT_FOREIGN_KEY
94# define FKEY 0
95#else
96# define FKEY 0x00000200
97#endif
98#ifdef SQLITE_OMIT_PRAGMA
99# define PRAGMA 0
100#else
101# define PRAGMA 0x00000400
102#endif
103#ifdef SQLITE_OMIT_REINDEX
104# define REINDEX 0
105#else
106# define REINDEX 0x00000800
107#endif
108#ifdef SQLITE_OMIT_SUBQUERY
109# define SUBQUERY 0
110#else
111# define SUBQUERY 0x00001000
112#endif
113#ifdef SQLITE_OMIT_TRIGGER
114# define TRIGGER 0
115#else
116# define TRIGGER 0x00002000
117#endif
118#if defined(SQLITE_OMIT_AUTOVACUUM) && \
119 (defined(SQLITE_OMIT_VACUUM) || defined(SQLITE_OMIT_ATTACH))
120# define VACUUM 0
121#else
122# define VACUUM 0x00004000
123#endif
124#ifdef SQLITE_OMIT_VIEW
125# define VIEW 0
126#else
127# define VIEW 0x00008000
128#endif
129#ifdef SQLITE_OMIT_VIRTUALTABLE
130# define VTAB 0
131#else
132# define VTAB 0x00010000
133#endif
134#ifdef SQLITE_OMIT_AUTOVACUUM
135# define AUTOVACUUM 0
136#else
137# define AUTOVACUUM 0x00020000
138#endif
139
140/*
141** These are the keywords
142*/
143static Keyword aKeywordTable[] = {
144 { "ABORT", "TK_ABORT", CONFLICT|TRIGGER },
145 { "ADD", "TK_ADD", ALTER },
146 { "AFTER", "TK_AFTER", TRIGGER },
147 { "ALL", "TK_ALL", ALWAYS },
148 { "ALTER", "TK_ALTER", ALTER },
149 { "ANALYZE", "TK_ANALYZE", ANALYZE },
150 { "AND", "TK_AND", ALWAYS },
151 { "AS", "TK_AS", ALWAYS },
152 { "ASC", "TK_ASC", ALWAYS },
153 { "ATTACH", "TK_ATTACH", ATTACH },
154 { "AUTOINCREMENT", "TK_AUTOINCR", AUTOINCR },
155 { "BEFORE", "TK_BEFORE", TRIGGER },
156 { "BEGIN", "TK_BEGIN", ALWAYS },
157 { "BETWEEN", "TK_BETWEEN", ALWAYS },
158 { "BY", "TK_BY", ALWAYS },
159 { "CASCADE", "TK_CASCADE", FKEY },
160 { "CASE", "TK_CASE", ALWAYS },
161 { "CAST", "TK_CAST", CAST },
162 { "CHECK", "TK_CHECK", ALWAYS },
163 { "COLLATE", "TK_COLLATE", ALWAYS },
164 { "COLUMN", "TK_COLUMNKW", ALTER },
165 { "COMMIT", "TK_COMMIT", ALWAYS },
166 { "CONFLICT", "TK_CONFLICT", CONFLICT },
167 { "CONSTRAINT", "TK_CONSTRAINT", ALWAYS },
168 { "CREATE", "TK_CREATE", ALWAYS },
169 { "CROSS", "TK_JOIN_KW", ALWAYS },
170 { "CURRENT_DATE", "TK_CTIME_KW", ALWAYS },
171 { "CURRENT_TIME", "TK_CTIME_KW", ALWAYS },
172 { "CURRENT_TIMESTAMP","TK_CTIME_KW", ALWAYS },
173 { "DATABASE", "TK_DATABASE", ATTACH },
174 { "DEFAULT", "TK_DEFAULT", ALWAYS },
175 { "DEFERRED", "TK_DEFERRED", ALWAYS },
176 { "DEFERRABLE", "TK_DEFERRABLE", FKEY },
177 { "DELETE", "TK_DELETE", ALWAYS },
178 { "DESC", "TK_DESC", ALWAYS },
179 { "DETACH", "TK_DETACH", ATTACH },
180 { "DISTINCT", "TK_DISTINCT", ALWAYS },
181 { "DROP", "TK_DROP", ALWAYS },
182 { "END", "TK_END", ALWAYS },
183 { "EACH", "TK_EACH", TRIGGER },
184 { "ELSE", "TK_ELSE", ALWAYS },
185 { "ESCAPE", "TK_ESCAPE", ALWAYS },
186 { "EXCEPT", "TK_EXCEPT", COMPOUND },
187 { "EXCLUSIVE", "TK_EXCLUSIVE", ALWAYS },
188 { "EXISTS", "TK_EXISTS", ALWAYS },
189 { "EXPLAIN", "TK_EXPLAIN", EXPLAIN },
190 { "FAIL", "TK_FAIL", CONFLICT|TRIGGER },
191 { "FOR", "TK_FOR", TRIGGER },
192 { "FOREIGN", "TK_FOREIGN", FKEY },
193 { "FROM", "TK_FROM", ALWAYS },
194 { "FULL", "TK_JOIN_KW", ALWAYS },
195 { "GLOB", "TK_LIKE_KW", ALWAYS },
196 { "GROUP", "TK_GROUP", ALWAYS },
197 { "HAVING", "TK_HAVING", ALWAYS },
198 { "IF", "TK_IF", ALWAYS },
199 { "IGNORE", "TK_IGNORE", CONFLICT|TRIGGER },
200 { "IMMEDIATE", "TK_IMMEDIATE", ALWAYS },
201 { "IN", "TK_IN", ALWAYS },
202 { "INDEX", "TK_INDEX", ALWAYS },
203 { "INITIALLY", "TK_INITIALLY", FKEY },
204 { "INNER", "TK_JOIN_KW", ALWAYS },
205 { "INSERT", "TK_INSERT", ALWAYS },
206 { "INSTEAD", "TK_INSTEAD", TRIGGER },
207 { "INTERSECT", "TK_INTERSECT", COMPOUND },
208 { "INTO", "TK_INTO", ALWAYS },
209 { "IS", "TK_IS", ALWAYS },
210 { "ISNULL", "TK_ISNULL", ALWAYS },
211 { "JOIN", "TK_JOIN", ALWAYS },
212 { "KEY", "TK_KEY", ALWAYS },
213 { "LEFT", "TK_JOIN_KW", ALWAYS },
214 { "LIKE", "TK_LIKE_KW", ALWAYS },
215 { "LIMIT", "TK_LIMIT", ALWAYS },
216 { "MATCH", "TK_MATCH", ALWAYS },
217 { "NATURAL", "TK_JOIN_KW", ALWAYS },
218 { "NOT", "TK_NOT", ALWAYS },
219 { "NOTNULL", "TK_NOTNULL", ALWAYS },
220 { "NULL", "TK_NULL", ALWAYS },
221 { "OF", "TK_OF", ALWAYS },
222 { "OFFSET", "TK_OFFSET", ALWAYS },
223 { "ON", "TK_ON", ALWAYS },
224 { "OR", "TK_OR", ALWAYS },
225 { "ORDER", "TK_ORDER", ALWAYS },
226 { "OUTER", "TK_JOIN_KW", ALWAYS },
227 { "PLAN", "TK_PLAN", EXPLAIN },
228 { "PRAGMA", "TK_PRAGMA", PRAGMA },
229 { "PRIMARY", "TK_PRIMARY", ALWAYS },
230 { "QUERY", "TK_QUERY", EXPLAIN },
231 { "RAISE", "TK_RAISE", TRIGGER },
232 { "REFERENCES", "TK_REFERENCES", FKEY },
233 { "REGEXP", "TK_LIKE_KW", ALWAYS },
234 { "REINDEX", "TK_REINDEX", REINDEX },
235 { "RENAME", "TK_RENAME", ALTER },
236 { "REPLACE", "TK_REPLACE", CONFLICT },
237 { "RESTRICT", "TK_RESTRICT", FKEY },
238 { "RIGHT", "TK_JOIN_KW", ALWAYS },
239 { "ROLLBACK", "TK_ROLLBACK", ALWAYS },
240 { "ROW", "TK_ROW", TRIGGER },
241 { "SELECT", "TK_SELECT", ALWAYS },
242 { "SET", "TK_SET", ALWAYS },
243 { "TABLE", "TK_TABLE", ALWAYS },
244 { "TEMP", "TK_TEMP", ALWAYS },
245 { "TEMPORARY", "TK_TEMP", ALWAYS },
246 { "THEN", "TK_THEN", ALWAYS },
247 { "TO", "TK_TO", ALTER },
248 { "TRANSACTION", "TK_TRANSACTION", ALWAYS },
249 { "TRIGGER", "TK_TRIGGER", TRIGGER },
250 { "UNION", "TK_UNION", COMPOUND },
251 { "UNIQUE", "TK_UNIQUE", ALWAYS },
252 { "UPDATE", "TK_UPDATE", ALWAYS },
253 { "USING", "TK_USING", ALWAYS },
254 { "VACUUM", "TK_VACUUM", VACUUM },
255 { "VALUES", "TK_VALUES", ALWAYS },
256 { "VIEW", "TK_VIEW", VIEW },
257 { "VIRTUAL", "TK_VIRTUAL", VTAB },
258 { "WHEN", "TK_WHEN", ALWAYS },
259 { "WHERE", "TK_WHERE", ALWAYS },
260};
261
262/* Number of keywords */
263static int nKeyword = (sizeof(aKeywordTable)/sizeof(aKeywordTable[0]));
264
265/* An array to map all upper-case characters into their corresponding
266** lower-case character.
267*/
268const unsigned char sqlite3UpperToLower[] = {
269 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
270 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
271 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
272 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103,
273 104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,
274 122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,
275 108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
276 126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
277 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,
278 162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
279 180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,
280 198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,
281 216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
282 234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
283 252,253,254,255
284};
285#define UpperToLower sqlite3UpperToLower
286
287/*
288** Comparision function for two Keyword records
289*/
290static int keywordCompare1(const void *a, const void *b){
291 const Keyword *pA = (Keyword*)a;
292 const Keyword *pB = (Keyword*)b;
293 int n = pA->len - pB->len;
294 if( n==0 ){
295 n = strcmp(pA->zName, pB->zName);
296 }
297 return n;
298}
299static int keywordCompare2(const void *a, const void *b){
300 const Keyword *pA = (Keyword*)a;
301 const Keyword *pB = (Keyword*)b;
302 int n = pB->longestSuffix - pA->longestSuffix;
303 if( n==0 ){
304 n = strcmp(pA->zName, pB->zName);
305 }
306 return n;
307}
308static int keywordCompare3(const void *a, const void *b){
309 const Keyword *pA = (Keyword*)a;
310 const Keyword *pB = (Keyword*)b;
311 int n = pA->offset - pB->offset;
312 return n;
313}
314
315/*
316** Return a KeywordTable entry with the given id
317*/
318static Keyword *findById(int id){
319 int i;
320 for(i=0; i<nKeyword; i++){
321 if( aKeywordTable[i].id==id ) break;
322 }
323 return &aKeywordTable[i];
324}
325
326/*
327** This routine does the work. The generated code is printed on standard
328** output.
329*/
330int main(int argc, char **argv){
331 int i, j, k, h;
332 int bestSize, bestCount;
333 int count;
334 int nChar;
335 int totalLen = 0;
336 int aHash[1000]; /* 1000 is much bigger than nKeyword */
337
338 /* Remove entries from the list of keywords that have mask==0 */
339 for(i=j=0; i<nKeyword; i++){
340 if( aKeywordTable[i].mask==0 ) continue;
341 if( j<i ){
342 aKeywordTable[j] = aKeywordTable[i];
343 }
344 j++;
345 }
346 nKeyword = j;
347
348 /* Fill in the lengths of strings and hashes for all entries. */
349 for(i=0; i<nKeyword; i++){
350 Keyword *p = &aKeywordTable[i];
351 p->len = strlen(p->zName);
352 totalLen += p->len;
353 p->hash = (UpperToLower[(int)p->zName[0]]*4) ^
354 (UpperToLower[(int)p->zName[p->len-1]]*3) ^ p->len;
355 p->id = i+1;
356 }
357
358 /* Sort the table from shortest to longest keyword */
359 qsort(aKeywordTable, nKeyword, sizeof(aKeywordTable[0]), keywordCompare1);
360
361 /* Look for short keywords embedded in longer keywords */
362 for(i=nKeyword-2; i>=0; i--){
363 Keyword *p = &aKeywordTable[i];
364 for(j=nKeyword-1; j>i && p->substrId==0; j--){
365 Keyword *pOther = &aKeywordTable[j];
366 if( pOther->substrId ) continue;
367 if( pOther->len<=p->len ) continue;
368 for(k=0; k<=pOther->len-p->len; k++){
369 if( memcmp(p->zName, &pOther->zName[k], p->len)==0 ){
370 p->substrId = pOther->id;
371 p->substrOffset = k;
372 break;
373 }
374 }
375 }
376 }
377
378 /* Compute the longestSuffix value for every word */
379 for(i=0; i<nKeyword; i++){
380 Keyword *p = &aKeywordTable[i];
381 if( p->substrId ) continue;
382 for(j=0; j<nKeyword; j++){
383 Keyword *pOther;
384 if( j==i ) continue;
385 pOther = &aKeywordTable[j];
386 if( pOther->substrId ) continue;
387 for(k=p->longestSuffix+1; k<p->len && k<pOther->len; k++){
388 if( memcmp(&p->zName[p->len-k], pOther->zName, k)==0 ){
389 p->longestSuffix = k;
390 }
391 }
392 }
393 }
394
395 /* Sort the table into reverse order by length */
396 qsort(aKeywordTable, nKeyword, sizeof(aKeywordTable[0]), keywordCompare2);
397
398 /* Fill in the offset for all entries */
399 nChar = 0;
400 for(i=0; i<nKeyword; i++){
401 Keyword *p = &aKeywordTable[i];
402 if( p->offset>0 || p->substrId ) continue;
403 p->offset = nChar;
404 nChar += p->len;
405 for(k=p->len-1; k>=1; k--){
406 for(j=i+1; j<nKeyword; j++){
407 Keyword *pOther = &aKeywordTable[j];
408 if( pOther->offset>0 || pOther->substrId ) continue;
409 if( pOther->len<=k ) continue;
410 if( memcmp(&p->zName[p->len-k], pOther->zName, k)==0 ){
411 p = pOther;
412 p->offset = nChar - k;
413 nChar = p->offset + p->len;
414 p->zName += k;
415 p->len -= k;
416 p->prefix = k;
417 j = i;
418 k = p->len;
419 }
420 }
421 }
422 }
423 for(i=0; i<nKeyword; i++){
424 Keyword *p = &aKeywordTable[i];
425 if( p->substrId ){
426 p->offset = findById(p->substrId)->offset + p->substrOffset;
427 }
428 }
429
430 /* Sort the table by offset */
431 qsort(aKeywordTable, nKeyword, sizeof(aKeywordTable[0]), keywordCompare3);
432
433 /* Figure out how big to make the hash table in order to minimize the
434 ** number of collisions */
435 bestSize = nKeyword;
436 bestCount = nKeyword*nKeyword;
437 for(i=nKeyword/2; i<=2*nKeyword; i++){
438 for(j=0; j<i; j++) aHash[j] = 0;
439 for(j=0; j<nKeyword; j++){
440 h = aKeywordTable[j].hash % i;
441 aHash[h] *= 2;
442 aHash[h]++;
443 }
444 for(j=count=0; j<i; j++) count += aHash[j];
445 if( count<bestCount ){
446 bestCount = count;
447 bestSize = i;
448 }
449 }
450
451 /* Compute the hash */
452 for(i=0; i<bestSize; i++) aHash[i] = 0;
453 for(i=0; i<nKeyword; i++){
454 h = aKeywordTable[i].hash % bestSize;
455 aKeywordTable[i].iNext = aHash[h];
456 aHash[h] = i+1;
457 }
458
459 /* Begin generating code */
460 printf("%s", zHdr);
461 printf("/* Hash score: %d */\n", bestCount);
462 printf("static int keywordCode(const char *z, int n){\n");
463 printf(" /* zText[] encodes %d bytes of keywords in %d bytes */\n",
464 totalLen + nKeyword, nChar+1 );
465
466 printf(" static const char zText[%d] =\n", nChar+1);
467 for(i=j=0; i<nKeyword; i++){
468 Keyword *p = &aKeywordTable[i];
469 if( p->substrId ) continue;
470 if( j==0 ) printf(" \"");
471 printf("%s", p->zName);
472 j += p->len;
473 if( j>60 ){
474 printf("\"\n");
475 j = 0;
476 }
477 }
478 printf("%s;\n", j>0 ? "\"" : " ");
479
480 printf(" static const unsigned char aHash[%d] = {\n", bestSize);
481 for(i=j=0; i<bestSize; i++){
482 if( j==0 ) printf(" ");
483 printf(" %3d,", aHash[i]);
484 j++;
485 if( j>12 ){
486 printf("\n");
487 j = 0;
488 }
489 }
490 printf("%s };\n", j==0 ? "" : "\n");
491
492 printf(" static const unsigned char aNext[%d] = {\n", nKeyword);
493 for(i=j=0; i<nKeyword; i++){
494 if( j==0 ) printf(" ");
495 printf(" %3d,", aKeywordTable[i].iNext);
496 j++;
497 if( j>12 ){
498 printf("\n");
499 j = 0;
500 }
501 }
502 printf("%s };\n", j==0 ? "" : "\n");
503
504 printf(" static const unsigned char aLen[%d] = {\n", nKeyword);
505 for(i=j=0; i<nKeyword; i++){
506 if( j==0 ) printf(" ");
507 printf(" %3d,", aKeywordTable[i].len+aKeywordTable[i].prefix);
508 j++;
509 if( j>12 ){
510 printf("\n");
511 j = 0;
512 }
513 }
514 printf("%s };\n", j==0 ? "" : "\n");
515
516 printf(" static const unsigned short int aOffset[%d] = {\n", nKeyword);
517 for(i=j=0; i<nKeyword; i++){
518 if( j==0 ) printf(" ");
519 printf(" %3d,", aKeywordTable[i].offset);
520 j++;
521 if( j>12 ){
522 printf("\n");
523 j = 0;
524 }
525 }
526 printf("%s };\n", j==0 ? "" : "\n");
527
528 printf(" static const unsigned char aCode[%d] = {\n", nKeyword);
529 for(i=j=0; i<nKeyword; i++){
530 char *zToken = aKeywordTable[i].zTokenType;
531 if( j==0 ) printf(" ");
532 printf("%s,%*s", zToken, (int)(14-strlen(zToken)), "");
533 j++;
534 if( j>=5 ){
535 printf("\n");
536 j = 0;
537 }
538 }
539 printf("%s };\n", j==0 ? "" : "\n");
540
541 printf(" int h, i;\n");
542 printf(" if( n<2 ) return TK_ID;\n");
543 printf(" h = ((charMap(z[0])*4) ^\n"
544 " (charMap(z[n-1])*3) ^\n"
545 " n) %% %d;\n", bestSize);
546 printf(" for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){\n");
547 printf(" if( aLen[i]==n &&"
548 " sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){\n");
549 printf(" return aCode[i];\n");
550 printf(" }\n");
551 printf(" }\n");
552 printf(" return TK_ID;\n");
553 printf("}\n");
554 printf("int sqlite3KeywordCode(const unsigned char *z, int n){\n");
555 printf(" return keywordCode((char*)z, n);\n");
556 printf("}\n");
557
558 return 0;
559}