/ Hex Artifact Content
Login

Artifact 5d6e785345b0d87d174fcc0653bfacd0d9fd7f2e:


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 0a 2f 2a 0a 2a 2a 20 43 72 65 61  .h>.../*.** Crea
01c0: 74 65 20 61 20 22 73 69 6d 70 6c 65 22 20 74 6f  te a "simple" to
01d0: 6b 65 6e 69 7a 65 72 2e 0a 2a 2f 0a 73 74 61 74  kenizer..*/.stat
01e0: 69 63 20 69 6e 74 20 66 74 73 35 53 69 6d 70 6c  ic int fts5Simpl
01f0: 65 43 72 65 61 74 65 28 0a 20 20 76 6f 69 64 20  eCreate(.  void 
0200: 2a 70 43 74 78 2c 20 0a 20 20 63 6f 6e 73 74 20  *pCtx, .  const 
0210: 63 68 61 72 20 2a 2a 61 7a 41 72 67 2c 20 69 6e  char **azArg, in
0220: 74 20 6e 41 72 67 2c 0a 20 20 46 74 73 35 54 6f  t nArg,.  Fts5To
0230: 6b 65 6e 69 7a 65 72 20 2a 2a 70 70 4f 75 74 0a  kenizer **ppOut.
0240: 29 7b 0a 20 20 2a 70 70 4f 75 74 20 3d 20 30 3b  ){.  *ppOut = 0;
0250: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
0260: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65  _OK;.}../*.** De
0270: 6c 65 74 65 20 61 20 22 73 69 6d 70 6c 65 22 20  lete a "simple" 
0280: 74 6f 6b 65 6e 69 7a 65 72 2e 0a 2a 2f 0a 73 74  tokenizer..*/.st
0290: 61 74 69 63 20 76 6f 69 64 20 66 74 73 35 53 69  atic void fts5Si
02a0: 6d 70 6c 65 44 65 6c 65 74 65 28 46 74 73 35 54  mpleDelete(Fts5T
02b0: 6f 6b 65 6e 69 7a 65 72 20 2a 70 29 7b 0a 20 20  okenizer *p){.  
02c0: 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  return;.}../*.**
02d0: 20 46 6f 72 20 74 6f 6b 65 6e 69 7a 65 72 73 20   For tokenizers 
02e0: 77 69 74 68 20 6e 6f 20 22 75 6e 69 63 6f 64 65  with no "unicode
02f0: 22 20 6d 6f 64 69 66 69 65 72 2c 20 74 68 65 20  " modifier, the 
0300: 73 65 74 20 6f 66 20 74 6f 6b 65 6e 20 63 68 61  set of token cha
0310: 72 61 63 74 65 72 73 0a 2a 2a 20 69 73 20 74 68  racters.** is th
0320: 65 20 73 61 6d 65 20 61 73 20 74 68 65 20 73 65  e same as the se
0330: 74 20 6f 66 20 41 53 43 49 49 20 72 61 6e 67 65  t of ASCII range
0340: 20 61 6c 70 68 61 6e 75 6d 65 72 69 63 20 63 68   alphanumeric ch
0350: 61 72 61 63 74 65 72 73 2e 20 0a 2a 2f 0a 73 74  aracters. .*/.st
0360: 61 74 69 63 20 75 6e 73 69 67 6e 65 64 20 63 68  atic unsigned ch
0370: 61 72 20 61 53 69 6d 70 6c 65 54 6f 6b 65 6e 43  ar aSimpleTokenC
0380: 68 61 72 5b 31 32 38 5d 20 3d 20 7b 0a 20 20 30  har[128] = {.  0
0390: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c  , 0, 0, 0, 0, 0,
03a0: 20 30 2c 20 30 2c 20 20 20 30 2c 20 30 2c 20 30   0, 0,   0, 0, 0
03b0: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c  , 0, 0, 0, 0, 0,
03c0: 20 20 20 2f 2a 20 30 78 30 30 2e 2e 30 78 30 46     /* 0x00..0x0F
03d0: 20 2a 2f 0a 20 20 30 2c 20 30 2c 20 30 2c 20 30   */.  0, 0, 0, 0
03e0: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20 20  , 0, 0, 0, 0,   
03f0: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30  0, 0, 0, 0, 0, 0
0400: 2c 20 30 2c 20 30 2c 20 20 20 2f 2a 20 30 78 31  , 0, 0,   /* 0x1
0410: 30 2e 2e 30 78 31 46 20 2a 2f 0a 20 20 30 2c 20  0..0x1F */.  0, 
0420: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30  0, 0, 0, 0, 0, 0
0430: 2c 20 30 2c 20 20 20 30 2c 20 30 2c 20 30 2c 20  , 0,   0, 0, 0, 
0440: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20  0, 0, 0, 0, 0,  
0450: 20 2f 2a 20 30 78 32 30 2e 2e 30 78 32 46 20 2a   /* 0x20..0x2F *
0460: 2f 0a 20 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20  /.  1, 1, 1, 1, 
0470: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 20 20 31 2c  1, 1, 1, 1,   1,
0480: 20 31 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20   1, 0, 0, 0, 0, 
0490: 30 2c 20 30 2c 20 20 20 2f 2a 20 30 78 33 30 2e  0, 0,   /* 0x30.
04a0: 2e 30 78 33 46 20 2a 2f 0a 20 20 30 2c 20 31 2c  .0x3F */.  0, 1,
04b0: 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20   1, 1, 1, 1, 1, 
04c0: 31 2c 20 20 20 31 2c 20 31 2c 20 31 2c 20 31 2c  1,   1, 1, 1, 1,
04d0: 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 20 20 2f   1, 1, 1, 1,   /
04e0: 2a 20 30 78 34 30 2e 2e 30 78 34 46 20 2a 2f 0a  * 0x40..0x4F */.
04f0: 20 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c    1, 1, 1, 1, 1,
0500: 20 31 2c 20 31 2c 20 31 2c 20 20 20 31 2c 20 31   1, 1, 1,   1, 1
0510: 2c 20 31 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c  , 1, 0, 0, 0, 0,
0520: 20 30 2c 20 20 20 2f 2a 20 30 78 35 30 2e 2e 30   0,   /* 0x50..0
0530: 78 35 46 20 2a 2f 0a 20 20 30 2c 20 31 2c 20 31  x5F */.  0, 1, 1
0540: 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c  , 1, 1, 1, 1, 1,
0550: 20 20 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31     1, 1, 1, 1, 1
0560: 2c 20 31 2c 20 31 2c 20 31 2c 20 20 20 2f 2a 20  , 1, 1, 1,   /* 
0570: 30 78 36 30 2e 2e 30 78 36 46 20 2a 2f 0a 20 20  0x60..0x6F */.  
0580: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
0590: 2c 20 31 2c 20 31 2c 20 20 20 31 2c 20 31 2c 20  , 1, 1,   1, 1, 
05a0: 31 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30  1, 0, 0, 0, 0, 0
05b0: 2c 20 20 20 2f 2a 20 30 78 37 30 2e 2e 30 78 37  ,   /* 0x70..0x7
05c0: 46 20 2a 2f 0a 7d 3b 0a 0a 0a 73 74 61 74 69 63  F */.};...static
05d0: 20 76 6f 69 64 20 73 69 6d 70 6c 65 46 6f 6c 64   void simpleFold
05e0: 28 63 68 61 72 20 2a 61 4f 75 74 2c 20 63 6f 6e  (char *aOut, con
05f0: 73 74 20 63 68 61 72 20 2a 61 49 6e 2c 20 69 6e  st char *aIn, in
0600: 74 20 6e 42 79 74 65 29 7b 0a 20 20 69 6e 74 20  t nByte){.  int 
0610: 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  i;.  for(i=0; i<
0620: 6e 42 79 74 65 3b 20 69 2b 2b 29 7b 0a 20 20 20  nByte; i++){.   
0630: 20 63 68 61 72 20 63 20 3d 20 61 49 6e 5b 69 5d   char c = aIn[i]
0640: 3b 0a 20 20 20 20 69 66 28 20 63 3e 3d 27 41 27  ;.    if( c>='A'
0650: 20 26 26 20 63 3c 3d 27 5a 27 20 29 20 63 20 2b   && c<='Z' ) c +
0660: 3d 20 33 32 3b 0a 20 20 20 20 61 4f 75 74 5b 69  = 32;.    aOut[i
0670: 5d 20 3d 20 63 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  ] = c;.  }.}../*
0680: 0a 2a 2a 20 54 6f 6b 65 6e 69 7a 65 20 73 6f 6d  .** Tokenize som
0690: 65 20 74 65 78 74 20 75 73 69 6e 67 20 74 68 65  e text using the
06a0: 20 73 69 6d 70 6c 65 20 74 6f 6b 65 6e 69 7a 65   simple tokenize
06b0: 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  r..*/.static int
06c0: 20 66 74 73 35 53 69 6d 70 6c 65 54 6f 6b 65 6e   fts5SimpleToken
06d0: 69 7a 65 28 0a 20 20 46 74 73 35 54 6f 6b 65 6e  ize(.  Fts5Token
06e0: 69 7a 65 72 20 2a 70 54 6f 6b 65 6e 69 7a 65 72  izer *pTokenizer
06f0: 2c 0a 20 20 76 6f 69 64 20 2a 70 43 74 78 2c 0a  ,.  void *pCtx,.
0700: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 54    const char *pT
0710: 65 78 74 2c 20 69 6e 74 20 6e 54 65 78 74 2c 0a  ext, int nText,.
0720: 20 20 69 6e 74 20 28 2a 78 54 6f 6b 65 6e 29 28    int (*xToken)(
0730: 76 6f 69 64 2a 2c 20 63 6f 6e 73 74 20 63 68 61  void*, const cha
0740: 72 2a 2c 20 69 6e 74 20 6e 54 6f 6b 65 6e 2c 20  r*, int nToken, 
0750: 69 6e 74 20 69 53 74 61 72 74 2c 20 69 6e 74 20  int iStart, int 
0760: 69 45 6e 64 2c 20 69 6e 74 20 69 50 6f 73 29 0a  iEnd, int iPos).
0770: 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 69  ){.  int rc;.  i
0780: 6e 74 20 69 65 3b 0a 20 20 69 6e 74 20 69 73 20  nt ie;.  int is 
0790: 3d 20 30 3b 0a 20 20 69 6e 74 20 69 50 6f 73 20  = 0;.  int iPos 
07a0: 3d 20 30 3b 0a 0a 20 20 63 68 61 72 20 61 46 6f  = 0;..  char aFo
07b0: 6c 64 5b 36 34 5d 3b 0a 20 20 69 6e 74 20 6e 46  ld[64];.  int nF
07c0: 6f 6c 64 20 3d 20 73 69 7a 65 6f 66 28 61 46 6f  old = sizeof(aFo
07d0: 6c 64 29 3b 0a 20 20 63 68 61 72 20 2a 70 46 6f  ld);.  char *pFo
07e0: 6c 64 20 3d 20 61 46 6f 6c 64 3b 0a 0a 20 20 64  ld = aFold;..  d
07f0: 6f 20 7b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74  o {.    int nByt
0800: 65 3b 0a 0a 20 20 20 20 2f 2a 20 53 6b 69 70 20  e;..    /* Skip 
0810: 61 6e 79 20 6c 65 61 64 69 6e 67 20 64 69 76 69  any leading divi
0820: 64 65 72 20 63 68 61 72 61 63 74 65 72 73 2e 20  der characters. 
0830: 2a 2f 0a 20 20 20 20 77 68 69 6c 65 28 20 69 73  */.    while( is
0840: 3c 6e 54 65 78 74 20 26 26 20 28 28 70 54 65 78  <nText && ((pTex
0850: 74 5b 69 73 5d 26 30 78 38 30 29 20 7c 7c 20 61  t[is]&0x80) || a
0860: 53 69 6d 70 6c 65 54 6f 6b 65 6e 43 68 61 72 5b  SimpleTokenChar[
0870: 70 54 65 78 74 5b 69 73 5d 5d 3d 3d 30 20 29 20  pText[is]]==0 ) 
0880: 29 7b 0a 20 20 20 20 20 20 69 73 2b 2b 3b 0a 20  ){.      is++;. 
0890: 20 20 20 7d 0a 20 20 20 20 69 66 28 20 69 73 3d     }.    if( is=
08a0: 3d 6e 54 65 78 74 20 29 20 62 72 65 61 6b 3b 0a  =nText ) break;.
08b0: 0a 20 20 20 20 2f 2a 20 43 6f 75 6e 74 20 74 68  .    /* Count th
08c0: 65 20 74 6f 6b 65 6e 20 63 68 61 72 61 63 74 65  e token characte
08d0: 72 73 20 2a 2f 0a 20 20 20 20 69 65 20 3d 20 69  rs */.    ie = i
08e0: 73 2b 31 3b 0a 20 20 20 20 77 68 69 6c 65 28 20  s+1;.    while( 
08f0: 69 65 3c 6e 54 65 78 74 20 26 26 20 28 28 70 54  ie<nText && ((pT
0900: 65 78 74 5b 69 65 5d 26 30 78 38 30 29 3d 3d 30  ext[ie]&0x80)==0
0910: 20 26 26 20 61 53 69 6d 70 6c 65 54 6f 6b 65 6e   && aSimpleToken
0920: 43 68 61 72 5b 70 54 65 78 74 5b 69 65 5d 5d 20  Char[pText[ie]] 
0930: 29 20 29 7b 0a 20 20 20 20 20 20 69 65 2b 2b 3b  ) ){.      ie++;
0940: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 46  .    }..    /* F
0950: 6f 6c 64 20 74 6f 20 6c 6f 77 65 72 20 63 61 73  old to lower cas
0960: 65 20 2a 2f 0a 20 20 20 20 6e 42 79 74 65 20 3d  e */.    nByte =
0970: 20 69 65 2d 69 73 3b 0a 20 20 20 20 69 66 28 20   ie-is;.    if( 
0980: 6e 42 79 74 65 3e 6e 46 6f 6c 64 20 29 7b 0a 20  nByte>nFold ){. 
0990: 20 20 20 20 20 69 66 28 20 70 46 6f 6c 64 21 3d       if( pFold!=
09a0: 61 46 6f 6c 64 20 29 20 73 71 6c 69 74 65 33 5f  aFold ) sqlite3_
09b0: 66 72 65 65 28 70 46 6f 6c 64 29 3b 0a 20 20 20  free(pFold);.   
09c0: 20 20 20 70 46 6f 6c 64 20 3d 20 73 71 6c 69 74     pFold = sqlit
09d0: 65 33 5f 6d 61 6c 6c 6f 63 28 6e 42 79 74 65 2a  e3_malloc(nByte*
09e0: 32 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 46  2);.      if( pF
09f0: 6f 6c 64 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  old==0 ){.      
0a00: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f    rc = SQLITE_NO
0a10: 4d 45 4d 3b 0a 20 20 20 20 20 20 20 20 62 72 65  MEM;.        bre
0a20: 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ak;.      }.    
0a30: 20 20 6e 46 6f 6c 64 20 3d 20 6e 42 79 74 65 2a    nFold = nByte*
0a40: 32 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 69 6d  2;.    }.    sim
0a50: 70 6c 65 46 6f 6c 64 28 70 46 6f 6c 64 2c 20 26  pleFold(pFold, &
0a60: 70 54 65 78 74 5b 69 73 5d 2c 20 6e 42 79 74 65  pText[is], nByte
0a70: 29 3b 0a 0a 20 20 20 20 2f 2a 20 49 6e 76 6f 6b  );..    /* Invok
0a80: 65 20 74 68 65 20 74 6f 6b 65 6e 20 63 61 6c 6c  e the token call
0a90: 62 61 63 6b 20 2a 2f 0a 20 20 20 20 72 63 20 3d  back */.    rc =
0aa0: 20 78 54 6f 6b 65 6e 28 70 43 74 78 2c 20 70 46   xToken(pCtx, pF
0ab0: 6f 6c 64 2c 20 6e 42 79 74 65 2c 20 69 73 2c 20  old, nByte, is, 
0ac0: 69 65 2c 20 69 50 6f 73 29 3b 0a 20 20 20 20 69  ie, iPos);.    i
0ad0: 50 6f 73 2b 2b 3b 0a 20 20 20 20 69 73 20 3d 20  Pos++;.    is = 
0ae0: 69 65 2b 31 3b 0a 20 20 7d 77 68 69 6c 65 28 20  ie+1;.  }while( 
0af0: 69 73 3c 6e 54 65 78 74 20 26 26 20 72 63 3d 3d  is<nText && rc==
0b00: 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 0a  SQLITE_OK );.  .
0b10: 20 20 69 66 28 20 70 46 6f 6c 64 21 3d 61 46 6f    if( pFold!=aFo
0b20: 6c 64 20 29 20 73 71 6c 69 74 65 33 5f 66 72 65  ld ) sqlite3_fre
0b30: 65 28 70 46 6f 6c 64 29 3b 0a 20 20 69 66 28 20  e(pFold);.  if( 
0b40: 72 63 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20  rc==SQLITE_DONE 
0b50: 29 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  ) rc = SQLITE_OK
0b60: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
0b70: 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ../*************
0b80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0b90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0ba0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0bb0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a  *************.**
0bc0: 20 53 74 61 72 74 20 6f 66 20 70 6f 72 74 65 72   Start of porter
0bd0: 32 20 73 74 65 6d 6d 65 72 20 69 6d 70 6c 65 6d  2 stemmer implem
0be0: 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2f 0a 0a 2f 2a  entation..*/../*
0bf0: 20 41 6e 79 20 74 6f 6b 65 6e 73 20 6c 61 72 67   Any tokens larg
0c00: 65 72 20 74 68 61 6e 20 74 68 69 73 20 28 69 6e  er than this (in
0c10: 20 62 79 74 65 73 29 20 61 72 65 20 70 61 73 73   bytes) are pass
0c20: 65 64 20 74 68 72 6f 75 67 68 20 77 69 74 68 6f  ed through witho
0c30: 75 74 0a 2a 2a 20 73 74 65 6d 6d 69 6e 67 2e 20  ut.** stemming. 
0c40: 2a 2f 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f  */.#define FTS5_
0c50: 50 4f 52 54 45 52 5f 4d 41 58 5f 54 4f 4b 45 4e  PORTER_MAX_TOKEN
0c60: 20 36 34 0a 0a 74 79 70 65 64 65 66 20 73 74 72   64..typedef str
0c70: 75 63 74 20 50 6f 72 74 65 72 54 6f 6b 65 6e 69  uct PorterTokeni
0c80: 7a 65 72 20 50 6f 72 74 65 72 54 6f 6b 65 6e 69  zer PorterTokeni
0c90: 7a 65 72 3b 0a 73 74 72 75 63 74 20 50 6f 72 74  zer;.struct Port
0ca0: 65 72 54 6f 6b 65 6e 69 7a 65 72 20 7b 0a 20 20  erTokenizer {.  
0cb0: 66 74 73 35 5f 74 6f 6b 65 6e 69 7a 65 72 20 74  fts5_tokenizer t
0cc0: 6f 6b 65 6e 69 7a 65 72 3b 20 20 20 20 20 20 20  okenizer;       
0cd0: 2f 2a 20 50 61 72 65 6e 74 20 74 6f 6b 65 6e 69  /* Parent tokeni
0ce0: 7a 65 72 20 6d 6f 64 75 6c 65 20 2a 2f 0a 20 20  zer module */.  
0cf0: 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72 20 2a 70  Fts5Tokenizer *p
0d00: 54 6f 6b 65 6e 69 7a 65 72 3b 20 20 20 20 20 20  Tokenizer;      
0d10: 2f 2a 20 50 61 72 65 6e 74 20 74 6f 6b 65 6e 69  /* Parent tokeni
0d20: 7a 65 72 20 69 6e 73 74 61 6e 63 65 20 2a 2f 0a  zer instance */.
0d30: 20 20 63 68 61 72 20 61 42 75 66 5b 46 54 53 35    char aBuf[FTS5
0d40: 5f 50 4f 52 54 45 52 5f 4d 41 58 5f 54 4f 4b 45  _PORTER_MAX_TOKE
0d50: 4e 20 2b 20 36 34 5d 3b 0a 7d 3b 0a 0a 2f 2a 0a  N + 64];.};../*.
0d60: 2a 2a 20 44 65 6c 65 74 65 20 61 20 22 70 6f 72  ** Delete a "por
0d70: 74 65 72 22 20 74 6f 6b 65 6e 69 7a 65 72 2e 0a  ter" tokenizer..
0d80: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66  */.static void f
0d90: 74 73 35 50 6f 72 74 65 72 44 65 6c 65 74 65 28  ts5PorterDelete(
0da0: 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72 20 2a 70  Fts5Tokenizer *p
0db0: 54 6f 6b 29 7b 0a 20 20 69 66 28 20 70 54 6f 6b  Tok){.  if( pTok
0dc0: 20 29 7b 0a 20 20 20 20 50 6f 72 74 65 72 54 6f   ){.    PorterTo
0dd0: 6b 65 6e 69 7a 65 72 20 2a 70 20 3d 20 28 50 6f  kenizer *p = (Po
0de0: 72 74 65 72 54 6f 6b 65 6e 69 7a 65 72 2a 29 70  rterTokenizer*)p
0df0: 54 6f 6b 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e  Tok;.    if( p->
0e00: 70 54 6f 6b 65 6e 69 7a 65 72 20 29 7b 0a 20 20  pTokenizer ){.  
0e10: 20 20 20 20 70 2d 3e 74 6f 6b 65 6e 69 7a 65 72      p->tokenizer
0e20: 2e 78 44 65 6c 65 74 65 28 70 2d 3e 70 54 6f 6b  .xDelete(p->pTok
0e30: 65 6e 69 7a 65 72 29 3b 0a 20 20 20 20 7d 0a 20  enizer);.    }. 
0e40: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
0e50: 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  p);.  }.}../*.**
0e60: 20 43 72 65 61 74 65 20 61 20 22 70 6f 72 74 65   Create a "porte
0e70: 72 22 20 74 6f 6b 65 6e 69 7a 65 72 2e 0a 2a 2f  r" tokenizer..*/
0e80: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
0e90: 50 6f 72 74 65 72 43 72 65 61 74 65 28 0a 20 20  PorterCreate(.  
0ea0: 76 6f 69 64 20 2a 70 43 74 78 2c 20 0a 20 20 63  void *pCtx, .  c
0eb0: 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61 7a 41 72  onst char **azAr
0ec0: 67 2c 20 69 6e 74 20 6e 41 72 67 2c 0a 20 20 46  g, int nArg,.  F
0ed0: 74 73 35 54 6f 6b 65 6e 69 7a 65 72 20 2a 2a 70  ts5Tokenizer **p
0ee0: 70 4f 75 74 0a 29 7b 0a 20 20 66 74 73 35 5f 61  pOut.){.  fts5_a
0ef0: 70 69 20 2a 70 41 70 69 20 3d 20 28 66 74 73 35  pi *pApi = (fts5
0f00: 5f 61 70 69 2a 29 70 43 74 78 3b 0a 20 20 69 6e  _api*)pCtx;.  in
0f10: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
0f20: 3b 0a 20 20 50 6f 72 74 65 72 54 6f 6b 65 6e 69  ;.  PorterTokeni
0f30: 7a 65 72 20 2a 70 52 65 74 3b 0a 20 20 76 6f 69  zer *pRet;.  voi
0f40: 64 20 2a 70 55 73 65 72 64 61 74 61 20 3d 20 30  d *pUserdata = 0
0f50: 3b 0a 0a 20 20 70 52 65 74 20 3d 20 28 50 6f 72  ;..  pRet = (Por
0f60: 74 65 72 54 6f 6b 65 6e 69 7a 65 72 2a 29 73 71  terTokenizer*)sq
0f70: 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a  lite3_malloc(siz
0f80: 65 6f 66 28 50 6f 72 74 65 72 54 6f 6b 65 6e 69  eof(PorterTokeni
0f90: 7a 65 72 29 29 3b 0a 20 20 69 66 28 20 70 52 65  zer));.  if( pRe
0fa0: 74 20 29 7b 0a 20 20 20 20 6d 65 6d 73 65 74 28  t ){.    memset(
0fb0: 70 52 65 74 2c 20 30 2c 20 73 69 7a 65 6f 66 28  pRet, 0, sizeof(
0fc0: 50 6f 72 74 65 72 54 6f 6b 65 6e 69 7a 65 72 29  PorterTokenizer)
0fd0: 29 3b 0a 20 20 20 20 72 63 20 3d 20 70 41 70 69  );.    rc = pApi
0fe0: 2d 3e 78 46 69 6e 64 54 6f 6b 65 6e 69 7a 65 72  ->xFindTokenizer
0ff0: 28 70 41 70 69 2c 20 22 73 69 6d 70 6c 65 22 2c  (pApi, "simple",
1000: 20 26 70 55 73 65 72 64 61 74 61 2c 20 26 70 52   &pUserdata, &pR
1010: 65 74 2d 3e 74 6f 6b 65 6e 69 7a 65 72 29 3b 0a  et->tokenizer);.
1020: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72 63 20    }else{.    rc 
1030: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
1040: 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53 51    }.  if( rc==SQ
1050: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  LITE_OK ){.    r
1060: 63 20 3d 20 70 52 65 74 2d 3e 74 6f 6b 65 6e 69  c = pRet->tokeni
1070: 7a 65 72 2e 78 43 72 65 61 74 65 28 70 55 73 65  zer.xCreate(pUse
1080: 72 64 61 74 61 2c 20 30 2c 20 30 2c 20 26 70 52  rdata, 0, 0, &pR
1090: 65 74 2d 3e 70 54 6f 6b 65 6e 69 7a 65 72 29 3b  et->pTokenizer);
10a0: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 21 3d  .  }..  if( rc!=
10b0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
10c0: 20 66 74 73 35 50 6f 72 74 65 72 44 65 6c 65 74   fts5PorterDelet
10d0: 65 28 28 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72  e((Fts5Tokenizer
10e0: 2a 29 70 52 65 74 29 3b 0a 20 20 20 20 70 52 65  *)pRet);.    pRe
10f0: 74 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 2a 70 70  t = 0;.  }.  *pp
1100: 4f 75 74 20 3d 20 28 46 74 73 35 54 6f 6b 65 6e  Out = (Fts5Token
1110: 69 7a 65 72 2a 29 70 52 65 74 3b 0a 20 20 72 65  izer*)pRet;.  re
1120: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 74 79 70 65  turn rc;.}..type
1130: 64 65 66 20 73 74 72 75 63 74 20 50 6f 72 74 65  def struct Porte
1140: 72 43 6f 6e 74 65 78 74 20 50 6f 72 74 65 72 43  rContext PorterC
1150: 6f 6e 74 65 78 74 3b 0a 73 74 72 75 63 74 20 50  ontext;.struct P
1160: 6f 72 74 65 72 43 6f 6e 74 65 78 74 20 7b 0a 20  orterContext {. 
1170: 20 76 6f 69 64 20 2a 70 43 74 78 3b 0a 20 20 69   void *pCtx;.  i
1180: 6e 74 20 28 2a 78 54 6f 6b 65 6e 29 28 76 6f 69  nt (*xToken)(voi
1190: 64 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 2a 2c  d*, const char*,
11a0: 20 69 6e 74 2c 20 69 6e 74 2c 20 69 6e 74 2c 20   int, int, int, 
11b0: 69 6e 74 29 3b 0a 20 20 63 68 61 72 20 2a 61 42  int);.  char *aB
11c0: 75 66 3b 0a 7d 3b 0a 0a 74 79 70 65 64 65 66 20  uf;.};..typedef 
11d0: 73 74 72 75 63 74 20 50 6f 72 74 65 72 52 75 6c  struct PorterRul
11e0: 65 20 50 6f 72 74 65 72 52 75 6c 65 3b 0a 73 74  e PorterRule;.st
11f0: 72 75 63 74 20 50 6f 72 74 65 72 52 75 6c 65 20  ruct PorterRule 
1200: 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  {.  const char *
1210: 7a 53 75 66 66 69 78 3b 0a 20 20 69 6e 74 20 6e  zSuffix;.  int n
1220: 53 75 66 66 69 78 3b 0a 20 20 69 6e 74 20 28 2a  Suffix;.  int (*
1230: 78 43 6f 6e 64 29 28 63 68 61 72 20 2a 7a 53 74  xCond)(char *zSt
1240: 65 6d 2c 20 69 6e 74 20 6e 53 74 65 6d 29 3b 0a  em, int nStem);.
1250: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4f    const char *zO
1260: 75 74 70 75 74 3b 0a 20 20 69 6e 74 20 6e 4f 75  utput;.  int nOu
1270: 74 70 75 74 3b 0a 7d 3b 0a 0a 73 74 61 74 69 63  tput;.};..static
1280: 20 69 6e 74 20 66 74 73 35 50 6f 72 74 65 72 41   int fts5PorterA
1290: 70 70 6c 79 28 63 68 61 72 20 2a 61 42 75 66 2c  pply(char *aBuf,
12a0: 20 69 6e 74 20 2a 70 6e 42 75 66 2c 20 50 6f 72   int *pnBuf, Por
12b0: 74 65 72 52 75 6c 65 20 2a 61 52 75 6c 65 29 7b  terRule *aRule){
12c0: 0a 20 20 69 6e 74 20 72 65 74 20 3d 20 2d 31 3b  .  int ret = -1;
12d0: 0a 20 20 69 6e 74 20 6e 42 75 66 20 3d 20 2a 70  .  int nBuf = *p
12e0: 6e 42 75 66 3b 0a 20 20 50 6f 72 74 65 72 52 75  nBuf;.  PorterRu
12f0: 6c 65 20 2a 70 3b 0a 0a 0a 20 20 66 6f 72 28 70  le *p;...  for(p
1300: 3d 61 52 75 6c 65 3b 20 70 2d 3e 7a 53 75 66 66  =aRule; p->zSuff
1310: 69 78 3b 20 70 2b 2b 29 7b 0a 20 20 20 20 61 73  ix; p++){.    as
1320: 73 65 72 74 28 20 73 74 72 6c 65 6e 28 70 2d 3e  sert( strlen(p->
1330: 7a 53 75 66 66 69 78 29 3d 3d 70 2d 3e 6e 53 75  zSuffix)==p->nSu
1340: 66 66 69 78 20 29 3b 0a 20 20 20 20 61 73 73 65  ffix );.    asse
1350: 72 74 28 20 73 74 72 6c 65 6e 28 70 2d 3e 7a 4f  rt( strlen(p->zO
1360: 75 74 70 75 74 29 3d 3d 70 2d 3e 6e 4f 75 74 70  utput)==p->nOutp
1370: 75 74 20 29 3b 0a 20 20 20 20 69 66 28 20 6e 42  ut );.    if( nB
1380: 75 66 3c 70 2d 3e 6e 53 75 66 66 69 78 20 29 20  uf<p->nSuffix ) 
1390: 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 69 66  continue;.    if
13a0: 28 20 30 3d 3d 6d 65 6d 63 6d 70 28 26 61 42 75  ( 0==memcmp(&aBu
13b0: 66 5b 6e 42 75 66 20 2d 20 70 2d 3e 6e 53 75 66  f[nBuf - p->nSuf
13c0: 66 69 78 5d 2c 20 70 2d 3e 7a 53 75 66 66 69 78  fix], p->zSuffix
13d0: 2c 20 70 2d 3e 6e 53 75 66 66 69 78 29 20 29 20  , p->nSuffix) ) 
13e0: 62 72 65 61 6b 3b 0a 20 20 7d 0a 0a 20 20 69 66  break;.  }..  if
13f0: 28 20 70 2d 3e 7a 53 75 66 66 69 78 20 29 7b 0a  ( p->zSuffix ){.
1400: 20 20 20 20 69 6e 74 20 6e 53 74 65 6d 20 3d 20      int nStem = 
1410: 6e 42 75 66 20 2d 20 70 2d 3e 6e 53 75 66 66 69  nBuf - p->nSuffi
1420: 78 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e 78 43  x;.    if( p->xC
1430: 6f 6e 64 3d 3d 30 20 7c 7c 20 70 2d 3e 78 43 6f  ond==0 || p->xCo
1440: 6e 64 28 61 42 75 66 2c 20 6e 53 74 65 6d 29 20  nd(aBuf, nStem) 
1450: 29 7b 0a 20 20 20 20 20 20 6d 65 6d 63 70 79 28  ){.      memcpy(
1460: 26 61 42 75 66 5b 6e 53 74 65 6d 5d 2c 20 70 2d  &aBuf[nStem], p-
1470: 3e 7a 4f 75 74 70 75 74 2c 20 70 2d 3e 6e 4f 75  >zOutput, p->nOu
1480: 74 70 75 74 29 3b 0a 20 20 20 20 20 20 2a 70 6e  tput);.      *pn
1490: 42 75 66 20 3d 20 6e 53 74 65 6d 20 2b 20 70 2d  Buf = nStem + p-
14a0: 3e 6e 4f 75 74 70 75 74 3b 0a 20 20 20 20 20 20  >nOutput;.      
14b0: 72 65 74 20 3d 20 70 20 2d 20 61 52 75 6c 65 3b  ret = p - aRule;
14c0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65  .    }.  }..  re
14d0: 74 75 72 6e 20 72 65 74 3b 0a 7d 0a 0a 73 74 61  turn ret;.}..sta
14e0: 74 69 63 20 69 6e 74 20 66 74 73 35 50 6f 72 74  tic int fts5Port
14f0: 65 72 49 73 56 6f 77 65 6c 28 63 68 61 72 20 63  erIsVowel(char c
1500: 2c 20 69 6e 74 20 62 59 49 73 56 6f 77 65 6c 29  , int bYIsVowel)
1510: 7b 0a 20 20 72 65 74 75 72 6e 20 28 0a 20 20 20  {.  return (.   
1520: 20 20 20 63 3d 3d 27 61 27 20 7c 7c 20 63 3d 3d     c=='a' || c==
1530: 27 65 27 20 7c 7c 20 63 3d 3d 27 69 27 20 7c 7c  'e' || c=='i' ||
1540: 20 63 3d 3d 27 6f 27 20 7c 7c 20 63 3d 3d 27 75   c=='o' || c=='u
1550: 27 20 7c 7c 20 28 62 59 49 73 56 6f 77 65 6c 20  ' || (bYIsVowel 
1560: 26 26 20 63 3d 3d 27 79 27 29 0a 20 20 29 3b 0a  && c=='y').  );.
1570: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  }..static int ft
1580: 73 35 50 6f 72 74 65 72 47 6f 62 62 6c 65 56 43  s5PorterGobbleVC
1590: 28 63 68 61 72 20 2a 7a 53 74 65 6d 2c 20 69 6e  (char *zStem, in
15a0: 74 20 6e 53 74 65 6d 2c 20 69 6e 74 20 62 50 72  t nStem, int bPr
15b0: 65 76 43 6f 6e 73 29 7b 0a 20 20 69 6e 74 20 69  evCons){.  int i
15c0: 3b 0a 20 20 69 6e 74 20 62 43 6f 6e 73 20 3d 20  ;.  int bCons = 
15d0: 62 50 72 65 76 43 6f 6e 73 3b 0a 0a 20 20 2f 2a  bPrevCons;..  /*
15e0: 20 53 63 61 6e 20 66 6f 72 20 61 20 76 6f 77 65   Scan for a vowe
15f0: 6c 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20  l */.  for(i=0; 
1600: 69 3c 6e 53 74 65 6d 3b 20 69 2b 2b 29 7b 0a 20  i<nStem; i++){. 
1610: 20 20 20 69 66 28 20 30 3d 3d 28 62 43 6f 6e 73     if( 0==(bCons
1620: 20 3d 20 21 66 74 73 35 50 6f 72 74 65 72 49 73   = !fts5PorterIs
1630: 56 6f 77 65 6c 28 7a 53 74 65 6d 5b 69 5d 2c 20  Vowel(zStem[i], 
1640: 62 43 6f 6e 73 29 29 20 29 20 62 72 65 61 6b 3b  bCons)) ) break;
1650: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 63 61 6e 20  .  }..  /* Scan 
1660: 66 6f 72 20 61 20 63 6f 6e 73 6f 6e 65 6e 74 20  for a consonent 
1670: 2a 2f 0a 20 20 66 6f 72 28 69 2b 2b 3b 20 69 3c  */.  for(i++; i<
1680: 6e 53 74 65 6d 3b 20 69 2b 2b 29 7b 0a 20 20 20  nStem; i++){.   
1690: 20 69 66 28 20 28 62 43 6f 6e 73 20 3d 20 21 66   if( (bCons = !f
16a0: 74 73 35 50 6f 72 74 65 72 49 73 56 6f 77 65 6c  ts5PorterIsVowel
16b0: 28 7a 53 74 65 6d 5b 69 5d 2c 20 62 43 6f 6e 73  (zStem[i], bCons
16c0: 29 29 20 29 20 72 65 74 75 72 6e 20 69 2b 31 3b  )) ) return i+1;
16d0: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 30 3b  .  }.  return 0;
16e0: 0a 7d 0a 0a 2f 2a 20 70 6f 72 74 65 72 20 72 75  .}../* porter ru
16f0: 6c 65 20 63 6f 6e 64 69 74 69 6f 6e 3a 20 28 6d  le condition: (m
1700: 20 3e 20 30 29 20 2a 2f 0a 73 74 61 74 69 63 20   > 0) */.static 
1710: 69 6e 74 20 66 74 73 35 50 6f 72 74 65 72 5f 4d  int fts5Porter_M
1720: 47 74 30 28 63 68 61 72 20 2a 7a 53 74 65 6d 2c  Gt0(char *zStem,
1730: 20 69 6e 74 20 6e 53 74 65 6d 29 7b 0a 20 20 72   int nStem){.  r
1740: 65 74 75 72 6e 20 21 21 66 74 73 35 50 6f 72 74  eturn !!fts5Port
1750: 65 72 47 6f 62 62 6c 65 56 43 28 7a 53 74 65 6d  erGobbleVC(zStem
1760: 2c 20 6e 53 74 65 6d 2c 20 30 29 3b 0a 7d 0a 0a  , nStem, 0);.}..
1770: 2f 2a 20 70 6f 72 74 65 72 20 72 75 6c 65 20 63  /* porter rule c
1780: 6f 6e 64 69 74 69 6f 6e 3a 20 28 6d 20 3e 20 31  ondition: (m > 1
1790: 29 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ) */.static int 
17a0: 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 28  fts5Porter_MGt1(
17b0: 63 68 61 72 20 2a 7a 53 74 65 6d 2c 20 69 6e 74  char *zStem, int
17c0: 20 6e 53 74 65 6d 29 7b 0a 20 20 69 6e 74 20 6e   nStem){.  int n
17d0: 3b 0a 20 20 6e 20 3d 20 66 74 73 35 50 6f 72 74  ;.  n = fts5Port
17e0: 65 72 47 6f 62 62 6c 65 56 43 28 7a 53 74 65 6d  erGobbleVC(zStem
17f0: 2c 20 6e 53 74 65 6d 2c 20 30 29 3b 0a 20 20 69  , nStem, 0);.  i
1800: 66 28 20 6e 20 26 26 20 66 74 73 35 50 6f 72 74  f( n && fts5Port
1810: 65 72 47 6f 62 62 6c 65 56 43 28 26 7a 53 74 65  erGobbleVC(&zSte
1820: 6d 5b 6e 5d 2c 20 6e 53 74 65 6d 2d 6e 2c 20 31  m[n], nStem-n, 1
1830: 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  ) ){.    return 
1840: 31 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  1;.  }.  return 
1850: 30 3b 0a 7d 0a 0a 2f 2a 20 70 6f 72 74 65 72 20  0;.}../* porter 
1860: 72 75 6c 65 20 63 6f 6e 64 69 74 69 6f 6e 3a 20  rule condition: 
1870: 28 6d 20 3d 20 31 29 20 2a 2f 0a 73 74 61 74 69  (m = 1) */.stati
1880: 63 20 69 6e 74 20 66 74 73 35 50 6f 72 74 65 72  c int fts5Porter
1890: 5f 4d 45 71 31 28 63 68 61 72 20 2a 7a 53 74 65  _MEq1(char *zSte
18a0: 6d 2c 20 69 6e 74 20 6e 53 74 65 6d 29 7b 0a 20  m, int nStem){. 
18b0: 20 69 6e 74 20 6e 3b 0a 20 20 6e 20 3d 20 66 74   int n;.  n = ft
18c0: 73 35 50 6f 72 74 65 72 47 6f 62 62 6c 65 56 43  s5PorterGobbleVC
18d0: 28 7a 53 74 65 6d 2c 20 6e 53 74 65 6d 2c 20 30  (zStem, nStem, 0
18e0: 29 3b 0a 20 20 69 66 28 20 6e 20 26 26 20 30 3d  );.  if( n && 0=
18f0: 3d 66 74 73 35 50 6f 72 74 65 72 47 6f 62 62 6c  =fts5PorterGobbl
1900: 65 56 43 28 26 7a 53 74 65 6d 5b 6e 5d 2c 20 6e  eVC(&zStem[n], n
1910: 53 74 65 6d 2d 6e 2c 20 31 29 20 29 7b 0a 20 20  Stem-n, 1) ){.  
1920: 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 7d 0a    return 1;.  }.
1930: 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f    return 0;.}../
1940: 2a 20 70 6f 72 74 65 72 20 72 75 6c 65 20 63 6f  * porter rule co
1950: 6e 64 69 74 69 6f 6e 3a 20 28 2a 6f 29 20 2a 2f  ndition: (*o) */
1960: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
1970: 50 6f 72 74 65 72 5f 4f 73 74 61 72 28 63 68 61  Porter_Ostar(cha
1980: 72 20 2a 7a 53 74 65 6d 2c 20 69 6e 74 20 6e 53  r *zStem, int nS
1990: 74 65 6d 29 7b 0a 20 20 69 66 28 20 7a 53 74 65  tem){.  if( zSte
19a0: 6d 5b 6e 53 74 65 6d 2d 31 5d 3d 3d 27 77 27 20  m[nStem-1]=='w' 
19b0: 7c 7c 20 7a 53 74 65 6d 5b 6e 53 74 65 6d 2d 31  || zStem[nStem-1
19c0: 5d 3d 3d 27 78 27 20 7c 7c 20 7a 53 74 65 6d 5b  ]=='x' || zStem[
19d0: 6e 53 74 65 6d 2d 31 5d 3d 3d 27 79 27 20 29 7b  nStem-1]=='y' ){
19e0: 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20  .    return 0;. 
19f0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74 20   }else{.    int 
1a00: 69 3b 0a 20 20 20 20 69 6e 74 20 6d 61 73 6b 20  i;.    int mask 
1a10: 3d 20 30 3b 0a 20 20 20 20 69 6e 74 20 62 43 6f  = 0;.    int bCo
1a20: 6e 73 20 3d 20 30 3b 0a 20 20 20 20 66 6f 72 28  ns = 0;.    for(
1a30: 69 3d 30 3b 20 69 3c 6e 53 74 65 6d 3b 20 69 2b  i=0; i<nStem; i+
1a40: 2b 29 7b 0a 20 20 20 20 20 20 62 43 6f 6e 73 20  +){.      bCons 
1a50: 3d 20 21 66 74 73 35 50 6f 72 74 65 72 49 73 56  = !fts5PorterIsV
1a60: 6f 77 65 6c 28 7a 53 74 65 6d 5b 69 5d 2c 20 62  owel(zStem[i], b
1a70: 43 6f 6e 73 29 3b 0a 20 20 20 20 20 20 61 73 73  Cons);.      ass
1a80: 65 72 74 28 20 62 43 6f 6e 73 3d 3d 30 20 7c 7c  ert( bCons==0 ||
1a90: 20 62 43 6f 6e 73 3d 3d 31 20 29 3b 0a 20 20 20   bCons==1 );.   
1aa0: 20 20 20 6d 61 73 6b 20 3d 20 28 6d 61 73 6b 20     mask = (mask 
1ab0: 3c 3c 20 31 29 20 2b 20 62 43 6f 6e 73 3b 0a 20  << 1) + bCons;. 
1ac0: 20 20 20 7d 0a 20 20 20 20 72 65 74 75 72 6e 20     }.    return 
1ad0: 28 28 6d 61 73 6b 20 26 20 30 78 30 30 30 37 29  ((mask & 0x0007)
1ae0: 3d 3d 30 78 30 30 30 35 29 3b 0a 20 20 7d 0a 7d  ==0x0005);.  }.}
1af0: 0a 0a 2f 2a 20 70 6f 72 74 65 72 20 72 75 6c 65  ../* porter rule
1b00: 20 63 6f 6e 64 69 74 69 6f 6e 3a 20 28 6d 20 3e   condition: (m >
1b10: 20 31 20 61 6e 64 20 28 2a 53 20 6f 72 20 2a 54   1 and (*S or *T
1b20: 29 29 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  )) */.static int
1b30: 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31   fts5Porter_MGt1
1b40: 5f 61 6e 64 5f 53 5f 6f 72 5f 54 28 63 68 61 72  _and_S_or_T(char
1b50: 20 2a 7a 53 74 65 6d 2c 20 69 6e 74 20 6e 53 74   *zStem, int nSt
1b60: 65 6d 29 7b 0a 20 20 72 65 74 75 72 6e 20 6e 53  em){.  return nS
1b70: 74 65 6d 3e 30 0a 20 20 20 20 20 20 26 26 20 28  tem>0.      && (
1b80: 7a 53 74 65 6d 5b 6e 53 74 65 6d 2d 31 5d 3d 3d  zStem[nStem-1]==
1b90: 27 73 27 20 7c 7c 20 7a 53 74 65 6d 5b 6e 53 74  's' || zStem[nSt
1ba0: 65 6d 2d 31 5d 3d 3d 27 74 27 29 0a 20 20 20 20  em-1]=='t').    
1bb0: 20 20 26 26 20 66 74 73 35 50 6f 72 74 65 72 5f    && fts5Porter_
1bc0: 4d 47 74 31 28 7a 53 74 65 6d 2c 20 6e 53 74 65  MGt1(zStem, nSte
1bd0: 6d 29 3b 0a 7d 0a 0a 2f 2a 20 70 6f 72 74 65 72  m);.}../* porter
1be0: 20 72 75 6c 65 20 63 6f 6e 64 69 74 69 6f 6e 3a   rule condition:
1bf0: 20 28 2a 76 2a 29 20 2a 2f 0a 73 74 61 74 69 63   (*v*) */.static
1c00: 20 69 6e 74 20 66 74 73 35 50 6f 72 74 65 72 5f   int fts5Porter_
1c10: 56 6f 77 65 6c 28 63 68 61 72 20 2a 7a 53 74 65  Vowel(char *zSte
1c20: 6d 2c 20 69 6e 74 20 6e 53 74 65 6d 29 7b 0a 20  m, int nStem){. 
1c30: 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d   int i;.  for(i=
1c40: 30 3b 20 69 3c 6e 53 74 65 6d 3b 20 69 2b 2b 29  0; i<nStem; i++)
1c50: 7b 0a 20 20 20 20 69 66 28 20 66 74 73 35 50 6f  {.    if( fts5Po
1c60: 72 74 65 72 49 73 56 6f 77 65 6c 28 7a 53 74 65  rterIsVowel(zSte
1c70: 6d 5b 69 5d 2c 20 69 3e 30 29 20 29 7b 0a 20 20  m[i], i>0) ){.  
1c80: 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20      return 1;.  
1c90: 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
1ca0: 20 30 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e   0;.}..static in
1cb0: 74 20 66 74 73 35 50 6f 72 74 65 72 43 62 28 0a  t fts5PorterCb(.
1cc0: 20 20 76 6f 69 64 20 2a 70 43 74 78 2c 20 0a 20    void *pCtx, . 
1cd0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 54 6f   const char *pTo
1ce0: 6b 65 6e 2c 20 0a 20 20 69 6e 74 20 6e 54 6f 6b  ken, .  int nTok
1cf0: 65 6e 2c 20 0a 20 20 69 6e 74 20 69 53 74 61 72  en, .  int iStar
1d00: 74 2c 20 0a 20 20 69 6e 74 20 69 45 6e 64 2c 20  t, .  int iEnd, 
1d10: 0a 20 20 69 6e 74 20 69 50 6f 73 0a 29 7b 0a 20  .  int iPos.){. 
1d20: 20 50 6f 72 74 65 72 43 6f 6e 74 65 78 74 20 2a   PorterContext *
1d30: 70 20 3d 20 28 50 6f 72 74 65 72 43 6f 6e 74 65  p = (PorterConte
1d40: 78 74 2a 29 70 43 74 78 3b 0a 0a 20 20 50 6f 72  xt*)pCtx;..  Por
1d50: 74 65 72 52 75 6c 65 20 61 53 74 65 70 31 41 5b  terRule aStep1A[
1d60: 5d 20 3d 20 7b 0a 20 20 20 20 7b 20 22 73 73 65  ] = {.    { "sse
1d70: 73 22 2c 20 34 2c 20 20 30 2c 20 22 73 73 22 2c  s", 4,  0, "ss",
1d80: 20 32 20 7d 2c 0a 20 20 20 20 7b 20 22 69 65 73   2 },.    { "ies
1d90: 22 2c 20 20 33 2c 20 20 30 2c 20 22 69 22 2c 20  ",  3,  0, "i", 
1da0: 20 31 20 20 7d 2c 0a 20 20 20 20 7b 20 22 73 73   1  },.    { "ss
1db0: 22 2c 20 20 20 32 2c 20 20 30 2c 20 22 73 73 22  ",   2,  0, "ss"
1dc0: 2c 20 32 20 7d 2c 0a 20 20 20 20 7b 20 22 73 22  , 2 },.    { "s"
1dd0: 2c 20 20 20 20 31 2c 20 20 30 2c 20 22 22 2c 20  ,    1,  0, "", 
1de0: 20 20 30 20 7d 2c 0a 20 20 20 20 7b 20 30 2c 20    0 },.    { 0, 
1df0: 30 2c 20 30 2c 20 30 20 7d 0a 20 20 7d 3b 0a 0a  0, 0, 0 }.  };..
1e00: 20 20 50 6f 72 74 65 72 52 75 6c 65 20 61 53 74    PorterRule aSt
1e10: 65 70 31 42 5b 5d 20 3d 20 7b 0a 20 20 20 20 7b  ep1B[] = {.    {
1e20: 20 22 65 65 64 22 2c 20 33 2c 20 20 66 74 73 35   "eed", 3,  fts5
1e30: 50 6f 72 74 65 72 5f 4d 47 74 30 2c 20 20 22 65  Porter_MGt0,  "e
1e40: 65 22 2c 20 32 20 7d 2c 0a 20 20 20 20 7b 20 22  e", 2 },.    { "
1e50: 65 64 22 2c 20 20 32 2c 20 20 66 74 73 35 50 6f  ed",  2,  fts5Po
1e60: 72 74 65 72 5f 56 6f 77 65 6c 2c 20 22 22 2c 20  rter_Vowel, "", 
1e70: 20 20 30 20 7d 2c 0a 20 20 20 20 7b 20 22 69 6e    0 },.    { "in
1e80: 67 22 2c 20 33 2c 20 20 66 74 73 35 50 6f 72 74  g", 3,  fts5Port
1e90: 65 72 5f 56 6f 77 65 6c 2c 20 22 22 2c 20 20 20  er_Vowel, "",   
1ea0: 30 20 7d 2c 0a 20 20 20 20 7b 20 30 2c 20 30 2c  0 },.    { 0, 0,
1eb0: 20 30 2c 20 30 20 7d 0a 20 20 7d 3b 0a 0a 20 20   0, 0 }.  };..  
1ec0: 50 6f 72 74 65 72 52 75 6c 65 20 61 53 74 65 70  PorterRule aStep
1ed0: 31 42 32 5b 5d 20 3d 20 7b 0a 20 20 20 20 7b 20  1B2[] = {.    { 
1ee0: 22 61 74 22 2c 20 32 2c 20 20 30 2c 20 22 61 74  "at", 2,  0, "at
1ef0: 65 22 2c 20 33 20 7d 2c 0a 20 20 20 20 7b 20 22  e", 3 },.    { "
1f00: 62 6c 22 2c 20 32 2c 20 20 30 2c 20 22 62 6c 65  bl", 2,  0, "ble
1f10: 22 2c 20 33 20 7d 2c 0a 20 20 20 20 7b 20 22 69  ", 3 },.    { "i
1f20: 7a 22 2c 20 32 2c 20 20 30 2c 20 22 69 7a 65 22  z", 2,  0, "ize"
1f30: 2c 20 33 20 7d 2c 0a 20 20 20 20 7b 20 30 2c 20  , 3 },.    { 0, 
1f40: 30 2c 20 30 2c 20 30 20 7d 0a 20 20 7d 3b 0a 0a  0, 0, 0 }.  };..
1f50: 20 20 50 6f 72 74 65 72 52 75 6c 65 20 61 53 74    PorterRule aSt
1f60: 65 70 31 43 5b 5d 20 3d 20 7b 0a 20 20 20 20 7b  ep1C[] = {.    {
1f70: 20 22 79 22 2c 20 20 31 2c 20 20 66 74 73 35 50   "y",  1,  fts5P
1f80: 6f 72 74 65 72 5f 56 6f 77 65 6c 2c 20 22 69 22  orter_Vowel, "i"
1f90: 2c 20 31 20 7d 2c 0a 20 20 20 20 7b 20 30 2c 20  , 1 },.    { 0, 
1fa0: 30 2c 20 30 2c 20 30 20 7d 0a 20 20 7d 3b 0a 0a  0, 0, 0 }.  };..
1fb0: 20 20 50 6f 72 74 65 72 52 75 6c 65 20 61 53 74    PorterRule aSt
1fc0: 65 70 32 5b 5d 20 3d 20 7b 0a 20 20 20 20 7b 20  ep2[] = {.    { 
1fd0: 22 61 74 69 6f 6e 61 6c 22 2c 20 37 2c 20 66 74  "ational", 7, ft
1fe0: 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c 20 22  s5Porter_MGt0, "
1ff0: 61 74 65 22 2c 20 33 7d 2c 20 0a 20 20 20 20 7b  ate", 3}, .    {
2000: 20 22 74 69 6f 6e 61 6c 22 2c 20 36 2c 20 66 74   "tional", 6, ft
2010: 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c 20 22  s5Porter_MGt0, "
2020: 74 69 6f 6e 22 2c 20 34 7d 2c 20 0a 20 20 20 20  tion", 4}, .    
2030: 7b 20 22 65 6e 63 69 22 2c 20 34 2c 20 66 74 73  { "enci", 4, fts
2040: 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c 20 22 65  5Porter_MGt0, "e
2050: 6e 63 65 22 2c 20 34 7d 2c 20 0a 20 20 20 20 7b  nce", 4}, .    {
2060: 20 22 61 6e 63 69 22 2c 20 34 2c 20 66 74 73 35   "anci", 4, fts5
2070: 50 6f 72 74 65 72 5f 4d 47 74 30 2c 20 22 61 6e  Porter_MGt0, "an
2080: 63 65 22 2c 20 34 7d 2c 20 0a 20 20 20 20 7b 20  ce", 4}, .    { 
2090: 22 69 7a 65 72 22 2c 20 34 2c 20 66 74 73 35 50  "izer", 4, fts5P
20a0: 6f 72 74 65 72 5f 4d 47 74 30 2c 20 22 69 7a 65  orter_MGt0, "ize
20b0: 22 2c 20 33 7d 2c 20 0a 20 20 20 20 7b 20 22 6c  ", 3}, .    { "l
20c0: 6f 67 69 22 2c 20 34 2c 20 66 74 73 35 50 6f 72  ogi", 4, fts5Por
20d0: 74 65 72 5f 4d 47 74 30 2c 20 22 6c 6f 67 22 2c  ter_MGt0, "log",
20e0: 20 33 7d 2c 20 20 20 20 20 2f 2a 20 61 64 64 65   3},     /* adde
20f0: 64 20 70 6f 73 74 20 31 39 37 39 20 2a 2f 0a 20  d post 1979 */. 
2100: 20 20 20 7b 20 22 62 6c 69 22 2c 20 33 2c 20 66     { "bli", 3, f
2110: 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c 20  ts5Porter_MGt0, 
2120: 22 62 6c 65 22 2c 20 33 7d 2c 20 20 20 20 20 20  "ble", 3},      
2130: 2f 2a 20 6d 6f 64 69 66 69 65 64 20 70 6f 73 74  /* modified post
2140: 20 31 39 37 39 20 2a 2f 0a 20 20 20 20 7b 20 22   1979 */.    { "
2150: 61 6c 6c 69 22 2c 20 34 2c 20 66 74 73 35 50 6f  alli", 4, fts5Po
2160: 72 74 65 72 5f 4d 47 74 30 2c 20 22 61 6c 22 2c  rter_MGt0, "al",
2170: 20 32 7d 2c 20 0a 20 20 20 20 7b 20 22 65 6e 74   2}, .    { "ent
2180: 6c 69 22 2c 20 35 2c 20 66 74 73 35 50 6f 72 74  li", 5, fts5Port
2190: 65 72 5f 4d 47 74 30 2c 20 22 65 6e 74 22 2c 20  er_MGt0, "ent", 
21a0: 33 7d 2c 20 0a 20 20 20 20 7b 20 22 65 6c 69 22  3}, .    { "eli"
21b0: 2c 20 33 2c 20 66 74 73 35 50 6f 72 74 65 72 5f  , 3, fts5Porter_
21c0: 4d 47 74 30 2c 20 22 65 22 2c 20 31 7d 2c 20 0a  MGt0, "e", 1}, .
21d0: 20 20 20 20 7b 20 22 6f 75 73 6c 69 22 2c 20 35      { "ousli", 5
21e0: 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74  , fts5Porter_MGt
21f0: 30 2c 20 22 6f 75 73 22 2c 20 33 7d 2c 20 0a 20  0, "ous", 3}, . 
2200: 20 20 20 7b 20 22 69 7a 61 74 69 6f 6e 22 2c 20     { "ization", 
2210: 37 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47  7, fts5Porter_MG
2220: 74 30 2c 20 22 69 7a 65 22 2c 20 33 7d 2c 20 0a  t0, "ize", 3}, .
2230: 20 20 20 20 7b 20 22 61 74 69 6f 6e 22 2c 20 35      { "ation", 5
2240: 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74  , fts5Porter_MGt
2250: 30 2c 20 22 61 74 65 22 2c 20 33 7d 2c 20 0a 20  0, "ate", 3}, . 
2260: 20 20 20 7b 20 22 61 74 6f 72 22 2c 20 34 2c 20     { "ator", 4, 
2270: 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c  fts5Porter_MGt0,
2280: 20 22 61 74 65 22 2c 20 33 7d 2c 20 0a 20 20 20   "ate", 3}, .   
2290: 20 7b 20 22 61 6c 69 73 6d 22 2c 20 35 2c 20 66   { "alism", 5, f
22a0: 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c 20  ts5Porter_MGt0, 
22b0: 22 61 6c 22 2c 20 32 7d 2c 20 0a 20 20 20 20 7b  "al", 2}, .    {
22c0: 20 22 69 76 65 6e 65 73 73 22 2c 20 37 2c 20 66   "iveness", 7, f
22d0: 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c 20  ts5Porter_MGt0, 
22e0: 22 69 76 65 22 2c 20 33 7d 2c 20 0a 20 20 20 20  "ive", 3}, .    
22f0: 7b 20 22 66 75 6c 6e 65 73 73 22 2c 20 37 2c 20  { "fulness", 7, 
2300: 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c  fts5Porter_MGt0,
2310: 20 22 66 75 6c 22 2c 20 33 7d 2c 20 0a 20 20 20   "ful", 3}, .   
2320: 20 7b 20 22 6f 75 73 6e 65 73 73 22 2c 20 37 2c   { "ousness", 7,
2330: 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30   fts5Porter_MGt0
2340: 2c 20 22 6f 75 73 22 2c 20 33 7d 2c 20 0a 20 20  , "ous", 3}, .  
2350: 20 20 7b 20 22 61 6c 69 74 69 22 2c 20 35 2c 20    { "aliti", 5, 
2360: 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c  fts5Porter_MGt0,
2370: 20 22 61 6c 22 2c 20 32 7d 2c 20 0a 20 20 20 20   "al", 2}, .    
2380: 7b 20 22 69 76 69 74 69 22 2c 20 35 2c 20 66 74  { "iviti", 5, ft
2390: 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c 20 22  s5Porter_MGt0, "
23a0: 69 76 65 22 2c 20 33 7d 2c 20 0a 20 20 20 20 7b  ive", 3}, .    {
23b0: 20 22 62 69 6c 69 74 69 22 2c 20 36 2c 20 66 74   "biliti", 6, ft
23c0: 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c 20 22  s5Porter_MGt0, "
23d0: 62 6c 65 22 2c 20 33 7d 2c 20 0a 20 20 20 20 7b  ble", 3}, .    {
23e0: 20 30 2c 20 30 2c 20 30 2c 20 30 20 7d 0a 20 20   0, 0, 0, 0 }.  
23f0: 7d 3b 0a 0a 20 20 50 6f 72 74 65 72 52 75 6c 65  };..  PorterRule
2400: 20 61 53 74 65 70 33 5b 5d 20 3d 20 7b 0a 20 20   aStep3[] = {.  
2410: 20 20 7b 20 22 69 63 61 74 65 22 2c 20 35 2c 20    { "icate", 5, 
2420: 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c  fts5Porter_MGt0,
2430: 20 22 69 63 22 2c 20 32 7d 2c 20 0a 20 20 20 20   "ic", 2}, .    
2440: 7b 20 22 61 74 69 76 65 22 2c 20 35 2c 20 66 74  { "ative", 5, ft
2450: 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c 20 22  s5Porter_MGt0, "
2460: 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b 20 22 61  ", 0}, .    { "a
2470: 6c 69 7a 65 22 2c 20 35 2c 20 66 74 73 35 50 6f  lize", 5, fts5Po
2480: 72 74 65 72 5f 4d 47 74 30 2c 20 22 61 6c 22 2c  rter_MGt0, "al",
2490: 20 32 7d 2c 20 0a 20 20 20 20 7b 20 22 69 63 69   2}, .    { "ici
24a0: 74 69 22 2c 20 35 2c 20 66 74 73 35 50 6f 72 74  ti", 5, fts5Port
24b0: 65 72 5f 4d 47 74 30 2c 20 22 69 63 22 2c 20 32  er_MGt0, "ic", 2
24c0: 7d 2c 20 0a 20 20 20 20 7b 20 22 69 63 61 6c 22  }, .    { "ical"
24d0: 2c 20 34 2c 20 66 74 73 35 50 6f 72 74 65 72 5f  , 4, fts5Porter_
24e0: 4d 47 74 30 2c 20 22 69 63 22 2c 20 32 7d 2c 20  MGt0, "ic", 2}, 
24f0: 0a 20 20 20 20 7b 20 22 66 75 6c 22 2c 20 33 2c  .    { "ful", 3,
2500: 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30   fts5Porter_MGt0
2510: 2c 20 22 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b  , "", 0}, .    {
2520: 20 22 6e 65 73 73 22 2c 20 34 2c 20 66 74 73 35   "ness", 4, fts5
2530: 50 6f 72 74 65 72 5f 4d 47 74 30 2c 20 22 22 2c  Porter_MGt0, "",
2540: 20 30 7d 2c 20 0a 20 20 20 20 7b 20 30 2c 20 30   0}, .    { 0, 0
2550: 2c 20 30 2c 20 30 20 7d 0a 20 20 7d 3b 0a 0a 20  , 0, 0 }.  };.. 
2560: 20 50 6f 72 74 65 72 52 75 6c 65 20 61 53 74 65   PorterRule aSte
2570: 70 34 5b 5d 20 3d 20 7b 0a 20 20 20 20 7b 20 22  p4[] = {.    { "
2580: 61 6c 22 2c 20 32 2c 20 66 74 73 35 50 6f 72 74  al", 2, fts5Port
2590: 65 72 5f 4d 47 74 31 2c 20 22 22 2c 20 30 7d 2c  er_MGt1, "", 0},
25a0: 20 0a 20 20 20 20 7b 20 22 61 6e 63 65 22 2c 20   .    { "ance", 
25b0: 34 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47  4, fts5Porter_MG
25c0: 74 31 2c 20 22 22 2c 20 30 7d 2c 20 0a 20 20 20  t1, "", 0}, .   
25d0: 20 7b 20 22 65 6e 63 65 22 2c 20 34 2c 20 66 74   { "ence", 4, ft
25e0: 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 2c 20 22  s5Porter_MGt1, "
25f0: 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b 20 22 65  ", 0}, .    { "e
2600: 72 22 2c 20 32 2c 20 66 74 73 35 50 6f 72 74 65  r", 2, fts5Porte
2610: 72 5f 4d 47 74 31 2c 20 22 22 2c 20 30 7d 2c 20  r_MGt1, "", 0}, 
2620: 0a 20 20 20 20 7b 20 22 69 63 22 2c 20 32 2c 20  .    { "ic", 2, 
2630: 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 2c  fts5Porter_MGt1,
2640: 20 22 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b 20   "", 0}, .    { 
2650: 22 61 62 6c 65 22 2c 20 34 2c 20 66 74 73 35 50  "able", 4, fts5P
2660: 6f 72 74 65 72 5f 4d 47 74 31 2c 20 22 22 2c 20  orter_MGt1, "", 
2670: 30 7d 2c 20 0a 20 20 20 20 7b 20 22 69 62 6c 65  0}, .    { "ible
2680: 22 2c 20 34 2c 20 66 74 73 35 50 6f 72 74 65 72  ", 4, fts5Porter
2690: 5f 4d 47 74 31 2c 20 22 22 2c 20 30 7d 2c 20 0a  _MGt1, "", 0}, .
26a0: 20 20 20 20 7b 20 22 61 6e 74 22 2c 20 33 2c 20      { "ant", 3, 
26b0: 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 2c  fts5Porter_MGt1,
26c0: 20 22 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b 20   "", 0}, .    { 
26d0: 22 65 6d 65 6e 74 22 2c 20 35 2c 20 66 74 73 35  "ement", 5, fts5
26e0: 50 6f 72 74 65 72 5f 4d 47 74 31 2c 20 22 22 2c  Porter_MGt1, "",
26f0: 20 30 7d 2c 20 0a 20 20 20 20 7b 20 22 6d 65 6e   0}, .    { "men
2700: 74 22 2c 20 34 2c 20 66 74 73 35 50 6f 72 74 65  t", 4, fts5Porte
2710: 72 5f 4d 47 74 31 2c 20 22 22 2c 20 30 7d 2c 20  r_MGt1, "", 0}, 
2720: 0a 20 20 20 20 7b 20 22 65 6e 74 22 2c 20 33 2c  .    { "ent", 3,
2730: 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31   fts5Porter_MGt1
2740: 2c 20 22 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b  , "", 0}, .    {
2750: 20 22 69 6f 6e 22 2c 20 33 2c 20 66 74 73 35 50   "ion", 3, fts5P
2760: 6f 72 74 65 72 5f 4d 47 74 31 5f 61 6e 64 5f 53  orter_MGt1_and_S
2770: 5f 6f 72 5f 54 2c 20 22 22 2c 20 30 7d 2c 20 0a  _or_T, "", 0}, .
2780: 20 20 20 20 7b 20 22 6f 75 22 2c 20 32 2c 20 66      { "ou", 2, f
2790: 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 2c 20  ts5Porter_MGt1, 
27a0: 22 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b 20 22  "", 0}, .    { "
27b0: 69 73 6d 22 2c 20 33 2c 20 66 74 73 35 50 6f 72  ism", 3, fts5Por
27c0: 74 65 72 5f 4d 47 74 31 2c 20 22 22 2c 20 30 7d  ter_MGt1, "", 0}
27d0: 2c 20 0a 20 20 20 20 7b 20 22 61 74 65 22 2c 20  , .    { "ate", 
27e0: 33 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47  3, fts5Porter_MG
27f0: 74 31 2c 20 22 22 2c 20 30 7d 2c 20 0a 20 20 20  t1, "", 0}, .   
2800: 20 7b 20 22 69 74 69 22 2c 20 33 2c 20 66 74 73   { "iti", 3, fts
2810: 35 50 6f 72 74 65 72 5f 4d 47 74 31 2c 20 22 22  5Porter_MGt1, ""
2820: 2c 20 30 7d 2c 20 0a 20 20 20 20 7b 20 22 6f 75  , 0}, .    { "ou
2830: 73 22 2c 20 33 2c 20 66 74 73 35 50 6f 72 74 65  s", 3, fts5Porte
2840: 72 5f 4d 47 74 31 2c 20 22 22 2c 20 30 7d 2c 20  r_MGt1, "", 0}, 
2850: 0a 20 20 20 20 7b 20 22 69 76 65 22 2c 20 33 2c  .    { "ive", 3,
2860: 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31   fts5Porter_MGt1
2870: 2c 20 22 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b  , "", 0}, .    {
2880: 20 22 69 7a 65 22 2c 20 33 2c 20 66 74 73 35 50   "ize", 3, fts5P
2890: 6f 72 74 65 72 5f 4d 47 74 31 2c 20 22 22 2c 20  orter_MGt1, "", 
28a0: 30 7d 2c 20 0a 20 20 20 20 7b 20 30 2c 20 30 2c  0}, .    { 0, 0,
28b0: 20 30 2c 20 30 20 7d 0a 20 20 7d 3b 0a 0a 0a 20   0, 0 }.  };... 
28c0: 20 63 68 61 72 20 2a 61 42 75 66 3b 0a 20 20 69   char *aBuf;.  i
28d0: 6e 74 20 6e 42 75 66 3b 0a 20 20 69 6e 74 20 6e  nt nBuf;.  int n
28e0: 3b 0a 0a 20 20 69 66 28 20 6e 54 6f 6b 65 6e 3e  ;..  if( nToken>
28f0: 46 54 53 35 5f 50 4f 52 54 45 52 5f 4d 41 58 5f  FTS5_PORTER_MAX_
2900: 54 4f 4b 45 4e 20 7c 7c 20 6e 54 6f 6b 65 6e 3c  TOKEN || nToken<
2910: 33 20 29 20 67 6f 74 6f 20 70 61 73 73 5f 74 68  3 ) goto pass_th
2920: 72 6f 75 67 68 3b 0a 20 20 61 42 75 66 20 3d 20  rough;.  aBuf = 
2930: 70 2d 3e 61 42 75 66 3b 0a 20 20 6e 42 75 66 20  p->aBuf;.  nBuf 
2940: 3d 20 6e 54 6f 6b 65 6e 3b 0a 20 20 6d 65 6d 63  = nToken;.  memc
2950: 70 79 28 61 42 75 66 2c 20 70 54 6f 6b 65 6e 2c  py(aBuf, pToken,
2960: 20 6e 42 75 66 29 3b 0a 0a 20 20 2f 2a 20 53 74   nBuf);..  /* St
2970: 65 70 20 31 2e 20 2a 2f 0a 20 20 66 74 73 35 50  ep 1. */.  fts5P
2980: 6f 72 74 65 72 41 70 70 6c 79 28 61 42 75 66 2c  orterApply(aBuf,
2990: 20 26 6e 42 75 66 2c 20 61 53 74 65 70 31 41 29   &nBuf, aStep1A)
29a0: 3b 0a 20 20 6e 20 3d 20 66 74 73 35 50 6f 72 74  ;.  n = fts5Port
29b0: 65 72 41 70 70 6c 79 28 61 42 75 66 2c 20 26 6e  erApply(aBuf, &n
29c0: 42 75 66 2c 20 61 53 74 65 70 31 42 29 3b 0a 20  Buf, aStep1B);. 
29d0: 20 69 66 28 20 6e 3d 3d 31 20 7c 7c 20 6e 3d 3d   if( n==1 || n==
29e0: 32 20 29 7b 0a 20 20 20 20 69 66 28 20 66 74 73  2 ){.    if( fts
29f0: 35 50 6f 72 74 65 72 41 70 70 6c 79 28 61 42 75  5PorterApply(aBu
2a00: 66 2c 20 26 6e 42 75 66 2c 20 61 53 74 65 70 31  f, &nBuf, aStep1
2a10: 42 32 29 3c 30 20 29 7b 0a 20 20 20 20 20 20 63  B2)<0 ){.      c
2a20: 68 61 72 20 63 20 3d 20 61 42 75 66 5b 6e 42 75  har c = aBuf[nBu
2a30: 66 2d 31 5d 3b 0a 20 20 20 20 20 20 69 66 28 20  f-1];.      if( 
2a40: 66 74 73 35 50 6f 72 74 65 72 49 73 56 6f 77 65  fts5PorterIsVowe
2a50: 6c 28 63 2c 20 30 29 3d 3d 30 20 0a 20 20 20 20  l(c, 0)==0 .    
2a60: 20 20 20 26 26 20 63 21 3d 27 6c 27 20 26 26 20     && c!='l' && 
2a70: 63 21 3d 27 73 27 20 26 26 20 63 21 3d 27 7a 27  c!='s' && c!='z'
2a80: 20 26 26 20 63 3d 3d 61 42 75 66 5b 6e 42 75 66   && c==aBuf[nBuf
2a90: 2d 32 5d 20 0a 20 20 20 20 20 20 29 7b 0a 20 20  -2] .      ){.  
2aa0: 20 20 20 20 20 20 6e 42 75 66 2d 2d 3b 0a 20 20        nBuf--;.  
2ab0: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 66 74      }else if( ft
2ac0: 73 35 50 6f 72 74 65 72 5f 4d 45 71 31 28 61 42  s5Porter_MEq1(aB
2ad0: 75 66 2c 20 6e 42 75 66 29 20 26 26 20 66 74 73  uf, nBuf) && fts
2ae0: 35 50 6f 72 74 65 72 5f 4f 73 74 61 72 28 61 42  5Porter_Ostar(aB
2af0: 75 66 2c 20 6e 42 75 66 29 20 29 7b 0a 20 20 20  uf, nBuf) ){.   
2b00: 20 20 20 20 20 61 42 75 66 5b 6e 42 75 66 2b 2b       aBuf[nBuf++
2b10: 5d 20 3d 20 27 65 27 3b 0a 20 20 20 20 20 20 7d  ] = 'e';.      }
2b20: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 66 74 73  .    }.  }.  fts
2b30: 35 50 6f 72 74 65 72 41 70 70 6c 79 28 61 42 75  5PorterApply(aBu
2b40: 66 2c 20 26 6e 42 75 66 2c 20 61 53 74 65 70 31  f, &nBuf, aStep1
2b50: 43 29 3b 0a 0a 20 20 2f 2a 20 53 74 65 70 73 20  C);..  /* Steps 
2b60: 32 20 74 68 72 6f 75 67 68 20 34 2e 20 2a 2f 0a  2 through 4. */.
2b70: 20 20 66 74 73 35 50 6f 72 74 65 72 41 70 70 6c    fts5PorterAppl
2b80: 79 28 61 42 75 66 2c 20 26 6e 42 75 66 2c 20 61  y(aBuf, &nBuf, a
2b90: 53 74 65 70 32 29 3b 0a 20 20 66 74 73 35 50 6f  Step2);.  fts5Po
2ba0: 72 74 65 72 41 70 70 6c 79 28 61 42 75 66 2c 20  rterApply(aBuf, 
2bb0: 26 6e 42 75 66 2c 20 61 53 74 65 70 33 29 3b 0a  &nBuf, aStep3);.
2bc0: 20 20 66 74 73 35 50 6f 72 74 65 72 41 70 70 6c    fts5PorterAppl
2bd0: 79 28 61 42 75 66 2c 20 26 6e 42 75 66 2c 20 61  y(aBuf, &nBuf, a
2be0: 53 74 65 70 34 29 3b 0a 0a 20 20 2f 2a 20 53 74  Step4);..  /* St
2bf0: 65 70 20 35 61 2e 20 2a 2f 0a 20 20 69 66 28 20  ep 5a. */.  if( 
2c00: 6e 42 75 66 3e 30 20 26 26 20 61 42 75 66 5b 6e  nBuf>0 && aBuf[n
2c10: 42 75 66 2d 31 5d 3d 3d 27 65 27 20 29 7b 0a 20  Buf-1]=='e' ){. 
2c20: 20 20 20 69 66 28 20 66 74 73 35 50 6f 72 74 65     if( fts5Porte
2c30: 72 5f 4d 47 74 31 28 61 42 75 66 2c 20 6e 42 75  r_MGt1(aBuf, nBu
2c40: 66 2d 31 29 20 0a 20 20 20 20 20 7c 7c 20 28 66  f-1) .     || (f
2c50: 74 73 35 50 6f 72 74 65 72 5f 4d 45 71 31 28 61  ts5Porter_MEq1(a
2c60: 42 75 66 2c 20 6e 42 75 66 2d 31 29 20 26 26 20  Buf, nBuf-1) && 
2c70: 21 66 74 73 35 50 6f 72 74 65 72 5f 4f 73 74 61  !fts5Porter_Osta
2c80: 72 28 61 42 75 66 2c 20 6e 42 75 66 2d 31 29 29  r(aBuf, nBuf-1))
2c90: 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 6e 42  .    ){.      nB
2ca0: 75 66 2d 2d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  uf--;.    }.  }.
2cb0: 0a 20 20 2f 2a 20 53 74 65 70 20 35 62 2e 20 2a  .  /* Step 5b. *
2cc0: 2f 0a 20 20 69 66 28 20 6e 42 75 66 3e 31 20 26  /.  if( nBuf>1 &
2cd0: 26 20 61 42 75 66 5b 6e 42 75 66 2d 31 5d 3d 3d  & aBuf[nBuf-1]==
2ce0: 27 6c 27 20 0a 20 20 20 26 26 20 61 42 75 66 5b  'l' .   && aBuf[
2cf0: 6e 42 75 66 2d 32 5d 3d 3d 27 6c 27 20 26 26 20  nBuf-2]=='l' && 
2d00: 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 28  fts5Porter_MGt1(
2d10: 61 42 75 66 2c 20 6e 42 75 66 2d 31 29 20 0a 20  aBuf, nBuf-1) . 
2d20: 20 29 7b 0a 20 20 20 20 6e 42 75 66 2d 2d 3b 0a   ){.    nBuf--;.
2d30: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 70 2d    }..  return p-
2d40: 3e 78 54 6f 6b 65 6e 28 70 2d 3e 70 43 74 78 2c  >xToken(p->pCtx,
2d50: 20 61 42 75 66 2c 20 6e 42 75 66 2c 20 69 53 74   aBuf, nBuf, iSt
2d60: 61 72 74 2c 20 69 45 6e 64 2c 20 69 50 6f 73 29  art, iEnd, iPos)
2d70: 3b 0a 0a 20 70 61 73 73 5f 74 68 72 6f 75 67 68  ;.. pass_through
2d80: 3a 0a 20 20 72 65 74 75 72 6e 20 70 2d 3e 78 54  :.  return p->xT
2d90: 6f 6b 65 6e 28 70 2d 3e 70 43 74 78 2c 20 70 54  oken(p->pCtx, pT
2da0: 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 2c 20 69 53  oken, nToken, iS
2db0: 74 61 72 74 2c 20 69 45 6e 64 2c 20 69 50 6f 73  tart, iEnd, iPos
2dc0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 6f 6b 65  );.}../*.** Toke
2dd0: 6e 69 7a 65 20 75 73 69 6e 67 20 74 68 65 20 70  nize using the p
2de0: 6f 72 74 65 72 20 74 6f 6b 65 6e 69 7a 65 72 2e  orter tokenizer.
2df0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
2e00: 74 73 35 50 6f 72 74 65 72 54 6f 6b 65 6e 69 7a  ts5PorterTokeniz
2e10: 65 28 0a 20 20 46 74 73 35 54 6f 6b 65 6e 69 7a  e(.  Fts5Tokeniz
2e20: 65 72 20 2a 70 54 6f 6b 65 6e 69 7a 65 72 2c 0a  er *pTokenizer,.
2e30: 20 20 76 6f 69 64 20 2a 70 43 74 78 2c 0a 20 20    void *pCtx,.  
2e40: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 54 65 78  const char *pTex
2e50: 74 2c 20 69 6e 74 20 6e 54 65 78 74 2c 0a 20 20  t, int nText,.  
2e60: 69 6e 74 20 28 2a 78 54 6f 6b 65 6e 29 28 76 6f  int (*xToken)(vo
2e70: 69 64 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 2a  id*, const char*
2e80: 2c 20 69 6e 74 20 6e 54 6f 6b 65 6e 2c 20 69 6e  , int nToken, in
2e90: 74 20 69 53 74 61 72 74 2c 20 69 6e 74 20 69 45  t iStart, int iE
2ea0: 6e 64 2c 20 69 6e 74 20 69 50 6f 73 29 0a 29 7b  nd, int iPos).){
2eb0: 0a 20 20 50 6f 72 74 65 72 54 6f 6b 65 6e 69 7a  .  PorterTokeniz
2ec0: 65 72 20 2a 70 20 3d 20 28 50 6f 72 74 65 72 54  er *p = (PorterT
2ed0: 6f 6b 65 6e 69 7a 65 72 2a 29 70 54 6f 6b 65 6e  okenizer*)pToken
2ee0: 69 7a 65 72 3b 0a 20 20 50 6f 72 74 65 72 43 6f  izer;.  PorterCo
2ef0: 6e 74 65 78 74 20 73 43 74 78 3b 0a 20 20 73 43  ntext sCtx;.  sC
2f00: 74 78 2e 78 54 6f 6b 65 6e 20 3d 20 78 54 6f 6b  tx.xToken = xTok
2f10: 65 6e 3b 0a 20 20 73 43 74 78 2e 70 43 74 78 20  en;.  sCtx.pCtx 
2f20: 3d 20 70 43 74 78 3b 0a 20 20 73 43 74 78 2e 61  = pCtx;.  sCtx.a
2f30: 42 75 66 20 3d 20 70 2d 3e 61 42 75 66 3b 0a 20  Buf = p->aBuf;. 
2f40: 20 72 65 74 75 72 6e 20 70 2d 3e 74 6f 6b 65 6e   return p->token
2f50: 69 7a 65 72 2e 78 54 6f 6b 65 6e 69 7a 65 28 0a  izer.xTokenize(.
2f60: 20 20 20 20 20 20 70 2d 3e 70 54 6f 6b 65 6e 69        p->pTokeni
2f70: 7a 65 72 2c 20 28 76 6f 69 64 2a 29 26 73 43 74  zer, (void*)&sCt
2f80: 78 2c 20 70 54 65 78 74 2c 20 6e 54 65 78 74 2c  x, pText, nText,
2f90: 20 66 74 73 35 50 6f 72 74 65 72 43 62 0a 20 20   fts5PorterCb.  
2fa0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69  );.}../*.** Regi
2fb0: 73 74 65 72 20 61 6c 6c 20 62 75 69 6c 74 2d 69  ster all built-i
2fc0: 6e 20 74 6f 6b 65 6e 69 7a 65 72 73 20 77 69 74  n tokenizers wit
2fd0: 68 20 46 54 53 35 2e 0a 2a 2f 0a 69 6e 74 20 73  h FTS5..*/.int s
2fe0: 71 6c 69 74 65 33 46 74 73 35 54 6f 6b 65 6e 69  qlite3Fts5Tokeni
2ff0: 7a 65 72 49 6e 69 74 28 66 74 73 35 5f 61 70 69  zerInit(fts5_api
3000: 20 2a 70 41 70 69 29 7b 0a 20 20 73 74 72 75 63   *pApi){.  struc
3010: 74 20 42 75 69 6c 74 69 6e 54 6f 6b 65 6e 69 7a  t BuiltinTokeniz
3020: 65 72 20 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63  er {.    const c
3030: 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20  har *zName;.    
3040: 66 74 73 35 5f 74 6f 6b 65 6e 69 7a 65 72 20 78  fts5_tokenizer x
3050: 3b 0a 20 20 7d 20 61 42 75 69 6c 74 69 6e 5b 5d  ;.  } aBuiltin[]
3060: 20 3d 20 7b 0a 20 20 20 20 7b 20 22 70 6f 72 74   = {.    { "port
3070: 65 72 22 2c 20 20 7b 20 66 74 73 35 50 6f 72 74  er",  { fts5Port
3080: 65 72 43 72 65 61 74 65 2c 20 66 74 73 35 50 6f  erCreate, fts5Po
3090: 72 74 65 72 44 65 6c 65 74 65 2c 20 66 74 73 35  rterDelete, fts5
30a0: 50 6f 72 74 65 72 54 6f 6b 65 6e 69 7a 65 20 7d  PorterTokenize }
30b0: 20 7d 2c 0a 20 20 20 20 7b 20 22 73 69 6d 70 6c   },.    { "simpl
30c0: 65 22 2c 20 20 7b 20 66 74 73 35 53 69 6d 70 6c  e",  { fts5Simpl
30d0: 65 43 72 65 61 74 65 2c 20 66 74 73 35 53 69 6d  eCreate, fts5Sim
30e0: 70 6c 65 44 65 6c 65 74 65 2c 20 66 74 73 35 53  pleDelete, fts5S
30f0: 69 6d 70 6c 65 54 6f 6b 65 6e 69 7a 65 20 7d 20  impleTokenize } 
3100: 7d 0a 20 20 7d 3b 0a 20 20 0a 20 20 69 6e 74 20  }.  };.  .  int 
3110: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20  rc = SQLITE_OK; 
3120: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
3130: 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20  eturn code */.  
3140: 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20  int i;          
3150: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3160: 2f 2a 20 54 6f 20 69 74 65 72 61 74 65 20 74 68  /* To iterate th
3170: 72 6f 75 67 68 20 62 75 69 6c 74 69 6e 20 66 75  rough builtin fu
3180: 6e 63 74 69 6f 6e 73 20 2a 2f 0a 0a 20 20 66 6f  nctions */..  fo
3190: 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54  r(i=0; rc==SQLIT
31a0: 45 5f 4f 4b 20 26 26 20 69 3c 73 69 7a 65 6f 66  E_OK && i<sizeof
31b0: 28 61 42 75 69 6c 74 69 6e 29 2f 73 69 7a 65 6f  (aBuiltin)/sizeo
31c0: 66 28 61 42 75 69 6c 74 69 6e 5b 30 5d 29 3b 20  f(aBuiltin[0]); 
31d0: 69 2b 2b 29 7b 0a 20 20 20 20 72 63 20 3d 20 70  i++){.    rc = p
31e0: 41 70 69 2d 3e 78 43 72 65 61 74 65 54 6f 6b 65  Api->xCreateToke
31f0: 6e 69 7a 65 72 28 70 41 70 69 2c 0a 20 20 20 20  nizer(pApi,.    
3200: 20 20 20 20 61 42 75 69 6c 74 69 6e 5b 69 5d 2e      aBuiltin[i].
3210: 7a 4e 61 6d 65 2c 0a 20 20 20 20 20 20 20 20 28  zName,.        (
3220: 76 6f 69 64 2a 29 70 41 70 69 2c 0a 20 20 20 20  void*)pApi,.    
3230: 20 20 20 20 26 61 42 75 69 6c 74 69 6e 5b 69 5d      &aBuiltin[i]
3240: 2e 78 2c 0a 20 20 20 20 20 20 20 20 30 0a 20 20  .x,.        0.  
3250: 20 20 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75    );.  }..  retu
3260: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
3270: 0a 0a                                            ..