15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Compile and run this standalone program in order to generate code that
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** implements a function that will translate alphabetic identifiers into
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** parser token codes.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A header comment placed at the beginning of generated code.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char zHdr[] =
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "/***** This file contains automatically generated code ******\n"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "**\n"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "** The code in this file has been automatically generated by\n"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "**\n"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "**   sqlite/tool/mkkeywordhash.c\n"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "**\n"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "** The code in this file implements a function that determines whether\n"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "** or not a given identifier is really an SQL keyword.  The same thing\n"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "** might be implemented more directly using a hand-written hash table.\n"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "** But by using this automatically generated code, the size of the code\n"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "** is substantially reduced.  This is important for embedded applications\n"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "** on platforms with limited memory.\n"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "*/\n"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles);
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** All the keywords of the SQL language are stored in a hash
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** table composed of instances of the following structure.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct Keyword Keyword;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Keyword {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zName;         /* The keyword name */
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zTokenType;    /* Token value for this keyword */
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int mask;            /* Code this keyword if non-zero */
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int id;              /* Unique ID for this record */
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int hash;            /* Hash on the keyword */
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int offset;          /* Offset to start of name string */
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int len;             /* Length of this keyword, not counting final \000 */
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int prefix;          /* Number of characters in prefix */
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int longestSuffix;   /* Longest suffix that is a prefix on another word */
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iNext;           /* Index in aKeywordTable[] of next with same hash */
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int substrId;        /* Id to another keyword this keyword is embedded in */
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int substrOffset;    /* Offset into substrId for start of this keyword */
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char zOrigName[20];  /* Original keyword name before processing */
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Define masks used to determine which keywords are allowed
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_OMIT_ALTERTABLE
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define ALTER      0
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define ALTER      0x00000001
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ALWAYS       0x00000002
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_OMIT_ANALYZE
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define ANALYZE    0
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define ANALYZE    0x00000004
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_OMIT_ATTACH
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define ATTACH     0
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define ATTACH     0x00000008
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_OMIT_AUTOINCREMENT
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define AUTOINCR   0
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define AUTOINCR   0x00000010
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_OMIT_CAST
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define CAST       0
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define CAST       0x00000020
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_OMIT_COMPOUND_SELECT
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define COMPOUND   0
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define COMPOUND   0x00000040
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_OMIT_CONFLICT_CLAUSE
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define CONFLICT   0
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define CONFLICT   0x00000080
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_OMIT_EXPLAIN
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define EXPLAIN    0
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define EXPLAIN    0x00000100
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_OMIT_FOREIGN_KEY
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define FKEY       0
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define FKEY       0x00000200
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_OMIT_PRAGMA
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define PRAGMA     0
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define PRAGMA     0x00000400
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_OMIT_REINDEX
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define REINDEX    0
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define REINDEX    0x00000800
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_OMIT_SUBQUERY
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define SUBQUERY   0
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define SUBQUERY   0x00001000
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_OMIT_TRIGGER
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define TRIGGER    0
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define TRIGGER    0x00002000
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(SQLITE_OMIT_AUTOVACUUM) && \
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (defined(SQLITE_OMIT_VACUUM) || defined(SQLITE_OMIT_ATTACH))
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define VACUUM     0
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define VACUUM     0x00004000
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_OMIT_VIEW
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define VIEW       0
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define VIEW       0x00008000
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_OMIT_VIRTUALTABLE
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define VTAB       0
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define VTAB       0x00010000
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_OMIT_AUTOVACUUM
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define AUTOVACUUM 0
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define AUTOVACUUM 0x00020000
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** These are the keywords
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Keyword aKeywordTable[] = {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "ABORT",            "TK_ABORT",        CONFLICT|TRIGGER       },
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "ACTION",           "TK_ACTION",       FKEY                   },
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "ADD",              "TK_ADD",          ALTER                  },
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "AFTER",            "TK_AFTER",        TRIGGER                },
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "ALL",              "TK_ALL",          ALWAYS                 },
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "ALTER",            "TK_ALTER",        ALTER                  },
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "ANALYZE",          "TK_ANALYZE",      ANALYZE                },
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "AND",              "TK_AND",          ALWAYS                 },
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "AS",               "TK_AS",           ALWAYS                 },
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "ASC",              "TK_ASC",          ALWAYS                 },
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "ATTACH",           "TK_ATTACH",       ATTACH                 },
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "AUTOINCREMENT",    "TK_AUTOINCR",     AUTOINCR               },
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "BEFORE",           "TK_BEFORE",       TRIGGER                },
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "BEGIN",            "TK_BEGIN",        ALWAYS                 },
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "BETWEEN",          "TK_BETWEEN",      ALWAYS                 },
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "BY",               "TK_BY",           ALWAYS                 },
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "CASCADE",          "TK_CASCADE",      FKEY                   },
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "CASE",             "TK_CASE",         ALWAYS                 },
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "CAST",             "TK_CAST",         CAST                   },
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "CHECK",            "TK_CHECK",        ALWAYS                 },
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "COLLATE",          "TK_COLLATE",      ALWAYS                 },
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "COLUMN",           "TK_COLUMNKW",     ALTER                  },
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "COMMIT",           "TK_COMMIT",       ALWAYS                 },
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "CONFLICT",         "TK_CONFLICT",     CONFLICT               },
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "CONSTRAINT",       "TK_CONSTRAINT",   ALWAYS                 },
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "CREATE",           "TK_CREATE",       ALWAYS                 },
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "CROSS",            "TK_JOIN_KW",      ALWAYS                 },
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "CURRENT_DATE",     "TK_CTIME_KW",     ALWAYS                 },
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "CURRENT_TIME",     "TK_CTIME_KW",     ALWAYS                 },
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "CURRENT_TIMESTAMP","TK_CTIME_KW",     ALWAYS                 },
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "DATABASE",         "TK_DATABASE",     ATTACH                 },
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "DEFAULT",          "TK_DEFAULT",      ALWAYS                 },
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "DEFERRED",         "TK_DEFERRED",     ALWAYS                 },
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "DEFERRABLE",       "TK_DEFERRABLE",   FKEY                   },
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "DELETE",           "TK_DELETE",       ALWAYS                 },
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "DESC",             "TK_DESC",         ALWAYS                 },
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "DETACH",           "TK_DETACH",       ATTACH                 },
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "DISTINCT",         "TK_DISTINCT",     ALWAYS                 },
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "DROP",             "TK_DROP",         ALWAYS                 },
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "END",              "TK_END",          ALWAYS                 },
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "EACH",             "TK_EACH",         TRIGGER                },
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "ELSE",             "TK_ELSE",         ALWAYS                 },
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "ESCAPE",           "TK_ESCAPE",       ALWAYS                 },
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "EXCEPT",           "TK_EXCEPT",       COMPOUND               },
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "EXCLUSIVE",        "TK_EXCLUSIVE",    ALWAYS                 },
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "EXISTS",           "TK_EXISTS",       ALWAYS                 },
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "EXPLAIN",          "TK_EXPLAIN",      EXPLAIN                },
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "FAIL",             "TK_FAIL",         CONFLICT|TRIGGER       },
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "FOR",              "TK_FOR",          TRIGGER                },
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "FOREIGN",          "TK_FOREIGN",      FKEY                   },
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "FROM",             "TK_FROM",         ALWAYS                 },
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "FULL",             "TK_JOIN_KW",      ALWAYS                 },
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "GLOB",             "TK_LIKE_KW",      ALWAYS                 },
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "GROUP",            "TK_GROUP",        ALWAYS                 },
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "HAVING",           "TK_HAVING",       ALWAYS                 },
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "IF",               "TK_IF",           ALWAYS                 },
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "IGNORE",           "TK_IGNORE",       CONFLICT|TRIGGER       },
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "IMMEDIATE",        "TK_IMMEDIATE",    ALWAYS                 },
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "IN",               "TK_IN",           ALWAYS                 },
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "INDEX",            "TK_INDEX",        ALWAYS                 },
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "INDEXED",          "TK_INDEXED",      ALWAYS                 },
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "INITIALLY",        "TK_INITIALLY",    FKEY                   },
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "INNER",            "TK_JOIN_KW",      ALWAYS                 },
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "INSERT",           "TK_INSERT",       ALWAYS                 },
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "INSTEAD",          "TK_INSTEAD",      TRIGGER                },
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "INTERSECT",        "TK_INTERSECT",    COMPOUND               },
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "INTO",             "TK_INTO",         ALWAYS                 },
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "IS",               "TK_IS",           ALWAYS                 },
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "ISNULL",           "TK_ISNULL",       ALWAYS                 },
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "JOIN",             "TK_JOIN",         ALWAYS                 },
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "KEY",              "TK_KEY",          ALWAYS                 },
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "LEFT",             "TK_JOIN_KW",      ALWAYS                 },
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "LIKE",             "TK_LIKE_KW",      ALWAYS                 },
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "LIMIT",            "TK_LIMIT",        ALWAYS                 },
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "MATCH",            "TK_MATCH",        ALWAYS                 },
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "NATURAL",          "TK_JOIN_KW",      ALWAYS                 },
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "NO",               "TK_NO",           FKEY                   },
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "NOT",              "TK_NOT",          ALWAYS                 },
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "NOTNULL",          "TK_NOTNULL",      ALWAYS                 },
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "NULL",             "TK_NULL",         ALWAYS                 },
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "OF",               "TK_OF",           ALWAYS                 },
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "OFFSET",           "TK_OFFSET",       ALWAYS                 },
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "ON",               "TK_ON",           ALWAYS                 },
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "OR",               "TK_OR",           ALWAYS                 },
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "ORDER",            "TK_ORDER",        ALWAYS                 },
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "OUTER",            "TK_JOIN_KW",      ALWAYS                 },
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "PLAN",             "TK_PLAN",         EXPLAIN                },
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "PRAGMA",           "TK_PRAGMA",       PRAGMA                 },
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "PRIMARY",          "TK_PRIMARY",      ALWAYS                 },
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "QUERY",            "TK_QUERY",        EXPLAIN                },
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "RAISE",            "TK_RAISE",        TRIGGER                },
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "REFERENCES",       "TK_REFERENCES",   FKEY                   },
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "REGEXP",           "TK_LIKE_KW",      ALWAYS                 },
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "REINDEX",          "TK_REINDEX",      REINDEX                },
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "RELEASE",          "TK_RELEASE",      ALWAYS                 },
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "RENAME",           "TK_RENAME",       ALTER                  },
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "REPLACE",          "TK_REPLACE",      CONFLICT               },
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "RESTRICT",         "TK_RESTRICT",     FKEY                   },
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "RIGHT",            "TK_JOIN_KW",      ALWAYS                 },
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "ROLLBACK",         "TK_ROLLBACK",     ALWAYS                 },
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "ROW",              "TK_ROW",          TRIGGER                },
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "SAVEPOINT",        "TK_SAVEPOINT",    ALWAYS                 },
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "SELECT",           "TK_SELECT",       ALWAYS                 },
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "SET",              "TK_SET",          ALWAYS                 },
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "TABLE",            "TK_TABLE",        ALWAYS                 },
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "TEMP",             "TK_TEMP",         ALWAYS                 },
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "TEMPORARY",        "TK_TEMP",         ALWAYS                 },
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "THEN",             "TK_THEN",         ALWAYS                 },
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "TO",               "TK_TO",           ALWAYS                 },
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "TRANSACTION",      "TK_TRANSACTION",  ALWAYS                 },
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "TRIGGER",          "TK_TRIGGER",      TRIGGER                },
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "UNION",            "TK_UNION",        COMPOUND               },
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "UNIQUE",           "TK_UNIQUE",       ALWAYS                 },
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "UPDATE",           "TK_UPDATE",       ALWAYS                 },
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "USING",            "TK_USING",        ALWAYS                 },
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "VACUUM",           "TK_VACUUM",       VACUUM                 },
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "VALUES",           "TK_VALUES",       ALWAYS                 },
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "VIEW",             "TK_VIEW",         VIEW                   },
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "VIRTUAL",          "TK_VIRTUAL",      VTAB                   },
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "WHEN",             "TK_WHEN",         ALWAYS                 },
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "WHERE",            "TK_WHERE",        ALWAYS                 },
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Number of keywords */
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int nKeyword = (sizeof(aKeywordTable)/sizeof(aKeywordTable[0]));
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* An array to map all upper-case characters into their corresponding
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** lower-case character.
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const unsigned char sqlite3UpperToLower[] = {
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103,
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    252,253,254,255
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define UpperToLower sqlite3UpperToLower
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Comparision function for two Keyword records
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int keywordCompare1(const void *a, const void *b){
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Keyword *pA = (Keyword*)a;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Keyword *pB = (Keyword*)b;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int n = pA->len - pB->len;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( n==0 ){
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    n = strcmp(pA->zName, pB->zName);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( n!=0 );
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return n;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int keywordCompare2(const void *a, const void *b){
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Keyword *pA = (Keyword*)a;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Keyword *pB = (Keyword*)b;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int n = pB->longestSuffix - pA->longestSuffix;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( n==0 ){
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    n = strcmp(pA->zName, pB->zName);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( n!=0 );
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return n;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int keywordCompare3(const void *a, const void *b){
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Keyword *pA = (Keyword*)a;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Keyword *pB = (Keyword*)b;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int n = pA->offset - pB->offset;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( n==0 ) n = pB->id - pA->id;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( n!=0 );
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return n;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return a KeywordTable entry with the given id
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Keyword *findById(int id){
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<nKeyword; i++){
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( aKeywordTable[i].id==id ) break;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &aKeywordTable[i];
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine does the work.  The generated code is printed on standard
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** output.
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc, char **argv){
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i, j, k, h;
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bestSize, bestCount;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int count;
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nChar;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int totalLen = 0;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int aHash[1000];  /* 1000 is much bigger than nKeyword */
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char zText[2000];
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Remove entries from the list of keywords that have mask==0 */
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=j=0; i<nKeyword; i++){
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( aKeywordTable[i].mask==0 ) continue;
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( j<i ){
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      aKeywordTable[j] = aKeywordTable[i];
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    j++;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nKeyword = j;
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Fill in the lengths of strings and hashes for all entries. */
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<nKeyword; i++){
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Keyword *p = &aKeywordTable[i];
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    p->len = strlen(p->zName);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert( p->len<sizeof(p->zOrigName) );
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    strcpy(p->zOrigName, p->zName);
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    totalLen += p->len;
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    p->hash = (UpperToLower[(int)p->zName[0]]*4) ^
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              (UpperToLower[(int)p->zName[p->len-1]]*3) ^ p->len;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    p->id = i+1;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Sort the table from shortest to longest keyword */
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  qsort(aKeywordTable, nKeyword, sizeof(aKeywordTable[0]), keywordCompare1);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Look for short keywords embedded in longer keywords */
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=nKeyword-2; i>=0; i--){
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Keyword *p = &aKeywordTable[i];
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(j=nKeyword-1; j>i && p->substrId==0; j--){
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Keyword *pOther = &aKeywordTable[j];
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if( pOther->substrId ) continue;
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if( pOther->len<=p->len ) continue;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for(k=0; k<=pOther->len-p->len; k++){
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if( memcmp(p->zName, &pOther->zName[k], p->len)==0 ){
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          p->substrId = pOther->id;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          p->substrOffset = k;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Compute the longestSuffix value for every word */
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<nKeyword; i++){
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Keyword *p = &aKeywordTable[i];
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( p->substrId ) continue;
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(j=0; j<nKeyword; j++){
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Keyword *pOther;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if( j==i ) continue;
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pOther = &aKeywordTable[j];
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if( pOther->substrId ) continue;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for(k=p->longestSuffix+1; k<p->len && k<pOther->len; k++){
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if( memcmp(&p->zName[p->len-k], pOther->zName, k)==0 ){
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          p->longestSuffix = k;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Sort the table into reverse order by length */
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  qsort(aKeywordTable, nKeyword, sizeof(aKeywordTable[0]), keywordCompare2);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Fill in the offset for all entries */
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nChar = 0;
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<nKeyword; i++){
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Keyword *p = &aKeywordTable[i];
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( p->offset>0 || p->substrId ) continue;
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    p->offset = nChar;
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nChar += p->len;
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(k=p->len-1; k>=1; k--){
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for(j=i+1; j<nKeyword; j++){
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Keyword *pOther = &aKeywordTable[j];
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if( pOther->offset>0 || pOther->substrId ) continue;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if( pOther->len<=k ) continue;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if( memcmp(&p->zName[p->len-k], pOther->zName, k)==0 ){
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          p = pOther;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          p->offset = nChar - k;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          nChar = p->offset + p->len;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          p->zName += k;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          p->len -= k;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          p->prefix = k;
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          j = i;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          k = p->len;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<nKeyword; i++){
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Keyword *p = &aKeywordTable[i];
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( p->substrId ){
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      p->offset = findById(p->substrId)->offset + p->substrOffset;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Sort the table by offset */
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  qsort(aKeywordTable, nKeyword, sizeof(aKeywordTable[0]), keywordCompare3);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Figure out how big to make the hash table in order to minimize the
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** number of collisions */
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bestSize = nKeyword;
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bestCount = nKeyword*nKeyword;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=nKeyword/2; i<=2*nKeyword; i++){
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(j=0; j<i; j++) aHash[j] = 0;
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(j=0; j<nKeyword; j++){
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      h = aKeywordTable[j].hash % i;
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      aHash[h] *= 2;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      aHash[h]++;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(j=count=0; j<i; j++) count += aHash[j];
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( count<bestCount ){
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bestCount = count;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bestSize = i;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Compute the hash */
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<bestSize; i++) aHash[i] = 0;
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<nKeyword; i++){
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    h = aKeywordTable[i].hash % bestSize;
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aKeywordTable[i].iNext = aHash[h];
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aHash[h] = i+1;
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Begin generating code */
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("%s", zHdr);
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("/* Hash score: %d */\n", bestCount);
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("static int keywordCode(const char *z, int n){\n");
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("  /* zText[] encodes %d bytes of keywords in %d bytes */\n",
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          totalLen + nKeyword, nChar+1 );
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=j=k=0; i<nKeyword; i++){
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Keyword *p = &aKeywordTable[i];
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( p->substrId ) continue;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(&zText[k], p->zName, p->len);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    k += p->len;
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( j+p->len>70 ){
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printf("%*s */\n", 74-j, "");
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      j = 0;
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( j==0 ){
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printf("  /*   ");
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      j = 8;
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("%s", p->zName);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    j += p->len;
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( j>0 ){
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("%*s */\n", 74-j, "");
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("  static const char zText[%d] = {\n", nChar);
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zText[nChar] = 0;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=j=0; i<k; i++){
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( j==0 ){
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printf("    ");
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( zText[i]==0 ){
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printf("0");
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }else{
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printf("'%c',", zText[i]);
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    j += 4;
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( j>68 ){
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printf("\n");
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      j = 0;
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( j>0 ) printf("\n");
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("  };\n");
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("  static const unsigned char aHash[%d] = {\n", bestSize);
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=j=0; i<bestSize; i++){
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( j==0 ) printf("    ");
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf(" %3d,", aHash[i]);
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    j++;
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( j>12 ){
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printf("\n");
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      j = 0;
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("%s  };\n", j==0 ? "" : "\n");
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("  static const unsigned char aNext[%d] = {\n", nKeyword);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=j=0; i<nKeyword; i++){
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( j==0 ) printf("    ");
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf(" %3d,", aKeywordTable[i].iNext);
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    j++;
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( j>12 ){
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printf("\n");
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      j = 0;
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("%s  };\n", j==0 ? "" : "\n");
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("  static const unsigned char aLen[%d] = {\n", nKeyword);
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=j=0; i<nKeyword; i++){
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( j==0 ) printf("    ");
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf(" %3d,", aKeywordTable[i].len+aKeywordTable[i].prefix);
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    j++;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( j>12 ){
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printf("\n");
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      j = 0;
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("%s  };\n", j==0 ? "" : "\n");
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("  static const unsigned short int aOffset[%d] = {\n", nKeyword);
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=j=0; i<nKeyword; i++){
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( j==0 ) printf("    ");
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf(" %3d,", aKeywordTable[i].offset);
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    j++;
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( j>12 ){
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printf("\n");
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      j = 0;
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("%s  };\n", j==0 ? "" : "\n");
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("  static const unsigned char aCode[%d] = {\n", nKeyword);
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=j=0; i<nKeyword; i++){
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *zToken = aKeywordTable[i].zTokenType;
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( j==0 ) printf("    ");
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("%s,%*s", zToken, (int)(14-strlen(zToken)), "");
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    j++;
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( j>=5 ){
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printf("\n");
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      j = 0;
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("%s  };\n", j==0 ? "" : "\n");
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("  int h, i;\n");
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("  if( n<2 ) return TK_ID;\n");
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("  h = ((charMap(z[0])*4) ^\n"
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         "      (charMap(z[n-1])*3) ^\n"
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         "      n) %% %d;\n", bestSize);
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("  for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){\n");
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("    if( aLen[i]==n &&"
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   " sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){\n");
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<nKeyword; i++){
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("      testcase( i==%d ); /* %s */\n",
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           i, aKeywordTable[i].zOrigName);
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("      return aCode[i];\n");
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("    }\n");
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("  }\n");
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("  return TK_ID;\n");
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("}\n");
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("int sqlite3KeywordCode(const unsigned char *z, int n){\n");
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("  return keywordCode((char*)z, n);\n");
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("}\n");
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("#define SQLITE_N_KEYWORD %d\n", nKeyword);
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
603