/ Hex Artifact Content
Login

Artifact bdb6a1f599a94ec6e9c1cad037d1071e823dcb5d:


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 61 73 63  .** Start of asc
0210: 69 69 20 74 6f 6b 65 6e 69 7a 65 72 20 69 6d 70  ii tokenizer imp
0220: 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2f 0a  lementation..*/.
0230: 0a 2f 2a 0a 2a 2a 20 46 6f 72 20 74 6f 6b 65 6e  ./*.** For token
0240: 69 7a 65 72 73 20 77 69 74 68 20 6e 6f 20 22 75  izers with no "u
0250: 6e 69 63 6f 64 65 22 20 6d 6f 64 69 66 69 65 72  nicode" modifier
0260: 2c 20 74 68 65 20 73 65 74 20 6f 66 20 74 6f 6b  , the set of tok
0270: 65 6e 20 63 68 61 72 61 63 74 65 72 73 0a 2a 2a  en characters.**
0280: 20 69 73 20 74 68 65 20 73 61 6d 65 20 61 73 20   is the same as 
0290: 74 68 65 20 73 65 74 20 6f 66 20 41 53 43 49 49  the set of ASCII
02a0: 20 72 61 6e 67 65 20 61 6c 70 68 61 6e 75 6d 65   range alphanume
02b0: 72 69 63 20 63 68 61 72 61 63 74 65 72 73 2e 20  ric characters. 
02c0: 0a 2a 2f 0a 73 74 61 74 69 63 20 75 6e 73 69 67  .*/.static unsig
02d0: 6e 65 64 20 63 68 61 72 20 61 41 73 63 69 69 54  ned char aAsciiT
02e0: 6f 6b 65 6e 43 68 61 72 5b 31 32 38 5d 20 3d 20  okenChar[128] = 
02f0: 7b 0a 20 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20  {.  0, 0, 0, 0, 
0300: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20 20 30 2c  0, 0, 0, 0,   0,
0310: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20   0, 0, 0, 0, 0, 
0320: 30 2c 20 30 2c 20 20 20 2f 2a 20 30 78 30 30 2e  0, 0,   /* 0x00.
0330: 2e 30 78 30 46 20 2a 2f 0a 20 20 30 2c 20 30 2c  .0x0F */.  0, 0,
0340: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20   0, 0, 0, 0, 0, 
0350: 30 2c 20 20 20 30 2c 20 30 2c 20 30 2c 20 30 2c  0,   0, 0, 0, 0,
0360: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20 20 2f   0, 0, 0, 0,   /
0370: 2a 20 30 78 31 30 2e 2e 30 78 31 46 20 2a 2f 0a  * 0x10..0x1F */.
0380: 20 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c    0, 0, 0, 0, 0,
0390: 20 30 2c 20 30 2c 20 30 2c 20 20 20 30 2c 20 30   0, 0, 0,   0, 0
03a0: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c  , 0, 0, 0, 0, 0,
03b0: 20 30 2c 20 20 20 2f 2a 20 30 78 32 30 2e 2e 30   0,   /* 0x20..0
03c0: 78 32 46 20 2a 2f 0a 20 20 31 2c 20 31 2c 20 31  x2F */.  1, 1, 1
03d0: 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c  , 1, 1, 1, 1, 1,
03e0: 20 20 20 31 2c 20 31 2c 20 30 2c 20 30 2c 20 30     1, 1, 0, 0, 0
03f0: 2c 20 30 2c 20 30 2c 20 30 2c 20 20 20 2f 2a 20  , 0, 0, 0,   /* 
0400: 30 78 33 30 2e 2e 30 78 33 46 20 2a 2f 0a 20 20  0x30..0x3F */.  
0410: 30 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  0, 1, 1, 1, 1, 1
0420: 2c 20 31 2c 20 31 2c 20 20 20 31 2c 20 31 2c 20  , 1, 1,   1, 1, 
0430: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
0440: 2c 20 20 20 2f 2a 20 30 78 34 30 2e 2e 30 78 34  ,   /* 0x40..0x4
0450: 46 20 2a 2f 0a 20 20 31 2c 20 31 2c 20 31 2c 20  F */.  1, 1, 1, 
0460: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 20  1, 1, 1, 1, 1,  
0470: 20 31 2c 20 31 2c 20 31 2c 20 30 2c 20 30 2c 20   1, 1, 1, 0, 0, 
0480: 30 2c 20 30 2c 20 30 2c 20 20 20 2f 2a 20 30 78  0, 0, 0,   /* 0x
0490: 35 30 2e 2e 30 78 35 46 20 2a 2f 0a 20 20 30 2c  50..0x5F */.  0,
04a0: 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20   1, 1, 1, 1, 1, 
04b0: 31 2c 20 31 2c 20 20 20 31 2c 20 31 2c 20 31 2c  1, 1,   1, 1, 1,
04c0: 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20   1, 1, 1, 1, 1, 
04d0: 20 20 2f 2a 20 30 78 36 30 2e 2e 30 78 36 46 20    /* 0x60..0x6F 
04e0: 2a 2f 0a 20 20 31 2c 20 31 2c 20 31 2c 20 31 2c  */.  1, 1, 1, 1,
04f0: 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 20 20 31   1, 1, 1, 1,   1
0500: 2c 20 31 2c 20 31 2c 20 30 2c 20 30 2c 20 30 2c  , 1, 1, 0, 0, 0,
0510: 20 30 2c 20 30 2c 20 20 20 2f 2a 20 30 78 37 30   0, 0,   /* 0x70
0520: 2e 2e 30 78 37 46 20 2a 2f 0a 7d 3b 0a 0a 74 79  ..0x7F */.};..ty
0530: 70 65 64 65 66 20 73 74 72 75 63 74 20 41 73 63  pedef struct Asc
0540: 69 69 54 6f 6b 65 6e 69 7a 65 72 20 41 73 63 69  iiTokenizer Asci
0550: 69 54 6f 6b 65 6e 69 7a 65 72 3b 0a 73 74 72 75  iTokenizer;.stru
0560: 63 74 20 41 73 63 69 69 54 6f 6b 65 6e 69 7a 65  ct AsciiTokenize
0570: 72 20 7b 0a 20 20 75 6e 73 69 67 6e 65 64 20 63  r {.  unsigned c
0580: 68 61 72 20 61 54 6f 6b 65 6e 43 68 61 72 5b 31  har aTokenChar[1
0590: 32 38 5d 3b 0a 7d 3b 0a 0a 73 74 61 74 69 63 20  28];.};..static 
05a0: 76 6f 69 64 20 66 74 73 35 41 73 63 69 69 41 64  void fts5AsciiAd
05b0: 64 45 78 63 65 70 74 69 6f 6e 73 28 0a 20 20 41  dExceptions(.  A
05c0: 73 63 69 69 54 6f 6b 65 6e 69 7a 65 72 20 2a 70  sciiTokenizer *p
05d0: 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  , .  const char 
05e0: 2a 7a 41 72 67 2c 20 0a 20 20 69 6e 74 20 62 54  *zArg, .  int bT
05f0: 6f 6b 65 6e 43 68 61 72 73 0a 29 7b 0a 20 20 69  okenChars.){.  i
0600: 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b  nt i;.  for(i=0;
0610: 20 7a 41 72 67 5b 69 5d 3b 20 69 2b 2b 29 7b 0a   zArg[i]; i++){.
0620: 20 20 20 20 69 66 28 20 28 7a 41 72 67 5b 69 5d      if( (zArg[i]
0630: 20 26 20 30 78 38 30 29 3d 3d 30 20 29 7b 0a 20   & 0x80)==0 ){. 
0640: 20 20 20 20 20 70 2d 3e 61 54 6f 6b 65 6e 43 68       p->aTokenCh
0650: 61 72 5b 28 69 6e 74 29 7a 41 72 67 5b 69 5d 5d  ar[(int)zArg[i]]
0660: 20 3d 20 28 75 6e 73 69 67 6e 65 64 20 63 68 61   = (unsigned cha
0670: 72 29 62 54 6f 6b 65 6e 43 68 61 72 73 3b 0a 20  r)bTokenChars;. 
0680: 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a     }.  }.}../*.*
0690: 2a 20 43 72 65 61 74 65 20 61 20 22 61 73 63 69  * Create a "asci
06a0: 69 22 20 74 6f 6b 65 6e 69 7a 65 72 2e 0a 2a 2f  i" tokenizer..*/
06b0: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
06c0: 41 73 63 69 69 43 72 65 61 74 65 28 0a 20 20 76  AsciiCreate(.  v
06d0: 6f 69 64 20 2a 70 43 74 78 2c 20 0a 20 20 63 6f  oid *pCtx, .  co
06e0: 6e 73 74 20 63 68 61 72 20 2a 2a 61 7a 41 72 67  nst char **azArg
06f0: 2c 20 69 6e 74 20 6e 41 72 67 2c 0a 20 20 46 74  , int nArg,.  Ft
0700: 73 35 54 6f 6b 65 6e 69 7a 65 72 20 2a 2a 70 70  s5Tokenizer **pp
0710: 4f 75 74 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20  Out.){.  int rc 
0720: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 41  = SQLITE_OK;.  A
0730: 73 63 69 69 54 6f 6b 65 6e 69 7a 65 72 20 2a 70  sciiTokenizer *p
0740: 20 3d 20 30 3b 0a 20 20 69 66 28 20 6e 41 72 67   = 0;.  if( nArg
0750: 25 32 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53  %2 ){.    rc = S
0760: 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d  QLITE_ERROR;.  }
0770: 65 6c 73 65 7b 0a 20 20 20 20 70 20 3d 20 73 71  else{.    p = sq
0780: 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a  lite3_malloc(siz
0790: 65 6f 66 28 41 73 63 69 69 54 6f 6b 65 6e 69 7a  eof(AsciiTokeniz
07a0: 65 72 29 29 3b 0a 20 20 20 20 69 66 28 20 70 3d  er));.    if( p=
07b0: 3d 30 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  =0 ){.      rc =
07c0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
07d0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
07e0: 69 6e 74 20 69 3b 0a 20 20 20 20 20 20 6d 65 6d  int i;.      mem
07f0: 73 65 74 28 70 2c 20 30 2c 20 73 69 7a 65 6f 66  set(p, 0, sizeof
0800: 28 41 73 63 69 69 54 6f 6b 65 6e 69 7a 65 72 29  (AsciiTokenizer)
0810: 29 3b 0a 20 20 20 20 20 20 6d 65 6d 63 70 79 28  );.      memcpy(
0820: 70 2d 3e 61 54 6f 6b 65 6e 43 68 61 72 2c 20 61  p->aTokenChar, a
0830: 41 73 63 69 69 54 6f 6b 65 6e 43 68 61 72 2c 20  AsciiTokenChar, 
0840: 73 69 7a 65 6f 66 28 61 41 73 63 69 69 54 6f 6b  sizeof(aAsciiTok
0850: 65 6e 43 68 61 72 29 29 3b 0a 20 20 20 20 20 20  enChar));.      
0860: 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c  for(i=0; rc==SQL
0870: 49 54 45 5f 4f 4b 20 26 26 20 69 3c 6e 41 72 67  ITE_OK && i<nArg
0880: 3b 20 69 2b 3d 32 29 7b 0a 20 20 20 20 20 20 20  ; i+=2){.       
0890: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 41 72   const char *zAr
08a0: 67 20 3d 20 61 7a 41 72 67 5b 69 2b 31 5d 3b 0a  g = azArg[i+1];.
08b0: 20 20 20 20 20 20 20 20 69 66 28 20 30 3d 3d 73          if( 0==s
08c0: 71 6c 69 74 65 33 5f 73 74 72 69 63 6d 70 28 61  qlite3_stricmp(a
08d0: 7a 41 72 67 5b 69 5d 2c 20 22 74 6f 6b 65 6e 63  zArg[i], "tokenc
08e0: 68 61 72 73 22 29 20 29 7b 0a 20 20 20 20 20 20  hars") ){.      
08f0: 20 20 20 20 66 74 73 35 41 73 63 69 69 41 64 64      fts5AsciiAdd
0900: 45 78 63 65 70 74 69 6f 6e 73 28 70 2c 20 7a 41  Exceptions(p, zA
0910: 72 67 2c 20 31 29 3b 0a 20 20 20 20 20 20 20 20  rg, 1);.        
0920: 7d 65 6c 73 65 0a 20 20 20 20 20 20 20 20 69 66  }else.        if
0930: 28 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74 72  ( 0==sqlite3_str
0940: 69 63 6d 70 28 61 7a 41 72 67 5b 69 5d 2c 20 22  icmp(azArg[i], "
0950: 73 65 70 61 72 61 74 6f 72 73 22 29 20 29 7b 0a  separators") ){.
0960: 20 20 20 20 20 20 20 20 20 20 66 74 73 35 41 73            fts5As
0970: 63 69 69 41 64 64 45 78 63 65 70 74 69 6f 6e 73  ciiAddExceptions
0980: 28 70 2c 20 7a 41 72 67 2c 20 30 29 3b 0a 20 20  (p, zArg, 0);.  
0990: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
09a0: 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49         rc = SQLI
09b0: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  TE_ERROR;.      
09c0: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
09d0: 7d 0a 20 20 7d 0a 0a 20 20 2a 70 70 4f 75 74 20  }.  }..  *ppOut 
09e0: 3d 20 28 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72  = (Fts5Tokenizer
09f0: 2a 29 70 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  *)p;.  return rc
0a00: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 6c 65 74  ;.}../*.** Delet
0a10: 65 20 61 20 22 61 73 63 69 69 22 20 74 6f 6b 65  e a "ascii" toke
0a20: 6e 69 7a 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63  nizer..*/.static
0a30: 20 76 6f 69 64 20 66 74 73 35 41 73 63 69 69 44   void fts5AsciiD
0a40: 65 6c 65 74 65 28 46 74 73 35 54 6f 6b 65 6e 69  elete(Fts5Tokeni
0a50: 7a 65 72 20 2a 70 29 7b 0a 20 20 73 71 6c 69 74  zer *p){.  sqlit
0a60: 65 33 5f 66 72 65 65 28 70 29 3b 0a 7d 0a 0a 0a  e3_free(p);.}...
0a70: 73 74 61 74 69 63 20 76 6f 69 64 20 61 73 63 69  static void asci
0a80: 69 46 6f 6c 64 28 63 68 61 72 20 2a 61 4f 75 74  iFold(char *aOut
0a90: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 49  , const char *aI
0aa0: 6e 2c 20 69 6e 74 20 6e 42 79 74 65 29 7b 0a 20  n, int nByte){. 
0ab0: 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d   int i;.  for(i=
0ac0: 30 3b 20 69 3c 6e 42 79 74 65 3b 20 69 2b 2b 29  0; i<nByte; i++)
0ad0: 7b 0a 20 20 20 20 63 68 61 72 20 63 20 3d 20 61  {.    char c = a
0ae0: 49 6e 5b 69 5d 3b 0a 20 20 20 20 69 66 28 20 63  In[i];.    if( c
0af0: 3e 3d 27 41 27 20 26 26 20 63 3c 3d 27 5a 27 20  >='A' && c<='Z' 
0b00: 29 20 63 20 2b 3d 20 33 32 3b 0a 20 20 20 20 61  ) c += 32;.    a
0b10: 4f 75 74 5b 69 5d 20 3d 20 63 3b 0a 20 20 7d 0a  Out[i] = c;.  }.
0b20: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 6f 6b 65 6e 69 7a  }../*.** Tokeniz
0b30: 65 20 73 6f 6d 65 20 74 65 78 74 20 75 73 69 6e  e some text usin
0b40: 67 20 74 68 65 20 61 73 63 69 69 20 74 6f 6b 65  g the ascii toke
0b50: 6e 69 7a 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63  nizer..*/.static
0b60: 20 69 6e 74 20 66 74 73 35 41 73 63 69 69 54 6f   int fts5AsciiTo
0b70: 6b 65 6e 69 7a 65 28 0a 20 20 46 74 73 35 54 6f  kenize(.  Fts5To
0b80: 6b 65 6e 69 7a 65 72 20 2a 70 54 6f 6b 65 6e 69  kenizer *pTokeni
0b90: 7a 65 72 2c 0a 20 20 76 6f 69 64 20 2a 70 43 74  zer,.  void *pCt
0ba0: 78 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  x,.  const char 
0bb0: 2a 70 54 65 78 74 2c 20 69 6e 74 20 6e 54 65 78  *pText, int nTex
0bc0: 74 2c 0a 20 20 69 6e 74 20 28 2a 78 54 6f 6b 65  t,.  int (*xToke
0bd0: 6e 29 28 76 6f 69 64 2a 2c 20 63 6f 6e 73 74 20  n)(void*, const 
0be0: 63 68 61 72 2a 2c 20 69 6e 74 20 6e 54 6f 6b 65  char*, int nToke
0bf0: 6e 2c 20 69 6e 74 20 69 53 74 61 72 74 2c 20 69  n, int iStart, i
0c00: 6e 74 20 69 45 6e 64 29 0a 29 7b 0a 20 20 41 73  nt iEnd).){.  As
0c10: 63 69 69 54 6f 6b 65 6e 69 7a 65 72 20 2a 70 20  ciiTokenizer *p 
0c20: 3d 20 28 41 73 63 69 69 54 6f 6b 65 6e 69 7a 65  = (AsciiTokenize
0c30: 72 2a 29 70 54 6f 6b 65 6e 69 7a 65 72 3b 0a 20  r*)pTokenizer;. 
0c40: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
0c50: 5f 4f 4b 3b 0a 20 20 69 6e 74 20 69 65 3b 0a 20  _OK;.  int ie;. 
0c60: 20 69 6e 74 20 69 73 20 3d 20 30 3b 0a 0a 20 20   int is = 0;..  
0c70: 63 68 61 72 20 61 46 6f 6c 64 5b 36 34 5d 3b 0a  char aFold[64];.
0c80: 20 20 69 6e 74 20 6e 46 6f 6c 64 20 3d 20 73 69    int nFold = si
0c90: 7a 65 6f 66 28 61 46 6f 6c 64 29 3b 0a 20 20 63  zeof(aFold);.  c
0ca0: 68 61 72 20 2a 70 46 6f 6c 64 20 3d 20 61 46 6f  har *pFold = aFo
0cb0: 6c 64 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 63  ld;.  unsigned c
0cc0: 68 61 72 20 2a 61 20 3d 20 70 2d 3e 61 54 6f 6b  har *a = p->aTok
0cd0: 65 6e 43 68 61 72 3b 0a 0a 20 20 77 68 69 6c 65  enChar;..  while
0ce0: 28 20 69 73 3c 6e 54 65 78 74 20 26 26 20 72 63  ( is<nText && rc
0cf0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
0d00: 20 20 20 69 6e 74 20 6e 42 79 74 65 3b 0a 0a 20     int nByte;.. 
0d10: 20 20 20 2f 2a 20 53 6b 69 70 20 61 6e 79 20 6c     /* Skip any l
0d20: 65 61 64 69 6e 67 20 64 69 76 69 64 65 72 20 63  eading divider c
0d30: 68 61 72 61 63 74 65 72 73 2e 20 2a 2f 0a 20 20  haracters. */.  
0d40: 20 20 77 68 69 6c 65 28 20 69 73 3c 6e 54 65 78    while( is<nTex
0d50: 74 20 26 26 20 28 28 70 54 65 78 74 5b 69 73 5d  t && ((pText[is]
0d60: 26 30 78 38 30 29 3d 3d 30 20 26 26 20 61 5b 28  &0x80)==0 && a[(
0d70: 69 6e 74 29 70 54 65 78 74 5b 69 73 5d 5d 3d 3d  int)pText[is]]==
0d80: 30 29 20 29 7b 0a 20 20 20 20 20 20 69 73 2b 2b  0) ){.      is++
0d90: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
0da0: 69 73 3d 3d 6e 54 65 78 74 20 29 20 62 72 65 61  is==nText ) brea
0db0: 6b 3b 0a 0a 20 20 20 20 2f 2a 20 43 6f 75 6e 74  k;..    /* Count
0dc0: 20 74 68 65 20 74 6f 6b 65 6e 20 63 68 61 72 61   the token chara
0dd0: 63 74 65 72 73 20 2a 2f 0a 20 20 20 20 69 65 20  cters */.    ie 
0de0: 3d 20 69 73 2b 31 3b 0a 20 20 20 20 77 68 69 6c  = is+1;.    whil
0df0: 65 28 20 69 65 3c 6e 54 65 78 74 20 26 26 20 28  e( ie<nText && (
0e00: 28 70 54 65 78 74 5b 69 65 5d 26 30 78 38 30 29  (pText[ie]&0x80)
0e10: 20 7c 7c 20 61 5b 28 69 6e 74 29 70 54 65 78 74   || a[(int)pText
0e20: 5b 69 65 5d 5d 20 29 20 29 7b 0a 20 20 20 20 20  [ie]] ) ){.     
0e30: 20 69 65 2b 2b 3b 0a 20 20 20 20 7d 0a 0a 20 20   ie++;.    }..  
0e40: 20 20 2f 2a 20 46 6f 6c 64 20 74 6f 20 6c 6f 77    /* Fold to low
0e50: 65 72 20 63 61 73 65 20 2a 2f 0a 20 20 20 20 6e  er case */.    n
0e60: 42 79 74 65 20 3d 20 69 65 2d 69 73 3b 0a 20 20  Byte = ie-is;.  
0e70: 20 20 69 66 28 20 6e 42 79 74 65 3e 6e 46 6f 6c    if( nByte>nFol
0e80: 64 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70  d ){.      if( p
0e90: 46 6f 6c 64 21 3d 61 46 6f 6c 64 20 29 20 73 71  Fold!=aFold ) sq
0ea0: 6c 69 74 65 33 5f 66 72 65 65 28 70 46 6f 6c 64  lite3_free(pFold
0eb0: 29 3b 0a 20 20 20 20 20 20 70 46 6f 6c 64 20 3d  );.      pFold =
0ec0: 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28   sqlite3_malloc(
0ed0: 6e 42 79 74 65 2a 32 29 3b 0a 20 20 20 20 20 20  nByte*2);.      
0ee0: 69 66 28 20 70 46 6f 6c 64 3d 3d 30 20 29 7b 0a  if( pFold==0 ){.
0ef0: 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c          rc = SQL
0f00: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20  ITE_NOMEM;.     
0f10: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
0f20: 7d 0a 20 20 20 20 20 20 6e 46 6f 6c 64 20 3d 20  }.      nFold = 
0f30: 6e 42 79 74 65 2a 32 3b 0a 20 20 20 20 7d 0a 20  nByte*2;.    }. 
0f40: 20 20 20 61 73 63 69 69 46 6f 6c 64 28 70 46 6f     asciiFold(pFo
0f50: 6c 64 2c 20 26 70 54 65 78 74 5b 69 73 5d 2c 20  ld, &pText[is], 
0f60: 6e 42 79 74 65 29 3b 0a 0a 20 20 20 20 2f 2a 20  nByte);..    /* 
0f70: 49 6e 76 6f 6b 65 20 74 68 65 20 74 6f 6b 65 6e  Invoke the token
0f80: 20 63 61 6c 6c 62 61 63 6b 20 2a 2f 0a 20 20 20   callback */.   
0f90: 20 72 63 20 3d 20 78 54 6f 6b 65 6e 28 70 43 74   rc = xToken(pCt
0fa0: 78 2c 20 70 46 6f 6c 64 2c 20 6e 42 79 74 65 2c  x, pFold, nByte,
0fb0: 20 69 73 2c 20 69 65 29 3b 0a 20 20 20 20 69 73   is, ie);.    is
0fc0: 20 3d 20 69 65 2b 31 3b 0a 20 20 7d 0a 20 20 0a   = ie+1;.  }.  .
0fd0: 20 20 69 66 28 20 70 46 6f 6c 64 21 3d 61 46 6f    if( pFold!=aFo
0fe0: 6c 64 20 29 20 73 71 6c 69 74 65 33 5f 66 72 65  ld ) sqlite3_fre
0ff0: 65 28 70 46 6f 6c 64 29 3b 0a 20 20 69 66 28 20  e(pFold);.  if( 
1000: 72 63 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20  rc==SQLITE_DONE 
1010: 29 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  ) rc = SQLITE_OK
1020: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
1030: 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ../*************
1040: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
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 0a 2a 2a  *************.**
1080: 20 53 74 61 72 74 20 6f 66 20 75 6e 69 63 6f 64   Start of unicod
1090: 65 36 31 20 74 6f 6b 65 6e 69 7a 65 72 20 69 6d  e61 tokenizer im
10a0: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2f  plementation..*/
10b0: 0a 0a 2f 2a 0a 2a 2a 20 46 75 6e 63 74 69 6f 6e  ../*.** Function
10c0: 73 20 69 6e 20 66 74 73 35 5f 75 6e 69 63 6f 64  s in fts5_unicod
10d0: 65 32 2e 63 2e 20 0a 2a 2f 0a 69 6e 74 20 73 71  e2.c. .*/.int sq
10e0: 6c 69 74 65 33 46 74 73 35 55 6e 69 63 6f 64 65  lite3Fts5Unicode
10f0: 49 73 61 6c 6e 75 6d 28 69 6e 74 20 63 29 3b 0a  Isalnum(int c);.
1100: 69 6e 74 20 73 71 6c 69 74 65 33 46 74 73 35 55  int sqlite3Fts5U
1110: 6e 69 63 6f 64 65 49 73 64 69 61 63 72 69 74 69  nicodeIsdiacriti
1120: 63 28 69 6e 74 20 63 29 3b 0a 69 6e 74 20 73 71  c(int c);.int sq
1130: 6c 69 74 65 33 46 74 73 35 55 6e 69 63 6f 64 65  lite3Fts5Unicode
1140: 46 6f 6c 64 28 69 6e 74 20 63 2c 20 69 6e 74 20  Fold(int c, int 
1150: 62 52 65 6d 6f 76 65 44 69 61 63 72 69 74 69 63  bRemoveDiacritic
1160: 29 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 66  );.../*.** The f
1170: 6f 6c 6c 6f 77 69 6e 67 20 74 77 6f 20 6d 61 63  ollowing two mac
1180: 72 6f 73 20 2d 20 52 45 41 44 5f 55 54 46 38 20  ros - READ_UTF8 
1190: 61 6e 64 20 57 52 49 54 45 5f 55 54 46 38 20 2d  and WRITE_UTF8 -
11a0: 20 68 61 76 65 20 62 65 65 6e 20 63 6f 70 69 65   have been copie
11b0: 64 0a 2a 2a 20 66 72 6f 6d 20 74 68 65 20 73 71  d.** from the sq
11c0: 6c 69 74 65 33 20 73 6f 75 72 63 65 20 66 69 6c  lite3 source fil
11d0: 65 20 75 74 66 2e 63 2e 20 49 66 20 74 68 69 73  e utf.c. If this
11e0: 20 66 69 6c 65 20 69 73 20 63 6f 6d 70 69 6c 65   file is compile
11f0: 64 20 61 73 20 70 61 72 74 0a 2a 2a 20 6f 66 20  d as part.** of 
1200: 74 68 65 20 61 6d 61 6c 67 61 6d 61 74 69 6f 6e  the amalgamation
1210: 2c 20 74 68 65 79 20 61 72 65 20 6e 6f 74 20 72  , they are not r
1220: 65 71 75 69 72 65 64 2e 0a 2a 2f 0a 23 69 66 6e  equired..*/.#ifn
1230: 64 65 66 20 53 51 4c 49 54 45 5f 41 4d 41 4c 47  def SQLITE_AMALG
1240: 41 4d 41 54 49 4f 4e 0a 0a 73 74 61 74 69 63 20  AMATION..static 
1250: 63 6f 6e 73 74 20 75 6e 73 69 67 6e 65 64 20 63  const unsigned c
1260: 68 61 72 20 73 71 6c 69 74 65 33 55 74 66 38 54  har sqlite3Utf8T
1270: 72 61 6e 73 31 5b 5d 20 3d 20 7b 0a 20 20 30 78  rans1[] = {.  0x
1280: 30 30 2c 20 30 78 30 31 2c 20 30 78 30 32 2c 20  00, 0x01, 0x02, 
1290: 30 78 30 33 2c 20 30 78 30 34 2c 20 30 78 30 35  0x03, 0x04, 0x05
12a0: 2c 20 30 78 30 36 2c 20 30 78 30 37 2c 0a 20 20  , 0x06, 0x07,.  
12b0: 30 78 30 38 2c 20 30 78 30 39 2c 20 30 78 30 61  0x08, 0x09, 0x0a
12c0: 2c 20 30 78 30 62 2c 20 30 78 30 63 2c 20 30 78  , 0x0b, 0x0c, 0x
12d0: 30 64 2c 20 30 78 30 65 2c 20 30 78 30 66 2c 0a  0d, 0x0e, 0x0f,.
12e0: 20 20 30 78 31 30 2c 20 30 78 31 31 2c 20 30 78    0x10, 0x11, 0x
12f0: 31 32 2c 20 30 78 31 33 2c 20 30 78 31 34 2c 20  12, 0x13, 0x14, 
1300: 30 78 31 35 2c 20 30 78 31 36 2c 20 30 78 31 37  0x15, 0x16, 0x17
1310: 2c 0a 20 20 30 78 31 38 2c 20 30 78 31 39 2c 20  ,.  0x18, 0x19, 
1320: 30 78 31 61 2c 20 30 78 31 62 2c 20 30 78 31 63  0x1a, 0x1b, 0x1c
1330: 2c 20 30 78 31 64 2c 20 30 78 31 65 2c 20 30 78  , 0x1d, 0x1e, 0x
1340: 31 66 2c 0a 20 20 30 78 30 30 2c 20 30 78 30 31  1f,.  0x00, 0x01
1350: 2c 20 30 78 30 32 2c 20 30 78 30 33 2c 20 30 78  , 0x02, 0x03, 0x
1360: 30 34 2c 20 30 78 30 35 2c 20 30 78 30 36 2c 20  04, 0x05, 0x06, 
1370: 30 78 30 37 2c 0a 20 20 30 78 30 38 2c 20 30 78  0x07,.  0x08, 0x
1380: 30 39 2c 20 30 78 30 61 2c 20 30 78 30 62 2c 20  09, 0x0a, 0x0b, 
1390: 30 78 30 63 2c 20 30 78 30 64 2c 20 30 78 30 65  0x0c, 0x0d, 0x0e
13a0: 2c 20 30 78 30 66 2c 0a 20 20 30 78 30 30 2c 20  , 0x0f,.  0x00, 
13b0: 30 78 30 31 2c 20 30 78 30 32 2c 20 30 78 30 33  0x01, 0x02, 0x03
13c0: 2c 20 30 78 30 34 2c 20 30 78 30 35 2c 20 30 78  , 0x04, 0x05, 0x
13d0: 30 36 2c 20 30 78 30 37 2c 0a 20 20 30 78 30 30  06, 0x07,.  0x00
13e0: 2c 20 30 78 30 31 2c 20 30 78 30 32 2c 20 30 78  , 0x01, 0x02, 0x
13f0: 30 33 2c 20 30 78 30 30 2c 20 30 78 30 31 2c 20  03, 0x00, 0x01, 
1400: 30 78 30 30 2c 20 30 78 30 30 2c 0a 7d 3b 0a 0a  0x00, 0x00,.};..
1410: 23 64 65 66 69 6e 65 20 52 45 41 44 5f 55 54 46  #define READ_UTF
1420: 38 28 7a 49 6e 2c 20 7a 54 65 72 6d 2c 20 63 29  8(zIn, zTerm, c)
1430: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1440: 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 63             \.  c
1450: 20 3d 20 2a 28 7a 49 6e 2b 2b 29 3b 20 20 20 20   = *(zIn++);    
1460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1480: 20 20 20 20 20 20 20 20 5c 0a 20 20 69 66 28 20          \.  if( 
1490: 63 3e 3d 30 78 63 30 20 29 7b 20 20 20 20 20 20  c>=0xc0 ){      
14a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14c0: 20 20 20 20 20 5c 0a 20 20 20 20 63 20 3d 20 73       \.    c = s
14d0: 71 6c 69 74 65 33 55 74 66 38 54 72 61 6e 73 31  qlite3Utf8Trans1
14e0: 5b 63 2d 30 78 63 30 5d 3b 20 20 20 20 20 20 20  [c-0xc0];       
14f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1500: 20 20 5c 0a 20 20 20 20 77 68 69 6c 65 28 20 7a    \.    while( z
1510: 49 6e 21 3d 7a 54 65 72 6d 20 26 26 20 28 2a 7a  In!=zTerm && (*z
1520: 49 6e 20 26 20 30 78 63 30 29 3d 3d 30 78 38 30  In & 0xc0)==0x80
1530: 20 29 7b 20 20 20 20 20 20 20 20 20 20 20 20 5c   ){            \
1540: 0a 20 20 20 20 20 20 63 20 3d 20 28 63 3c 3c 36  .      c = (c<<6
1550: 29 20 2b 20 28 30 78 33 66 20 26 20 2a 28 7a 49  ) + (0x3f & *(zI
1560: 6e 2b 2b 29 29 3b 20 20 20 20 20 20 20 20 20 20  n++));          
1570: 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20              \.  
1580: 20 20 7d 20 20 20 20 20 20 20 20 20 20 20 20 20    }             
1590: 20 20 20 20 20 20 20 20 20 20 20 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 5c 0a 20 20 20 20 69           \.    i
15c0: 66 28 20 63 3c 30 78 38 30 20 20 20 20 20 20 20  f( c<0x80       
15d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15f0: 20 20 20 20 20 20 5c 0a 20 20 20 20 20 20 20 20        \.        
1600: 7c 7c 20 28 63 26 30 78 46 46 46 46 46 38 30 30  || (c&0xFFFFF800
1610: 29 3d 3d 30 78 44 38 30 30 20 20 20 20 20 20 20  )==0xD800       
1620: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1630: 20 20 20 5c 0a 20 20 20 20 20 20 20 20 7c 7c 20     \.        || 
1640: 28 63 26 30 78 46 46 46 46 46 46 46 45 29 3d 3d  (c&0xFFFFFFFE)==
1650: 30 78 46 46 46 45 20 29 7b 20 20 63 20 3d 20 30  0xFFFE ){  c = 0
1660: 78 46 46 46 44 3b 20 7d 20 20 20 20 20 20 20 20  xFFFD; }        
1670: 5c 0a 20 20 7d 0a 0a 0a 23 64 65 66 69 6e 65 20  \.  }...#define 
1680: 57 52 49 54 45 5f 55 54 46 38 28 7a 4f 75 74 2c  WRITE_UTF8(zOut,
1690: 20 63 29 20 7b 20 20 20 20 20 20 20 20 20 20 20   c) {           
16a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c                 \
16b0: 0a 20 20 69 66 28 20 63 3c 30 78 30 30 30 38 30  .  if( c<0x00080
16c0: 20 29 7b 20 20 20 20 20 20 20 20 20 20 20 20 20   ){             
16d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16e0: 20 20 20 20 20 20 20 20 5c 0a 20 20 20 20 2a 7a          \.    *z
16f0: 4f 75 74 2b 2b 20 3d 20 28 75 6e 73 69 67 6e 65  Out++ = (unsigne
1700: 64 20 63 68 61 72 29 28 63 26 30 78 46 46 29 3b  d char)(c&0xFF);
1710: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1720: 20 5c 0a 20 20 7d 20 20 20 20 20 20 20 20 20 20   \.  }          
1730: 20 20 20 20 20 20 20 20 20 20 20 20 20 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 5c 0a 20 20 65 6c            \.  el
1760: 73 65 20 69 66 28 20 63 3c 30 78 30 30 38 30 30  se if( c<0x00800
1770: 20 29 7b 20 20 20 20 20 20 20 20 20 20 20 20 20   ){             
1780: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1790: 20 20 20 5c 0a 20 20 20 20 2a 7a 4f 75 74 2b 2b     \.    *zOut++
17a0: 20 3d 20 30 78 43 30 20 2b 20 28 75 6e 73 69 67   = 0xC0 + (unsig
17b0: 6e 65 64 20 63 68 61 72 29 28 28 63 3e 3e 36 29  ned char)((c>>6)
17c0: 26 30 78 31 46 29 3b 20 20 20 20 20 5c 0a 20 20  &0x1F);     \.  
17d0: 20 20 2a 7a 4f 75 74 2b 2b 20 3d 20 30 78 38 30    *zOut++ = 0x80
17e0: 20 2b 20 28 75 6e 73 69 67 6e 65 64 20 63 68 61   + (unsigned cha
17f0: 72 29 28 63 20 26 20 30 78 33 46 29 3b 20 20 20  r)(c & 0x3F);   
1800: 20 20 20 20 20 5c 0a 20 20 7d 20 20 20 20 20 20       \.  }      
1810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1820: 20 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 5c 0a                \.
1840: 20 20 65 6c 73 65 20 69 66 28 20 63 3c 30 78 31    else if( c<0x1
1850: 30 30 30 30 20 29 7b 20 20 20 20 20 20 20 20 20  0000 ){         
1860: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1870: 20 20 20 20 20 20 20 5c 0a 20 20 20 20 2a 7a 4f         \.    *zO
1880: 75 74 2b 2b 20 3d 20 30 78 45 30 20 2b 20 28 75  ut++ = 0xE0 + (u
1890: 6e 73 69 67 6e 65 64 20 63 68 61 72 29 28 28 63  nsigned char)((c
18a0: 3e 3e 31 32 29 26 30 78 30 46 29 3b 20 20 20 20  >>12)&0x0F);    
18b0: 5c 0a 20 20 20 20 2a 7a 4f 75 74 2b 2b 20 3d 20  \.    *zOut++ = 
18c0: 30 78 38 30 20 2b 20 28 75 6e 73 69 67 6e 65 64  0x80 + (unsigned
18d0: 20 63 68 61 72 29 28 28 63 3e 3e 36 29 20 26 20   char)((c>>6) & 
18e0: 30 78 33 46 29 3b 20 20 20 5c 0a 20 20 20 20 2a  0x3F);   \.    *
18f0: 7a 4f 75 74 2b 2b 20 3d 20 30 78 38 30 20 2b 20  zOut++ = 0x80 + 
1900: 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72 29 28  (unsigned char)(
1910: 63 20 26 20 30 78 33 46 29 3b 20 20 20 20 20 20  c & 0x3F);      
1920: 20 20 5c 0a 20 20 7d 65 6c 73 65 7b 20 20 20 20    \.  }else{    
1930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1940: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1950: 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20             \.   
1960: 20 2a 7a 4f 75 74 2b 2b 20 3d 20 30 78 46 30 20   *zOut++ = 0xF0 
1970: 2b 20 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72  + (unsigned char
1980: 29 28 28 63 3e 3e 31 38 29 20 26 20 30 78 30 37  )((c>>18) & 0x07
1990: 29 3b 20 20 5c 0a 20 20 20 20 2a 7a 4f 75 74 2b  );  \.    *zOut+
19a0: 2b 20 3d 20 30 78 38 30 20 2b 20 28 75 6e 73 69  + = 0x80 + (unsi
19b0: 67 6e 65 64 20 63 68 61 72 29 28 28 63 3e 3e 31  gned char)((c>>1
19c0: 32 29 20 26 20 30 78 33 46 29 3b 20 20 5c 0a 20  2) & 0x3F);  \. 
19d0: 20 20 20 2a 7a 4f 75 74 2b 2b 20 3d 20 30 78 38     *zOut++ = 0x8
19e0: 30 20 2b 20 28 75 6e 73 69 67 6e 65 64 20 63 68  0 + (unsigned ch
19f0: 61 72 29 28 28 63 3e 3e 36 29 20 26 20 30 78 33  ar)((c>>6) & 0x3
1a00: 46 29 3b 20 20 20 5c 0a 20 20 20 20 2a 7a 4f 75  F);   \.    *zOu
1a10: 74 2b 2b 20 3d 20 30 78 38 30 20 2b 20 28 75 6e  t++ = 0x80 + (un
1a20: 73 69 67 6e 65 64 20 63 68 61 72 29 28 63 20 26  signed char)(c &
1a30: 20 30 78 33 46 29 3b 20 20 20 20 20 20 20 20 5c   0x3F);        \
1a40: 0a 20 20 7d 20 20 20 20 20 20 20 20 20 20 20 20  .  }            
1a50: 20 20 20 20 20 20 20 20 20 20 20 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 5c 0a 7d 0a 0a 23 65 6e          \.}..#en
1a80: 64 69 66 20 2f 2a 20 69 66 6e 64 65 66 20 53 51  dif /* ifndef SQ
1a90: 4c 49 54 45 5f 41 4d 41 4c 47 41 4d 41 54 49 4f  LITE_AMALGAMATIO
1aa0: 4e 20 2a 2f 0a 0a 74 79 70 65 64 65 66 20 73 74  N */..typedef st
1ab0: 72 75 63 74 20 55 6e 69 63 6f 64 65 36 31 54 6f  ruct Unicode61To
1ac0: 6b 65 6e 69 7a 65 72 20 55 6e 69 63 6f 64 65 36  kenizer Unicode6
1ad0: 31 54 6f 6b 65 6e 69 7a 65 72 3b 0a 73 74 72 75  1Tokenizer;.stru
1ae0: 63 74 20 55 6e 69 63 6f 64 65 36 31 54 6f 6b 65  ct Unicode61Toke
1af0: 6e 69 7a 65 72 20 7b 0a 20 20 75 6e 73 69 67 6e  nizer {.  unsign
1b00: 65 64 20 63 68 61 72 20 61 54 6f 6b 65 6e 43 68  ed char aTokenCh
1b10: 61 72 5b 31 32 38 5d 3b 20 20 2f 2a 20 41 53 43  ar[128];  /* ASC
1b20: 49 49 20 72 61 6e 67 65 20 74 6f 6b 65 6e 20 63  II range token c
1b30: 68 61 72 61 63 74 65 72 73 20 2a 2f 0a 20 20 63  haracters */.  c
1b40: 68 61 72 20 2a 61 46 6f 6c 64 3b 20 20 20 20 20  har *aFold;     
1b50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1b60: 2a 20 42 75 66 66 65 72 20 74 6f 20 66 6f 6c 64  * Buffer to fold
1b70: 20 74 65 78 74 20 69 6e 74 6f 20 2a 2f 0a 20 20   text into */.  
1b80: 69 6e 74 20 6e 46 6f 6c 64 3b 20 20 20 20 20 20  int nFold;      
1b90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ba0: 2f 2a 20 53 69 7a 65 20 6f 66 20 61 46 6f 6c 64  /* Size of aFold
1bb0: 5b 5d 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20  [] in bytes */. 
1bc0: 20 69 6e 74 20 62 52 65 6d 6f 76 65 44 69 61 63   int bRemoveDiac
1bd0: 72 69 74 69 63 3b 20 20 20 20 20 20 20 20 20 20  ritic;          
1be0: 20 2f 2a 20 54 72 75 65 20 69 66 20 72 65 6d 6f   /* True if remo
1bf0: 76 65 5f 64 69 61 63 72 69 74 69 63 73 3d 31 20  ve_diacritics=1 
1c00: 69 73 20 73 65 74 20 2a 2f 0a 20 20 69 6e 74 20  is set */.  int 
1c10: 6e 45 78 63 65 70 74 69 6f 6e 3b 0a 20 20 69 6e  nException;.  in
1c20: 74 20 2a 61 69 45 78 63 65 70 74 69 6f 6e 3b 0a  t *aiException;.
1c30: 7d 3b 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66  };..static int f
1c40: 74 73 35 55 6e 69 63 6f 64 65 41 64 64 45 78 63  ts5UnicodeAddExc
1c50: 65 70 74 69 6f 6e 73 28 0a 20 20 55 6e 69 63 6f  eptions(.  Unico
1c60: 64 65 36 31 54 6f 6b 65 6e 69 7a 65 72 20 2a 70  de61Tokenizer *p
1c70: 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 6f  ,          /* To
1c80: 6b 65 6e 69 7a 65 72 20 6f 62 6a 65 63 74 20 2a  kenizer object *
1c90: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
1ca0: 7a 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  z,              
1cb0: 20 20 20 20 2f 2a 20 43 68 61 72 61 63 74 65 72      /* Character
1cc0: 73 20 74 6f 20 74 72 65 61 74 20 61 73 20 65 78  s to treat as ex
1cd0: 63 65 70 74 69 6f 6e 73 20 2a 2f 0a 20 20 69 6e  ceptions */.  in
1ce0: 74 20 62 54 6f 6b 65 6e 43 68 61 72 73 20 20 20  t bTokenChars   
1cf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1d00: 20 31 20 66 6f 72 20 27 74 6f 6b 65 6e 63 68 61   1 for 'tokencha
1d10: 72 73 27 2c 20 30 20 66 6f 72 20 27 73 65 70 61  rs', 0 for 'sepa
1d20: 72 61 74 6f 72 73 27 20 2a 2f 0a 29 7b 0a 20 20  rators' */.){.  
1d30: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
1d40: 4f 4b 3b 0a 20 20 69 6e 74 20 6e 20 3d 20 73 74  OK;.  int n = st
1d50: 72 6c 65 6e 28 7a 29 3b 0a 20 20 69 6e 74 20 2a  rlen(z);.  int *
1d60: 61 4e 65 77 3b 0a 0a 20 20 69 66 28 20 6e 3e 30  aNew;..  if( n>0
1d70: 20 29 7b 0a 20 20 20 20 61 4e 65 77 20 3d 20 28   ){.    aNew = (
1d80: 69 6e 74 2a 29 73 71 6c 69 74 65 33 5f 72 65 61  int*)sqlite3_rea
1d90: 6c 6c 6f 63 28 70 2d 3e 61 69 45 78 63 65 70 74  lloc(p->aiExcept
1da0: 69 6f 6e 2c 20 28 6e 2b 70 2d 3e 6e 45 78 63 65  ion, (n+p->nExce
1db0: 70 74 69 6f 6e 29 2a 73 69 7a 65 6f 66 28 69 6e  ption)*sizeof(in
1dc0: 74 29 29 3b 0a 20 20 20 20 69 66 28 20 61 4e 65  t));.    if( aNe
1dd0: 77 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e  w ){.      int n
1de0: 4e 65 77 20 3d 20 70 2d 3e 6e 45 78 63 65 70 74  New = p->nExcept
1df0: 69 6f 6e 3b 0a 20 20 20 20 20 20 63 6f 6e 73 74  ion;.      const
1e00: 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a   unsigned char *
1e10: 7a 43 73 72 20 3d 20 28 63 6f 6e 73 74 20 75 6e  zCsr = (const un
1e20: 73 69 67 6e 65 64 20 63 68 61 72 2a 29 7a 3b 0a  signed char*)z;.
1e30: 20 20 20 20 20 20 63 6f 6e 73 74 20 75 6e 73 69        const unsi
1e40: 67 6e 65 64 20 63 68 61 72 20 2a 7a 54 65 72 6d  gned char *zTerm
1e50: 20 3d 20 28 63 6f 6e 73 74 20 75 6e 73 69 67 6e   = (const unsign
1e60: 65 64 20 63 68 61 72 2a 29 26 7a 5b 6e 5d 3b 0a  ed char*)&z[n];.
1e70: 20 20 20 20 20 20 77 68 69 6c 65 28 20 7a 43 73        while( zCs
1e80: 72 3c 7a 54 65 72 6d 20 29 7b 0a 20 20 20 20 20  r<zTerm ){.     
1e90: 20 20 20 69 6e 74 20 69 43 6f 64 65 3b 0a 20 20     int iCode;.  
1ea0: 20 20 20 20 20 20 69 6e 74 20 62 54 6f 6b 65 6e        int bToken
1eb0: 3b 0a 20 20 20 20 20 20 20 20 52 45 41 44 5f 55  ;.        READ_U
1ec0: 54 46 38 28 7a 43 73 72 2c 20 7a 54 65 72 6d 2c  TF8(zCsr, zTerm,
1ed0: 20 69 43 6f 64 65 29 3b 0a 20 20 20 20 20 20 20   iCode);.       
1ee0: 20 69 66 28 20 69 43 6f 64 65 3c 31 32 38 20 29   if( iCode<128 )
1ef0: 7b 0a 20 20 20 20 20 20 20 20 20 20 70 2d 3e 61  {.          p->a
1f00: 54 6f 6b 65 6e 43 68 61 72 5b 69 43 6f 64 65 5d  TokenChar[iCode]
1f10: 20 3d 20 62 54 6f 6b 65 6e 43 68 61 72 73 3b 0a   = bTokenChars;.
1f20: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20          }else{. 
1f30: 20 20 20 20 20 20 20 20 20 62 54 6f 6b 65 6e 20           bToken 
1f40: 3d 20 73 71 6c 69 74 65 33 46 74 73 35 55 6e 69  = sqlite3Fts5Uni
1f50: 63 6f 64 65 49 73 61 6c 6e 75 6d 28 69 43 6f 64  codeIsalnum(iCod
1f60: 65 29 3b 0a 20 20 20 20 20 20 20 20 20 20 61 73  e);.          as
1f70: 73 65 72 74 28 20 28 62 54 6f 6b 65 6e 3d 3d 30  sert( (bToken==0
1f80: 20 7c 7c 20 62 54 6f 6b 65 6e 3d 3d 31 29 20 29   || bToken==1) )
1f90: 3b 20 0a 20 20 20 20 20 20 20 20 20 20 61 73 73  ; .          ass
1fa0: 65 72 74 28 20 28 62 54 6f 6b 65 6e 43 68 61 72  ert( (bTokenChar
1fb0: 73 3d 3d 30 20 7c 7c 20 62 54 6f 6b 65 6e 43 68  s==0 || bTokenCh
1fc0: 61 72 73 3d 3d 31 29 20 29 3b 0a 20 20 20 20 20  ars==1) );.     
1fd0: 20 20 20 20 20 69 66 28 20 62 54 6f 6b 65 6e 21       if( bToken!
1fe0: 3d 62 54 6f 6b 65 6e 43 68 61 72 73 20 26 26 20  =bTokenChars && 
1ff0: 73 71 6c 69 74 65 33 46 74 73 35 55 6e 69 63 6f  sqlite3Fts5Unico
2000: 64 65 49 73 64 69 61 63 72 69 74 69 63 28 69 43  deIsdiacritic(iC
2010: 6f 64 65 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20  ode)==0 ){.     
2020: 20 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 20 20         int i;.  
2030: 20 20 20 20 20 20 20 20 20 20 66 6f 72 28 69 3d            for(i=
2040: 30 3b 20 69 3c 6e 4e 65 77 3b 20 69 2b 2b 29 7b  0; i<nNew; i++){
2050: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69  .              i
2060: 66 28 20 61 4e 65 77 5b 69 5d 3e 69 43 6f 64 65  f( aNew[i]>iCode
2070: 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20   ) break;.      
2080: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
2090: 20 20 20 20 6d 65 6d 6d 6f 76 65 28 26 61 4e 65      memmove(&aNe
20a0: 77 5b 69 2b 31 5d 2c 20 26 61 4e 65 77 5b 69 5d  w[i+1], &aNew[i]
20b0: 2c 20 28 6e 4e 65 77 2d 69 29 2a 73 69 7a 65 6f  , (nNew-i)*sizeo
20c0: 66 28 69 6e 74 29 29 3b 0a 20 20 20 20 20 20 20  f(int));.       
20d0: 20 20 20 20 20 61 4e 65 77 5b 69 5d 20 3d 20 69       aNew[i] = i
20e0: 43 6f 64 65 3b 0a 20 20 20 20 20 20 20 20 20 20  Code;.          
20f0: 20 20 6e 4e 65 77 2b 2b 3b 0a 20 20 20 20 20 20    nNew++;.      
2100: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a      }.        }.
2110: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70 2d        }.      p-
2120: 3e 61 69 45 78 63 65 70 74 69 6f 6e 20 3d 20 61  >aiException = a
2130: 4e 65 77 3b 0a 20 20 20 20 20 20 70 2d 3e 6e 45  New;.      p->nE
2140: 78 63 65 70 74 69 6f 6e 20 3d 20 6e 4e 65 77 3b  xception = nNew;
2150: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
2160: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f    rc = SQLITE_NO
2170: 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  MEM;.    }.  }..
2180: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
2190: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 72 75  /*.** Return tru
21a0: 65 20 69 66 20 74 68 65 20 70 2d 3e 61 69 45 78  e if the p->aiEx
21b0: 63 65 70 74 69 6f 6e 5b 5d 20 61 72 72 61 79 20  ception[] array 
21c0: 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 76 61 6c  contains the val
21d0: 75 65 20 69 43 6f 64 65 2e 0a 2a 2f 0a 73 74 61  ue iCode..*/.sta
21e0: 74 69 63 20 69 6e 74 20 66 74 73 35 55 6e 69 63  tic int fts5Unic
21f0: 6f 64 65 49 73 45 78 63 65 70 74 69 6f 6e 28 55  odeIsException(U
2200: 6e 69 63 6f 64 65 36 31 54 6f 6b 65 6e 69 7a 65  nicode61Tokenize
2210: 72 20 2a 70 2c 20 69 6e 74 20 69 43 6f 64 65 29  r *p, int iCode)
2220: 7b 0a 20 20 69 66 28 20 70 2d 3e 6e 45 78 63 65  {.  if( p->nExce
2230: 70 74 69 6f 6e 3e 30 20 29 7b 0a 20 20 20 20 69  ption>0 ){.    i
2240: 6e 74 20 2a 61 20 3d 20 70 2d 3e 61 69 45 78 63  nt *a = p->aiExc
2250: 65 70 74 69 6f 6e 3b 0a 20 20 20 20 69 6e 74 20  eption;.    int 
2260: 69 4c 6f 20 3d 20 30 3b 0a 20 20 20 20 69 6e 74  iLo = 0;.    int
2270: 20 69 48 69 20 3d 20 70 2d 3e 6e 45 78 63 65 70   iHi = p->nExcep
2280: 74 69 6f 6e 2d 31 3b 0a 0a 20 20 20 20 77 68 69  tion-1;..    whi
2290: 6c 65 28 20 69 48 69 3e 3d 69 4c 6f 20 29 7b 0a  le( iHi>=iLo ){.
22a0: 20 20 20 20 20 20 69 6e 74 20 69 54 65 73 74 20        int iTest 
22b0: 3d 20 28 69 48 69 20 2b 20 69 4c 6f 29 20 2f 20  = (iHi + iLo) / 
22c0: 32 3b 0a 20 20 20 20 20 20 69 66 28 20 69 43 6f  2;.      if( iCo
22d0: 64 65 3d 3d 61 5b 69 54 65 73 74 5d 20 29 7b 0a  de==a[iTest] ){.
22e0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 31          return 1
22f0: 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66  ;.      }else if
2300: 28 20 69 43 6f 64 65 3e 61 5b 69 54 65 73 74 5d  ( iCode>a[iTest]
2310: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 4c 6f 20   ){.        iLo 
2320: 3d 20 69 54 65 73 74 2b 31 3b 0a 20 20 20 20 20  = iTest+1;.     
2330: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
2340: 69 48 69 20 3d 20 69 54 65 73 74 2d 31 3b 0a 20  iHi = iTest-1;. 
2350: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
2360: 0a 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a  ..  return 0;.}.
2370: 0a 2f 2a 0a 2a 2a 20 44 65 6c 65 74 65 20 61 20  ./*.** Delete a 
2380: 22 75 6e 69 63 6f 64 65 36 31 22 20 74 6f 6b 65  "unicode61" toke
2390: 6e 69 7a 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63  nizer..*/.static
23a0: 20 76 6f 69 64 20 66 74 73 35 55 6e 69 63 6f 64   void fts5Unicod
23b0: 65 44 65 6c 65 74 65 28 46 74 73 35 54 6f 6b 65  eDelete(Fts5Toke
23c0: 6e 69 7a 65 72 20 2a 70 54 6f 6b 29 7b 0a 20 20  nizer *pTok){.  
23d0: 69 66 28 20 70 54 6f 6b 20 29 7b 0a 20 20 20 20  if( pTok ){.    
23e0: 55 6e 69 63 6f 64 65 36 31 54 6f 6b 65 6e 69 7a  Unicode61Tokeniz
23f0: 65 72 20 2a 70 20 3d 20 28 55 6e 69 63 6f 64 65  er *p = (Unicode
2400: 36 31 54 6f 6b 65 6e 69 7a 65 72 2a 29 70 54 6f  61Tokenizer*)pTo
2410: 6b 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  k;.    sqlite3_f
2420: 72 65 65 28 70 2d 3e 61 69 45 78 63 65 70 74 69  ree(p->aiExcepti
2430: 6f 6e 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  on);.    sqlite3
2440: 5f 66 72 65 65 28 70 2d 3e 61 46 6f 6c 64 29 3b  _free(p->aFold);
2450: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
2460: 65 28 70 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  e(p);.  }.  retu
2470: 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 72 65  rn;.}../*.** Cre
2480: 61 74 65 20 61 20 22 75 6e 69 63 6f 64 65 36 31  ate a "unicode61
2490: 22 20 74 6f 6b 65 6e 69 7a 65 72 2e 0a 2a 2f 0a  " tokenizer..*/.
24a0: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 55  static int fts5U
24b0: 6e 69 63 6f 64 65 43 72 65 61 74 65 28 0a 20 20  nicodeCreate(.  
24c0: 76 6f 69 64 20 2a 70 43 74 78 2c 20 0a 20 20 63  void *pCtx, .  c
24d0: 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61 7a 41 72  onst char **azAr
24e0: 67 2c 20 69 6e 74 20 6e 41 72 67 2c 0a 20 20 46  g, int nArg,.  F
24f0: 74 73 35 54 6f 6b 65 6e 69 7a 65 72 20 2a 2a 70  ts5Tokenizer **p
2500: 70 4f 75 74 0a 29 7b 0a 20 20 69 6e 74 20 72 63  pOut.){.  int rc
2510: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20   = SQLITE_OK;   
2520: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
2530: 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 55 6e  urn code */.  Un
2540: 69 63 6f 64 65 36 31 54 6f 6b 65 6e 69 7a 65 72  icode61Tokenizer
2550: 20 2a 70 20 3d 20 30 3b 20 20 20 20 20 20 2f 2a   *p = 0;      /*
2560: 20 4e 65 77 20 74 6f 6b 65 6e 69 7a 65 72 20 6f   New tokenizer o
2570: 62 6a 65 63 74 20 2a 2f 20 0a 0a 20 20 69 66 28  bject */ ..  if(
2580: 20 6e 41 72 67 25 32 20 29 7b 0a 20 20 20 20 72   nArg%2 ){.    r
2590: 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  c = SQLITE_ERROR
25a0: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70  ;.  }else{.    p
25b0: 20 3d 20 28 55 6e 69 63 6f 64 65 36 31 54 6f 6b   = (Unicode61Tok
25c0: 65 6e 69 7a 65 72 2a 29 73 71 6c 69 74 65 33 5f  enizer*)sqlite3_
25d0: 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 55 6e  malloc(sizeof(Un
25e0: 69 63 6f 64 65 36 31 54 6f 6b 65 6e 69 7a 65 72  icode61Tokenizer
25f0: 29 29 3b 0a 20 20 20 20 69 66 28 20 70 20 29 7b  ));.    if( p ){
2600: 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 20 20  .      int i;.  
2610: 20 20 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c      memset(p, 0,
2620: 20 73 69 7a 65 6f 66 28 55 6e 69 63 6f 64 65 36   sizeof(Unicode6
2630: 31 54 6f 6b 65 6e 69 7a 65 72 29 29 3b 0a 20 20  1Tokenizer));.  
2640: 20 20 20 20 6d 65 6d 63 70 79 28 70 2d 3e 61 54      memcpy(p->aT
2650: 6f 6b 65 6e 43 68 61 72 2c 20 61 41 73 63 69 69  okenChar, aAscii
2660: 54 6f 6b 65 6e 43 68 61 72 2c 20 73 69 7a 65 6f  TokenChar, sizeo
2670: 66 28 61 41 73 63 69 69 54 6f 6b 65 6e 43 68 61  f(aAsciiTokenCha
2680: 72 29 29 3b 0a 20 20 20 20 20 20 70 2d 3e 62 52  r));.      p->bR
2690: 65 6d 6f 76 65 44 69 61 63 72 69 74 69 63 20 3d  emoveDiacritic =
26a0: 20 31 3b 0a 20 20 20 20 20 20 70 2d 3e 6e 46 6f   1;.      p->nFo
26b0: 6c 64 20 3d 20 36 34 3b 0a 20 20 20 20 20 20 70  ld = 64;.      p
26c0: 2d 3e 61 46 6f 6c 64 20 3d 20 73 71 6c 69 74 65  ->aFold = sqlite
26d0: 33 5f 6d 61 6c 6c 6f 63 28 70 2d 3e 6e 46 6f 6c  3_malloc(p->nFol
26e0: 64 20 2a 20 73 69 7a 65 6f 66 28 63 68 61 72 29  d * sizeof(char)
26f0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 2d 3e  );.      if( p->
2700: 61 46 6f 6c 64 3d 3d 30 20 29 7b 0a 20 20 20 20  aFold==0 ){.    
2710: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
2720: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 7d 0a 20  NOMEM;.      }. 
2730: 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 72 63       for(i=0; rc
2740: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69  ==SQLITE_OK && i
2750: 3c 6e 41 72 67 3b 20 69 2b 3d 32 29 7b 0a 20 20  <nArg; i+=2){.  
2760: 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72        const char
2770: 20 2a 7a 41 72 67 20 3d 20 61 7a 41 72 67 5b 69   *zArg = azArg[i
2780: 2b 31 5d 3b 0a 20 20 20 20 20 20 20 20 69 66 28  +1];.        if(
2790: 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74 72 69   0==sqlite3_stri
27a0: 63 6d 70 28 61 7a 41 72 67 5b 69 5d 2c 20 22 72  cmp(azArg[i], "r
27b0: 65 6d 6f 76 65 5f 64 69 61 63 72 69 74 69 63 73  emove_diacritics
27c0: 22 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  ") ){.          
27d0: 69 66 28 20 28 7a 41 72 67 5b 30 5d 21 3d 27 30  if( (zArg[0]!='0
27e0: 27 20 26 26 20 7a 41 72 67 5b 30 5d 21 3d 27 31  ' && zArg[0]!='1
27f0: 27 29 20 7c 7c 20 7a 41 72 67 5b 31 5d 20 29 7b  ') || zArg[1] ){
2800: 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 63 20  .            rc 
2810: 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  = SQLITE_ERROR;.
2820: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
2830: 20 20 20 20 20 20 70 2d 3e 62 52 65 6d 6f 76 65        p->bRemove
2840: 44 69 61 63 72 69 74 69 63 20 3d 20 28 7a 41 72  Diacritic = (zAr
2850: 67 5b 30 5d 3d 3d 27 31 27 29 3b 0a 20 20 20 20  g[0]=='1');.    
2860: 20 20 20 20 7d 65 6c 73 65 0a 20 20 20 20 20 20      }else.      
2870: 20 20 69 66 28 20 30 3d 3d 73 71 6c 69 74 65 33    if( 0==sqlite3
2880: 5f 73 74 72 69 63 6d 70 28 61 7a 41 72 67 5b 69  _stricmp(azArg[i
2890: 5d 2c 20 22 74 6f 6b 65 6e 63 68 61 72 73 22 29  ], "tokenchars")
28a0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63   ){.          rc
28b0: 20 3d 20 66 74 73 35 55 6e 69 63 6f 64 65 41 64   = fts5UnicodeAd
28c0: 64 45 78 63 65 70 74 69 6f 6e 73 28 70 2c 20 7a  dExceptions(p, z
28d0: 41 72 67 2c 20 31 29 3b 0a 20 20 20 20 20 20 20  Arg, 1);.       
28e0: 20 7d 65 6c 73 65 0a 20 20 20 20 20 20 20 20 69   }else.        i
28f0: 66 28 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74  f( 0==sqlite3_st
2900: 72 69 63 6d 70 28 61 7a 41 72 67 5b 69 5d 2c 20  ricmp(azArg[i], 
2910: 22 73 65 70 61 72 61 74 6f 72 73 22 29 20 29 7b  "separators") ){
2920: 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20  .          rc = 
2930: 66 74 73 35 55 6e 69 63 6f 64 65 41 64 64 45 78  fts5UnicodeAddEx
2940: 63 65 70 74 69 6f 6e 73 28 70 2c 20 7a 41 72 67  ceptions(p, zArg
2950: 2c 20 30 29 3b 0a 20 20 20 20 20 20 20 20 7d 65  , 0);.        }e
2960: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 72  lse{.          r
2970: 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  c = SQLITE_ERROR
2980: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
2990: 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20    }.    }else{. 
29a0: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
29b0: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20  _NOMEM;.    }.  
29c0: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
29d0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 66 74 73  _OK ){.      fts
29e0: 35 55 6e 69 63 6f 64 65 44 65 6c 65 74 65 28 28  5UnicodeDelete((
29f0: 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72 2a 29 70  Fts5Tokenizer*)p
2a00: 29 3b 0a 20 20 20 20 20 20 70 20 3d 20 30 3b 0a  );.      p = 0;.
2a10: 20 20 20 20 7d 0a 20 20 20 20 2a 70 70 4f 75 74      }.    *ppOut
2a20: 20 3d 20 28 46 74 73 35 54 6f 6b 65 6e 69 7a 65   = (Fts5Tokenize
2a30: 72 2a 29 70 3b 0a 20 20 7d 0a 20 20 72 65 74 75  r*)p;.  }.  retu
2a40: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
2a50: 52 65 74 75 72 6e 20 74 72 75 65 20 69 66 2c 20  Return true if, 
2a60: 66 6f 72 20 74 68 65 20 70 75 72 70 6f 73 65 73  for the purposes
2a70: 20 6f 66 20 74 6f 6b 65 6e 69 7a 69 6e 67 20 77   of tokenizing w
2a80: 69 74 68 20 74 68 65 20 74 6f 6b 65 6e 69 7a 65  ith the tokenize
2a90: 72 0a 2a 2a 20 70 61 73 73 65 64 20 61 73 20 74  r.** passed as t
2aa0: 68 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e  he first argumen
2ab0: 74 2c 20 63 6f 64 65 70 6f 69 6e 74 20 69 43 6f  t, codepoint iCo
2ac0: 64 65 20 69 73 20 63 6f 6e 73 69 64 65 72 65 64  de is considered
2ad0: 20 61 20 74 6f 6b 65 6e 20 0a 2a 2a 20 63 68 61   a token .** cha
2ae0: 72 61 63 74 65 72 20 28 6e 6f 74 20 61 20 73 65  racter (not a se
2af0: 70 61 72 61 74 6f 72 29 2e 0a 2a 2f 0a 73 74 61  parator)..*/.sta
2b00: 74 69 63 20 69 6e 74 20 66 74 73 35 55 6e 69 63  tic int fts5Unic
2b10: 6f 64 65 49 73 41 6c 6e 75 6d 28 55 6e 69 63 6f  odeIsAlnum(Unico
2b20: 64 65 36 31 54 6f 6b 65 6e 69 7a 65 72 20 2a 70  de61Tokenizer *p
2b30: 2c 20 69 6e 74 20 69 43 6f 64 65 29 7b 0a 20 20  , int iCode){.  
2b40: 61 73 73 65 72 74 28 20 28 73 71 6c 69 74 65 33  assert( (sqlite3
2b50: 46 74 73 35 55 6e 69 63 6f 64 65 49 73 61 6c 6e  Fts5UnicodeIsaln
2b60: 75 6d 28 69 43 6f 64 65 29 20 26 20 30 78 46 46  um(iCode) & 0xFF
2b70: 46 46 46 46 46 45 29 3d 3d 30 20 29 3b 0a 20 20  FFFFFE)==0 );.  
2b80: 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 46 74  return sqlite3Ft
2b90: 73 35 55 6e 69 63 6f 64 65 49 73 61 6c 6e 75 6d  s5UnicodeIsalnum
2ba0: 28 69 43 6f 64 65 29 20 5e 20 66 74 73 35 55 6e  (iCode) ^ fts5Un
2bb0: 69 63 6f 64 65 49 73 45 78 63 65 70 74 69 6f 6e  icodeIsException
2bc0: 28 70 2c 20 69 43 6f 64 65 29 3b 0a 7d 0a 0a 73  (p, iCode);.}..s
2bd0: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 55 6e  tatic int fts5Un
2be0: 69 63 6f 64 65 54 6f 6b 65 6e 69 7a 65 28 0a 20  icodeTokenize(. 
2bf0: 20 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72 20 2a   Fts5Tokenizer *
2c00: 70 54 6f 6b 65 6e 69 7a 65 72 2c 0a 20 20 76 6f  pTokenizer,.  vo
2c10: 69 64 20 2a 70 43 74 78 2c 0a 20 20 63 6f 6e 73  id *pCtx,.  cons
2c20: 74 20 63 68 61 72 20 2a 70 54 65 78 74 2c 20 69  t char *pText, i
2c30: 6e 74 20 6e 54 65 78 74 2c 0a 20 20 69 6e 74 20  nt nText,.  int 
2c40: 28 2a 78 54 6f 6b 65 6e 29 28 76 6f 69 64 2a 2c  (*xToken)(void*,
2c50: 20 63 6f 6e 73 74 20 63 68 61 72 2a 2c 20 69 6e   const char*, in
2c60: 74 20 6e 54 6f 6b 65 6e 2c 20 69 6e 74 20 69 53  t nToken, int iS
2c70: 74 61 72 74 2c 20 69 6e 74 20 69 45 6e 64 29 0a  tart, int iEnd).
2c80: 29 7b 0a 20 20 55 6e 69 63 6f 64 65 36 31 54 6f  ){.  Unicode61To
2c90: 6b 65 6e 69 7a 65 72 20 2a 70 20 3d 20 28 55 6e  kenizer *p = (Un
2ca0: 69 63 6f 64 65 36 31 54 6f 6b 65 6e 69 7a 65 72  icode61Tokenizer
2cb0: 2a 29 70 54 6f 6b 65 6e 69 7a 65 72 3b 0a 20 20  *)pTokenizer;.  
2cc0: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
2cd0: 4f 4b 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 63  OK;.  unsigned c
2ce0: 68 61 72 20 2a 61 20 3d 20 70 2d 3e 61 54 6f 6b  har *a = p->aTok
2cf0: 65 6e 43 68 61 72 3b 0a 0a 20 20 75 6e 73 69 67  enChar;..  unsig
2d00: 6e 65 64 20 63 68 61 72 20 2a 7a 54 65 72 6d 20  ned char *zTerm 
2d10: 3d 20 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72  = (unsigned char
2d20: 2a 29 26 70 54 65 78 74 5b 6e 54 65 78 74 5d 3b  *)&pText[nText];
2d30: 0a 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72  .  unsigned char
2d40: 20 2a 7a 43 73 72 20 3d 20 28 75 6e 73 69 67 6e   *zCsr = (unsign
2d50: 65 64 20 63 68 61 72 20 2a 29 70 54 65 78 74 3b  ed char *)pText;
2d60: 0a 0a 20 20 2f 2a 20 4f 75 74 70 75 74 20 62 75  ..  /* Output bu
2d70: 66 66 65 72 20 2a 2f 0a 20 20 63 68 61 72 20 2a  ffer */.  char *
2d80: 61 46 6f 6c 64 20 3d 20 70 2d 3e 61 46 6f 6c 64  aFold = p->aFold
2d90: 3b 0a 20 20 69 6e 74 20 6e 46 6f 6c 64 20 3d 20  ;.  int nFold = 
2da0: 70 2d 3e 6e 46 6f 6c 64 3b 0a 0a 20 20 2f 2a 20  p->nFold;..  /* 
2db0: 45 61 63 68 20 69 74 65 72 61 74 69 6f 6e 20 6f  Each iteration o
2dc0: 66 20 74 68 69 73 20 6c 6f 6f 70 20 67 6f 62 62  f this loop gobb
2dd0: 6c 65 73 20 75 70 20 61 20 63 6f 6e 74 69 67 75  les up a contigu
2de0: 6f 75 73 20 72 75 6e 20 6f 66 20 73 65 70 61 72  ous run of separ
2df0: 61 74 6f 72 73 2c 0a 20 20 2a 2a 20 74 68 65 6e  ators,.  ** then
2e00: 20 74 68 65 20 6e 65 78 74 20 74 6f 6b 65 6e 2e   the next token.
2e10: 20 20 2a 2f 0a 20 20 77 68 69 6c 65 28 20 72 63    */.  while( rc
2e20: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
2e30: 20 20 20 69 6e 74 20 69 43 6f 64 65 3b 20 20 20     int iCode;   
2e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2e50: 20 2f 2a 20 6e 6f 6e 2d 41 53 43 49 49 20 63 6f   /* non-ASCII co
2e60: 64 65 70 6f 69 6e 74 20 72 65 61 64 20 66 72 6f  depoint read fro
2e70: 6d 20 69 6e 70 75 74 20 2a 2f 0a 20 20 20 20 63  m input */.    c
2e80: 68 61 72 20 2a 7a 4f 75 74 20 3d 20 61 46 6f 6c  har *zOut = aFol
2e90: 64 3b 0a 20 20 20 20 69 6e 74 20 69 73 3b 0a 20  d;.    int is;. 
2ea0: 20 20 20 69 6e 74 20 69 65 3b 0a 0a 20 20 20 20     int ie;..    
2eb0: 2f 2a 20 53 6b 69 70 20 61 6e 79 20 73 65 70 61  /* Skip any sepa
2ec0: 72 61 74 6f 72 20 63 68 61 72 61 63 74 65 72 73  rator characters
2ed0: 2e 20 2a 2f 0a 20 20 20 20 77 68 69 6c 65 28 20  . */.    while( 
2ee0: 31 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 7a  1 ){.      if( z
2ef0: 43 73 72 3e 3d 7a 54 65 72 6d 20 29 20 67 6f 74  Csr>=zTerm ) got
2f00: 6f 20 74 6f 6b 65 6e 69 7a 65 5f 64 6f 6e 65 3b  o tokenize_done;
2f10: 0a 20 20 20 20 20 20 69 66 28 20 2a 7a 43 73 72  .      if( *zCsr
2f20: 20 26 20 30 78 38 30 20 29 20 7b 0a 20 20 20 20   & 0x80 ) {.    
2f30: 20 20 20 20 2f 2a 20 41 20 63 68 61 72 61 63 74      /* A charact
2f40: 65 72 20 6f 75 74 73 69 64 65 20 6f 66 20 74 68  er outside of th
2f50: 65 20 61 73 63 69 69 20 72 61 6e 67 65 2e 20 53  e ascii range. S
2f60: 6b 69 70 20 70 61 73 74 20 69 74 20 69 66 20 69  kip past it if i
2f70: 74 20 69 73 0a 20 20 20 20 20 20 20 20 2a 2a 20  t is.        ** 
2f80: 61 20 73 65 70 61 72 61 74 6f 72 20 63 68 61 72  a separator char
2f90: 61 63 74 65 72 2e 20 4f 72 20 62 72 65 61 6b 20  acter. Or break 
2fa0: 6f 75 74 20 6f 66 20 74 68 65 20 6c 6f 6f 70 20  out of the loop 
2fb0: 69 66 20 69 74 20 69 73 20 6e 6f 74 2e 20 2a 2f  if it is not. */
2fc0: 0a 20 20 20 20 20 20 20 20 69 73 20 3d 20 7a 43  .        is = zC
2fd0: 73 72 20 2d 20 28 75 6e 73 69 67 6e 65 64 20 63  sr - (unsigned c
2fe0: 68 61 72 2a 29 70 54 65 78 74 3b 0a 20 20 20 20  har*)pText;.    
2ff0: 20 20 20 20 52 45 41 44 5f 55 54 46 38 28 7a 43      READ_UTF8(zC
3000: 73 72 2c 20 7a 54 65 72 6d 2c 20 69 43 6f 64 65  sr, zTerm, iCode
3010: 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 66  );.        if( f
3020: 74 73 35 55 6e 69 63 6f 64 65 49 73 41 6c 6e 75  ts5UnicodeIsAlnu
3030: 6d 28 70 2c 20 69 43 6f 64 65 29 20 29 7b 0a 20  m(p, iCode) ){. 
3040: 20 20 20 20 20 20 20 20 20 67 6f 74 6f 20 6e 6f           goto no
3050: 6e 5f 61 73 63 69 69 5f 74 6f 6b 65 6e 63 68 61  n_ascii_tokencha
3060: 72 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  r;.        }.   
3070: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
3080: 20 20 69 66 28 20 61 5b 2a 7a 43 73 72 5d 20 29    if( a[*zCsr] )
3090: 7b 0a 20 20 20 20 20 20 20 20 20 20 69 73 20 3d  {.          is =
30a0: 20 7a 43 73 72 20 2d 20 28 75 6e 73 69 67 6e 65   zCsr - (unsigne
30b0: 64 20 63 68 61 72 2a 29 70 54 65 78 74 3b 0a 20  d char*)pText;. 
30c0: 20 20 20 20 20 20 20 20 20 67 6f 74 6f 20 61 73           goto as
30d0: 63 69 69 5f 74 6f 6b 65 6e 63 68 61 72 3b 0a 20  cii_tokenchar;. 
30e0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
30f0: 20 7a 43 73 72 2b 2b 3b 0a 20 20 20 20 20 20 7d   zCsr++;.      }
3100: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 52  .    }..    /* R
3110: 75 6e 20 74 68 72 6f 75 67 68 20 74 68 65 20 74  un through the t
3120: 6f 6b 65 6e 63 68 61 72 73 2e 20 46 6f 6c 64 20  okenchars. Fold 
3130: 74 68 65 6d 20 69 6e 74 6f 20 74 68 65 20 6f 75  them into the ou
3140: 74 70 75 74 20 62 75 66 66 65 72 20 61 6c 6f 6e  tput buffer alon
3150: 67 0a 20 20 20 20 2a 2a 20 74 68 65 20 77 61 79  g.    ** the way
3160: 2e 20 20 2a 2f 0a 20 20 20 20 77 68 69 6c 65 28  .  */.    while(
3170: 20 7a 43 73 72 3c 7a 54 65 72 6d 20 29 7b 0a 0a   zCsr<zTerm ){..
3180: 20 20 20 20 20 20 2f 2a 20 47 72 6f 77 20 74 68        /* Grow th
3190: 65 20 6f 75 74 70 75 74 20 62 75 66 66 65 72 20  e output buffer 
31a0: 73 6f 20 74 68 61 74 20 74 68 65 72 65 20 69 73  so that there is
31b0: 20 73 75 66 66 69 63 69 65 6e 74 20 73 70 61 63   sufficient spac
31c0: 65 20 74 6f 20 66 69 74 20 74 68 65 0a 20 20 20  e to fit the.   
31d0: 20 20 20 2a 2a 20 6c 61 72 67 65 73 74 20 70 6f     ** largest po
31e0: 73 73 69 62 6c 65 20 75 74 66 2d 38 20 63 68 61  ssible utf-8 cha
31f0: 72 61 63 74 65 72 2e 20 20 2a 2f 0a 20 20 20 20  racter.  */.    
3200: 20 20 69 66 28 20 28 7a 4f 75 74 2d 61 46 6f 6c    if( (zOut-aFol
3210: 64 29 2b 36 3e 6e 46 6f 6c 64 20 29 7b 0a 20 20  d)+6>nFold ){.  
3220: 20 20 20 20 20 20 61 46 6f 6c 64 20 3d 20 73 71        aFold = sq
3230: 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 46 6f  lite3_malloc(nFo
3240: 6c 64 2a 32 29 3b 0a 20 20 20 20 20 20 20 20 69  ld*2);.        i
3250: 66 28 20 61 46 6f 6c 64 3d 3d 30 20 29 7b 0a 20  f( aFold==0 ){. 
3260: 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51           rc = SQ
3270: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
3280: 20 20 20 20 20 20 67 6f 74 6f 20 74 6f 6b 65 6e        goto token
3290: 69 7a 65 5f 64 6f 6e 65 3b 0a 20 20 20 20 20 20  ize_done;.      
32a0: 20 20 7d 0a 20 20 20 20 20 20 20 20 6d 65 6d 63    }.        memc
32b0: 70 79 28 61 46 6f 6c 64 2c 20 70 2d 3e 61 46 6f  py(aFold, p->aFo
32c0: 6c 64 2c 20 6e 46 6f 6c 64 29 3b 0a 20 20 20 20  ld, nFold);.    
32d0: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
32e0: 28 70 2d 3e 61 46 6f 6c 64 29 3b 0a 20 20 20 20  (p->aFold);.    
32f0: 20 20 20 20 70 2d 3e 61 46 6f 6c 64 20 3d 20 61      p->aFold = a
3300: 46 6f 6c 64 3b 0a 20 20 20 20 20 20 20 20 70 2d  Fold;.        p-
3310: 3e 6e 46 6f 6c 64 20 3d 20 6e 46 6f 6c 64 20 3d  >nFold = nFold =
3320: 20 6e 46 6f 6c 64 2a 32 3b 0a 20 20 20 20 20 20   nFold*2;.      
3330: 7d 0a 0a 20 20 20 20 20 20 69 66 28 20 2a 7a 43  }..      if( *zC
3340: 73 72 20 26 20 30 78 38 30 20 29 7b 0a 20 20 20  sr & 0x80 ){.   
3350: 20 20 20 20 20 2f 2a 20 41 6e 20 6e 6f 6e 2d 61       /* An non-a
3360: 73 63 69 69 2d 72 61 6e 67 65 20 63 68 61 72 61  scii-range chara
3370: 63 74 65 72 2e 20 46 6f 6c 64 20 69 74 20 69 6e  cter. Fold it in
3380: 74 6f 20 74 68 65 20 6f 75 74 70 75 74 20 62 75  to the output bu
3390: 66 66 65 72 20 69 66 0a 20 20 20 20 20 20 20 20  ffer if.        
33a0: 2a 2a 20 69 74 20 69 73 20 61 20 74 6f 6b 65 6e  ** it is a token
33b0: 20 63 68 61 72 61 63 74 65 72 2c 20 6f 72 20 62   character, or b
33c0: 72 65 61 6b 20 6f 75 74 20 6f 66 20 74 68 65 20  reak out of the 
33d0: 6c 6f 6f 70 20 69 66 20 69 74 20 69 73 20 6e 6f  loop if it is no
33e0: 74 2e 20 2a 2f 0a 20 20 20 20 20 20 20 20 52 45  t. */.        RE
33f0: 41 44 5f 55 54 46 38 28 7a 43 73 72 2c 20 7a 54  AD_UTF8(zCsr, zT
3400: 65 72 6d 2c 20 69 43 6f 64 65 29 3b 0a 20 20 20  erm, iCode);.   
3410: 20 20 20 20 20 69 66 28 20 66 74 73 35 55 6e 69       if( fts5Uni
3420: 63 6f 64 65 49 73 41 6c 6e 75 6d 28 70 2c 69 43  codeIsAlnum(p,iC
3430: 6f 64 65 29 7c 7c 73 71 6c 69 74 65 33 46 74 73  ode)||sqlite3Fts
3440: 35 55 6e 69 63 6f 64 65 49 73 64 69 61 63 72 69  5UnicodeIsdiacri
3450: 74 69 63 28 69 43 6f 64 65 29 20 29 7b 0a 20 6e  tic(iCode) ){. n
3460: 6f 6e 5f 61 73 63 69 69 5f 74 6f 6b 65 6e 63 68  on_ascii_tokench
3470: 61 72 3a 0a 20 20 20 20 20 20 20 20 20 20 69 43  ar:.          iC
3480: 6f 64 65 20 3d 20 73 71 6c 69 74 65 33 46 74 73  ode = sqlite3Fts
3490: 35 55 6e 69 63 6f 64 65 46 6f 6c 64 28 69 43 6f  5UnicodeFold(iCo
34a0: 64 65 2c 20 70 2d 3e 62 52 65 6d 6f 76 65 44 69  de, p->bRemoveDi
34b0: 61 63 72 69 74 69 63 29 3b 0a 20 20 20 20 20 20  acritic);.      
34c0: 20 20 20 20 69 66 28 20 69 43 6f 64 65 20 29 20      if( iCode ) 
34d0: 57 52 49 54 45 5f 55 54 46 38 28 7a 4f 75 74 2c  WRITE_UTF8(zOut,
34e0: 20 69 43 6f 64 65 29 3b 0a 20 20 20 20 20 20 20   iCode);.       
34f0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
3500: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20    break;.       
3510: 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69   }.      }else i
3520: 66 28 20 61 5b 2a 7a 43 73 72 5d 3d 3d 30 20 29  f( a[*zCsr]==0 )
3530: 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 41 6e 20  {.        /* An 
3540: 61 73 63 69 69 2d 72 61 6e 67 65 20 73 65 70 61  ascii-range sepa
3550: 72 61 74 6f 72 20 63 68 61 72 61 63 74 65 72 2e  rator character.
3560: 20 45 6e 64 20 6f 66 20 74 6f 6b 65 6e 2e 20 2a   End of token. *
3570: 2f 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b  /.        break;
3580: 20 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20   .      }else{. 
3590: 61 73 63 69 69 5f 74 6f 6b 65 6e 63 68 61 72 3a  ascii_tokenchar:
35a0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 2a 7a 43  .        if( *zC
35b0: 73 72 3e 3d 27 41 27 20 26 26 20 2a 7a 43 73 72  sr>='A' && *zCsr
35c0: 3c 3d 27 5a 27 20 29 7b 0a 20 20 20 20 20 20 20  <='Z' ){.       
35d0: 20 20 20 2a 7a 4f 75 74 2b 2b 20 3d 20 2a 7a 43     *zOut++ = *zC
35e0: 73 72 20 2b 20 33 32 3b 0a 20 20 20 20 20 20 20  sr + 32;.       
35f0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
3600: 20 20 2a 7a 4f 75 74 2b 2b 20 3d 20 2a 7a 43 73    *zOut++ = *zCs
3610: 72 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  r;.        }.   
3620: 20 20 20 20 20 7a 43 73 72 2b 2b 3b 0a 20 20 20       zCsr++;.   
3630: 20 20 20 7d 0a 20 20 20 20 20 20 69 65 20 3d 20     }.      ie = 
3640: 7a 43 73 72 20 2d 20 28 75 6e 73 69 67 6e 65 64  zCsr - (unsigned
3650: 20 63 68 61 72 2a 29 70 54 65 78 74 3b 0a 20 20   char*)pText;.  
3660: 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 6e 76 6f    }..    /* Invo
3670: 6b 65 20 74 68 65 20 74 6f 6b 65 6e 20 63 61 6c  ke the token cal
3680: 6c 62 61 63 6b 20 2a 2f 0a 20 20 20 20 72 63 20  lback */.    rc 
3690: 3d 20 78 54 6f 6b 65 6e 28 70 43 74 78 2c 20 61  = xToken(pCtx, a
36a0: 46 6f 6c 64 2c 20 7a 4f 75 74 2d 61 46 6f 6c 64  Fold, zOut-aFold
36b0: 2c 20 69 73 2c 20 69 65 29 3b 0a 20 20 7d 0a 20  , is, ie);.  }. 
36c0: 20 0a 20 74 6f 6b 65 6e 69 7a 65 5f 64 6f 6e 65   . tokenize_done
36d0: 3a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  :.  if( rc==SQLI
36e0: 54 45 5f 44 4f 4e 45 20 29 20 72 63 20 3d 20 53  TE_DONE ) rc = S
36f0: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 72 65 74 75  QLITE_OK;.  retu
3700: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a  rn rc;.}../*****
3710: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3720: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3730: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3740: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3750: 2a 2a 2a 2a 2a 0a 2a 2a 20 53 74 61 72 74 20 6f  *****.** Start o
3760: 66 20 70 6f 72 74 65 72 20 73 74 65 6d 6d 65 72  f porter stemmer
3770: 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e   implementation.
3780: 0a 2a 2f 0a 0a 2f 2a 20 41 6e 79 20 74 6f 6b 65  .*/../* Any toke
3790: 6e 73 20 6c 61 72 67 65 72 20 74 68 61 6e 20 74  ns larger than t
37a0: 68 69 73 20 28 69 6e 20 62 79 74 65 73 29 20 61  his (in bytes) a
37b0: 72 65 20 70 61 73 73 65 64 20 74 68 72 6f 75 67  re passed throug
37c0: 68 20 77 69 74 68 6f 75 74 0a 2a 2a 20 73 74 65  h without.** ste
37d0: 6d 6d 69 6e 67 2e 20 2a 2f 0a 23 64 65 66 69 6e  mming. */.#defin
37e0: 65 20 46 54 53 35 5f 50 4f 52 54 45 52 5f 4d 41  e FTS5_PORTER_MA
37f0: 58 5f 54 4f 4b 45 4e 20 36 34 0a 0a 74 79 70 65  X_TOKEN 64..type
3800: 64 65 66 20 73 74 72 75 63 74 20 50 6f 72 74 65  def struct Porte
3810: 72 54 6f 6b 65 6e 69 7a 65 72 20 50 6f 72 74 65  rTokenizer Porte
3820: 72 54 6f 6b 65 6e 69 7a 65 72 3b 0a 73 74 72 75  rTokenizer;.stru
3830: 63 74 20 50 6f 72 74 65 72 54 6f 6b 65 6e 69 7a  ct PorterTokeniz
3840: 65 72 20 7b 0a 20 20 66 74 73 35 5f 74 6f 6b 65  er {.  fts5_toke
3850: 6e 69 7a 65 72 20 74 6f 6b 65 6e 69 7a 65 72 3b  nizer tokenizer;
3860: 20 20 20 20 20 20 20 2f 2a 20 50 61 72 65 6e 74         /* Parent
3870: 20 74 6f 6b 65 6e 69 7a 65 72 20 6d 6f 64 75 6c   tokenizer modul
3880: 65 20 2a 2f 0a 20 20 46 74 73 35 54 6f 6b 65 6e  e */.  Fts5Token
3890: 69 7a 65 72 20 2a 70 54 6f 6b 65 6e 69 7a 65 72  izer *pTokenizer
38a0: 3b 20 20 20 20 20 20 2f 2a 20 50 61 72 65 6e 74  ;      /* Parent
38b0: 20 74 6f 6b 65 6e 69 7a 65 72 20 69 6e 73 74 61   tokenizer insta
38c0: 6e 63 65 20 2a 2f 0a 20 20 63 68 61 72 20 61 42  nce */.  char aB
38d0: 75 66 5b 46 54 53 35 5f 50 4f 52 54 45 52 5f 4d  uf[FTS5_PORTER_M
38e0: 41 58 5f 54 4f 4b 45 4e 20 2b 20 36 34 5d 3b 0a  AX_TOKEN + 64];.
38f0: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 44 65 6c 65 74 65  };../*.** Delete
3900: 20 61 20 22 70 6f 72 74 65 72 22 20 74 6f 6b 65   a "porter" toke
3910: 6e 69 7a 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63  nizer..*/.static
3920: 20 76 6f 69 64 20 66 74 73 35 50 6f 72 74 65 72   void fts5Porter
3930: 44 65 6c 65 74 65 28 46 74 73 35 54 6f 6b 65 6e  Delete(Fts5Token
3940: 69 7a 65 72 20 2a 70 54 6f 6b 29 7b 0a 20 20 69  izer *pTok){.  i
3950: 66 28 20 70 54 6f 6b 20 29 7b 0a 20 20 20 20 50  f( pTok ){.    P
3960: 6f 72 74 65 72 54 6f 6b 65 6e 69 7a 65 72 20 2a  orterTokenizer *
3970: 70 20 3d 20 28 50 6f 72 74 65 72 54 6f 6b 65 6e  p = (PorterToken
3980: 69 7a 65 72 2a 29 70 54 6f 6b 3b 0a 20 20 20 20  izer*)pTok;.    
3990: 69 66 28 20 70 2d 3e 70 54 6f 6b 65 6e 69 7a 65  if( p->pTokenize
39a0: 72 20 29 7b 0a 20 20 20 20 20 20 70 2d 3e 74 6f  r ){.      p->to
39b0: 6b 65 6e 69 7a 65 72 2e 78 44 65 6c 65 74 65 28  kenizer.xDelete(
39c0: 70 2d 3e 70 54 6f 6b 65 6e 69 7a 65 72 29 3b 0a  p->pTokenizer);.
39d0: 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65      }.    sqlite
39e0: 33 5f 66 72 65 65 28 70 29 3b 0a 20 20 7d 0a 7d  3_free(p);.  }.}
39f0: 0a 0a 2f 2a 0a 2a 2a 20 43 72 65 61 74 65 20 61  ../*.** Create a
3a00: 20 22 70 6f 72 74 65 72 22 20 74 6f 6b 65 6e 69   "porter" tokeni
3a10: 7a 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  zer..*/.static i
3a20: 6e 74 20 66 74 73 35 50 6f 72 74 65 72 43 72 65  nt fts5PorterCre
3a30: 61 74 65 28 0a 20 20 76 6f 69 64 20 2a 70 43 74  ate(.  void *pCt
3a40: 78 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  x, .  const char
3a50: 20 2a 2a 61 7a 41 72 67 2c 20 69 6e 74 20 6e 41   **azArg, int nA
3a60: 72 67 2c 0a 20 20 46 74 73 35 54 6f 6b 65 6e 69  rg,.  Fts5Tokeni
3a70: 7a 65 72 20 2a 2a 70 70 4f 75 74 0a 29 7b 0a 20  zer **ppOut.){. 
3a80: 20 66 74 73 35 5f 61 70 69 20 2a 70 41 70 69 20   fts5_api *pApi 
3a90: 3d 20 28 66 74 73 35 5f 61 70 69 2a 29 70 43 74  = (fts5_api*)pCt
3aa0: 78 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  x;.  int rc = SQ
3ab0: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 50 6f 72 74 65  LITE_OK;.  Porte
3ac0: 72 54 6f 6b 65 6e 69 7a 65 72 20 2a 70 52 65 74  rTokenizer *pRet
3ad0: 3b 0a 20 20 76 6f 69 64 20 2a 70 55 73 65 72 64  ;.  void *pUserd
3ae0: 61 74 61 20 3d 20 30 3b 0a 0a 20 20 70 52 65 74  ata = 0;..  pRet
3af0: 20 3d 20 28 50 6f 72 74 65 72 54 6f 6b 65 6e 69   = (PorterTokeni
3b00: 7a 65 72 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c  zer*)sqlite3_mal
3b10: 6c 6f 63 28 73 69 7a 65 6f 66 28 50 6f 72 74 65  loc(sizeof(Porte
3b20: 72 54 6f 6b 65 6e 69 7a 65 72 29 29 3b 0a 20 20  rTokenizer));.  
3b30: 69 66 28 20 70 52 65 74 20 29 7b 0a 20 20 20 20  if( pRet ){.    
3b40: 6d 65 6d 73 65 74 28 70 52 65 74 2c 20 30 2c 20  memset(pRet, 0, 
3b50: 73 69 7a 65 6f 66 28 50 6f 72 74 65 72 54 6f 6b  sizeof(PorterTok
3b60: 65 6e 69 7a 65 72 29 29 3b 0a 20 20 20 20 72 63  enizer));.    rc
3b70: 20 3d 20 70 41 70 69 2d 3e 78 46 69 6e 64 54 6f   = pApi->xFindTo
3b80: 6b 65 6e 69 7a 65 72 28 70 41 70 69 2c 20 22 61  kenizer(pApi, "a
3b90: 73 63 69 69 22 2c 20 26 70 55 73 65 72 64 61 74  scii", &pUserdat
3ba0: 61 2c 20 26 70 52 65 74 2d 3e 74 6f 6b 65 6e 69  a, &pRet->tokeni
3bb0: 7a 65 72 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  zer);.  }else{. 
3bc0: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e     rc = SQLITE_N
3bd0: 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 69 66 28 20  OMEM;.  }.  if( 
3be0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
3bf0: 0a 20 20 20 20 72 63 20 3d 20 70 52 65 74 2d 3e  .    rc = pRet->
3c00: 74 6f 6b 65 6e 69 7a 65 72 2e 78 43 72 65 61 74  tokenizer.xCreat
3c10: 65 28 70 55 73 65 72 64 61 74 61 2c 20 30 2c 20  e(pUserdata, 0, 
3c20: 30 2c 20 26 70 52 65 74 2d 3e 70 54 6f 6b 65 6e  0, &pRet->pToken
3c30: 69 7a 65 72 29 3b 0a 20 20 7d 0a 0a 20 20 69 66  izer);.  }..  if
3c40: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
3c50: 29 7b 0a 20 20 20 20 66 74 73 35 50 6f 72 74 65  ){.    fts5Porte
3c60: 72 44 65 6c 65 74 65 28 28 46 74 73 35 54 6f 6b  rDelete((Fts5Tok
3c70: 65 6e 69 7a 65 72 2a 29 70 52 65 74 29 3b 0a 20  enizer*)pRet);. 
3c80: 20 20 20 70 52 65 74 20 3d 20 30 3b 0a 20 20 7d     pRet = 0;.  }
3c90: 0a 20 20 2a 70 70 4f 75 74 20 3d 20 28 46 74 73  .  *ppOut = (Fts
3ca0: 35 54 6f 6b 65 6e 69 7a 65 72 2a 29 70 52 65 74  5Tokenizer*)pRet
3cb0: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
3cc0: 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  ..typedef struct
3cd0: 20 50 6f 72 74 65 72 43 6f 6e 74 65 78 74 20 50   PorterContext P
3ce0: 6f 72 74 65 72 43 6f 6e 74 65 78 74 3b 0a 73 74  orterContext;.st
3cf0: 72 75 63 74 20 50 6f 72 74 65 72 43 6f 6e 74 65  ruct PorterConte
3d00: 78 74 20 7b 0a 20 20 76 6f 69 64 20 2a 70 43 74  xt {.  void *pCt
3d10: 78 3b 0a 20 20 69 6e 74 20 28 2a 78 54 6f 6b 65  x;.  int (*xToke
3d20: 6e 29 28 76 6f 69 64 2a 2c 20 63 6f 6e 73 74 20  n)(void*, const 
3d30: 63 68 61 72 2a 2c 20 69 6e 74 2c 20 69 6e 74 2c  char*, int, int,
3d40: 20 69 6e 74 29 3b 0a 20 20 63 68 61 72 20 2a 61   int);.  char *a
3d50: 42 75 66 3b 0a 7d 3b 0a 0a 74 79 70 65 64 65 66  Buf;.};..typedef
3d60: 20 73 74 72 75 63 74 20 50 6f 72 74 65 72 52 75   struct PorterRu
3d70: 6c 65 20 50 6f 72 74 65 72 52 75 6c 65 3b 0a 73  le PorterRule;.s
3d80: 74 72 75 63 74 20 50 6f 72 74 65 72 52 75 6c 65  truct PorterRule
3d90: 20 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20   {.  const char 
3da0: 2a 7a 53 75 66 66 69 78 3b 0a 20 20 69 6e 74 20  *zSuffix;.  int 
3db0: 6e 53 75 66 66 69 78 3b 0a 20 20 69 6e 74 20 28  nSuffix;.  int (
3dc0: 2a 78 43 6f 6e 64 29 28 63 68 61 72 20 2a 7a 53  *xCond)(char *zS
3dd0: 74 65 6d 2c 20 69 6e 74 20 6e 53 74 65 6d 29 3b  tem, int nStem);
3de0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
3df0: 4f 75 74 70 75 74 3b 0a 20 20 69 6e 74 20 6e 4f  Output;.  int nO
3e00: 75 74 70 75 74 3b 0a 7d 3b 0a 0a 73 74 61 74 69  utput;.};..stati
3e10: 63 20 69 6e 74 20 66 74 73 35 50 6f 72 74 65 72  c int fts5Porter
3e20: 41 70 70 6c 79 28 63 68 61 72 20 2a 61 42 75 66  Apply(char *aBuf
3e30: 2c 20 69 6e 74 20 2a 70 6e 42 75 66 2c 20 50 6f  , int *pnBuf, Po
3e40: 72 74 65 72 52 75 6c 65 20 2a 61 52 75 6c 65 29  rterRule *aRule)
3e50: 7b 0a 20 20 69 6e 74 20 72 65 74 20 3d 20 2d 31  {.  int ret = -1
3e60: 3b 0a 20 20 69 6e 74 20 6e 42 75 66 20 3d 20 2a  ;.  int nBuf = *
3e70: 70 6e 42 75 66 3b 0a 20 20 50 6f 72 74 65 72 52  pnBuf;.  PorterR
3e80: 75 6c 65 20 2a 70 3b 0a 0a 20 20 66 6f 72 28 70  ule *p;..  for(p
3e90: 3d 61 52 75 6c 65 3b 20 70 2d 3e 7a 53 75 66 66  =aRule; p->zSuff
3ea0: 69 78 3b 20 70 2b 2b 29 7b 0a 20 20 20 20 61 73  ix; p++){.    as
3eb0: 73 65 72 74 28 20 73 74 72 6c 65 6e 28 70 2d 3e  sert( strlen(p->
3ec0: 7a 53 75 66 66 69 78 29 3d 3d 70 2d 3e 6e 53 75  zSuffix)==p->nSu
3ed0: 66 66 69 78 20 29 3b 0a 20 20 20 20 61 73 73 65  ffix );.    asse
3ee0: 72 74 28 20 73 74 72 6c 65 6e 28 70 2d 3e 7a 4f  rt( strlen(p->zO
3ef0: 75 74 70 75 74 29 3d 3d 70 2d 3e 6e 4f 75 74 70  utput)==p->nOutp
3f00: 75 74 20 29 3b 0a 20 20 20 20 69 66 28 20 6e 42  ut );.    if( nB
3f10: 75 66 3c 70 2d 3e 6e 53 75 66 66 69 78 20 29 20  uf<p->nSuffix ) 
3f20: 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 69 66  continue;.    if
3f30: 28 20 30 3d 3d 6d 65 6d 63 6d 70 28 26 61 42 75  ( 0==memcmp(&aBu
3f40: 66 5b 6e 42 75 66 20 2d 20 70 2d 3e 6e 53 75 66  f[nBuf - p->nSuf
3f50: 66 69 78 5d 2c 20 70 2d 3e 7a 53 75 66 66 69 78  fix], p->zSuffix
3f60: 2c 20 70 2d 3e 6e 53 75 66 66 69 78 29 20 29 20  , p->nSuffix) ) 
3f70: 62 72 65 61 6b 3b 0a 20 20 7d 0a 0a 20 20 69 66  break;.  }..  if
3f80: 28 20 70 2d 3e 7a 53 75 66 66 69 78 20 29 7b 0a  ( p->zSuffix ){.
3f90: 20 20 20 20 69 6e 74 20 6e 53 74 65 6d 20 3d 20      int nStem = 
3fa0: 6e 42 75 66 20 2d 20 70 2d 3e 6e 53 75 66 66 69  nBuf - p->nSuffi
3fb0: 78 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e 78 43  x;.    if( p->xC
3fc0: 6f 6e 64 3d 3d 30 20 7c 7c 20 70 2d 3e 78 43 6f  ond==0 || p->xCo
3fd0: 6e 64 28 61 42 75 66 2c 20 6e 53 74 65 6d 29 20  nd(aBuf, nStem) 
3fe0: 29 7b 0a 20 20 20 20 20 20 6d 65 6d 63 70 79 28  ){.      memcpy(
3ff0: 26 61 42 75 66 5b 6e 53 74 65 6d 5d 2c 20 70 2d  &aBuf[nStem], p-
4000: 3e 7a 4f 75 74 70 75 74 2c 20 70 2d 3e 6e 4f 75  >zOutput, p->nOu
4010: 74 70 75 74 29 3b 0a 20 20 20 20 20 20 2a 70 6e  tput);.      *pn
4020: 42 75 66 20 3d 20 6e 53 74 65 6d 20 2b 20 70 2d  Buf = nStem + p-
4030: 3e 6e 4f 75 74 70 75 74 3b 0a 20 20 20 20 20 20  >nOutput;.      
4040: 72 65 74 20 3d 20 70 20 2d 20 61 52 75 6c 65 3b  ret = p - aRule;
4050: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65  .    }.  }..  re
4060: 74 75 72 6e 20 72 65 74 3b 0a 7d 0a 0a 73 74 61  turn ret;.}..sta
4070: 74 69 63 20 69 6e 74 20 66 74 73 35 50 6f 72 74  tic int fts5Port
4080: 65 72 49 73 56 6f 77 65 6c 28 63 68 61 72 20 63  erIsVowel(char c
4090: 2c 20 69 6e 74 20 62 59 49 73 56 6f 77 65 6c 29  , int bYIsVowel)
40a0: 7b 0a 20 20 72 65 74 75 72 6e 20 28 0a 20 20 20  {.  return (.   
40b0: 20 20 20 63 3d 3d 27 61 27 20 7c 7c 20 63 3d 3d     c=='a' || c==
40c0: 27 65 27 20 7c 7c 20 63 3d 3d 27 69 27 20 7c 7c  'e' || c=='i' ||
40d0: 20 63 3d 3d 27 6f 27 20 7c 7c 20 63 3d 3d 27 75   c=='o' || c=='u
40e0: 27 20 7c 7c 20 28 62 59 49 73 56 6f 77 65 6c 20  ' || (bYIsVowel 
40f0: 26 26 20 63 3d 3d 27 79 27 29 0a 20 20 29 3b 0a  && c=='y').  );.
4100: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  }..static int ft
4110: 73 35 50 6f 72 74 65 72 47 6f 62 62 6c 65 56 43  s5PorterGobbleVC
4120: 28 63 68 61 72 20 2a 7a 53 74 65 6d 2c 20 69 6e  (char *zStem, in
4130: 74 20 6e 53 74 65 6d 2c 20 69 6e 74 20 62 50 72  t nStem, int bPr
4140: 65 76 43 6f 6e 73 29 7b 0a 20 20 69 6e 74 20 69  evCons){.  int i
4150: 3b 0a 20 20 69 6e 74 20 62 43 6f 6e 73 20 3d 20  ;.  int bCons = 
4160: 62 50 72 65 76 43 6f 6e 73 3b 0a 0a 20 20 2f 2a  bPrevCons;..  /*
4170: 20 53 63 61 6e 20 66 6f 72 20 61 20 76 6f 77 65   Scan for a vowe
4180: 6c 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20  l */.  for(i=0; 
4190: 69 3c 6e 53 74 65 6d 3b 20 69 2b 2b 29 7b 0a 20  i<nStem; i++){. 
41a0: 20 20 20 69 66 28 20 30 3d 3d 28 62 43 6f 6e 73     if( 0==(bCons
41b0: 20 3d 20 21 66 74 73 35 50 6f 72 74 65 72 49 73   = !fts5PorterIs
41c0: 56 6f 77 65 6c 28 7a 53 74 65 6d 5b 69 5d 2c 20  Vowel(zStem[i], 
41d0: 62 43 6f 6e 73 29 29 20 29 20 62 72 65 61 6b 3b  bCons)) ) break;
41e0: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 63 61 6e 20  .  }..  /* Scan 
41f0: 66 6f 72 20 61 20 63 6f 6e 73 6f 6e 65 6e 74 20  for a consonent 
4200: 2a 2f 0a 20 20 66 6f 72 28 69 2b 2b 3b 20 69 3c  */.  for(i++; i<
4210: 6e 53 74 65 6d 3b 20 69 2b 2b 29 7b 0a 20 20 20  nStem; i++){.   
4220: 20 69 66 28 20 28 62 43 6f 6e 73 20 3d 20 21 66   if( (bCons = !f
4230: 74 73 35 50 6f 72 74 65 72 49 73 56 6f 77 65 6c  ts5PorterIsVowel
4240: 28 7a 53 74 65 6d 5b 69 5d 2c 20 62 43 6f 6e 73  (zStem[i], bCons
4250: 29 29 20 29 20 72 65 74 75 72 6e 20 69 2b 31 3b  )) ) return i+1;
4260: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 30 3b  .  }.  return 0;
4270: 0a 7d 0a 0a 2f 2a 20 70 6f 72 74 65 72 20 72 75  .}../* porter ru
4280: 6c 65 20 63 6f 6e 64 69 74 69 6f 6e 3a 20 28 6d  le condition: (m
4290: 20 3e 20 30 29 20 2a 2f 0a 73 74 61 74 69 63 20   > 0) */.static 
42a0: 69 6e 74 20 66 74 73 35 50 6f 72 74 65 72 5f 4d  int fts5Porter_M
42b0: 47 74 30 28 63 68 61 72 20 2a 7a 53 74 65 6d 2c  Gt0(char *zStem,
42c0: 20 69 6e 74 20 6e 53 74 65 6d 29 7b 0a 20 20 72   int nStem){.  r
42d0: 65 74 75 72 6e 20 21 21 66 74 73 35 50 6f 72 74  eturn !!fts5Port
42e0: 65 72 47 6f 62 62 6c 65 56 43 28 7a 53 74 65 6d  erGobbleVC(zStem
42f0: 2c 20 6e 53 74 65 6d 2c 20 30 29 3b 0a 7d 0a 0a  , nStem, 0);.}..
4300: 2f 2a 20 70 6f 72 74 65 72 20 72 75 6c 65 20 63  /* porter rule c
4310: 6f 6e 64 69 74 69 6f 6e 3a 20 28 6d 20 3e 20 31  ondition: (m > 1
4320: 29 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ) */.static int 
4330: 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 28  fts5Porter_MGt1(
4340: 63 68 61 72 20 2a 7a 53 74 65 6d 2c 20 69 6e 74  char *zStem, int
4350: 20 6e 53 74 65 6d 29 7b 0a 20 20 69 6e 74 20 6e   nStem){.  int n
4360: 3b 0a 20 20 6e 20 3d 20 66 74 73 35 50 6f 72 74  ;.  n = fts5Port
4370: 65 72 47 6f 62 62 6c 65 56 43 28 7a 53 74 65 6d  erGobbleVC(zStem
4380: 2c 20 6e 53 74 65 6d 2c 20 30 29 3b 0a 20 20 69  , nStem, 0);.  i
4390: 66 28 20 6e 20 26 26 20 66 74 73 35 50 6f 72 74  f( n && fts5Port
43a0: 65 72 47 6f 62 62 6c 65 56 43 28 26 7a 53 74 65  erGobbleVC(&zSte
43b0: 6d 5b 6e 5d 2c 20 6e 53 74 65 6d 2d 6e 2c 20 31  m[n], nStem-n, 1
43c0: 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  ) ){.    return 
43d0: 31 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  1;.  }.  return 
43e0: 30 3b 0a 7d 0a 0a 2f 2a 20 70 6f 72 74 65 72 20  0;.}../* porter 
43f0: 72 75 6c 65 20 63 6f 6e 64 69 74 69 6f 6e 3a 20  rule condition: 
4400: 28 6d 20 3d 20 31 29 20 2a 2f 0a 73 74 61 74 69  (m = 1) */.stati
4410: 63 20 69 6e 74 20 66 74 73 35 50 6f 72 74 65 72  c int fts5Porter
4420: 5f 4d 45 71 31 28 63 68 61 72 20 2a 7a 53 74 65  _MEq1(char *zSte
4430: 6d 2c 20 69 6e 74 20 6e 53 74 65 6d 29 7b 0a 20  m, int nStem){. 
4440: 20 69 6e 74 20 6e 3b 0a 20 20 6e 20 3d 20 66 74   int n;.  n = ft
4450: 73 35 50 6f 72 74 65 72 47 6f 62 62 6c 65 56 43  s5PorterGobbleVC
4460: 28 7a 53 74 65 6d 2c 20 6e 53 74 65 6d 2c 20 30  (zStem, nStem, 0
4470: 29 3b 0a 20 20 69 66 28 20 6e 20 26 26 20 30 3d  );.  if( n && 0=
4480: 3d 66 74 73 35 50 6f 72 74 65 72 47 6f 62 62 6c  =fts5PorterGobbl
4490: 65 56 43 28 26 7a 53 74 65 6d 5b 6e 5d 2c 20 6e  eVC(&zStem[n], n
44a0: 53 74 65 6d 2d 6e 2c 20 31 29 20 29 7b 0a 20 20  Stem-n, 1) ){.  
44b0: 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 7d 0a    return 1;.  }.
44c0: 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f    return 0;.}../
44d0: 2a 20 70 6f 72 74 65 72 20 72 75 6c 65 20 63 6f  * porter rule co
44e0: 6e 64 69 74 69 6f 6e 3a 20 28 2a 6f 29 20 2a 2f  ndition: (*o) */
44f0: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
4500: 50 6f 72 74 65 72 5f 4f 73 74 61 72 28 63 68 61  Porter_Ostar(cha
4510: 72 20 2a 7a 53 74 65 6d 2c 20 69 6e 74 20 6e 53  r *zStem, int nS
4520: 74 65 6d 29 7b 0a 20 20 69 66 28 20 7a 53 74 65  tem){.  if( zSte
4530: 6d 5b 6e 53 74 65 6d 2d 31 5d 3d 3d 27 77 27 20  m[nStem-1]=='w' 
4540: 7c 7c 20 7a 53 74 65 6d 5b 6e 53 74 65 6d 2d 31  || zStem[nStem-1
4550: 5d 3d 3d 27 78 27 20 7c 7c 20 7a 53 74 65 6d 5b  ]=='x' || zStem[
4560: 6e 53 74 65 6d 2d 31 5d 3d 3d 27 79 27 20 29 7b  nStem-1]=='y' ){
4570: 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20  .    return 0;. 
4580: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74 20   }else{.    int 
4590: 69 3b 0a 20 20 20 20 69 6e 74 20 6d 61 73 6b 20  i;.    int mask 
45a0: 3d 20 30 3b 0a 20 20 20 20 69 6e 74 20 62 43 6f  = 0;.    int bCo
45b0: 6e 73 20 3d 20 30 3b 0a 20 20 20 20 66 6f 72 28  ns = 0;.    for(
45c0: 69 3d 30 3b 20 69 3c 6e 53 74 65 6d 3b 20 69 2b  i=0; i<nStem; i+
45d0: 2b 29 7b 0a 20 20 20 20 20 20 62 43 6f 6e 73 20  +){.      bCons 
45e0: 3d 20 21 66 74 73 35 50 6f 72 74 65 72 49 73 56  = !fts5PorterIsV
45f0: 6f 77 65 6c 28 7a 53 74 65 6d 5b 69 5d 2c 20 62  owel(zStem[i], b
4600: 43 6f 6e 73 29 3b 0a 20 20 20 20 20 20 61 73 73  Cons);.      ass
4610: 65 72 74 28 20 62 43 6f 6e 73 3d 3d 30 20 7c 7c  ert( bCons==0 ||
4620: 20 62 43 6f 6e 73 3d 3d 31 20 29 3b 0a 20 20 20   bCons==1 );.   
4630: 20 20 20 6d 61 73 6b 20 3d 20 28 6d 61 73 6b 20     mask = (mask 
4640: 3c 3c 20 31 29 20 2b 20 62 43 6f 6e 73 3b 0a 20  << 1) + bCons;. 
4650: 20 20 20 7d 0a 20 20 20 20 72 65 74 75 72 6e 20     }.    return 
4660: 28 28 6d 61 73 6b 20 26 20 30 78 30 30 30 37 29  ((mask & 0x0007)
4670: 3d 3d 30 78 30 30 30 35 29 3b 0a 20 20 7d 0a 7d  ==0x0005);.  }.}
4680: 0a 0a 2f 2a 20 70 6f 72 74 65 72 20 72 75 6c 65  ../* porter rule
4690: 20 63 6f 6e 64 69 74 69 6f 6e 3a 20 28 6d 20 3e   condition: (m >
46a0: 20 31 20 61 6e 64 20 28 2a 53 20 6f 72 20 2a 54   1 and (*S or *T
46b0: 29 29 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  )) */.static int
46c0: 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31   fts5Porter_MGt1
46d0: 5f 61 6e 64 5f 53 5f 6f 72 5f 54 28 63 68 61 72  _and_S_or_T(char
46e0: 20 2a 7a 53 74 65 6d 2c 20 69 6e 74 20 6e 53 74   *zStem, int nSt
46f0: 65 6d 29 7b 0a 20 20 72 65 74 75 72 6e 20 6e 53  em){.  return nS
4700: 74 65 6d 3e 30 0a 20 20 20 20 20 20 26 26 20 28  tem>0.      && (
4710: 7a 53 74 65 6d 5b 6e 53 74 65 6d 2d 31 5d 3d 3d  zStem[nStem-1]==
4720: 27 73 27 20 7c 7c 20 7a 53 74 65 6d 5b 6e 53 74  's' || zStem[nSt
4730: 65 6d 2d 31 5d 3d 3d 27 74 27 29 0a 20 20 20 20  em-1]=='t').    
4740: 20 20 26 26 20 66 74 73 35 50 6f 72 74 65 72 5f    && fts5Porter_
4750: 4d 47 74 31 28 7a 53 74 65 6d 2c 20 6e 53 74 65  MGt1(zStem, nSte
4760: 6d 29 3b 0a 7d 0a 0a 2f 2a 20 70 6f 72 74 65 72  m);.}../* porter
4770: 20 72 75 6c 65 20 63 6f 6e 64 69 74 69 6f 6e 3a   rule condition:
4780: 20 28 2a 76 2a 29 20 2a 2f 0a 73 74 61 74 69 63   (*v*) */.static
4790: 20 69 6e 74 20 66 74 73 35 50 6f 72 74 65 72 5f   int fts5Porter_
47a0: 56 6f 77 65 6c 28 63 68 61 72 20 2a 7a 53 74 65  Vowel(char *zSte
47b0: 6d 2c 20 69 6e 74 20 6e 53 74 65 6d 29 7b 0a 20  m, int nStem){. 
47c0: 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d   int i;.  for(i=
47d0: 30 3b 20 69 3c 6e 53 74 65 6d 3b 20 69 2b 2b 29  0; i<nStem; i++)
47e0: 7b 0a 20 20 20 20 69 66 28 20 66 74 73 35 50 6f  {.    if( fts5Po
47f0: 72 74 65 72 49 73 56 6f 77 65 6c 28 7a 53 74 65  rterIsVowel(zSte
4800: 6d 5b 69 5d 2c 20 69 3e 30 29 20 29 7b 0a 20 20  m[i], i>0) ){.  
4810: 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20      return 1;.  
4820: 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
4830: 20 30 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e   0;.}..static in
4840: 74 20 66 74 73 35 50 6f 72 74 65 72 43 62 28 0a  t fts5PorterCb(.
4850: 20 20 76 6f 69 64 20 2a 70 43 74 78 2c 20 0a 20    void *pCtx, . 
4860: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 54 6f   const char *pTo
4870: 6b 65 6e 2c 20 0a 20 20 69 6e 74 20 6e 54 6f 6b  ken, .  int nTok
4880: 65 6e 2c 20 0a 20 20 69 6e 74 20 69 53 74 61 72  en, .  int iStar
4890: 74 2c 20 0a 20 20 69 6e 74 20 69 45 6e 64 0a 29  t, .  int iEnd.)
48a0: 7b 0a 20 20 50 6f 72 74 65 72 43 6f 6e 74 65 78  {.  PorterContex
48b0: 74 20 2a 70 20 3d 20 28 50 6f 72 74 65 72 43 6f  t *p = (PorterCo
48c0: 6e 74 65 78 74 2a 29 70 43 74 78 3b 0a 0a 20 20  ntext*)pCtx;..  
48d0: 50 6f 72 74 65 72 52 75 6c 65 20 61 53 74 65 70  PorterRule aStep
48e0: 31 41 5b 5d 20 3d 20 7b 0a 20 20 20 20 7b 20 22  1A[] = {.    { "
48f0: 73 73 65 73 22 2c 20 34 2c 20 20 30 2c 20 22 73  sses", 4,  0, "s
4900: 73 22 2c 20 32 20 7d 2c 0a 20 20 20 20 7b 20 22  s", 2 },.    { "
4910: 69 65 73 22 2c 20 20 33 2c 20 20 30 2c 20 22 69  ies",  3,  0, "i
4920: 22 2c 20 20 31 20 20 7d 2c 0a 20 20 20 20 7b 20  ",  1  },.    { 
4930: 22 73 73 22 2c 20 20 20 32 2c 20 20 30 2c 20 22  "ss",   2,  0, "
4940: 73 73 22 2c 20 32 20 7d 2c 0a 20 20 20 20 7b 20  ss", 2 },.    { 
4950: 22 73 22 2c 20 20 20 20 31 2c 20 20 30 2c 20 22  "s",    1,  0, "
4960: 22 2c 20 20 20 30 20 7d 2c 0a 20 20 20 20 7b 20  ",   0 },.    { 
4970: 30 2c 20 30 2c 20 30 2c 20 30 20 7d 0a 20 20 7d  0, 0, 0, 0 }.  }
4980: 3b 0a 0a 20 20 50 6f 72 74 65 72 52 75 6c 65 20  ;..  PorterRule 
4990: 61 53 74 65 70 31 42 5b 5d 20 3d 20 7b 0a 20 20  aStep1B[] = {.  
49a0: 20 20 7b 20 22 65 65 64 22 2c 20 33 2c 20 20 66    { "eed", 3,  f
49b0: 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c 20  ts5Porter_MGt0, 
49c0: 20 22 65 65 22 2c 20 32 20 7d 2c 0a 20 20 20 20   "ee", 2 },.    
49d0: 7b 20 22 65 64 22 2c 20 20 32 2c 20 20 66 74 73  { "ed",  2,  fts
49e0: 35 50 6f 72 74 65 72 5f 56 6f 77 65 6c 2c 20 22  5Porter_Vowel, "
49f0: 22 2c 20 20 20 30 20 7d 2c 0a 20 20 20 20 7b 20  ",   0 },.    { 
4a00: 22 69 6e 67 22 2c 20 33 2c 20 20 66 74 73 35 50  "ing", 3,  fts5P
4a10: 6f 72 74 65 72 5f 56 6f 77 65 6c 2c 20 22 22 2c  orter_Vowel, "",
4a20: 20 20 20 30 20 7d 2c 0a 20 20 20 20 7b 20 30 2c     0 },.    { 0,
4a30: 20 30 2c 20 30 2c 20 30 20 7d 0a 20 20 7d 3b 0a   0, 0, 0 }.  };.
4a40: 0a 20 20 50 6f 72 74 65 72 52 75 6c 65 20 61 53  .  PorterRule aS
4a50: 74 65 70 31 42 32 5b 5d 20 3d 20 7b 0a 20 20 20  tep1B2[] = {.   
4a60: 20 7b 20 22 61 74 22 2c 20 32 2c 20 20 30 2c 20   { "at", 2,  0, 
4a70: 22 61 74 65 22 2c 20 33 20 7d 2c 0a 20 20 20 20  "ate", 3 },.    
4a80: 7b 20 22 62 6c 22 2c 20 32 2c 20 20 30 2c 20 22  { "bl", 2,  0, "
4a90: 62 6c 65 22 2c 20 33 20 7d 2c 0a 20 20 20 20 7b  ble", 3 },.    {
4aa0: 20 22 69 7a 22 2c 20 32 2c 20 20 30 2c 20 22 69   "iz", 2,  0, "i
4ab0: 7a 65 22 2c 20 33 20 7d 2c 0a 20 20 20 20 7b 20  ze", 3 },.    { 
4ac0: 30 2c 20 30 2c 20 30 2c 20 30 20 7d 0a 20 20 7d  0, 0, 0, 0 }.  }
4ad0: 3b 0a 0a 20 20 50 6f 72 74 65 72 52 75 6c 65 20  ;..  PorterRule 
4ae0: 61 53 74 65 70 31 43 5b 5d 20 3d 20 7b 0a 20 20  aStep1C[] = {.  
4af0: 20 20 7b 20 22 79 22 2c 20 20 31 2c 20 20 66 74    { "y",  1,  ft
4b00: 73 35 50 6f 72 74 65 72 5f 56 6f 77 65 6c 2c 20  s5Porter_Vowel, 
4b10: 22 69 22 2c 20 31 20 7d 2c 0a 20 20 20 20 7b 20  "i", 1 },.    { 
4b20: 30 2c 20 30 2c 20 30 2c 20 30 20 7d 0a 20 20 7d  0, 0, 0, 0 }.  }
4b30: 3b 0a 0a 20 20 50 6f 72 74 65 72 52 75 6c 65 20  ;..  PorterRule 
4b40: 61 53 74 65 70 32 5b 5d 20 3d 20 7b 0a 20 20 20  aStep2[] = {.   
4b50: 20 7b 20 22 61 74 69 6f 6e 61 6c 22 2c 20 37 2c   { "ational", 7,
4b60: 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30   fts5Porter_MGt0
4b70: 2c 20 22 61 74 65 22 2c 20 33 7d 2c 20 0a 20 20  , "ate", 3}, .  
4b80: 20 20 7b 20 22 74 69 6f 6e 61 6c 22 2c 20 36 2c    { "tional", 6,
4b90: 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30   fts5Porter_MGt0
4ba0: 2c 20 22 74 69 6f 6e 22 2c 20 34 7d 2c 20 0a 20  , "tion", 4}, . 
4bb0: 20 20 20 7b 20 22 65 6e 63 69 22 2c 20 34 2c 20     { "enci", 4, 
4bc0: 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c  fts5Porter_MGt0,
4bd0: 20 22 65 6e 63 65 22 2c 20 34 7d 2c 20 0a 20 20   "ence", 4}, .  
4be0: 20 20 7b 20 22 61 6e 63 69 22 2c 20 34 2c 20 66    { "anci", 4, f
4bf0: 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c 20  ts5Porter_MGt0, 
4c00: 22 61 6e 63 65 22 2c 20 34 7d 2c 20 0a 20 20 20  "ance", 4}, .   
4c10: 20 7b 20 22 69 7a 65 72 22 2c 20 34 2c 20 66 74   { "izer", 4, ft
4c20: 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c 20 22  s5Porter_MGt0, "
4c30: 69 7a 65 22 2c 20 33 7d 2c 20 0a 20 20 20 20 7b  ize", 3}, .    {
4c40: 20 22 6c 6f 67 69 22 2c 20 34 2c 20 66 74 73 35   "logi", 4, fts5
4c50: 50 6f 72 74 65 72 5f 4d 47 74 30 2c 20 22 6c 6f  Porter_MGt0, "lo
4c60: 67 22 2c 20 33 7d 2c 20 20 20 20 20 2f 2a 20 61  g", 3},     /* a
4c70: 64 64 65 64 20 70 6f 73 74 20 31 39 37 39 20 2a  dded post 1979 *
4c80: 2f 0a 20 20 20 20 7b 20 22 62 6c 69 22 2c 20 33  /.    { "bli", 3
4c90: 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74  , fts5Porter_MGt
4ca0: 30 2c 20 22 62 6c 65 22 2c 20 33 7d 2c 20 20 20  0, "ble", 3},   
4cb0: 20 20 20 2f 2a 20 6d 6f 64 69 66 69 65 64 20 70     /* modified p
4cc0: 6f 73 74 20 31 39 37 39 20 2a 2f 0a 20 20 20 20  ost 1979 */.    
4cd0: 7b 20 22 61 6c 6c 69 22 2c 20 34 2c 20 66 74 73  { "alli", 4, fts
4ce0: 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c 20 22 61  5Porter_MGt0, "a
4cf0: 6c 22 2c 20 32 7d 2c 20 0a 20 20 20 20 7b 20 22  l", 2}, .    { "
4d00: 65 6e 74 6c 69 22 2c 20 35 2c 20 66 74 73 35 50  entli", 5, fts5P
4d10: 6f 72 74 65 72 5f 4d 47 74 30 2c 20 22 65 6e 74  orter_MGt0, "ent
4d20: 22 2c 20 33 7d 2c 20 0a 20 20 20 20 7b 20 22 65  ", 3}, .    { "e
4d30: 6c 69 22 2c 20 33 2c 20 66 74 73 35 50 6f 72 74  li", 3, fts5Port
4d40: 65 72 5f 4d 47 74 30 2c 20 22 65 22 2c 20 31 7d  er_MGt0, "e", 1}
4d50: 2c 20 0a 20 20 20 20 7b 20 22 6f 75 73 6c 69 22  , .    { "ousli"
4d60: 2c 20 35 2c 20 66 74 73 35 50 6f 72 74 65 72 5f  , 5, fts5Porter_
4d70: 4d 47 74 30 2c 20 22 6f 75 73 22 2c 20 33 7d 2c  MGt0, "ous", 3},
4d80: 20 0a 20 20 20 20 7b 20 22 69 7a 61 74 69 6f 6e   .    { "ization
4d90: 22 2c 20 37 2c 20 66 74 73 35 50 6f 72 74 65 72  ", 7, fts5Porter
4da0: 5f 4d 47 74 30 2c 20 22 69 7a 65 22 2c 20 33 7d  _MGt0, "ize", 3}
4db0: 2c 20 0a 20 20 20 20 7b 20 22 61 74 69 6f 6e 22  , .    { "ation"
4dc0: 2c 20 35 2c 20 66 74 73 35 50 6f 72 74 65 72 5f  , 5, fts5Porter_
4dd0: 4d 47 74 30 2c 20 22 61 74 65 22 2c 20 33 7d 2c  MGt0, "ate", 3},
4de0: 20 0a 20 20 20 20 7b 20 22 61 74 6f 72 22 2c 20   .    { "ator", 
4df0: 34 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47  4, fts5Porter_MG
4e00: 74 30 2c 20 22 61 74 65 22 2c 20 33 7d 2c 20 0a  t0, "ate", 3}, .
4e10: 20 20 20 20 7b 20 22 61 6c 69 73 6d 22 2c 20 35      { "alism", 5
4e20: 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74  , fts5Porter_MGt
4e30: 30 2c 20 22 61 6c 22 2c 20 32 7d 2c 20 0a 20 20  0, "al", 2}, .  
4e40: 20 20 7b 20 22 69 76 65 6e 65 73 73 22 2c 20 37    { "iveness", 7
4e50: 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74  , fts5Porter_MGt
4e60: 30 2c 20 22 69 76 65 22 2c 20 33 7d 2c 20 0a 20  0, "ive", 3}, . 
4e70: 20 20 20 7b 20 22 66 75 6c 6e 65 73 73 22 2c 20     { "fulness", 
4e80: 37 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47  7, fts5Porter_MG
4e90: 74 30 2c 20 22 66 75 6c 22 2c 20 33 7d 2c 20 0a  t0, "ful", 3}, .
4ea0: 20 20 20 20 7b 20 22 6f 75 73 6e 65 73 73 22 2c      { "ousness",
4eb0: 20 37 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d   7, fts5Porter_M
4ec0: 47 74 30 2c 20 22 6f 75 73 22 2c 20 33 7d 2c 20  Gt0, "ous", 3}, 
4ed0: 0a 20 20 20 20 7b 20 22 61 6c 69 74 69 22 2c 20  .    { "aliti", 
4ee0: 35 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47  5, fts5Porter_MG
4ef0: 74 30 2c 20 22 61 6c 22 2c 20 32 7d 2c 20 0a 20  t0, "al", 2}, . 
4f00: 20 20 20 7b 20 22 69 76 69 74 69 22 2c 20 35 2c     { "iviti", 5,
4f10: 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30   fts5Porter_MGt0
4f20: 2c 20 22 69 76 65 22 2c 20 33 7d 2c 20 0a 20 20  , "ive", 3}, .  
4f30: 20 20 7b 20 22 62 69 6c 69 74 69 22 2c 20 36 2c    { "biliti", 6,
4f40: 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30   fts5Porter_MGt0
4f50: 2c 20 22 62 6c 65 22 2c 20 33 7d 2c 20 0a 20 20  , "ble", 3}, .  
4f60: 20 20 7b 20 30 2c 20 30 2c 20 30 2c 20 30 20 7d    { 0, 0, 0, 0 }
4f70: 0a 20 20 7d 3b 0a 0a 20 20 50 6f 72 74 65 72 52  .  };..  PorterR
4f80: 75 6c 65 20 61 53 74 65 70 33 5b 5d 20 3d 20 7b  ule aStep3[] = {
4f90: 0a 20 20 20 20 7b 20 22 69 63 61 74 65 22 2c 20  .    { "icate", 
4fa0: 35 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47  5, fts5Porter_MG
4fb0: 74 30 2c 20 22 69 63 22 2c 20 32 7d 2c 20 0a 20  t0, "ic", 2}, . 
4fc0: 20 20 20 7b 20 22 61 74 69 76 65 22 2c 20 35 2c     { "ative", 5,
4fd0: 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30   fts5Porter_MGt0
4fe0: 2c 20 22 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b  , "", 0}, .    {
4ff0: 20 22 61 6c 69 7a 65 22 2c 20 35 2c 20 66 74 73   "alize", 5, fts
5000: 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c 20 22 61  5Porter_MGt0, "a
5010: 6c 22 2c 20 32 7d 2c 20 0a 20 20 20 20 7b 20 22  l", 2}, .    { "
5020: 69 63 69 74 69 22 2c 20 35 2c 20 66 74 73 35 50  iciti", 5, fts5P
5030: 6f 72 74 65 72 5f 4d 47 74 30 2c 20 22 69 63 22  orter_MGt0, "ic"
5040: 2c 20 32 7d 2c 20 0a 20 20 20 20 7b 20 22 69 63  , 2}, .    { "ic
5050: 61 6c 22 2c 20 34 2c 20 66 74 73 35 50 6f 72 74  al", 4, fts5Port
5060: 65 72 5f 4d 47 74 30 2c 20 22 69 63 22 2c 20 32  er_MGt0, "ic", 2
5070: 7d 2c 20 0a 20 20 20 20 7b 20 22 66 75 6c 22 2c  }, .    { "ful",
5080: 20 33 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d   3, fts5Porter_M
5090: 47 74 30 2c 20 22 22 2c 20 30 7d 2c 20 0a 20 20  Gt0, "", 0}, .  
50a0: 20 20 7b 20 22 6e 65 73 73 22 2c 20 34 2c 20 66    { "ness", 4, f
50b0: 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 2c 20  ts5Porter_MGt0, 
50c0: 22 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b 20 30  "", 0}, .    { 0
50d0: 2c 20 30 2c 20 30 2c 20 30 20 7d 0a 20 20 7d 3b  , 0, 0, 0 }.  };
50e0: 0a 0a 20 20 50 6f 72 74 65 72 52 75 6c 65 20 61  ..  PorterRule a
50f0: 53 74 65 70 34 5b 5d 20 3d 20 7b 0a 20 20 20 20  Step4[] = {.    
5100: 7b 20 22 61 6c 22 2c 20 32 2c 20 66 74 73 35 50  { "al", 2, fts5P
5110: 6f 72 74 65 72 5f 4d 47 74 31 2c 20 22 22 2c 20  orter_MGt1, "", 
5120: 30 7d 2c 20 0a 20 20 20 20 7b 20 22 61 6e 63 65  0}, .    { "ance
5130: 22 2c 20 34 2c 20 66 74 73 35 50 6f 72 74 65 72  ", 4, fts5Porter
5140: 5f 4d 47 74 31 2c 20 22 22 2c 20 30 7d 2c 20 0a  _MGt1, "", 0}, .
5150: 20 20 20 20 7b 20 22 65 6e 63 65 22 2c 20 34 2c      { "ence", 4,
5160: 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31   fts5Porter_MGt1
5170: 2c 20 22 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b  , "", 0}, .    {
5180: 20 22 65 72 22 2c 20 32 2c 20 66 74 73 35 50 6f   "er", 2, fts5Po
5190: 72 74 65 72 5f 4d 47 74 31 2c 20 22 22 2c 20 30  rter_MGt1, "", 0
51a0: 7d 2c 20 0a 20 20 20 20 7b 20 22 69 63 22 2c 20  }, .    { "ic", 
51b0: 32 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47  2, fts5Porter_MG
51c0: 74 31 2c 20 22 22 2c 20 30 7d 2c 20 0a 20 20 20  t1, "", 0}, .   
51d0: 20 7b 20 22 61 62 6c 65 22 2c 20 34 2c 20 66 74   { "able", 4, ft
51e0: 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 2c 20 22  s5Porter_MGt1, "
51f0: 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b 20 22 69  ", 0}, .    { "i
5200: 62 6c 65 22 2c 20 34 2c 20 66 74 73 35 50 6f 72  ble", 4, fts5Por
5210: 74 65 72 5f 4d 47 74 31 2c 20 22 22 2c 20 30 7d  ter_MGt1, "", 0}
5220: 2c 20 0a 20 20 20 20 7b 20 22 61 6e 74 22 2c 20  , .    { "ant", 
5230: 33 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47  3, fts5Porter_MG
5240: 74 31 2c 20 22 22 2c 20 30 7d 2c 20 0a 20 20 20  t1, "", 0}, .   
5250: 20 7b 20 22 65 6d 65 6e 74 22 2c 20 35 2c 20 66   { "ement", 5, f
5260: 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 2c 20  ts5Porter_MGt1, 
5270: 22 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b 20 22  "", 0}, .    { "
5280: 6d 65 6e 74 22 2c 20 34 2c 20 66 74 73 35 50 6f  ment", 4, fts5Po
5290: 72 74 65 72 5f 4d 47 74 31 2c 20 22 22 2c 20 30  rter_MGt1, "", 0
52a0: 7d 2c 20 0a 20 20 20 20 7b 20 22 65 6e 74 22 2c  }, .    { "ent",
52b0: 20 33 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d   3, fts5Porter_M
52c0: 47 74 31 2c 20 22 22 2c 20 30 7d 2c 20 0a 20 20  Gt1, "", 0}, .  
52d0: 20 20 7b 20 22 69 6f 6e 22 2c 20 33 2c 20 66 74    { "ion", 3, ft
52e0: 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 5f 61 6e  s5Porter_MGt1_an
52f0: 64 5f 53 5f 6f 72 5f 54 2c 20 22 22 2c 20 30 7d  d_S_or_T, "", 0}
5300: 2c 20 0a 20 20 20 20 7b 20 22 6f 75 22 2c 20 32  , .    { "ou", 2
5310: 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74  , fts5Porter_MGt
5320: 31 2c 20 22 22 2c 20 30 7d 2c 20 0a 20 20 20 20  1, "", 0}, .    
5330: 7b 20 22 69 73 6d 22 2c 20 33 2c 20 66 74 73 35  { "ism", 3, fts5
5340: 50 6f 72 74 65 72 5f 4d 47 74 31 2c 20 22 22 2c  Porter_MGt1, "",
5350: 20 30 7d 2c 20 0a 20 20 20 20 7b 20 22 61 74 65   0}, .    { "ate
5360: 22 2c 20 33 2c 20 66 74 73 35 50 6f 72 74 65 72  ", 3, fts5Porter
5370: 5f 4d 47 74 31 2c 20 22 22 2c 20 30 7d 2c 20 0a  _MGt1, "", 0}, .
5380: 20 20 20 20 7b 20 22 69 74 69 22 2c 20 33 2c 20      { "iti", 3, 
5390: 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 2c  fts5Porter_MGt1,
53a0: 20 22 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b 20   "", 0}, .    { 
53b0: 22 6f 75 73 22 2c 20 33 2c 20 66 74 73 35 50 6f  "ous", 3, fts5Po
53c0: 72 74 65 72 5f 4d 47 74 31 2c 20 22 22 2c 20 30  rter_MGt1, "", 0
53d0: 7d 2c 20 0a 20 20 20 20 7b 20 22 69 76 65 22 2c  }, .    { "ive",
53e0: 20 33 2c 20 66 74 73 35 50 6f 72 74 65 72 5f 4d   3, fts5Porter_M
53f0: 47 74 31 2c 20 22 22 2c 20 30 7d 2c 20 0a 20 20  Gt1, "", 0}, .  
5400: 20 20 7b 20 22 69 7a 65 22 2c 20 33 2c 20 66 74    { "ize", 3, ft
5410: 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 2c 20 22  s5Porter_MGt1, "
5420: 22 2c 20 30 7d 2c 20 0a 20 20 20 20 7b 20 30 2c  ", 0}, .    { 0,
5430: 20 30 2c 20 30 2c 20 30 20 7d 0a 20 20 7d 3b 0a   0, 0, 0 }.  };.
5440: 0a 0a 20 20 63 68 61 72 20 2a 61 42 75 66 3b 0a  ..  char *aBuf;.
5450: 20 20 69 6e 74 20 6e 42 75 66 3b 0a 20 20 69 6e    int nBuf;.  in
5460: 74 20 6e 3b 0a 0a 20 20 69 66 28 20 6e 54 6f 6b  t n;..  if( nTok
5470: 65 6e 3e 46 54 53 35 5f 50 4f 52 54 45 52 5f 4d  en>FTS5_PORTER_M
5480: 41 58 5f 54 4f 4b 45 4e 20 7c 7c 20 6e 54 6f 6b  AX_TOKEN || nTok
5490: 65 6e 3c 33 20 29 20 67 6f 74 6f 20 70 61 73 73  en<3 ) goto pass
54a0: 5f 74 68 72 6f 75 67 68 3b 0a 20 20 61 42 75 66  _through;.  aBuf
54b0: 20 3d 20 70 2d 3e 61 42 75 66 3b 0a 20 20 6e 42   = p->aBuf;.  nB
54c0: 75 66 20 3d 20 6e 54 6f 6b 65 6e 3b 0a 20 20 6d  uf = nToken;.  m
54d0: 65 6d 63 70 79 28 61 42 75 66 2c 20 70 54 6f 6b  emcpy(aBuf, pTok
54e0: 65 6e 2c 20 6e 42 75 66 29 3b 0a 0a 20 20 2f 2a  en, nBuf);..  /*
54f0: 20 53 74 65 70 20 31 2e 20 2a 2f 0a 20 20 66 74   Step 1. */.  ft
5500: 73 35 50 6f 72 74 65 72 41 70 70 6c 79 28 61 42  s5PorterApply(aB
5510: 75 66 2c 20 26 6e 42 75 66 2c 20 61 53 74 65 70  uf, &nBuf, aStep
5520: 31 41 29 3b 0a 20 20 6e 20 3d 20 66 74 73 35 50  1A);.  n = fts5P
5530: 6f 72 74 65 72 41 70 70 6c 79 28 61 42 75 66 2c  orterApply(aBuf,
5540: 20 26 6e 42 75 66 2c 20 61 53 74 65 70 31 42 29   &nBuf, aStep1B)
5550: 3b 0a 20 20 69 66 28 20 6e 3d 3d 31 20 7c 7c 20  ;.  if( n==1 || 
5560: 6e 3d 3d 32 20 29 7b 0a 20 20 20 20 69 66 28 20  n==2 ){.    if( 
5570: 66 74 73 35 50 6f 72 74 65 72 41 70 70 6c 79 28  fts5PorterApply(
5580: 61 42 75 66 2c 20 26 6e 42 75 66 2c 20 61 53 74  aBuf, &nBuf, aSt
5590: 65 70 31 42 32 29 3c 30 20 29 7b 0a 20 20 20 20  ep1B2)<0 ){.    
55a0: 20 20 63 68 61 72 20 63 20 3d 20 61 42 75 66 5b    char c = aBuf[
55b0: 6e 42 75 66 2d 31 5d 3b 0a 20 20 20 20 20 20 69  nBuf-1];.      i
55c0: 66 28 20 66 74 73 35 50 6f 72 74 65 72 49 73 56  f( fts5PorterIsV
55d0: 6f 77 65 6c 28 63 2c 20 30 29 3d 3d 30 20 0a 20  owel(c, 0)==0 . 
55e0: 20 20 20 20 20 20 26 26 20 63 21 3d 27 6c 27 20        && c!='l' 
55f0: 26 26 20 63 21 3d 27 73 27 20 26 26 20 63 21 3d  && c!='s' && c!=
5600: 27 7a 27 20 26 26 20 63 3d 3d 61 42 75 66 5b 6e  'z' && c==aBuf[n
5610: 42 75 66 2d 32 5d 20 0a 20 20 20 20 20 20 29 7b  Buf-2] .      ){
5620: 0a 20 20 20 20 20 20 20 20 6e 42 75 66 2d 2d 3b  .        nBuf--;
5630: 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28  .      }else if(
5640: 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 45 71 31   fts5Porter_MEq1
5650: 28 61 42 75 66 2c 20 6e 42 75 66 29 20 26 26 20  (aBuf, nBuf) && 
5660: 66 74 73 35 50 6f 72 74 65 72 5f 4f 73 74 61 72  fts5Porter_Ostar
5670: 28 61 42 75 66 2c 20 6e 42 75 66 29 20 29 7b 0a  (aBuf, nBuf) ){.
5680: 20 20 20 20 20 20 20 20 61 42 75 66 5b 6e 42 75          aBuf[nBu
5690: 66 2b 2b 5d 20 3d 20 27 65 27 3b 0a 20 20 20 20  f++] = 'e';.    
56a0: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20    }.    }.  }.  
56b0: 66 74 73 35 50 6f 72 74 65 72 41 70 70 6c 79 28  fts5PorterApply(
56c0: 61 42 75 66 2c 20 26 6e 42 75 66 2c 20 61 53 74  aBuf, &nBuf, aSt
56d0: 65 70 31 43 29 3b 0a 0a 20 20 2f 2a 20 53 74 65  ep1C);..  /* Ste
56e0: 70 73 20 32 20 74 68 72 6f 75 67 68 20 34 2e 20  ps 2 through 4. 
56f0: 2a 2f 0a 20 20 66 74 73 35 50 6f 72 74 65 72 41  */.  fts5PorterA
5700: 70 70 6c 79 28 61 42 75 66 2c 20 26 6e 42 75 66  pply(aBuf, &nBuf
5710: 2c 20 61 53 74 65 70 32 29 3b 0a 20 20 66 74 73  , aStep2);.  fts
5720: 35 50 6f 72 74 65 72 41 70 70 6c 79 28 61 42 75  5PorterApply(aBu
5730: 66 2c 20 26 6e 42 75 66 2c 20 61 53 74 65 70 33  f, &nBuf, aStep3
5740: 29 3b 0a 20 20 66 74 73 35 50 6f 72 74 65 72 41  );.  fts5PorterA
5750: 70 70 6c 79 28 61 42 75 66 2c 20 26 6e 42 75 66  pply(aBuf, &nBuf
5760: 2c 20 61 53 74 65 70 34 29 3b 0a 0a 20 20 2f 2a  , aStep4);..  /*
5770: 20 53 74 65 70 20 35 61 2e 20 2a 2f 0a 20 20 69   Step 5a. */.  i
5780: 66 28 20 6e 42 75 66 3e 30 20 26 26 20 61 42 75  f( nBuf>0 && aBu
5790: 66 5b 6e 42 75 66 2d 31 5d 3d 3d 27 65 27 20 29  f[nBuf-1]=='e' )
57a0: 7b 0a 20 20 20 20 69 66 28 20 66 74 73 35 50 6f  {.    if( fts5Po
57b0: 72 74 65 72 5f 4d 47 74 31 28 61 42 75 66 2c 20  rter_MGt1(aBuf, 
57c0: 6e 42 75 66 2d 31 29 20 0a 20 20 20 20 20 7c 7c  nBuf-1) .     ||
57d0: 20 28 66 74 73 35 50 6f 72 74 65 72 5f 4d 45 71   (fts5Porter_MEq
57e0: 31 28 61 42 75 66 2c 20 6e 42 75 66 2d 31 29 20  1(aBuf, nBuf-1) 
57f0: 26 26 20 21 66 74 73 35 50 6f 72 74 65 72 5f 4f  && !fts5Porter_O
5800: 73 74 61 72 28 61 42 75 66 2c 20 6e 42 75 66 2d  star(aBuf, nBuf-
5810: 31 29 29 0a 20 20 20 20 29 7b 0a 20 20 20 20 20  1)).    ){.     
5820: 20 6e 42 75 66 2d 2d 3b 0a 20 20 20 20 7d 0a 20   nBuf--;.    }. 
5830: 20 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20 35 62   }..  /* Step 5b
5840: 2e 20 2a 2f 0a 20 20 69 66 28 20 6e 42 75 66 3e  . */.  if( nBuf>
5850: 31 20 26 26 20 61 42 75 66 5b 6e 42 75 66 2d 31  1 && aBuf[nBuf-1
5860: 5d 3d 3d 27 6c 27 20 0a 20 20 20 26 26 20 61 42  ]=='l' .   && aB
5870: 75 66 5b 6e 42 75 66 2d 32 5d 3d 3d 27 6c 27 20  uf[nBuf-2]=='l' 
5880: 26 26 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47  && fts5Porter_MG
5890: 74 31 28 61 42 75 66 2c 20 6e 42 75 66 2d 31 29  t1(aBuf, nBuf-1)
58a0: 20 0a 20 20 29 7b 0a 20 20 20 20 6e 42 75 66 2d   .  ){.    nBuf-
58b0: 2d 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e  -;.  }..  return
58c0: 20 70 2d 3e 78 54 6f 6b 65 6e 28 70 2d 3e 70 43   p->xToken(p->pC
58d0: 74 78 2c 20 61 42 75 66 2c 20 6e 42 75 66 2c 20  tx, aBuf, nBuf, 
58e0: 69 53 74 61 72 74 2c 20 69 45 6e 64 29 3b 0a 0a  iStart, iEnd);..
58f0: 20 70 61 73 73 5f 74 68 72 6f 75 67 68 3a 0a 20   pass_through:. 
5900: 20 72 65 74 75 72 6e 20 70 2d 3e 78 54 6f 6b 65   return p->xToke
5910: 6e 28 70 2d 3e 70 43 74 78 2c 20 70 54 6f 6b 65  n(p->pCtx, pToke
5920: 6e 2c 20 6e 54 6f 6b 65 6e 2c 20 69 53 74 61 72  n, nToken, iStar
5930: 74 2c 20 69 45 6e 64 29 3b 0a 7d 0a 0a 2f 2a 0a  t, iEnd);.}../*.
5940: 2a 2a 20 54 6f 6b 65 6e 69 7a 65 20 75 73 69 6e  ** Tokenize usin
5950: 67 20 74 68 65 20 70 6f 72 74 65 72 20 74 6f 6b  g the porter tok
5960: 65 6e 69 7a 65 72 2e 0a 2a 2f 0a 73 74 61 74 69  enizer..*/.stati
5970: 63 20 69 6e 74 20 66 74 73 35 50 6f 72 74 65 72  c int fts5Porter
5980: 54 6f 6b 65 6e 69 7a 65 28 0a 20 20 46 74 73 35  Tokenize(.  Fts5
5990: 54 6f 6b 65 6e 69 7a 65 72 20 2a 70 54 6f 6b 65  Tokenizer *pToke
59a0: 6e 69 7a 65 72 2c 0a 20 20 76 6f 69 64 20 2a 70  nizer,.  void *p
59b0: 43 74 78 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61  Ctx,.  const cha
59c0: 72 20 2a 70 54 65 78 74 2c 20 69 6e 74 20 6e 54  r *pText, int nT
59d0: 65 78 74 2c 0a 20 20 69 6e 74 20 28 2a 78 54 6f  ext,.  int (*xTo
59e0: 6b 65 6e 29 28 76 6f 69 64 2a 2c 20 63 6f 6e 73  ken)(void*, cons
59f0: 74 20 63 68 61 72 2a 2c 20 69 6e 74 20 6e 54 6f  t char*, int nTo
5a00: 6b 65 6e 2c 20 69 6e 74 20 69 53 74 61 72 74 2c  ken, int iStart,
5a10: 20 69 6e 74 20 69 45 6e 64 29 0a 29 7b 0a 20 20   int iEnd).){.  
5a20: 50 6f 72 74 65 72 54 6f 6b 65 6e 69 7a 65 72 20  PorterTokenizer 
5a30: 2a 70 20 3d 20 28 50 6f 72 74 65 72 54 6f 6b 65  *p = (PorterToke
5a40: 6e 69 7a 65 72 2a 29 70 54 6f 6b 65 6e 69 7a 65  nizer*)pTokenize
5a50: 72 3b 0a 20 20 50 6f 72 74 65 72 43 6f 6e 74 65  r;.  PorterConte
5a60: 78 74 20 73 43 74 78 3b 0a 20 20 73 43 74 78 2e  xt sCtx;.  sCtx.
5a70: 78 54 6f 6b 65 6e 20 3d 20 78 54 6f 6b 65 6e 3b  xToken = xToken;
5a80: 0a 20 20 73 43 74 78 2e 70 43 74 78 20 3d 20 70  .  sCtx.pCtx = p
5a90: 43 74 78 3b 0a 20 20 73 43 74 78 2e 61 42 75 66  Ctx;.  sCtx.aBuf
5aa0: 20 3d 20 70 2d 3e 61 42 75 66 3b 0a 20 20 72 65   = p->aBuf;.  re
5ab0: 74 75 72 6e 20 70 2d 3e 74 6f 6b 65 6e 69 7a 65  turn p->tokenize
5ac0: 72 2e 78 54 6f 6b 65 6e 69 7a 65 28 0a 20 20 20  r.xTokenize(.   
5ad0: 20 20 20 70 2d 3e 70 54 6f 6b 65 6e 69 7a 65 72     p->pTokenizer
5ae0: 2c 20 28 76 6f 69 64 2a 29 26 73 43 74 78 2c 20  , (void*)&sCtx, 
5af0: 70 54 65 78 74 2c 20 6e 54 65 78 74 2c 20 66 74  pText, nText, ft
5b00: 73 35 50 6f 72 74 65 72 43 62 0a 20 20 29 3b 0a  s5PorterCb.  );.
5b10: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74 65  }../*.** Registe
5b20: 72 20 61 6c 6c 20 62 75 69 6c 74 2d 69 6e 20 74  r all built-in t
5b30: 6f 6b 65 6e 69 7a 65 72 73 20 77 69 74 68 20 46  okenizers with F
5b40: 54 53 35 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  TS5..*/.int sqli
5b50: 74 65 33 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72  te3Fts5Tokenizer
5b60: 49 6e 69 74 28 66 74 73 35 5f 61 70 69 20 2a 70  Init(fts5_api *p
5b70: 41 70 69 29 7b 0a 20 20 73 74 72 75 63 74 20 42  Api){.  struct B
5b80: 75 69 6c 74 69 6e 54 6f 6b 65 6e 69 7a 65 72 20  uiltinTokenizer 
5b90: 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72  {.    const char
5ba0: 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20 66 74 73   *zName;.    fts
5bb0: 35 5f 74 6f 6b 65 6e 69 7a 65 72 20 78 3b 0a 20  5_tokenizer x;. 
5bc0: 20 7d 20 61 42 75 69 6c 74 69 6e 5b 5d 20 3d 20   } aBuiltin[] = 
5bd0: 7b 0a 20 20 20 20 7b 20 22 75 6e 69 63 6f 64 65  {.    { "unicode
5be0: 36 31 22 2c 20 7b 66 74 73 35 55 6e 69 63 6f 64  61", {fts5Unicod
5bf0: 65 43 72 65 61 74 65 2c 20 66 74 73 35 55 6e 69  eCreate, fts5Uni
5c00: 63 6f 64 65 44 65 6c 65 74 65 2c 20 66 74 73 35  codeDelete, fts5
5c10: 55 6e 69 63 6f 64 65 54 6f 6b 65 6e 69 7a 65 7d  UnicodeTokenize}
5c20: 7d 2c 0a 20 20 20 20 7b 20 22 61 73 63 69 69 22  },.    { "ascii"
5c30: 2c 20 20 20 20 20 7b 66 74 73 35 41 73 63 69 69  ,     {fts5Ascii
5c40: 43 72 65 61 74 65 2c 20 66 74 73 35 41 73 63 69  Create, fts5Asci
5c50: 69 44 65 6c 65 74 65 2c 20 66 74 73 35 41 73 63  iDelete, fts5Asc
5c60: 69 69 54 6f 6b 65 6e 69 7a 65 20 7d 7d 2c 0a 20  iiTokenize }},. 
5c70: 20 20 20 7b 20 22 70 6f 72 74 65 72 22 2c 20 20     { "porter",  
5c80: 20 20 7b 66 74 73 35 50 6f 72 74 65 72 43 72 65    {fts5PorterCre
5c90: 61 74 65 2c 20 66 74 73 35 50 6f 72 74 65 72 44  ate, fts5PorterD
5ca0: 65 6c 65 74 65 2c 20 66 74 73 35 50 6f 72 74 65  elete, fts5Porte
5cb0: 72 54 6f 6b 65 6e 69 7a 65 20 7d 7d 2c 0a 20 20  rTokenize }},.  
5cc0: 7d 3b 0a 20 20 0a 20 20 69 6e 74 20 72 63 20 3d  };.  .  int rc =
5cd0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20   SQLITE_OK;     
5ce0: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
5cf0: 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20  n code */.  int 
5d00: 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  i;              
5d10: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
5d20: 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f 75 67  o iterate throug
5d30: 68 20 62 75 69 6c 74 69 6e 20 66 75 6e 63 74 69  h builtin functi
5d40: 6f 6e 73 20 2a 2f 0a 0a 20 20 66 6f 72 28 69 3d  ons */..  for(i=
5d50: 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  0; rc==SQLITE_OK
5d60: 20 26 26 20 69 3c 73 69 7a 65 6f 66 28 61 42 75   && i<sizeof(aBu
5d70: 69 6c 74 69 6e 29 2f 73 69 7a 65 6f 66 28 61 42  iltin)/sizeof(aB
5d80: 75 69 6c 74 69 6e 5b 30 5d 29 3b 20 69 2b 2b 29  uiltin[0]); i++)
5d90: 7b 0a 20 20 20 20 72 63 20 3d 20 70 41 70 69 2d  {.    rc = pApi-
5da0: 3e 78 43 72 65 61 74 65 54 6f 6b 65 6e 69 7a 65  >xCreateTokenize
5db0: 72 28 70 41 70 69 2c 0a 20 20 20 20 20 20 20 20  r(pApi,.        
5dc0: 61 42 75 69 6c 74 69 6e 5b 69 5d 2e 7a 4e 61 6d  aBuiltin[i].zNam
5dd0: 65 2c 0a 20 20 20 20 20 20 20 20 28 76 6f 69 64  e,.        (void
5de0: 2a 29 70 41 70 69 2c 0a 20 20 20 20 20 20 20 20  *)pApi,.        
5df0: 26 61 42 75 69 6c 74 69 6e 5b 69 5d 2e 78 2c 0a  &aBuiltin[i].x,.
5e00: 20 20 20 20 20 20 20 20 30 0a 20 20 20 20 29 3b          0.    );
5e10: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53  .  }..  return S
5e20: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 0a        QLITE_OK;.}...