/ Check-in [62b87751]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Split the sqlite3_complete() API out into a separate source file so that in static links where it is not used it will not take up space in the resulting binary. (CVS 2594)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 62b87751dea56c565bcc2aca88a2edda7dfc2a57
User & Date: drh 2005-08-14 17:53:21
Context
2005-08-14
20:47
General code cleanup resulting in smaller footprint. (CVS 2595) check-in: 98338abf user: drh tags: trunk
17:53
Split the sqlite3_complete() API out into a separate source file so that in static links where it is not used it will not take up space in the resulting binary. (CVS 2594) check-in: 62b87751 user: drh tags: trunk
01:34
Declare local-use functions as static. Ticket #1363. (CVS 2593) check-in: 94efd790 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   109    109   
   110    110   OPTS += -DSQLITE_OMIT_CURSOR          # Cursors do not work at this time
   111    111   TCC += -DSQLITE_OMIT_CURSOR
   112    112   
   113    113   # Object files for the SQLite library.
   114    114   #
   115    115   LIBOBJ = alter.lo analyze.lo attach.lo auth.lo btree.lo build.lo \
   116         -         callback.lo date.lo \
          116  +         callback.lo complete.lo date.lo \
   117    117            delete.lo expr.lo func.lo hash.lo insert.lo \
   118    118            main.lo opcodes.lo os_unix.lo os_win.lo \
   119    119            pager.lo parse.lo pragma.lo prepare.lo printf.lo random.lo \
   120    120            select.lo table.lo tokenize.lo trigger.lo update.lo \
   121    121            util.lo vacuum.lo \
   122    122            vdbe.lo vdbeapi.lo vdbeaux.lo vdbefifo.lo vdbemem.lo \
   123    123            where.lo utf.lo legacy.lo
................................................................................
   129    129     $(TOP)/src/analyze.c \
   130    130     $(TOP)/src/attach.c \
   131    131     $(TOP)/src/auth.c \
   132    132     $(TOP)/src/btree.c \
   133    133     $(TOP)/src/btree.h \
   134    134     $(TOP)/src/build.c \
   135    135     $(TOP)/src/callback.c \
          136  +  $(TOP)/src/complete.c \
   136    137     $(TOP)/src/date.c \
   137    138     $(TOP)/src/delete.c \
   138    139     $(TOP)/src/expr.c \
   139    140     $(TOP)/src/func.c \
   140    141     $(TOP)/src/hash.c \
   141    142     $(TOP)/src/hash.h \
   142    143     $(TOP)/src/insert.c \
................................................................................
   187    188     $(TOP)/src/test2.c \
   188    189     $(TOP)/src/test3.c \
   189    190     $(TOP)/src/test4.c \
   190    191     $(TOP)/src/test5.c \
   191    192     $(TOP)/src/utf.c \
   192    193     $(TOP)/src/util.c \
   193    194     $(TOP)/src/vdbe.c \
   194         -  $(TOP)/src/md5.c
          195  +  $(TOP)/src/md5.c \
          196  +  $(TOP)/src/where.c
   195    197   
   196    198   # In LIBOBJ but not TESTSRC
   197    199   COMMONOBJ = $(foreach obj,$(LIBOBJ),\
   198    200   	$(if $(findstring $(patsubst %.lo,%.c,$(obj)),$(TESTSRC)),,$(obj)))
   199    201   
   200    202   # Header files used by all library source files.
   201    203   #
................................................................................
   286    288   	$(LTCOMPILE) -c $(TOP)/src/btree.c
   287    289   
   288    290   build.lo:	$(TOP)/src/build.c $(HDR)
   289    291   	$(LTCOMPILE) -c $(TOP)/src/build.c
   290    292   
   291    293   callback.lo:	$(TOP)/src/callback.c $(HDR)
   292    294   	$(LTCOMPILE) -c $(TOP)/src/callback.c
          295  +
          296  +complete.lo:	$(TOP)/src/complete.c $(HDR)
          297  +	$(LTCOMPILE) -c $(TOP)/src/complete.c
   293    298   
   294    299   date.lo:	$(TOP)/src/date.c $(HDR)
   295    300   	$(LTCOMPILE) -c $(TOP)/src/date.c
   296    301   
   297    302   delete.lo:	$(TOP)/src/delete.c $(HDR)
   298    303   	$(LTCOMPILE) -c $(TOP)/src/delete.c
   299    304   

