Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: third_party/sqlite/tool/mkkeywordhash.c

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

Powered by Google App Engine
This is Rietveld 408576698