/ Hex Artifact Content
Login

Artifact 79f2a7fbb3f672fa032e5a432ca274ea3ee93c34:


0000: 2f 2a 0a 2a 2a 20 32 30 31 31 20 4a 75 6e 20 31  /*.** 2011 Jun 1
0010: 33 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68  3.**.** The auth
0020: 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70  or disclaims cop
0030: 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73  yright to this s
0040: 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20  ource code.  In 
0050: 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65  place of.** a le
0060: 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65  gal notice, here
0070: 20 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a   is a blessing:.
0080: 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75  **.**    May you
0090: 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74   do good and not
00a0: 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79   evil..**    May
00b0: 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76   you find forgiv
00c0: 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65  eness for yourse
00d0: 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f  lf and forgive o
00e0: 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79  thers..**    May
00f0: 20 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c   you share freel
0100: 79 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20  y, never taking 
0110: 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69  more than you gi
0120: 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ve..**.*********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73  *****.**.** This
0180: 20 66 69 6c 65 20 69 73 20 6e 6f 74 20 70 61 72   file is not par
0190: 74 20 6f 66 20 74 68 65 20 70 72 6f 64 75 63 74  t of the product
01a0: 69 6f 6e 20 46 54 53 20 63 6f 64 65 2e 20 49 74  ion FTS code. It
01b0: 20 69 73 20 6f 6e 6c 79 20 75 73 65 64 20 66 6f   is only used fo
01c0: 72 0a 2a 2a 20 74 65 73 74 69 6e 67 2e 20 49 74  r.** testing. It
01d0: 20 63 6f 6e 74 61 69 6e 73 20 61 20 54 63 6c 20   contains a Tcl 
01e0: 63 6f 6d 6d 61 6e 64 20 74 68 61 74 20 63 61 6e  command that can
01f0: 20 62 65 20 75 73 65 64 20 74 6f 20 74 65 73 74   be used to test
0200: 20 69 66 20 61 20 64 6f 63 75 6d 65 6e 74 0a 2a   if a document.*
0210: 2a 20 6d 61 74 63 68 65 73 20 61 6e 20 46 54 53  * matches an FTS
0220: 20 4e 45 41 52 20 65 78 70 72 65 73 73 69 6f 6e   NEAR expression
0230: 2e 0a 2a 2a 0a 2a 2a 20 41 73 20 6f 66 20 4d 61  ..**.** As of Ma
0240: 72 63 68 20 32 30 31 32 2c 20 69 74 20 61 6c 73  rch 2012, it als
0250: 6f 20 63 6f 6e 74 61 69 6e 73 20 61 20 76 65 72  o contains a ver
0260: 73 69 6f 6e 20 31 20 74 6f 6b 65 6e 69 7a 65 72  sion 1 tokenizer
0270: 20 75 73 65 64 20 66 6f 72 20 74 65 73 74 69 6e   used for testin
0280: 67 0a 2a 2a 20 74 68 61 74 20 74 68 65 20 73 71  g.** that the sq
0290: 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f  lite3_tokenizer_
02a0: 6d 6f 64 75 6c 65 2e 78 4c 61 6e 67 75 61 67 65  module.xLanguage
02b0: 28 29 20 6d 65 74 68 6f 64 20 69 73 20 69 6e 76  () method is inv
02c0: 6f 6b 65 64 20 63 6f 72 72 65 63 74 6c 79 2e 0a  oked correctly..
02d0: 2a 2f 0a 0a 23 69 66 20 64 65 66 69 6e 65 64 28  */..#if defined(
02e0: 49 4e 43 4c 55 44 45 5f 53 51 4c 49 54 45 5f 54  INCLUDE_SQLITE_T
02f0: 43 4c 5f 48 29 0a 23 20 20 69 6e 63 6c 75 64 65  CL_H).#  include
0300: 20 22 73 71 6c 69 74 65 5f 74 63 6c 2e 68 22 0a   "sqlite_tcl.h".
0310: 23 65 6c 73 65 0a 23 20 20 69 6e 63 6c 75 64 65  #else.#  include
0320: 20 22 74 63 6c 2e 68 22 0a 23 20 20 69 66 6e 64   "tcl.h".#  ifnd
0330: 65 66 20 53 51 4c 49 54 45 5f 54 43 4c 41 50 49  ef SQLITE_TCLAPI
0340: 0a 23 20 20 20 20 64 65 66 69 6e 65 20 53 51 4c  .#    define SQL
0350: 49 54 45 5f 54 43 4c 41 50 49 0a 23 20 20 65 6e  ITE_TCLAPI.#  en
0360: 64 69 66 0a 23 65 6e 64 69 66 0a 23 69 6e 63 6c  dif.#endif.#incl
0370: 75 64 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23  ude <string.h>.#
0380: 69 6e 63 6c 75 64 65 20 3c 61 73 73 65 72 74 2e  include <assert.
0390: 68 3e 0a 0a 23 69 66 20 64 65 66 69 6e 65 64 28  h>..#if defined(
03a0: 53 51 4c 49 54 45 5f 54 45 53 54 29 0a 23 69 66  SQLITE_TEST).#if
03b0: 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f   defined(SQLITE_
03c0: 45 4e 41 42 4c 45 5f 46 54 53 33 29 20 7c 7c 20  ENABLE_FTS3) || 
03d0: 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 45  defined(SQLITE_E
03e0: 4e 41 42 4c 45 5f 46 54 53 34 29 0a 0a 2f 2a 20  NABLE_FTS4)../* 
03f0: 52 65 71 75 69 72 65 64 20 73 6f 20 74 68 61 74  Required so that
0400: 20 74 68 65 20 22 69 66 64 65 66 20 53 51 4c 49   the "ifdef SQLI
0410: 54 45 5f 45 4e 41 42 4c 45 5f 46 54 53 33 22 20  TE_ENABLE_FTS3" 
0420: 62 65 6c 6f 77 20 77 6f 72 6b 73 20 2a 2f 0a 23  below works */.#
0430: 69 6e 63 6c 75 64 65 20 22 66 74 73 33 49 6e 74  include "fts3Int
0440: 2e 68 22 0a 0a 23 64 65 66 69 6e 65 20 4e 4d 5f  .h"..#define NM_
0450: 4d 41 58 5f 54 4f 4b 45 4e 20 31 32 0a 0a 74 79  MAX_TOKEN 12..ty
0460: 70 65 64 65 66 20 73 74 72 75 63 74 20 4e 65 61  pedef struct Nea
0470: 72 50 68 72 61 73 65 20 4e 65 61 72 50 68 72 61  rPhrase NearPhra
0480: 73 65 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75  se;.typedef stru
0490: 63 74 20 4e 65 61 72 44 6f 63 75 6d 65 6e 74 20  ct NearDocument 
04a0: 4e 65 61 72 44 6f 63 75 6d 65 6e 74 3b 0a 74 79  NearDocument;.ty
04b0: 70 65 64 65 66 20 73 74 72 75 63 74 20 4e 65 61  pedef struct Nea
04c0: 72 54 6f 6b 65 6e 20 4e 65 61 72 54 6f 6b 65 6e  rToken NearToken
04d0: 3b 0a 0a 73 74 72 75 63 74 20 4e 65 61 72 44 6f  ;..struct NearDo
04e0: 63 75 6d 65 6e 74 20 7b 0a 20 20 69 6e 74 20 6e  cument {.  int n
04f0: 54 6f 6b 65 6e 3b 20 20 20 20 20 20 20 20 20 20  Token;          
0500: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 65             /* Le
0510: 6e 67 74 68 20 6f 66 20 74 6f 6b 65 6e 20 69 6e  ngth of token in
0520: 20 62 79 74 65 73 20 2a 2f 0a 20 20 4e 65 61 72   bytes */.  Near
0530: 54 6f 6b 65 6e 20 2a 61 54 6f 6b 65 6e 3b 20 20  Token *aToken;  
0540: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
0550: 6f 6b 65 6e 20 61 72 72 61 79 20 2a 2f 0a 7d 3b  oken array */.};
0560: 0a 0a 73 74 72 75 63 74 20 4e 65 61 72 54 6f 6b  ..struct NearTok
0570: 65 6e 20 7b 0a 20 20 69 6e 74 20 6e 3b 20 20 20  en {.  int n;   
0580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0590: 20 20 20 20 20 20 20 2f 2a 20 4c 65 6e 67 74 68         /* Length
05a0: 20 6f 66 20 74 6f 6b 65 6e 20 69 6e 20 62 79 74   of token in byt
05b0: 65 73 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  es */.  const ch
05c0: 61 72 20 2a 7a 3b 20 20 20 20 20 20 20 20 20 20  ar *z;          
05d0: 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74          /* Point
05e0: 65 72 20 74 6f 20 74 6f 6b 65 6e 20 73 74 72 69  er to token stri
05f0: 6e 67 20 2a 2f 0a 7d 3b 0a 0a 73 74 72 75 63 74  ng */.};..struct
0600: 20 4e 65 61 72 50 68 72 61 73 65 20 7b 0a 20 20   NearPhrase {.  
0610: 69 6e 74 20 6e 4e 65 61 72 3b 20 20 20 20 20 20  int nNear;      
0620: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0630: 2f 2a 20 50 72 65 63 65 64 69 6e 67 20 4e 45 41  /* Preceding NEA
0640: 52 20 76 61 6c 75 65 20 2a 2f 0a 20 20 69 6e 74  R value */.  int
0650: 20 6e 54 6f 6b 65 6e 3b 20 20 20 20 20 20 20 20   nToken;        
0660: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0670: 4e 75 6d 62 65 72 20 6f 66 20 74 6f 6b 65 6e 73  Number of tokens
0680: 20 69 6e 20 74 68 69 73 20 70 68 72 61 73 65 20   in this phrase 
0690: 2a 2f 0a 20 20 4e 65 61 72 54 6f 6b 65 6e 20 61  */.  NearToken a
06a0: 54 6f 6b 65 6e 5b 4e 4d 5f 4d 41 58 5f 54 4f 4b  Token[NM_MAX_TOK
06b0: 45 4e 5d 3b 20 2f 2a 20 41 72 72 61 79 20 6f 66  EN]; /* Array of
06c0: 20 74 6f 6b 65 6e 73 20 69 6e 20 74 68 69 73 20   tokens in this 
06d0: 70 68 72 61 73 65 20 2a 2f 0a 7d 3b 0a 0a 73 74  phrase */.};..st
06e0: 61 74 69 63 20 69 6e 74 20 6e 6d 5f 70 68 72 61  atic int nm_phra
06f0: 73 65 5f 6d 61 74 63 68 28 0a 20 20 4e 65 61 72  se_match(.  Near
0700: 50 68 72 61 73 65 20 2a 70 2c 0a 20 20 4e 65 61  Phrase *p,.  Nea
0710: 72 54 6f 6b 65 6e 20 2a 61 54 6f 6b 65 6e 0a 29  rToken *aToken.)
0720: 7b 0a 20 20 69 6e 74 20 69 69 3b 0a 0a 20 20 66  {.  int ii;..  f
0730: 6f 72 28 69 69 3d 30 3b 20 69 69 3c 70 2d 3e 6e  or(ii=0; ii<p->n
0740: 54 6f 6b 65 6e 3b 20 69 69 2b 2b 29 7b 0a 20 20  Token; ii++){.  
0750: 20 20 4e 65 61 72 54 6f 6b 65 6e 20 2a 70 54 6f    NearToken *pTo
0760: 6b 65 6e 20 3d 20 26 70 2d 3e 61 54 6f 6b 65 6e  ken = &p->aToken
0770: 5b 69 69 5d 3b 0a 20 20 20 20 69 66 28 20 70 54  [ii];.    if( pT
0780: 6f 6b 65 6e 2d 3e 6e 3e 30 20 26 26 20 70 54 6f  oken->n>0 && pTo
0790: 6b 65 6e 2d 3e 7a 5b 70 54 6f 6b 65 6e 2d 3e 6e  ken->z[pToken->n
07a0: 2d 31 5d 3d 3d 27 2a 27 20 29 7b 0a 20 20 20 20  -1]=='*' ){.    
07b0: 20 20 69 66 28 20 61 54 6f 6b 65 6e 5b 69 69 5d    if( aToken[ii]
07c0: 2e 6e 3c 28 70 54 6f 6b 65 6e 2d 3e 6e 2d 31 29  .n<(pToken->n-1)
07d0: 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20   ) return 0;.   
07e0: 20 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 61 54     if( memcmp(aT
07f0: 6f 6b 65 6e 5b 69 69 5d 2e 7a 2c 20 70 54 6f 6b  oken[ii].z, pTok
0800: 65 6e 2d 3e 7a 2c 20 70 54 6f 6b 65 6e 2d 3e 6e  en->z, pToken->n
0810: 2d 31 29 20 29 20 72 65 74 75 72 6e 20 30 3b 0a  -1) ) return 0;.
0820: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
0830: 20 69 66 28 20 61 54 6f 6b 65 6e 5b 69 69 5d 2e   if( aToken[ii].
0840: 6e 21 3d 70 54 6f 6b 65 6e 2d 3e 6e 20 29 20 72  n!=pToken->n ) r
0850: 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 20 20 69  eturn 0;.      i
0860: 66 28 20 6d 65 6d 63 6d 70 28 61 54 6f 6b 65 6e  f( memcmp(aToken
0870: 5b 69 69 5d 2e 7a 2c 20 70 54 6f 6b 65 6e 2d 3e  [ii].z, pToken->
0880: 7a 2c 20 70 54 6f 6b 65 6e 2d 3e 6e 29 20 29 20  z, pToken->n) ) 
0890: 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 7d 0a  return 0;.    }.
08a0: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 31 3b    }..  return 1;
08b0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 6e  .}..static int n
08c0: 6d 5f 6e 65 61 72 5f 63 68 61 69 6e 28 0a 20 20  m_near_chain(.  
08d0: 69 6e 74 20 69 44 69 72 2c 20 20 20 20 20 20 20  int iDir,       
08e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
08f0: 2f 2a 20 44 69 72 65 63 74 69 6f 6e 20 74 6f 20  /* Direction to 
0900: 69 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20  iterate through 
0910: 61 50 68 72 61 73 65 5b 5d 20 2a 2f 0a 20 20 4e  aPhrase[] */.  N
0920: 65 61 72 44 6f 63 75 6d 65 6e 74 20 2a 70 44 6f  earDocument *pDo
0930: 63 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  c,             /
0940: 2a 20 44 6f 63 75 6d 65 6e 74 20 74 6f 20 6d 61  * Document to ma
0950: 74 63 68 20 61 67 61 69 6e 73 74 20 2a 2f 0a 20  tch against */. 
0960: 20 69 6e 74 20 69 50 6f 73 2c 20 20 20 20 20 20   int iPos,      
0970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0980: 20 2f 2a 20 50 6f 73 69 74 69 6f 6e 20 61 74 20   /* Position at 
0990: 77 68 69 63 68 20 69 50 68 72 61 73 65 20 77 61  which iPhrase wa
09a0: 73 20 66 6f 75 6e 64 20 2a 2f 0a 20 20 69 6e 74  s found */.  int
09b0: 20 6e 50 68 72 61 73 65 2c 20 20 20 20 20 20 20   nPhrase,       
09c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
09d0: 53 69 7a 65 20 6f 66 20 70 68 72 61 73 65 20 61  Size of phrase a
09e0: 72 72 61 79 20 2a 2f 0a 20 20 4e 65 61 72 50 68  rray */.  NearPh
09f0: 72 61 73 65 20 2a 61 50 68 72 61 73 65 2c 20 20  rase *aPhrase,  
0a00: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 68 72            /* Phr
0a10: 61 73 65 20 61 72 72 61 79 20 2a 2f 0a 20 20 69  ase array */.  i
0a20: 6e 74 20 69 50 68 72 61 73 65 20 20 20 20 20 20  nt iPhrase      
0a30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0a40: 2a 20 49 6e 64 65 78 20 6f 66 20 70 68 72 61 73  * Index of phras
0a50: 65 20 66 6f 75 6e 64 20 2a 2f 0a 29 7b 0a 20 20  e found */.){.  
0a60: 69 6e 74 20 69 53 74 61 72 74 3b 0a 20 20 69 6e  int iStart;.  in
0a70: 74 20 69 53 74 6f 70 3b 0a 20 20 69 6e 74 20 69  t iStop;.  int i
0a80: 69 3b 0a 20 20 69 6e 74 20 6e 4e 65 61 72 3b 0a  i;.  int nNear;.
0a90: 20 20 69 6e 74 20 69 50 68 72 61 73 65 32 3b 0a    int iPhrase2;.
0aa0: 20 20 4e 65 61 72 50 68 72 61 73 65 20 2a 70 3b    NearPhrase *p;
0ab0: 0a 20 20 4e 65 61 72 50 68 72 61 73 65 20 2a 70  .  NearPhrase *p
0ac0: 50 72 65 76 3b 0a 0a 20 20 61 73 73 65 72 74 28  Prev;..  assert(
0ad0: 20 69 44 69 72 3d 3d 31 20 7c 7c 20 69 44 69 72   iDir==1 || iDir
0ae0: 3d 3d 2d 31 20 29 3b 0a 0a 20 20 69 66 28 20 69  ==-1 );..  if( i
0af0: 44 69 72 3d 3d 31 20 29 7b 0a 20 20 20 20 69 66  Dir==1 ){.    if
0b00: 28 20 28 69 50 68 72 61 73 65 2b 31 29 3d 3d 6e  ( (iPhrase+1)==n
0b10: 50 68 72 61 73 65 20 29 20 72 65 74 75 72 6e 20  Phrase ) return 
0b20: 31 3b 0a 20 20 20 20 6e 4e 65 61 72 20 3d 20 61  1;.    nNear = a
0b30: 50 68 72 61 73 65 5b 69 50 68 72 61 73 65 2b 31  Phrase[iPhrase+1
0b40: 5d 2e 6e 4e 65 61 72 3b 0a 20 20 7d 65 6c 73 65  ].nNear;.  }else
0b50: 7b 0a 20 20 20 20 69 66 28 20 69 50 68 72 61 73  {.    if( iPhras
0b60: 65 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 31 3b  e==0 ) return 1;
0b70: 0a 20 20 20 20 6e 4e 65 61 72 20 3d 20 61 50 68  .    nNear = aPh
0b80: 72 61 73 65 5b 69 50 68 72 61 73 65 5d 2e 6e 4e  rase[iPhrase].nN
0b90: 65 61 72 3b 0a 20 20 7d 0a 20 20 70 50 72 65 76  ear;.  }.  pPrev
0ba0: 20 3d 20 26 61 50 68 72 61 73 65 5b 69 50 68 72   = &aPhrase[iPhr
0bb0: 61 73 65 5d 3b 0a 20 20 69 50 68 72 61 73 65 32  ase];.  iPhrase2
0bc0: 20 3d 20 69 50 68 72 61 73 65 2b 69 44 69 72 3b   = iPhrase+iDir;
0bd0: 0a 20 20 70 20 3d 20 26 61 50 68 72 61 73 65 5b  .  p = &aPhrase[
0be0: 69 50 68 72 61 73 65 32 5d 3b 0a 0a 20 20 69 53  iPhrase2];..  iS
0bf0: 74 61 72 74 20 3d 20 69 50 6f 73 20 2d 20 6e 4e  tart = iPos - nN
0c00: 65 61 72 20 2d 20 70 2d 3e 6e 54 6f 6b 65 6e 3b  ear - p->nToken;
0c10: 0a 20 20 69 53 74 6f 70 20 3d 20 69 50 6f 73 20  .  iStop = iPos 
0c20: 2b 20 6e 4e 65 61 72 20 2b 20 70 50 72 65 76 2d  + nNear + pPrev-
0c30: 3e 6e 54 6f 6b 65 6e 3b 0a 0a 20 20 69 66 28 20  >nToken;..  if( 
0c40: 69 53 74 61 72 74 3c 30 20 29 20 69 53 74 61 72  iStart<0 ) iStar
0c50: 74 20 3d 20 30 3b 0a 20 20 69 66 28 20 69 53 74  t = 0;.  if( iSt
0c60: 6f 70 20 3e 20 70 44 6f 63 2d 3e 6e 54 6f 6b 65  op > pDoc->nToke
0c70: 6e 20 2d 20 70 2d 3e 6e 54 6f 6b 65 6e 20 29 20  n - p->nToken ) 
0c80: 69 53 74 6f 70 20 3d 20 70 44 6f 63 2d 3e 6e 54  iStop = pDoc->nT
0c90: 6f 6b 65 6e 20 2d 20 70 2d 3e 6e 54 6f 6b 65 6e  oken - p->nToken
0ca0: 3b 0a 0a 20 20 66 6f 72 28 69 69 3d 69 53 74 61  ;..  for(ii=iSta
0cb0: 72 74 3b 20 69 69 3c 3d 69 53 74 6f 70 3b 20 69  rt; ii<=iStop; i
0cc0: 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 6e 6d  i++){.    if( nm
0cd0: 5f 70 68 72 61 73 65 5f 6d 61 74 63 68 28 70 2c  _phrase_match(p,
0ce0: 20 26 70 44 6f 63 2d 3e 61 54 6f 6b 65 6e 5b 69   &pDoc->aToken[i
0cf0: 69 5d 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28  i]) ){.      if(
0d00: 20 6e 6d 5f 6e 65 61 72 5f 63 68 61 69 6e 28 69   nm_near_chain(i
0d10: 44 69 72 2c 20 70 44 6f 63 2c 20 69 69 2c 20 6e  Dir, pDoc, ii, n
0d20: 50 68 72 61 73 65 2c 20 61 50 68 72 61 73 65 2c  Phrase, aPhrase,
0d30: 20 69 50 68 72 61 73 65 32 29 20 29 20 72 65 74   iPhrase2) ) ret
0d40: 75 72 6e 20 31 3b 0a 20 20 20 20 7d 0a 20 20 7d  urn 1;.    }.  }
0d50: 0a 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a  ..  return 0;.}.
0d60: 0a 73 74 61 74 69 63 20 69 6e 74 20 6e 6d 5f 6d  .static int nm_m
0d70: 61 74 63 68 5f 63 6f 75 6e 74 28 0a 20 20 4e 65  atch_count(.  Ne
0d80: 61 72 44 6f 63 75 6d 65 6e 74 20 2a 70 44 6f 63  arDocument *pDoc
0d90: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ,             /*
0da0: 20 44 6f 63 75 6d 65 6e 74 20 74 6f 20 6d 61 74   Document to mat
0db0: 63 68 20 61 67 61 69 6e 73 74 20 2a 2f 0a 20 20  ch against */.  
0dc0: 69 6e 74 20 6e 50 68 72 61 73 65 2c 20 20 20 20  int nPhrase,    
0dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0de0: 2f 2a 20 53 69 7a 65 20 6f 66 20 70 68 72 61 73  /* Size of phras
0df0: 65 20 61 72 72 61 79 20 2a 2f 0a 20 20 4e 65 61  e array */.  Nea
0e00: 72 50 68 72 61 73 65 20 2a 61 50 68 72 61 73 65  rPhrase *aPhrase
0e10: 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ,            /* 
0e20: 50 68 72 61 73 65 20 61 72 72 61 79 20 2a 2f 0a  Phrase array */.
0e30: 20 20 69 6e 74 20 69 50 68 72 61 73 65 20 20 20    int iPhrase   
0e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e50: 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20 70 68    /* Index of ph
0e60: 72 61 73 65 20 74 6f 20 63 6f 75 6e 74 20 6d 61  rase to count ma
0e70: 74 63 68 65 73 20 66 6f 72 20 2a 2f 0a 29 7b 0a  tches for */.){.
0e80: 20 20 69 6e 74 20 6e 4f 63 63 20 3d 20 30 3b 0a    int nOcc = 0;.
0e90: 20 20 69 6e 74 20 69 69 3b 0a 20 20 4e 65 61 72    int ii;.  Near
0ea0: 50 68 72 61 73 65 20 2a 70 20 3d 20 26 61 50 68  Phrase *p = &aPh
0eb0: 72 61 73 65 5b 69 50 68 72 61 73 65 5d 3b 0a 0a  rase[iPhrase];..
0ec0: 20 20 66 6f 72 28 69 69 3d 30 3b 20 69 69 3c 28    for(ii=0; ii<(
0ed0: 70 44 6f 63 2d 3e 6e 54 6f 6b 65 6e 20 2b 20 31  pDoc->nToken + 1
0ee0: 20 2d 20 70 2d 3e 6e 54 6f 6b 65 6e 29 3b 20 69   - p->nToken); i
0ef0: 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 6e 6d  i++){.    if( nm
0f00: 5f 70 68 72 61 73 65 5f 6d 61 74 63 68 28 70 2c  _phrase_match(p,
0f10: 20 26 70 44 6f 63 2d 3e 61 54 6f 6b 65 6e 5b 69   &pDoc->aToken[i
0f20: 69 5d 29 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20  i]) ){.      /* 
0f30: 54 65 73 74 20 66 6f 72 77 61 72 64 20 4e 45 41  Test forward NEA
0f40: 52 20 63 68 61 69 6e 20 28 69 3e 69 50 68 72 61  R chain (i>iPhra
0f50: 73 65 29 20 2a 2f 0a 20 20 20 20 20 20 69 66 28  se) */.      if(
0f60: 20 30 3d 3d 6e 6d 5f 6e 65 61 72 5f 63 68 61 69   0==nm_near_chai
0f70: 6e 28 31 2c 20 70 44 6f 63 2c 20 69 69 2c 20 6e  n(1, pDoc, ii, n
0f80: 50 68 72 61 73 65 2c 20 61 50 68 72 61 73 65 2c  Phrase, aPhrase,
0f90: 20 69 50 68 72 61 73 65 29 20 29 20 63 6f 6e 74   iPhrase) ) cont
0fa0: 69 6e 75 65 3b 0a 0a 20 20 20 20 20 20 2f 2a 20  inue;..      /* 
0fb0: 54 65 73 74 20 72 65 76 65 72 73 65 20 4e 45 41  Test reverse NEA
0fc0: 52 20 63 68 61 69 6e 20 28 69 3c 69 50 68 72 61  R chain (i<iPhra
0fd0: 73 65 29 20 2a 2f 0a 20 20 20 20 20 20 69 66 28  se) */.      if(
0fe0: 20 30 3d 3d 6e 6d 5f 6e 65 61 72 5f 63 68 61 69   0==nm_near_chai
0ff0: 6e 28 2d 31 2c 20 70 44 6f 63 2c 20 69 69 2c 20  n(-1, pDoc, ii, 
1000: 6e 50 68 72 61 73 65 2c 20 61 50 68 72 61 73 65  nPhrase, aPhrase
1010: 2c 20 69 50 68 72 61 73 65 29 20 29 20 63 6f 6e  , iPhrase) ) con
1020: 74 69 6e 75 65 3b 0a 0a 20 20 20 20 20 20 2f 2a  tinue;..      /*
1030: 20 54 68 69 73 20 69 73 20 61 20 72 65 61 6c 20   This is a real 
1040: 6d 61 74 63 68 2e 20 49 6e 63 72 65 6d 65 6e 74  match. Increment
1050: 20 74 68 65 20 63 6f 75 6e 74 65 72 2e 20 2a 2f   the counter. */
1060: 0a 20 20 20 20 20 20 6e 4f 63 63 2b 2b 3b 0a 20  .      nOcc++;. 
1070: 20 20 20 7d 0a 20 20 7d 20 0a 0a 20 20 72 65 74     }.  } ..  ret
1080: 75 72 6e 20 6e 4f 63 63 3b 0a 7d 0a 0a 2f 2a 0a  urn nOcc;.}../*.
1090: 2a 2a 20 54 63 6c 63 6d 64 3a 20 66 74 73 33 5f  ** Tclcmd: fts3_
10a0: 6e 65 61 72 5f 6d 61 74 63 68 20 44 4f 43 55 4d  near_match DOCUM
10b0: 45 4e 54 20 45 58 50 52 20 3f 4f 50 54 49 4f 4e  ENT EXPR ?OPTION
10c0: 53 3f 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  S?.*/.static int
10d0: 20 53 51 4c 49 54 45 5f 54 43 4c 41 50 49 20 66   SQLITE_TCLAPI f
10e0: 74 73 33 5f 6e 65 61 72 5f 6d 61 74 63 68 5f 63  ts3_near_match_c
10f0: 6d 64 28 0a 20 20 43 6c 69 65 6e 74 44 61 74 61  md(.  ClientData
1100: 20 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20 54   clientData,.  T
1110: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
1120: 70 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20  p,.  int objc,. 
1130: 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20   Tcl_Obj *CONST 
1140: 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20 69 6e 74 20  objv[].){.  int 
1150: 6e 54 6f 74 61 6c 20 3d 20 30 3b 0a 20 20 69 6e  nTotal = 0;.  in
1160: 74 20 72 63 3b 0a 20 20 69 6e 74 20 69 69 3b 0a  t rc;.  int ii;.
1170: 20 20 69 6e 74 20 6e 50 68 72 61 73 65 3b 0a 20    int nPhrase;. 
1180: 20 4e 65 61 72 50 68 72 61 73 65 20 2a 61 50 68   NearPhrase *aPh
1190: 72 61 73 65 20 3d 20 30 3b 0a 20 20 4e 65 61 72  rase = 0;.  Near
11a0: 44 6f 63 75 6d 65 6e 74 20 64 6f 63 20 3d 20 7b  Document doc = {
11b0: 30 2c 20 30 7d 3b 0a 20 20 54 63 6c 5f 4f 62 6a  0, 0};.  Tcl_Obj
11c0: 20 2a 2a 61 70 44 6f 63 54 6f 6b 65 6e 3b 0a 20   **apDocToken;. 
11d0: 20 54 63 6c 5f 4f 62 6a 20 2a 70 52 65 74 3b 0a   Tcl_Obj *pRet;.
11e0: 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 50 68 72 61    Tcl_Obj *pPhra
11f0: 73 65 63 6f 75 6e 74 20 3d 20 30 3b 0a 20 20 0a  secount = 0;.  .
1200: 20 20 54 63 6c 5f 4f 62 6a 20 2a 2a 61 70 45 78    Tcl_Obj **apEx
1210: 70 72 54 6f 6b 65 6e 3b 0a 20 20 69 6e 74 20 6e  prToken;.  int n
1220: 45 78 70 72 54 6f 6b 65 6e 3b 0a 0a 20 20 55 4e  ExprToken;..  UN
1230: 55 53 45 44 5f 50 41 52 41 4d 45 54 45 52 28 63  USED_PARAMETER(c
1240: 6c 69 65 6e 74 44 61 74 61 29 3b 0a 0a 20 20 2f  lientData);..  /
1250: 2a 20 4d 75 73 74 20 68 61 76 65 20 33 20 6f 72  * Must have 3 or
1260: 20 6d 6f 72 65 20 61 72 67 75 6d 65 6e 74 73 2e   more arguments.
1270: 20 2a 2f 0a 20 20 69 66 28 20 6f 62 6a 63 3c 33   */.  if( objc<3
1280: 20 7c 7c 20 28 6f 62 6a 63 25 32 29 3d 3d 30 20   || (objc%2)==0 
1290: 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67  ){.    Tcl_Wrong
12a0: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
12b0: 31 2c 20 6f 62 6a 76 2c 20 22 44 4f 43 55 4d 45  1, objv, "DOCUME
12c0: 4e 54 20 45 58 50 52 20 3f 4f 50 54 49 4f 4e 20  NT EXPR ?OPTION 
12d0: 56 41 4c 55 45 3f 2e 2e 2e 22 29 3b 0a 20 20 20  VALUE?...");.   
12e0: 20 72 63 20 3d 20 54 43 4c 5f 45 52 52 4f 52 3b   rc = TCL_ERROR;
12f0: 0a 20 20 20 20 67 6f 74 6f 20 6e 65 61 72 5f 6d  .    goto near_m
1300: 61 74 63 68 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20  atch_out;.  }.. 
1310: 20 66 6f 72 28 69 69 3d 33 3b 20 69 69 3c 6f 62   for(ii=3; ii<ob
1320: 6a 63 3b 20 69 69 2b 3d 32 29 7b 0a 20 20 20 20  jc; ii+=2){.    
1330: 65 6e 75 6d 20 4e 4d 5f 65 6e 75 6d 20 7b 20 4e  enum NM_enum { N
1340: 4d 5f 50 48 52 41 53 45 43 4f 55 4e 54 53 20 7d  M_PHRASECOUNTS }
1350: 3b 0a 20 20 20 20 73 74 72 75 63 74 20 54 65 73  ;.    struct Tes
1360: 74 6e 6d 53 75 62 63 6d 64 20 7b 0a 20 20 20 20  tnmSubcmd {.    
1370: 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20    char *zName;. 
1380: 20 20 20 20 20 65 6e 75 6d 20 4e 4d 5f 65 6e 75       enum NM_enu
1390: 6d 20 65 4f 70 74 3b 0a 20 20 20 20 7d 20 61 4f  m eOpt;.    } aO
13a0: 70 74 5b 5d 20 3d 20 7b 0a 20 20 20 20 20 20 7b  pt[] = {.      {
13b0: 20 22 2d 70 68 72 61 73 65 63 6f 75 6e 74 76 61   "-phrasecountva
13c0: 72 22 2c 20 4e 4d 5f 50 48 52 41 53 45 43 4f 55  r", NM_PHRASECOU
13d0: 4e 54 53 20 7d 2c 0a 20 20 20 20 20 20 7b 20 30  NTS },.      { 0
13e0: 2c 20 30 20 7d 0a 20 20 20 20 7d 3b 0a 20 20 20  , 0 }.    };.   
13f0: 20 69 6e 74 20 69 4f 70 74 3b 0a 20 20 20 20 69   int iOpt;.    i
1400: 66 28 20 54 63 6c 5f 47 65 74 49 6e 64 65 78 46  f( Tcl_GetIndexF
1410: 72 6f 6d 4f 62 6a 53 74 72 75 63 74 28 0a 20 20  romObjStruct(.  
1420: 20 20 20 20 20 20 69 6e 74 65 72 70 2c 20 6f 62        interp, ob
1430: 6a 76 5b 69 69 5d 2c 20 61 4f 70 74 2c 20 73 69  jv[ii], aOpt, si
1440: 7a 65 6f 66 28 61 4f 70 74 5b 30 5d 29 2c 20 22  zeof(aOpt[0]), "
1450: 6f 70 74 69 6f 6e 22 2c 20 30 2c 20 26 69 4f 70  option", 0, &iOp
1460: 74 29 20 0a 20 20 20 20 29 7b 0a 20 20 20 20 20  t) .    ){.     
1470: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
1480: 52 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 73 77  R;.    }..    sw
1490: 69 74 63 68 28 20 61 4f 70 74 5b 69 4f 70 74 5d  itch( aOpt[iOpt]
14a0: 2e 65 4f 70 74 20 29 7b 0a 20 20 20 20 20 20 63  .eOpt ){.      c
14b0: 61 73 65 20 4e 4d 5f 50 48 52 41 53 45 43 4f 55  ase NM_PHRASECOU
14c0: 4e 54 53 3a 0a 20 20 20 20 20 20 20 20 70 50 68  NTS:.        pPh
14d0: 72 61 73 65 63 6f 75 6e 74 20 3d 20 6f 62 6a 76  rasecount = objv
14e0: 5b 69 69 2b 31 5d 3b 0a 20 20 20 20 20 20 20 20  [ii+1];.        
14f0: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d  break;.    }.  }
1500: 0a 0a 20 20 72 63 20 3d 20 54 63 6c 5f 4c 69 73  ..  rc = Tcl_Lis
1510: 74 4f 62 6a 47 65 74 45 6c 65 6d 65 6e 74 73 28  tObjGetElements(
1520: 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 31 5d 2c  interp, objv[1],
1530: 20 26 64 6f 63 2e 6e 54 6f 6b 65 6e 2c 20 26 61   &doc.nToken, &a
1540: 70 44 6f 63 54 6f 6b 65 6e 29 3b 0a 20 20 69 66  pDocToken);.  if
1550: 28 20 72 63 21 3d 54 43 4c 5f 4f 4b 20 29 20 67  ( rc!=TCL_OK ) g
1560: 6f 74 6f 20 6e 65 61 72 5f 6d 61 74 63 68 5f 6f  oto near_match_o
1570: 75 74 3b 0a 20 20 64 6f 63 2e 61 54 6f 6b 65 6e  ut;.  doc.aToken
1580: 20 3d 20 28 4e 65 61 72 54 6f 6b 65 6e 20 2a 29   = (NearToken *)
1590: 63 6b 61 6c 6c 6f 63 28 64 6f 63 2e 6e 54 6f 6b  ckalloc(doc.nTok
15a0: 65 6e 2a 73 69 7a 65 6f 66 28 4e 65 61 72 54 6f  en*sizeof(NearTo
15b0: 6b 65 6e 29 29 3b 0a 20 20 66 6f 72 28 69 69 3d  ken));.  for(ii=
15c0: 30 3b 20 69 69 3c 64 6f 63 2e 6e 54 6f 6b 65 6e  0; ii<doc.nToken
15d0: 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 64 6f 63  ; ii++){.    doc
15e0: 2e 61 54 6f 6b 65 6e 5b 69 69 5d 2e 7a 20 3d 20  .aToken[ii].z = 
15f0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 46 72 6f  Tcl_GetStringFro
1600: 6d 4f 62 6a 28 61 70 44 6f 63 54 6f 6b 65 6e 5b  mObj(apDocToken[
1610: 69 69 5d 2c 20 26 64 6f 63 2e 61 54 6f 6b 65 6e  ii], &doc.aToken
1620: 5b 69 69 5d 2e 6e 29 3b 0a 20 20 7d 0a 0a 20 20  [ii].n);.  }..  
1630: 72 63 20 3d 20 54 63 6c 5f 4c 69 73 74 4f 62 6a  rc = Tcl_ListObj
1640: 47 65 74 45 6c 65 6d 65 6e 74 73 28 69 6e 74 65  GetElements(inte
1650: 72 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26 6e 45  rp, objv[2], &nE
1660: 78 70 72 54 6f 6b 65 6e 2c 20 26 61 70 45 78 70  xprToken, &apExp
1670: 72 54 6f 6b 65 6e 29 3b 0a 20 20 69 66 28 20 72  rToken);.  if( r
1680: 63 21 3d 54 43 4c 5f 4f 4b 20 29 20 67 6f 74 6f  c!=TCL_OK ) goto
1690: 20 6e 65 61 72 5f 6d 61 74 63 68 5f 6f 75 74 3b   near_match_out;
16a0: 0a 0a 20 20 6e 50 68 72 61 73 65 20 3d 20 28 6e  ..  nPhrase = (n
16b0: 45 78 70 72 54 6f 6b 65 6e 20 2b 20 31 29 20 2f  ExprToken + 1) /
16c0: 20 32 3b 0a 20 20 61 50 68 72 61 73 65 20 3d 20   2;.  aPhrase = 
16d0: 28 4e 65 61 72 50 68 72 61 73 65 20 2a 29 63 6b  (NearPhrase *)ck
16e0: 61 6c 6c 6f 63 28 6e 50 68 72 61 73 65 20 2a 20  alloc(nPhrase * 
16f0: 73 69 7a 65 6f 66 28 4e 65 61 72 50 68 72 61 73  sizeof(NearPhras
1700: 65 29 29 3b 0a 20 20 6d 65 6d 73 65 74 28 61 50  e));.  memset(aP
1710: 68 72 61 73 65 2c 20 30 2c 20 6e 50 68 72 61 73  hrase, 0, nPhras
1720: 65 20 2a 20 73 69 7a 65 6f 66 28 4e 65 61 72 50  e * sizeof(NearP
1730: 68 72 61 73 65 29 29 3b 0a 20 20 66 6f 72 28 69  hrase));.  for(i
1740: 69 3d 30 3b 20 69 69 3c 6e 50 68 72 61 73 65 3b  i=0; ii<nPhrase;
1750: 20 69 69 2b 2b 29 7b 0a 20 20 20 20 54 63 6c 5f   ii++){.    Tcl_
1760: 4f 62 6a 20 2a 70 50 68 72 61 73 65 20 3d 20 61  Obj *pPhrase = a
1770: 70 45 78 70 72 54 6f 6b 65 6e 5b 69 69 2a 32 5d  pExprToken[ii*2]
1780: 3b 0a 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a 2a  ;.    Tcl_Obj **
1790: 61 70 54 6f 6b 65 6e 3b 0a 20 20 20 20 69 6e 74  apToken;.    int
17a0: 20 6e 54 6f 6b 65 6e 3b 0a 20 20 20 20 69 6e 74   nToken;.    int
17b0: 20 6a 6a 3b 0a 0a 20 20 20 20 72 63 20 3d 20 54   jj;..    rc = T
17c0: 63 6c 5f 4c 69 73 74 4f 62 6a 47 65 74 45 6c 65  cl_ListObjGetEle
17d0: 6d 65 6e 74 73 28 69 6e 74 65 72 70 2c 20 70 50  ments(interp, pP
17e0: 68 72 61 73 65 2c 20 26 6e 54 6f 6b 65 6e 2c 20  hrase, &nToken, 
17f0: 26 61 70 54 6f 6b 65 6e 29 3b 0a 20 20 20 20 69  &apToken);.    i
1800: 66 28 20 72 63 21 3d 54 43 4c 5f 4f 4b 20 29 20  f( rc!=TCL_OK ) 
1810: 67 6f 74 6f 20 6e 65 61 72 5f 6d 61 74 63 68 5f  goto near_match_
1820: 6f 75 74 3b 0a 20 20 20 20 69 66 28 20 6e 54 6f  out;.    if( nTo
1830: 6b 65 6e 3e 4e 4d 5f 4d 41 58 5f 54 4f 4b 45 4e  ken>NM_MAX_TOKEN
1840: 20 29 7b 0a 20 20 20 20 20 20 54 63 6c 5f 41 70   ){.      Tcl_Ap
1850: 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72  pendResult(inter
1860: 70 2c 20 22 54 6f 6f 20 6d 61 6e 79 20 74 6f 6b  p, "Too many tok
1870: 65 6e 73 20 69 6e 20 70 68 72 61 73 65 22 2c 20  ens in phrase", 
1880: 30 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 54  0);.      rc = T
1890: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  CL_ERROR;.      
18a0: 67 6f 74 6f 20 6e 65 61 72 5f 6d 61 74 63 68 5f  goto near_match_
18b0: 6f 75 74 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66  out;.    }.    f
18c0: 6f 72 28 6a 6a 3d 30 3b 20 6a 6a 3c 6e 54 6f 6b  or(jj=0; jj<nTok
18d0: 65 6e 3b 20 6a 6a 2b 2b 29 7b 0a 20 20 20 20 20  en; jj++){.     
18e0: 20 4e 65 61 72 54 6f 6b 65 6e 20 2a 70 54 20 3d   NearToken *pT =
18f0: 20 26 61 50 68 72 61 73 65 5b 69 69 5d 2e 61 54   &aPhrase[ii].aT
1900: 6f 6b 65 6e 5b 6a 6a 5d 3b 0a 20 20 20 20 20 20  oken[jj];.      
1910: 70 54 2d 3e 7a 20 3d 20 54 63 6c 5f 47 65 74 53  pT->z = Tcl_GetS
1920: 74 72 69 6e 67 46 72 6f 6d 4f 62 6a 28 61 70 54  tringFromObj(apT
1930: 6f 6b 65 6e 5b 6a 6a 5d 2c 20 26 70 54 2d 3e 6e  oken[jj], &pT->n
1940: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61 50 68  );.    }.    aPh
1950: 72 61 73 65 5b 69 69 5d 2e 6e 54 6f 6b 65 6e 20  rase[ii].nToken 
1960: 3d 20 6e 54 6f 6b 65 6e 3b 0a 20 20 7d 0a 20 20  = nToken;.  }.  
1970: 66 6f 72 28 69 69 3d 31 3b 20 69 69 3c 6e 50 68  for(ii=1; ii<nPh
1980: 72 61 73 65 3b 20 69 69 2b 2b 29 7b 0a 20 20 20  rase; ii++){.   
1990: 20 54 63 6c 5f 4f 62 6a 20 2a 70 4e 65 61 72 20   Tcl_Obj *pNear 
19a0: 3d 20 61 70 45 78 70 72 54 6f 6b 65 6e 5b 32 2a  = apExprToken[2*
19b0: 69 69 2d 31 5d 3b 0a 20 20 20 20 69 6e 74 20 6e  ii-1];.    int n
19c0: 4e 65 61 72 3b 0a 20 20 20 20 72 63 20 3d 20 54  Near;.    rc = T
19d0: 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f 62 6a  cl_GetIntFromObj
19e0: 28 69 6e 74 65 72 70 2c 20 70 4e 65 61 72 2c 20  (interp, pNear, 
19f0: 26 6e 4e 65 61 72 29 3b 0a 20 20 20 20 69 66 28  &nNear);.    if(
1a00: 20 72 63 21 3d 54 43 4c 5f 4f 4b 20 29 20 67 6f   rc!=TCL_OK ) go
1a10: 74 6f 20 6e 65 61 72 5f 6d 61 74 63 68 5f 6f 75  to near_match_ou
1a20: 74 3b 0a 20 20 20 20 61 50 68 72 61 73 65 5b 69  t;.    aPhrase[i
1a30: 69 5d 2e 6e 4e 65 61 72 20 3d 20 6e 4e 65 61 72  i].nNear = nNear
1a40: 3b 0a 20 20 7d 0a 0a 20 20 70 52 65 74 20 3d 20  ;.  }..  pRet = 
1a50: 54 63 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20 20  Tcl_NewObj();.  
1a60: 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74  Tcl_IncrRefCount
1a70: 28 70 52 65 74 29 3b 0a 20 20 66 6f 72 28 69 69  (pRet);.  for(ii
1a80: 3d 30 3b 20 69 69 3c 6e 50 68 72 61 73 65 3b 20  =0; ii<nPhrase; 
1a90: 69 69 2b 2b 29 7b 0a 20 20 20 20 69 6e 74 20 6e  ii++){.    int n
1aa0: 4f 63 63 20 3d 20 6e 6d 5f 6d 61 74 63 68 5f 63  Occ = nm_match_c
1ab0: 6f 75 6e 74 28 26 64 6f 63 2c 20 6e 50 68 72 61  ount(&doc, nPhra
1ac0: 73 65 2c 20 61 50 68 72 61 73 65 2c 20 69 69 29  se, aPhrase, ii)
1ad0: 3b 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62  ;.    Tcl_ListOb
1ae0: 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69  jAppendElement(i
1af0: 6e 74 65 72 70 2c 20 70 52 65 74 2c 20 54 63 6c  nterp, pRet, Tcl
1b00: 5f 4e 65 77 49 6e 74 4f 62 6a 28 6e 4f 63 63 29  _NewIntObj(nOcc)
1b10: 29 3b 0a 20 20 20 20 6e 54 6f 74 61 6c 20 2b 3d  );.    nTotal +=
1b20: 20 6e 4f 63 63 3b 0a 20 20 7d 0a 20 20 69 66 28   nOcc;.  }.  if(
1b30: 20 70 50 68 72 61 73 65 63 6f 75 6e 74 20 29 7b   pPhrasecount ){
1b40: 0a 20 20 20 20 54 63 6c 5f 4f 62 6a 53 65 74 56  .    Tcl_ObjSetV
1b50: 61 72 32 28 69 6e 74 65 72 70 2c 20 70 50 68 72  ar2(interp, pPhr
1b60: 61 73 65 63 6f 75 6e 74 2c 20 30 2c 20 70 52 65  asecount, 0, pRe
1b70: 74 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 54 63 6c  t, 0);.  }.  Tcl
1b80: 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28 70 52  _DecrRefCount(pR
1b90: 65 74 29 3b 0a 20 20 54 63 6c 5f 53 65 74 4f 62  et);.  Tcl_SetOb
1ba0: 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  jResult(interp, 
1bb0: 54 63 6c 5f 4e 65 77 42 6f 6f 6c 65 61 6e 4f 62  Tcl_NewBooleanOb
1bc0: 6a 28 6e 54 6f 74 61 6c 3e 30 29 29 3b 0a 0a 20  j(nTotal>0));.. 
1bd0: 6e 65 61 72 5f 6d 61 74 63 68 5f 6f 75 74 3a 20  near_match_out: 
1be0: 0a 20 20 63 6b 66 72 65 65 28 28 63 68 61 72 20  .  ckfree((char 
1bf0: 2a 29 61 50 68 72 61 73 65 29 3b 0a 20 20 63 6b  *)aPhrase);.  ck
1c00: 66 72 65 65 28 28 63 68 61 72 20 2a 29 64 6f 63  free((char *)doc
1c10: 2e 61 54 6f 6b 65 6e 29 3b 0a 20 20 72 65 74 75  .aToken);.  retu
1c20: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
1c30: 20 20 54 63 6c 63 6d 64 3a 20 66 74 73 33 5f 63    Tclcmd: fts3_c
1c40: 6f 6e 66 69 67 75 72 65 5f 69 6e 63 72 5f 6c 6f  onfigure_incr_lo
1c50: 61 64 20 3f 43 48 55 4e 4b 53 49 5a 45 20 54 48  ad ?CHUNKSIZE TH
1c60: 52 45 53 48 4f 4c 44 3f 0a 2a 2a 0a 2a 2a 20 4e  RESHOLD?.**.** N
1c70: 6f 72 6d 61 6c 6c 79 2c 20 46 54 53 20 75 73 65  ormally, FTS use
1c80: 73 20 68 61 72 64 2d 63 6f 64 65 64 20 76 61 6c  s hard-coded val
1c90: 75 65 73 20 74 6f 20 64 65 74 65 72 6d 69 6e 65  ues to determine
1ca0: 20 74 68 65 20 6d 69 6e 69 6d 75 6d 20 64 6f 63   the minimum doc
1cb0: 6c 69 73 74 0a 2a 2a 20 73 69 7a 65 20 65 6c 69  list.** size eli
1cc0: 67 69 62 6c 65 20 66 6f 72 20 69 6e 63 72 65 6d  gible for increm
1cd0: 65 6e 74 61 6c 20 6c 6f 61 64 69 6e 67 2c 20 61  ental loading, a
1ce0: 6e 64 20 74 68 65 20 73 69 7a 65 20 6f 66 20 74  nd the size of t
1cf0: 68 65 20 63 68 75 6e 6b 73 20 6c 6f 61 64 65 64  he chunks loaded
1d00: 0a 2a 2a 20 77 68 65 6e 20 61 20 64 6f 63 6c 69  .** when a docli
1d10: 73 74 20 69 73 20 69 6e 63 72 65 6d 65 6e 74 61  st is incrementa
1d20: 6c 6c 79 20 6c 6f 61 64 65 64 2e 20 54 68 69 73  lly loaded. This
1d30: 20 63 6f 6d 6d 61 6e 64 20 61 6c 6c 6f 77 73 20   command allows 
1d40: 74 68 65 20 62 75 69 6c 74 2d 69 6e 0a 2a 2a 20  the built-in.** 
1d50: 76 61 6c 75 65 73 20 74 6f 20 62 65 20 6f 76 65  values to be ove
1d60: 72 72 69 64 64 65 6e 20 66 6f 72 20 74 65 73 74  rridden for test
1d70: 69 6e 67 20 70 75 72 70 6f 73 65 73 2e 0a 2a 2a  ing purposes..**
1d80: 0a 2a 2a 20 49 66 20 70 72 65 73 65 6e 74 2c 20  .** If present, 
1d90: 74 68 65 20 66 69 72 73 74 20 61 72 67 75 6d 65  the first argume
1da0: 6e 74 20 69 73 20 74 68 65 20 63 68 75 6e 6b 73  nt is the chunks
1db0: 69 7a 65 20 69 6e 20 62 79 74 65 73 20 74 6f 20  ize in bytes to 
1dc0: 6c 6f 61 64 20 64 6f 63 6c 69 73 74 73 0a 2a 2a  load doclists.**
1dd0: 20 69 6e 2e 20 54 68 65 20 73 65 63 6f 6e 64 20   in. The second 
1de0: 61 72 67 75 6d 65 6e 74 20 69 73 20 74 68 65 20  argument is the 
1df0: 6d 69 6e 69 6d 75 6d 20 64 6f 63 6c 69 73 74 20  minimum doclist 
1e00: 73 69 7a 65 20 69 6e 20 62 79 74 65 73 20 74 6f  size in bytes to
1e10: 20 75 73 65 0a 2a 2a 20 69 6e 63 72 65 6d 65 6e   use.** incremen
1e20: 74 61 6c 20 6c 6f 61 64 69 6e 67 20 77 69 74 68  tal loading with
1e30: 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 74 68 65 72 20  ..**.** Whether 
1e40: 6f 72 20 6e 6f 74 20 74 68 65 20 61 72 67 75 6d  or not the argum
1e50: 65 6e 74 73 20 61 72 65 20 70 72 65 73 65 6e 74  ents are present
1e60: 2c 20 74 68 69 73 20 63 6f 6d 6d 61 6e 64 20 72  , this command r
1e70: 65 74 75 72 6e 73 20 61 20 6c 69 73 74 20 6f 66  eturns a list of
1e80: 0a 2a 2a 20 74 77 6f 20 69 6e 74 65 67 65 72 73  .** two integers
1e90: 20 2d 20 74 68 65 20 69 6e 69 74 69 61 6c 20 63   - the initial c
1ea0: 68 75 6e 6b 73 69 7a 65 20 61 6e 64 20 74 68 72  hunksize and thr
1eb0: 65 73 68 6f 6c 64 20 77 68 65 6e 20 74 68 65 20  eshold when the 
1ec0: 63 6f 6d 6d 61 6e 64 20 69 73 0a 2a 2a 20 69 6e  command is.** in
1ed0: 76 6f 6b 65 64 2e 20 54 68 69 73 20 63 61 6e 20  voked. This can 
1ee0: 62 65 20 75 73 65 64 20 74 6f 20 72 65 73 74 6f  be used to resto
1ef0: 72 65 20 74 68 65 20 64 65 66 61 75 6c 74 20 62  re the default b
1f00: 65 68 61 76 69 6f 72 20 61 66 74 65 72 20 72 75  ehavior after ru
1f10: 6e 6e 69 6e 67 0a 2a 2a 20 74 65 73 74 73 2e 20  nning.** tests. 
1f20: 46 6f 72 20 65 78 61 6d 70 6c 65 3a 0a 2a 2a 0a  For example:.**.
1f30: 2a 2a 20 20 20 20 23 20 4f 76 65 72 72 69 64 65  **    # Override
1f40: 20 69 6e 63 72 2d 6c 6f 61 64 20 73 65 74 74 69   incr-load setti
1f50: 6e 67 73 20 66 6f 72 20 74 65 73 74 69 6e 67 3a  ngs for testing:
1f60: 0a 2a 2a 20 20 20 20 73 65 74 20 63 66 67 20 5b  .**    set cfg [
1f70: 66 74 73 33 5f 63 6f 6e 66 69 67 75 72 65 5f 69  fts3_configure_i
1f80: 6e 63 72 5f 6c 6f 61 64 20 24 6e 65 77 5f 63 68  ncr_load $new_ch
1f90: 75 6e 6b 73 69 7a 65 20 24 6e 65 77 5f 74 68 72  unksize $new_thr
1fa0: 65 73 68 6f 6c 64 5d 0a 2a 2a 0a 2a 2a 20 20 20  eshold].**.**   
1fb0: 20 2e 2e 2e 2e 20 72 75 6e 20 74 65 73 74 73 20   .... run tests 
1fc0: 2e 2e 2e 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 23 20  .....**.**    # 
1fd0: 52 65 73 74 6f 72 65 20 69 6e 69 74 69 61 6c 20  Restore initial 
1fe0: 69 6e 63 72 2d 6c 6f 61 64 20 73 65 74 74 69 6e  incr-load settin
1ff0: 67 73 3a 0a 2a 2a 20 20 20 20 65 76 61 6c 20 66  gs:.**    eval f
2000: 74 73 33 5f 63 6f 6e 66 69 67 75 72 65 5f 69 6e  ts3_configure_in
2010: 63 72 5f 6c 6f 61 64 20 24 63 66 67 0a 2a 2f 0a  cr_load $cfg.*/.
2020: 73 74 61 74 69 63 20 69 6e 74 20 53 51 4c 49 54  static int SQLIT
2030: 45 5f 54 43 4c 41 50 49 20 66 74 73 33 5f 63 6f  E_TCLAPI fts3_co
2040: 6e 66 69 67 75 72 65 5f 69 6e 63 72 5f 6c 6f 61  nfigure_incr_loa
2050: 64 5f 63 6d 64 28 0a 20 20 43 6c 69 65 6e 74 44  d_cmd(.  ClientD
2060: 61 74 61 20 63 6c 69 65 6e 74 44 61 74 61 2c 0a  ata clientData,.
2070: 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e    Tcl_Interp *in
2080: 74 65 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a 63  terp,.  int objc
2090: 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e  ,.  Tcl_Obj *CON
20a0: 53 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 23 69 66  ST objv[].){.#if
20b0: 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c  def SQLITE_ENABL
20c0: 45 5f 46 54 53 33 0a 20 20 65 78 74 65 72 6e 20  E_FTS3.  extern 
20d0: 69 6e 74 20 74 65 73 74 5f 66 74 73 33 5f 6e 6f  int test_fts3_no
20e0: 64 65 5f 63 68 75 6e 6b 73 69 7a 65 3b 0a 20 20  de_chunksize;.  
20f0: 65 78 74 65 72 6e 20 69 6e 74 20 74 65 73 74 5f  extern int test_
2100: 66 74 73 33 5f 6e 6f 64 65 5f 63 68 75 6e 6b 5f  fts3_node_chunk_
2110: 74 68 72 65 73 68 6f 6c 64 3b 0a 20 20 54 63 6c  threshold;.  Tcl
2120: 5f 4f 62 6a 20 2a 70 52 65 74 3b 0a 0a 20 20 69  _Obj *pRet;..  i
2130: 66 28 20 6f 62 6a 63 21 3d 31 20 26 26 20 6f 62  f( objc!=1 && ob
2140: 6a 63 21 3d 33 20 29 7b 0a 20 20 20 20 54 63 6c  jc!=3 ){.    Tcl
2150: 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e  _WrongNumArgs(in
2160: 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22  terp, 1, objv, "
2170: 3f 43 48 55 4e 4b 53 49 5a 45 20 54 48 52 45 53  ?CHUNKSIZE THRES
2180: 48 4f 4c 44 3f 22 29 3b 0a 20 20 20 20 72 65 74  HOLD?");.    ret
2190: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
21a0: 20 7d 0a 0a 20 20 70 52 65 74 20 3d 20 54 63 6c   }..  pRet = Tcl
21b0: 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20 20 54 63 6c  _NewObj();.  Tcl
21c0: 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 70 52  _IncrRefCount(pR
21d0: 65 74 29 3b 0a 20 20 54 63 6c 5f 4c 69 73 74 4f  et);.  Tcl_ListO
21e0: 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28  bjAppendElement(
21f0: 0a 20 20 20 20 20 20 69 6e 74 65 72 70 2c 20 70  .      interp, p
2200: 52 65 74 2c 20 54 63 6c 5f 4e 65 77 49 6e 74 4f  Ret, Tcl_NewIntO
2210: 62 6a 28 74 65 73 74 5f 66 74 73 33 5f 6e 6f 64  bj(test_fts3_nod
2220: 65 5f 63 68 75 6e 6b 73 69 7a 65 29 29 3b 0a 20  e_chunksize));. 
2230: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65   Tcl_ListObjAppe
2240: 6e 64 45 6c 65 6d 65 6e 74 28 0a 20 20 20 20 20  ndElement(.     
2250: 20 69 6e 74 65 72 70 2c 20 70 52 65 74 2c 20 54   interp, pRet, T
2260: 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28 74 65 73  cl_NewIntObj(tes
2270: 74 5f 66 74 73 33 5f 6e 6f 64 65 5f 63 68 75 6e  t_fts3_node_chun
2280: 6b 5f 74 68 72 65 73 68 6f 6c 64 29 29 3b 0a 0a  k_threshold));..
2290: 20 20 69 66 28 20 6f 62 6a 63 3d 3d 33 20 29 7b    if( objc==3 ){
22a0: 0a 20 20 20 20 69 6e 74 20 69 41 72 67 31 3b 0a  .    int iArg1;.
22b0: 20 20 20 20 69 6e 74 20 69 41 72 67 32 3b 0a 20      int iArg2;. 
22c0: 20 20 20 69 66 28 20 54 63 6c 5f 47 65 74 49 6e     if( Tcl_GetIn
22d0: 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c  tFromObj(interp,
22e0: 20 6f 62 6a 76 5b 31 5d 2c 20 26 69 41 72 67 31   objv[1], &iArg1
22f0: 29 0a 20 20 20 20 20 7c 7c 20 54 63 6c 5f 47 65  ).     || Tcl_Ge
2300: 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65  tIntFromObj(inte
2310: 72 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26 69 41  rp, objv[2], &iA
2320: 72 67 32 29 0a 20 20 20 20 29 7b 0a 20 20 20 20  rg2).    ){.    
2330: 20 20 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75    Tcl_DecrRefCou
2340: 6e 74 28 70 52 65 74 29 3b 0a 20 20 20 20 20 20  nt(pRet);.      
2350: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
2360: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 74 65 73 74  ;.    }.    test
2370: 5f 66 74 73 33 5f 6e 6f 64 65 5f 63 68 75 6e 6b  _fts3_node_chunk
2380: 73 69 7a 65 20 3d 20 69 41 72 67 31 3b 0a 20 20  size = iArg1;.  
2390: 20 20 74 65 73 74 5f 66 74 73 33 5f 6e 6f 64 65    test_fts3_node
23a0: 5f 63 68 75 6e 6b 5f 74 68 72 65 73 68 6f 6c 64  _chunk_threshold
23b0: 20 3d 20 69 41 72 67 32 3b 0a 20 20 7d 0a 0a 20   = iArg2;.  }.. 
23c0: 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c   Tcl_SetObjResul
23d0: 74 28 69 6e 74 65 72 70 2c 20 70 52 65 74 29 3b  t(interp, pRet);
23e0: 0a 20 20 54 63 6c 5f 44 65 63 72 52 65 66 43 6f  .  Tcl_DecrRefCo
23f0: 75 6e 74 28 70 52 65 74 29 3b 0a 23 65 6e 64 69  unt(pRet);.#endi
2400: 66 0a 20 20 55 4e 55 53 45 44 5f 50 41 52 41 4d  f.  UNUSED_PARAM
2410: 45 54 45 52 28 63 6c 69 65 6e 74 44 61 74 61 29  ETER(clientData)
2420: 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f  ;.  return TCL_O
2430: 4b 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c  K;.}..#ifdef SQL
2440: 49 54 45 5f 45 4e 41 42 4c 45 5f 46 54 53 33 0a  ITE_ENABLE_FTS3.
2450: 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  /***************
2460: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2470: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2480: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2490: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a 20 42  ***********.** B
24a0: 65 67 69 6e 6e 69 6e 67 20 6f 66 20 74 65 73 74  eginning of test
24b0: 20 74 6f 6b 65 6e 69 7a 65 72 20 63 6f 64 65 2e   tokenizer code.
24c0: 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 6c 61 6e 67 75  .**.** For langu
24d0: 61 67 65 20 30 2c 20 74 68 69 73 20 74 6f 6b 65  age 0, this toke
24e0: 6e 69 7a 65 72 20 69 73 20 73 69 6d 69 6c 61 72  nizer is similar
24f0: 20 74 6f 20 74 68 65 20 64 65 66 61 75 6c 74 20   to the default 
2500: 27 73 69 6d 70 6c 65 27 20 0a 2a 2a 20 74 6f 6b  'simple' .** tok
2510: 65 6e 69 7a 65 72 2e 20 46 6f 72 20 6f 74 68 65  enizer. For othe
2520: 72 20 6c 61 6e 67 75 61 67 65 73 20 4c 2c 20 74  r languages L, t
2530: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 3a 0a 2a 2a  he following:.**
2540: 0a 2a 2a 20 20 20 2a 20 4f 64 64 20 6e 75 6d 62  .**   * Odd numb
2550: 65 72 65 64 20 6c 61 6e 67 75 61 67 65 73 20 61  ered languages a
2560: 72 65 20 63 61 73 65 2d 73 65 6e 73 69 74 69 76  re case-sensitiv
2570: 65 2e 20 45 76 65 6e 20 6e 75 6d 62 65 72 65 64  e. Even numbered
2580: 20 0a 2a 2a 20 20 20 20 20 6c 61 6e 67 75 61 67   .**     languag
2590: 65 73 20 61 72 65 20 6e 6f 74 2e 0a 2a 2a 0a 2a  es are not..**.*
25a0: 2a 20 20 20 2a 20 4c 61 6e 67 75 61 67 65 20 69  *   * Language i
25b0: 64 73 20 31 30 30 20 6f 72 20 67 72 65 61 74 65  ds 100 or greate
25c0: 72 20 61 72 65 20 63 6f 6e 73 69 64 65 72 65 64  r are considered
25d0: 20 61 6e 20 65 72 72 6f 72 2e 0a 2a 2a 0a 2a 2a   an error..**.**
25e0: 20 54 68 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74   The implementat
25f0: 69 6f 6e 20 61 73 73 75 6d 65 73 20 74 68 61 74  ion assumes that
2600: 20 74 68 65 20 69 6e 70 75 74 20 63 6f 6e 74 61   the input conta
2610: 69 6e 73 20 6f 6e 6c 79 20 41 53 43 49 49 20 63  ins only ASCII c
2620: 68 61 72 61 63 74 65 72 73 0a 2a 2a 20 28 69 2e  haracters.** (i.
2630: 65 2e 20 74 68 6f 73 65 20 74 68 61 74 20 6d 61  e. those that ma
2640: 79 20 62 65 20 65 6e 63 6f 64 65 64 20 69 6e 20  y be encoded in 
2650: 55 54 46 2d 38 20 75 73 69 6e 67 20 61 20 73 69  UTF-8 using a si
2660: 6e 67 6c 65 20 62 79 74 65 29 2e 0a 2a 2f 0a 74  ngle byte)..*/.t
2670: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 74 65  ypedef struct te
2680: 73 74 5f 74 6f 6b 65 6e 69 7a 65 72 20 7b 0a 20  st_tokenizer {. 
2690: 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a   sqlite3_tokeniz
26a0: 65 72 20 62 61 73 65 3b 0a 7d 20 74 65 73 74 5f  er base;.} test_
26b0: 74 6f 6b 65 6e 69 7a 65 72 3b 0a 0a 74 79 70 65  tokenizer;..type
26c0: 64 65 66 20 73 74 72 75 63 74 20 74 65 73 74 5f  def struct test_
26d0: 74 6f 6b 65 6e 69 7a 65 72 5f 63 75 72 73 6f 72  tokenizer_cursor
26e0: 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 74 6f 6b   {.  sqlite3_tok
26f0: 65 6e 69 7a 65 72 5f 63 75 72 73 6f 72 20 62 61  enizer_cursor ba
2700: 73 65 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  se;.  const char
2710: 20 2a 61 49 6e 70 75 74 3b 20 20 20 20 20 20 20   *aInput;       
2720: 20 20 20 2f 2a 20 49 6e 70 75 74 20 62 65 69 6e     /* Input bein
2730: 67 20 74 6f 6b 65 6e 69 7a 65 64 20 2a 2f 0a 20  g tokenized */. 
2740: 20 69 6e 74 20 6e 49 6e 70 75 74 3b 20 20 20 20   int nInput;    
2750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2760: 20 53 69 7a 65 20 6f 66 20 74 68 65 20 69 6e 70   Size of the inp
2770: 75 74 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20  ut in bytes */. 
2780: 20 69 6e 74 20 69 49 6e 70 75 74 3b 20 20 20 20   int iInput;    
2790: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
27a0: 20 43 75 72 72 65 6e 74 20 6f 66 66 73 65 74 20   Current offset 
27b0: 69 6e 20 61 49 6e 70 75 74 20 2a 2f 0a 20 20 69  in aInput */.  i
27c0: 6e 74 20 69 54 6f 6b 65 6e 3b 20 20 20 20 20 20  nt iToken;      
27d0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
27e0: 6e 64 65 78 20 6f 66 20 6e 65 78 74 20 74 6f 6b  ndex of next tok
27f0: 65 6e 20 74 6f 20 62 65 20 72 65 74 75 72 6e 65  en to be returne
2800: 64 20 2a 2f 0a 20 20 63 68 61 72 20 2a 61 42 75  d */.  char *aBu
2810: 66 66 65 72 3b 20 20 20 20 20 20 20 20 20 20 20  ffer;           
2820: 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20 63 6f      /* Buffer co
2830: 6e 74 61 69 6e 69 6e 67 20 63 75 72 72 65 6e 74  ntaining current
2840: 20 74 6f 6b 65 6e 20 2a 2f 0a 20 20 69 6e 74 20   token */.  int 
2850: 6e 42 75 66 66 65 72 3b 20 20 20 20 20 20 20 20  nBuffer;        
2860: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
2870: 65 72 20 6f 66 20 62 79 74 65 73 20 61 6c 6c 6f  er of bytes allo
2880: 63 61 74 65 64 20 61 74 20 70 54 6f 6b 65 6e 20  cated at pToken 
2890: 2a 2f 0a 20 20 69 6e 74 20 69 4c 61 6e 67 69 64  */.  int iLangid
28a0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
28b0: 20 20 2f 2a 20 43 6f 6e 66 69 67 75 72 65 64 20    /* Configured 
28c0: 6c 61 6e 67 75 61 67 65 20 69 64 20 2a 2f 0a 7d  language id */.}
28d0: 20 74 65 73 74 5f 74 6f 6b 65 6e 69 7a 65 72 5f   test_tokenizer_
28e0: 63 75 72 73 6f 72 3b 0a 0a 73 74 61 74 69 63 20  cursor;..static 
28f0: 69 6e 74 20 74 65 73 74 54 6f 6b 65 6e 69 7a 65  int testTokenize
2900: 72 43 72 65 61 74 65 28 0a 20 20 69 6e 74 20 61  rCreate(.  int a
2910: 72 67 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  rgc, const char 
2920: 2a 20 63 6f 6e 73 74 20 2a 61 72 67 76 2c 0a 20  * const *argv,. 
2930: 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a   sqlite3_tokeniz
2940: 65 72 20 2a 2a 70 70 54 6f 6b 65 6e 69 7a 65 72  er **ppTokenizer
2950: 0a 29 7b 0a 20 20 74 65 73 74 5f 74 6f 6b 65 6e  .){.  test_token
2960: 69 7a 65 72 20 2a 70 4e 65 77 3b 0a 20 20 55 4e  izer *pNew;.  UN
2970: 55 53 45 44 5f 50 41 52 41 4d 45 54 45 52 28 61  USED_PARAMETER(a
2980: 72 67 63 29 3b 0a 20 20 55 4e 55 53 45 44 5f 50  rgc);.  UNUSED_P
2990: 41 52 41 4d 45 54 45 52 28 61 72 67 76 29 3b 0a  ARAMETER(argv);.
29a0: 0a 20 20 70 4e 65 77 20 3d 20 73 71 6c 69 74 65  .  pNew = sqlite
29b0: 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28  3_malloc(sizeof(
29c0: 74 65 73 74 5f 74 6f 6b 65 6e 69 7a 65 72 29 29  test_tokenizer))
29d0: 3b 0a 20 20 69 66 28 20 21 70 4e 65 77 20 29 20  ;.  if( !pNew ) 
29e0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
29f0: 4d 45 4d 3b 0a 20 20 6d 65 6d 73 65 74 28 70 4e  MEM;.  memset(pN
2a00: 65 77 2c 20 30 2c 20 73 69 7a 65 6f 66 28 74 65  ew, 0, sizeof(te
2a10: 73 74 5f 74 6f 6b 65 6e 69 7a 65 72 29 29 3b 0a  st_tokenizer));.
2a20: 0a 20 20 2a 70 70 54 6f 6b 65 6e 69 7a 65 72 20  .  *ppTokenizer 
2a30: 3d 20 28 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e  = (sqlite3_token
2a40: 69 7a 65 72 20 2a 29 70 4e 65 77 3b 0a 20 20 72  izer *)pNew;.  r
2a50: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
2a60: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .}..static int t
2a70: 65 73 74 54 6f 6b 65 6e 69 7a 65 72 44 65 73 74  estTokenizerDest
2a80: 72 6f 79 28 73 71 6c 69 74 65 33 5f 74 6f 6b 65  roy(sqlite3_toke
2a90: 6e 69 7a 65 72 20 2a 70 54 6f 6b 65 6e 69 7a 65  nizer *pTokenize
2aa0: 72 29 7b 0a 20 20 74 65 73 74 5f 74 6f 6b 65 6e  r){.  test_token
2ab0: 69 7a 65 72 20 2a 70 20 3d 20 28 74 65 73 74 5f  izer *p = (test_
2ac0: 74 6f 6b 65 6e 69 7a 65 72 20 2a 29 70 54 6f 6b  tokenizer *)pTok
2ad0: 65 6e 69 7a 65 72 3b 0a 20 20 73 71 6c 69 74 65  enizer;.  sqlite
2ae0: 33 5f 66 72 65 65 28 70 29 3b 0a 20 20 72 65 74  3_free(p);.  ret
2af0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
2b00: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 65 73  ..static int tes
2b10: 74 54 6f 6b 65 6e 69 7a 65 72 4f 70 65 6e 28 0a  tTokenizerOpen(.
2b20: 20 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69    sqlite3_tokeni
2b30: 7a 65 72 20 2a 70 54 6f 6b 65 6e 69 7a 65 72 2c  zer *pTokenizer,
2b40: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
2b50: 74 6f 6b 65 6e 69 7a 65 72 20 2a 2f 0a 20 20 63  tokenizer */.  c
2b60: 6f 6e 73 74 20 63 68 61 72 20 2a 70 49 6e 70 75  onst char *pInpu
2b70: 74 2c 20 69 6e 74 20 6e 42 79 74 65 73 2c 20 20  t, int nBytes,  
2b80: 20 20 20 20 20 20 2f 2a 20 53 74 72 69 6e 67 20        /* String 
2b90: 74 6f 20 62 65 20 74 6f 6b 65 6e 69 7a 65 64 20  to be tokenized 
2ba0: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 74 6f 6b  */.  sqlite3_tok
2bb0: 65 6e 69 7a 65 72 5f 63 75 72 73 6f 72 20 2a 2a  enizer_cursor **
2bc0: 70 70 43 75 72 73 6f 72 20 20 20 20 2f 2a 20 4f  ppCursor    /* O
2bd0: 55 54 3a 20 54 6f 6b 65 6e 69 7a 61 74 69 6f 6e  UT: Tokenization
2be0: 20 63 75 72 73 6f 72 20 2a 2f 0a 29 7b 0a 20 20   cursor */.){.  
2bf0: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
2c00: 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  OK;             
2c10: 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
2c20: 20 63 6f 64 65 20 2a 2f 0a 20 20 74 65 73 74 5f   code */.  test_
2c30: 74 6f 6b 65 6e 69 7a 65 72 5f 63 75 72 73 6f 72  tokenizer_cursor
2c40: 20 2a 70 43 73 72 3b 20 20 20 20 20 20 20 20 20   *pCsr;         
2c50: 20 20 2f 2a 20 4e 65 77 20 63 75 72 73 6f 72 20    /* New cursor 
2c60: 6f 62 6a 65 63 74 20 2a 2f 0a 0a 20 20 55 4e 55  object */..  UNU
2c70: 53 45 44 5f 50 41 52 41 4d 45 54 45 52 28 70 54  SED_PARAMETER(pT
2c80: 6f 6b 65 6e 69 7a 65 72 29 3b 0a 0a 20 20 70 43  okenizer);..  pC
2c90: 73 72 20 3d 20 28 74 65 73 74 5f 74 6f 6b 65 6e  sr = (test_token
2ca0: 69 7a 65 72 5f 63 75 72 73 6f 72 20 2a 29 73 71  izer_cursor *)sq
2cb0: 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a  lite3_malloc(siz
2cc0: 65 6f 66 28 74 65 73 74 5f 74 6f 6b 65 6e 69 7a  eof(test_tokeniz
2cd0: 65 72 5f 63 75 72 73 6f 72 29 29 3b 0a 20 20 69  er_cursor));.  i
2ce0: 66 28 20 70 43 73 72 3d 3d 30 20 29 7b 0a 20 20  f( pCsr==0 ){.  
2cf0: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f    rc = SQLITE_NO
2d00: 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  MEM;.  }else{.  
2d10: 20 20 6d 65 6d 73 65 74 28 70 43 73 72 2c 20 30    memset(pCsr, 0
2d20: 2c 20 73 69 7a 65 6f 66 28 74 65 73 74 5f 74 6f  , sizeof(test_to
2d30: 6b 65 6e 69 7a 65 72 5f 63 75 72 73 6f 72 29 29  kenizer_cursor))
2d40: 3b 0a 20 20 20 20 70 43 73 72 2d 3e 61 49 6e 70  ;.    pCsr->aInp
2d50: 75 74 20 3d 20 70 49 6e 70 75 74 3b 0a 20 20 20  ut = pInput;.   
2d60: 20 69 66 28 20 6e 42 79 74 65 73 3c 30 20 29 7b   if( nBytes<0 ){
2d70: 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 6e 49 6e  .      pCsr->nIn
2d80: 70 75 74 20 3d 20 28 69 6e 74 29 73 74 72 6c 65  put = (int)strle
2d90: 6e 28 70 49 6e 70 75 74 29 3b 0a 20 20 20 20 7d  n(pInput);.    }
2da0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 43 73 72  else{.      pCsr
2db0: 2d 3e 6e 49 6e 70 75 74 20 3d 20 6e 42 79 74 65  ->nInput = nByte
2dc0: 73 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  s;.    }.  }..  
2dd0: 2a 70 70 43 75 72 73 6f 72 20 3d 20 28 73 71 6c  *ppCursor = (sql
2de0: 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63  ite3_tokenizer_c
2df0: 75 72 73 6f 72 20 2a 29 70 43 73 72 3b 0a 20 20  ursor *)pCsr;.  
2e00: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74  return rc;.}..st
2e10: 61 74 69 63 20 69 6e 74 20 74 65 73 74 54 6f 6b  atic int testTok
2e20: 65 6e 69 7a 65 72 43 6c 6f 73 65 28 73 71 6c 69  enizerClose(sqli
2e30: 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75  te3_tokenizer_cu
2e40: 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 29 7b 0a  rsor *pCursor){.
2e50: 20 20 74 65 73 74 5f 74 6f 6b 65 6e 69 7a 65 72    test_tokenizer
2e60: 5f 63 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20  _cursor *pCsr = 
2e70: 28 74 65 73 74 5f 74 6f 6b 65 6e 69 7a 65 72 5f  (test_tokenizer_
2e80: 63 75 72 73 6f 72 20 2a 29 70 43 75 72 73 6f 72  cursor *)pCursor
2e90: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
2ea0: 28 70 43 73 72 2d 3e 61 42 75 66 66 65 72 29 3b  (pCsr->aBuffer);
2eb0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
2ec0: 70 43 73 72 29 3b 0a 20 20 72 65 74 75 72 6e 20  pCsr);.  return 
2ed0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74  SQLITE_OK;.}..st
2ee0: 61 74 69 63 20 69 6e 74 20 74 65 73 74 49 73 54  atic int testIsT
2ef0: 6f 6b 65 6e 43 68 61 72 28 63 68 61 72 20 63 29  okenChar(char c)
2f00: 7b 0a 20 20 72 65 74 75 72 6e 20 28 63 3e 3d 27  {.  return (c>='
2f10: 61 27 20 26 26 20 63 3c 3d 27 7a 27 29 20 7c 7c  a' && c<='z') ||
2f20: 20 28 63 3e 3d 27 41 27 20 26 26 20 63 3c 3d 27   (c>='A' && c<='
2f30: 5a 27 29 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e  Z');.}.static in
2f40: 74 20 74 65 73 74 54 6f 6c 6f 77 65 72 28 63 68  t testTolower(ch
2f50: 61 72 20 63 29 7b 0a 20 20 63 68 61 72 20 72 65  ar c){.  char re
2f60: 74 20 3d 20 63 3b 0a 20 20 69 66 28 20 72 65 74  t = c;.  if( ret
2f70: 3e 3d 27 41 27 20 26 26 20 72 65 74 3c 3d 27 5a  >='A' && ret<='Z
2f80: 27 29 20 72 65 74 20 3d 20 72 65 74 20 2d 20 28  ') ret = ret - (
2f90: 27 41 27 2d 27 61 27 29 3b 0a 20 20 72 65 74 75  'A'-'a');.  retu
2fa0: 72 6e 20 72 65 74 3b 0a 7d 0a 0a 73 74 61 74 69  rn ret;.}..stati
2fb0: 63 20 69 6e 74 20 74 65 73 74 54 6f 6b 65 6e 69  c int testTokeni
2fc0: 7a 65 72 4e 65 78 74 28 0a 20 20 73 71 6c 69 74  zerNext(.  sqlit
2fd0: 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75 72  e3_tokenizer_cur
2fe0: 73 6f 72 20 2a 70 43 75 72 73 6f 72 2c 20 20 2f  sor *pCursor,  /
2ff0: 2a 20 43 75 72 73 6f 72 20 72 65 74 75 72 6e 65  * Cursor returne
3000: 64 20 62 79 20 74 65 73 74 54 6f 6b 65 6e 69 7a  d by testTokeniz
3010: 65 72 4f 70 65 6e 20 2a 2f 0a 20 20 63 6f 6e 73  erOpen */.  cons
3020: 74 20 63 68 61 72 20 2a 2a 70 70 54 6f 6b 65 6e  t char **ppToken
3030: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
3040: 2f 2a 20 4f 55 54 3a 20 2a 70 70 54 6f 6b 65 6e  /* OUT: *ppToken
3050: 20 69 73 20 74 68 65 20 74 6f 6b 65 6e 20 74 65   is the token te
3060: 78 74 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 42  xt */.  int *pnB
3070: 79 74 65 73 2c 20 20 20 20 20 20 20 20 20 20 20  ytes,           
3080: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
3090: 55 54 3a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79  UT: Number of by
30a0: 74 65 73 20 69 6e 20 74 6f 6b 65 6e 20 2a 2f 0a  tes in token */.
30b0: 20 20 69 6e 74 20 2a 70 69 53 74 61 72 74 4f 66    int *piStartOf
30c0: 66 73 65 74 2c 20 20 20 20 20 20 20 20 20 20 20  fset,           
30d0: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 53 74        /* OUT: St
30e0: 61 72 74 69 6e 67 20 6f 66 66 73 65 74 20 6f 66  arting offset of
30f0: 20 74 6f 6b 65 6e 20 2a 2f 0a 20 20 69 6e 74 20   token */.  int 
3100: 2a 70 69 45 6e 64 4f 66 66 73 65 74 2c 20 20 20  *piEndOffset,   
3110: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3120: 2f 2a 20 4f 55 54 3a 20 45 6e 64 69 6e 67 20 6f  /* OUT: Ending o
3130: 66 66 73 65 74 20 6f 66 20 74 6f 6b 65 6e 20 2a  ffset of token *
3140: 2f 0a 20 20 69 6e 74 20 2a 70 69 50 6f 73 69 74  /.  int *piPosit
3150: 69 6f 6e 20 20 20 20 20 20 20 20 20 20 20 20 20  ion             
3160: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
3170: 50 6f 73 69 74 69 6f 6e 20 69 6e 74 65 67 65 72  Position integer
3180: 20 6f 66 20 74 6f 6b 65 6e 20 2a 2f 0a 29 7b 0a   of token */.){.
3190: 20 20 74 65 73 74 5f 74 6f 6b 65 6e 69 7a 65 72    test_tokenizer
31a0: 5f 63 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20  _cursor *pCsr = 
31b0: 28 74 65 73 74 5f 74 6f 6b 65 6e 69 7a 65 72 5f  (test_tokenizer_
31c0: 63 75 72 73 6f 72 20 2a 29 70 43 75 72 73 6f 72  cursor *)pCursor
31d0: 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  ;.  int rc = SQL
31e0: 49 54 45 5f 4f 4b 3b 0a 20 20 63 6f 6e 73 74 20  ITE_OK;.  const 
31f0: 63 68 61 72 20 2a 70 3b 0a 20 20 63 6f 6e 73 74  char *p;.  const
3200: 20 63 68 61 72 20 2a 70 45 6e 64 3b 0a 0a 20 20   char *pEnd;..  
3210: 70 20 3d 20 26 70 43 73 72 2d 3e 61 49 6e 70 75  p = &pCsr->aInpu
3220: 74 5b 70 43 73 72 2d 3e 69 49 6e 70 75 74 5d 3b  t[pCsr->iInput];
3230: 0a 20 20 70 45 6e 64 20 3d 20 26 70 43 73 72 2d  .  pEnd = &pCsr-
3240: 3e 61 49 6e 70 75 74 5b 70 43 73 72 2d 3e 6e 49  >aInput[pCsr->nI
3250: 6e 70 75 74 5d 3b 0a 0a 20 20 2f 2a 20 53 6b 69  nput];..  /* Ski
3260: 70 20 70 61 73 74 20 61 6e 79 20 77 68 69 74 65  p past any white
3270: 2d 73 70 61 63 65 20 2a 2f 0a 20 20 61 73 73 65  -space */.  asse
3280: 72 74 28 20 70 3c 3d 70 45 6e 64 20 29 3b 0a 20  rt( p<=pEnd );. 
3290: 20 77 68 69 6c 65 28 20 70 3c 70 45 6e 64 20 26   while( p<pEnd &
32a0: 26 20 74 65 73 74 49 73 54 6f 6b 65 6e 43 68 61  & testIsTokenCha
32b0: 72 28 2a 70 29 3d 3d 30 20 29 20 70 2b 2b 3b 0a  r(*p)==0 ) p++;.
32c0: 0a 20 20 69 66 28 20 70 3d 3d 70 45 6e 64 20 29  .  if( p==pEnd )
32d0: 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54  {.    rc = SQLIT
32e0: 45 5f 44 4f 4e 45 3b 0a 20 20 7d 65 6c 73 65 7b  E_DONE;.  }else{
32f0: 0a 20 20 20 20 2f 2a 20 41 64 76 61 6e 63 65 20  .    /* Advance 
3300: 74 6f 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68  to the end of th
3310: 65 20 74 6f 6b 65 6e 20 2a 2f 0a 20 20 20 20 63  e token */.    c
3320: 6f 6e 73 74 20 63 68 61 72 20 2a 70 54 6f 6b 65  onst char *pToke
3330: 6e 20 3d 20 70 3b 0a 20 20 20 20 69 6e 74 20 6e  n = p;.    int n
3340: 54 6f 6b 65 6e 3b 0a 20 20 20 20 77 68 69 6c 65  Token;.    while
3350: 28 20 70 3c 70 45 6e 64 20 26 26 20 74 65 73 74  ( p<pEnd && test
3360: 49 73 54 6f 6b 65 6e 43 68 61 72 28 2a 70 29 20  IsTokenChar(*p) 
3370: 29 20 70 2b 2b 3b 0a 20 20 20 20 6e 54 6f 6b 65  ) p++;.    nToke
3380: 6e 20 3d 20 28 69 6e 74 29 28 70 2d 70 54 6f 6b  n = (int)(p-pTok
3390: 65 6e 29 3b 0a 0a 20 20 20 20 2f 2a 20 43 6f 70  en);..    /* Cop
33a0: 79 20 74 68 65 20 74 6f 6b 65 6e 20 69 6e 74 6f  y the token into
33b0: 20 74 68 65 20 62 75 66 66 65 72 20 2a 2f 0a 20   the buffer */. 
33c0: 20 20 20 69 66 28 20 6e 54 6f 6b 65 6e 3e 70 43     if( nToken>pC
33d0: 73 72 2d 3e 6e 42 75 66 66 65 72 20 29 7b 0a 20  sr->nBuffer ){. 
33e0: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65       sqlite3_fre
33f0: 65 28 70 43 73 72 2d 3e 61 42 75 66 66 65 72 29  e(pCsr->aBuffer)
3400: 3b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 61 42  ;.      pCsr->aB
3410: 75 66 66 65 72 20 3d 20 73 71 6c 69 74 65 33 5f  uffer = sqlite3_
3420: 6d 61 6c 6c 6f 63 28 6e 54 6f 6b 65 6e 29 3b 0a  malloc(nToken);.
3430: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70 43      }.    if( pC
3440: 73 72 2d 3e 61 42 75 66 66 65 72 3d 3d 30 20 29  sr->aBuffer==0 )
3450: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  {.      rc = SQL
3460: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d  ITE_NOMEM;.    }
3470: 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 6e 74 20  else{.      int 
3480: 69 3b 0a 0a 20 20 20 20 20 20 69 66 28 20 70 43  i;..      if( pC
3490: 73 72 2d 3e 69 4c 61 6e 67 69 64 20 26 20 30 78  sr->iLangid & 0x
34a0: 30 30 30 30 30 30 30 31 20 29 7b 0a 20 20 20 20  00000001 ){.    
34b0: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e      for(i=0; i<n
34c0: 54 6f 6b 65 6e 3b 20 69 2b 2b 29 20 70 43 73 72  Token; i++) pCsr
34d0: 2d 3e 61 42 75 66 66 65 72 5b 69 5d 20 3d 20 70  ->aBuffer[i] = p
34e0: 54 6f 6b 65 6e 5b 69 5d 3b 0a 20 20 20 20 20 20  Token[i];.      
34f0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 66  }else{.        f
3500: 6f 72 28 69 3d 30 3b 20 69 3c 6e 54 6f 6b 65 6e  or(i=0; i<nToken
3510: 3b 20 69 2b 2b 29 20 70 43 73 72 2d 3e 61 42 75  ; i++) pCsr->aBu
3520: 66 66 65 72 5b 69 5d 20 3d 20 28 63 68 61 72 29  ffer[i] = (char)
3530: 74 65 73 74 54 6f 6c 6f 77 65 72 28 70 54 6f 6b  testTolower(pTok
3540: 65 6e 5b 69 5d 29 3b 0a 20 20 20 20 20 20 7d 0a  en[i]);.      }.
3550: 20 20 20 20 20 20 70 43 73 72 2d 3e 69 54 6f 6b        pCsr->iTok
3560: 65 6e 2b 2b 3b 0a 20 20 20 20 20 20 70 43 73 72  en++;.      pCsr
3570: 2d 3e 69 49 6e 70 75 74 20 3d 20 28 69 6e 74 29  ->iInput = (int)
3580: 28 70 20 2d 20 70 43 73 72 2d 3e 61 49 6e 70 75  (p - pCsr->aInpu
3590: 74 29 3b 0a 0a 20 20 20 20 20 20 2a 70 70 54 6f  t);..      *ppTo
35a0: 6b 65 6e 20 3d 20 70 43 73 72 2d 3e 61 42 75 66  ken = pCsr->aBuf
35b0: 66 65 72 3b 0a 20 20 20 20 20 20 2a 70 6e 42 79  fer;.      *pnBy
35c0: 74 65 73 20 3d 20 6e 54 6f 6b 65 6e 3b 0a 20 20  tes = nToken;.  
35d0: 20 20 20 20 2a 70 69 53 74 61 72 74 4f 66 66 73      *piStartOffs
35e0: 65 74 20 3d 20 28 69 6e 74 29 28 70 54 6f 6b 65  et = (int)(pToke
35f0: 6e 20 2d 20 70 43 73 72 2d 3e 61 49 6e 70 75 74  n - pCsr->aInput
3600: 29 3b 0a 20 20 20 20 20 20 2a 70 69 45 6e 64 4f  );.      *piEndO
3610: 66 66 73 65 74 20 3d 20 28 69 6e 74 29 28 70 20  ffset = (int)(p 
3620: 2d 20 70 43 73 72 2d 3e 61 49 6e 70 75 74 29 3b  - pCsr->aInput);
3630: 0a 20 20 20 20 20 20 2a 70 69 50 6f 73 69 74 69  .      *piPositi
3640: 6f 6e 20 3d 20 70 43 73 72 2d 3e 69 54 6f 6b 65  on = pCsr->iToke
3650: 6e 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  n;.    }.  }..  
3660: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74  return rc;.}..st
3670: 61 74 69 63 20 69 6e 74 20 74 65 73 74 54 6f 6b  atic int testTok
3680: 65 6e 69 7a 65 72 4c 61 6e 67 75 61 67 65 28 0a  enizerLanguage(.
3690: 20 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69    sqlite3_tokeni
36a0: 7a 65 72 5f 63 75 72 73 6f 72 20 2a 70 43 75 72  zer_cursor *pCur
36b0: 73 6f 72 2c 0a 20 20 69 6e 74 20 69 4c 61 6e 67  sor,.  int iLang
36c0: 69 64 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  id.){.  int rc =
36d0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 74 65   SQLITE_OK;.  te
36e0: 73 74 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75 72  st_tokenizer_cur
36f0: 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 74 65 73  sor *pCsr = (tes
3700: 74 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75 72 73  t_tokenizer_curs
3710: 6f 72 20 2a 29 70 43 75 72 73 6f 72 3b 0a 20 20  or *)pCursor;.  
3720: 70 43 73 72 2d 3e 69 4c 61 6e 67 69 64 20 3d 20  pCsr->iLangid = 
3730: 69 4c 61 6e 67 69 64 3b 0a 20 20 69 66 28 20 70  iLangid;.  if( p
3740: 43 73 72 2d 3e 69 4c 61 6e 67 69 64 3e 3d 31 30  Csr->iLangid>=10
3750: 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51  0 ){.    rc = SQ
3760: 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a  LITE_ERROR;.  }.
3770: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 23    return rc;.}.#
3780: 65 6e 64 69 66 0a 0a 73 74 61 74 69 63 20 69 6e  endif..static in
3790: 74 20 53 51 4c 49 54 45 5f 54 43 4c 41 50 49 20  t SQLITE_TCLAPI 
37a0: 66 74 73 33 5f 74 65 73 74 5f 74 6f 6b 65 6e 69  fts3_test_tokeni
37b0: 7a 65 72 5f 63 6d 64 28 0a 20 20 43 6c 69 65 6e  zer_cmd(.  Clien
37c0: 74 44 61 74 61 20 63 6c 69 65 6e 74 44 61 74 61  tData clientData
37d0: 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  ,.  Tcl_Interp *
37e0: 69 6e 74 65 72 70 2c 0a 20 20 69 6e 74 20 6f 62  interp,.  int ob
37f0: 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43  jc,.  Tcl_Obj *C
3800: 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 23  ONST objv[].){.#
3810: 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41  ifdef SQLITE_ENA
3820: 42 4c 45 5f 46 54 53 33 0a 20 20 73 74 61 74 69  BLE_FTS3.  stati
3830: 63 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f  c const sqlite3_
3840: 74 6f 6b 65 6e 69 7a 65 72 5f 6d 6f 64 75 6c 65  tokenizer_module
3850: 20 74 65 73 74 54 6f 6b 65 6e 69 7a 65 72 4d 6f   testTokenizerMo
3860: 64 75 6c 65 20 3d 20 7b 0a 20 20 20 20 31 2c 0a  dule = {.    1,.
3870: 20 20 20 20 74 65 73 74 54 6f 6b 65 6e 69 7a 65      testTokenize
3880: 72 43 72 65 61 74 65 2c 0a 20 20 20 20 74 65 73  rCreate,.    tes
3890: 74 54 6f 6b 65 6e 69 7a 65 72 44 65 73 74 72 6f  tTokenizerDestro
38a0: 79 2c 0a 20 20 20 20 74 65 73 74 54 6f 6b 65 6e  y,.    testToken
38b0: 69 7a 65 72 4f 70 65 6e 2c 0a 20 20 20 20 74 65  izerOpen,.    te
38c0: 73 74 54 6f 6b 65 6e 69 7a 65 72 43 6c 6f 73 65  stTokenizerClose
38d0: 2c 0a 20 20 20 20 74 65 73 74 54 6f 6b 65 6e 69  ,.    testTokeni
38e0: 7a 65 72 4e 65 78 74 2c 0a 20 20 20 20 74 65 73  zerNext,.    tes
38f0: 74 54 6f 6b 65 6e 69 7a 65 72 4c 61 6e 67 75 61  tTokenizerLangua
3900: 67 65 0a 20 20 7d 3b 0a 20 20 63 6f 6e 73 74 20  ge.  };.  const 
3910: 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65  sqlite3_tokenize
3920: 72 5f 6d 6f 64 75 6c 65 20 2a 70 50 74 72 20 3d  r_module *pPtr =
3930: 20 26 74 65 73 74 54 6f 6b 65 6e 69 7a 65 72 4d   &testTokenizerM
3940: 6f 64 75 6c 65 3b 0a 20 20 69 66 28 20 6f 62 6a  odule;.  if( obj
3950: 63 21 3d 31 20 29 7b 0a 20 20 20 20 54 63 6c 5f  c!=1 ){.    Tcl_
3960: 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74  WrongNumArgs(int
3970: 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 22  erp, 1, objv, ""
3980: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43  );.    return TC
3990: 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 54  L_ERROR;.  }.  T
39a0: 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_SetObjResult(
39b0: 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 42  interp, Tcl_NewB
39c0: 79 74 65 41 72 72 61 79 4f 62 6a 28 0a 20 20 20  yteArrayObj(.   
39d0: 20 28 63 6f 6e 73 74 20 75 6e 73 69 67 6e 65 64   (const unsigned
39e0: 20 63 68 61 72 20 2a 29 26 70 50 74 72 2c 20 73   char *)&pPtr, s
39f0: 69 7a 65 6f 66 28 73 71 6c 69 74 65 33 5f 74 6f  izeof(sqlite3_to
3a00: 6b 65 6e 69 7a 65 72 5f 6d 6f 64 75 6c 65 20 2a  kenizer_module *
3a10: 29 0a 20 20 29 29 3b 0a 23 65 6e 64 69 66 0a 20  ).  ));.#endif. 
3a20: 20 55 4e 55 53 45 44 5f 50 41 52 41 4d 45 54 45   UNUSED_PARAMETE
3a30: 52 28 63 6c 69 65 6e 74 44 61 74 61 29 3b 0a 20  R(clientData);. 
3a40: 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a   return TCL_OK;.
3a50: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 53 51  }..static int SQ
3a60: 4c 49 54 45 5f 54 43 4c 41 50 49 20 66 74 73 33  LITE_TCLAPI fts3
3a70: 5f 74 65 73 74 5f 76 61 72 69 6e 74 5f 63 6d 64  _test_varint_cmd
3a80: 28 0a 20 20 43 6c 69 65 6e 74 44 61 74 61 20 63  (.  ClientData c
3a90: 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20 54 63 6c  lientData,.  Tcl
3aa0: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
3ab0: 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54  .  int objc,.  T
3ac0: 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62  cl_Obj *CONST ob
3ad0: 6a 76 5b 5d 0a 29 7b 0a 23 69 66 64 65 66 20 53  jv[].){.#ifdef S
3ae0: 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 46 54 53  QLITE_ENABLE_FTS
3af0: 33 0a 20 20 63 68 61 72 20 61 42 75 66 5b 32 34  3.  char aBuf[24
3b00: 5d 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 54  ];.  int rc;.  T
3b10: 63 6c 5f 57 69 64 65 49 6e 74 20 77 3b 0a 20 20  cl_WideInt w;.  
3b20: 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 77 32  sqlite3_int64 w2
3b30: 3b 0a 20 20 69 6e 74 20 6e 42 79 74 65 2c 20 6e  ;.  int nByte, n
3b40: 42 79 74 65 32 3b 0a 0a 20 20 69 66 28 20 6f 62  Byte2;..  if( ob
3b50: 6a 63 21 3d 32 20 29 7b 0a 20 20 20 20 54 63 6c  jc!=2 ){.    Tcl
3b60: 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e  _WrongNumArgs(in
3b70: 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22  terp, 1, objv, "
3b80: 49 4e 54 45 47 45 52 22 29 3b 0a 20 20 20 20 72  INTEGER");.    r
3b90: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
3ba0: 0a 20 20 7d 0a 0a 20 20 72 63 20 3d 20 54 63 6c  .  }..  rc = Tcl
3bb0: 5f 47 65 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f  _GetWideIntFromO
3bc0: 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b  bj(interp, objv[
3bd0: 31 5d 2c 20 26 77 29 3b 0a 20 20 69 66 28 20 72  1], &w);.  if( r
3be0: 63 21 3d 54 43 4c 5f 4f 4b 20 29 20 72 65 74 75  c!=TCL_OK ) retu
3bf0: 72 6e 20 72 63 3b 0a 0a 20 20 6e 42 79 74 65 20  rn rc;..  nByte 
3c00: 3d 20 73 71 6c 69 74 65 33 46 74 73 33 50 75 74  = sqlite3Fts3Put
3c10: 56 61 72 69 6e 74 28 61 42 75 66 2c 20 77 29 3b  Varint(aBuf, w);
3c20: 0a 20 20 6e 42 79 74 65 32 20 3d 20 73 71 6c 69  .  nByte2 = sqli
3c30: 74 65 33 46 74 73 33 47 65 74 56 61 72 69 6e 74  te3Fts3GetVarint
3c40: 28 61 42 75 66 2c 20 26 77 32 29 3b 0a 20 20 69  (aBuf, &w2);.  i
3c50: 66 28 20 77 21 3d 77 32 20 7c 7c 20 6e 42 79 74  f( w!=w2 || nByt
3c60: 65 21 3d 6e 42 79 74 65 32 20 29 7b 0a 20 20 20  e!=nByte2 ){.   
3c70: 20 63 68 61 72 20 2a 7a 45 72 72 20 3d 20 73 71   char *zErr = sq
3c80: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 65  lite3_mprintf("e
3c90: 72 72 6f 72 20 74 65 73 74 69 6e 67 20 25 6c 6c  rror testing %ll
3ca0: 64 22 2c 20 77 29 3b 0a 20 20 20 20 54 63 6c 5f  d", w);.    Tcl_
3cb0: 52 65 73 65 74 52 65 73 75 6c 74 28 69 6e 74 65  ResetResult(inte
3cc0: 72 70 29 3b 0a 20 20 20 20 54 63 6c 5f 41 70 70  rp);.    Tcl_App
3cd0: 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70  endResult(interp
3ce0: 2c 20 7a 45 72 72 2c 20 30 29 3b 0a 20 20 20 20  , zErr, 0);.    
3cf0: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
3d00: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 77 3c 3d  ;.  }..  if( w<=
3d10: 32 31 34 37 34 38 33 36 34 37 20 26 26 20 77 3e  2147483647 && w>
3d20: 3d 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 3b  =0 ){.    int i;
3d30: 0a 20 20 20 20 6e 42 79 74 65 32 20 3d 20 66 74  .    nByte2 = ft
3d40: 73 33 47 65 74 56 61 72 69 6e 74 33 32 28 61 42  s3GetVarint32(aB
3d50: 75 66 2c 20 26 69 29 3b 0a 20 20 20 20 69 66 28  uf, &i);.    if(
3d60: 20 28 69 6e 74 29 77 21 3d 69 20 7c 7c 20 6e 42   (int)w!=i || nB
3d70: 79 74 65 21 3d 6e 42 79 74 65 32 20 29 7b 0a 20  yte!=nByte2 ){. 
3d80: 20 20 20 20 20 63 68 61 72 20 2a 7a 45 72 72 20       char *zErr 
3d90: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
3da0: 66 28 22 65 72 72 6f 72 20 74 65 73 74 69 6e 67  f("error testing
3db0: 20 25 6c 6c 64 20 28 33 32 2d 62 69 74 29 22 2c   %lld (32-bit)",
3dc0: 20 77 29 3b 0a 20 20 20 20 20 20 54 63 6c 5f 52   w);.      Tcl_R
3dd0: 65 73 65 74 52 65 73 75 6c 74 28 69 6e 74 65 72  esetResult(inter
3de0: 70 29 3b 0a 20 20 20 20 20 20 54 63 6c 5f 41 70  p);.      Tcl_Ap
3df0: 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72  pendResult(inter
3e00: 70 2c 20 7a 45 72 72 2c 20 30 29 3b 0a 20 20 20  p, zErr, 0);.   
3e10: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
3e20: 52 4f 52 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  ROR;.    }.  }..
3e30: 23 65 6e 64 69 66 0a 20 20 55 4e 55 53 45 44 5f  #endif.  UNUSED_
3e40: 50 41 52 41 4d 45 54 45 52 28 63 6c 69 65 6e 74  PARAMETER(client
3e50: 44 61 74 61 29 3b 0a 20 20 72 65 74 75 72 6e 20  Data);.  return 
3e60: 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 0a 2a  TCL_OK;.}../* .*
3e70: 2a 20 45 6e 64 20 6f 66 20 74 6f 6b 65 6e 69 7a  * End of tokeniz
3e80: 65 72 20 63 6f 64 65 2e 0a 2a 2a 2a 2a 2a 2a 2a  er code..*******
3e90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3ea0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3eb0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3ec0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3ed0: 2a 2a 2a 2f 20 0a 0a 69 6e 74 20 53 71 6c 69 74  ***/ ..int Sqlit
3ee0: 65 74 65 73 74 66 74 73 33 5f 49 6e 69 74 28 54  etestfts3_Init(T
3ef0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
3f00: 70 29 7b 0a 20 20 54 63 6c 5f 43 72 65 61 74 65  p){.  Tcl_Create
3f10: 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72  ObjCommand(inter
3f20: 70 2c 20 22 66 74 73 33 5f 6e 65 61 72 5f 6d 61  p, "fts3_near_ma
3f30: 74 63 68 22 2c 20 66 74 73 33 5f 6e 65 61 72 5f  tch", fts3_near_
3f40: 6d 61 74 63 68 5f 63 6d 64 2c 20 30 2c 20 30 29  match_cmd, 0, 0)
3f50: 3b 0a 20 20 54 63 6c 5f 43 72 65 61 74 65 4f 62  ;.  Tcl_CreateOb
3f60: 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c  jCommand(interp,
3f70: 20 0a 20 20 20 20 20 20 22 66 74 73 33 5f 63 6f   .      "fts3_co
3f80: 6e 66 69 67 75 72 65 5f 69 6e 63 72 5f 6c 6f 61  nfigure_incr_loa
3f90: 64 22 2c 20 66 74 73 33 5f 63 6f 6e 66 69 67 75  d", fts3_configu
3fa0: 72 65 5f 69 6e 63 72 5f 6c 6f 61 64 5f 63 6d 64  re_incr_load_cmd
3fb0: 2c 20 30 2c 20 30 0a 20 20 29 3b 0a 20 20 54 63  , 0, 0.  );.  Tc
3fc0: 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61  l_CreateObjComma
3fd0: 6e 64 28 0a 20 20 20 20 20 20 69 6e 74 65 72 70  nd(.      interp
3fe0: 2c 20 22 66 74 73 33 5f 74 65 73 74 5f 74 6f 6b  , "fts3_test_tok
3ff0: 65 6e 69 7a 65 72 22 2c 20 66 74 73 33 5f 74 65  enizer", fts3_te
4000: 73 74 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 6d 64  st_tokenizer_cmd
4010: 2c 20 30 2c 20 30 0a 20 20 29 3b 0a 0a 20 20 54  , 0, 0.  );..  T
4020: 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d  cl_CreateObjComm
4030: 61 6e 64 28 0a 20 20 20 20 20 20 69 6e 74 65 72  and(.      inter
4040: 70 2c 20 22 66 74 73 33 5f 74 65 73 74 5f 76 61  p, "fts3_test_va
4050: 72 69 6e 74 22 2c 20 66 74 73 33 5f 74 65 73 74  rint", fts3_test
4060: 5f 76 61 72 69 6e 74 5f 63 6d 64 2c 20 30 2c 20  _varint_cmd, 0, 
4070: 30 0a 20 20 29 3b 0a 20 20 72 65 74 75 72 6e 20  0.  );.  return 
4080: 54 43 4c 5f 4f 4b 3b 0a 7d 0a 23 65 6e 64 69 66  TCL_OK;.}.#endif
4090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
40a0: 20 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41 42    /* SQLITE_ENAB
40b0: 4c 45 5f 46 54 53 33 20 7c 7c 20 53 51 4c 49 54  LE_FTS3 || SQLIT
40c0: 45 5f 45 4e 41 42 4c 45 5f 46 54 53 34 20 2a 2f  E_ENABLE_FTS4 */
40d0: 0a 23 65 6e 64 69 66 20 20 20 20 20 20 20 20 20  .#endif         
40e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 69 66 64 65           /* ifde
40f0: 66 20 53 51 4c 49 54 45 5f 54 45 53 54 20 2a 2f  f SQLITE_TEST */
4100: 0a                                               .