Changes to main.mk.

    51     51   # This is how we compile
    52     52   #
    53     53   TCCX = $(TCC) $(OPTS) $(THREADSAFE) $(USLEEP) -I. -I$(TOP)/src
    54     54   
    55     55   # Object files for the SQLite library.
    56     56   #
    57     57   LIBOBJ+= alter.o analyze.o attach.o auth.o btree.o build.o \
    58         -         callback.o date.o delete.o \
           58  +         callback.o complete.o date.o delete.o \
    59     59            expr.o func.o hash.o insert.o \
    60     60            main.o opcodes.o os_unix.o os_win.o \
    61     61            pager.o parse.o pragma.o prepare.o printf.o random.o \
    62     62            select.o table.o tclsqlite.o tokenize.o trigger.o \
    63     63            update.o util.o vacuum.o \
    64     64            vdbe.o vdbeapi.o vdbeaux.o vdbefifo.o vdbemem.o \
    65     65            where.o utf.o legacy.o
................................................................................
    71     71     $(TOP)/src/analyze.c \
    72     72     $(TOP)/src/attach.c \
    73     73     $(TOP)/src/auth.c \
    74     74     $(TOP)/src/btree.c \
    75     75     $(TOP)/src/btree.h \
    76     76     $(TOP)/src/build.c \
    77     77     $(TOP)/src/callback.c \
           78  +  $(TOP)/src/complete.c \
    78     79     $(TOP)/src/date.c \
    79     80     $(TOP)/src/delete.c \
    80     81     $(TOP)/src/expr.c \
    81     82     $(TOP)/src/func.c \
    82     83     $(TOP)/src/hash.c \
    83     84     $(TOP)/src/hash.h \
    84     85     $(TOP)/src/insert.c \
................................................................................
   217    218   	$(TCCX) -c $(TOP)/src/btree.c
   218    219   
   219    220   build.o:	$(TOP)/src/build.c $(HDR)
   220    221   	$(TCCX) -c $(TOP)/src/build.c
   221    222   
   222    223   callback.o:	$(TOP)/src/callback.c $(HDR)
   223    224   	$(TCCX) -c $(TOP)/src/callback.c
          225  +
          226  +complete.o:	$(TOP)/src/complete.c $(HDR)
          227  +	$(TCCX) -c $(TOP)/src/complete.c
   224    228   
   225    229   date.o:	$(TOP)/src/date.c $(HDR)
   226    230   	$(TCCX) -c $(TOP)/src/date.c
   227    231   
   228    232   delete.o:	$(TOP)/src/delete.c $(HDR)
   229    233   	$(TCCX) -c $(TOP)/src/delete.c
   230    234   

