/ Hex Artifact Content
Login

Artifact 4c30cf32c63e59bec5b38533e0a65987df262851:


0000: 2f 2a 0a 2a 2a 20 32 30 31 34 20 4d 61 79 20 33  /*.** 2014 May 3
0010: 31 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68  1.**.** 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 2f 0a 0a 23 69 6e 63 6c 75  *****.*/..#inclu
0180: 64 65 20 22 66 74 73 35 2e 68 22 0a 23 69 6e 63  de "fts5.h".#inc
0190: 6c 75 64 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a  lude <string.h>.
01a0: 23 69 6e 63 6c 75 64 65 20 3c 61 73 73 65 72 74  #include <assert
01b0: 2e 68 3e 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .h>../**********
01c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
01d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
01e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
01f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0200: 0a 2a 2a 20 53 74 61 72 74 20 6f 66 20 73 69 6d  .** Start of sim
0210: 70 6c 65 20 74 6f 6b 65 6e 69 7a 65 72 20 69 6d  ple tokenizer im
0220: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2f  plementation..*/
0230: 0a 0a 2f 2a 0a 2a 2a 20 46 6f 72 20 74 6f 6b 65  ../*.** For toke
0240: 6e 69 7a 65 72 73 20 77 69 74 68 20 6e 6f 20 22  nizers with no "
0250: 75 6e 69 63 6f 64 65 22 20 6d 6f 64 69 66 69 65  unicode" modifie
0260: 72 2c 20 74 68 65 20 73 65 74 20 6f 66 20 74 6f  r, the set of to
0270: 6b 65 6e 20 63 68 61 72 61 63 74 65 72 73 0a 2a  ken characters.*
0280: 2a 20 69 73 20 74 68 65 20 73 61 6d 65 20 61 73  * is the same as
0290: 20 74 68 65 20 73 65 74 20 6f 66 20 41 53 43 49   the set of ASCI
02a0: 49 20 72 61 6e 67 65 20 61 6c 70 68 61 6e 75 6d  I range alphanum
02b0: 65 72 69 63 20 63 68 61 72 61 63 74 65 72 73 2e  eric characters.
02c0: 20 0a 2a 2f 0a 73 74 61 74 69 63 20 75 6e 73 69   .*/.static unsi
02d0: 67 6e 65 64 20 63 68 61 72 20 61 53 69 6d 70 6c  gned char aSimpl
02e0: 65 54 6f 6b 65 6e 43 68 61 72 5b 31 32 38 5d 20  eTokenChar[128] 
02f0: 3d 20 7b 0a 20 20 30 2c 20 30 2c 20 30 2c 20 30  = {.  0, 0, 0, 0
0300: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20 20  , 0, 0, 0, 0,   
0310: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30  0, 0, 0, 0, 0, 0
0320: 2c 20 30 2c 20 30 2c 20 20 20 2f 2a 20 30 78 30  , 0, 0,   /* 0x0
0330: 30 2e 2e 30 78 30 46 20 2a 2f 0a 20 20 30 2c 20  0..0x0F */.  0, 
0340: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30  0, 0, 0, 0, 0, 0
0350: 2c 20 30 2c 20 20 20 30 2c 20 30 2c 20 30 2c 20  , 0,   0, 0, 0, 
0360: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20  0, 0, 0, 0, 0,  
0370: 20 2f 2a 20 30 78 31 30 2e 2e 30 78 31 46 20 2a   /* 0x10..0x1F *
0380: 2f 0a 20 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20  /.  0, 0, 0, 0, 
0390: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20 20 30 2c  0, 0, 0, 0,   0,
03a0: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20   0, 0, 0, 0, 0, 
03b0: 30 2c 20 30 2c 20 20 20 2f 2a 20 30 78 32 30 2e  0, 0,   /* 0x20.
03c0: 2e 30 78 32 46 20 2a 2f 0a 20 20 31 2c 20 31 2c  .0x2F */.  1, 1,
03d0: 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20   1, 1, 1, 1, 1, 
03e0: 31 2c 20 20 20 31 2c 20 31 2c 20 30 2c 20 30 2c  1,   1, 1, 0, 0,
03f0: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20 20 2f   0, 0, 0, 0,   /
0400: 2a 20 30 78 33 30 2e 2e 30 78 33 46 20 2a 2f 0a  * 0x30..0x3F */.
0410: 20 20 30 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c    0, 1, 1, 1, 1,
0420: 20 31 2c 20 31 2c 20 31 2c 20 20 20 31 2c 20 31   1, 1, 1,   1, 1
0430: 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c  , 1, 1, 1, 1, 1,
0440: 20 31 2c 20 20 20 2f 2a 20 30 78 34 30 2e 2e 30   1,   /* 0x40..0
0450: 78 34 46 20 2a 2f 0a 20 20 31 2c 20 31 2c 20 31  x4F */.  1, 1, 1
0460: 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c  , 1, 1, 1, 1, 1,
0470: 20 20 20 31 2c 20 31 2c 20 31 2c 20 30 2c 20 30     1, 1, 1, 0, 0
0480: 2c 20 30 2c 20 30 2c 20 30 2c 20 20 20 2f 2a 20  , 0, 0, 0,   /* 
0490: 30 78 35 30 2e 2e 30 78 35 46 20 2a 2f 0a 20 20  0x50..0x5F */.  
04a0: 30 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  0, 1, 1, 1, 1, 1
04b0: 2c 20 31 2c 20 31 2c 20 20 20 31 2c 20 31 2c 20  , 1, 1,   1, 1, 
04c0: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
04d0: 2c 20 20 20 2f 2a 20 30 78 36 30 2e 2e 30 78 36  ,   /* 0x60..0x6
04e0: 46 20 2a 2f 0a 20 20 31 2c 20 31 2c 20 31 2c 20  F */.  1, 1, 1, 
04f0: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 20  1, 1, 1, 1, 1,  
0500: 20 31 2c 20 31 2c 20 31 2c 20 30 2c 20 30 2c 20   1, 1, 1, 0, 0, 
0510: 30 2c 20 30 2c 20 30 2c 20 20 20 2f 2a 20 30 78  0, 0, 0,   /* 0x
0520: 37 30 2e 2e 30 78 37 46 20 2a 2f 0a 7d 3b 0a 0a  70..0x7F */.};..
0530: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 53  typedef struct S
0540: 69 6d 70 6c 65 54 6f 6b 65 6e 69 7a 65 72 20 53  impleTokenizer S
0550: 69 6d 70 6c 65 54 6f 6b 65 6e 69 7a 65 72 3b 0a  impleTokenizer;.
0560: 73 74 72 75 63 74 20 53 69 6d 70 6c 65 54 6f 6b  struct SimpleTok
0570: 65 6e 69 7a 65 72 20 7b 0a 20 20 75 6e 73 69 67  enizer {.  unsig
0580: 6e 65 64 20 63 68 61 72 20 61 54 6f 6b 65 6e 43  ned char aTokenC
0590: 68 61 72 5b 31 32 38 5d 3b 0a 7d 3b 0a 0a 73 74  har[128];.};..st
05a0: 61 74 69 63 20 76 6f 69 64 20 66 74 73 35 53 69  atic void fts5Si
05b0: 6d 70 6c 65 41 64 64 45 78 63 65 70 74 69 6f 6e  mpleAddException
05c0: 73 28 0a 20 20 53 69 6d 70 6c 65 54 6f 6b 65 6e  s(.  SimpleToken
05d0: 69 7a 65 72 20 2a 70 2c 20 0a 20 20 63 6f 6e 73  izer *p, .  cons
05e0: 74 20 63 68 61 72 20 2a 7a 41 72 67 2c 20 0a 20  t char *zArg, . 
05f0: 20 69 6e 74 20 62 54 6f 6b 65 6e 43 68 61 72 73   int bTokenChars
0600: 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 66  .){.  int i;.  f
0610: 6f 72 28 69 3d 30 3b 20 7a 41 72 67 5b 69 5d 3b  or(i=0; zArg[i];
0620: 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 28   i++){.    if( (
0630: 7a 41 72 67 5b 69 5d 20 26 20 30 78 38 30 29 3d  zArg[i] & 0x80)=
0640: 3d 30 20 29 7b 0a 20 20 20 20 20 20 70 2d 3e 61  =0 ){.      p->a
0650: 54 6f 6b 65 6e 43 68 61 72 5b 28 69 6e 74 29 7a  TokenChar[(int)z
0660: 41 72 67 5b 69 5d 5d 20 3d 20 28 75 6e 73 69 67  Arg[i]] = (unsig
0670: 6e 65 64 20 63 68 61 72 29 62 54 6f 6b 65 6e 43  ned char)bTokenC
0680: 68 61 72 73 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  hars;.    }.  }.
0690: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 72 65 61 74 65 20  }../*.** Create 
06a0: 61 20 22 73 69 6d 70 6c 65 22 20 74 6f 6b 65 6e  a "simple" token
06b0: 69 7a 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  izer..*/.static 
06c0: 69 6e 74 20 66 74 73 35 53 69 6d 70 6c 65 43 72  int fts5SimpleCr
06d0: 65 61 74 65 28 0a 20 20 76 6f 69 64 20 2a 70 43  eate(.  void *pC
06e0: 74 78 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61  tx, .  const cha
06f0: 72 20 2a 2a 61 7a 41 72 67 2c 20 69 6e 74 20 6e  r **azArg, int n
0700: 41 72 67 2c 0a 20 20 46 74 73 35 54 6f 6b 65 6e  Arg,.  Fts5Token
0710: 69 7a 65 72 20 2a 2a 70 70 4f 75 74 0a 29 7b 0a  izer **ppOut.){.
0720: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
0730: 45 5f 4f 4b 3b 0a 20 20 53 69 6d 70 6c 65 54 6f  E_OK;.  SimpleTo
0740: 6b 65 6e 69 7a 65 72 20 2a 70 20 3d 20 30 3b 0a  kenizer *p = 0;.
0750: 20 20 69 66 28 20 6e 41 72 67 25 32 20 29 7b 0a    if( nArg%2 ){.
0760: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
0770: 45 52 52 4f 52 3b 0a 20 20 7d 65 6c 73 65 7b 0a  ERROR;.  }else{.
0780: 20 20 20 20 70 20 3d 20 73 71 6c 69 74 65 33 5f      p = sqlite3_
0790: 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 53 69  malloc(sizeof(Si
07a0: 6d 70 6c 65 54 6f 6b 65 6e 69 7a 65 72 29 29 3b  mpleTokenizer));
07b0: 0a 20 20 20 20 69 66 28 20 70 3d 3d 30 20 29 7b  .    if( p==0 ){
07c0: 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49  .      rc = SQLI
07d0: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 65  TE_NOMEM;.    }e
07e0: 6c 73 65 7b 0a 20 20 20 20 20 20 69 6e 74 20 69  lse{.      int i
07f0: 3b 0a 20 20 20 20 20 20 6d 65 6d 73 65 74 28 70  ;.      memset(p
0800: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 53 69 6d 70  , 0, sizeof(Simp
0810: 6c 65 54 6f 6b 65 6e 69 7a 65 72 29 29 3b 0a 20  leTokenizer));. 
0820: 20 20 20 20 20 6d 65 6d 63 70 79 28 70 2d 3e 61       memcpy(p->a
0830: 54 6f 6b 65 6e 43 68 61 72 2c 20 61 53 69 6d 70  TokenChar, aSimp
0840: 6c 65 54 6f 6b 65 6e 43 68 61 72 2c 20 73 69 7a  leTokenChar, siz
0850: 65 6f 66 28 61 53 69 6d 70 6c 65 54 6f 6b 65 6e  eof(aSimpleToken
0860: 43 68 61 72 29 29 3b 0a 20 20 20 20 20 20 66 6f  Char));.      fo
0870: 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54  r(i=0; rc==SQLIT
0880: 45 5f 4f 4b 20 26 26 20 69 3c 6e 41 72 67 3b 20  E_OK && i<nArg; 
0890: 69 2b 3d 32 29 7b 0a 20 20 20 20 20 20 20 20 63  i+=2){.        c
08a0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 41 72 67 20  onst char *zArg 
08b0: 3d 20 61 7a 41 72 67 5b 69 2b 31 5d 3b 0a 20 20  = azArg[i+1];.  
08c0: 20 20 20 20 20 20 69 66 28 20 30 3d 3d 73 71 6c        if( 0==sql
08d0: 69 74 65 33 5f 73 74 72 69 63 6d 70 28 61 7a 41  ite3_stricmp(azA
08e0: 72 67 5b 69 5d 2c 20 22 74 6f 6b 65 6e 63 68 61  rg[i], "tokencha
08f0: 72 73 22 29 20 29 7b 0a 20 20 20 20 20 20 20 20  rs") ){.        
0900: 20 20 66 74 73 35 53 69 6d 70 6c 65 41 64 64 45    fts5SimpleAddE
0910: 78 63 65 70 74 69 6f 6e 73 28 70 2c 20 7a 41 72  xceptions(p, zAr
0920: 67 2c 20 31 29 3b 0a 20 20 20 20 20 20 20 20 7d  g, 1);.        }
0930: 65 6c 73 65 0a 20 20 20 20 20 20 20 20 69 66 28  else.        if(
0940: 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74 72 69   0==sqlite3_stri
0950: 63 6d 70 28 61 7a 41 72 67 5b 69 5d 2c 20 22 73  cmp(azArg[i], "s
0960: 65 70 61 72 61 74 6f 72 73 22 29 20 29 7b 0a 20  eparators") ){. 
0970: 20 20 20 20 20 20 20 20 20 66 74 73 35 53 69 6d           fts5Sim
0980: 70 6c 65 41 64 64 45 78 63 65 70 74 69 6f 6e 73  pleAddExceptions
0990: 28 70 2c 20 7a 41 72 67 2c 20 30 29 3b 0a 20 20  (p, zArg, 0);.  
09a0: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
09b0: 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49         rc = SQLI
09c0: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  TE_ERROR;.      
09d0: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
09e0: 7d 0a 20 20 7d 0a 0a 20 20 2a 70 70 4f 75 74 20  }.  }..  *ppOut 
09f0: 3d 20 28 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72  = (Fts5Tokenizer
0a00: 2a 29 70 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  *)p;.  return rc
0a10: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 6c 65 74  ;.}../*.** Delet
0a20: 65 20 61 20 22 73 69 6d 70 6c 65 22 20 74 6f 6b  e a "simple" tok
0a30: 65 6e 69 7a 65 72 2e 0a 2a 2f 0a 73 74 61 74 69  enizer..*/.stati
0a40: 63 20 76 6f 69 64 20 66 74 73 35 53 69 6d 70 6c  c void fts5Simpl
0a50: 65 44 65 6c 65 74 65 28 46 74 73 35 54 6f 6b 65  eDelete(Fts5Toke
0a60: 6e 69 7a 65 72 20 2a 70 29 7b 0a 20 20 73 71 6c  nizer *p){.  sql
0a70: 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 7d 0a  ite3_free(p);.}.
0a80: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 69  ..static void si
0a90: 6d 70 6c 65 46 6f 6c 64 28 63 68 61 72 20 2a 61  mpleFold(char *a
0aa0: 4f 75 74 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  Out, const char 
0ab0: 2a 61 49 6e 2c 20 69 6e 74 20 6e 42 79 74 65 29  *aIn, int nByte)
0ac0: 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72  {.  int i;.  for
0ad0: 28 69 3d 30 3b 20 69 3c 6e 42 79 74 65 3b 20 69  (i=0; i<nByte; i
0ae0: 2b 2b 29 7b 0a 20 20 20 20 63 68 61 72 20 63 20  ++){.    char c 
0af0: 3d 20 61 49 6e 5b 69 5d 3b 0a 20 20 20 20 69 66  = aIn[i];.    if
0b00: 28 20 63 3e 3d 27 41 27 20 26 26 20 63 3c 3d 27  ( c>='A' && c<='
0b10: 5a 27 20 29 20 63 20 2b 3d 20 33 32 3b 0a 20 20  Z' ) c += 32;.  
0b20: 20 20 61 4f 75 74 5b 69 5d 20 3d 20 63 3b 0a 20    aOut[i] = c;. 
0b30: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 6f 6b 65   }.}../*.** Toke
0b40: 6e 69 7a 65 20 73 6f 6d 65 20 74 65 78 74 20 75  nize some text u
0b50: 73 69 6e 67 20 74 68 65 20 73 69 6d 70 6c 65 20  sing the simple 
0b60: 74 6f 6b 65 6e 69 7a 65 72 2e 0a 2a 2f 0a 73 74  tokenizer..*/.st
0b70: 61 74 69 63 20 69 6e 74 20 66 74 73 35 53 69 6d  atic int fts5Sim
0b80: 70 6c 65 54 6f 6b 65 6e 69 7a 65 28 0a 20 20 46  pleTokenize(.  F
0b90: 74 73 35 54 6f 6b 65 6e 69 7a 65 72 20 2a 70 54  ts5Tokenizer *pT
0ba0: 6f 6b 65 6e 69 7a 65 72 2c 0a 20 20 76 6f 69 64  okenizer,.  void
0bb0: 20 2a 70 43 74 78 2c 0a 20 20 63 6f 6e 73 74 20   *pCtx,.  const 
0bc0: 63 68 61 72 20 2a 70 54 65 78 74 2c 20 69 6e 74  char *pText, int
0bd0: 20 6e 54 65 78 74 2c 0a 20 20 69 6e 74 20 28 2a   nText,.  int (*
0be0: 78 54 6f 6b 65 6e 29 28 76 6f 69 64 2a 2c 20 63  xToken)(void*, c
0bf0: 6f 6e 73 74 20 63 68 61 72 2a 2c 20 69 6e 74 20  onst char*, int 
0c00: 6e 54 6f 6b 65 6e 2c 20 69 6e 74 20 69 53 74 61  nToken, int iSta
0c10: 72 74 2c 20 69 6e 74 20 69 45 6e 64 29 0a 29 7b  rt, int iEnd).){
0c20: 0a 20 20 53 69 6d 70 6c 65 54 6f 6b 65 6e 69 7a  .  SimpleTokeniz
0c30: 65 72 20 2a 70 20 3d 20 28 53 69 6d 70 6c 65 54  er *p = (SimpleT
0c40: 6f 6b 65 6e 69 7a 65 72 2a 29 70 54 6f 6b 65 6e  okenizer*)pToken
0c50: 69 7a 65 72 3b 0a 20 20 69 6e 74 20 72 63 20 3d  izer;.  int rc =
0c60: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e   SQLITE_OK;.  in
0c70: 74 20 69 65 3b 0a 20 20 69 6e 74 20 69 73 20 3d  t ie;.  int is =
0c80: 20 30 3b 0a 0a 20 20 63 68 61 72 20 61 46 6f 6c   0;..  char aFol
0c90: 64 5b 36 34 5d 3b 0a 20 20 69 6e 74 20 6e 46 6f  d[64];.  int nFo
0ca0: 6c 64 20 3d 20 73 69 7a 65 6f 66 28 61 46 6f 6c  ld = sizeof(aFol
0cb0: 64 29 3b 0a 20 20 63 68 61 72 20 2a 70 46 6f 6c  d);.  char *pFol
0cc0: 64 20 3d 20 61 46 6f 6c 64 3b 0a 20 20 75 6e 73  d = aFold;.  uns
0cd0: 69 67 6e 65 64 20 63 68 61 72 20 2a 61 20 3d 20  igned char *a = 
0ce0: 70 2d 3e 61 54 6f 6b 65 6e 43 68 61 72 3b 0a 0a  p->aTokenChar;..
0cf0: 20 20 77 68 69 6c 65 28 20 69 73 3c 6e 54 65 78    while( is<nTex
0d00: 74 20 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f  t && rc==SQLITE_
0d10: 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 42  OK ){.    int nB
0d20: 79 74 65 3b 0a 0a 20 20 20 20 2f 2a 20 53 6b 69  yte;..    /* Ski
0d30: 70 20 61 6e 79 20 6c 65 61 64 69 6e 67 20 64 69  p any leading di
0d40: 76 69 64 65 72 20 63 68 61 72 61 63 74 65 72 73  vider characters
0d50: 2e 20 2a 2f 0a 20 20 20 20 77 68 69 6c 65 28 20  . */.    while( 
0d60: 69 73 3c 6e 54 65 78 74 20 26 26 20 28 28 70 54  is<nText && ((pT
0d70: 65 78 74 5b 69 73 5d 26 30 78 38 30 29 20 7c 7c  ext[is]&0x80) ||
0d80: 20 61 5b 28 69 6e 74 29 70 54 65 78 74 5b 69 73   a[(int)pText[is
0d90: 5d 5d 3d 3d 30 29 20 29 7b 0a 20 20 20 20 20 20  ]]==0) ){.      
0da0: 69 73 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 20 20  is++;.    }.    
0db0: 69 66 28 20 69 73 3d 3d 6e 54 65 78 74 20 29 20  if( is==nText ) 
0dc0: 62 72 65 61 6b 3b 0a 0a 20 20 20 20 2f 2a 20 43  break;..    /* C
0dd0: 6f 75 6e 74 20 74 68 65 20 74 6f 6b 65 6e 20 63  ount the token c
0de0: 68 61 72 61 63 74 65 72 73 20 2a 2f 0a 20 20 20  haracters */.   
0df0: 20 69 65 20 3d 20 69 73 2b 31 3b 0a 20 20 20 20   ie = is+1;.    
0e00: 77 68 69 6c 65 28 20 69 65 3c 6e 54 65 78 74 20  while( ie<nText 
0e10: 26 26 20 28 28 70 54 65 78 74 5b 69 65 5d 26 30  && ((pText[ie]&0
0e20: 78 38 30 29 3d 3d 30 20 26 26 20 61 5b 28 69 6e  x80)==0 && a[(in
0e30: 74 29 70 54 65 78 74 5b 69 65 5d 5d 20 29 20 29  t)pText[ie]] ) )
0e40: 7b 0a 20 20 20 20 20 20 69 65 2b 2b 3b 0a 20 20  {.      ie++;.  
0e50: 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 46 6f 6c 64    }..    /* Fold
0e60: 20 74 6f 20 6c 6f 77 65 72 20 63 61 73 65 20 2a   to lower case *
0e70: 2f 0a 20 20 20 20 6e 42 79 74 65 20 3d 20 69 65  /.    nByte = ie
0e80: 2d 69 73 3b 0a 20 20 20 20 69 66 28 20 6e 42 79  -is;.    if( nBy
0e90: 74 65 3e 6e 46 6f 6c 64 20 29 7b 0a 20 20 20 20  te>nFold ){.    
0ea0: 20 20 69 66 28 20 70 46 6f 6c 64 21 3d 61 46 6f    if( pFold!=aFo
0eb0: 6c 64 20 29 20 73 71 6c 69 74 65 33 5f 66 72 65  ld ) sqlite3_fre
0ec0: 65 28 70 46 6f 6c 64 29 3b 0a 20 20 20 20 20 20  e(pFold);.      
0ed0: 70 46 6f 6c 64 20 3d 20 73 71 6c 69 74 65 33 5f  pFold = sqlite3_
0ee0: 6d 61 6c 6c 6f 63 28 6e 42 79 74 65 2a 32 29 3b  malloc(nByte*2);
0ef0: 0a 20 20 20 20 20 20 69 66 28 20 70 46 6f 6c 64  .      if( pFold
0f00: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 72  ==0 ){.        r
0f10: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
0f20: 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b  ;.        break;
0f30: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 6e  .      }.      n
0f40: 46 6f 6c 64 20 3d 20 6e 42 79 74 65 2a 32 3b 0a  Fold = nByte*2;.
0f50: 20 20 20 20 7d 0a 20 20 20 20 73 69 6d 70 6c 65      }.    simple
0f60: 46 6f 6c 64 28 70 46 6f 6c 64 2c 20 26 70 54 65  Fold(pFold, &pTe
0f70: 78 74 5b 69 73 5d 2c 20 6e 42 79 74 65 29 3b 0a  xt[is], nByte);.
0f80: 0a 20 20 20 20 2f 2a 20 49 6e 76 6f 6b 65 20 74  .    /* Invoke t
0f90: 68 65 20 74 6f 6b 65 6e 20 63 61 6c 6c 62 61 63  he token callbac
0fa0: 6b 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 78 54  k */.    rc = xT
0fb0: 6f 6b 65 6e 28 70 43 74 78 2c 20 70 46 6f 6c 64  oken(pCtx, pFold
0fc0: 2c 20 6e 42 79 74 65 2c 20 69 73 2c 20 69 65 29  , nByte, is, ie)
0fd0: 3b 0a 20 20 20 20 69 73 20 3d 20 69 65 2b 31 3b  ;.    is = ie+1;
0fe0: 0a 20 20 7d 0a 20 20 0a 20 20 69 66 28 20 70 46  .  }.  .  if( pF
0ff0: 6f 6c 64 21 3d 61 46 6f 6c 64 20 29 20 73 71 6c  old!=aFold ) sql
1000: 69 74 65 33 5f 66 72 65 65 28 70 46 6f 6c 64 29  ite3_free(pFold)
1010: 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ;.  if( rc==SQLI
1020: 54 45 5f 44 4f 4e 45 20 29 20 72 63 20 3d 20 53  TE_DONE ) rc = S
1030: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 72 65 74 75  QLITE_OK;.  retu
1040: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a  rn rc;.}../*****
1050: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1060: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1070: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1080: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1090: 2a 2a 2a 2a 2a 0a 2a 2a 20 53 74 61 72 74 20 6f  *****.** Start o
10a0: 66 20 75 6e 69 63 6f 64 65 36 31 20 74 6f 6b 65  f unicode61 toke
10b0: 6e 69 7a 65 72 20 69 6d 70 6c 65 6d 65 6e 74 61  nizer implementa
10c0: 74 69 6f 6e 2e 0a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20  tion..*/../*.** 
10d0: 46 75 6e 63 74 69 6f 6e 73 20 69 6e 20 66 74 73  Functions in fts
10e0: 35 5f 75 6e 69 63 6f 64 65 32 2e 63 2e 20 0a 2a  5_unicode2.c. .*
10f0: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 46 74 73  /.int sqlite3Fts
1100: 35 55 6e 69 63 6f 64 65 49 73 61 6c 6e 75 6d 28  5UnicodeIsalnum(
1110: 69 6e 74 20 63 29 3b 0a 69 6e 74 20 73 71 6c 69  int c);.int sqli
1120: 74 65 33 46 74 73 35 55 6e 69 63 6f 64 65 49 73  te3Fts5UnicodeIs
1130: 64 69 61 63 72 69 74 69 63 28 69 6e 74 20 63 29  diacritic(int c)
1140: 3b 0a 69 6e 74 20 73 71 6c 69 74 65 33 46 74 73  ;.int sqlite3Fts
1150: 35 55 6e 69 63 6f 64 65 46 6f 6c 64 28 69 6e 74  5UnicodeFold(int
1160: 20 63 2c 20 69 6e 74 20 62 52 65 6d 6f 76 65 44   c, int bRemoveD
1170: 69 61 63 72 69 74 69 63 29 3b 0a 0a 0a 2f 2a 0a  iacritic);.../*.
1180: 2a 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  ** The following
1190: 20 74 77 6f 20 6d 61 63 72 6f 73 20 2d 20 52 45   two macros - RE
11a0: 41 44 5f 55 54 46 38 20 61 6e 64 20 57 52 49 54  AD_UTF8 and WRIT
11b0: 45 5f 55 54 46 38 20 2d 20 68 61 76 65 20 62 65  E_UTF8 - have be
11c0: 65 6e 20 63 6f 70 69 65 64 0a 2a 2a 20 66 72 6f  en copied.** fro
11d0: 6d 20 74 68 65 20 73 71 6c 69 74 65 33 20 73 6f  m the sqlite3 so
11e0: 75 72 63 65 20 66 69 6c 65 20 75 74 66 2e 63 2e  urce file utf.c.
11f0: 20 49 66 20 74 68 69 73 20 66 69 6c 65 20 69 73   If this file is
1200: 20 63 6f 6d 70 69 6c 65 64 20 61 73 20 70 61 72   compiled as par
1210: 74 0a 2a 2a 20 6f 66 20 74 68 65 20 61 6d 61 6c  t.** of the amal
1220: 67 61 6d 61 74 69 6f 6e 2c 20 74 68 65 79 20 61  gamation, they a
1230: 72 65 20 6e 6f 74 20 72 65 71 75 69 72 65 64 2e  re not required.
1240: 0a 2a 2f 0a 23 69 66 6e 64 65 66 20 53 51 4c 49  .*/.#ifndef SQLI
1250: 54 45 5f 41 4d 41 4c 47 41 4d 41 54 49 4f 4e 0a  TE_AMALGAMATION.
1260: 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 20 75 6e  .static const un
1270: 73 69 67 6e 65 64 20 63 68 61 72 20 73 71 6c 69  signed char sqli
1280: 74 65 33 55 74 66 38 54 72 61 6e 73 31 5b 5d 20  te3Utf8Trans1[] 
1290: 3d 20 7b 0a 20 20 30 78 30 30 2c 20 30 78 30 31  = {.  0x00, 0x01
12a0: 2c 20 30 78 30 32 2c 20 30 78 30 33 2c 20 30 78  , 0x02, 0x03, 0x
12b0: 30 34 2c 20 30 78 30 35 2c 20 30 78 30 36 2c 20  04, 0x05, 0x06, 
12c0: 30 78 30 37 2c 0a 20 20 30 78 30 38 2c 20 30 78  0x07,.  0x08, 0x
12d0: 30 39 2c 20 30 78 30 61 2c 20 30 78 30 62 2c 20  09, 0x0a, 0x0b, 
12e0: 30 78 30 63 2c 20 30 78 30 64 2c 20 30 78 30 65  0x0c, 0x0d, 0x0e
12f0: 2c 20 30 78 30 66 2c 0a 20 20 30 78 31 30 2c 20  , 0x0f,.  0x10, 
1300: 30 78 31 31 2c 20 30 78 31 32 2c 20 30 78 31 33  0x11, 0x12, 0x13
1310: 2c 20 30 78 31 34 2c 20 30 78 31 35 2c 20 30 78  , 0x14, 0x15, 0x
1320: 31 36 2c 20 30 78 31 37 2c 0a 20 20 30 78 31 38  16, 0x17,.  0x18
1330: 2c 20 30 78 31 39 2c 20 30 78 31 61 2c 20 30 78  , 0x19, 0x1a, 0x
1340: 31 62 2c 20 30 78 31 63 2c 20 30 78 31 64 2c 20  1b, 0x1c, 0x1d, 
1350: 30 78 31 65 2c 20 30 78 31 66 2c 0a 20 20 30 78  0x1e, 0x1f,.  0x
1360: 30 30 2c 20 30 78 30 31 2c 20 30 78 30 32 2c 20  00, 0x01, 0x02, 
1370: 30 78 30 33 2c 20 30 78 30 34 2c 20 30 78 30 35  0x03, 0x04, 0x05
1380: 2c 20 30 78 30 36 2c 20 30 78 30 37 2c 0a 20 20  , 0x06, 0x07,.  
1390: 30 78 30 38 2c 20 30 78 30 39 2c 20 30 78 30 61  0x08, 0x09, 0x0a
13a0: 2c 20 30 78 30 62 2c 20 30 78 30 63 2c 20 30 78  , 0x0b, 0x0c, 0x
13b0: 30 64 2c 20 30 78 30 65 2c 20 30 78 30 66 2c 0a  0d, 0x0e, 0x0f,.
13c0: 20 20 30 78 30 30 2c 20 30 78 30 31 2c 20 30 78    0x00, 0x01, 0x
13d0: 30 32 2c 20 30 78 30 33 2c 20 30 78 30 34 2c 20  02, 0x03, 0x04, 
13e0: 30 78 30 35 2c 20 30 78 30 36 2c 20 30 78 30 37  0x05, 0x06, 0x07
13f0: 2c 0a 20 20 30 78 30 30 2c 20 30 78 30 31 2c 20  ,.  0x00, 0x01, 
1400: 30 78 30 32 2c 20 30 78 30 33 2c 20 30 78 30 30  0x02, 0x03, 0x00
1410: 2c 20 30 78 30 31 2c 20 30 78 30 30 2c 20 30 78  , 0x01, 0x00, 0x
1420: 30 30 2c 0a 7d 3b 0a 0a 23 64 65 66 69 6e 65 20  00,.};..#define 
1430: 52 45 41 44 5f 55 54 46 38 28 7a 49 6e 2c 20 7a  READ_UTF8(zIn, z
1440: 54 65 72 6d 2c 20 63 29 20 20 20 20 20 20 20 20  Term, c)        
1450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1460: 20 20 20 5c 0a 20 20 63 20 3d 20 2a 28 7a 49 6e     \.  c = *(zIn
1470: 2b 2b 29 3b 20 20 20 20 20 20 20 20 20 20 20 20  ++);            
1480: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14a0: 5c 0a 20 20 69 66 28 20 63 3e 3d 30 78 63 30 20  \.  if( c>=0xc0 
14b0: 29 7b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ){              
14c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20               \. 
14e0: 20 20 20 63 20 3d 20 73 71 6c 69 74 65 33 55 74     c = sqlite3Ut
14f0: 66 38 54 72 61 6e 73 31 5b 63 2d 30 78 63 30 5d  f8Trans1[c-0xc0]
1500: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1510: 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20 20            \.    
1520: 77 68 69 6c 65 28 20 7a 49 6e 21 3d 7a 54 65 72  while( zIn!=zTer
1530: 6d 20 26 26 20 28 2a 7a 49 6e 20 26 20 30 78 63  m && (*zIn & 0xc
1540: 30 29 3d 3d 30 78 38 30 20 29 7b 20 20 20 20 20  0)==0x80 ){     
1550: 20 20 20 20 20 20 20 5c 0a 20 20 20 20 20 20 63         \.      c
1560: 20 3d 20 28 63 3c 3c 36 29 20 2b 20 28 30 78 33   = (c<<6) + (0x3
1570: 66 20 26 20 2a 28 7a 49 6e 2b 2b 29 29 3b 20 20  f & *(zIn++));  
1580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1590: 20 20 20 20 5c 0a 20 20 20 20 7d 20 20 20 20 20      \.    }     
15a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15d0: 20 5c 0a 20 20 20 20 69 66 28 20 63 3c 30 78 38   \.    if( c<0x8
15e0: 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0               
15f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a                \.
1610: 20 20 20 20 20 20 20 20 7c 7c 20 28 63 26 30 78          || (c&0x
1620: 46 46 46 46 46 38 30 30 29 3d 3d 30 78 44 38 30  FFFFF800)==0xD80
1630: 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0               
1640: 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20             \.   
1650: 20 20 20 20 20 7c 7c 20 28 63 26 30 78 46 46 46       || (c&0xFFF
1660: 46 46 46 46 45 29 3d 3d 30 78 46 46 46 45 20 29  FFFFE)==0xFFFE )
1670: 7b 20 20 63 20 3d 20 30 78 46 46 46 44 3b 20 7d  {  c = 0xFFFD; }
1680: 20 20 20 20 20 20 20 20 5c 0a 20 20 7d 0a 0a 23          \.  }..#
1690: 64 65 66 69 6e 65 20 57 52 49 54 45 5f 55 54 46  define WRITE_UTF
16a0: 38 28 7a 4f 75 74 2c 20 63 29 20 7b 20 20 20 20  8(zOut, c) {    
16b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16c0: 20 20 20 20 20 20 5c 0a 20 20 69 66 28 20 63 3c        \.  if( c<
16d0: 30 78 30 30 30 38 30 20 29 7b 20 20 20 20 20 20  0x00080 ){      
16e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c                 \
1700: 0a 20 20 20 20 2a 7a 4f 75 74 2b 2b 20 3d 20 28  .    *zOut++ = (
1710: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 29 28 63  unsigned char)(c
1720: 26 30 78 46 46 29 3b 20 20 20 20 20 20 20 20 20  &0xFF);         
1730: 20 20 20 20 20 20 20 20 5c 0a 20 20 7d 20 20 20          \.  }   
1740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1770: 20 5c 0a 20 20 65 6c 73 65 20 69 66 28 20 63 3c   \.  else if( c<
1780: 30 78 30 30 38 30 30 20 29 7b 20 20 20 20 20 20  0x00800 ){      
1790: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17a0: 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20 20            \.    
17b0: 2a 7a 4f 75 74 2b 2b 20 3d 20 30 78 43 30 20 2b  *zOut++ = 0xC0 +
17c0: 20 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72 29   (unsigned char)
17d0: 28 28 63 3e 3e 36 29 26 30 78 31 46 29 3b 20 20  ((c>>6)&0x1F);  
17e0: 20 20 20 5c 0a 20 20 20 20 2a 7a 4f 75 74 2b 2b     \.    *zOut++
17f0: 20 3d 20 30 78 38 30 20 2b 20 28 75 6e 73 69 67   = 0x80 + (unsig
1800: 6e 65 64 20 63 68 61 72 29 28 63 20 26 20 30 78  ned char)(c & 0x
1810: 33 46 29 3b 20 20 20 20 20 20 20 20 5c 0a 20 20  3F);        \.  
1820: 7d 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  }               
1830: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1840: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1850: 20 20 20 20 20 5c 0a 20 20 65 6c 73 65 20 69 66       \.  else if
1860: 28 20 63 3c 30 78 31 30 30 30 30 20 29 7b 20 20  ( c<0x10000 ){  
1870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a                \.
1890: 20 20 20 20 2a 7a 4f 75 74 2b 2b 20 3d 20 30 78      *zOut++ = 0x
18a0: 45 30 20 2b 20 28 75 6e 73 69 67 6e 65 64 20 63  E0 + (unsigned c
18b0: 68 61 72 29 28 28 63 3e 3e 31 32 29 26 30 78 30  har)((c>>12)&0x0
18c0: 46 29 3b 20 20 20 20 5c 0a 20 20 20 20 2a 7a 4f  F);    \.    *zO
18d0: 75 74 2b 2b 20 3d 20 30 78 38 30 20 2b 20 28 75  ut++ = 0x80 + (u
18e0: 6e 73 69 67 6e 65 64 20 63 68 61 72 29 28 28 63  nsigned char)((c
18f0: 3e 3e 36 29 20 26 20 30 78 33 46 29 3b 20 20 20  >>6) & 0x3F);   
1900: 5c 0a 20 20 20 20 2a 7a 4f 75 74 2b 2b 20 3d 20  \.    *zOut++ = 
1910: 30 78 38 30 20 2b 20 28 75 6e 73 69 67 6e 65 64  0x80 + (unsigned
1920: 20 63 68 61 72 29 28 63 20 26 20 30 78 33 46 29   char)(c & 0x3F)
1930: 3b 20 20 20 20 20 20 20 20 5c 0a 20 20 7d 65 6c  ;        \.  }el
1940: 73 65 7b 20 20 20 20 20 20 20 20 20 20 20 20 20  se{             
1950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1960: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1970: 20 20 5c 0a 20 20 20 20 2a 7a 4f 75 74 2b 2b 20    \.    *zOut++ 
1980: 3d 20 30 78 46 30 20 2b 20 28 75 6e 73 69 67 6e  = 0xF0 + (unsign
1990: 65 64 20 63 68 61 72 29 28 28 63 3e 3e 31 38 29  ed char)((c>>18)
19a0: 20 26 20 30 78 30 37 29 3b 20 20 5c 0a 20 20 20   & 0x07);  \.   
19b0: 20 2a 7a 4f 75 74 2b 2b 20 3d 20 30 78 38 30 20   *zOut++ = 0x80 
19c0: 2b 20 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72  + (unsigned char
19d0: 29 28 28 63 3e 3e 31 32 29 20 26 20 30 78 33 46  )((c>>12) & 0x3F
19e0: 29 3b 20 20 5c 0a 20 20 20 20 2a 7a 4f 75 74 2b  );  \.    *zOut+
19f0: 2b 20 3d 20 30 78 38 30 20 2b 20 28 75 6e 73 69  + = 0x80 + (unsi
1a00: 67 6e 65 64 20 63 68 61 72 29 28 28 63 3e 3e 36  gned char)((c>>6
1a10: 29 20 26 20 30 78 33 46 29 3b 20 20 20 5c 0a 20  ) & 0x3F);   \. 
1a20: 20 20 20 2a 7a 4f 75 74 2b 2b 20 3d 20 30 78 38     *zOut++ = 0x8
1a30: 30 20 2b 20 28 75 6e 73 69 67 6e 65 64 20 63 68  0 + (unsigned ch
1a40: 61 72 29 28 63 20 26 20 30 78 33 46 29 3b 20 20  ar)(c & 0x3F);  
1a50: 20 20 20 20 20 20 5c 0a 20 20 7d 20 20 20 20 20        \.  }     
1a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c                 \
1a90: 0a 7d 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 69 66  .}..#endif /* if
1aa0: 6e 64 65 66 20 53 51 4c 49 54 45 5f 41 4d 41 4c  ndef SQLITE_AMAL
1ab0: 47 41 4d 41 54 49 4f 4e 20 2a 2f 0a 0a 74 79 70  GAMATION */..typ
1ac0: 65 64 65 66 20 73 74 72 75 63 74 20 55 6e 69 63  edef struct Unic
1ad0: 6f 64 65 36 31 54 6f 6b 65 6e 69 7a 65 72 20 55  ode61Tokenizer U
1ae0: 6e 69 63 6f 64 65 36 31 54 6f 6b 65 6e 69 7a 65  nicode61Tokenize
1af0: 72 3b 0a 73 74 72 75 63 74 20 55 6e 69 63 6f 64  r;.struct Unicod
1b00: 65 36 31 54 6f 6b 65 6e 69 7a 65 72 20 7b 0a 20  e61Tokenizer {. 
1b10: 20 69 6e 74 20 62 52 65 6d 6f 76 65 44 69 61 63   int bRemoveDiac
1b20: 72 69 74 69 63 3b 20 20 20 20 20 20 20 20 20 20  ritic;          
1b30: 20 2f 2a 20 54 72 75 65 20 69 66 20 72 65 6d 6f   /* True if remo
1b40: 76 65 5f 64 69 61 63 72 69 74 69 63 73 3d 31 20  ve_diacritics=1 
1b50: 69 73 20 73 65 74 20 2a 2f 0a 20 20 69 6e 74 20  is set */.  int 
1b60: 6e 45 78 63 65 70 74 69 6f 6e 3b 0a 20 20 69 6e  nException;.  in
1b70: 74 20 2a 61 69 45 78 63 65 70 74 69 6f 6e 3b 0a  t *aiException;.
1b80: 7d 3b 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66  };..static int f
1b90: 74 73 35 55 6e 69 63 6f 64 65 41 64 64 45 78 63  ts5UnicodeAddExc
1ba0: 65 70 74 69 6f 6e 73 28 0a 20 20 55 6e 69 63 6f  eptions(.  Unico
1bb0: 64 65 36 31 54 6f 6b 65 6e 69 7a 65 72 20 2a 70  de61Tokenizer *p
1bc0: 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 6f  ,          /* To
1bd0: 6b 65 6e 69 7a 65 72 20 6f 62 6a 65 63 74 20 2a  kenizer object *
1be0: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
1bf0: 7a 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  z,              
1c00: 20 20 20 20 2f 2a 20 43 68 61 72 61 63 74 65 72      /* Character
1c10: 73 20 74 6f 20 74 72 65 61 74 20 61 73 20 65 78  s to treat as ex
1c20: 63 65 70 74 69 6f 6e 73 20 2a 2f 0a 20 20 69 6e  ceptions */.  in
1c30: 74 20 62 54 6f 6b 65 6e 43 68 61 72 73 20 20 20  t bTokenChars   
1c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1c50: 20 31 20 66 6f 72 20 27 74 6f 6b 65 6e 63 68 61   1 for 'tokencha
1c60: 72 73 27 2c 20 30 20 66 6f 72 20 27 73 65 70 61  rs', 0 for 'sepa
1c70: 72 61 74 6f 72 73 27 20 2a 2f 0a 29 7b 0a 20 20  rators' */.){.  
1c80: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
1c90: 4f 4b 3b 0a 20 20 69 6e 74 20 6e 20 3d 20 73 74  OK;.  int n = st
1ca0: 72 6c 65 6e 28 7a 29 3b 0a 20 20 69 6e 74 20 2a  rlen(z);.  int *
1cb0: 61 4e 65 77 3b 0a 0a 20 20 69 66 28 20 6e 3e 30  aNew;..  if( n>0
1cc0: 20 29 7b 0a 20 20 20 20 61 4e 65 77 20 3d 20 28   ){.    aNew = (
1cd0: 69 6e 74 2a 29 73 71 6c 69 74 65 33 5f 72 65 61  int*)sqlite3_rea
1ce0: 6c 6c 6f 63 28 70 2d 3e 61 69 45 78 63 65 70 74  lloc(p->aiExcept
1cf0: 69 6f 6e 2c 20 28 6e 2b 70 2d 3e 6e 45 78 63 65  ion, (n+p->nExce
1d00: 70 74 69 6f 6e 29 2a 73 69 7a 65 6f 66 28 69 6e  ption)*sizeof(in
1d10: 74 29 29 3b 0a 20 20 20 20 69 66 28 20 61 4e 65  t));.    if( aNe
1d20: 77 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e  w ){.      int n
1d30: 4e 65 77 20 3d 20 70 2d 3e 6e 45 78 63 65 70 74  New = p->nExcept
1d40: 69 6f 6e 3b 0a 20 20 20 20 20 20 63 6f 6e 73 74  ion;.      const
1d50: 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a   unsigned char *
1d60: 7a 43 73 72 20 3d 20 28 63 6f 6e 73 74 20 75 6e  zCsr = (const un
1d70: 73 69 67 6e 65 64 20 63 68 61 72 2a 29 7a 3b 0a  signed char*)z;.
1d80: 20 20 20 20 20 20 63 6f 6e 73 74 20 75 6e 73 69        const unsi
1d90: 67 6e 65 64 20 63 68 61 72 20 2a 7a 54 65 72 6d  gned char *zTerm
1da0: 20 3d 20 28 63 6f 6e 73 74 20 75 6e 73 69 67 6e   = (const unsign
1db0: 65 64 20 63 68 61 72 2a 29 26 7a 5b 6e 5d 3b 0a  ed char*)&z[n];.
1dc0: 20 20 20 20 20 20 77 68 69 6c 65 28 20 7a 43 73        while( zCs
1dd0: 72 3c 7a 54 65 72 6d 20 29 7b 0a 20 20 20 20 20  r<zTerm ){.     
1de0: 20 20 20 69 6e 74 20 69 43 6f 64 65 3b 0a 20 20     int iCode;.  
1df0: 20 20 20 20 20 20 69 6e 74 20 62 54 6f 6b 65 6e        int bToken
1e00: 3b 0a 20 20 20 20 20 20 20 20 52 45 41 44 5f 55  ;.        READ_U
1e10: 54 46 38 28 7a 43 73 72 2c 20 7a 54 65 72 6d 2c  TF8(zCsr, zTerm,
1e20: 20 69 43 6f 64 65 29 3b 0a 20 20 20 20 20 20 20   iCode);.       
1e30: 20 62 54 6f 6b 65 6e 20 3d 20 73 71 6c 69 74 65   bToken = sqlite
1e40: 33 46 74 73 35 55 6e 69 63 6f 64 65 49 73 61 6c  3Fts5UnicodeIsal
1e50: 6e 75 6d 28 69 43 6f 64 65 29 3b 0a 20 20 20 20  num(iCode);.    
1e60: 20 20 20 20 61 73 73 65 72 74 28 20 28 62 54 6f      assert( (bTo
1e70: 6b 65 6e 3d 3d 30 20 7c 7c 20 62 54 6f 6b 65 6e  ken==0 || bToken
1e80: 3d 3d 31 29 20 29 3b 20 0a 20 20 20 20 20 20 20  ==1) ); .       
1e90: 20 61 73 73 65 72 74 28 20 28 62 54 6f 6b 65 6e   assert( (bToken
1ea0: 43 68 61 72 73 3d 3d 30 20 7c 7c 20 62 54 6f 6b  Chars==0 || bTok
1eb0: 65 6e 43 68 61 72 73 3d 3d 31 29 20 29 3b 0a 20  enChars==1) );. 
1ec0: 20 20 20 20 20 20 20 69 66 28 20 62 54 6f 6b 65         if( bToke
1ed0: 6e 21 3d 62 54 6f 6b 65 6e 43 68 61 72 73 20 26  n!=bTokenChars &
1ee0: 26 20 73 71 6c 69 74 65 33 46 74 73 35 55 6e 69  & sqlite3Fts5Uni
1ef0: 63 6f 64 65 49 73 64 69 61 63 72 69 74 69 63 28  codeIsdiacritic(
1f00: 69 43 6f 64 65 29 3d 3d 30 20 29 7b 0a 20 20 20  iCode)==0 ){.   
1f10: 20 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 20 20         int i;.  
1f20: 20 20 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b          for(i=0;
1f30: 20 69 3c 6e 4e 65 77 3b 20 69 2b 2b 29 7b 0a 20   i<nNew; i++){. 
1f40: 20 20 20 20 20 20 20 20 20 20 20 69 66 28 20 61             if( a
1f50: 4e 65 77 5b 69 5d 3e 69 43 6f 64 65 20 29 20 62  New[i]>iCode ) b
1f60: 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 20 20  reak;.          
1f70: 7d 0a 20 20 20 20 20 20 20 20 20 20 6d 65 6d 6d  }.          memm
1f80: 6f 76 65 28 26 61 4e 65 77 5b 69 2b 31 5d 2c 20  ove(&aNew[i+1], 
1f90: 26 61 4e 65 77 5b 69 5d 2c 20 28 6e 4e 65 77 2d  &aNew[i], (nNew-
1fa0: 69 29 2a 73 69 7a 65 6f 66 28 69 6e 74 29 29 3b  i)*sizeof(int));
1fb0: 0a 20 20 20 20 20 20 20 20 20 20 61 4e 65 77 5b  .          aNew[
1fc0: 69 5d 20 3d 20 69 43 6f 64 65 3b 0a 20 20 20 20  i] = iCode;.    
1fd0: 20 20 20 20 20 20 6e 4e 65 77 2b 2b 3b 0a 20 20        nNew++;.  
1fe0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a        }.      }.
1ff0: 20 20 20 20 20 20 70 2d 3e 61 69 45 78 63 65 70        p->aiExcep
2000: 74 69 6f 6e 20 3d 20 61 4e 65 77 3b 0a 20 20 20  tion = aNew;.   
2010: 20 20 20 70 2d 3e 6e 45 78 63 65 70 74 69 6f 6e     p->nException
2020: 20 3d 20 6e 4e 65 77 3b 0a 20 20 20 20 7d 65 6c   = nNew;.    }el
2030: 73 65 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53  se{.      rc = S
2040: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
2050: 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e   }.  }..  return
2060: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65   rc;.}../*.** Re
2070: 74 75 72 6e 20 74 72 75 65 20 69 66 20 74 68 65  turn true if the
2080: 20 70 2d 3e 61 69 45 78 63 65 70 74 69 6f 6e 5b   p->aiException[
2090: 5d 20 61 72 72 61 79 20 63 6f 6e 74 61 69 6e 73  ] array contains
20a0: 20 74 68 65 20 76 61 6c 75 65 20 69 43 6f 64 65   the value iCode
20b0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
20c0: 66 74 73 35 55 6e 69 63 6f 64 65 49 73 45 78 63  fts5UnicodeIsExc
20d0: 65 70 74 69 6f 6e 28 55 6e 69 63 6f 64 65 36 31  eption(Unicode61
20e0: 54 6f 6b 65 6e 69 7a 65 72 20 2a 70 2c 20 69 6e  Tokenizer *p, in
20f0: 74 20 69 43 6f 64 65 29 7b 0a 20 20 69 66 28 20  t iCode){.  if( 
2100: 70 2d 3e 6e 45 78 63 65 70 74 69 6f 6e 3e 30 20  p->nException>0 
2110: 29 7b 0a 20 20 20 20 69 6e 74 20 2a 61 20 3d 20  ){.    int *a = 
2120: 70 2d 3e 61 69 45 78 63 65 70 74 69 6f 6e 3b 0a  p->aiException;.
2130: 20 20 20 20 69 6e 74 20 69 4c 6f 20 3d 20 30 3b      int iLo = 0;
2140: 0a 20 20 20 20 69 6e 74 20 69 48 69 20 3d 20 70  .    int iHi = p
2150: 2d 3e 6e 45 78 63 65 70 74 69 6f 6e 2d 31 3b 0a  ->nException-1;.
2160: 0a 20 20 20 20 77 68 69 6c 65 28 20 69 48 69 3e  .    while( iHi>
2170: 3d 69 4c 6f 20 29 7b 0a 20 20 20 20 20 20 69 6e  =iLo ){.      in
2180: 74 20 69 54 65 73 74 20 3d 20 28 69 48 69 20 2b  t iTest = (iHi +
2190: 20 69 4c 6f 29 20 2f 20 32 3b 0a 20 20 20 20 20   iLo) / 2;.     
21a0: 20 69 66 28 20 69 43 6f 64 65 3d 3d 61 5b 69 54   if( iCode==a[iT
21b0: 65 73 74 5d 20 29 7b 0a 20 20 20 20 20 20 20 20  est] ){.        
21c0: 72 65 74 75 72 6e 20 31 3b 0a 20 20 20 20 20 20  return 1;.      
21d0: 7d 65 6c 73 65 20 69 66 28 20 69 43 6f 64 65 3e  }else if( iCode>
21e0: 61 5b 69 54 65 73 74 5d 20 29 7b 0a 20 20 20 20  a[iTest] ){.    
21f0: 20 20 20 20 69 4c 6f 20 3d 20 69 54 65 73 74 2b      iLo = iTest+
2200: 31 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  1;.      }else{.
2210: 20 20 20 20 20 20 20 20 69 48 69 20 3d 20 69 54          iHi = iT
2220: 65 73 74 2d 31 3b 0a 20 20 20 20 20 20 7d 0a 20  est-1;.      }. 
2230: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
2240: 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  rn 0;.}../*.** C
2250: 72 65 61 74 65 20 61 20 22 75 6e 69 63 6f 64 65  reate a "unicode
2260: 36 31 22 20 74 6f 6b 65 6e 69 7a 65 72 2e 0a 2a  61" tokenizer..*
2270: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  /.static int fts
2280: 35 55 6e 69 63 6f 64 65 43 72 65 61 74 65 28 0a  5UnicodeCreate(.
2290: 20 20 76 6f 69 64 20 2a 70 43 74 78 2c 20 0a 20    void *pCtx, . 
22a0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61 7a   const char **az
22b0: 41 72 67 2c 20 69 6e 74 20 6e 41 72 67 2c 0a 20  Arg, int nArg,. 
22c0: 20 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72 20 2a   Fts5Tokenizer *
22d0: 2a 70 70 4f 75 74 0a 29 7b 0a 20 20 69 6e 74 20  *ppOut.){.  int 
22e0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20  rc = SQLITE_OK; 
22f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
2300: 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20  eturn code */.  
2310: 55 6e 69 63 6f 64 65 36 31 54 6f 6b 65 6e 69 7a  Unicode61Tokeniz
2320: 65 72 20 2a 70 20 3d 20 30 3b 20 20 20 20 20 20  er *p = 0;      
2330: 2f 2a 20 4e 65 77 20 74 6f 6b 65 6e 69 7a 65 72  /* New tokenizer
2340: 20 6f 62 6a 65 63 74 20 2a 2f 20 0a 0a 20 20 69   object */ ..  i
2350: 66 28 20 6e 41 72 67 25 32 20 29 7b 0a 20 20 20  f( nArg%2 ){.   
2360: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52   rc = SQLITE_ERR
2370: 4f 52 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  OR;.  }else{.   
2380: 20 70 20 3d 20 28 55 6e 69 63 6f 64 65 36 31 54   p = (Unicode61T
2390: 6f 6b 65 6e 69 7a 65 72 2a 29 73 71 6c 69 74 65  okenizer*)sqlite
23a0: 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28  3_malloc(sizeof(
23b0: 55 6e 69 63 6f 64 65 36 31 54 6f 6b 65 6e 69 7a  Unicode61Tokeniz
23c0: 65 72 29 29 3b 0a 20 20 20 20 69 66 28 20 70 20  er));.    if( p 
23d0: 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 0a  ){.      int i;.
23e0: 20 20 20 20 20 20 6d 65 6d 73 65 74 28 70 2c 20        memset(p, 
23f0: 30 2c 20 73 69 7a 65 6f 66 28 55 6e 69 63 6f 64  0, sizeof(Unicod
2400: 65 36 31 54 6f 6b 65 6e 69 7a 65 72 29 29 3b 0a  e61Tokenizer));.
2410: 20 20 20 20 20 20 70 2d 3e 62 52 65 6d 6f 76 65        p->bRemove
2420: 44 69 61 63 72 69 74 69 63 20 3d 20 31 3b 0a 20  Diacritic = 1;. 
2430: 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 72 63       for(i=0; rc
2440: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69  ==SQLITE_OK && i
2450: 3c 6e 41 72 67 3b 20 69 2b 3d 32 29 7b 0a 20 20  <nArg; i+=2){.  
2460: 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72        const char
2470: 20 2a 7a 41 72 67 20 3d 20 61 7a 41 72 67 5b 69   *zArg = azArg[i
2480: 2b 31 5d 3b 0a 20 20 20 20 20 20 20 20 69 66 28  +1];.        if(
2490: 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74 72 69   0==sqlite3_stri
24a0: 63 6d 70 28 61 7a 41 72 67 5b 69 5d 2c 20 22 72  cmp(azArg[i], "r
24b0: 65 6d 6f 76 65 5f 64 69 61 63 72 69 74 69 63 73  emove_diacritics
24c0: 22 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  ") ){.          
24d0: 69 66 28 20 28 7a 41 72 67 5b 30 5d 21 3d 27 30  if( (zArg[0]!='0
24e0: 27 20 26 26 20 7a 41 72 67 5b 30 5d 21 3d 27 31  ' && zArg[0]!='1
24f0: 27 29 20 7c 7c 20 7a 41 72 67 5b 31 5d 20 29 7b  ') || zArg[1] ){
2500: 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 63 20  .            rc 
2510: 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  = SQLITE_ERROR;.
2520: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
2530: 20 20 20 20 20 20 70 2d 3e 62 52 65 6d 6f 76 65        p->bRemove
2540: 44 69 61 63 72 69 74 69 63 20 3d 20 28 7a 41 72  Diacritic = (zAr
2550: 67 5b 30 5d 3d 3d 27 31 27 29 3b 0a 20 20 20 20  g[0]=='1');.    
2560: 20 20 20 20 7d 65 6c 73 65 0a 20 20 20 20 20 20      }else.      
2570: 20 20 69 66 28 20 30 3d 3d 73 71 6c 69 74 65 33    if( 0==sqlite3
2580: 5f 73 74 72 69 63 6d 70 28 61 7a 41 72 67 5b 69  _stricmp(azArg[i
2590: 5d 2c 20 22 74 6f 6b 65 6e 63 68 61 72 73 22 29  ], "tokenchars")
25a0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63   ){.          rc
25b0: 20 3d 20 66 74 73 35 55 6e 69 63 6f 64 65 41 64   = fts5UnicodeAd
25c0: 64 45 78 63 65 70 74 69 6f 6e 73 28 70 2c 20 7a  dExceptions(p, z
25d0: 41 72 67 2c 20 31 29 3b 0a 20 20 20 20 20 20 20  Arg, 1);.       
25e0: 20 7d 65 6c 73 65 0a 20 20 20 20 20 20 20 20 69   }else.        i
25f0: 66 28 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74  f( 0==sqlite3_st
2600: 72 69 63 6d 70 28 61 7a 41 72 67 5b 69 5d 2c 20  ricmp(azArg[i], 
2610: 22 73 65 70 61 72 61 74 6f 72 73 22 29 20 29 7b  "separators") ){
2620: 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20  .          rc = 
2630: 66 74 73 35 55 6e 69 63 6f 64 65 41 64 64 45 78  fts5UnicodeAddEx
2640: 63 65 70 74 69 6f 6e 73 28 70 2c 20 7a 41 72 67  ceptions(p, zArg
2650: 2c 20 30 29 3b 0a 20 20 20 20 20 20 20 20 7d 65  , 0);.        }e
2660: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 72  lse{.          r
2670: 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  c = SQLITE_ERROR
2680: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
2690: 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20    }.    }else{. 
26a0: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
26b0: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20  _NOMEM;.    }.  
26c0: 20 20 2a 70 70 4f 75 74 20 3d 20 28 46 74 73 35    *ppOut = (Fts5
26d0: 54 6f 6b 65 6e 69 7a 65 72 2a 29 70 3b 0a 20 20  Tokenizer*)p;.  
26e0: 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
26f0: 0a 0a 2f 2a 0a 2a 2a 20 44 65 6c 65 74 65 20 61  ../*.** Delete a
2700: 20 22 75 6e 69 63 6f 64 65 36 31 22 20 74 6f 6b   "unicode61" tok
2710: 65 6e 69 7a 65 72 2e 0a 2a 2f 0a 73 74 61 74 69  enizer..*/.stati
2720: 63 20 76 6f 69 64 20 66 74 73 35 55 6e 69 63 6f  c void fts5Unico
2730: 64 65 44 65 6c 65 74 65 28 46 74 73 35 54 6f 6b  deDelete(Fts5Tok
2740: 65 6e 69 7a 65 72 20 2a 70 54 6f 6b 29 7b 0a 20  enizer *pTok){. 
2750: 20 55 6e 69 63 6f 64 65 36 31 54 6f 6b 65 6e 69   Unicode61Tokeni
2760: 7a 65 72 20 2a 70 20 3d 20 28 55 6e 69 63 6f 64  zer *p = (Unicod
2770: 65 36 31 54 6f 6b 65 6e 69 7a 65 72 2a 29 70 54  e61Tokenizer*)pT
2780: 6f 6b 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  ok;.  sqlite3_fr
2790: 65 65 28 70 2d 3e 61 69 45 78 63 65 70 74 69 6f  ee(p->aiExceptio
27a0: 6e 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  n);.  sqlite3_fr
27b0: 65 65 28 70 29 3b 0a 20 20 72 65 74 75 72 6e 3b  ee(p);.  return;
27c0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  .}../*.** Return
27d0: 20 74 72 75 65 20 69 66 2c 20 66 6f 72 20 74 68   true if, for th
27e0: 65 20 70 75 72 70 6f 73 65 73 20 6f 66 20 74 6f  e purposes of to
27f0: 6b 65 6e 69 7a 69 6e 67 20 77 69 74 68 20 74 68  kenizing with th
2800: 65 20 74 6f 6b 65 6e 69 7a 65 72 0a 2a 2a 20 70  e tokenizer.** p
2810: 61 73 73 65 64 20 61 73 20 74 68 65 20 66 69 72  assed as the fir
2820: 73 74 20 61 72 67 75 6d 65 6e 74 2c 20 63 6f 64  st argument, cod
2830: 65 70 6f 69 6e 74 20 69 43 6f 64 65 20 69 73 20  epoint iCode is 
2840: 63 6f 6e 73 69 64 65 72 65 64 20 61 20 74 6f 6b  considered a tok
2850: 65 6e 20 0a 2a 2a 20 63 68 61 72 61 63 74 65 72  en .** character
2860: 20 28 6e 6f 74 20 61 20 73 65 70 61 72 61 74 6f   (not a separato
2870: 72 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  r)..*/.static in
2880: 74 20 66 74 73 35 55 6e 69 63 6f 64 65 49 73 41  t fts5UnicodeIsA
2890: 6c 6e 75 6d 28 55 6e 69 63 6f 64 65 36 31 54 6f  lnum(Unicode61To
28a0: 6b 65 6e 69 7a 65 72 20 2a 70 2c 20 69 6e 74 20  kenizer *p, int 
28b0: 69 43 6f 64 65 29 7b 0a 20 20 61 73 73 65 72 74  iCode){.  assert
28c0: 28 20 28 73 71 6c 69 74 65 33 46 74 73 35 55 6e  ( (sqlite3Fts5Un
28d0: 69 63 6f 64 65 49 73 61 6c 6e 75 6d 28 69 43 6f  icodeIsalnum(iCo
28e0: 64 65 29 20 26 20 30 78 46 46 46 46 46 46 46 45  de) & 0xFFFFFFFE
28f0: 29 3d 3d 30 20 29 3b 0a 20 20 72 65 74 75 72 6e  )==0 );.  return
2900: 20 73 71 6c 69 74 65 33 46 74 73 35 55 6e 69 63   sqlite3Fts5Unic
2910: 6f 64 65 49 73 61 6c 6e 75 6d 28 69 43 6f 64 65  odeIsalnum(iCode
2920: 29 20 5e 20 66 74 73 35 55 6e 69 63 6f 64 65 49  ) ^ fts5UnicodeI
2930: 73 45 78 63 65 70 74 69 6f 6e 28 70 2c 20 69 43  sException(p, iC
2940: 6f 64 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  ode);.}../*.** T
2950: 6f 6b 65 6e 69 7a 65 20 73 6f 6d 65 20 74 65 78  okenize some tex
2960: 74 20 75 73 69 6e 67 20 61 20 75 6e 69 63 6f 64  t using a unicod
2970: 65 36 31 20 74 6f 6b 65 6e 69 7a 65 72 2e 0a 2a  e61 tokenizer..*
2980: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  /.static int fts
2990: 35 55 6e 69 63 6f 64 65 54 6f 6b 65 6e 69 7a 65  5UnicodeTokenize
29a0: 28 0a 20 20 46 74 73 35 54 6f 6b 65 6e 69 7a 65  (.  Fts5Tokenize
29b0: 72 20 2a 70 54 6f 6b 65 6e 69 7a 65 72 2c 0a 20  r *pTokenizer,. 
29c0: 20 76 6f 69 64 20 2a 70 43 74 78 2c 0a 20 20 63   void *pCtx,.  c
29d0: 6f 6e 73 74 20 63 68 61 72 20 2a 70 54 65 78 74  onst char *pText
29e0: 2c 20 69 6e 74 20 6e 54 65 78 74 2c 0a 20 20 69  , int nText,.  i
29f0: 6e 74 20 28 2a 78 54 6f 6b 65 6e 29 28 76 6f 69  nt (*xToken)(voi
2a00: 64 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 2a 2c  d*, const char*,
2a10: 20 69 6e 74 20 6e 54 6f 6b 65 6e 2c 20 69 6e 74   int nToken, int
2a20: 20 69 53 74 61 72 74 2c 20 69 6e 74 20 69 45 6e   iStart, int iEn
2a30: 64 29 0a 29 7b 0a 20 20 55 6e 69 63 6f 64 65 36  d).){.  Unicode6
2a40: 31 54 6f 6b 65 6e 69 7a 65 72 20 2a 70 20 3d 20  1Tokenizer *p = 
2a50: 28 55 6e 69 63 6f 64 65 36 31 54 6f 6b 65 6e 69  (Unicode61Tokeni
2a60: 7a 65 72 2a 29 70 54 6f 6b 65 6e 69 7a 65 72 3b  zer*)pTokenizer;
2a70: 0a 20 20 63 6f 6e 73 74 20 75 6e 73 69 67 6e 65  .  const unsigne
2a80: 64 20 63 68 61 72 20 2a 7a 49 6e 70 75 74 20 3d  d char *zInput =
2a90: 20 28 63 6f 6e 73 74 20 75 6e 73 69 67 6e 65 64   (const unsigned
2aa0: 20 63 68 61 72 2a 29 70 54 65 78 74 3b 0a 20 20   char*)pText;.  
2ab0: 63 6f 6e 73 74 20 75 6e 73 69 67 6e 65 64 20 63  const unsigned c
2ac0: 68 61 72 20 2a 7a 54 65 72 6d 20 3d 20 26 7a 49  har *zTerm = &zI
2ad0: 6e 70 75 74 5b 6e 54 65 78 74 5d 3b 0a 20 20 63  nput[nText];.  c
2ae0: 6f 6e 73 74 20 75 6e 73 69 67 6e 65 64 20 63 68  onst unsigned ch
2af0: 61 72 20 2a 7a 20 3d 20 7a 49 6e 70 75 74 3b 0a  ar *z = zInput;.
2b00: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
2b10: 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e 42 75 66  E_OK;.  int nBuf
2b20: 20 3d 20 30 3b 0a 20 20 75 6e 73 69 67 6e 65 64   = 0;.  unsigned
2b30: 20 63 68 61 72 20 2a 7a 42 75 66 20 3d 20 30 3b   char *zBuf = 0;
2b40: 0a 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72  .  unsigned char
2b50: 20 2a 7a 4f 75 74 20 3d 20 30 3b 0a 0a 20 20 77   *zOut = 0;..  w
2b60: 68 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54 45  hile( rc==SQLITE
2b70: 5f 4f 4b 20 26 26 20 7a 3c 7a 54 65 72 6d 20 29  _OK && z<zTerm )
2b80: 7b 0a 20 20 20 20 69 6e 74 20 69 43 6f 64 65 3b  {.    int iCode;
2b90: 0a 20 20 20 20 69 6e 74 20 62 41 6c 6e 75 6d 3b  .    int bAlnum;
2ba0: 0a 20 20 20 20 63 6f 6e 73 74 20 75 6e 73 69 67  .    const unsig
2bb0: 6e 65 64 20 63 68 61 72 20 2a 7a 53 74 61 72 74  ned char *zStart
2bc0: 3b 0a 20 20 20 20 63 6f 6e 73 74 20 75 6e 73 69  ;.    const unsi
2bd0: 67 6e 65 64 20 63 68 61 72 20 2a 7a 43 6f 64 65  gned char *zCode
2be0: 3b 0a 0a 20 20 20 20 69 66 28 20 7a 4f 75 74 3d  ;..    if( zOut=
2bf0: 3d 7a 42 75 66 20 29 20 7a 53 74 61 72 74 20 3d  =zBuf ) zStart =
2c00: 20 7a 3b 0a 20 20 20 20 7a 43 6f 64 65 20 3d 20   z;.    zCode = 
2c10: 7a 3b 0a 20 20 20 20 52 45 41 44 5f 55 54 46 38  z;.    READ_UTF8
2c20: 28 7a 2c 20 7a 54 65 72 6d 2c 20 69 43 6f 64 65  (z, zTerm, iCode
2c30: 29 3b 0a 20 20 20 20 62 41 6c 6e 75 6d 20 3d 20  );.    bAlnum = 
2c40: 66 74 73 35 55 6e 69 63 6f 64 65 49 73 41 6c 6e  fts5UnicodeIsAln
2c50: 75 6d 28 70 2c 20 69 43 6f 64 65 29 3b 0a 20 20  um(p, iCode);.  
2c60: 20 20 69 66 28 20 62 41 6c 6e 75 6d 3d 3d 30 20    if( bAlnum==0 
2c70: 26 26 20 7a 4f 75 74 3e 7a 42 75 66 20 29 7b 0a  && zOut>zBuf ){.
2c80: 20 20 20 20 20 20 62 41 6c 6e 75 6d 20 3d 20 73        bAlnum = s
2c90: 71 6c 69 74 65 33 46 74 73 35 55 6e 69 63 6f 64  qlite3Fts5Unicod
2ca0: 65 49 73 64 69 61 63 72 69 74 69 63 28 69 43 6f  eIsdiacritic(iCo
2cb0: 64 65 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  de);.    }..    
2cc0: 69 66 28 20 62 41 6c 6e 75 6d 20 29 7b 0a 20 20  if( bAlnum ){.  
2cd0: 20 20 20 20 69 6e 74 20 69 4f 75 74 3b 0a 0a 20      int iOut;.. 
2ce0: 20 20 20 20 20 2f 2a 20 47 72 6f 77 20 74 68 65       /* Grow the
2cf0: 20 6f 75 74 70 75 74 20 62 75 66 66 65 72 20 69   output buffer i
2d00: 66 20 72 65 71 75 69 72 65 64 20 2a 2f 0a 20 20  f required */.  
2d10: 20 20 20 20 77 68 69 6c 65 28 20 28 7a 4f 75 74      while( (zOut
2d20: 2d 7a 42 75 66 29 2b 34 3e 3d 6e 42 75 66 20 29  -zBuf)+4>=nBuf )
2d30: 7b 0a 20 20 20 20 20 20 20 20 75 6e 73 69 67 6e  {.        unsign
2d40: 65 64 20 63 68 61 72 20 2a 7a 4e 65 77 3b 0a 20  ed char *zNew;. 
2d50: 20 20 20 20 20 20 20 6e 42 75 66 20 3d 20 28 6e         nBuf = (n
2d60: 42 75 66 20 3f 20 6e 42 75 66 2a 32 20 3a 20 31  Buf ? nBuf*2 : 1
2d70: 32 38 29 3b 0a 20 20 20 20 20 20 20 20 7a 4e 65  28);.        zNe
2d80: 77 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 61 6c  w = sqlite3_real
2d90: 6c 6f 63 28 7a 42 75 66 2c 20 6e 42 75 66 29 3b  loc(zBuf, nBuf);
2da0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 7a 4e 65  .        if( zNe
2db0: 77 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  w==0 ){.        
2dc0: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f    rc = SQLITE_NO
2dd0: 4d 45 4d 3b 0a 20 20 20 20 20 20 20 20 20 20 67  MEM;.          g
2de0: 6f 74 6f 20 74 6f 6b 65 6e 69 7a 65 5f 66 69 6e  oto tokenize_fin
2df0: 69 73 68 65 64 3b 0a 20 20 20 20 20 20 20 20 7d  ished;.        }
2e00: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20  else{.          
2e10: 7a 4f 75 74 20 3d 20 26 7a 4e 65 77 5b 7a 4f 75  zOut = &zNew[zOu
2e20: 74 2d 7a 42 75 66 5d 3b 0a 20 20 20 20 20 20 20  t-zBuf];.       
2e30: 20 20 20 7a 42 75 66 20 3d 20 7a 4e 65 77 3b 0a     zBuf = zNew;.
2e40: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
2e50: 7d 0a 0a 20 20 20 20 20 20 2f 2a 20 57 72 69 74  }..      /* Writ
2e60: 65 20 74 68 65 20 6e 65 77 20 63 68 61 72 61 63  e the new charac
2e70: 74 65 72 20 74 6f 20 69 74 20 2a 2f 0a 20 20 20  ter to it */.   
2e80: 20 20 20 69 4f 75 74 20 3d 20 73 71 6c 69 74 65     iOut = sqlite
2e90: 33 46 74 73 35 55 6e 69 63 6f 64 65 46 6f 6c 64  3Fts5UnicodeFold
2ea0: 28 69 43 6f 64 65 2c 20 70 2d 3e 62 52 65 6d 6f  (iCode, p->bRemo
2eb0: 76 65 44 69 61 63 72 69 74 69 63 29 3b 0a 20 20  veDiacritic);.  
2ec0: 20 20 20 20 69 66 28 20 69 4f 75 74 20 29 20 57      if( iOut ) W
2ed0: 52 49 54 45 5f 55 54 46 38 28 7a 4f 75 74 2c 20  RITE_UTF8(zOut, 
2ee0: 69 4f 75 74 29 3b 0a 20 20 20 20 7d 0a 0a 20 20  iOut);.    }..  
2ef0: 20 20 69 66 28 20 7a 4f 75 74 3e 7a 42 75 66 20    if( zOut>zBuf 
2f00: 26 26 20 28 62 41 6c 6e 75 6d 3d 3d 30 20 7c 7c  && (bAlnum==0 ||
2f10: 20 7a 3e 3d 7a 54 65 72 6d 29 20 29 7b 0a 20 20   z>=zTerm) ){.  
2f20: 20 20 20 20 69 6e 74 20 69 65 20 3d 20 28 62 41      int ie = (bA
2f30: 6c 6e 75 6d 20 3f 20 7a 20 3a 20 7a 43 6f 64 65  lnum ? z : zCode
2f40: 29 20 2d 20 7a 49 6e 70 75 74 3b 0a 20 20 20 20  ) - zInput;.    
2f50: 20 20 72 63 20 3d 20 78 54 6f 6b 65 6e 28 70 43    rc = xToken(pC
2f60: 74 78 2c 20 28 63 6f 6e 73 74 20 63 68 61 72 2a  tx, (const char*
2f70: 29 7a 42 75 66 2c 20 7a 4f 75 74 2d 7a 42 75 66  )zBuf, zOut-zBuf
2f80: 2c 20 7a 53 74 61 72 74 2d 7a 49 6e 70 75 74 2c  , zStart-zInput,
2f90: 20 69 65 29 3b 0a 20 20 20 20 20 20 7a 4f 75 74   ie);.      zOut
2fa0: 20 3d 20 7a 42 75 66 3b 0a 20 20 20 20 7d 0a 20   = zBuf;.    }. 
2fb0: 20 7d 0a 0a 20 74 6f 6b 65 6e 69 7a 65 5f 66 69   }.. tokenize_fi
2fc0: 6e 69 73 68 65 64 3a 0a 20 20 73 71 6c 69 74 65  nished:.  sqlite
2fd0: 33 5f 66 72 65 65 28 7a 42 75 66 29 3b 0a 20 20  3_free(zBuf);.  
2fe0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
2ff0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3000: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3010: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3020: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3030: 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a 20 53 74 61  *********.** Sta
3040: 72 74 20 6f 66 20 70 6f 72 74 65 72 20 73 74 65  rt of porter ste
3050: 6d 6d 65 72 20 69 6d 70 6c 65 6d 65 6e 74 61 74  mmer implementat
3060: 69 6f 6e 2e 0a 2a 2f 0a 0a 2f 2a 20 41 6e 79 20  ion..*/../* Any 
3070: 74 6f 6b 65 6e 73 20 6c 61 72 67 65 72 20 74 68  tokens larger th
3080: 61 6e 20 74 68 69 73 20 28 69 6e 20 62 79 74 65  an this (in byte
3090: 73 29 20 61 72 65 20 70 61 73 73 65 64 20 74 68  s) are passed th
30a0: 72 6f 75 67 68 20 77 69 74 68 6f 75 74 0a 2a 2a  rough without.**
30b0: 20 73 74 65 6d 6d 69 6e 67 2e 20 2a 2f 0a 23 64   stemming. */.#d
30c0: 65 66 69 6e 65 20 46 54 53 35 5f 50 4f 52 54 45  efine FTS5_PORTE
30d0: 52 5f 4d 41 58 5f 54 4f 4b 45 4e 20 36 34 0a 0a  R_MAX_TOKEN 64..
30e0: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 50  typedef struct P
30f0: 6f 72 74 65 72 54 6f 6b 65 6e 69 7a 65 72 20 50  orterTokenizer P
3100: 6f 72 74 65 72 54 6f 6b 65 6e 69 7a 65 72 3b 0a  orterTokenizer;.
3110: 73 74 72 75 63 74 20 50 6f 72 74 65 72 54 6f 6b  struct PorterTok
3120: 65 6e 69 7a 65 72 20 7b 0a 20 20 66 74 73 35 5f  enizer {.  fts5_
3130: 74 6f 6b 65 6e 69 7a 65 72 20 74 6f 6b 65 6e 69  tokenizer tokeni
3140: 7a 65 72 3b 20 20 20 20 20 20 20 2f 2a 20 50 61  zer;       /* Pa
3150: 72 65 6e 74 20 74 6f 6b 65 6e 69 7a 65 72 20 6d  rent tokenizer m
3160: 6f 64 75 6c 65 20 2a 2f 0a 20 20 46 74 73 35 54  odule */.  Fts5T
3170: 6f 6b 65 6e 69 7a 65 72 20 2a 70 54 6f 6b 65 6e  okenizer *pToken
3180: 69 7a 65 72 3b 20 20 20 20 20 20 2f 2a 20 50 61  izer;      /* Pa
3190: 72 65 6e 74 20 74 6f 6b 65 6e 69 7a 65 72 20 69  rent tokenizer i
31a0: 6e 73 74 61 6e 63 65 20 2a 2f 0a 20 20 63 68 61  nstance */.  cha
31b0: 72 20 61 42 75 66 5b 46 54 53 35 5f 50 4f 52 54  r aBuf[FTS5_PORT
31c0: 45 52 5f 4d 41 58 5f 54 4f 4b 45 4e 20 2b 20 36  ER_MAX_TOKEN + 6
31d0: 34 5d 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 44 65  4];.};../*.** De
31e0: 6c 65 74 65 20 61 20 22 70 6f 72 74 65 72 22 20  lete a "porter" 
31f0: 74 6f 6b 65 6e 69 7a 65 72 2e 0a 2a 2f 0a 73 74  tokenizer..*/.st
3200: 61 74 69 63 20 76 6f 69 64 20 66 74 73 35 50 6f  atic void fts5Po
3210: 72 74 65 72 44 65 6c 65 74 65 28 46 74 73 35 54  rterDelete(Fts5T
3220: 6f 6b 65 6e 69 7a 65 72 20 2a 70 54 6f 6b 29 7b  okenizer *pTok){
3230: 0a 20 20 69 66 28 20 70 54 6f 6b 20 29 7b 0a 20  .  if( pTok ){. 
3240: 20 20 20 50 6f 72 74 65 72 54 6f 6b 65 6e 69 7a     PorterTokeniz
3250: 65 72 20 2a 70 20 3d 20 28 50 6f 72 74 65 72 54  er *p = (PorterT
3260: 6f 6b 65 6e 69 7a 65 72 2a 29 70 54 6f 6b 3b 0a  okenizer*)pTok;.
3270: 20 20 20 20 69 66 28 20 70 2d 3e 70 54 6f 6b 65      if( p->pToke
3280: 6e 69 7a 65 72 20 29 7b 0a 20 20 20 20 20 20 70  nizer ){.      p
3290: 2d 3e 74 6f 6b 65 6e 69 7a 65 72 2e 78 44 65 6c  ->tokenizer.xDel
32a0: 65 74 65 28 70 2d 3e 70 54 6f 6b 65 6e 69 7a 65  ete(p->pTokenize
32b0: 72 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71  r);.    }.    sq
32c0: 6c 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 20  lite3_free(p);. 
32d0: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 72 65 61   }.}../*.** Crea
32e0: 74 65 20 61 20 22 70 6f 72 74 65 72 22 20 74 6f  te a "porter" to
32f0: 6b 65 6e 69 7a 65 72 2e 0a 2a 2f 0a 73 74 61 74  kenizer..*/.stat
3300: 69 63 20 69 6e 74 20 66 74 73 35 50 6f 72 74 65  ic int fts5Porte
3310: 72 43 72 65 61 74 65 28 0a 20 20 76 6f 69 64 20  rCreate(.  void 
3320: 2a 70 43 74 78 2c 20 0a 20 20 63 6f 6e 73 74 20  *pCtx, .  const 
3330: 63 68 61 72 20 2a 2a 61 7a 41 72 67 2c 20 69 6e  char **azArg, in
3340: 74 20 6e 41 72 67 2c 0a 20 20 46 74 73 35 54 6f  t nArg,.  Fts5To
3350: 6b 65 6e 69 7a 65 72 20 2a 2a 70 70 4f 75 74 0a  kenizer **ppOut.
3360: 29 7b 0a 20 20 66 74 73 35 5f 61 70 69 20 2a 70  ){.  fts5_api *p
3370: 41 70 69 20 3d 20 28 66 74 73 35 5f 61 70 69 2a  Api = (fts5_api*
3380: 29 70 43 74 78 3b 0a 20 20 69 6e 74 20 72 63 20  )pCtx;.  int rc 
3390: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 50  = SQLITE_OK;.  P
33a0: 6f 72 74 65 72 54 6f 6b 65 6e 69 7a 65 72 20 2a  orterTokenizer *
33b0: 70 52 65 74 3b 0a 20 20 76 6f 69 64 20 2a 70 55  pRet;.  void *pU
33c0: 73 65 72 64 61 74 61 20 3d 20 30 3b 0a 0a 20 20  serdata = 0;..  
33d0: 70 52 65 74 20 3d 20 28 50 6f 72 74 65 72 54 6f  pRet = (PorterTo
33e0: 6b 65 6e 69 7a 65 72 2a 29 73 71 6c 69 74 65 33  kenizer*)sqlite3
33f0: 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 50  _malloc(sizeof(P
3400: 6f 72 74 65 72 54 6f 6b 65 6e 69 7a 65 72 29 29  orterTokenizer))
3410: 3b 0a 20 20 69 66 28 20 70 52 65 74 20 29 7b 0a  ;.  if( pRet ){.
3420: 20 20 20 20 6d 65 6d 73 65 74 28 70 52 65 74 2c      memset(pRet,
3430: 20 30 2c 20 73 69 7a 65 6f 66 28 50 6f 72 74 65   0, sizeof(Porte
3440: 72 54 6f 6b 65 6e 69 7a 65 72 29 29 3b 0a 20 20  rTokenizer));.  
3450: 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 46 69    rc = pApi->xFi
3460: 6e 64 54 6f 6b 65 6e 69 7a 65 72 28 70 41 70 69  ndTokenizer(pApi
3470: 2c 20 22 73 69 6d 70 6c 65 22 2c 20 26 70 55 73  , "simple", &pUs
3480: 65 72 64 61 74 61 2c 20 26 70 52 65 74 2d 3e 74  erdata, &pRet->t
3490: 6f 6b 65 6e 69 7a 65 72 29 3b 0a 20 20 7d 65 6c  okenizer);.  }el
34a0: 73 65 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c  se{.    rc = SQL
34b0: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20  ITE_NOMEM;.  }. 
34c0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
34d0: 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 70  OK ){.    rc = p
34e0: 52 65 74 2d 3e 74 6f 6b 65 6e 69 7a 65 72 2e 78  Ret->tokenizer.x
34f0: 43 72 65 61 74 65 28 70 55 73 65 72 64 61 74 61  Create(pUserdata
3500: 2c 20 30 2c 20 30 2c 20 26 70 52 65 74 2d 3e 70  , 0, 0, &pRet->p
3510: 54 6f 6b 65 6e 69 7a 65 72 29 3b 0a 20 20 7d 0a  Tokenizer);.  }.
3520: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
3530: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 66 74 73 35  E_OK ){.    fts5
3540: 50 6f 72 74 65 72 44 65 6c 65 74 65 28 28 46 74  PorterDelete((Ft
3550: 73 35 54 6f 6b 65 6e 69 7a 65 72 2a 29 70 52 65  s5Tokenizer*)pRe
3560: 74 29 3b 0a 20 20 20 20 70 52 65 74 20 3d 20 30  t);.    pRet = 0
3570: 3b 0a 20 20 7d 0a 20 20 2a 70 70 4f 75 74 20 3d  ;.  }.  *ppOut =
3580: 20 28 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72 2a   (Fts5Tokenizer*
3590: 29 70 52 65 74 3b 0a 20 20 72 65 74 75 72 6e 20  )pRet;.  return 
35a0: 72 63 3b 0a 7d 0a 0a 74 79 70 65 64 65 66 20 73  rc;.}..typedef s
35b0: 74 72 75 63 74 20 50 6f 72 74 65 72 43 6f 6e 74  truct PorterCont
35c0: 65 78 74 20 50 6f 72 74 65 72 43 6f 6e 74 65 78  ext PorterContex
35d0: 74 3b 0a 73 74 72 75 63 74 20 50 6f 72 74 65 72  t;.struct Porter
35e0: 43 6f 6e 74 65 78 74 20 7b 0a 20 20 76 6f 69 64  Context {.  void
35f0: 20 2a 70 43 74 78 3b 0a 20 20 69 6e 74 20 28 2a   *pCtx;.  int (*
3600: 78 54 6f 6b 65 6e 29 28 76 6f 69 64 2a 2c 20 63  xToken)(void*, c
3610: 6f 6e 73 74 20 63 68 61 72 2a 2c 20 69 6e 74 2c  onst char*, int,
3620: 20 69 6e 74 2c 20 69 6e 74 29 3b 0a 20 20 63 68   int, int);.  ch
3630: 61 72 20 2a 61 42 75 66 3b 0a 7d 3b 0a 0a 74 79  ar *aBuf;.};..ty
3640: 70 65 64 65 66 20 73 74 72 75 63 74 20 50 6f 72  pedef struct Por
3650: 74 65 72 52 75 6c 65 20 50 6f 72 74 65 72 52 75  terRule PorterRu
3660: 6c 65 3b 0a 73 74 72 75 63 74 20 50 6f 72 74 65  le;.struct Porte
3670: 72 52 75 6c 65 20 7b 0a 20 20 63 6f 6e 73 74 20  rRule {.  const 
3680: 63 68 61 72 20 2a 7a 53 75 66 66 69 78 3b 0a 20  char *zSuffix;. 
3690: 20 69 6e 74 20 6e 53 75 66 66 69 78 3b 0a 20 20   int nSuffix;.  
36a0: 69 6e 74 20 28 2a 78 43 6f 6e 64 29 28 63 68 61  int (*xCond)(cha
36b0: 72 20 2a 7a 53 74 65 6d 2c 20 69 6e 74 20 6e 53  r *zStem, int nS
36c0: 74 65 6d 29 3b 0a 20 20 63 6f 6e 73 74 20 63 68  tem);.  const ch
36d0: 61 72 20 2a 7a 4f 75 74 70 75 74 3b 0a 20 20 69  ar *zOutput;.  i
36e0: 6e 74 20 6e 4f 75 74 70 75 74 3b 0a 7d 3b 0a 0a  nt nOutput;.};..
36f0: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 50  static int fts5P
3700: 6f 72 74 65 72 41 70 70 6c 79 28 63 68 61 72 20  orterApply(char 
3710: 2a 61 42 75 66 2c 20 69 6e 74 20 2a 70 6e 42 75  *aBuf, int *pnBu
3720: 66 2c 20 50 6f 72 74 65 72 52 75 6c 65 20 2a 61  f, PorterRule *a
3730: 52 75 6c 65 29 7b 0a 20 20 69 6e 74 20 72 65 74  Rule){.  int ret
3740: 20 3d 20 2d 31 3b 0a 20 20 69 6e 74 20 6e 42 75   = -1;.  int nBu
3750: 66 20 3d 20 2a 70 6e 42 75 66 3b 0a 20 20 50 6f  f = *pnBuf;.  Po
3760: 72 74 65 72 52 75 6c 65 20 2a 70 3b 0a 0a 20 20  rterRule *p;..  
3770: 66 6f 72 28 70 3d 61 52 75 6c 65 3b 20 70 2d 3e  for(p=aRule; p->
3780: 7a 53 75 66 66 69 78 3b 20 70 2b 2b 29 7b 0a 20  zSuffix; p++){. 
3790: 20 20 20 61 73 73 65 72 74 28 20 73 74 72 6c 65     assert( strle
37a0: 6e 28 70 2d 3e 7a 53 75 66 66 69 78 29 3d 3d 70  n(p->zSuffix)==p
37b0: 2d 3e 6e 53 75 66 66 69 78 20 29 3b 0a 20 20 20  ->nSuffix );.   
37c0: 20 61 73 73 65 72 74 28 20 73 74 72 6c 65 6e 28   assert( strlen(
37d0: 70 2d 3e 7a 4f 75 74 70 75 74 29 3d 3d 70 2d 3e  p->zOutput)==p->
37e0: 6e 4f 75 74 70 75 74 20 29 3b 0a 20 20 20 20 69  nOutput );.    i
37f0: 66 28 20 6e 42 75 66 3c 70 2d 3e 6e 53 75 66 66  f( nBuf<p->nSuff
3800: 69 78 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20  ix ) continue;. 
3810: 20 20 20 69 66 28 20 30 3d 3d 6d 65 6d 63 6d 70     if( 0==memcmp
3820: 28 26 61 42 75 66 5b 6e 42 75 66 20 2d 20 70 2d  (&aBuf[nBuf - p-
3830: 3e 6e 53 75 66 66 69 78 5d 2c 20 70 2d 3e 7a 53  >nSuffix], p->zS
3840: 75 66 66 69 78 2c 20 70 2d 3e 6e 53 75 66 66 69  uffix, p->nSuffi
3850: 78 29 20 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a  x) ) break;.  }.
3860: 0a 20 20 69 66 28 20 70 2d 3e 7a 53 75 66 66 69  .  if( p->zSuffi
3870: 78 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 53 74  x ){.    int nSt
3880: 65 6d 20 3d 20 6e 42 75 66 20 2d 20 70 2d 3e 6e  em = nBuf - p->n
3890: 53 75 66 66 69 78 3b 0a 20 20 20 20 69 66 28 20  Suffix;.    if( 
38a0: 70 2d 3e 78 43 6f 6e 64 3d 3d 30 20 7c 7c 20 70  p->xCond==0 || p
38b0: 2d 3e 78 43 6f 6e 64 28 61 42 75 66 2c 20 6e 53  ->xCond(aBuf, nS
38c0: 74 65 6d 29 20 29 7b 0a 20 20 20 20 20 20 6d 65  tem) ){.      me
38d0: 6d 63 70 79 28 26 61 42 75 66 5b 6e 53 74 65 6d  mcpy(&aBuf[nStem
38e0: 5d 2c 20 70 2d 3e 7a 4f 75 74 70 75 74 2c 20 70  ], p->zOutput, p
38f0: 2d 3e 6e 4f 75 74 70 75 74 29 3b 0a 20 20 20 20  ->nOutput);.    
3900: 20 20 2a 70 6e 42 75 66 20 3d 20 6e 53 74 65 6d    *pnBuf = nStem
3910: 20 2b 20 70 2d 3e 6e 4f 75 74 70 75 74 3b 0a 20   + p->nOutput;. 
3920: 20 20 20 20 20 72 65 74 20 3d 20 70 20 2d 20 61       ret = p - a
3930: 52 75 6c 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  Rule;.    }.  }.
3940: 0a 20 20 72 65 74 75 72 6e 20 72 65 74 3b 0a 7d  .  return ret;.}
3950: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  ..static int fts
3960: 35 50 6f 72 74 65 72 49 73 56 6f 77 65 6c 28 63  5PorterIsVowel(c
3970: 68 61 72 20 63 2c 20 69 6e 74 20 62 59 49 73 56  har c, int bYIsV
3980: 6f 77 65 6c 29 7b 0a 20 20 72 65 74 75 72 6e 20  owel){.  return 
3990: 28 0a 20 20 20 20 20 20 63 3d 3d 27 61 27 20 7c  (.      c=='a' |
39a0: 7c 20 63 3d 3d 27 65 27 20 7c 7c 20 63 3d 3d 27  | c=='e' || c=='
39b0: 69 27 20 7c 7c 20 63 3d 3d 27 6f 27 20 7c 7c 20  i' || c=='o' || 
39c0: 63 3d 3d 27 75 27 20 7c 7c 20 28 62 59 49 73 56  c=='u' || (bYIsV
39d0: 6f 77 65 6c 20 26 26 20 63 3d 3d 27 79 27 29 0a  owel && c=='y').
39e0: 20 20 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69    );.}..static i
39f0: 6e 74 20 66 74 73 35 50 6f 72 74 65 72 47 6f 62  nt fts5PorterGob
3a00: 62 6c 65 56 43 28 63 68 61 72 20 2a 7a 53 74 65  bleVC(char *zSte
3a10: 6d 2c 20 69 6e 74 20 6e 53 74 65 6d 2c 20 69 6e  m, int nStem, in
3a20: 74 20 62 50 72 65 76 43 6f 6e 73 29 7b 0a 20 20  t bPrevCons){.  
3a30: 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 62 43 6f  int i;.  int bCo
3a40: 6e 73 20 3d 20 62 50 72 65 76 43 6f 6e 73 3b 0a  ns = bPrevCons;.
3a50: 0a 20 20 2f 2a 20 53 63 61 6e 20 66 6f 72 20 61  .  /* Scan for a
3a60: 20 76 6f 77 65 6c 20 2a 2f 0a 20 20 66 6f 72 28   vowel */.  for(
3a70: 69 3d 30 3b 20 69 3c 6e 53 74 65 6d 3b 20 69 2b  i=0; i<nStem; i+
3a80: 2b 29 7b 0a 20 20 20 20 69 66 28 20 30 3d 3d 28  +){.    if( 0==(
3a90: 62 43 6f 6e 73 20 3d 20 21 66 74 73 35 50 6f 72  bCons = !fts5Por
3aa0: 74 65 72 49 73 56 6f 77 65 6c 28 7a 53 74 65 6d  terIsVowel(zStem
3ab0: 5b 69 5d 2c 20 62 43 6f 6e 73 29 29 20 29 20 62  [i], bCons)) ) b
3ac0: 72 65 61 6b 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  reak;.  }..  /* 
3ad0: 53 63 61 6e 20 66 6f 72 20 61 20 63 6f 6e 73 6f  Scan for a conso
3ae0: 6e 65 6e 74 20 2a 2f 0a 20 20 66 6f 72 28 69 2b  nent */.  for(i+
3af0: 2b 3b 20 69 3c 6e 53 74 65 6d 3b 20 69 2b 2b 29  +; i<nStem; i++)
3b00: 7b 0a 20 20 20 20 69 66 28 20 28 62 43 6f 6e 73  {.    if( (bCons
3b10: 20 3d 20 21 66 74 73 35 50 6f 72 74 65 72 49 73   = !fts5PorterIs
3b20: 56 6f 77 65 6c 28 7a 53 74 65 6d 5b 69 5d 2c 20  Vowel(zStem[i], 
3b30: 62 43 6f 6e 73 29 29 20 29 20 72 65 74 75 72 6e  bCons)) ) return
3b40: 20 69 2b 31 3b 0a 20 20 7d 0a 20 20 72 65 74 75   i+1;.  }.  retu
3b50: 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 20 70 6f 72 74  rn 0;.}../* port
3b60: 65 72 20 72 75 6c 65 20 63 6f 6e 64 69 74 69 6f  er rule conditio
3b70: 6e 3a 20 28 6d 20 3e 20 30 29 20 2a 2f 0a 73 74  n: (m > 0) */.st
3b80: 61 74 69 63 20 69 6e 74 20 66 74 73 35 50 6f 72  atic int fts5Por
3b90: 74 65 72 5f 4d 47 74 30 28 63 68 61 72 20 2a 7a  ter_MGt0(char *z
3ba0: 53 74 65 6d 2c 20 69 6e 74 20 6e 53 74 65 6d 29  Stem, int nStem)
3bb0: 7b 0a 20 20 72 65 74 75 72 6e 20 21 21 66 74 73  {.  return !!fts
3bc0: 35 50 6f 72 74 65 72 47 6f 62 62 6c 65 56 43 28  5PorterGobbleVC(
3bd0: 7a 53 74 65 6d 2c 20 6e 53 74 65 6d 2c 20 30 29  zStem, nStem, 0)
3be0: 3b 0a 7d 0a 0a 2f 2a 20 70 6f 72 74 65 72 20 72  ;.}../* porter r
3bf0: 75 6c 65 20 63 6f 6e 64 69 74 69 6f 6e 3a 20 28  ule condition: (
3c00: 6d 20 3e 20 31 29 20 2a 2f 0a 73 74 61 74 69 63  m > 1) */.static
3c10: 20 69 6e 74 20 66 74 73 35 50 6f 72 74 65 72 5f   int fts5Porter_
3c20: 4d 47 74 31 28 63 68 61 72 20 2a 7a 53 74 65 6d  MGt1(char *zStem
3c30: 2c 20 69 6e 74 20 6e 53 74 65 6d 29 7b 0a 20 20  , int nStem){.  
3c40: 69 6e 74 20 6e 3b 0a 20 20 6e 20 3d 20 66 74 73  int n;.  n = fts
3c50: 35 50 6f 72 74 65 72 47 6f 62 62 6c 65 56 43 28  5PorterGobbleVC(
3c60: 7a 53 74 65 6d 2c 20 6e 53 74 65 6d 2c 20 30 29  zStem, nStem, 0)
3c70: 3b 0a 20 20 69 66 28 20 6e 20 26 26 20 66 74 73  ;.  if( n && fts
3c80: 35 50 6f 72 74 65 72 47 6f 62 62 6c 65 56 43 28  5PorterGobbleVC(
3c90: 26 7a 53 74 65 6d 5b 6e 5d 2c 20 6e 53 74 65 6d  &zStem[n], nStem
3ca0: 2d 6e 2c 20 31 29 20 29 7b 0a 20 20 20 20 72 65  -n, 1) ){.    re
3cb0: 74 75 72 6e 20 31 3b 0a 20 20 7d 0a 20 20 72 65  turn 1;.  }.  re
3cc0: 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 20 70 6f  turn 0;.}../* po
3cd0: 72 74 65 72 20 72 75 6c 65 20 63 6f 6e 64 69 74  rter rule condit
3ce0: 69 6f 6e 3a 20 28 6d 20 3d 20 31 29 20 2a 2f 0a  ion: (m = 1) */.
3cf0: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 50  static int fts5P
3d00: 6f 72 74 65 72 5f 4d 45 71 31 28 63 68 61 72 20  orter_MEq1(char 
3d10: 2a 7a 53 74 65 6d 2c 20 69 6e 74 20 6e 53 74 65  *zStem, int nSte
3d20: 6d 29 7b 0a 20 20 69 6e 74 20 6e 3b 0a 20 20 6e  m){.  int n;.  n
3d30: 20 3d 20 66 74 73 35 50 6f 72 74 65 72 47 6f 62   = fts5PorterGob
3d40: 62 6c 65 56 43 28 7a 53 74 65 6d 2c 20 6e 53 74  bleVC(zStem, nSt
3d50: 65 6d 2c 20 30 29 3b 0a 20 20 69 66 28 20 6e 20  em, 0);.  if( n 
3d60: 26 26 20 30 3d 3d 66 74 73 35 50 6f 72 74 65 72  && 0==fts5Porter
3d70: 47 6f 62 62 6c 65 56 43 28 26 7a 53 74 65 6d 5b  GobbleVC(&zStem[
3d80: 6e 5d 2c 20 6e 53 74 65 6d 2d 6e 2c 20 31 29 20  n], nStem-n, 1) 
3d90: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 31 3b  ){.    return 1;
3da0: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 30 3b  .  }.  return 0;
3db0: 0a 7d 0a 0a 2f 2a 20 70 6f 72 74 65 72 20 72 75  .}../* porter ru
3dc0: 6c 65 20 63 6f 6e 64 69 74 69 6f 6e 3a 20 28 2a  le condition: (*
3dd0: 6f 29 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  o) */.static int
3de0: 20 66 74 73 35 50 6f 72 74 65 72 5f 4f 73 74 61   fts5Porter_Osta
3df0: 72 28 63 68 61 72 20 2a 7a 53 74 65 6d 2c 20 69  r(char *zStem, i
3e00: 6e 74 20 6e 53 74 65 6d 29 7b 0a 20 20 69 66 28  nt nStem){.  if(
3e10: 20 7a 53 74 65 6d 5b 6e 53 74 65 6d 2d 31 5d 3d   zStem[nStem-1]=
3e20: 3d 27 77 27 20 7c 7c 20 7a 53 74 65 6d 5b 6e 53  ='w' || zStem[nS
3e30: 74 65 6d 2d 31 5d 3d 3d 27 78 27 20 7c 7c 20 7a  tem-1]=='x' || z
3e40: 53 74 65 6d 5b 6e 53 74 65 6d 2d 31 5d 3d 3d 27  Stem[nStem-1]=='
3e50: 79 27 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  y' ){.    return
3e60: 20 30 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20   0;.  }else{.   
3e70: 20 69 6e 74 20 69 3b 0a 20 20 20 20 69 6e 74 20   int i;.    int 
3e80: 6d 61 73 6b 20 3d 20 30 3b 0a 20 20 20 20 69 6e  mask = 0;.    in
3e90: 74 20 62 43 6f 6e 73 20 3d 20 30 3b 0a 20 20 20  t bCons = 0;.   
3ea0: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 53 74 65   for(i=0; i<nSte
3eb0: 6d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 62  m; i++){.      b
3ec0: 43 6f 6e 73 20 3d 20 21 66 74 73 35 50 6f 72 74  Cons = !fts5Port
3ed0: 65 72 49 73 56 6f 77 65 6c 28 7a 53 74 65 6d 5b  erIsVowel(zStem[
3ee0: 69 5d 2c 20 62 43 6f 6e 73 29 3b 0a 20 20 20 20  i], bCons);.    
3ef0: 20 20 61 73 73 65 72 74 28 20 62 43 6f 6e 73 3d    assert( bCons=
3f00: 3d 30 20 7c 7c 20 62 43 6f 6e 73 3d 3d 31 20 29  =0 || bCons==1 )
3f10: 3b 0a 20 20 20 20 20 20 6d 61 73 6b 20 3d 20 28  ;.      mask = (
3f20: 6d 61 73 6b 20 3c 3c 20 31 29 20 2b 20 62 43 6f  mask << 1) + bCo
3f30: 6e 73 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 65  ns;.    }.    re
3f40: 74 75 72 6e 20 28 28 6d 61 73 6b 20 26 20 30 78  turn ((mask & 0x
3f50: 30 30 30 37 29 3d 3d 30 78 30 30 30 35 29 3b 0a  0007)==0x0005);.
3f60: 20 20 7d 0a 7d 0a 0a 2f 2a 20 70 6f 72 74 65 72    }.}../* porter
3f70: 20 72 75 6c 65 20 63 6f 6e 64 69 74 69 6f 6e 3a   rule condition:
3f80: 20 28 6d 20 3e 20 31 20 61 6e 64 20 28 2a 53 20   (m > 1 and (*S 
3f90: 6f 72 20 2a 54 29 29 20 2a 2f 0a 73 74 61 74 69  or *T)) */.stati
3fa0: 63 20 69 6e 74 20 66 74 73 35 50 6f 72 74 65 72  c int fts5Porter
3fb0: 5f 4d 47 74 31 5f 61 6e 64 5f 53 5f 6f 72 5f 54  _MGt1_and_S_or_T
3fc0: 28 63 68 61 72 20 2a 7a 53 74 65 6d 2c 20 69 6e  (char *zStem, in
3fd0: 74 20 6e 53 74 65 6d 29 7b 0a 20 20 72 65 74 75  t nStem){.  retu
3fe0: 72 6e 20 6e 53 74 65 6d 3e 30 0a 20 20 20 20 20  rn nStem>0.     
3ff0: 20 26 26 20 28 7a 53 74 65 6d 5b 6e 53 74 65 6d   && (zStem[nStem
4000: 2d 31 5d 3d 3d 27 73 27 20 7c 7c 20 7a 53 74 65  -1]=='s' || zSte
4010: 6d 5b 6e 53 74 65 6d 2d 31 5d 3d 3d 27 74 27 29  m[nStem-1]=='t')
4020: 0a 20 20 20 20 20 20 26 26 20 66 74 73 35 50 6f  .      && fts5Po
4030: 72 74 65 72 5f 4d 47 74 31 28 7a 53 74 65 6d 2c  rter_MGt1(zStem,
4040: 20 6e 53 74 65 6d 29 3b 0a 7d 0a 0a 2f 2a 20 70   nStem);.}../* p
4050: 6f 72 74 65 72 20 72 75 6c 65 20 63 6f 6e 64 69  orter rule condi
4060: 74 69 6f 6e 3a 20 28 2a 76 2a 29 20 2a 2f 0a 73  tion: (*v*) */.s
4070: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 50 6f  tatic int fts5Po
4080: 72 74 65 72 5f 56 6f 77 65 6c 28 63 68 61 72 20  rter_Vowel(char 
4090: 2a 7a 53 74 65 6d 2c 20 69 6e 74 20 6e 53 74 65  *zStem, int nSte
40a0: 6d 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 66  m){.  int i;.  f
40b0: 6f 72 28 69 3d 30 3b 20 69 3c 6e 53 74 65 6d 3b  or(i=0; i<nStem;
40c0: 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 66   i++){.    if( f
40d0: 74 73 35 50 6f 72 74 65 72 49 73 56 6f 77 65 6c  ts5PorterIsVowel
40e0: 28 7a 53 74 65 6d 5b 69 5d 2c 20 69 3e 30 29 20  (zStem[i], i>0) 
40f0: 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  ){.      return 
4100: 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72  1;.    }.  }.  r
4110: 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 73 74 61 74  eturn 0;.}..stat
4120: 69 63 20 69 6e 74 20 66 74 73 35 50 6f 72 74 65  ic int fts5Porte
4130: 72 43 62 28 0a 20 20 76 6f 69 64 20 2a 70 43 74  rCb(.  void *pCt
4140: 78 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  x, .  const char
4150: 20 2a 70 54 6f 6b 65 6e 2c 20 0a 20 20 69 6e 74   *pToken, .  int
4160: 20 6e 54 6f 6b 65 6e 2c 20 0a 20 20 69 6e 74 20   nToken, .  int 
4170: 69 53 74 61 72 74 2c 20 0a 20 20 69 6e 74 20 69  iStart, .  int i
4180: 45 6e 64 0a 29 7b 0a 20 20 50 6f 72 74 65 72 43  End.){.  PorterC
4190: 6f 6e 74 65 78 74 20 2a 70 20 3d 20 28 50 6f 72  ontext *p = (Por
41a0: 74 65 72 43 6f 6e 74 65 78 74 2a 29 70 43 74 78  terContext*)pCtx
41b0: 3b 0a 0a 20 20 50 6f 72 74 65 72 52 75 6c 65 20  ;..  PorterRule 
41c0: 61 53 74 65 70 31 41 5b 5d 20 3d 20 7b 0a 20 20  aStep1A[] = {.  
41d0: 20 20 7b 20 22 73 73 65 73 22 2c 20 34 2c 20 20    { "sses", 4,  
41e0: 30 2c 20 22 73 73 22 2c 20 32 20 7d 2c 0a 20 20  0, "ss", 2 },.  
41f0: 20 20 7b 20 22 69 65 73 22 2c 20 20 33 2c 20 20    { "ies",  3,  
4200: 30 2c 20 22 69 22 2c 20 20 31 20 20 7d 2c 0a 20  0, "i",  1  },. 
4210: 20 20 20 7b 20 22 73 73 22 2c 20 20 20 32 2c 20     { "ss",   2, 
4220: 20 30 2c 20 22 73 73 22 2c 20 32 20 7d 2c 0a 20   0, "ss", 2 },. 
4230: 20 20 20 7b 20 22 73 22 2c 20 20 20 20 31 2c 20     { "s",    1, 
4240: 20 30 2c 20 22 22 2c 20 20 20 30 20 7d 2c 0a 20   0, "",   0 },. 
4250: 20 20 20 7b 20 30 2c 20 30 2c 20 30 2c 20 30 20     { 0, 0, 0, 0 
4260: 7d 0a 20 20 7d 3b 0a 0a 20 20 50 6f 72 74 65 72  }.  };..  Porter
4270: 52 75 6c 65 20 61 53 74 65 70 31 42 5b 5d 20 3d  Rule aStep1B[] =
4280: 20 7b 0a 20 20 20 20 7b 20 22 65 65 64 22 2c 20   {.    { "eed", 
4290: 33 2c 20 20 66 74 73 35 50 6f 72 74 65 72 5f 4d  3,  fts5Porter_M
42a0: 47 74 30 2c 20 20 22 65 65 22 2c 20 32 20 7d 2c  Gt0,  "ee", 2 },
42b0: 0a 20 20 20 20 7b 20 22 65 64 22 2c 20 20 32 2c  .    { "ed",  2,
42c0: 20 20 66 74 73 35 50 6f 72 74 65 72 5f 56 6f 77    fts5Porter_Vow
42d0: 65 6c 2c 20 22 22 2c 20 20 20 30 20 7d 2c 0a 20  el, "",   0 },. 
42e0: 20 20 20 7b 20 22 69 6e 67 22 2c 20 33 2c 20 20     { "ing", 3,  
42f0: 66 74 73 35 50 6f 72 74 65 72 5f 56 6f 77 65 6c  fts5Porter_Vowel
4300: 2c 20 22 22 2c 20 20 20 30 20 7d 2c 0a 20 20 20  , "",   0 },.   
4310: 20 7b 20 30 2c 20 30 2c 20 30 2c 20 30 20 7d 0a   { 0, 0, 0, 0 }.
4320: 20 20 7d 3b 0a 0a 20 20 50 6f 72 74 65 72 52 75    };..  PorterRu
4330: 6c 65 20 61 53 74 65 70 31 42 32 5b 5d 20 3d 20  le aStep1B2[] = 
4340: 7b 0a 20 20 20 20 7b 20 22 61 74 22 2c 20 32 2c  {.    { "at", 2,
4350: 20 20 30 2c 20 22 61 74 65 22 2c 20 33 20 7d 2c    0, "ate", 3 },
4360: 0a 20 20 20 20 7b 20 22 62 6c 22 2c 20 32 2c 20  .    { "bl", 2, 
4370: 20 30 2c 20 22 62 6c 65 22 2c 20 33 20 7d 2c 0a   0, "ble", 3 },.
4380: 20 20 20 20 7b 20 22 69 7a 22 2c 20 32 2c 20 20      { "iz", 2,  
4390: 30 2c 20 22 69 7a 65 22 2c 20 33 20 7d 2c 0a 20  0, "ize", 3 },. 
43a0: 20 20 20 7b 20 30 2c 20 30 2c 20 30 2c 20 30 20     { 0, 0, 0, 0 
43b0: 7d 0a 20 20 7d 3b 0a 0a 20 20 50 6f 72 74 65 72  }.  };..  Porter
43c0: 52 75 6c 65 20 61 53 74 65 70 31 43 5b 5d 20 3d  Rule aStep1C[] =
43d0: 20 7b 0a 20 20 20 20 7b 20 22 79 22 2c 20 20 31   {.    { "y",  1
43e0: 2c 20 20 66 74 73 35 50 6f 72 74 65 72 5f 56 6f  ,  fts5Porter_Vo
43f0: 77 65 6c 2c 20 22 69 22 2c 20 31 20 7d 2c 0a 20  wel, "i", 1 },. 
4400: 20 20 20 7b 20 30 2c 20 30 2c 20 30 2c 20 30 20     { 0, 0, 0, 0 
4410: 7d 0a 20 20 7d 3b 0a 0a 20 20 50 6f 72 74 65 72  }.  };..  Porter
4420: 52 75 6c 65 20 61 53 74 65 70 32 5b 5d 20 3d 20  Rule aStep2[] = 
4430: 7b 0a 20 20 20 20 7b 20 22 61 74 69 6f 6e 61 6c  {.    { "ational
4440: 22 2c 20 37 2c 20 66 74 73 35 50 6f 72 74 65 72  ", 7, fts5Porter
4450: 5f 4d 47 74 30 2c 20 22 61 74 65 22 2c 20 33 7d  _MGt0, "ate", 3}
4460: 2c 20 0a 20 20 20 20 7b 20 22 74 69 6f 6e 61 6c  , .    { "tional
4470: 22 2c 20 36 2c 20 66 74 73 35 50 6f 72 74 65 72  ", 6, fts5Porter
4480: 5f 4d 47 74 30 2c 20 22 74 69 6f 6e 22 2c 20 34  _MGt0, "tion", 4
4490: 7d 2c 20 0a 20 20 20 20 7b 20 22 65 6e 63 69 22  }, .    { "enci"
44a0: 2c 20 34 2c 20 66 74 73 35 50 6f 72 74 65 72 5f  , 4, fts5Porter_
44b0: 4d 47 74 30 2c 20 22 65 6e 63 65 22 2c 20 34 7d  MGt0, "ence", 4}
44c0: 2c 20 0a 20 20 20 20 7b 20 22 61 6e 63 69 22 2c  , .    { "anci",
44d0: 20 34 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d   4, fts5Porter_M
44e0: 47 74 30 2c 20 22 61 6e 63 65 22 2c 20 34 7d 2c  Gt0, "ance", 4},
44f0: 20 0a 20 20 20 20 7b 20 22 69 7a 65 72 22 2c 20   .    { "izer", 
4500: 34 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47  4, fts5Porter_MG
4510: 74 30 2c 20 22 69 7a 65 22 2c 20 33 7d 2c 20 0a  t0, "ize", 3}, .
4520: 20 20 20 20 7b 20 22 6c 6f 67 69 22 2c 20 34 2c      { "logi", 4,
4530: 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30   fts5Porter_MGt0
4540: 2c 20 22 6c 6f 67 22 2c 20 33 7d 2c 20 20 20 20  , "log", 3},    
4550: 20 2f 2a 20 61 64 64 65 64 20 70 6f 73 74 20 31   /* added post 1
4560: 39 37 39 20 2a 2f 0a 20 20 20 20 7b 20 22 62 6c  979 */.    { "bl
4570: 69 22 2c 20 33 2c 20 66 74 73 35 50 6f 72 74 65  i", 3, fts5Porte
4580: 72 5f 4d 47 74 30 2c 20 22 62 6c 65 22 2c 20 33  r_MGt0, "ble", 3
4590: 7d 2c 20 20 20 20 20 20 2f 2a 20 6d 6f 64 69 66  },      /* modif
45a0: 69 65 64 20 70 6f 73 74 20 31 39 37 39 20 2a 2f  ied post 1979 */
45b0: 0a 20 20 20 20 7b 20 22 61 6c 6c 69 22 2c 20 34  .    { "alli", 4
45c0: 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74  , fts5Porter_MGt
45d0: 30 2c 20 22 61 6c 22 2c 20 32 7d 2c 20 0a 20 20  0, "al", 2}, .  
45e0: 20 20 7b 20 22 65 6e 74 6c 69 22 2c 20 35 2c 20    { "entli", 5, 
45f0: 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c  fts5Porter_MGt0,
4600: 20 22 65 6e 74 22 2c 20 33 7d 2c 20 0a 20 20 20   "ent", 3}, .   
4610: 20 7b 20 22 65 6c 69 22 2c 20 33 2c 20 66 74 73   { "eli", 3, fts
4620: 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c 20 22 65  5Porter_MGt0, "e
4630: 22 2c 20 31 7d 2c 20 0a 20 20 20 20 7b 20 22 6f  ", 1}, .    { "o
4640: 75 73 6c 69 22 2c 20 35 2c 20 66 74 73 35 50 6f  usli", 5, fts5Po
4650: 72 74 65 72 5f 4d 47 74 30 2c 20 22 6f 75 73 22  rter_MGt0, "ous"
4660: 2c 20 33 7d 2c 20 0a 20 20 20 20 7b 20 22 69 7a  , 3}, .    { "iz
4670: 61 74 69 6f 6e 22 2c 20 37 2c 20 66 74 73 35 50  ation", 7, fts5P
4680: 6f 72 74 65 72 5f 4d 47 74 30 2c 20 22 69 7a 65  orter_MGt0, "ize
4690: 22 2c 20 33 7d 2c 20 0a 20 20 20 20 7b 20 22 61  ", 3}, .    { "a
46a0: 74 69 6f 6e 22 2c 20 35 2c 20 66 74 73 35 50 6f  tion", 5, fts5Po
46b0: 72 74 65 72 5f 4d 47 74 30 2c 20 22 61 74 65 22  rter_MGt0, "ate"
46c0: 2c 20 33 7d 2c 20 0a 20 20 20 20 7b 20 22 61 74  , 3}, .    { "at
46d0: 6f 72 22 2c 20 34 2c 20 66 74 73 35 50 6f 72 74  or", 4, fts5Port
46e0: 65 72 5f 4d 47 74 30 2c 20 22 61 74 65 22 2c 20  er_MGt0, "ate", 
46f0: 33 7d 2c 20 0a 20 20 20 20 7b 20 22 61 6c 69 73  3}, .    { "alis
4700: 6d 22 2c 20 35 2c 20 66 74 73 35 50 6f 72 74 65  m", 5, fts5Porte
4710: 72 5f 4d 47 74 30 2c 20 22 61 6c 22 2c 20 32 7d  r_MGt0, "al", 2}
4720: 2c 20 0a 20 20 20 20 7b 20 22 69 76 65 6e 65 73  , .    { "ivenes
4730: 73 22 2c 20 37 2c 20 66 74 73 35 50 6f 72 74 65  s", 7, fts5Porte
4740: 72 5f 4d 47 74 30 2c 20 22 69 76 65 22 2c 20 33  r_MGt0, "ive", 3
4750: 7d 2c 20 0a 20 20 20 20 7b 20 22 66 75 6c 6e 65  }, .    { "fulne
4760: 73 73 22 2c 20 37 2c 20 66 74 73 35 50 6f 72 74  ss", 7, fts5Port
4770: 65 72 5f 4d 47 74 30 2c 20 22 66 75 6c 22 2c 20  er_MGt0, "ful", 
4780: 33 7d 2c 20 0a 20 20 20 20 7b 20 22 6f 75 73 6e  3}, .    { "ousn
4790: 65 73 73 22 2c 20 37 2c 20 66 74 73 35 50 6f 72  ess", 7, fts5Por
47a0: 74 65 72 5f 4d 47 74 30 2c 20 22 6f 75 73 22 2c  ter_MGt0, "ous",
47b0: 20 33 7d 2c 20 0a 20 20 20 20 7b 20 22 61 6c 69   3}, .    { "ali
47c0: 74 69 22 2c 20 35 2c 20 66 74 73 35 50 6f 72 74  ti", 5, fts5Port
47d0: 65 72 5f 4d 47 74 30 2c 20 22 61 6c 22 2c 20 32  er_MGt0, "al", 2
47e0: 7d 2c 20 0a 20 20 20 20 7b 20 22 69 76 69 74 69  }, .    { "iviti
47f0: 22 2c 20 35 2c 20 66 74 73 35 50 6f 72 74 65 72  ", 5, fts5Porter
4800: 5f 4d 47 74 30 2c 20 22 69 76 65 22 2c 20 33 7d  _MGt0, "ive", 3}
4810: 2c 20 0a 20 20 20 20 7b 20 22 62 69 6c 69 74 69  , .    { "biliti
4820: 22 2c 20 36 2c 20 66 74 73 35 50 6f 72 74 65 72  ", 6, fts5Porter
4830: 5f 4d 47 74 30 2c 20 22 62 6c 65 22 2c 20 33 7d  _MGt0, "ble", 3}
4840: 2c 20 0a 20 20 20 20 7b 20 30 2c 20 30 2c 20 30  , .    { 0, 0, 0
4850: 2c 20 30 20 7d 0a 20 20 7d 3b 0a 0a 20 20 50 6f  , 0 }.  };..  Po
4860: 72 74 65 72 52 75 6c 65 20 61 53 74 65 70 33 5b  rterRule aStep3[
4870: 5d 20 3d 20 7b 0a 20 20 20 20 7b 20 22 69 63 61  ] = {.    { "ica
4880: 74 65 22 2c 20 35 2c 20 66 74 73 35 50 6f 72 74  te", 5, fts5Port
4890: 65 72 5f 4d 47 74 30 2c 20 22 69 63 22 2c 20 32  er_MGt0, "ic", 2
48a0: 7d 2c 20 0a 20 20 20 20 7b 20 22 61 74 69 76 65  }, .    { "ative
48b0: 22 2c 20 35 2c 20 66 74 73 35 50 6f 72 74 65 72  ", 5, fts5Porter
48c0: 5f 4d 47 74 30 2c 20 22 22 2c 20 30 7d 2c 20 0a  _MGt0, "", 0}, .
48d0: 20 20 20 20 7b 20 22 61 6c 69 7a 65 22 2c 20 35      { "alize", 5
48e0: 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74  , fts5Porter_MGt
48f0: 30 2c 20 22 61 6c 22 2c 20 32 7d 2c 20 0a 20 20  0, "al", 2}, .  
4900: 20 20 7b 20 22 69 63 69 74 69 22 2c 20 35 2c 20    { "iciti", 5, 
4910: 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c  fts5Porter_MGt0,
4920: 20 22 69 63 22 2c 20 32 7d 2c 20 0a 20 20 20 20   "ic", 2}, .    
4930: 7b 20 22 69 63 61 6c 22 2c 20 34 2c 20 66 74 73  { "ical", 4, fts
4940: 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c 20 22 69  5Porter_MGt0, "i
4950: 63 22 2c 20 32 7d 2c 20 0a 20 20 20 20 7b 20 22  c", 2}, .    { "
4960: 66 75 6c 22 2c 20 33 2c 20 66 74 73 35 50 6f 72  ful", 3, fts5Por
4970: 74 65 72 5f 4d 47 74 30 2c 20 22 22 2c 20 30 7d  ter_MGt0, "", 0}
4980: 2c 20 0a 20 20 20 20 7b 20 22 6e 65 73 73 22 2c  , .    { "ness",
4990: 20 34 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d   4, fts5Porter_M
49a0: 47 74 30 2c 20 22 22 2c 20 30 7d 2c 20 0a 20 20  Gt0, "", 0}, .  
49b0: 20 20 7b 20 30 2c 20 30 2c 20 30 2c 20 30 20 7d    { 0, 0, 0, 0 }
49c0: 0a 20 20 7d 3b 0a 0a 20 20 50 6f 72 74 65 72 52  .  };..  PorterR
49d0: 75 6c 65 20 61 53 74 65 70 34 5b 5d 20 3d 20 7b  ule aStep4[] = {
49e0: 0a 20 20 20 20 7b 20 22 61 6c 22 2c 20 32 2c 20  .    { "al", 2, 
49f0: 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 2c  fts5Porter_MGt1,
4a00: 20 22 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b 20   "", 0}, .    { 
4a10: 22 61 6e 63 65 22 2c 20 34 2c 20 66 74 73 35 50  "ance", 4, fts5P
4a20: 6f 72 74 65 72 5f 4d 47 74 31 2c 20 22 22 2c 20  orter_MGt1, "", 
4a30: 30 7d 2c 20 0a 20 20 20 20 7b 20 22 65 6e 63 65  0}, .    { "ence
4a40: 22 2c 20 34 2c 20 66 74 73 35 50 6f 72 74 65 72  ", 4, fts5Porter
4a50: 5f 4d 47 74 31 2c 20 22 22 2c 20 30 7d 2c 20 0a  _MGt1, "", 0}, .
4a60: 20 20 20 20 7b 20 22 65 72 22 2c 20 32 2c 20 66      { "er", 2, f
4a70: 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 2c 20  ts5Porter_MGt1, 
4a80: 22 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b 20 22  "", 0}, .    { "
4a90: 69 63 22 2c 20 32 2c 20 66 74 73 35 50 6f 72 74  ic", 2, fts5Port
4aa0: 65 72 5f 4d 47 74 31 2c 20 22 22 2c 20 30 7d 2c  er_MGt1, "", 0},
4ab0: 20 0a 20 20 20 20 7b 20 22 61 62 6c 65 22 2c 20   .    { "able", 
4ac0: 34 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47  4, fts5Porter_MG
4ad0: 74 31 2c 20 22 22 2c 20 30 7d 2c 20 0a 20 20 20  t1, "", 0}, .   
4ae0: 20 7b 20 22 69 62 6c 65 22 2c 20 34 2c 20 66 74   { "ible", 4, ft
4af0: 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 2c 20 22  s5Porter_MGt1, "
4b00: 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b 20 22 61  ", 0}, .    { "a
4b10: 6e 74 22 2c 20 33 2c 20 66 74 73 35 50 6f 72 74  nt", 3, fts5Port
4b20: 65 72 5f 4d 47 74 31 2c 20 22 22 2c 20 30 7d 2c  er_MGt1, "", 0},
4b30: 20 0a 20 20 20 20 7b 20 22 65 6d 65 6e 74 22 2c   .    { "ement",
4b40: 20 35 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d   5, fts5Porter_M
4b50: 47 74 31 2c 20 22 22 2c 20 30 7d 2c 20 0a 20 20  Gt1, "", 0}, .  
4b60: 20 20 7b 20 22 6d 65 6e 74 22 2c 20 34 2c 20 66    { "ment", 4, f
4b70: 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 2c 20  ts5Porter_MGt1, 
4b80: 22 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b 20 22  "", 0}, .    { "
4b90: 65 6e 74 22 2c 20 33 2c 20 66 74 73 35 50 6f 72  ent", 3, fts5Por
4ba0: 74 65 72 5f 4d 47 74 31 2c 20 22 22 2c 20 30 7d  ter_MGt1, "", 0}
4bb0: 2c 20 0a 20 20 20 20 7b 20 22 69 6f 6e 22 2c 20  , .    { "ion", 
4bc0: 33 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47  3, fts5Porter_MG
4bd0: 74 31 5f 61 6e 64 5f 53 5f 6f 72 5f 54 2c 20 22  t1_and_S_or_T, "
4be0: 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b 20 22 6f  ", 0}, .    { "o
4bf0: 75 22 2c 20 32 2c 20 66 74 73 35 50 6f 72 74 65  u", 2, fts5Porte
4c00: 72 5f 4d 47 74 31 2c 20 22 22 2c 20 30 7d 2c 20  r_MGt1, "", 0}, 
4c10: 0a 20 20 20 20 7b 20 22 69 73 6d 22 2c 20 33 2c  .    { "ism", 3,
4c20: 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31   fts5Porter_MGt1
4c30: 2c 20 22 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b  , "", 0}, .    {
4c40: 20 22 61 74 65 22 2c 20 33 2c 20 66 74 73 35 50   "ate", 3, fts5P
4c50: 6f 72 74 65 72 5f 4d 47 74 31 2c 20 22 22 2c 20  orter_MGt1, "", 
4c60: 30 7d 2c 20 0a 20 20 20 20 7b 20 22 69 74 69 22  0}, .    { "iti"
4c70: 2c 20 33 2c 20 66 74 73 35 50 6f 72 74 65 72 5f  , 3, fts5Porter_
4c80: 4d 47 74 31 2c 20 22 22 2c 20 30 7d 2c 20 0a 20  MGt1, "", 0}, . 
4c90: 20 20 20 7b 20 22 6f 75 73 22 2c 20 33 2c 20 66     { "ous", 3, f
4ca0: 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 2c 20  ts5Porter_MGt1, 
4cb0: 22 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b 20 22  "", 0}, .    { "
4cc0: 69 76 65 22 2c 20 33 2c 20 66 74 73 35 50 6f 72  ive", 3, fts5Por
4cd0: 74 65 72 5f 4d 47 74 31 2c 20 22 22 2c 20 30 7d  ter_MGt1, "", 0}
4ce0: 2c 20 0a 20 20 20 20 7b 20 22 69 7a 65 22 2c 20  , .    { "ize", 
4cf0: 33 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47  3, fts5Porter_MG
4d00: 74 31 2c 20 22 22 2c 20 30 7d 2c 20 0a 20 20 20  t1, "", 0}, .   
4d10: 20 7b 20 30 2c 20 30 2c 20 30 2c 20 30 20 7d 0a   { 0, 0, 0, 0 }.
4d20: 20 20 7d 3b 0a 0a 0a 20 20 63 68 61 72 20 2a 61    };...  char *a
4d30: 42 75 66 3b 0a 20 20 69 6e 74 20 6e 42 75 66 3b  Buf;.  int nBuf;
4d40: 0a 20 20 69 6e 74 20 6e 3b 0a 0a 20 20 69 66 28  .  int n;..  if(
4d50: 20 6e 54 6f 6b 65 6e 3e 46 54 53 35 5f 50 4f 52   nToken>FTS5_POR
4d60: 54 45 52 5f 4d 41 58 5f 54 4f 4b 45 4e 20 7c 7c  TER_MAX_TOKEN ||
4d70: 20 6e 54 6f 6b 65 6e 3c 33 20 29 20 67 6f 74 6f   nToken<3 ) goto
4d80: 20 70 61 73 73 5f 74 68 72 6f 75 67 68 3b 0a 20   pass_through;. 
4d90: 20 61 42 75 66 20 3d 20 70 2d 3e 61 42 75 66 3b   aBuf = p->aBuf;
4da0: 0a 20 20 6e 42 75 66 20 3d 20 6e 54 6f 6b 65 6e  .  nBuf = nToken
4db0: 3b 0a 20 20 6d 65 6d 63 70 79 28 61 42 75 66 2c  ;.  memcpy(aBuf,
4dc0: 20 70 54 6f 6b 65 6e 2c 20 6e 42 75 66 29 3b 0a   pToken, nBuf);.
4dd0: 0a 20 20 2f 2a 20 53 74 65 70 20 31 2e 20 2a 2f  .  /* Step 1. */
4de0: 0a 20 20 66 74 73 35 50 6f 72 74 65 72 41 70 70  .  fts5PorterApp
4df0: 6c 79 28 61 42 75 66 2c 20 26 6e 42 75 66 2c 20  ly(aBuf, &nBuf, 
4e00: 61 53 74 65 70 31 41 29 3b 0a 20 20 6e 20 3d 20  aStep1A);.  n = 
4e10: 66 74 73 35 50 6f 72 74 65 72 41 70 70 6c 79 28  fts5PorterApply(
4e20: 61 42 75 66 2c 20 26 6e 42 75 66 2c 20 61 53 74  aBuf, &nBuf, aSt
4e30: 65 70 31 42 29 3b 0a 20 20 69 66 28 20 6e 3d 3d  ep1B);.  if( n==
4e40: 31 20 7c 7c 20 6e 3d 3d 32 20 29 7b 0a 20 20 20  1 || n==2 ){.   
4e50: 20 69 66 28 20 66 74 73 35 50 6f 72 74 65 72 41   if( fts5PorterA
4e60: 70 70 6c 79 28 61 42 75 66 2c 20 26 6e 42 75 66  pply(aBuf, &nBuf
4e70: 2c 20 61 53 74 65 70 31 42 32 29 3c 30 20 29 7b  , aStep1B2)<0 ){
4e80: 0a 20 20 20 20 20 20 63 68 61 72 20 63 20 3d 20  .      char c = 
4e90: 61 42 75 66 5b 6e 42 75 66 2d 31 5d 3b 0a 20 20  aBuf[nBuf-1];.  
4ea0: 20 20 20 20 69 66 28 20 66 74 73 35 50 6f 72 74      if( fts5Port
4eb0: 65 72 49 73 56 6f 77 65 6c 28 63 2c 20 30 29 3d  erIsVowel(c, 0)=
4ec0: 3d 30 20 0a 20 20 20 20 20 20 20 26 26 20 63 21  =0 .       && c!
4ed0: 3d 27 6c 27 20 26 26 20 63 21 3d 27 73 27 20 26  ='l' && c!='s' &
4ee0: 26 20 63 21 3d 27 7a 27 20 26 26 20 63 3d 3d 61  & c!='z' && c==a
4ef0: 42 75 66 5b 6e 42 75 66 2d 32 5d 20 0a 20 20 20  Buf[nBuf-2] .   
4f00: 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20 6e 42     ){.        nB
4f10: 75 66 2d 2d 3b 0a 20 20 20 20 20 20 7d 65 6c 73  uf--;.      }els
4f20: 65 20 69 66 28 20 66 74 73 35 50 6f 72 74 65 72  e if( fts5Porter
4f30: 5f 4d 45 71 31 28 61 42 75 66 2c 20 6e 42 75 66  _MEq1(aBuf, nBuf
4f40: 29 20 26 26 20 66 74 73 35 50 6f 72 74 65 72 5f  ) && fts5Porter_
4f50: 4f 73 74 61 72 28 61 42 75 66 2c 20 6e 42 75 66  Ostar(aBuf, nBuf
4f60: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 61 42 75  ) ){.        aBu
4f70: 66 5b 6e 42 75 66 2b 2b 5d 20 3d 20 27 65 27 3b  f[nBuf++] = 'e';
4f80: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
4f90: 20 7d 0a 20 20 66 74 73 35 50 6f 72 74 65 72 41   }.  fts5PorterA
4fa0: 70 70 6c 79 28 61 42 75 66 2c 20 26 6e 42 75 66  pply(aBuf, &nBuf
4fb0: 2c 20 61 53 74 65 70 31 43 29 3b 0a 0a 20 20 2f  , aStep1C);..  /
4fc0: 2a 20 53 74 65 70 73 20 32 20 74 68 72 6f 75 67  * Steps 2 throug
4fd0: 68 20 34 2e 20 2a 2f 0a 20 20 66 74 73 35 50 6f  h 4. */.  fts5Po
4fe0: 72 74 65 72 41 70 70 6c 79 28 61 42 75 66 2c 20  rterApply(aBuf, 
4ff0: 26 6e 42 75 66 2c 20 61 53 74 65 70 32 29 3b 0a  &nBuf, aStep2);.
5000: 20 20 66 74 73 35 50 6f 72 74 65 72 41 70 70 6c    fts5PorterAppl
5010: 79 28 61 42 75 66 2c 20 26 6e 42 75 66 2c 20 61  y(aBuf, &nBuf, a
5020: 53 74 65 70 33 29 3b 0a 20 20 66 74 73 35 50 6f  Step3);.  fts5Po
5030: 72 74 65 72 41 70 70 6c 79 28 61 42 75 66 2c 20  rterApply(aBuf, 
5040: 26 6e 42 75 66 2c 20 61 53 74 65 70 34 29 3b 0a  &nBuf, aStep4);.
5050: 0a 20 20 2f 2a 20 53 74 65 70 20 35 61 2e 20 2a  .  /* Step 5a. *
5060: 2f 0a 20 20 69 66 28 20 6e 42 75 66 3e 30 20 26  /.  if( nBuf>0 &
5070: 26 20 61 42 75 66 5b 6e 42 75 66 2d 31 5d 3d 3d  & aBuf[nBuf-1]==
5080: 27 65 27 20 29 7b 0a 20 20 20 20 69 66 28 20 66  'e' ){.    if( f
5090: 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 28 61  ts5Porter_MGt1(a
50a0: 42 75 66 2c 20 6e 42 75 66 2d 31 29 20 0a 20 20  Buf, nBuf-1) .  
50b0: 20 20 20 7c 7c 20 28 66 74 73 35 50 6f 72 74 65     || (fts5Porte
50c0: 72 5f 4d 45 71 31 28 61 42 75 66 2c 20 6e 42 75  r_MEq1(aBuf, nBu
50d0: 66 2d 31 29 20 26 26 20 21 66 74 73 35 50 6f 72  f-1) && !fts5Por
50e0: 74 65 72 5f 4f 73 74 61 72 28 61 42 75 66 2c 20  ter_Ostar(aBuf, 
50f0: 6e 42 75 66 2d 31 29 29 0a 20 20 20 20 29 7b 0a  nBuf-1)).    ){.
5100: 20 20 20 20 20 20 6e 42 75 66 2d 2d 3b 0a 20 20        nBuf--;.  
5110: 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 74    }.  }..  /* St
5120: 65 70 20 35 62 2e 20 2a 2f 0a 20 20 69 66 28 20  ep 5b. */.  if( 
5130: 6e 42 75 66 3e 31 20 26 26 20 61 42 75 66 5b 6e  nBuf>1 && aBuf[n
5140: 42 75 66 2d 31 5d 3d 3d 27 6c 27 20 0a 20 20 20  Buf-1]=='l' .   
5150: 26 26 20 61 42 75 66 5b 6e 42 75 66 2d 32 5d 3d  && aBuf[nBuf-2]=
5160: 3d 27 6c 27 20 26 26 20 66 74 73 35 50 6f 72 74  ='l' && fts5Port
5170: 65 72 5f 4d 47 74 31 28 61 42 75 66 2c 20 6e 42  er_MGt1(aBuf, nB
5180: 75 66 2d 31 29 20 0a 20 20 29 7b 0a 20 20 20 20  uf-1) .  ){.    
5190: 6e 42 75 66 2d 2d 3b 0a 20 20 7d 0a 0a 20 20 72  nBuf--;.  }..  r
51a0: 65 74 75 72 6e 20 70 2d 3e 78 54 6f 6b 65 6e 28  eturn p->xToken(
51b0: 70 2d 3e 70 43 74 78 2c 20 61 42 75 66 2c 20 6e  p->pCtx, aBuf, n
51c0: 42 75 66 2c 20 69 53 74 61 72 74 2c 20 69 45 6e  Buf, iStart, iEn
51d0: 64 29 3b 0a 0a 20 70 61 73 73 5f 74 68 72 6f 75  d);.. pass_throu
51e0: 67 68 3a 0a 20 20 72 65 74 75 72 6e 20 70 2d 3e  gh:.  return p->
51f0: 78 54 6f 6b 65 6e 28 70 2d 3e 70 43 74 78 2c 20  xToken(p->pCtx, 
5200: 70 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 2c 20  pToken, nToken, 
5210: 69 53 74 61 72 74 2c 20 69 45 6e 64 29 3b 0a 7d  iStart, iEnd);.}
5220: 0a 0a 2f 2a 0a 2a 2a 20 54 6f 6b 65 6e 69 7a 65  ../*.** Tokenize
5230: 20 75 73 69 6e 67 20 74 68 65 20 70 6f 72 74 65   using the porte
5240: 72 20 74 6f 6b 65 6e 69 7a 65 72 2e 0a 2a 2f 0a  r tokenizer..*/.
5250: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 50  static int fts5P
5260: 6f 72 74 65 72 54 6f 6b 65 6e 69 7a 65 28 0a 20  orterTokenize(. 
5270: 20 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72 20 2a   Fts5Tokenizer *
5280: 70 54 6f 6b 65 6e 69 7a 65 72 2c 0a 20 20 76 6f  pTokenizer,.  vo
5290: 69 64 20 2a 70 43 74 78 2c 0a 20 20 63 6f 6e 73  id *pCtx,.  cons
52a0: 74 20 63 68 61 72 20 2a 70 54 65 78 74 2c 20 69  t char *pText, i
52b0: 6e 74 20 6e 54 65 78 74 2c 0a 20 20 69 6e 74 20  nt nText,.  int 
52c0: 28 2a 78 54 6f 6b 65 6e 29 28 76 6f 69 64 2a 2c  (*xToken)(void*,
52d0: 20 63 6f 6e 73 74 20 63 68 61 72 2a 2c 20 69 6e   const char*, in
52e0: 74 20 6e 54 6f 6b 65 6e 2c 20 69 6e 74 20 69 53  t nToken, int iS
52f0: 74 61 72 74 2c 20 69 6e 74 20 69 45 6e 64 29 0a  tart, int iEnd).
5300: 29 7b 0a 20 20 50 6f 72 74 65 72 54 6f 6b 65 6e  ){.  PorterToken
5310: 69 7a 65 72 20 2a 70 20 3d 20 28 50 6f 72 74 65  izer *p = (Porte
5320: 72 54 6f 6b 65 6e 69 7a 65 72 2a 29 70 54 6f 6b  rTokenizer*)pTok
5330: 65 6e 69 7a 65 72 3b 0a 20 20 50 6f 72 74 65 72  enizer;.  Porter
5340: 43 6f 6e 74 65 78 74 20 73 43 74 78 3b 0a 20 20  Context sCtx;.  
5350: 73 43 74 78 2e 78 54 6f 6b 65 6e 20 3d 20 78 54  sCtx.xToken = xT
5360: 6f 6b 65 6e 3b 0a 20 20 73 43 74 78 2e 70 43 74  oken;.  sCtx.pCt
5370: 78 20 3d 20 70 43 74 78 3b 0a 20 20 73 43 74 78  x = pCtx;.  sCtx
5380: 2e 61 42 75 66 20 3d 20 70 2d 3e 61 42 75 66 3b  .aBuf = p->aBuf;
5390: 0a 20 20 72 65 74 75 72 6e 20 70 2d 3e 74 6f 6b  .  return p->tok
53a0: 65 6e 69 7a 65 72 2e 78 54 6f 6b 65 6e 69 7a 65  enizer.xTokenize
53b0: 28 0a 20 20 20 20 20 20 70 2d 3e 70 54 6f 6b 65  (.      p->pToke
53c0: 6e 69 7a 65 72 2c 20 28 76 6f 69 64 2a 29 26 73  nizer, (void*)&s
53d0: 43 74 78 2c 20 70 54 65 78 74 2c 20 6e 54 65 78  Ctx, pText, nTex
53e0: 74 2c 20 66 74 73 35 50 6f 72 74 65 72 43 62 0a  t, fts5PorterCb.
53f0: 20 20 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65    );.}../*.** Re
5400: 67 69 73 74 65 72 20 61 6c 6c 20 62 75 69 6c 74  gister all built
5410: 2d 69 6e 20 74 6f 6b 65 6e 69 7a 65 72 73 20 77  -in tokenizers w
5420: 69 74 68 20 46 54 53 35 2e 0a 2a 2f 0a 69 6e 74  ith FTS5..*/.int
5430: 20 73 71 6c 69 74 65 33 46 74 73 35 54 6f 6b 65   sqlite3Fts5Toke
5440: 6e 69 7a 65 72 49 6e 69 74 28 66 74 73 35 5f 61  nizerInit(fts5_a
5450: 70 69 20 2a 70 41 70 69 29 7b 0a 20 20 73 74 72  pi *pApi){.  str
5460: 75 63 74 20 42 75 69 6c 74 69 6e 54 6f 6b 65 6e  uct BuiltinToken
5470: 69 7a 65 72 20 7b 0a 20 20 20 20 63 6f 6e 73 74  izer {.    const
5480: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20   char *zName;.  
5490: 20 20 66 74 73 35 5f 74 6f 6b 65 6e 69 7a 65 72    fts5_tokenizer
54a0: 20 78 3b 0a 20 20 7d 20 61 42 75 69 6c 74 69 6e   x;.  } aBuiltin
54b0: 5b 5d 20 3d 20 7b 0a 20 20 20 20 7b 20 22 70 6f  [] = {.    { "po
54c0: 72 74 65 72 22 2c 20 20 20 20 7b 66 74 73 35 50  rter",    {fts5P
54d0: 6f 72 74 65 72 43 72 65 61 74 65 2c 20 66 74 73  orterCreate, fts
54e0: 35 50 6f 72 74 65 72 44 65 6c 65 74 65 2c 20 66  5PorterDelete, f
54f0: 74 73 35 50 6f 72 74 65 72 54 6f 6b 65 6e 69 7a  ts5PorterTokeniz
5500: 65 20 7d 7d 2c 0a 20 20 20 20 7b 20 22 75 6e 69  e }},.    { "uni
5510: 63 6f 64 65 36 31 22 2c 20 7b 66 74 73 35 55 6e  code61", {fts5Un
5520: 69 63 6f 64 65 43 72 65 61 74 65 2c 20 66 74 73  icodeCreate, fts
5530: 35 55 6e 69 63 6f 64 65 44 65 6c 65 74 65 2c 20  5UnicodeDelete, 
5540: 66 74 73 35 55 6e 69 63 6f 64 65 54 6f 6b 65 6e  fts5UnicodeToken
5550: 69 7a 65 7d 7d 2c 0a 20 20 20 20 7b 20 22 73 69  ize}},.    { "si
5560: 6d 70 6c 65 22 2c 20 20 20 20 7b 66 74 73 35 53  mple",    {fts5S
5570: 69 6d 70 6c 65 43 72 65 61 74 65 2c 20 66 74 73  impleCreate, fts
5580: 35 53 69 6d 70 6c 65 44 65 6c 65 74 65 2c 20 66  5SimpleDelete, f
5590: 74 73 35 53 69 6d 70 6c 65 54 6f 6b 65 6e 69 7a  ts5SimpleTokeniz
55a0: 65 20 7d 7d 0a 20 20 7d 3b 0a 20 20 0a 20 20 69  e }}.  };.  .  i
55b0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
55c0: 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  K;             /
55d0: 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f  * Return code */
55e0: 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20  .  int i;       
55f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5600: 20 20 20 2f 2a 20 54 6f 20 69 74 65 72 61 74 65     /* To iterate
5610: 20 74 68 72 6f 75 67 68 20 62 75 69 6c 74 69 6e   through builtin
5620: 20 66 75 6e 63 74 69 6f 6e 73 20 2a 2f 0a 0a 20   functions */.. 
5630: 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51   for(i=0; rc==SQ
5640: 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 73 69 7a  LITE_OK && i<siz
5650: 65 6f 66 28 61 42 75 69 6c 74 69 6e 29 2f 73 69  eof(aBuiltin)/si
5660: 7a 65 6f 66 28 61 42 75 69 6c 74 69 6e 5b 30 5d  zeof(aBuiltin[0]
5670: 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 72 63 20  ); i++){.    rc 
5680: 3d 20 70 41 70 69 2d 3e 78 43 72 65 61 74 65 54  = pApi->xCreateT
5690: 6f 6b 65 6e 69 7a 65 72 28 70 41 70 69 2c 0a 20  okenizer(pApi,. 
56a0: 20 20 20 20 20 20 20 61 42 75 69 6c 74 69 6e 5b         aBuiltin[
56b0: 69 5d 2e 7a 4e 61 6d 65 2c 0a 20 20 20 20 20 20  i].zName,.      
56c0: 20 20 28 76 6f 69 64 2a 29 70 41 70 69 2c 0a 20    (void*)pApi,. 
56d0: 20 20 20 20 20 20 20 26 61 42 75 69 6c 74 69 6e         &aBuiltin
56e0: 5b 69 5d 2e 78 2c 0a 20 20 20 20 20 20 20 20 30  [i].x,.        0
56f0: 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 0a 20 20 72  .    );.  }..  r
5700: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
5710: 0a 7d 0a 0a 0a                                   .}...