/ Hex Artifact Content
Login

Artifact 8a3a78c4458b2d7c631fcf4b152a5cd656fa7038:


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 6e 63 6c 75 64 65 20 3c 74 63  */..#include <tc
02e0: 6c 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73  l.h>.#include <s
02f0: 74 72 69 6e 67 2e 68 3e 0a 23 69 6e 63 6c 75 64  tring.h>.#includ
0300: 65 20 3c 61 73 73 65 72 74 2e 68 3e 0a 0a 23 69  e <assert.h>..#i
0310: 66 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45  f defined(SQLITE
0320: 5f 54 45 53 54 29 0a 23 69 66 20 64 65 66 69 6e  _TEST).#if defin
0330: 65 64 28 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45  ed(SQLITE_ENABLE
0340: 5f 46 54 53 33 29 20 7c 7c 20 64 65 66 69 6e 65  _FTS3) || define
0350: 64 28 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  d(SQLITE_ENABLE_
0360: 46 54 53 34 29 0a 0a 2f 2a 20 52 65 71 75 69 72  FTS4)../* Requir
0370: 65 64 20 73 6f 20 74 68 61 74 20 74 68 65 20 22  ed so that the "
0380: 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41  ifdef SQLITE_ENA
0390: 42 4c 45 5f 46 54 53 33 22 20 62 65 6c 6f 77 20  BLE_FTS3" below 
03a0: 77 6f 72 6b 73 20 2a 2f 0a 23 69 6e 63 6c 75 64  works */.#includ
03b0: 65 20 22 66 74 73 33 49 6e 74 2e 68 22 0a 0a 23  e "fts3Int.h"..#
03c0: 64 65 66 69 6e 65 20 4e 4d 5f 4d 41 58 5f 54 4f  define NM_MAX_TO
03d0: 4b 45 4e 20 31 32 0a 0a 74 79 70 65 64 65 66 20  KEN 12..typedef 
03e0: 73 74 72 75 63 74 20 4e 65 61 72 50 68 72 61 73  struct NearPhras
03f0: 65 20 4e 65 61 72 50 68 72 61 73 65 3b 0a 74 79  e NearPhrase;.ty
0400: 70 65 64 65 66 20 73 74 72 75 63 74 20 4e 65 61  pedef struct Nea
0410: 72 44 6f 63 75 6d 65 6e 74 20 4e 65 61 72 44 6f  rDocument NearDo
0420: 63 75 6d 65 6e 74 3b 0a 74 79 70 65 64 65 66 20  cument;.typedef 
0430: 73 74 72 75 63 74 20 4e 65 61 72 54 6f 6b 65 6e  struct NearToken
0440: 20 4e 65 61 72 54 6f 6b 65 6e 3b 0a 0a 73 74 72   NearToken;..str
0450: 75 63 74 20 4e 65 61 72 44 6f 63 75 6d 65 6e 74  uct NearDocument
0460: 20 7b 0a 20 20 69 6e 74 20 6e 54 6f 6b 65 6e 3b   {.  int nToken;
0470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0480: 20 20 20 20 20 2f 2a 20 4c 65 6e 67 74 68 20 6f       /* Length o
0490: 66 20 74 6f 6b 65 6e 20 69 6e 20 62 79 74 65 73  f token in bytes
04a0: 20 2a 2f 0a 20 20 4e 65 61 72 54 6f 6b 65 6e 20   */.  NearToken 
04b0: 2a 61 54 6f 6b 65 6e 3b 20 20 20 20 20 20 20 20  *aToken;        
04c0: 20 20 20 20 20 20 2f 2a 20 54 6f 6b 65 6e 20 61        /* Token a
04d0: 72 72 61 79 20 2a 2f 0a 7d 3b 0a 0a 73 74 72 75  rray */.};..stru
04e0: 63 74 20 4e 65 61 72 54 6f 6b 65 6e 20 7b 0a 20  ct NearToken {. 
04f0: 20 69 6e 74 20 6e 3b 20 20 20 20 20 20 20 20 20   int n;         
0500: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0510: 20 2f 2a 20 4c 65 6e 67 74 68 20 6f 66 20 74 6f   /* Length of to
0520: 6b 65 6e 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  ken in bytes */.
0530: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 3b    const char *z;
0540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0550: 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20    /* Pointer to 
0560: 74 6f 6b 65 6e 20 73 74 72 69 6e 67 20 2a 2f 0a  token string */.
0570: 7d 3b 0a 0a 73 74 72 75 63 74 20 4e 65 61 72 50  };..struct NearP
0580: 68 72 61 73 65 20 7b 0a 20 20 69 6e 74 20 6e 4e  hrase {.  int nN
0590: 65 61 72 3b 20 20 20 20 20 20 20 20 20 20 20 20  ear;            
05a0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 72 65            /* Pre
05b0: 63 65 64 69 6e 67 20 4e 45 41 52 20 76 61 6c 75  ceding NEAR valu
05c0: 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 54 6f 6b 65  e */.  int nToke
05d0: 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  n;              
05e0: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
05f0: 20 6f 66 20 74 6f 6b 65 6e 73 20 69 6e 20 74 68   of tokens in th
0600: 69 73 20 70 68 72 61 73 65 20 2a 2f 0a 20 20 4e  is phrase */.  N
0610: 65 61 72 54 6f 6b 65 6e 20 61 54 6f 6b 65 6e 5b  earToken aToken[
0620: 4e 4d 5f 4d 41 58 5f 54 4f 4b 45 4e 5d 3b 20 2f  NM_MAX_TOKEN]; /
0630: 2a 20 41 72 72 61 79 20 6f 66 20 74 6f 6b 65 6e  * Array of token
0640: 73 20 69 6e 20 74 68 69 73 20 70 68 72 61 73 65  s in this phrase
0650: 20 2a 2f 0a 7d 3b 0a 0a 73 74 61 74 69 63 20 69   */.};..static i
0660: 6e 74 20 6e 6d 5f 70 68 72 61 73 65 5f 6d 61 74  nt nm_phrase_mat
0670: 63 68 28 0a 20 20 4e 65 61 72 50 68 72 61 73 65  ch(.  NearPhrase
0680: 20 2a 70 2c 0a 20 20 4e 65 61 72 54 6f 6b 65 6e   *p,.  NearToken
0690: 20 2a 61 54 6f 6b 65 6e 0a 29 7b 0a 20 20 69 6e   *aToken.){.  in
06a0: 74 20 69 69 3b 0a 0a 20 20 66 6f 72 28 69 69 3d  t ii;..  for(ii=
06b0: 30 3b 20 69 69 3c 70 2d 3e 6e 54 6f 6b 65 6e 3b  0; ii<p->nToken;
06c0: 20 69 69 2b 2b 29 7b 0a 20 20 20 20 4e 65 61 72   ii++){.    Near
06d0: 54 6f 6b 65 6e 20 2a 70 54 6f 6b 65 6e 20 3d 20  Token *pToken = 
06e0: 26 70 2d 3e 61 54 6f 6b 65 6e 5b 69 69 5d 3b 0a  &p->aToken[ii];.
06f0: 20 20 20 20 69 66 28 20 70 54 6f 6b 65 6e 2d 3e      if( pToken->
0700: 6e 3e 30 20 26 26 20 70 54 6f 6b 65 6e 2d 3e 7a  n>0 && pToken->z
0710: 5b 70 54 6f 6b 65 6e 2d 3e 6e 2d 31 5d 3d 3d 27  [pToken->n-1]=='
0720: 2a 27 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  *' ){.      if( 
0730: 61 54 6f 6b 65 6e 5b 69 69 5d 2e 6e 3c 28 70 54  aToken[ii].n<(pT
0740: 6f 6b 65 6e 2d 3e 6e 2d 31 29 20 29 20 72 65 74  oken->n-1) ) ret
0750: 75 72 6e 20 30 3b 0a 20 20 20 20 20 20 69 66 28  urn 0;.      if(
0760: 20 6d 65 6d 63 6d 70 28 61 54 6f 6b 65 6e 5b 69   memcmp(aToken[i
0770: 69 5d 2e 7a 2c 20 70 54 6f 6b 65 6e 2d 3e 7a 2c  i].z, pToken->z,
0780: 20 70 54 6f 6b 65 6e 2d 3e 6e 2d 31 29 20 29 20   pToken->n-1) ) 
0790: 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 7d 65  return 0;.    }e
07a0: 6c 73 65 7b 0a 20 20 20 20 20 20 69 66 28 20 61  lse{.      if( a
07b0: 54 6f 6b 65 6e 5b 69 69 5d 2e 6e 21 3d 70 54 6f  Token[ii].n!=pTo
07c0: 6b 65 6e 2d 3e 6e 20 29 20 72 65 74 75 72 6e 20  ken->n ) return 
07d0: 30 3b 0a 20 20 20 20 20 20 69 66 28 20 6d 65 6d  0;.      if( mem
07e0: 63 6d 70 28 61 54 6f 6b 65 6e 5b 69 69 5d 2e 7a  cmp(aToken[ii].z
07f0: 2c 20 70 54 6f 6b 65 6e 2d 3e 7a 2c 20 70 54 6f  , pToken->z, pTo
0800: 6b 65 6e 2d 3e 6e 29 20 29 20 72 65 74 75 72 6e  ken->n) ) return
0810: 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20   0;.    }.  }.. 
0820: 20 72 65 74 75 72 6e 20 31 3b 0a 7d 0a 0a 73 74   return 1;.}..st
0830: 61 74 69 63 20 69 6e 74 20 6e 6d 5f 6e 65 61 72  atic int nm_near
0840: 5f 63 68 61 69 6e 28 0a 20 20 69 6e 74 20 69 44  _chain(.  int iD
0850: 69 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ir,             
0860: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 69 72            /* Dir
0870: 65 63 74 69 6f 6e 20 74 6f 20 69 74 65 72 61 74  ection to iterat
0880: 65 20 74 68 72 6f 75 67 68 20 61 50 68 72 61 73  e through aPhras
0890: 65 5b 5d 20 2a 2f 0a 20 20 4e 65 61 72 44 6f 63  e[] */.  NearDoc
08a0: 75 6d 65 6e 74 20 2a 70 44 6f 63 2c 20 20 20 20  ument *pDoc,    
08b0: 20 20 20 20 20 20 20 20 20 2f 2a 20 44 6f 63 75           /* Docu
08c0: 6d 65 6e 74 20 74 6f 20 6d 61 74 63 68 20 61 67  ment to match ag
08d0: 61 69 6e 73 74 20 2a 2f 0a 20 20 69 6e 74 20 69  ainst */.  int i
08e0: 50 6f 73 2c 20 20 20 20 20 20 20 20 20 20 20 20  Pos,            
08f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f             /* Po
0900: 73 69 74 69 6f 6e 20 61 74 20 77 68 69 63 68 20  sition at which 
0910: 69 50 68 72 61 73 65 20 77 61 73 20 66 6f 75 6e  iPhrase was foun
0920: 64 20 2a 2f 0a 20 20 69 6e 74 20 6e 50 68 72 61  d */.  int nPhra
0930: 73 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  se,             
0940: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
0950: 66 20 70 68 72 61 73 65 20 61 72 72 61 79 20 2a  f phrase array *
0960: 2f 0a 20 20 4e 65 61 72 50 68 72 61 73 65 20 2a  /.  NearPhrase *
0970: 61 50 68 72 61 73 65 2c 20 20 20 20 20 20 20 20  aPhrase,        
0980: 20 20 20 20 2f 2a 20 50 68 72 61 73 65 20 61 72      /* Phrase ar
0990: 72 61 79 20 2a 2f 0a 20 20 69 6e 74 20 69 50 68  ray */.  int iPh
09a0: 72 61 73 65 20 20 20 20 20 20 20 20 20 20 20 20  rase            
09b0: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65           /* Inde
09c0: 78 20 6f 66 20 70 68 72 61 73 65 20 66 6f 75 6e  x of phrase foun
09d0: 64 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 53  d */.){.  int iS
09e0: 74 61 72 74 3b 0a 20 20 69 6e 74 20 69 53 74 6f  tart;.  int iSto
09f0: 70 3b 0a 20 20 69 6e 74 20 69 69 3b 0a 20 20 69  p;.  int ii;.  i
0a00: 6e 74 20 6e 4e 65 61 72 3b 0a 20 20 69 6e 74 20  nt nNear;.  int 
0a10: 69 50 68 72 61 73 65 32 3b 0a 20 20 4e 65 61 72  iPhrase2;.  Near
0a20: 50 68 72 61 73 65 20 2a 70 3b 0a 20 20 4e 65 61  Phrase *p;.  Nea
0a30: 72 50 68 72 61 73 65 20 2a 70 50 72 65 76 3b 0a  rPhrase *pPrev;.
0a40: 0a 20 20 61 73 73 65 72 74 28 20 69 44 69 72 3d  .  assert( iDir=
0a50: 3d 31 20 7c 7c 20 69 44 69 72 3d 3d 2d 31 20 29  =1 || iDir==-1 )
0a60: 3b 0a 0a 20 20 69 66 28 20 69 44 69 72 3d 3d 31  ;..  if( iDir==1
0a70: 20 29 7b 0a 20 20 20 20 69 66 28 20 28 69 50 68   ){.    if( (iPh
0a80: 72 61 73 65 2b 31 29 3d 3d 6e 50 68 72 61 73 65  rase+1)==nPhrase
0a90: 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 20   ) return 1;.   
0aa0: 20 6e 4e 65 61 72 20 3d 20 61 50 68 72 61 73 65   nNear = aPhrase
0ab0: 5b 69 50 68 72 61 73 65 2b 31 5d 2e 6e 4e 65 61  [iPhrase+1].nNea
0ac0: 72 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  r;.  }else{.    
0ad0: 69 66 28 20 69 50 68 72 61 73 65 3d 3d 30 20 29  if( iPhrase==0 )
0ae0: 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 20 20 6e   return 1;.    n
0af0: 4e 65 61 72 20 3d 20 61 50 68 72 61 73 65 5b 69  Near = aPhrase[i
0b00: 50 68 72 61 73 65 5d 2e 6e 4e 65 61 72 3b 0a 20  Phrase].nNear;. 
0b10: 20 7d 0a 20 20 70 50 72 65 76 20 3d 20 26 61 50   }.  pPrev = &aP
0b20: 68 72 61 73 65 5b 69 50 68 72 61 73 65 5d 3b 0a  hrase[iPhrase];.
0b30: 20 20 69 50 68 72 61 73 65 32 20 3d 20 69 50 68    iPhrase2 = iPh
0b40: 72 61 73 65 2b 69 44 69 72 3b 0a 20 20 70 20 3d  rase+iDir;.  p =
0b50: 20 26 61 50 68 72 61 73 65 5b 69 50 68 72 61 73   &aPhrase[iPhras
0b60: 65 32 5d 3b 0a 0a 20 20 69 53 74 61 72 74 20 3d  e2];..  iStart =
0b70: 20 69 50 6f 73 20 2d 20 6e 4e 65 61 72 20 2d 20   iPos - nNear - 
0b80: 70 2d 3e 6e 54 6f 6b 65 6e 3b 0a 20 20 69 53 74  p->nToken;.  iSt
0b90: 6f 70 20 3d 20 69 50 6f 73 20 2b 20 6e 4e 65 61  op = iPos + nNea
0ba0: 72 20 2b 20 70 50 72 65 76 2d 3e 6e 54 6f 6b 65  r + pPrev->nToke
0bb0: 6e 3b 0a 0a 20 20 69 66 28 20 69 53 74 61 72 74  n;..  if( iStart
0bc0: 3c 30 20 29 20 69 53 74 61 72 74 20 3d 20 30 3b  <0 ) iStart = 0;
0bd0: 0a 20 20 69 66 28 20 69 53 74 6f 70 20 3e 20 70  .  if( iStop > p
0be0: 44 6f 63 2d 3e 6e 54 6f 6b 65 6e 20 2d 20 70 2d  Doc->nToken - p-
0bf0: 3e 6e 54 6f 6b 65 6e 20 29 20 69 53 74 6f 70 20  >nToken ) iStop 
0c00: 3d 20 70 44 6f 63 2d 3e 6e 54 6f 6b 65 6e 20 2d  = pDoc->nToken -
0c10: 20 70 2d 3e 6e 54 6f 6b 65 6e 3b 0a 0a 20 20 66   p->nToken;..  f
0c20: 6f 72 28 69 69 3d 69 53 74 61 72 74 3b 20 69 69  or(ii=iStart; ii
0c30: 3c 3d 69 53 74 6f 70 3b 20 69 69 2b 2b 29 7b 0a  <=iStop; ii++){.
0c40: 20 20 20 20 69 66 28 20 6e 6d 5f 70 68 72 61 73      if( nm_phras
0c50: 65 5f 6d 61 74 63 68 28 70 2c 20 26 70 44 6f 63  e_match(p, &pDoc
0c60: 2d 3e 61 54 6f 6b 65 6e 5b 69 69 5d 29 20 29 7b  ->aToken[ii]) ){
0c70: 0a 20 20 20 20 20 20 69 66 28 20 6e 6d 5f 6e 65  .      if( nm_ne
0c80: 61 72 5f 63 68 61 69 6e 28 69 44 69 72 2c 20 70  ar_chain(iDir, p
0c90: 44 6f 63 2c 20 69 69 2c 20 6e 50 68 72 61 73 65  Doc, ii, nPhrase
0ca0: 2c 20 61 50 68 72 61 73 65 2c 20 69 50 68 72 61  , aPhrase, iPhra
0cb0: 73 65 32 29 20 29 20 72 65 74 75 72 6e 20 31 3b  se2) ) return 1;
0cc0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65  .    }.  }..  re
0cd0: 74 75 72 6e 20 30 3b 0a 7d 0a 0a 73 74 61 74 69  turn 0;.}..stati
0ce0: 63 20 69 6e 74 20 6e 6d 5f 6d 61 74 63 68 5f 63  c int nm_match_c
0cf0: 6f 75 6e 74 28 0a 20 20 4e 65 61 72 44 6f 63 75  ount(.  NearDocu
0d00: 6d 65 6e 74 20 2a 70 44 6f 63 2c 20 20 20 20 20  ment *pDoc,     
0d10: 20 20 20 20 20 20 20 20 2f 2a 20 44 6f 63 75 6d          /* Docum
0d20: 65 6e 74 20 74 6f 20 6d 61 74 63 68 20 61 67 61  ent to match aga
0d30: 69 6e 73 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 50  inst */.  int nP
0d40: 68 72 61 73 65 2c 20 20 20 20 20 20 20 20 20 20  hrase,          
0d50: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
0d60: 65 20 6f 66 20 70 68 72 61 73 65 20 61 72 72 61  e of phrase arra
0d70: 79 20 2a 2f 0a 20 20 4e 65 61 72 50 68 72 61 73  y */.  NearPhras
0d80: 65 20 2a 61 50 68 72 61 73 65 2c 20 20 20 20 20  e *aPhrase,     
0d90: 20 20 20 20 20 20 20 2f 2a 20 50 68 72 61 73 65         /* Phrase
0da0: 20 61 72 72 61 79 20 2a 2f 0a 20 20 69 6e 74 20   array */.  int 
0db0: 69 50 68 72 61 73 65 20 20 20 20 20 20 20 20 20  iPhrase         
0dc0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
0dd0: 6e 64 65 78 20 6f 66 20 70 68 72 61 73 65 20 74  ndex of phrase t
0de0: 6f 20 63 6f 75 6e 74 20 6d 61 74 63 68 65 73 20  o count matches 
0df0: 66 6f 72 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  for */.){.  int 
0e00: 6e 4f 63 63 20 3d 20 30 3b 0a 20 20 69 6e 74 20  nOcc = 0;.  int 
0e10: 69 69 3b 0a 20 20 4e 65 61 72 50 68 72 61 73 65  ii;.  NearPhrase
0e20: 20 2a 70 20 3d 20 26 61 50 68 72 61 73 65 5b 69   *p = &aPhrase[i
0e30: 50 68 72 61 73 65 5d 3b 0a 0a 20 20 66 6f 72 28  Phrase];..  for(
0e40: 69 69 3d 30 3b 20 69 69 3c 28 70 44 6f 63 2d 3e  ii=0; ii<(pDoc->
0e50: 6e 54 6f 6b 65 6e 20 2b 20 31 20 2d 20 70 2d 3e  nToken + 1 - p->
0e60: 6e 54 6f 6b 65 6e 29 3b 20 69 69 2b 2b 29 7b 0a  nToken); ii++){.
0e70: 20 20 20 20 69 66 28 20 6e 6d 5f 70 68 72 61 73      if( nm_phras
0e80: 65 5f 6d 61 74 63 68 28 70 2c 20 26 70 44 6f 63  e_match(p, &pDoc
0e90: 2d 3e 61 54 6f 6b 65 6e 5b 69 69 5d 29 20 29 7b  ->aToken[ii]) ){
0ea0: 0a 20 20 20 20 20 20 2f 2a 20 54 65 73 74 20 66  .      /* Test f
0eb0: 6f 72 77 61 72 64 20 4e 45 41 52 20 63 68 61 69  orward NEAR chai
0ec0: 6e 20 28 69 3e 69 50 68 72 61 73 65 29 20 2a 2f  n (i>iPhrase) */
0ed0: 0a 20 20 20 20 20 20 69 66 28 20 30 3d 3d 6e 6d  .      if( 0==nm
0ee0: 5f 6e 65 61 72 5f 63 68 61 69 6e 28 31 2c 20 70  _near_chain(1, p
0ef0: 44 6f 63 2c 20 69 69 2c 20 6e 50 68 72 61 73 65  Doc, ii, nPhrase
0f00: 2c 20 61 50 68 72 61 73 65 2c 20 69 50 68 72 61  , aPhrase, iPhra
0f10: 73 65 29 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a  se) ) continue;.
0f20: 0a 20 20 20 20 20 20 2f 2a 20 54 65 73 74 20 72  .      /* Test r
0f30: 65 76 65 72 73 65 20 4e 45 41 52 20 63 68 61 69  everse NEAR chai
0f40: 6e 20 28 69 3c 69 50 68 72 61 73 65 29 20 2a 2f  n (i<iPhrase) */
0f50: 0a 20 20 20 20 20 20 69 66 28 20 30 3d 3d 6e 6d  .      if( 0==nm
0f60: 5f 6e 65 61 72 5f 63 68 61 69 6e 28 2d 31 2c 20  _near_chain(-1, 
0f70: 70 44 6f 63 2c 20 69 69 2c 20 6e 50 68 72 61 73  pDoc, ii, nPhras
0f80: 65 2c 20 61 50 68 72 61 73 65 2c 20 69 50 68 72  e, aPhrase, iPhr
0f90: 61 73 65 29 20 29 20 63 6f 6e 74 69 6e 75 65 3b  ase) ) continue;
0fa0: 0a 0a 20 20 20 20 20 20 2f 2a 20 54 68 69 73 20  ..      /* This 
0fb0: 69 73 20 61 20 72 65 61 6c 20 6d 61 74 63 68 2e  is a real match.
0fc0: 20 49 6e 63 72 65 6d 65 6e 74 20 74 68 65 20 63   Increment the c
0fd0: 6f 75 6e 74 65 72 2e 20 2a 2f 0a 20 20 20 20 20  ounter. */.     
0fe0: 20 6e 4f 63 63 2b 2b 3b 0a 20 20 20 20 7d 0a 20   nOcc++;.    }. 
0ff0: 20 7d 20 0a 0a 20 20 72 65 74 75 72 6e 20 6e 4f   } ..  return nO
1000: 63 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 63 6c  cc;.}../*.** Tcl
1010: 63 6d 64 3a 20 66 74 73 33 5f 6e 65 61 72 5f 6d  cmd: fts3_near_m
1020: 61 74 63 68 20 44 4f 43 55 4d 45 4e 54 20 45 58  atch DOCUMENT EX
1030: 50 52 20 3f 4f 50 54 49 4f 4e 53 3f 0a 2a 2f 0a  PR ?OPTIONS?.*/.
1040: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 33 5f  static int fts3_
1050: 6e 65 61 72 5f 6d 61 74 63 68 5f 63 6d 64 28 0a  near_match_cmd(.
1060: 20 20 43 6c 69 65 6e 74 44 61 74 61 20 63 6c 69    ClientData cli
1070: 65 6e 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49  entData,.  Tcl_I
1080: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20  nterp *interp,. 
1090: 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c   int objc,.  Tcl
10a0: 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76  _Obj *CONST objv
10b0: 5b 5d 0a 29 7b 0a 20 20 69 6e 74 20 6e 54 6f 74  [].){.  int nTot
10c0: 61 6c 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63  al = 0;.  int rc
10d0: 3b 0a 20 20 69 6e 74 20 69 69 3b 0a 20 20 69 6e  ;.  int ii;.  in
10e0: 74 20 6e 50 68 72 61 73 65 3b 0a 20 20 4e 65 61  t nPhrase;.  Nea
10f0: 72 50 68 72 61 73 65 20 2a 61 50 68 72 61 73 65  rPhrase *aPhrase
1100: 20 3d 20 30 3b 0a 20 20 4e 65 61 72 44 6f 63 75   = 0;.  NearDocu
1110: 6d 65 6e 74 20 64 6f 63 20 3d 20 7b 30 2c 20 30  ment doc = {0, 0
1120: 7d 3b 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 2a 61  };.  Tcl_Obj **a
1130: 70 44 6f 63 54 6f 6b 65 6e 3b 0a 20 20 54 63 6c  pDocToken;.  Tcl
1140: 5f 4f 62 6a 20 2a 70 52 65 74 3b 0a 20 20 54 63  _Obj *pRet;.  Tc
1150: 6c 5f 4f 62 6a 20 2a 70 50 68 72 61 73 65 63 6f  l_Obj *pPhraseco
1160: 75 6e 74 20 3d 20 30 3b 0a 20 20 0a 20 20 54 63  unt = 0;.  .  Tc
1170: 6c 5f 4f 62 6a 20 2a 2a 61 70 45 78 70 72 54 6f  l_Obj **apExprTo
1180: 6b 65 6e 3b 0a 20 20 69 6e 74 20 6e 45 78 70 72  ken;.  int nExpr
1190: 54 6f 6b 65 6e 3b 0a 0a 20 20 55 4e 55 53 45 44  Token;..  UNUSED
11a0: 5f 50 41 52 41 4d 45 54 45 52 28 63 6c 69 65 6e  _PARAMETER(clien
11b0: 74 44 61 74 61 29 3b 0a 0a 20 20 2f 2a 20 4d 75  tData);..  /* Mu
11c0: 73 74 20 68 61 76 65 20 33 20 6f 72 20 6d 6f 72  st have 3 or mor
11d0: 65 20 61 72 67 75 6d 65 6e 74 73 2e 20 2a 2f 0a  e arguments. */.
11e0: 20 20 69 66 28 20 6f 62 6a 63 3c 33 20 7c 7c 20    if( objc<3 || 
11f0: 28 6f 62 6a 63 25 32 29 3d 3d 30 20 29 7b 0a 20  (objc%2)==0 ){. 
1200: 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41     Tcl_WrongNumA
1210: 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f  rgs(interp, 1, o
1220: 62 6a 76 2c 20 22 44 4f 43 55 4d 45 4e 54 20 45  bjv, "DOCUMENT E
1230: 58 50 52 20 3f 4f 50 54 49 4f 4e 20 56 41 4c 55  XPR ?OPTION VALU
1240: 45 3f 2e 2e 2e 22 29 3b 0a 20 20 20 20 72 63 20  E?...");.    rc 
1250: 3d 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20  = TCL_ERROR;.   
1260: 20 67 6f 74 6f 20 6e 65 61 72 5f 6d 61 74 63 68   goto near_match
1270: 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20 66 6f 72  _out;.  }..  for
1280: 28 69 69 3d 33 3b 20 69 69 3c 6f 62 6a 63 3b 20  (ii=3; ii<objc; 
1290: 69 69 2b 3d 32 29 7b 0a 20 20 20 20 65 6e 75 6d  ii+=2){.    enum
12a0: 20 4e 4d 5f 65 6e 75 6d 20 7b 20 4e 4d 5f 50 48   NM_enum { NM_PH
12b0: 52 41 53 45 43 4f 55 4e 54 53 20 7d 3b 0a 20 20  RASECOUNTS };.  
12c0: 20 20 73 74 72 75 63 74 20 54 65 73 74 6e 6d 53    struct TestnmS
12d0: 75 62 63 6d 64 20 7b 0a 20 20 20 20 20 20 63 68  ubcmd {.      ch
12e0: 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20 20  ar *zName;.     
12f0: 20 65 6e 75 6d 20 4e 4d 5f 65 6e 75 6d 20 65 4f   enum NM_enum eO
1300: 70 74 3b 0a 20 20 20 20 7d 20 61 4f 70 74 5b 5d  pt;.    } aOpt[]
1310: 20 3d 20 7b 0a 20 20 20 20 20 20 7b 20 22 2d 70   = {.      { "-p
1320: 68 72 61 73 65 63 6f 75 6e 74 76 61 72 22 2c 20  hrasecountvar", 
1330: 4e 4d 5f 50 48 52 41 53 45 43 4f 55 4e 54 53 20  NM_PHRASECOUNTS 
1340: 7d 2c 0a 20 20 20 20 20 20 7b 20 30 2c 20 30 20  },.      { 0, 0 
1350: 7d 0a 20 20 20 20 7d 3b 0a 20 20 20 20 69 6e 74  }.    };.    int
1360: 20 69 4f 70 74 3b 0a 20 20 20 20 69 66 28 20 54   iOpt;.    if( T
1370: 63 6c 5f 47 65 74 49 6e 64 65 78 46 72 6f 6d 4f  cl_GetIndexFromO
1380: 62 6a 53 74 72 75 63 74 28 0a 20 20 20 20 20 20  bjStruct(.      
1390: 20 20 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 69    interp, objv[i
13a0: 69 5d 2c 20 61 4f 70 74 2c 20 73 69 7a 65 6f 66  i], aOpt, sizeof
13b0: 28 61 4f 70 74 5b 30 5d 29 2c 20 22 6f 70 74 69  (aOpt[0]), "opti
13c0: 6f 6e 22 2c 20 30 2c 20 26 69 4f 70 74 29 20 0a  on", 0, &iOpt) .
13d0: 20 20 20 20 29 7b 0a 20 20 20 20 20 20 72 65 74      ){.      ret
13e0: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
13f0: 20 20 20 7d 0a 0a 20 20 20 20 73 77 69 74 63 68     }..    switch
1400: 28 20 61 4f 70 74 5b 69 4f 70 74 5d 2e 65 4f 70  ( aOpt[iOpt].eOp
1410: 74 20 29 7b 0a 20 20 20 20 20 20 63 61 73 65 20  t ){.      case 
1420: 4e 4d 5f 50 48 52 41 53 45 43 4f 55 4e 54 53 3a  NM_PHRASECOUNTS:
1430: 0a 20 20 20 20 20 20 20 20 70 50 68 72 61 73 65  .        pPhrase
1440: 63 6f 75 6e 74 20 3d 20 6f 62 6a 76 5b 69 69 2b  count = objv[ii+
1450: 31 5d 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61  1];.        brea
1460: 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  k;.    }.  }..  
1470: 72 63 20 3d 20 54 63 6c 5f 4c 69 73 74 4f 62 6a  rc = Tcl_ListObj
1480: 47 65 74 45 6c 65 6d 65 6e 74 73 28 69 6e 74 65  GetElements(inte
1490: 72 70 2c 20 6f 62 6a 76 5b 31 5d 2c 20 26 64 6f  rp, objv[1], &do
14a0: 63 2e 6e 54 6f 6b 65 6e 2c 20 26 61 70 44 6f 63  c.nToken, &apDoc
14b0: 54 6f 6b 65 6e 29 3b 0a 20 20 69 66 28 20 72 63  Token);.  if( rc
14c0: 21 3d 54 43 4c 5f 4f 4b 20 29 20 67 6f 74 6f 20  !=TCL_OK ) goto 
14d0: 6e 65 61 72 5f 6d 61 74 63 68 5f 6f 75 74 3b 0a  near_match_out;.
14e0: 20 20 64 6f 63 2e 61 54 6f 6b 65 6e 20 3d 20 28    doc.aToken = (
14f0: 4e 65 61 72 54 6f 6b 65 6e 20 2a 29 63 6b 61 6c  NearToken *)ckal
1500: 6c 6f 63 28 64 6f 63 2e 6e 54 6f 6b 65 6e 2a 73  loc(doc.nToken*s
1510: 69 7a 65 6f 66 28 4e 65 61 72 54 6f 6b 65 6e 29  izeof(NearToken)
1520: 29 3b 0a 20 20 66 6f 72 28 69 69 3d 30 3b 20 69  );.  for(ii=0; i
1530: 69 3c 64 6f 63 2e 6e 54 6f 6b 65 6e 3b 20 69 69  i<doc.nToken; ii
1540: 2b 2b 29 7b 0a 20 20 20 20 64 6f 63 2e 61 54 6f  ++){.    doc.aTo
1550: 6b 65 6e 5b 69 69 5d 2e 7a 20 3d 20 54 63 6c 5f  ken[ii].z = Tcl_
1560: 47 65 74 53 74 72 69 6e 67 46 72 6f 6d 4f 62 6a  GetStringFromObj
1570: 28 61 70 44 6f 63 54 6f 6b 65 6e 5b 69 69 5d 2c  (apDocToken[ii],
1580: 20 26 64 6f 63 2e 61 54 6f 6b 65 6e 5b 69 69 5d   &doc.aToken[ii]
1590: 2e 6e 29 3b 0a 20 20 7d 0a 0a 20 20 72 63 20 3d  .n);.  }..  rc =
15a0: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 47 65 74 45   Tcl_ListObjGetE
15b0: 6c 65 6d 65 6e 74 73 28 69 6e 74 65 72 70 2c 20  lements(interp, 
15c0: 6f 62 6a 76 5b 32 5d 2c 20 26 6e 45 78 70 72 54  objv[2], &nExprT
15d0: 6f 6b 65 6e 2c 20 26 61 70 45 78 70 72 54 6f 6b  oken, &apExprTok
15e0: 65 6e 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 54  en);.  if( rc!=T
15f0: 43 4c 5f 4f 4b 20 29 20 67 6f 74 6f 20 6e 65 61  CL_OK ) goto nea
1600: 72 5f 6d 61 74 63 68 5f 6f 75 74 3b 0a 0a 20 20  r_match_out;..  
1610: 6e 50 68 72 61 73 65 20 3d 20 28 6e 45 78 70 72  nPhrase = (nExpr
1620: 54 6f 6b 65 6e 20 2b 20 31 29 20 2f 20 32 3b 0a  Token + 1) / 2;.
1630: 20 20 61 50 68 72 61 73 65 20 3d 20 28 4e 65 61    aPhrase = (Nea
1640: 72 50 68 72 61 73 65 20 2a 29 63 6b 61 6c 6c 6f  rPhrase *)ckallo
1650: 63 28 6e 50 68 72 61 73 65 20 2a 20 73 69 7a 65  c(nPhrase * size
1660: 6f 66 28 4e 65 61 72 50 68 72 61 73 65 29 29 3b  of(NearPhrase));
1670: 0a 20 20 6d 65 6d 73 65 74 28 61 50 68 72 61 73  .  memset(aPhras
1680: 65 2c 20 30 2c 20 6e 50 68 72 61 73 65 20 2a 20  e, 0, nPhrase * 
1690: 73 69 7a 65 6f 66 28 4e 65 61 72 50 68 72 61 73  sizeof(NearPhras
16a0: 65 29 29 3b 0a 20 20 66 6f 72 28 69 69 3d 30 3b  e));.  for(ii=0;
16b0: 20 69 69 3c 6e 50 68 72 61 73 65 3b 20 69 69 2b   ii<nPhrase; ii+
16c0: 2b 29 7b 0a 20 20 20 20 54 63 6c 5f 4f 62 6a 20  +){.    Tcl_Obj 
16d0: 2a 70 50 68 72 61 73 65 20 3d 20 61 70 45 78 70  *pPhrase = apExp
16e0: 72 54 6f 6b 65 6e 5b 69 69 2a 32 5d 3b 0a 20 20  rToken[ii*2];.  
16f0: 20 20 54 63 6c 5f 4f 62 6a 20 2a 2a 61 70 54 6f    Tcl_Obj **apTo
1700: 6b 65 6e 3b 0a 20 20 20 20 69 6e 74 20 6e 54 6f  ken;.    int nTo
1710: 6b 65 6e 3b 0a 20 20 20 20 69 6e 74 20 6a 6a 3b  ken;.    int jj;
1720: 0a 0a 20 20 20 20 72 63 20 3d 20 54 63 6c 5f 4c  ..    rc = Tcl_L
1730: 69 73 74 4f 62 6a 47 65 74 45 6c 65 6d 65 6e 74  istObjGetElement
1740: 73 28 69 6e 74 65 72 70 2c 20 70 50 68 72 61 73  s(interp, pPhras
1750: 65 2c 20 26 6e 54 6f 6b 65 6e 2c 20 26 61 70 54  e, &nToken, &apT
1760: 6f 6b 65 6e 29 3b 0a 20 20 20 20 69 66 28 20 72  oken);.    if( r
1770: 63 21 3d 54 43 4c 5f 4f 4b 20 29 20 67 6f 74 6f  c!=TCL_OK ) goto
1780: 20 6e 65 61 72 5f 6d 61 74 63 68 5f 6f 75 74 3b   near_match_out;
1790: 0a 20 20 20 20 69 66 28 20 6e 54 6f 6b 65 6e 3e  .    if( nToken>
17a0: 4e 4d 5f 4d 41 58 5f 54 4f 4b 45 4e 20 29 7b 0a  NM_MAX_TOKEN ){.
17b0: 20 20 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64        Tcl_Append
17c0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22  Result(interp, "
17d0: 54 6f 6f 20 6d 61 6e 79 20 74 6f 6b 65 6e 73 20  Too many tokens 
17e0: 69 6e 20 70 68 72 61 73 65 22 2c 20 30 29 3b 0a  in phrase", 0);.
17f0: 20 20 20 20 20 20 72 63 20 3d 20 54 43 4c 5f 45        rc = TCL_E
1800: 52 52 4f 52 3b 0a 20 20 20 20 20 20 67 6f 74 6f  RROR;.      goto
1810: 20 6e 65 61 72 5f 6d 61 74 63 68 5f 6f 75 74 3b   near_match_out;
1820: 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f 72 28 6a  .    }.    for(j
1830: 6a 3d 30 3b 20 6a 6a 3c 6e 54 6f 6b 65 6e 3b 20  j=0; jj<nToken; 
1840: 6a 6a 2b 2b 29 7b 0a 20 20 20 20 20 20 4e 65 61  jj++){.      Nea
1850: 72 54 6f 6b 65 6e 20 2a 70 54 20 3d 20 26 61 50  rToken *pT = &aP
1860: 68 72 61 73 65 5b 69 69 5d 2e 61 54 6f 6b 65 6e  hrase[ii].aToken
1870: 5b 6a 6a 5d 3b 0a 20 20 20 20 20 20 70 54 2d 3e  [jj];.      pT->
1880: 7a 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  z = Tcl_GetStrin
1890: 67 46 72 6f 6d 4f 62 6a 28 61 70 54 6f 6b 65 6e  gFromObj(apToken
18a0: 5b 6a 6a 5d 2c 20 26 70 54 2d 3e 6e 29 3b 0a 20  [jj], &pT->n);. 
18b0: 20 20 20 7d 0a 20 20 20 20 61 50 68 72 61 73 65     }.    aPhrase
18c0: 5b 69 69 5d 2e 6e 54 6f 6b 65 6e 20 3d 20 6e 54  [ii].nToken = nT
18d0: 6f 6b 65 6e 3b 0a 20 20 7d 0a 20 20 66 6f 72 28  oken;.  }.  for(
18e0: 69 69 3d 31 3b 20 69 69 3c 6e 50 68 72 61 73 65  ii=1; ii<nPhrase
18f0: 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 54 63 6c  ; ii++){.    Tcl
1900: 5f 4f 62 6a 20 2a 70 4e 65 61 72 20 3d 20 61 70  _Obj *pNear = ap
1910: 45 78 70 72 54 6f 6b 65 6e 5b 32 2a 69 69 2d 31  ExprToken[2*ii-1
1920: 5d 3b 0a 20 20 20 20 69 6e 74 20 6e 4e 65 61 72  ];.    int nNear
1930: 3b 0a 20 20 20 20 72 63 20 3d 20 54 63 6c 5f 47  ;.    rc = Tcl_G
1940: 65 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74  etIntFromObj(int
1950: 65 72 70 2c 20 70 4e 65 61 72 2c 20 26 6e 4e 65  erp, pNear, &nNe
1960: 61 72 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21  ar);.    if( rc!
1970: 3d 54 43 4c 5f 4f 4b 20 29 20 67 6f 74 6f 20 6e  =TCL_OK ) goto n
1980: 65 61 72 5f 6d 61 74 63 68 5f 6f 75 74 3b 0a 20  ear_match_out;. 
1990: 20 20 20 61 50 68 72 61 73 65 5b 69 69 5d 2e 6e     aPhrase[ii].n
19a0: 4e 65 61 72 20 3d 20 6e 4e 65 61 72 3b 0a 20 20  Near = nNear;.  
19b0: 7d 0a 0a 20 20 70 52 65 74 20 3d 20 54 63 6c 5f  }..  pRet = Tcl_
19c0: 4e 65 77 4f 62 6a 28 29 3b 0a 20 20 54 63 6c 5f  NewObj();.  Tcl_
19d0: 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 70 52 65  IncrRefCount(pRe
19e0: 74 29 3b 0a 20 20 66 6f 72 28 69 69 3d 30 3b 20  t);.  for(ii=0; 
19f0: 69 69 3c 6e 50 68 72 61 73 65 3b 20 69 69 2b 2b  ii<nPhrase; ii++
1a00: 29 7b 0a 20 20 20 20 69 6e 74 20 6e 4f 63 63 20  ){.    int nOcc 
1a10: 3d 20 6e 6d 5f 6d 61 74 63 68 5f 63 6f 75 6e 74  = nm_match_count
1a20: 28 26 64 6f 63 2c 20 6e 50 68 72 61 73 65 2c 20  (&doc, nPhrase, 
1a30: 61 50 68 72 61 73 65 2c 20 69 69 29 3b 0a 20 20  aPhrase, ii);.  
1a40: 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70    Tcl_ListObjApp
1a50: 65 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65 72  endElement(inter
1a60: 70 2c 20 70 52 65 74 2c 20 54 63 6c 5f 4e 65 77  p, pRet, Tcl_New
1a70: 49 6e 74 4f 62 6a 28 6e 4f 63 63 29 29 3b 0a 20  IntObj(nOcc));. 
1a80: 20 20 20 6e 54 6f 74 61 6c 20 2b 3d 20 6e 4f 63     nTotal += nOc
1a90: 63 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 50 68  c;.  }.  if( pPh
1aa0: 72 61 73 65 63 6f 75 6e 74 20 29 7b 0a 20 20 20  rasecount ){.   
1ab0: 20 54 63 6c 5f 4f 62 6a 53 65 74 56 61 72 32 28   Tcl_ObjSetVar2(
1ac0: 69 6e 74 65 72 70 2c 20 70 50 68 72 61 73 65 63  interp, pPhrasec
1ad0: 6f 75 6e 74 2c 20 30 2c 20 70 52 65 74 2c 20 30  ount, 0, pRet, 0
1ae0: 29 3b 0a 20 20 7d 0a 20 20 54 63 6c 5f 44 65 63  );.  }.  Tcl_Dec
1af0: 72 52 65 66 43 6f 75 6e 74 28 70 52 65 74 29 3b  rRefCount(pRet);
1b00: 0a 20 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73  .  Tcl_SetObjRes
1b10: 75 6c 74 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f  ult(interp, Tcl_
1b20: 4e 65 77 42 6f 6f 6c 65 61 6e 4f 62 6a 28 6e 54  NewBooleanObj(nT
1b30: 6f 74 61 6c 3e 30 29 29 3b 0a 0a 20 6e 65 61 72  otal>0));.. near
1b40: 5f 6d 61 74 63 68 5f 6f 75 74 3a 20 0a 20 20 63  _match_out: .  c
1b50: 6b 66 72 65 65 28 28 63 68 61 72 20 2a 29 61 50  kfree((char *)aP
1b60: 68 72 61 73 65 29 3b 0a 20 20 63 6b 66 72 65 65  hrase);.  ckfree
1b70: 28 28 63 68 61 72 20 2a 29 64 6f 63 2e 61 54 6f  ((char *)doc.aTo
1b80: 6b 65 6e 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  ken);.  return r
1b90: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 20 20 54 63  c;.}../*.**   Tc
1ba0: 6c 63 6d 64 3a 20 66 74 73 33 5f 63 6f 6e 66 69  lcmd: fts3_confi
1bb0: 67 75 72 65 5f 69 6e 63 72 5f 6c 6f 61 64 20 3f  gure_incr_load ?
1bc0: 43 48 55 4e 4b 53 49 5a 45 20 54 48 52 45 53 48  CHUNKSIZE THRESH
1bd0: 4f 4c 44 3f 0a 2a 2a 0a 2a 2a 20 4e 6f 72 6d 61  OLD?.**.** Norma
1be0: 6c 6c 79 2c 20 46 54 53 20 75 73 65 73 20 68 61  lly, FTS uses ha
1bf0: 72 64 2d 63 6f 64 65 64 20 76 61 6c 75 65 73 20  rd-coded values 
1c00: 74 6f 20 64 65 74 65 72 6d 69 6e 65 20 74 68 65  to determine the
1c10: 20 6d 69 6e 69 6d 75 6d 20 64 6f 63 6c 69 73 74   minimum doclist
1c20: 0a 2a 2a 20 73 69 7a 65 20 65 6c 69 67 69 62 6c  .** size eligibl
1c30: 65 20 66 6f 72 20 69 6e 63 72 65 6d 65 6e 74 61  e for incrementa
1c40: 6c 20 6c 6f 61 64 69 6e 67 2c 20 61 6e 64 20 74  l loading, and t
1c50: 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65 20 63  he size of the c
1c60: 68 75 6e 6b 73 20 6c 6f 61 64 65 64 0a 2a 2a 20  hunks loaded.** 
1c70: 77 68 65 6e 20 61 20 64 6f 63 6c 69 73 74 20 69  when a doclist i
1c80: 73 20 69 6e 63 72 65 6d 65 6e 74 61 6c 6c 79 20  s incrementally 
1c90: 6c 6f 61 64 65 64 2e 20 54 68 69 73 20 63 6f 6d  loaded. This com
1ca0: 6d 61 6e 64 20 61 6c 6c 6f 77 73 20 74 68 65 20  mand allows the 
1cb0: 62 75 69 6c 74 2d 69 6e 0a 2a 2a 20 76 61 6c 75  built-in.** valu
1cc0: 65 73 20 74 6f 20 62 65 20 6f 76 65 72 72 69 64  es to be overrid
1cd0: 64 65 6e 20 66 6f 72 20 74 65 73 74 69 6e 67 20  den for testing 
1ce0: 70 75 72 70 6f 73 65 73 2e 0a 2a 2a 0a 2a 2a 20  purposes..**.** 
1cf0: 49 66 20 70 72 65 73 65 6e 74 2c 20 74 68 65 20  If present, the 
1d00: 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 69  first argument i
1d10: 73 20 74 68 65 20 63 68 75 6e 6b 73 69 7a 65 20  s the chunksize 
1d20: 69 6e 20 62 79 74 65 73 20 74 6f 20 6c 6f 61 64  in bytes to load
1d30: 20 64 6f 63 6c 69 73 74 73 0a 2a 2a 20 69 6e 2e   doclists.** in.
1d40: 20 54 68 65 20 73 65 63 6f 6e 64 20 61 72 67 75   The second argu
1d50: 6d 65 6e 74 20 69 73 20 74 68 65 20 6d 69 6e 69  ment is the mini
1d60: 6d 75 6d 20 64 6f 63 6c 69 73 74 20 73 69 7a 65  mum doclist size
1d70: 20 69 6e 20 62 79 74 65 73 20 74 6f 20 75 73 65   in bytes to use
1d80: 0a 2a 2a 20 69 6e 63 72 65 6d 65 6e 74 61 6c 20  .** incremental 
1d90: 6c 6f 61 64 69 6e 67 20 77 69 74 68 2e 0a 2a 2a  loading with..**
1da0: 0a 2a 2a 20 57 68 65 74 68 65 72 20 6f 72 20 6e  .** Whether or n
1db0: 6f 74 20 74 68 65 20 61 72 67 75 6d 65 6e 74 73  ot the arguments
1dc0: 20 61 72 65 20 70 72 65 73 65 6e 74 2c 20 74 68   are present, th
1dd0: 69 73 20 63 6f 6d 6d 61 6e 64 20 72 65 74 75 72  is command retur
1de0: 6e 73 20 61 20 6c 69 73 74 20 6f 66 0a 2a 2a 20  ns a list of.** 
1df0: 74 77 6f 20 69 6e 74 65 67 65 72 73 20 2d 20 74  two integers - t
1e00: 68 65 20 69 6e 69 74 69 61 6c 20 63 68 75 6e 6b  he initial chunk
1e10: 73 69 7a 65 20 61 6e 64 20 74 68 72 65 73 68 6f  size and thresho
1e20: 6c 64 20 77 68 65 6e 20 74 68 65 20 63 6f 6d 6d  ld when the comm
1e30: 61 6e 64 20 69 73 0a 2a 2a 20 69 6e 76 6f 6b 65  and is.** invoke
1e40: 64 2e 20 54 68 69 73 20 63 61 6e 20 62 65 20 75  d. This can be u
1e50: 73 65 64 20 74 6f 20 72 65 73 74 6f 72 65 20 74  sed to restore t
1e60: 68 65 20 64 65 66 61 75 6c 74 20 62 65 68 61 76  he default behav
1e70: 69 6f 72 20 61 66 74 65 72 20 72 75 6e 6e 69 6e  ior after runnin
1e80: 67 0a 2a 2a 20 74 65 73 74 73 2e 20 46 6f 72 20  g.** tests. For 
1e90: 65 78 61 6d 70 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20  example:.**.**  
1ea0: 20 20 23 20 4f 76 65 72 72 69 64 65 20 69 6e 63    # Override inc
1eb0: 72 2d 6c 6f 61 64 20 73 65 74 74 69 6e 67 73 20  r-load settings 
1ec0: 66 6f 72 20 74 65 73 74 69 6e 67 3a 0a 2a 2a 20  for testing:.** 
1ed0: 20 20 20 73 65 74 20 63 66 67 20 5b 66 74 73 33     set cfg [fts3
1ee0: 5f 63 6f 6e 66 69 67 75 72 65 5f 69 6e 63 72 5f  _configure_incr_
1ef0: 6c 6f 61 64 20 24 6e 65 77 5f 63 68 75 6e 6b 73  load $new_chunks
1f00: 69 7a 65 20 24 6e 65 77 5f 74 68 72 65 73 68 6f  ize $new_thresho
1f10: 6c 64 5d 0a 2a 2a 0a 2a 2a 20 20 20 20 2e 2e 2e  ld].**.**    ...
1f20: 2e 20 72 75 6e 20 74 65 73 74 73 20 2e 2e 2e 2e  . run tests ....
1f30: 0a 2a 2a 0a 2a 2a 20 20 20 20 23 20 52 65 73 74  .**.**    # Rest
1f40: 6f 72 65 20 69 6e 69 74 69 61 6c 20 69 6e 63 72  ore initial incr
1f50: 2d 6c 6f 61 64 20 73 65 74 74 69 6e 67 73 3a 0a  -load settings:.
1f60: 2a 2a 20 20 20 20 65 76 61 6c 20 66 74 73 33 5f  **    eval fts3_
1f70: 63 6f 6e 66 69 67 75 72 65 5f 69 6e 63 72 5f 6c  configure_incr_l
1f80: 6f 61 64 20 24 63 66 67 0a 2a 2f 0a 73 74 61 74  oad $cfg.*/.stat
1f90: 69 63 20 69 6e 74 20 66 74 73 33 5f 63 6f 6e 66  ic int fts3_conf
1fa0: 69 67 75 72 65 5f 69 6e 63 72 5f 6c 6f 61 64 5f  igure_incr_load_
1fb0: 63 6d 64 28 0a 20 20 43 6c 69 65 6e 74 44 61 74  cmd(.  ClientDat
1fc0: 61 20 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20  a clientData,.  
1fd0: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
1fe0: 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a  rp,.  int objc,.
1ff0: 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54    Tcl_Obj *CONST
2000: 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 23 69 66 64 65   objv[].){.#ifde
2010: 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  f SQLITE_ENABLE_
2020: 46 54 53 33 0a 20 20 65 78 74 65 72 6e 20 69 6e  FTS3.  extern in
2030: 74 20 74 65 73 74 5f 66 74 73 33 5f 6e 6f 64 65  t test_fts3_node
2040: 5f 63 68 75 6e 6b 73 69 7a 65 3b 0a 20 20 65 78  _chunksize;.  ex
2050: 74 65 72 6e 20 69 6e 74 20 74 65 73 74 5f 66 74  tern int test_ft
2060: 73 33 5f 6e 6f 64 65 5f 63 68 75 6e 6b 5f 74 68  s3_node_chunk_th
2070: 72 65 73 68 6f 6c 64 3b 0a 20 20 54 63 6c 5f 4f  reshold;.  Tcl_O
2080: 62 6a 20 2a 70 52 65 74 3b 0a 0a 20 20 69 66 28  bj *pRet;..  if(
2090: 20 6f 62 6a 63 21 3d 31 20 26 26 20 6f 62 6a 63   objc!=1 && objc
20a0: 21 3d 33 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57  !=3 ){.    Tcl_W
20b0: 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65  rongNumArgs(inte
20c0: 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 3f 43  rp, 1, objv, "?C
20d0: 48 55 4e 4b 53 49 5a 45 20 54 48 52 45 53 48 4f  HUNKSIZE THRESHO
20e0: 4c 44 3f 22 29 3b 0a 20 20 20 20 72 65 74 75 72  LD?");.    retur
20f0: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d  n TCL_ERROR;.  }
2100: 0a 0a 20 20 70 52 65 74 20 3d 20 54 63 6c 5f 4e  ..  pRet = Tcl_N
2110: 65 77 4f 62 6a 28 29 3b 0a 20 20 54 63 6c 5f 49  ewObj();.  Tcl_I
2120: 6e 63 72 52 65 66 43 6f 75 6e 74 28 70 52 65 74  ncrRefCount(pRet
2130: 29 3b 0a 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a  );.  Tcl_ListObj
2140: 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 0a 20  AppendElement(. 
2150: 20 20 20 20 20 69 6e 74 65 72 70 2c 20 70 52 65       interp, pRe
2160: 74 2c 20 54 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a  t, Tcl_NewIntObj
2170: 28 74 65 73 74 5f 66 74 73 33 5f 6e 6f 64 65 5f  (test_fts3_node_
2180: 63 68 75 6e 6b 73 69 7a 65 29 29 3b 0a 20 20 54  chunksize));.  T
2190: 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64  cl_ListObjAppend
21a0: 45 6c 65 6d 65 6e 74 28 0a 20 20 20 20 20 20 69  Element(.      i
21b0: 6e 74 65 72 70 2c 20 70 52 65 74 2c 20 54 63 6c  nterp, pRet, Tcl
21c0: 5f 4e 65 77 49 6e 74 4f 62 6a 28 74 65 73 74 5f  _NewIntObj(test_
21d0: 66 74 73 33 5f 6e 6f 64 65 5f 63 68 75 6e 6b 5f  fts3_node_chunk_
21e0: 74 68 72 65 73 68 6f 6c 64 29 29 3b 0a 0a 20 20  threshold));..  
21f0: 69 66 28 20 6f 62 6a 63 3d 3d 33 20 29 7b 0a 20  if( objc==3 ){. 
2200: 20 20 20 69 6e 74 20 69 41 72 67 31 3b 0a 20 20     int iArg1;.  
2210: 20 20 69 6e 74 20 69 41 72 67 32 3b 0a 20 20 20    int iArg2;.   
2220: 20 69 66 28 20 54 63 6c 5f 47 65 74 49 6e 74 46   if( Tcl_GetIntF
2230: 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f  romObj(interp, o
2240: 62 6a 76 5b 31 5d 2c 20 26 69 41 72 67 31 29 0a  bjv[1], &iArg1).
2250: 20 20 20 20 20 7c 7c 20 54 63 6c 5f 47 65 74 49       || Tcl_GetI
2260: 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70  ntFromObj(interp
2270: 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26 69 41 72 67  , objv[2], &iArg
2280: 32 29 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20  2).    ){.      
2290: 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74  Tcl_DecrRefCount
22a0: 28 70 52 65 74 29 3b 0a 20 20 20 20 20 20 72 65  (pRet);.      re
22b0: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
22c0: 20 20 20 20 7d 0a 20 20 20 20 74 65 73 74 5f 66      }.    test_f
22d0: 74 73 33 5f 6e 6f 64 65 5f 63 68 75 6e 6b 73 69  ts3_node_chunksi
22e0: 7a 65 20 3d 20 69 41 72 67 31 3b 0a 20 20 20 20  ze = iArg1;.    
22f0: 74 65 73 74 5f 66 74 73 33 5f 6e 6f 64 65 5f 63  test_fts3_node_c
2300: 68 75 6e 6b 5f 74 68 72 65 73 68 6f 6c 64 20 3d  hunk_threshold =
2310: 20 69 41 72 67 32 3b 0a 20 20 7d 0a 0a 20 20 54   iArg2;.  }..  T
2320: 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_SetObjResult(
2330: 69 6e 74 65 72 70 2c 20 70 52 65 74 29 3b 0a 20  interp, pRet);. 
2340: 20 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e   Tcl_DecrRefCoun
2350: 74 28 70 52 65 74 29 3b 0a 23 65 6e 64 69 66 0a  t(pRet);.#endif.
2360: 20 20 55 4e 55 53 45 44 5f 50 41 52 41 4d 45 54    UNUSED_PARAMET
2370: 45 52 28 63 6c 69 65 6e 74 44 61 74 61 29 3b 0a  ER(clientData);.
2380: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b    return TCL_OK;
2390: 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54  .}..#ifdef SQLIT
23a0: 45 5f 45 4e 41 42 4c 45 5f 46 54 53 33 0a 2f 2a  E_ENABLE_FTS3./*
23b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
23c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
23d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
23e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
23f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a 20 42 65 67  *********.** Beg
2400: 69 6e 6e 69 6e 67 20 6f 66 20 74 65 73 74 20 74  inning of test t
2410: 6f 6b 65 6e 69 7a 65 72 20 63 6f 64 65 2e 0a 2a  okenizer code..*
2420: 2a 0a 2a 2a 20 46 6f 72 20 6c 61 6e 67 75 61 67  *.** For languag
2430: 65 20 30 2c 20 74 68 69 73 20 74 6f 6b 65 6e 69  e 0, this tokeni
2440: 7a 65 72 20 69 73 20 73 69 6d 69 6c 61 72 20 74  zer is similar t
2450: 6f 20 74 68 65 20 64 65 66 61 75 6c 74 20 27 73  o the default 's
2460: 69 6d 70 6c 65 27 20 0a 2a 2a 20 74 6f 6b 65 6e  imple' .** token
2470: 69 7a 65 72 2e 20 46 6f 72 20 6f 74 68 65 72 20  izer. For other 
2480: 6c 61 6e 67 75 61 67 65 73 20 4c 2c 20 74 68 65  languages L, the
2490: 20 66 6f 6c 6c 6f 77 69 6e 67 3a 0a 2a 2a 0a 2a   following:.**.*
24a0: 2a 20 20 20 2a 20 4f 64 64 20 6e 75 6d 62 65 72  *   * Odd number
24b0: 65 64 20 6c 61 6e 67 75 61 67 65 73 20 61 72 65  ed languages are
24c0: 20 63 61 73 65 2d 73 65 6e 73 69 74 69 76 65 2e   case-sensitive.
24d0: 20 45 76 65 6e 20 6e 75 6d 62 65 72 65 64 20 0a   Even numbered .
24e0: 2a 2a 20 20 20 20 20 6c 61 6e 67 75 61 67 65 73  **     languages
24f0: 20 61 72 65 20 6e 6f 74 2e 0a 2a 2a 0a 2a 2a 20   are not..**.** 
2500: 20 20 2a 20 4c 61 6e 67 75 61 67 65 20 69 64 73    * Language ids
2510: 20 31 30 30 20 6f 72 20 67 72 65 61 74 65 72 20   100 or greater 
2520: 61 72 65 20 63 6f 6e 73 69 64 65 72 65 64 20 61  are considered a
2530: 6e 20 65 72 72 6f 72 2e 0a 2a 2a 0a 2a 2a 20 54  n error..**.** T
2540: 68 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  he implementatio
2550: 6e 20 61 73 73 75 6d 65 73 20 74 68 61 74 20 74  n assumes that t
2560: 68 65 20 69 6e 70 75 74 20 63 6f 6e 74 61 69 6e  he input contain
2570: 73 20 6f 6e 6c 79 20 41 53 43 49 49 20 63 68 61  s only ASCII cha
2580: 72 61 63 74 65 72 73 0a 2a 2a 20 28 69 2e 65 2e  racters.** (i.e.
2590: 20 74 68 6f 73 65 20 74 68 61 74 20 6d 61 79 20   those that may 
25a0: 62 65 20 65 6e 63 6f 64 65 64 20 69 6e 20 55 54  be encoded in UT
25b0: 46 2d 38 20 75 73 69 6e 67 20 61 20 73 69 6e 67  F-8 using a sing
25c0: 6c 65 20 62 79 74 65 29 2e 0a 2a 2f 0a 74 79 70  le byte)..*/.typ
25d0: 65 64 65 66 20 73 74 72 75 63 74 20 74 65 73 74  edef struct test
25e0: 5f 74 6f 6b 65 6e 69 7a 65 72 20 7b 0a 20 20 73  _tokenizer {.  s
25f0: 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72  qlite3_tokenizer
2600: 20 62 61 73 65 3b 0a 7d 20 74 65 73 74 5f 74 6f   base;.} test_to
2610: 6b 65 6e 69 7a 65 72 3b 0a 0a 74 79 70 65 64 65  kenizer;..typede
2620: 66 20 73 74 72 75 63 74 20 74 65 73 74 5f 74 6f  f struct test_to
2630: 6b 65 6e 69 7a 65 72 5f 63 75 72 73 6f 72 20 7b  kenizer_cursor {
2640: 0a 20 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e  .  sqlite3_token
2650: 69 7a 65 72 5f 63 75 72 73 6f 72 20 62 61 73 65  izer_cursor base
2660: 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ;.  const char *
2670: 61 49 6e 70 75 74 3b 20 20 20 20 20 20 20 20 20  aInput;         
2680: 20 2f 2a 20 49 6e 70 75 74 20 62 65 69 6e 67 20   /* Input being 
2690: 74 6f 6b 65 6e 69 7a 65 64 20 2a 2f 0a 20 20 69  tokenized */.  i
26a0: 6e 74 20 6e 49 6e 70 75 74 3b 20 20 20 20 20 20  nt nInput;      
26b0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
26c0: 69 7a 65 20 6f 66 20 74 68 65 20 69 6e 70 75 74  ize of the input
26d0: 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 69   in bytes */.  i
26e0: 6e 74 20 69 49 6e 70 75 74 3b 20 20 20 20 20 20  nt iInput;      
26f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
2700: 75 72 72 65 6e 74 20 6f 66 66 73 65 74 20 69 6e  urrent offset in
2710: 20 61 49 6e 70 75 74 20 2a 2f 0a 20 20 69 6e 74   aInput */.  int
2720: 20 69 54 6f 6b 65 6e 3b 20 20 20 20 20 20 20 20   iToken;        
2730: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64            /* Ind
2740: 65 78 20 6f 66 20 6e 65 78 74 20 74 6f 6b 65 6e  ex of next token
2750: 20 74 6f 20 62 65 20 72 65 74 75 72 6e 65 64 20   to be returned 
2760: 2a 2f 0a 20 20 63 68 61 72 20 2a 61 42 75 66 66  */.  char *aBuff
2770: 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  er;             
2780: 20 20 2f 2a 20 42 75 66 66 65 72 20 63 6f 6e 74    /* Buffer cont
2790: 61 69 6e 69 6e 67 20 63 75 72 72 65 6e 74 20 74  aining current t
27a0: 6f 6b 65 6e 20 2a 2f 0a 20 20 69 6e 74 20 6e 42  oken */.  int nB
27b0: 75 66 66 65 72 3b 20 20 20 20 20 20 20 20 20 20  uffer;          
27c0: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
27d0: 20 6f 66 20 62 79 74 65 73 20 61 6c 6c 6f 63 61   of bytes alloca
27e0: 74 65 64 20 61 74 20 70 54 6f 6b 65 6e 20 2a 2f  ted at pToken */
27f0: 0a 20 20 69 6e 74 20 69 4c 61 6e 67 69 64 3b 20  .  int iLangid; 
2800: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2810: 2f 2a 20 43 6f 6e 66 69 67 75 72 65 64 20 6c 61  /* Configured la
2820: 6e 67 75 61 67 65 20 69 64 20 2a 2f 0a 7d 20 74  nguage id */.} t
2830: 65 73 74 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75  est_tokenizer_cu
2840: 72 73 6f 72 3b 0a 0a 73 74 61 74 69 63 20 69 6e  rsor;..static in
2850: 74 20 74 65 73 74 54 6f 6b 65 6e 69 7a 65 72 43  t testTokenizerC
2860: 72 65 61 74 65 28 0a 20 20 69 6e 74 20 61 72 67  reate(.  int arg
2870: 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 20  c, const char * 
2880: 63 6f 6e 73 74 20 2a 61 72 67 76 2c 0a 20 20 73  const *argv,.  s
2890: 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72  qlite3_tokenizer
28a0: 20 2a 2a 70 70 54 6f 6b 65 6e 69 7a 65 72 0a 29   **ppTokenizer.)
28b0: 7b 0a 20 20 74 65 73 74 5f 74 6f 6b 65 6e 69 7a  {.  test_tokeniz
28c0: 65 72 20 2a 70 4e 65 77 3b 0a 20 20 55 4e 55 53  er *pNew;.  UNUS
28d0: 45 44 5f 50 41 52 41 4d 45 54 45 52 28 61 72 67  ED_PARAMETER(arg
28e0: 63 29 3b 0a 20 20 55 4e 55 53 45 44 5f 50 41 52  c);.  UNUSED_PAR
28f0: 41 4d 45 54 45 52 28 61 72 67 76 29 3b 0a 0a 20  AMETER(argv);.. 
2900: 20 70 4e 65 77 20 3d 20 73 71 6c 69 74 65 33 5f   pNew = sqlite3_
2910: 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 74 65  malloc(sizeof(te
2920: 73 74 5f 74 6f 6b 65 6e 69 7a 65 72 29 29 3b 0a  st_tokenizer));.
2930: 20 20 69 66 28 20 21 70 4e 65 77 20 29 20 72 65    if( !pNew ) re
2940: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
2950: 4d 3b 0a 20 20 6d 65 6d 73 65 74 28 70 4e 65 77  M;.  memset(pNew
2960: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 74 65 73 74  , 0, sizeof(test
2970: 5f 74 6f 6b 65 6e 69 7a 65 72 29 29 3b 0a 0a 20  _tokenizer));.. 
2980: 20 2a 70 70 54 6f 6b 65 6e 69 7a 65 72 20 3d 20   *ppTokenizer = 
2990: 28 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a  (sqlite3_tokeniz
29a0: 65 72 20 2a 29 70 4e 65 77 3b 0a 20 20 72 65 74  er *)pNew;.  ret
29b0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
29c0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 65 73  ..static int tes
29d0: 74 54 6f 6b 65 6e 69 7a 65 72 44 65 73 74 72 6f  tTokenizerDestro
29e0: 79 28 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69  y(sqlite3_tokeni
29f0: 7a 65 72 20 2a 70 54 6f 6b 65 6e 69 7a 65 72 29  zer *pTokenizer)
2a00: 7b 0a 20 20 74 65 73 74 5f 74 6f 6b 65 6e 69 7a  {.  test_tokeniz
2a10: 65 72 20 2a 70 20 3d 20 28 74 65 73 74 5f 74 6f  er *p = (test_to
2a20: 6b 65 6e 69 7a 65 72 20 2a 29 70 54 6f 6b 65 6e  kenizer *)pToken
2a30: 69 7a 65 72 3b 0a 20 20 73 71 6c 69 74 65 33 5f  izer;.  sqlite3_
2a40: 66 72 65 65 28 70 29 3b 0a 20 20 72 65 74 75 72  free(p);.  retur
2a50: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
2a60: 73 74 61 74 69 63 20 69 6e 74 20 74 65 73 74 54  static int testT
2a70: 6f 6b 65 6e 69 7a 65 72 4f 70 65 6e 28 0a 20 20  okenizerOpen(.  
2a80: 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65  sqlite3_tokenize
2a90: 72 20 2a 70 54 6f 6b 65 6e 69 7a 65 72 2c 20 20  r *pTokenizer,  
2aa0: 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 74 6f         /* The to
2ab0: 6b 65 6e 69 7a 65 72 20 2a 2f 0a 20 20 63 6f 6e  kenizer */.  con
2ac0: 73 74 20 63 68 61 72 20 2a 70 49 6e 70 75 74 2c  st char *pInput,
2ad0: 20 69 6e 74 20 6e 42 79 74 65 73 2c 20 20 20 20   int nBytes,    
2ae0: 20 20 20 20 2f 2a 20 53 74 72 69 6e 67 20 74 6f      /* String to
2af0: 20 62 65 20 74 6f 6b 65 6e 69 7a 65 64 20 2a 2f   be tokenized */
2b00: 0a 20 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e  .  sqlite3_token
2b10: 69 7a 65 72 5f 63 75 72 73 6f 72 20 2a 2a 70 70  izer_cursor **pp
2b20: 43 75 72 73 6f 72 20 20 20 20 2f 2a 20 4f 55 54  Cursor    /* OUT
2b30: 3a 20 54 6f 6b 65 6e 69 7a 61 74 69 6f 6e 20 63  : Tokenization c
2b40: 75 72 73 6f 72 20 2a 2f 0a 29 7b 0a 20 20 69 6e  ursor */.){.  in
2b50: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
2b60: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
2b70: 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63       /* Return c
2b80: 6f 64 65 20 2a 2f 0a 20 20 74 65 73 74 5f 74 6f  ode */.  test_to
2b90: 6b 65 6e 69 7a 65 72 5f 63 75 72 73 6f 72 20 2a  kenizer_cursor *
2ba0: 70 43 73 72 3b 20 20 20 20 20 20 20 20 20 20 20  pCsr;           
2bb0: 2f 2a 20 4e 65 77 20 63 75 72 73 6f 72 20 6f 62  /* New cursor ob
2bc0: 6a 65 63 74 20 2a 2f 0a 0a 20 20 55 4e 55 53 45  ject */..  UNUSE
2bd0: 44 5f 50 41 52 41 4d 45 54 45 52 28 70 54 6f 6b  D_PARAMETER(pTok
2be0: 65 6e 69 7a 65 72 29 3b 0a 0a 20 20 70 43 73 72  enizer);..  pCsr
2bf0: 20 3d 20 28 74 65 73 74 5f 74 6f 6b 65 6e 69 7a   = (test_tokeniz
2c00: 65 72 5f 63 75 72 73 6f 72 20 2a 29 73 71 6c 69  er_cursor *)sqli
2c10: 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f  te3_malloc(sizeo
2c20: 66 28 74 65 73 74 5f 74 6f 6b 65 6e 69 7a 65 72  f(test_tokenizer
2c30: 5f 63 75 72 73 6f 72 29 29 3b 0a 20 20 69 66 28  _cursor));.  if(
2c40: 20 70 43 73 72 3d 3d 30 20 29 7b 0a 20 20 20 20   pCsr==0 ){.    
2c50: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  rc = SQLITE_NOME
2c60: 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  M;.  }else{.    
2c70: 6d 65 6d 73 65 74 28 70 43 73 72 2c 20 30 2c 20  memset(pCsr, 0, 
2c80: 73 69 7a 65 6f 66 28 74 65 73 74 5f 74 6f 6b 65  sizeof(test_toke
2c90: 6e 69 7a 65 72 5f 63 75 72 73 6f 72 29 29 3b 0a  nizer_cursor));.
2ca0: 20 20 20 20 70 43 73 72 2d 3e 61 49 6e 70 75 74      pCsr->aInput
2cb0: 20 3d 20 70 49 6e 70 75 74 3b 0a 20 20 20 20 69   = pInput;.    i
2cc0: 66 28 20 6e 42 79 74 65 73 3c 30 20 29 7b 0a 20  f( nBytes<0 ){. 
2cd0: 20 20 20 20 20 70 43 73 72 2d 3e 6e 49 6e 70 75       pCsr->nInpu
2ce0: 74 20 3d 20 28 69 6e 74 29 73 74 72 6c 65 6e 28  t = (int)strlen(
2cf0: 70 49 6e 70 75 74 29 3b 0a 20 20 20 20 7d 65 6c  pInput);.    }el
2d00: 73 65 7b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e  se{.      pCsr->
2d10: 6e 49 6e 70 75 74 20 3d 20 6e 42 79 74 65 73 3b  nInput = nBytes;
2d20: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70  .    }.  }..  *p
2d30: 70 43 75 72 73 6f 72 20 3d 20 28 73 71 6c 69 74  pCursor = (sqlit
2d40: 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75 72  e3_tokenizer_cur
2d50: 73 6f 72 20 2a 29 70 43 73 72 3b 0a 20 20 72 65  sor *)pCsr;.  re
2d60: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74  turn rc;.}..stat
2d70: 69 63 20 69 6e 74 20 74 65 73 74 54 6f 6b 65 6e  ic int testToken
2d80: 69 7a 65 72 43 6c 6f 73 65 28 73 71 6c 69 74 65  izerClose(sqlite
2d90: 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75 72 73  3_tokenizer_curs
2da0: 6f 72 20 2a 70 43 75 72 73 6f 72 29 7b 0a 20 20  or *pCursor){.  
2db0: 74 65 73 74 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63  test_tokenizer_c
2dc0: 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 74  ursor *pCsr = (t
2dd0: 65 73 74 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75  est_tokenizer_cu
2de0: 72 73 6f 72 20 2a 29 70 43 75 72 73 6f 72 3b 0a  rsor *)pCursor;.
2df0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
2e00: 43 73 72 2d 3e 61 42 75 66 66 65 72 29 3b 0a 20  Csr->aBuffer);. 
2e10: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43   sqlite3_free(pC
2e20: 73 72 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51  sr);.  return SQ
2e30: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74  LITE_OK;.}..stat
2e40: 69 63 20 69 6e 74 20 74 65 73 74 49 73 54 6f 6b  ic int testIsTok
2e50: 65 6e 43 68 61 72 28 63 68 61 72 20 63 29 7b 0a  enChar(char c){.
2e60: 20 20 72 65 74 75 72 6e 20 28 63 3e 3d 27 61 27    return (c>='a'
2e70: 20 26 26 20 63 3c 3d 27 7a 27 29 20 7c 7c 20 28   && c<='z') || (
2e80: 63 3e 3d 27 41 27 20 26 26 20 63 3c 3d 27 5a 27  c>='A' && c<='Z'
2e90: 29 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20  );.}.static int 
2ea0: 74 65 73 74 54 6f 6c 6f 77 65 72 28 63 68 61 72  testTolower(char
2eb0: 20 63 29 7b 0a 20 20 63 68 61 72 20 72 65 74 20   c){.  char ret 
2ec0: 3d 20 63 3b 0a 20 20 69 66 28 20 72 65 74 3e 3d  = c;.  if( ret>=
2ed0: 27 41 27 20 26 26 20 72 65 74 3c 3d 27 5a 27 29  'A' && ret<='Z')
2ee0: 20 72 65 74 20 3d 20 72 65 74 20 2d 20 28 27 41   ret = ret - ('A
2ef0: 27 2d 27 61 27 29 3b 0a 20 20 72 65 74 75 72 6e  '-'a');.  return
2f00: 20 72 65 74 3b 0a 7d 0a 0a 73 74 61 74 69 63 20   ret;.}..static 
2f10: 69 6e 74 20 74 65 73 74 54 6f 6b 65 6e 69 7a 65  int testTokenize
2f20: 72 4e 65 78 74 28 0a 20 20 73 71 6c 69 74 65 33  rNext(.  sqlite3
2f30: 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75 72 73 6f  _tokenizer_curso
2f40: 72 20 2a 70 43 75 72 73 6f 72 2c 20 20 2f 2a 20  r *pCursor,  /* 
2f50: 43 75 72 73 6f 72 20 72 65 74 75 72 6e 65 64 20  Cursor returned 
2f60: 62 79 20 74 65 73 74 54 6f 6b 65 6e 69 7a 65 72  by testTokenizer
2f70: 4f 70 65 6e 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  Open */.  const 
2f80: 63 68 61 72 20 2a 2a 70 70 54 6f 6b 65 6e 2c 20  char **ppToken, 
2f90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2fa0: 20 4f 55 54 3a 20 2a 70 70 54 6f 6b 65 6e 20 69   OUT: *ppToken i
2fb0: 73 20 74 68 65 20 74 6f 6b 65 6e 20 74 65 78 74  s the token text
2fc0: 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 42 79 74   */.  int *pnByt
2fd0: 65 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  es,             
2fe0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
2ff0: 3a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  : Number of byte
3000: 73 20 69 6e 20 74 6f 6b 65 6e 20 2a 2f 0a 20 20  s in token */.  
3010: 69 6e 74 20 2a 70 69 53 74 61 72 74 4f 66 66 73  int *piStartOffs
3020: 65 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  et,             
3030: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 53 74 61 72      /* OUT: Star
3040: 74 69 6e 67 20 6f 66 66 73 65 74 20 6f 66 20 74  ting offset of t
3050: 6f 6b 65 6e 20 2a 2f 0a 20 20 69 6e 74 20 2a 70  oken */.  int *p
3060: 69 45 6e 64 4f 66 66 73 65 74 2c 20 20 20 20 20  iEndOffset,     
3070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3080: 20 4f 55 54 3a 20 45 6e 64 69 6e 67 20 6f 66 66   OUT: Ending off
3090: 73 65 74 20 6f 66 20 74 6f 6b 65 6e 20 2a 2f 0a  set of token */.
30a0: 20 20 69 6e 74 20 2a 70 69 50 6f 73 69 74 69 6f    int *piPositio
30b0: 6e 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  n               
30c0: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 50 6f        /* OUT: Po
30d0: 73 69 74 69 6f 6e 20 69 6e 74 65 67 65 72 20 6f  sition integer o
30e0: 66 20 74 6f 6b 65 6e 20 2a 2f 0a 29 7b 0a 20 20  f token */.){.  
30f0: 74 65 73 74 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63  test_tokenizer_c
3100: 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 74  ursor *pCsr = (t
3110: 65 73 74 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75  est_tokenizer_cu
3120: 72 73 6f 72 20 2a 29 70 43 75 72 73 6f 72 3b 0a  rsor *)pCursor;.
3130: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
3140: 45 5f 4f 4b 3b 0a 20 20 63 6f 6e 73 74 20 63 68  E_OK;.  const ch
3150: 61 72 20 2a 70 3b 0a 20 20 63 6f 6e 73 74 20 63  ar *p;.  const c
3160: 68 61 72 20 2a 70 45 6e 64 3b 0a 0a 20 20 70 20  har *pEnd;..  p 
3170: 3d 20 26 70 43 73 72 2d 3e 61 49 6e 70 75 74 5b  = &pCsr->aInput[
3180: 70 43 73 72 2d 3e 69 49 6e 70 75 74 5d 3b 0a 20  pCsr->iInput];. 
3190: 20 70 45 6e 64 20 3d 20 26 70 43 73 72 2d 3e 61   pEnd = &pCsr->a
31a0: 49 6e 70 75 74 5b 70 43 73 72 2d 3e 6e 49 6e 70  Input[pCsr->nInp
31b0: 75 74 5d 3b 0a 0a 20 20 2f 2a 20 53 6b 69 70 20  ut];..  /* Skip 
31c0: 70 61 73 74 20 61 6e 79 20 77 68 69 74 65 2d 73  past any white-s
31d0: 70 61 63 65 20 2a 2f 0a 20 20 61 73 73 65 72 74  pace */.  assert
31e0: 28 20 70 3c 3d 70 45 6e 64 20 29 3b 0a 20 20 77  ( p<=pEnd );.  w
31f0: 68 69 6c 65 28 20 70 3c 70 45 6e 64 20 26 26 20  hile( p<pEnd && 
3200: 74 65 73 74 49 73 54 6f 6b 65 6e 43 68 61 72 28  testIsTokenChar(
3210: 2a 70 29 3d 3d 30 20 29 20 70 2b 2b 3b 0a 0a 20  *p)==0 ) p++;.. 
3220: 20 69 66 28 20 70 3d 3d 70 45 6e 64 20 29 7b 0a   if( p==pEnd ){.
3230: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
3240: 44 4f 4e 45 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  DONE;.  }else{. 
3250: 20 20 20 2f 2a 20 41 64 76 61 6e 63 65 20 74 6f     /* Advance to
3260: 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20   the end of the 
3270: 74 6f 6b 65 6e 20 2a 2f 0a 20 20 20 20 63 6f 6e  token */.    con
3280: 73 74 20 63 68 61 72 20 2a 70 54 6f 6b 65 6e 20  st char *pToken 
3290: 3d 20 70 3b 0a 20 20 20 20 69 6e 74 20 6e 54 6f  = p;.    int nTo
32a0: 6b 65 6e 3b 0a 20 20 20 20 77 68 69 6c 65 28 20  ken;.    while( 
32b0: 70 3c 70 45 6e 64 20 26 26 20 74 65 73 74 49 73  p<pEnd && testIs
32c0: 54 6f 6b 65 6e 43 68 61 72 28 2a 70 29 20 29 20  TokenChar(*p) ) 
32d0: 70 2b 2b 3b 0a 20 20 20 20 6e 54 6f 6b 65 6e 20  p++;.    nToken 
32e0: 3d 20 28 69 6e 74 29 28 70 2d 70 54 6f 6b 65 6e  = (int)(p-pToken
32f0: 29 3b 0a 0a 20 20 20 20 2f 2a 20 43 6f 70 79 20  );..    /* Copy 
3300: 74 68 65 20 74 6f 6b 65 6e 20 69 6e 74 6f 20 74  the token into t
3310: 68 65 20 62 75 66 66 65 72 20 2a 2f 0a 20 20 20  he buffer */.   
3320: 20 69 66 28 20 6e 54 6f 6b 65 6e 3e 70 43 73 72   if( nToken>pCsr
3330: 2d 3e 6e 42 75 66 66 65 72 20 29 7b 0a 20 20 20  ->nBuffer ){.   
3340: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
3350: 70 43 73 72 2d 3e 61 42 75 66 66 65 72 29 3b 0a  pCsr->aBuffer);.
3360: 20 20 20 20 20 20 70 43 73 72 2d 3e 61 42 75 66        pCsr->aBuf
3370: 66 65 72 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61  fer = sqlite3_ma
3380: 6c 6c 6f 63 28 6e 54 6f 6b 65 6e 29 3b 0a 20 20  lloc(nToken);.  
3390: 20 20 7d 0a 20 20 20 20 69 66 28 20 70 43 73 72    }.    if( pCsr
33a0: 2d 3e 61 42 75 66 66 65 72 3d 3d 30 20 29 7b 0a  ->aBuffer==0 ){.
33b0: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
33c0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 65 6c  E_NOMEM;.    }el
33d0: 73 65 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 3b  se{.      int i;
33e0: 0a 0a 20 20 20 20 20 20 69 66 28 20 70 43 73 72  ..      if( pCsr
33f0: 2d 3e 69 4c 61 6e 67 69 64 20 26 20 30 78 30 30  ->iLangid & 0x00
3400: 30 30 30 30 30 31 20 29 7b 0a 20 20 20 20 20 20  000001 ){.      
3410: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 54 6f    for(i=0; i<nTo
3420: 6b 65 6e 3b 20 69 2b 2b 29 20 70 43 73 72 2d 3e  ken; i++) pCsr->
3430: 61 42 75 66 66 65 72 5b 69 5d 20 3d 20 70 54 6f  aBuffer[i] = pTo
3440: 6b 65 6e 5b 69 5d 3b 0a 20 20 20 20 20 20 7d 65  ken[i];.      }e
3450: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 66 6f 72  lse{.        for
3460: 28 69 3d 30 3b 20 69 3c 6e 54 6f 6b 65 6e 3b 20  (i=0; i<nToken; 
3470: 69 2b 2b 29 20 70 43 73 72 2d 3e 61 42 75 66 66  i++) pCsr->aBuff
3480: 65 72 5b 69 5d 20 3d 20 74 65 73 74 54 6f 6c 6f  er[i] = testTolo
3490: 77 65 72 28 70 54 6f 6b 65 6e 5b 69 5d 29 3b 0a  wer(pToken[i]);.
34a0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70 43        }.      pC
34b0: 73 72 2d 3e 69 54 6f 6b 65 6e 2b 2b 3b 0a 20 20  sr->iToken++;.  
34c0: 20 20 20 20 70 43 73 72 2d 3e 69 49 6e 70 75 74      pCsr->iInput
34d0: 20 3d 20 28 69 6e 74 29 28 70 20 2d 20 70 43 73   = (int)(p - pCs
34e0: 72 2d 3e 61 49 6e 70 75 74 29 3b 0a 0a 20 20 20  r->aInput);..   
34f0: 20 20 20 2a 70 70 54 6f 6b 65 6e 20 3d 20 70 43     *ppToken = pC
3500: 73 72 2d 3e 61 42 75 66 66 65 72 3b 0a 20 20 20  sr->aBuffer;.   
3510: 20 20 20 2a 70 6e 42 79 74 65 73 20 3d 20 6e 54     *pnBytes = nT
3520: 6f 6b 65 6e 3b 0a 20 20 20 20 20 20 2a 70 69 53  oken;.      *piS
3530: 74 61 72 74 4f 66 66 73 65 74 20 3d 20 28 69 6e  tartOffset = (in
3540: 74 29 28 70 54 6f 6b 65 6e 20 2d 20 70 43 73 72  t)(pToken - pCsr
3550: 2d 3e 61 49 6e 70 75 74 29 3b 0a 20 20 20 20 20  ->aInput);.     
3560: 20 2a 70 69 45 6e 64 4f 66 66 73 65 74 20 3d 20   *piEndOffset = 
3570: 28 69 6e 74 29 28 70 20 2d 20 70 43 73 72 2d 3e  (int)(p - pCsr->
3580: 61 49 6e 70 75 74 29 3b 0a 20 20 20 20 20 20 2a  aInput);.      *
3590: 70 69 50 6f 73 69 74 69 6f 6e 20 3d 20 70 43 73  piPosition = pCs
35a0: 72 2d 3e 69 54 6f 6b 65 6e 3b 0a 20 20 20 20 7d  r->iToken;.    }
35b0: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
35c0: 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  c;.}..static int
35d0: 20 74 65 73 74 54 6f 6b 65 6e 69 7a 65 72 4c 61   testTokenizerLa
35e0: 6e 67 75 61 67 65 28 0a 20 20 73 71 6c 69 74 65  nguage(.  sqlite
35f0: 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75 72 73  3_tokenizer_curs
3600: 6f 72 20 2a 70 43 75 72 73 6f 72 2c 0a 20 20 69  or *pCursor,.  i
3610: 6e 74 20 69 4c 61 6e 67 69 64 0a 29 7b 0a 20 20  nt iLangid.){.  
3620: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
3630: 4f 4b 3b 0a 20 20 74 65 73 74 5f 74 6f 6b 65 6e  OK;.  test_token
3640: 69 7a 65 72 5f 63 75 72 73 6f 72 20 2a 70 43 73  izer_cursor *pCs
3650: 72 20 3d 20 28 74 65 73 74 5f 74 6f 6b 65 6e 69  r = (test_tokeni
3660: 7a 65 72 5f 63 75 72 73 6f 72 20 2a 29 70 43 75  zer_cursor *)pCu
3670: 72 73 6f 72 3b 0a 20 20 70 43 73 72 2d 3e 69 4c  rsor;.  pCsr->iL
3680: 61 6e 67 69 64 20 3d 20 69 4c 61 6e 67 69 64 3b  angid = iLangid;
3690: 0a 20 20 69 66 28 20 70 43 73 72 2d 3e 69 4c 61  .  if( pCsr->iLa
36a0: 6e 67 69 64 3e 3d 31 30 30 20 29 7b 0a 20 20 20  ngid>=100 ){.   
36b0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52   rc = SQLITE_ERR
36c0: 4f 52 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  OR;.  }.  return
36d0: 20 72 63 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 73   rc;.}.#endif..s
36e0: 74 61 74 69 63 20 69 6e 74 20 66 74 73 33 5f 74  tatic int fts3_t
36f0: 65 73 74 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 6d  est_tokenizer_cm
3700: 64 28 0a 20 20 43 6c 69 65 6e 74 44 61 74 61 20  d(.  ClientData 
3710: 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20 54 63  clientData,.  Tc
3720: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
3730: 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20  ,.  int objc,.  
3740: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f  Tcl_Obj *CONST o
3750: 62 6a 76 5b 5d 0a 29 7b 0a 23 69 66 64 65 66 20  bjv[].){.#ifdef 
3760: 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 46 54  SQLITE_ENABLE_FT
3770: 53 33 0a 20 20 73 74 61 74 69 63 20 63 6f 6e 73  S3.  static cons
3780: 74 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69  t sqlite3_tokeni
3790: 7a 65 72 5f 6d 6f 64 75 6c 65 20 74 65 73 74 54  zer_module testT
37a0: 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c 65 20 3d  okenizerModule =
37b0: 20 7b 0a 20 20 20 20 31 2c 0a 20 20 20 20 74 65   {.    1,.    te
37c0: 73 74 54 6f 6b 65 6e 69 7a 65 72 43 72 65 61 74  stTokenizerCreat
37d0: 65 2c 0a 20 20 20 20 74 65 73 74 54 6f 6b 65 6e  e,.    testToken
37e0: 69 7a 65 72 44 65 73 74 72 6f 79 2c 0a 20 20 20  izerDestroy,.   
37f0: 20 74 65 73 74 54 6f 6b 65 6e 69 7a 65 72 4f 70   testTokenizerOp
3800: 65 6e 2c 0a 20 20 20 20 74 65 73 74 54 6f 6b 65  en,.    testToke
3810: 6e 69 7a 65 72 43 6c 6f 73 65 2c 0a 20 20 20 20  nizerClose,.    
3820: 74 65 73 74 54 6f 6b 65 6e 69 7a 65 72 4e 65 78  testTokenizerNex
3830: 74 2c 0a 20 20 20 20 74 65 73 74 54 6f 6b 65 6e  t,.    testToken
3840: 69 7a 65 72 4c 61 6e 67 75 61 67 65 0a 20 20 7d  izerLanguage.  }
3850: 3b 0a 20 20 63 6f 6e 73 74 20 73 71 6c 69 74 65  ;.  const sqlite
3860: 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 6d 6f 64 75  3_tokenizer_modu
3870: 6c 65 20 2a 70 50 74 72 20 3d 20 26 74 65 73 74  le *pPtr = &test
3880: 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c 65 3b  TokenizerModule;
3890: 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d 31 20 29  .  if( objc!=1 )
38a0: 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e  {.    Tcl_WrongN
38b0: 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31  umArgs(interp, 1
38c0: 2c 20 6f 62 6a 76 2c 20 22 22 29 3b 0a 20 20 20  , objv, "");.   
38d0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
38e0: 52 3b 0a 20 20 7d 0a 20 20 54 63 6c 5f 53 65 74  R;.  }.  Tcl_Set
38f0: 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ObjResult(interp
3900: 2c 20 54 63 6c 5f 4e 65 77 42 79 74 65 41 72 72  , Tcl_NewByteArr
3910: 61 79 4f 62 6a 28 0a 20 20 20 20 28 63 6f 6e 73  ayObj(.    (cons
3920: 74 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20  t unsigned char 
3930: 2a 29 26 70 50 74 72 2c 20 73 69 7a 65 6f 66 28  *)&pPtr, sizeof(
3940: 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65  sqlite3_tokenize
3950: 72 5f 6d 6f 64 75 6c 65 20 2a 29 0a 20 20 29 29  r_module *).  ))
3960: 3b 0a 23 65 6e 64 69 66 0a 20 20 55 4e 55 53 45  ;.#endif.  UNUSE
3970: 44 5f 50 41 52 41 4d 45 54 45 52 28 63 6c 69 65  D_PARAMETER(clie
3980: 6e 74 44 61 74 61 29 3b 0a 20 20 72 65 74 75 72  ntData);.  retur
3990: 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61  n TCL_OK;.}..sta
39a0: 74 69 63 20 69 6e 74 20 66 74 73 33 5f 74 65 73  tic int fts3_tes
39b0: 74 5f 76 61 72 69 6e 74 5f 63 6d 64 28 0a 20 20  t_varint_cmd(.  
39c0: 43 6c 69 65 6e 74 44 61 74 61 20 63 6c 69 65 6e  ClientData clien
39d0: 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e 74  tData,.  Tcl_Int
39e0: 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69  erp *interp,.  i
39f0: 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f  nt objc,.  Tcl_O
3a00: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
3a10: 0a 29 7b 0a 23 69 66 64 65 66 20 53 51 4c 49 54  .){.#ifdef SQLIT
3a20: 45 5f 45 4e 41 42 4c 45 5f 46 54 53 33 0a 20 20  E_ENABLE_FTS3.  
3a30: 63 68 61 72 20 61 42 75 66 5b 32 34 5d 3b 0a 20  char aBuf[24];. 
3a40: 20 69 6e 74 20 72 63 3b 0a 20 20 54 63 6c 5f 57   int rc;.  Tcl_W
3a50: 69 64 65 49 6e 74 20 77 2c 20 77 32 3b 0a 20 20  ideInt w, w2;.  
3a60: 69 6e 74 20 6e 42 79 74 65 2c 20 6e 42 79 74 65  int nByte, nByte
3a70: 32 3b 0a 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d  2;..  if( objc!=
3a80: 32 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f  2 ){.    Tcl_Wro
3a90: 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70  ngNumArgs(interp
3aa0: 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 49 4e 54 45  , 1, objv, "INTE
3ab0: 47 45 52 22 29 3b 0a 20 20 20 20 72 65 74 75 72  GER");.    retur
3ac0: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d  n TCL_ERROR;.  }
3ad0: 0a 0a 20 20 72 63 20 3d 20 54 63 6c 5f 47 65 74  ..  rc = Tcl_Get
3ae0: 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28 69  WideIntFromObj(i
3af0: 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 31 5d 2c 20  nterp, objv[1], 
3b00: 26 77 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 54  &w);.  if( rc!=T
3b10: 43 4c 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  CL_OK ) return r
3b20: 63 3b 0a 0a 20 20 6e 42 79 74 65 20 3d 20 73 71  c;..  nByte = sq
3b30: 6c 69 74 65 33 46 74 73 33 50 75 74 56 61 72 69  lite3Fts3PutVari
3b40: 6e 74 28 61 42 75 66 2c 20 77 29 3b 0a 20 20 6e  nt(aBuf, w);.  n
3b50: 42 79 74 65 32 20 3d 20 73 71 6c 69 74 65 33 46  Byte2 = sqlite3F
3b60: 74 73 33 47 65 74 56 61 72 69 6e 74 28 61 42 75  ts3GetVarint(aBu
3b70: 66 2c 20 26 77 32 29 3b 0a 20 20 69 66 28 20 77  f, &w2);.  if( w
3b80: 21 3d 77 32 20 7c 7c 20 6e 42 79 74 65 21 3d 6e  !=w2 || nByte!=n
3b90: 42 79 74 65 32 20 29 7b 0a 20 20 20 20 63 68 61  Byte2 ){.    cha
3ba0: 72 20 2a 7a 45 72 72 20 3d 20 73 71 6c 69 74 65  r *zErr = sqlite
3bb0: 33 5f 6d 70 72 69 6e 74 66 28 22 65 72 72 6f 72  3_mprintf("error
3bc0: 20 74 65 73 74 69 6e 67 20 25 6c 6c 64 22 2c 20   testing %lld", 
3bd0: 77 29 3b 0a 20 20 20 20 54 63 6c 5f 52 65 73 65  w);.    Tcl_Rese
3be0: 74 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b  tResult(interp);
3bf0: 0a 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64 52  .    Tcl_AppendR
3c00: 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 7a 45  esult(interp, zE
3c10: 72 72 2c 20 30 29 3b 0a 20 20 20 20 72 65 74 75  rr, 0);.    retu
3c20: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
3c30: 7d 0a 0a 20 20 69 66 28 20 77 3c 3d 32 31 34 37  }..  if( w<=2147
3c40: 34 38 33 36 34 37 20 26 26 20 77 3e 3d 30 20 29  483647 && w>=0 )
3c50: 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20  {.    int i;.   
3c60: 20 6e 42 79 74 65 32 20 3d 20 66 74 73 33 47 65   nByte2 = fts3Ge
3c70: 74 56 61 72 69 6e 74 33 32 28 61 42 75 66 2c 20  tVarint32(aBuf, 
3c80: 26 69 29 3b 0a 20 20 20 20 69 66 28 20 28 69 6e  &i);.    if( (in
3c90: 74 29 77 21 3d 69 20 7c 7c 20 6e 42 79 74 65 21  t)w!=i || nByte!
3ca0: 3d 6e 42 79 74 65 32 20 29 7b 0a 20 20 20 20 20  =nByte2 ){.     
3cb0: 20 63 68 61 72 20 2a 7a 45 72 72 20 3d 20 73 71   char *zErr = sq
3cc0: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 65  lite3_mprintf("e
3cd0: 72 72 6f 72 20 74 65 73 74 69 6e 67 20 25 6c 6c  rror testing %ll
3ce0: 64 20 28 33 32 2d 62 69 74 29 22 2c 20 77 29 3b  d (32-bit)", w);
3cf0: 0a 20 20 20 20 20 20 54 63 6c 5f 52 65 73 65 74  .      Tcl_Reset
3d00: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a  Result(interp);.
3d10: 20 20 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64        Tcl_Append
3d20: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 7a  Result(interp, z
3d30: 45 72 72 2c 20 30 29 3b 0a 20 20 20 20 20 20 72  Err, 0);.      r
3d40: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
3d50: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 23 65 6e 64  .    }.  }..#end
3d60: 69 66 0a 20 20 55 4e 55 53 45 44 5f 50 41 52 41  if.  UNUSED_PARA
3d70: 4d 45 54 45 52 28 63 6c 69 65 6e 74 44 61 74 61  METER(clientData
3d80: 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  );.  return TCL_
3d90: 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 6e  OK;.}../* .** En
3da0: 64 20 6f 66 20 74 6f 6b 65 6e 69 7a 65 72 20 63  d of tokenizer c
3db0: 6f 64 65 2e 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ode..***********
3dc0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3dd0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3de0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3df0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f  ***************/
3e00: 20 0a 0a 69 6e 74 20 53 71 6c 69 74 65 74 65 73   ..int Sqlitetes
3e10: 74 66 74 73 33 5f 49 6e 69 74 28 54 63 6c 5f 49  tfts3_Init(Tcl_I
3e20: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 29 7b 0a  nterp *interp){.
3e30: 20 20 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43    Tcl_CreateObjC
3e40: 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22  ommand(interp, "
3e50: 66 74 73 33 5f 6e 65 61 72 5f 6d 61 74 63 68 22  fts3_near_match"
3e60: 2c 20 66 74 73 33 5f 6e 65 61 72 5f 6d 61 74 63  , fts3_near_matc
3e70: 68 5f 63 6d 64 2c 20 30 2c 20 30 29 3b 0a 20 20  h_cmd, 0, 0);.  
3e80: 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d  Tcl_CreateObjCom
3e90: 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 0a 20 20  mand(interp, .  
3ea0: 20 20 20 20 22 66 74 73 33 5f 63 6f 6e 66 69 67      "fts3_config
3eb0: 75 72 65 5f 69 6e 63 72 5f 6c 6f 61 64 22 2c 20  ure_incr_load", 
3ec0: 66 74 73 33 5f 63 6f 6e 66 69 67 75 72 65 5f 69  fts3_configure_i
3ed0: 6e 63 72 5f 6c 6f 61 64 5f 63 6d 64 2c 20 30 2c  ncr_load_cmd, 0,
3ee0: 20 30 0a 20 20 29 3b 0a 20 20 54 63 6c 5f 43 72   0.  );.  Tcl_Cr
3ef0: 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 0a  eateObjCommand(.
3f00: 20 20 20 20 20 20 69 6e 74 65 72 70 2c 20 22 66        interp, "f
3f10: 74 73 33 5f 74 65 73 74 5f 74 6f 6b 65 6e 69 7a  ts3_test_tokeniz
3f20: 65 72 22 2c 20 66 74 73 33 5f 74 65 73 74 5f 74  er", fts3_test_t
3f30: 6f 6b 65 6e 69 7a 65 72 5f 63 6d 64 2c 20 30 2c  okenizer_cmd, 0,
3f40: 20 30 0a 20 20 29 3b 0a 0a 20 20 54 63 6c 5f 43   0.  );..  Tcl_C
3f50: 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28  reateObjCommand(
3f60: 0a 20 20 20 20 20 20 69 6e 74 65 72 70 2c 20 22  .      interp, "
3f70: 66 74 73 33 5f 74 65 73 74 5f 76 61 72 69 6e 74  fts3_test_varint
3f80: 22 2c 20 66 74 73 33 5f 74 65 73 74 5f 76 61 72  ", fts3_test_var
3f90: 69 6e 74 5f 63 6d 64 2c 20 30 2c 20 30 0a 20 20  int_cmd, 0, 0.  
3fa0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  );.  return TCL_
3fb0: 4f 4b 3b 0a 7d 0a 23 65 6e 64 69 66 20 20 20 20  OK;.}.#endif    
3fc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3fd0: 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 46   SQLITE_ENABLE_F
3fe0: 54 53 33 20 7c 7c 20 53 51 4c 49 54 45 5f 45 4e  TS3 || SQLITE_EN
3ff0: 41 42 4c 45 5f 46 54 53 34 20 2a 2f 0a 23 65 6e  ABLE_FTS4 */.#en
4000: 64 69 66 20 20 20 20 20 20 20 20 20 20 20 20 20  dif             
4010: 20 20 20 20 20 2f 2a 20 69 66 64 65 66 20 53 51       /* ifdef SQ
4020: 4c 49 54 45 5f 54 45 53 54 20 2a 2f 0a           LITE_TEST */.