Added src/complete.c.

            1  +/*
            2  +** 2001 September 15
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +** An tokenizer for SQL
           13  +**
           14  +** This file contains C code that implements the sqlite3_complete() API.
           15  +** This code used to be part of the tokenizer.c source file.  But by
           16  +** separating it out, the code will be automatically omitted from
           17  +** static links that do not use it.
           18  +**
           19  +** $Id: complete.c,v 1.1 2005/08/14 17:53:21 drh Exp $
           20  +*/
           21  +#include "sqliteInt.h"
           22  +#ifndef SQLITE_OMIT_COMPLETE
           23  +
           24  +/*
           25  +** This is defined in tokenize.c.  We just have to import the definition.
           26  +*/
           27  +extern const char sqlite3IsIdChar[];
           28  +#define IdChar(C)  (((c=C)&0x80)!=0 || (c>0x1f && sqlite3IsIdChar[c-0x20]))
           29  +
           30  +
           31  +/*
           32  +** Token types used by the sqlite3_complete() routine.  See the header
           33  +** comments on that procedure for additional information.
           34  +*/
           35  +#define tkSEMI    0
           36  +#define tkWS      1
           37  +#define tkOTHER   2
           38  +#define tkEXPLAIN 3
           39  +#define tkCREATE  4
           40  +#define tkTEMP    5
           41  +#define tkTRIGGER 6
           42  +#define tkEND     7
           43  +
           44  +/*
           45  +** Return TRUE if the given SQL string ends in a semicolon.
           46  +**
           47  +** Special handling is require for CREATE TRIGGER statements.
           48  +** Whenever the CREATE TRIGGER keywords are seen, the statement
           49  +** must end with ";END;".
           50  +**
           51  +** This implementation uses a state machine with 7 states:
           52  +**
           53  +**   (0) START     At the beginning or end of an SQL statement.  This routine
           54  +**                 returns 1 if it ends in the START state and 0 if it ends
           55  +**                 in any other state.
           56  +**
           57  +**   (1) NORMAL    We are in the middle of statement which ends with a single
           58  +**                 semicolon.
           59  +**
           60  +**   (2) EXPLAIN   The keyword EXPLAIN has been seen at the beginning of 
           61  +**                 a statement.
           62  +**
           63  +**   (3) CREATE    The keyword CREATE has been seen at the beginning of a
           64  +**                 statement, possibly preceeded by EXPLAIN and/or followed by
           65  +**                 TEMP or TEMPORARY
           66  +**
           67  +**   (4) TRIGGER   We are in the middle of a trigger definition that must be
           68  +**                 ended by a semicolon, the keyword END, and another semicolon.
           69  +**
           70  +**   (5) SEMI      We've seen the first semicolon in the ";END;" that occurs at
           71  +**                 the end of a trigger definition.
           72  +**
           73  +**   (6) END       We've seen the ";END" of the ";END;" that occurs at the end
           74  +**                 of a trigger difinition.
           75  +**
           76  +** Transitions between states above are determined by tokens extracted
           77  +** from the input.  The following tokens are significant:
           78  +**
           79  +**   (0) tkSEMI      A semicolon.
           80  +**   (1) tkWS        Whitespace
           81  +**   (2) tkOTHER     Any other SQL token.
           82  +**   (3) tkEXPLAIN   The "explain" keyword.
           83  +**   (4) tkCREATE    The "create" keyword.
           84  +**   (5) tkTEMP      The "temp" or "temporary" keyword.
           85  +**   (6) tkTRIGGER   The "trigger" keyword.
           86  +**   (7) tkEND       The "end" keyword.
           87  +**
           88  +** Whitespace never causes a state transition and is always ignored.
           89  +**
           90  +** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed
           91  +** to recognize the end of a trigger can be omitted.  All we have to do
           92  +** is look for a semicolon that is not part of an string or comment.
           93  +*/
           94  +int sqlite3_complete(const char *zSql){
           95  +  u8 state = 0;   /* Current state, using numbers defined in header comment */
           96  +  u8 token;       /* Value of the next token */
           97  +
           98  +#ifndef SQLITE_OMIT_TRIGGER
           99  +  /* A complex statement machine used to detect the end of a CREATE TRIGGER
          100  +  ** statement.  This is the normal case.
          101  +  */
          102  +  static const u8 trans[7][8] = {
          103  +                     /* Token:                                                */
          104  +     /* State:       **  SEMI  WS  OTHER EXPLAIN  CREATE  TEMP  TRIGGER  END  */
          105  +     /* 0   START: */ {    0,  0,     1,      2,      3,    1,       1,   1,  },
          106  +     /* 1  NORMAL: */ {    0,  1,     1,      1,      1,    1,       1,   1,  },
          107  +     /* 2 EXPLAIN: */ {    0,  2,     1,      1,      3,    1,       1,   1,  },
          108  +     /* 3  CREATE: */ {    0,  3,     1,      1,      1,    3,       4,   1,  },
          109  +     /* 4 TRIGGER: */ {    5,  4,     4,      4,      4,    4,       4,   4,  },
          110  +     /* 5    SEMI: */ {    5,  5,     4,      4,      4,    4,       4,   6,  },
          111  +     /* 6     END: */ {    0,  6,     4,      4,      4,    4,       4,   4,  },
          112  +  };
          113  +#else
          114  +  /* If triggers are not suppored by this compile then the statement machine
          115  +  ** used to detect the end of a statement is much simplier
          116  +  */
          117  +  static const u8 trans[2][3] = {
          118  +                     /* Token:           */
          119  +     /* State:       **  SEMI  WS  OTHER */
          120  +     /* 0   START: */ {    0,  0,     1, },
          121  +     /* 1  NORMAL: */ {    0,  1,     1, },
          122  +  };
          123  +#endif /* SQLITE_OMIT_TRIGGER */
          124  +
          125  +  while( *zSql ){
          126  +    switch( *zSql ){
          127  +      case ';': {  /* A semicolon */
          128  +        token = tkSEMI;
          129  +        break;
          130  +      }
          131  +      case ' ':
          132  +      case '\r':
          133  +      case '\t':
          134  +      case '\n':
          135  +      case '\f': {  /* White space is ignored */
          136  +        token = tkWS;
          137  +        break;
          138  +      }
          139  +      case '/': {   /* C-style comments */
          140  +        if( zSql[1]!='*' ){
          141  +          token = tkOTHER;
          142  +          break;
          143  +        }
          144  +        zSql += 2;
          145  +        while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; }
          146  +        if( zSql[0]==0 ) return 0;
          147  +        zSql++;
          148  +        token = tkWS;
          149  +        break;
          150  +      }
          151  +      case '-': {   /* SQL-style comments from "--" to end of line */
          152  +        if( zSql[1]!='-' ){
          153  +          token = tkOTHER;
          154  +          break;
          155  +        }
          156  +        while( *zSql && *zSql!='\n' ){ zSql++; }
          157  +        if( *zSql==0 ) return state==0;
          158  +        token = tkWS;
          159  +        break;
          160  +      }
          161  +      case '[': {   /* Microsoft-style identifiers in [...] */
          162  +        zSql++;
          163  +        while( *zSql && *zSql!=']' ){ zSql++; }
          164  +        if( *zSql==0 ) return 0;
          165  +        token = tkOTHER;
          166  +        break;
          167  +      }
          168  +      case '`':     /* Grave-accent quoted symbols used by MySQL */
          169  +      case '"':     /* single- and double-quoted strings */
          170  +      case '\'': {
          171  +        int c = *zSql;
          172  +        zSql++;
          173  +        while( *zSql && *zSql!=c ){ zSql++; }
          174  +        if( *zSql==0 ) return 0;
          175  +        token = tkOTHER;
          176  +        break;
          177  +      }
          178  +      default: {
          179  +        int c;
          180  +        if( IdChar((u8)*zSql) ){
          181  +          /* Keywords and unquoted identifiers */
          182  +          int nId;
          183  +          for(nId=1; IdChar(zSql[nId]); nId++){}
          184  +#ifdef SQLITE_OMIT_TRIGGER
          185  +          token = tkOTHER;
          186  +#else
          187  +          switch( *zSql ){
          188  +            case 'c': case 'C': {
          189  +              if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){
          190  +                token = tkCREATE;
          191  +              }else{
          192  +                token = tkOTHER;
          193  +              }
          194  +              break;
          195  +            }
          196  +            case 't': case 'T': {
          197  +              if( nId==7 && sqlite3StrNICmp(zSql, "trigger", 7)==0 ){
          198  +                token = tkTRIGGER;
          199  +              }else if( nId==4 && sqlite3StrNICmp(zSql, "temp", 4)==0 ){
          200  +                token = tkTEMP;
          201  +              }else if( nId==9 && sqlite3StrNICmp(zSql, "temporary", 9)==0 ){
          202  +                token = tkTEMP;
          203  +              }else{
          204  +                token = tkOTHER;
          205  +              }
          206  +              break;
          207  +            }
          208  +            case 'e':  case 'E': {
          209  +              if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){
          210  +                token = tkEND;
          211  +              }else
          212  +#ifndef SQLITE_OMIT_EXPLAIN
          213  +              if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){
          214  +                token = tkEXPLAIN;
          215  +              }else
          216  +#endif
          217  +              {
          218  +                token = tkOTHER;
          219  +              }
          220  +              break;
          221  +            }
          222  +            default: {
          223  +              token = tkOTHER;
          224  +              break;
          225  +            }
          226  +          }
          227  +#endif /* SQLITE_OMIT_TRIGGER */
          228  +          zSql += nId-1;
          229  +        }else{
          230  +          /* Operators and special symbols */
          231  +          token = tkOTHER;
          232  +        }
          233  +        break;
          234  +      }
          235  +    }
          236  +    state = trans[state][token];
          237  +    zSql++;
          238  +  }
          239  +  return state==0;
          240  +}
          241  +
          242  +#ifndef SQLITE_OMIT_UTF16
          243  +/*
          244  +** This routine is the same as the sqlite3_complete() routine described
          245  +** above, except that the parameter is required to be UTF-16 encoded, not
          246  +** UTF-8.
          247  +*/
          248  +int sqlite3_complete16(const void *zSql){
          249  +  sqlite3_value *pVal;
          250  +  char const *zSql8;
          251  +  int rc = 0;
          252  +
          253  +  pVal = sqlite3ValueNew();
          254  +  sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
          255  +  zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8);
          256  +  if( zSql8 ){
          257  +    rc = sqlite3_complete(zSql8);
          258  +  }
          259  +  sqlite3ValueFree(pVal);
          260  +  return rc;
          261  +}
          262  +#endif /* SQLITE_OMIT_UTF16 */
          263  +#endif /* SQLITE_OMIT_COMPLETE */

Changes to src/tokenize.c.

    11     11   *************************************************************************
    12     12   ** An tokenizer for SQL
    13     13   **
    14     14   ** This file contains C code that splits an SQL input string up into
    15     15   ** individual tokens and sends those tokens one-by-one over to the
    16     16   ** parser for analysis.
    17     17   **
    18         -** $Id: tokenize.c,v 1.105 2005/08/13 18:15:43 drh Exp $
           18  +** $Id: tokenize.c,v 1.106 2005/08/14 17:53:21 drh Exp $
    19     19   */
    20     20   #include "sqliteInt.h"
    21     21   #include "os.h"
    22     22   #include <ctype.h>
    23     23   #include <stdlib.h>
    24     24   
    25     25   /*
................................................................................
    34     34   ** the #include below.
    35     35   */
    36     36   #include "keywordhash.h"
    37     37   
    38     38   
    39     39   /*
    40     40   ** If X is a character that can be used in an identifier and
    41         -** X&0x80==0 then isIdChar[X] will be 1.  If X&0x80==0x80 then
           41  +** X&0x80==0 then sqlite3IsIdChar[X] will be 1.  If X&0x80==0x80 then
    42     42   ** X is always an identifier character.  (Hence all UTF-8
    43         -** characters can be part of an identifier).  isIdChar[X] will
           43  +** characters can be part of an identifier).  sqlite3IsIdChar[X] will
    44     44   ** be 0 for every character in the lower 128 ASCII characters
    45     45   ** that cannot be used as part of an identifier.
    46     46   **
    47     47   ** In this implementation, an identifier can be a string of
    48     48   ** alphabetic characters, digits, and "_" plus any character
    49     49   ** with the high-order bit set.  The latter rule means that
    50     50   ** any sequence of UTF-8 characters or characters taken from
................................................................................
    51     51   ** an extended ISO8859 character set can form an identifier.
    52     52   **
    53     53   ** Ticket #1066.  the SQL standard does not allow '$' in the
    54     54   ** middle of identfiers.  But many SQL implementations do. 
    55     55   ** SQLite will allow '$' in identifiers for compatibility.
    56     56   ** But the feature is undocumented.
    57     57   */
    58         -static const char isIdChar[] = {
           58  +const char sqlite3IsIdChar[] = {
    59     59   /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
    60     60       0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 2x */
    61     61       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,  /* 3x */
    62     62       0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 4x */
    63     63       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,  /* 5x */
    64     64       0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 6x */
    65     65       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  /* 7x */
    66     66   };
    67     67   
    68         -#define IdChar(C)  (((c=C)&0x80)!=0 || (c>0x1f && isIdChar[c-0x20]))
           68  +#define IdChar(C)  (((c=C)&0x80)!=0 || (c>0x1f && sqlite3IsIdChar[c-0x20]))
    69     69   
    70     70   /*
    71     71   ** Return the length of the token that begins at z[0]. 
    72     72   ** Store the token type in *tokenType before returning.
    73     73   */
    74     74   static int getToken(const unsigned char *z, int *tokenType){
    75     75     int i, c;
................................................................................
   420    420     sqlite3DeleteTrigger(pParse->pNewTrigger);
   421    421     sqliteFree(pParse->apVarExpr);
   422    422     if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){
   423    423       pParse->rc = SQLITE_ERROR;
   424    424     }
   425    425     return nErr;
   426    426   }
   427         -
   428         -/* The sqlite3_complete() API may be omitted (to save code space) by
   429         -** defining the following symbol.
   430         -*/
   431         -#ifndef SQLITE_OMIT_COMPLETE
   432         -
   433         -/*
   434         -** Token types used by the sqlite3_complete() routine.  See the header
   435         -** comments on that procedure for additional information.
   436         -*/
   437         -#define tkSEMI    0
   438         -#define tkWS      1
   439         -#define tkOTHER   2
   440         -#define tkEXPLAIN 3
   441         -#define tkCREATE  4
   442         -#define tkTEMP    5
   443         -#define tkTRIGGER 6
   444         -#define tkEND     7
   445         -
   446         -/*
   447         -** Return TRUE if the given SQL string ends in a semicolon.
   448         -**
   449         -** Special handling is require for CREATE TRIGGER statements.
   450         -** Whenever the CREATE TRIGGER keywords are seen, the statement
   451         -** must end with ";END;".
   452         -**
   453         -** This implementation uses a state machine with 7 states:
   454         -**
   455         -**   (0) START     At the beginning or end of an SQL statement.  This routine
   456         -**                 returns 1 if it ends in the START state and 0 if it ends
   457         -**                 in any other state.
   458         -**
   459         -**   (1) NORMAL    We are in the middle of statement which ends with a single
   460         -**                 semicolon.
   461         -**
   462         -**   (2) EXPLAIN   The keyword EXPLAIN has been seen at the beginning of 
   463         -**                 a statement.
   464         -**
   465         -**   (3) CREATE    The keyword CREATE has been seen at the beginning of a
   466         -**                 statement, possibly preceeded by EXPLAIN and/or followed by
   467         -**                 TEMP or TEMPORARY
   468         -**
   469         -**   (4) TRIGGER   We are in the middle of a trigger definition that must be
   470         -**                 ended by a semicolon, the keyword END, and another semicolon.
   471         -**
   472         -**   (5) SEMI      We've seen the first semicolon in the ";END;" that occurs at
   473         -**                 the end of a trigger definition.
   474         -**
   475         -**   (6) END       We've seen the ";END" of the ";END;" that occurs at the end
   476         -**                 of a trigger difinition.
   477         -**
   478         -** Transitions between states above are determined by tokens extracted
   479         -** from the input.  The following tokens are significant:
   480         -**
   481         -**   (0) tkSEMI      A semicolon.
   482         -**   (1) tkWS        Whitespace
   483         -**   (2) tkOTHER     Any other SQL token.
   484         -**   (3) tkEXPLAIN   The "explain" keyword.
   485         -**   (4) tkCREATE    The "create" keyword.
   486         -**   (5) tkTEMP      The "temp" or "temporary" keyword.
   487         -**   (6) tkTRIGGER   The "trigger" keyword.
   488         -**   (7) tkEND       The "end" keyword.
   489         -**
   490         -** Whitespace never causes a state transition and is always ignored.
   491         -**
   492         -** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed
   493         -** to recognize the end of a trigger can be omitted.  All we have to do
   494         -** is look for a semicolon that is not part of an string or comment.
   495         -*/
   496         -int sqlite3_complete(const char *zSql){
   497         -  u8 state = 0;   /* Current state, using numbers defined in header comment */
   498         -  u8 token;       /* Value of the next token */
   499         -
   500         -#ifndef SQLITE_OMIT_TRIGGER
   501         -  /* A complex statement machine used to detect the end of a CREATE TRIGGER
   502         -  ** statement.  This is the normal case.
   503         -  */
   504         -  static const u8 trans[7][8] = {
   505         -                     /* Token:                                                */
   506         -     /* State:       **  SEMI  WS  OTHER EXPLAIN  CREATE  TEMP  TRIGGER  END  */
   507         -     /* 0   START: */ {    0,  0,     1,      2,      3,    1,       1,   1,  },
   508         -     /* 1  NORMAL: */ {    0,  1,     1,      1,      1,    1,       1,   1,  },
   509         -     /* 2 EXPLAIN: */ {    0,  2,     1,      1,      3,    1,       1,   1,  },
   510         -     /* 3  CREATE: */ {    0,  3,     1,      1,      1,    3,       4,   1,  },
   511         -     /* 4 TRIGGER: */ {    5,  4,     4,      4,      4,    4,       4,   4,  },
   512         -     /* 5    SEMI: */ {    5,  5,     4,      4,      4,    4,       4,   6,  },
   513         -     /* 6     END: */ {    0,  6,     4,      4,      4,    4,       4,   4,  },
   514         -  };
   515         -#else
   516         -  /* If triggers are not suppored by this compile then the statement machine
   517         -  ** used to detect the end of a statement is much simplier
   518         -  */
   519         -  static const u8 trans[2][3] = {
   520         -                     /* Token:           */
   521         -     /* State:       **  SEMI  WS  OTHER */
   522         -     /* 0   START: */ {    0,  0,     1, },
   523         -     /* 1  NORMAL: */ {    0,  1,     1, },
   524         -  };
   525         -#endif /* SQLITE_OMIT_TRIGGER */
   526         -
   527         -  while( *zSql ){
   528         -    switch( *zSql ){
   529         -      case ';': {  /* A semicolon */
   530         -        token = tkSEMI;
   531         -        break;
   532         -      }
   533         -      case ' ':
   534         -      case '\r':
   535         -      case '\t':
   536         -      case '\n':
   537         -      case '\f': {  /* White space is ignored */
   538         -        token = tkWS;
   539         -        break;
   540         -      }
   541         -      case '/': {   /* C-style comments */
   542         -        if( zSql[1]!='*' ){
   543         -          token = tkOTHER;
   544         -          break;
   545         -        }
   546         -        zSql += 2;
   547         -        while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; }
   548         -        if( zSql[0]==0 ) return 0;
   549         -        zSql++;
   550         -        token = tkWS;
   551         -        break;
   552         -      }
   553         -      case '-': {   /* SQL-style comments from "--" to end of line */
   554         -        if( zSql[1]!='-' ){
   555         -          token = tkOTHER;
   556         -          break;
   557         -        }
   558         -        while( *zSql && *zSql!='\n' ){ zSql++; }
   559         -        if( *zSql==0 ) return state==0;
   560         -        token = tkWS;
   561         -        break;
   562         -      }
   563         -      case '[': {   /* Microsoft-style identifiers in [...] */
   564         -        zSql++;
   565         -        while( *zSql && *zSql!=']' ){ zSql++; }
   566         -        if( *zSql==0 ) return 0;
   567         -        token = tkOTHER;
   568         -        break;
   569         -      }
   570         -      case '`':     /* Grave-accent quoted symbols used by MySQL */
   571         -      case '"':     /* single- and double-quoted strings */
   572         -      case '\'': {
   573         -        int c = *zSql;
   574         -        zSql++;
   575         -        while( *zSql && *zSql!=c ){ zSql++; }
   576         -        if( *zSql==0 ) return 0;
   577         -        token = tkOTHER;
   578         -        break;
   579         -      }
   580         -      default: {
   581         -        int c;
   582         -        if( IdChar((u8)*zSql) ){
   583         -          /* Keywords and unquoted identifiers */
   584         -          int nId;
   585         -          for(nId=1; IdChar(zSql[nId]); nId++){}
   586         -#ifdef SQLITE_OMIT_TRIGGER
   587         -          token = tkOTHER;
   588         -#else
   589         -          switch( *zSql ){
   590         -            case 'c': case 'C': {
   591         -              if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){
   592         -                token = tkCREATE;
   593         -              }else{
   594         -                token = tkOTHER;
   595         -              }
   596         -              break;
   597         -            }
   598         -            case 't': case 'T': {
   599         -              if( nId==7 && sqlite3StrNICmp(zSql, "trigger", 7)==0 ){
   600         -                token = tkTRIGGER;
   601         -              }else if( nId==4 && sqlite3StrNICmp(zSql, "temp", 4)==0 ){
   602         -                token = tkTEMP;
   603         -              }else if( nId==9 && sqlite3StrNICmp(zSql, "temporary", 9)==0 ){
   604         -                token = tkTEMP;
   605         -              }else{
   606         -                token = tkOTHER;
   607         -              }
   608         -              break;
   609         -            }
   610         -            case 'e':  case 'E': {
   611         -              if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){
   612         -                token = tkEND;
   613         -              }else
   614         -#ifndef SQLITE_OMIT_EXPLAIN
   615         -              if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){
   616         -                token = tkEXPLAIN;
   617         -              }else
   618         -#endif
   619         -              {
   620         -                token = tkOTHER;
   621         -              }
   622         -              break;
   623         -            }
   624         -            default: {
   625         -              token = tkOTHER;
   626         -              break;
   627         -            }
   628         -          }
   629         -#endif /* SQLITE_OMIT_TRIGGER */
   630         -          zSql += nId-1;
   631         -        }else{
   632         -          /* Operators and special symbols */
   633         -          token = tkOTHER;
   634         -        }
   635         -        break;
   636         -      }
   637         -    }
   638         -    state = trans[state][token];
   639         -    zSql++;
   640         -  }
   641         -  return state==0;
   642         -}
   643         -
   644         -#ifndef SQLITE_OMIT_UTF16
   645         -/*
   646         -** This routine is the same as the sqlite3_complete() routine described
   647         -** above, except that the parameter is required to be UTF-16 encoded, not
   648         -** UTF-8.
   649         -*/
   650         -int sqlite3_complete16(const void *zSql){
   651         -  sqlite3_value *pVal;
   652         -  char const *zSql8;
   653         -  int rc = 0;
   654         -
   655         -  pVal = sqlite3ValueNew();
   656         -  sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
   657         -  zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8);
   658         -  if( zSql8 ){
   659         -    rc = sqlite3_complete(zSql8);
   660         -  }
   661         -  sqlite3ValueFree(pVal);
   662         -  return rc;
   663         -}
   664         -#endif /* SQLITE_OMIT_UTF16 */
   665         -#endif /* SQLITE_OMIT_COMPLETE */