/ Hex Artifact Content
Login

Artifact 4d904c237707de8fbb8ab98d24d5c55d47204a3f1f35895d8a53a5327079b32c:


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 0a 23 69 6e 63 6c  *****.*/...#incl
0180: 75 64 65 20 22 66 74 73 35 49 6e 74 2e 68 22 0a  ude "fts5Int.h".
0190: 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ./**************
01a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
01b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
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 0a 2a 2a 20  ************.** 
01e0: 53 74 61 72 74 20 6f 66 20 61 73 63 69 69 20 74  Start of ascii t
01f0: 6f 6b 65 6e 69 7a 65 72 20 69 6d 70 6c 65 6d 65  okenizer impleme
0200: 6e 74 61 74 69 6f 6e 2e 0a 2a 2f 0a 0a 2f 2a 0a  ntation..*/../*.
0210: 2a 2a 20 46 6f 72 20 74 6f 6b 65 6e 69 7a 65 72  ** For tokenizer
0220: 73 20 77 69 74 68 20 6e 6f 20 22 75 6e 69 63 6f  s with no "unico
0230: 64 65 22 20 6d 6f 64 69 66 69 65 72 2c 20 74 68  de" modifier, th
0240: 65 20 73 65 74 20 6f 66 20 74 6f 6b 65 6e 20 63  e set of token c
0250: 68 61 72 61 63 74 65 72 73 0a 2a 2a 20 69 73 20  haracters.** is 
0260: 74 68 65 20 73 61 6d 65 20 61 73 20 74 68 65 20  the same as the 
0270: 73 65 74 20 6f 66 20 41 53 43 49 49 20 72 61 6e  set of ASCII ran
0280: 67 65 20 61 6c 70 68 61 6e 75 6d 65 72 69 63 20  ge alphanumeric 
0290: 63 68 61 72 61 63 74 65 72 73 2e 20 0a 2a 2f 0a  characters. .*/.
02a0: 73 74 61 74 69 63 20 75 6e 73 69 67 6e 65 64 20  static unsigned 
02b0: 63 68 61 72 20 61 41 73 63 69 69 54 6f 6b 65 6e  char aAsciiToken
02c0: 43 68 61 72 5b 31 32 38 5d 20 3d 20 7b 0a 20 20  Char[128] = {.  
02d0: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30  0, 0, 0, 0, 0, 0
02e0: 2c 20 30 2c 20 30 2c 20 20 20 30 2c 20 30 2c 20  , 0, 0,   0, 0, 
02f0: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30  0, 0, 0, 0, 0, 0
0300: 2c 20 20 20 2f 2a 20 30 78 30 30 2e 2e 30 78 30  ,   /* 0x00..0x0
0310: 46 20 2a 2f 0a 20 20 30 2c 20 30 2c 20 30 2c 20  F */.  0, 0, 0, 
0320: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20  0, 0, 0, 0, 0,  
0330: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20   0, 0, 0, 0, 0, 
0340: 30 2c 20 30 2c 20 30 2c 20 20 20 2f 2a 20 30 78  0, 0, 0,   /* 0x
0350: 31 30 2e 2e 30 78 31 46 20 2a 2f 0a 20 20 30 2c  10..0x1F */.  0,
0360: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20   0, 0, 0, 0, 0, 
0370: 30 2c 20 30 2c 20 20 20 30 2c 20 30 2c 20 30 2c  0, 0,   0, 0, 0,
0380: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20   0, 0, 0, 0, 0, 
0390: 20 20 2f 2a 20 30 78 32 30 2e 2e 30 78 32 46 20    /* 0x20..0x2F 
03a0: 2a 2f 0a 20 20 31 2c 20 31 2c 20 31 2c 20 31 2c  */.  1, 1, 1, 1,
03b0: 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 20 20 31   1, 1, 1, 1,   1
03c0: 2c 20 31 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c  , 1, 0, 0, 0, 0,
03d0: 20 30 2c 20 30 2c 20 20 20 2f 2a 20 30 78 33 30   0, 0,   /* 0x30
03e0: 2e 2e 30 78 33 46 20 2a 2f 0a 20 20 30 2c 20 31  ..0x3F */.  0, 1
03f0: 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c  , 1, 1, 1, 1, 1,
0400: 20 31 2c 20 20 20 31 2c 20 31 2c 20 31 2c 20 31   1,   1, 1, 1, 1
0410: 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 20 20  , 1, 1, 1, 1,   
0420: 2f 2a 20 30 78 34 30 2e 2e 30 78 34 46 20 2a 2f  /* 0x40..0x4F */
0430: 0a 20 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  .  1, 1, 1, 1, 1
0440: 2c 20 31 2c 20 31 2c 20 31 2c 20 20 20 31 2c 20  , 1, 1, 1,   1, 
0450: 31 2c 20 31 2c 20 30 2c 20 30 2c 20 30 2c 20 30  1, 1, 0, 0, 0, 0
0460: 2c 20 30 2c 20 20 20 2f 2a 20 30 78 35 30 2e 2e  , 0,   /* 0x50..
0470: 30 78 35 46 20 2a 2f 0a 20 20 30 2c 20 31 2c 20  0x5F */.  0, 1, 
0480: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
0490: 2c 20 20 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20  ,   1, 1, 1, 1, 
04a0: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 20 20 2f 2a  1, 1, 1, 1,   /*
04b0: 20 30 78 36 30 2e 2e 30 78 36 46 20 2a 2f 0a 20   0x60..0x6F */. 
04c0: 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20   1, 1, 1, 1, 1, 
04d0: 31 2c 20 31 2c 20 31 2c 20 20 20 31 2c 20 31 2c  1, 1, 1,   1, 1,
04e0: 20 31 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20   1, 0, 0, 0, 0, 
04f0: 30 2c 20 20 20 2f 2a 20 30 78 37 30 2e 2e 30 78  0,   /* 0x70..0x
0500: 37 46 20 2a 2f 0a 7d 3b 0a 0a 74 79 70 65 64 65  7F */.};..typede
0510: 66 20 73 74 72 75 63 74 20 41 73 63 69 69 54 6f  f struct AsciiTo
0520: 6b 65 6e 69 7a 65 72 20 41 73 63 69 69 54 6f 6b  kenizer AsciiTok
0530: 65 6e 69 7a 65 72 3b 0a 73 74 72 75 63 74 20 41  enizer;.struct A
0540: 73 63 69 69 54 6f 6b 65 6e 69 7a 65 72 20 7b 0a  sciiTokenizer {.
0550: 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20    unsigned char 
0560: 61 54 6f 6b 65 6e 43 68 61 72 5b 31 32 38 5d 3b  aTokenChar[128];
0570: 0a 7d 3b 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  .};..static void
0580: 20 66 74 73 35 41 73 63 69 69 41 64 64 45 78 63   fts5AsciiAddExc
0590: 65 70 74 69 6f 6e 73 28 0a 20 20 41 73 63 69 69  eptions(.  Ascii
05a0: 54 6f 6b 65 6e 69 7a 65 72 20 2a 70 2c 20 0a 20  Tokenizer *p, . 
05b0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 41 72   const char *zAr
05c0: 67 2c 20 0a 20 20 69 6e 74 20 62 54 6f 6b 65 6e  g, .  int bToken
05d0: 43 68 61 72 73 0a 29 7b 0a 20 20 69 6e 74 20 69  Chars.){.  int i
05e0: 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 7a 41 72  ;.  for(i=0; zAr
05f0: 67 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  g[i]; i++){.    
0600: 69 66 28 20 28 7a 41 72 67 5b 69 5d 20 26 20 30  if( (zArg[i] & 0
0610: 78 38 30 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20  x80)==0 ){.     
0620: 20 70 2d 3e 61 54 6f 6b 65 6e 43 68 61 72 5b 28   p->aTokenChar[(
0630: 69 6e 74 29 7a 41 72 67 5b 69 5d 5d 20 3d 20 28  int)zArg[i]] = (
0640: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 29 62 54  unsigned char)bT
0650: 6f 6b 65 6e 43 68 61 72 73 3b 0a 20 20 20 20 7d  okenChars;.    }
0660: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65  .  }.}../*.** De
0670: 6c 65 74 65 20 61 20 22 61 73 63 69 69 22 20 74  lete a "ascii" t
0680: 6f 6b 65 6e 69 7a 65 72 2e 0a 2a 2f 0a 73 74 61  okenizer..*/.sta
0690: 74 69 63 20 76 6f 69 64 20 66 74 73 35 41 73 63  tic void fts5Asc
06a0: 69 69 44 65 6c 65 74 65 28 46 74 73 35 54 6f 6b  iiDelete(Fts5Tok
06b0: 65 6e 69 7a 65 72 20 2a 70 29 7b 0a 20 20 73 71  enizer *p){.  sq
06c0: 6c 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 7d  lite3_free(p);.}
06d0: 0a 0a 2f 2a 0a 2a 2a 20 43 72 65 61 74 65 20 61  ../*.** Create a
06e0: 6e 20 22 61 73 63 69 69 22 20 74 6f 6b 65 6e 69  n "ascii" tokeni
06f0: 7a 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  zer..*/.static i
0700: 6e 74 20 66 74 73 35 41 73 63 69 69 43 72 65 61  nt fts5AsciiCrea
0710: 74 65 28 0a 20 20 76 6f 69 64 20 2a 70 55 6e 75  te(.  void *pUnu
0720: 73 65 64 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68  sed, .  const ch
0730: 61 72 20 2a 2a 61 7a 41 72 67 2c 20 69 6e 74 20  ar **azArg, int 
0740: 6e 41 72 67 2c 0a 20 20 46 74 73 35 54 6f 6b 65  nArg,.  Fts5Toke
0750: 6e 69 7a 65 72 20 2a 2a 70 70 4f 75 74 0a 29 7b  nizer **ppOut.){
0760: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
0770: 54 45 5f 4f 4b 3b 0a 20 20 41 73 63 69 69 54 6f  TE_OK;.  AsciiTo
0780: 6b 65 6e 69 7a 65 72 20 2a 70 20 3d 20 30 3b 0a  kenizer *p = 0;.
0790: 20 20 55 4e 55 53 45 44 5f 50 41 52 41 4d 28 70    UNUSED_PARAM(p
07a0: 55 6e 75 73 65 64 29 3b 0a 20 20 69 66 28 20 6e  Unused);.  if( n
07b0: 41 72 67 25 32 20 29 7b 0a 20 20 20 20 72 63 20  Arg%2 ){.    rc 
07c0: 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  = SQLITE_ERROR;.
07d0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 20 3d    }else{.    p =
07e0: 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28   sqlite3_malloc(
07f0: 73 69 7a 65 6f 66 28 41 73 63 69 69 54 6f 6b 65  sizeof(AsciiToke
0800: 6e 69 7a 65 72 29 29 3b 0a 20 20 20 20 69 66 28  nizer));.    if(
0810: 20 70 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72   p==0 ){.      r
0820: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
0830: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
0840: 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20     int i;.      
0850: 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 73 69 7a  memset(p, 0, siz
0860: 65 6f 66 28 41 73 63 69 69 54 6f 6b 65 6e 69 7a  eof(AsciiTokeniz
0870: 65 72 29 29 3b 0a 20 20 20 20 20 20 6d 65 6d 63  er));.      memc
0880: 70 79 28 70 2d 3e 61 54 6f 6b 65 6e 43 68 61 72  py(p->aTokenChar
0890: 2c 20 61 41 73 63 69 69 54 6f 6b 65 6e 43 68 61  , aAsciiTokenCha
08a0: 72 2c 20 73 69 7a 65 6f 66 28 61 41 73 63 69 69  r, sizeof(aAscii
08b0: 54 6f 6b 65 6e 43 68 61 72 29 29 3b 0a 20 20 20  TokenChar));.   
08c0: 20 20 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d     for(i=0; rc==
08d0: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 6e  SQLITE_OK && i<n
08e0: 41 72 67 3b 20 69 2b 3d 32 29 7b 0a 20 20 20 20  Arg; i+=2){.    
08f0: 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a      const char *
0900: 7a 41 72 67 20 3d 20 61 7a 41 72 67 5b 69 2b 31  zArg = azArg[i+1
0910: 5d 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 30  ];.        if( 0
0920: 3d 3d 73 71 6c 69 74 65 33 5f 73 74 72 69 63 6d  ==sqlite3_stricm
0930: 70 28 61 7a 41 72 67 5b 69 5d 2c 20 22 74 6f 6b  p(azArg[i], "tok
0940: 65 6e 63 68 61 72 73 22 29 20 29 7b 0a 20 20 20  enchars") ){.   
0950: 20 20 20 20 20 20 20 66 74 73 35 41 73 63 69 69         fts5Ascii
0960: 41 64 64 45 78 63 65 70 74 69 6f 6e 73 28 70 2c  AddExceptions(p,
0970: 20 7a 41 72 67 2c 20 31 29 3b 0a 20 20 20 20 20   zArg, 1);.     
0980: 20 20 20 7d 65 6c 73 65 0a 20 20 20 20 20 20 20     }else.       
0990: 20 69 66 28 20 30 3d 3d 73 71 6c 69 74 65 33 5f   if( 0==sqlite3_
09a0: 73 74 72 69 63 6d 70 28 61 7a 41 72 67 5b 69 5d  stricmp(azArg[i]
09b0: 2c 20 22 73 65 70 61 72 61 74 6f 72 73 22 29 20  , "separators") 
09c0: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 66 74 73  ){.          fts
09d0: 35 41 73 63 69 69 41 64 64 45 78 63 65 70 74 69  5AsciiAddExcepti
09e0: 6f 6e 73 28 70 2c 20 7a 41 72 67 2c 20 30 29 3b  ons(p, zArg, 0);
09f0: 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  .        }else{.
0a00: 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 53            rc = S
0a10: 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20  QLITE_ERROR;.   
0a20: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20       }.      }. 
0a30: 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c       if( rc!=SQL
0a40: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
0a50: 20 20 66 74 73 35 41 73 63 69 69 44 65 6c 65 74    fts5AsciiDelet
0a60: 65 28 28 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72  e((Fts5Tokenizer
0a70: 2a 29 70 29 3b 0a 20 20 20 20 20 20 20 20 70 20  *)p);.        p 
0a80: 3d 20 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  = 0;.      }.   
0a90: 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 70 4f 75 74   }.  }..  *ppOut
0aa0: 20 3d 20 28 46 74 73 35 54 6f 6b 65 6e 69 7a 65   = (Fts5Tokenize
0ab0: 72 2a 29 70 3b 0a 20 20 72 65 74 75 72 6e 20 72  r*)p;.  return r
0ac0: 63 3b 0a 7d 0a 0a 0a 73 74 61 74 69 63 20 76 6f  c;.}...static vo
0ad0: 69 64 20 61 73 63 69 69 46 6f 6c 64 28 63 68 61  id asciiFold(cha
0ae0: 72 20 2a 61 4f 75 74 2c 20 63 6f 6e 73 74 20 63  r *aOut, const c
0af0: 68 61 72 20 2a 61 49 6e 2c 20 69 6e 74 20 6e 42  har *aIn, int nB
0b00: 79 74 65 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20  yte){.  int i;. 
0b10: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 42 79 74   for(i=0; i<nByt
0b20: 65 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 63 68 61  e; i++){.    cha
0b30: 72 20 63 20 3d 20 61 49 6e 5b 69 5d 3b 0a 20 20  r c = aIn[i];.  
0b40: 20 20 69 66 28 20 63 3e 3d 27 41 27 20 26 26 20    if( c>='A' && 
0b50: 63 3c 3d 27 5a 27 20 29 20 63 20 2b 3d 20 33 32  c<='Z' ) c += 32
0b60: 3b 0a 20 20 20 20 61 4f 75 74 5b 69 5d 20 3d 20  ;.    aOut[i] = 
0b70: 63 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  c;.  }.}../*.** 
0b80: 54 6f 6b 65 6e 69 7a 65 20 73 6f 6d 65 20 74 65  Tokenize some te
0b90: 78 74 20 75 73 69 6e 67 20 74 68 65 20 61 73 63  xt using the asc
0ba0: 69 69 20 74 6f 6b 65 6e 69 7a 65 72 2e 0a 2a 2f  ii tokenizer..*/
0bb0: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
0bc0: 41 73 63 69 69 54 6f 6b 65 6e 69 7a 65 28 0a 20  AsciiTokenize(. 
0bd0: 20 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72 20 2a   Fts5Tokenizer *
0be0: 70 54 6f 6b 65 6e 69 7a 65 72 2c 0a 20 20 76 6f  pTokenizer,.  vo
0bf0: 69 64 20 2a 70 43 74 78 2c 0a 20 20 69 6e 74 20  id *pCtx,.  int 
0c00: 69 55 6e 75 73 65 64 2c 0a 20 20 63 6f 6e 73 74  iUnused,.  const
0c10: 20 63 68 61 72 20 2a 70 54 65 78 74 2c 20 69 6e   char *pText, in
0c20: 74 20 6e 54 65 78 74 2c 0a 20 20 69 6e 74 20 28  t nText,.  int (
0c30: 2a 78 54 6f 6b 65 6e 29 28 76 6f 69 64 2a 2c 20  *xToken)(void*, 
0c40: 69 6e 74 2c 20 63 6f 6e 73 74 20 63 68 61 72 2a  int, const char*
0c50: 2c 20 69 6e 74 20 6e 54 6f 6b 65 6e 2c 20 69 6e  , int nToken, in
0c60: 74 20 69 53 74 61 72 74 2c 20 69 6e 74 20 69 45  t iStart, int iE
0c70: 6e 64 29 0a 29 7b 0a 20 20 41 73 63 69 69 54 6f  nd).){.  AsciiTo
0c80: 6b 65 6e 69 7a 65 72 20 2a 70 20 3d 20 28 41 73  kenizer *p = (As
0c90: 63 69 69 54 6f 6b 65 6e 69 7a 65 72 2a 29 70 54  ciiTokenizer*)pT
0ca0: 6f 6b 65 6e 69 7a 65 72 3b 0a 20 20 69 6e 74 20  okenizer;.  int 
0cb0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
0cc0: 20 20 69 6e 74 20 69 65 3b 0a 20 20 69 6e 74 20    int ie;.  int 
0cd0: 69 73 20 3d 20 30 3b 0a 0a 20 20 63 68 61 72 20  is = 0;..  char 
0ce0: 61 46 6f 6c 64 5b 36 34 5d 3b 0a 20 20 69 6e 74  aFold[64];.  int
0cf0: 20 6e 46 6f 6c 64 20 3d 20 73 69 7a 65 6f 66 28   nFold = sizeof(
0d00: 61 46 6f 6c 64 29 3b 0a 20 20 63 68 61 72 20 2a  aFold);.  char *
0d10: 70 46 6f 6c 64 20 3d 20 61 46 6f 6c 64 3b 0a 20  pFold = aFold;. 
0d20: 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a   unsigned char *
0d30: 61 20 3d 20 70 2d 3e 61 54 6f 6b 65 6e 43 68 61  a = p->aTokenCha
0d40: 72 3b 0a 0a 20 20 55 4e 55 53 45 44 5f 50 41 52  r;..  UNUSED_PAR
0d50: 41 4d 28 69 55 6e 75 73 65 64 29 3b 0a 0a 20 20  AM(iUnused);..  
0d60: 77 68 69 6c 65 28 20 69 73 3c 6e 54 65 78 74 20  while( is<nText 
0d70: 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  && rc==SQLITE_OK
0d80: 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74   ){.    int nByt
0d90: 65 3b 0a 0a 20 20 20 20 2f 2a 20 53 6b 69 70 20  e;..    /* Skip 
0da0: 61 6e 79 20 6c 65 61 64 69 6e 67 20 64 69 76 69  any leading divi
0db0: 64 65 72 20 63 68 61 72 61 63 74 65 72 73 2e 20  der characters. 
0dc0: 2a 2f 0a 20 20 20 20 77 68 69 6c 65 28 20 69 73  */.    while( is
0dd0: 3c 6e 54 65 78 74 20 26 26 20 28 28 70 54 65 78  <nText && ((pTex
0de0: 74 5b 69 73 5d 26 30 78 38 30 29 3d 3d 30 20 26  t[is]&0x80)==0 &
0df0: 26 20 61 5b 28 69 6e 74 29 70 54 65 78 74 5b 69  & a[(int)pText[i
0e00: 73 5d 5d 3d 3d 30 29 20 29 7b 0a 20 20 20 20 20  s]]==0) ){.     
0e10: 20 69 73 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 20   is++;.    }.   
0e20: 20 69 66 28 20 69 73 3d 3d 6e 54 65 78 74 20 29   if( is==nText )
0e30: 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 2f 2a 20   break;..    /* 
0e40: 43 6f 75 6e 74 20 74 68 65 20 74 6f 6b 65 6e 20  Count the token 
0e50: 63 68 61 72 61 63 74 65 72 73 20 2a 2f 0a 20 20  characters */.  
0e60: 20 20 69 65 20 3d 20 69 73 2b 31 3b 0a 20 20 20    ie = is+1;.   
0e70: 20 77 68 69 6c 65 28 20 69 65 3c 6e 54 65 78 74   while( ie<nText
0e80: 20 26 26 20 28 28 70 54 65 78 74 5b 69 65 5d 26   && ((pText[ie]&
0e90: 30 78 38 30 29 20 7c 7c 20 61 5b 28 69 6e 74 29  0x80) || a[(int)
0ea0: 70 54 65 78 74 5b 69 65 5d 5d 20 29 20 29 7b 0a  pText[ie]] ) ){.
0eb0: 20 20 20 20 20 20 69 65 2b 2b 3b 0a 20 20 20 20        ie++;.    
0ec0: 7d 0a 0a 20 20 20 20 2f 2a 20 46 6f 6c 64 20 74  }..    /* Fold t
0ed0: 6f 20 6c 6f 77 65 72 20 63 61 73 65 20 2a 2f 0a  o lower case */.
0ee0: 20 20 20 20 6e 42 79 74 65 20 3d 20 69 65 2d 69      nByte = ie-i
0ef0: 73 3b 0a 20 20 20 20 69 66 28 20 6e 42 79 74 65  s;.    if( nByte
0f00: 3e 6e 46 6f 6c 64 20 29 7b 0a 20 20 20 20 20 20  >nFold ){.      
0f10: 69 66 28 20 70 46 6f 6c 64 21 3d 61 46 6f 6c 64  if( pFold!=aFold
0f20: 20 29 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28   ) sqlite3_free(
0f30: 70 46 6f 6c 64 29 3b 0a 20 20 20 20 20 20 70 46  pFold);.      pF
0f40: 6f 6c 64 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61  old = sqlite3_ma
0f50: 6c 6c 6f 63 36 34 28 28 73 71 6c 69 74 65 33 5f  lloc64((sqlite3_
0f60: 69 6e 74 36 34 29 6e 42 79 74 65 2a 32 29 3b 0a  int64)nByte*2);.
0f70: 20 20 20 20 20 20 69 66 28 20 70 46 6f 6c 64 3d        if( pFold=
0f80: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63  =0 ){.        rc
0f90: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
0fa0: 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  .        break;.
0fb0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 6e 46        }.      nF
0fc0: 6f 6c 64 20 3d 20 6e 42 79 74 65 2a 32 3b 0a 20  old = nByte*2;. 
0fd0: 20 20 20 7d 0a 20 20 20 20 61 73 63 69 69 46 6f     }.    asciiFo
0fe0: 6c 64 28 70 46 6f 6c 64 2c 20 26 70 54 65 78 74  ld(pFold, &pText
0ff0: 5b 69 73 5d 2c 20 6e 42 79 74 65 29 3b 0a 0a 20  [is], nByte);.. 
1000: 20 20 20 2f 2a 20 49 6e 76 6f 6b 65 20 74 68 65     /* Invoke the
1010: 20 74 6f 6b 65 6e 20 63 61 6c 6c 62 61 63 6b 20   token callback 
1020: 2a 2f 0a 20 20 20 20 72 63 20 3d 20 78 54 6f 6b  */.    rc = xTok
1030: 65 6e 28 70 43 74 78 2c 20 30 2c 20 70 46 6f 6c  en(pCtx, 0, pFol
1040: 64 2c 20 6e 42 79 74 65 2c 20 69 73 2c 20 69 65  d, nByte, is, ie
1050: 29 3b 0a 20 20 20 20 69 73 20 3d 20 69 65 2b 31  );.    is = ie+1
1060: 3b 0a 20 20 7d 0a 20 20 0a 20 20 69 66 28 20 70  ;.  }.  .  if( p
1070: 46 6f 6c 64 21 3d 61 46 6f 6c 64 20 29 20 73 71  Fold!=aFold ) sq
1080: 6c 69 74 65 33 5f 66 72 65 65 28 70 46 6f 6c 64  lite3_free(pFold
1090: 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  );.  if( rc==SQL
10a0: 49 54 45 5f 44 4f 4e 45 20 29 20 72 63 20 3d 20  ITE_DONE ) rc = 
10b0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 72 65 74  SQLITE_OK;.  ret
10c0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a  urn rc;.}../****
10d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
10e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
10f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1100: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1110: 2a 2a 2a 2a 2a 2a 0a 2a 2a 20 53 74 61 72 74 20  ******.** Start 
1120: 6f 66 20 75 6e 69 63 6f 64 65 36 31 20 74 6f 6b  of unicode61 tok
1130: 65 6e 69 7a 65 72 20 69 6d 70 6c 65 6d 65 6e 74  enizer implement
1140: 61 74 69 6f 6e 2e 0a 2a 2f 0a 0a 0a 2f 2a 0a 2a  ation..*/.../*.*
1150: 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  * The following 
1160: 74 77 6f 20 6d 61 63 72 6f 73 20 2d 20 52 45 41  two macros - REA
1170: 44 5f 55 54 46 38 20 61 6e 64 20 57 52 49 54 45  D_UTF8 and WRITE
1180: 5f 55 54 46 38 20 2d 20 68 61 76 65 20 62 65 65  _UTF8 - have bee
1190: 6e 20 63 6f 70 69 65 64 0a 2a 2a 20 66 72 6f 6d  n copied.** from
11a0: 20 74 68 65 20 73 71 6c 69 74 65 33 20 73 6f 75   the sqlite3 sou
11b0: 72 63 65 20 66 69 6c 65 20 75 74 66 2e 63 2e 20  rce file utf.c. 
11c0: 49 66 20 74 68 69 73 20 66 69 6c 65 20 69 73 20  If this file is 
11d0: 63 6f 6d 70 69 6c 65 64 20 61 73 20 70 61 72 74  compiled as part
11e0: 0a 2a 2a 20 6f 66 20 74 68 65 20 61 6d 61 6c 67  .** of the amalg
11f0: 61 6d 61 74 69 6f 6e 2c 20 74 68 65 79 20 61 72  amation, they ar
1200: 65 20 6e 6f 74 20 72 65 71 75 69 72 65 64 2e 0a  e not required..
1210: 2a 2f 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54  */.#ifndef SQLIT
1220: 45 5f 41 4d 41 4c 47 41 4d 41 54 49 4f 4e 0a 0a  E_AMALGAMATION..
1230: 73 74 61 74 69 63 20 63 6f 6e 73 74 20 75 6e 73  static const uns
1240: 69 67 6e 65 64 20 63 68 61 72 20 73 71 6c 69 74  igned char sqlit
1250: 65 33 55 74 66 38 54 72 61 6e 73 31 5b 5d 20 3d  e3Utf8Trans1[] =
1260: 20 7b 0a 20 20 30 78 30 30 2c 20 30 78 30 31 2c   {.  0x00, 0x01,
1270: 20 30 78 30 32 2c 20 30 78 30 33 2c 20 30 78 30   0x02, 0x03, 0x0
1280: 34 2c 20 30 78 30 35 2c 20 30 78 30 36 2c 20 30  4, 0x05, 0x06, 0
1290: 78 30 37 2c 0a 20 20 30 78 30 38 2c 20 30 78 30  x07,.  0x08, 0x0
12a0: 39 2c 20 30 78 30 61 2c 20 30 78 30 62 2c 20 30  9, 0x0a, 0x0b, 0
12b0: 78 30 63 2c 20 30 78 30 64 2c 20 30 78 30 65 2c  x0c, 0x0d, 0x0e,
12c0: 20 30 78 30 66 2c 0a 20 20 30 78 31 30 2c 20 30   0x0f,.  0x10, 0
12d0: 78 31 31 2c 20 30 78 31 32 2c 20 30 78 31 33 2c  x11, 0x12, 0x13,
12e0: 20 30 78 31 34 2c 20 30 78 31 35 2c 20 30 78 31   0x14, 0x15, 0x1
12f0: 36 2c 20 30 78 31 37 2c 0a 20 20 30 78 31 38 2c  6, 0x17,.  0x18,
1300: 20 30 78 31 39 2c 20 30 78 31 61 2c 20 30 78 31   0x19, 0x1a, 0x1
1310: 62 2c 20 30 78 31 63 2c 20 30 78 31 64 2c 20 30  b, 0x1c, 0x1d, 0
1320: 78 31 65 2c 20 30 78 31 66 2c 0a 20 20 30 78 30  x1e, 0x1f,.  0x0
1330: 30 2c 20 30 78 30 31 2c 20 30 78 30 32 2c 20 30  0, 0x01, 0x02, 0
1340: 78 30 33 2c 20 30 78 30 34 2c 20 30 78 30 35 2c  x03, 0x04, 0x05,
1350: 20 30 78 30 36 2c 20 30 78 30 37 2c 0a 20 20 30   0x06, 0x07,.  0
1360: 78 30 38 2c 20 30 78 30 39 2c 20 30 78 30 61 2c  x08, 0x09, 0x0a,
1370: 20 30 78 30 62 2c 20 30 78 30 63 2c 20 30 78 30   0x0b, 0x0c, 0x0
1380: 64 2c 20 30 78 30 65 2c 20 30 78 30 66 2c 0a 20  d, 0x0e, 0x0f,. 
1390: 20 30 78 30 30 2c 20 30 78 30 31 2c 20 30 78 30   0x00, 0x01, 0x0
13a0: 32 2c 20 30 78 30 33 2c 20 30 78 30 34 2c 20 30  2, 0x03, 0x04, 0
13b0: 78 30 35 2c 20 30 78 30 36 2c 20 30 78 30 37 2c  x05, 0x06, 0x07,
13c0: 0a 20 20 30 78 30 30 2c 20 30 78 30 31 2c 20 30  .  0x00, 0x01, 0
13d0: 78 30 32 2c 20 30 78 30 33 2c 20 30 78 30 30 2c  x02, 0x03, 0x00,
13e0: 20 30 78 30 31 2c 20 30 78 30 30 2c 20 30 78 30   0x01, 0x00, 0x0
13f0: 30 2c 0a 7d 3b 0a 0a 23 64 65 66 69 6e 65 20 52  0,.};..#define R
1400: 45 41 44 5f 55 54 46 38 28 7a 49 6e 2c 20 7a 54  EAD_UTF8(zIn, zT
1410: 65 72 6d 2c 20 63 29 20 20 20 20 20 20 20 20 20  erm, c)         
1420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1430: 20 20 5c 0a 20 20 63 20 3d 20 2a 28 7a 49 6e 2b    \.  c = *(zIn+
1440: 2b 29 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  +);             
1450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c                 \
1470: 0a 20 20 69 66 28 20 63 3e 3d 30 78 63 30 20 29  .  if( c>=0xc0 )
1480: 7b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  {               
1490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14a0: 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20              \.  
14b0: 20 20 63 20 3d 20 73 71 6c 69 74 65 33 55 74 66    c = sqlite3Utf
14c0: 38 54 72 61 6e 73 31 5b 63 2d 30 78 63 30 5d 3b  8Trans1[c-0xc0];
14d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14e0: 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20 20 77           \.    w
14f0: 68 69 6c 65 28 20 7a 49 6e 21 3d 7a 54 65 72 6d  hile( zIn!=zTerm
1500: 20 26 26 20 28 2a 7a 49 6e 20 26 20 30 78 63 30   && (*zIn & 0xc0
1510: 29 3d 3d 30 78 38 30 20 29 7b 20 20 20 20 20 20  )==0x80 ){      
1520: 20 20 20 20 20 20 5c 0a 20 20 20 20 20 20 63 20        \.      c 
1530: 3d 20 28 63 3c 3c 36 29 20 2b 20 28 30 78 33 66  = (c<<6) + (0x3f
1540: 20 26 20 2a 28 7a 49 6e 2b 2b 29 29 3b 20 20 20   & *(zIn++));   
1550: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1560: 20 20 20 5c 0a 20 20 20 20 7d 20 20 20 20 20 20     \.    }      
1570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1580: 20 20 20 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: 5c 0a 20 20 20 20 69 66 28 20 63 3c 30 78 38 30  \.    if( c<0x80
15b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20               \. 
15e0: 20 20 20 20 20 20 20 7c 7c 20 28 63 26 30 78 46         || (c&0xF
15f0: 46 46 46 46 38 30 30 29 3d 3d 30 78 44 38 30 30  FFFF800)==0xD800
1600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1610: 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20 20            \.    
1620: 20 20 20 20 7c 7c 20 28 63 26 30 78 46 46 46 46      || (c&0xFFFF
1630: 46 46 46 45 29 3d 3d 30 78 46 46 46 45 20 29 7b  FFFE)==0xFFFE ){
1640: 20 20 63 20 3d 20 30 78 46 46 46 44 3b 20 7d 20    c = 0xFFFD; } 
1650: 20 20 20 20 20 20 20 5c 0a 20 20 7d 0a 0a 0a 23         \.  }...#
1660: 64 65 66 69 6e 65 20 57 52 49 54 45 5f 55 54 46  define WRITE_UTF
1670: 38 28 7a 4f 75 74 2c 20 63 29 20 7b 20 20 20 20  8(zOut, c) {    
1680: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1690: 20 20 20 20 20 20 5c 0a 20 20 69 66 28 20 63 3c        \.  if( c<
16a0: 30 78 30 30 30 38 30 20 29 7b 20 20 20 20 20 20  0x00080 ){      
16b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c                 \
16d0: 0a 20 20 20 20 2a 7a 4f 75 74 2b 2b 20 3d 20 28  .    *zOut++ = (
16e0: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 29 28 63  unsigned char)(c
16f0: 26 30 78 46 46 29 3b 20 20 20 20 20 20 20 20 20  &0xFF);         
1700: 20 20 20 20 20 20 20 20 5c 0a 20 20 7d 20 20 20          \.  }   
1710: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1720: 20 20 20 20 20 20 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 5c 0a 20 20 65 6c 73 65 20 69 66 28 20 63 3c   \.  else if( c<
1750: 30 78 30 30 38 30 30 20 29 7b 20 20 20 20 20 20  0x00800 ){      
1760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1770: 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20 20            \.    
1780: 2a 7a 4f 75 74 2b 2b 20 3d 20 30 78 43 30 20 2b  *zOut++ = 0xC0 +
1790: 20 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72 29   (unsigned char)
17a0: 28 28 63 3e 3e 36 29 26 30 78 31 46 29 3b 20 20  ((c>>6)&0x1F);  
17b0: 20 20 20 5c 0a 20 20 20 20 2a 7a 4f 75 74 2b 2b     \.    *zOut++
17c0: 20 3d 20 30 78 38 30 20 2b 20 28 75 6e 73 69 67   = 0x80 + (unsig
17d0: 6e 65 64 20 63 68 61 72 29 28 63 20 26 20 30 78  ned char)(c & 0x
17e0: 33 46 29 3b 20 20 20 20 20 20 20 20 5c 0a 20 20  3F);        \.  
17f0: 7d 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  }               
1800: 20 20 20 20 20 20 20 20 20 20 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 5c 0a 20 20 65 6c 73 65 20 69 66       \.  else if
1830: 28 20 63 3c 30 78 31 30 30 30 30 20 29 7b 20 20  ( c<0x10000 ){  
1840: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1850: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a                \.
1860: 20 20 20 20 2a 7a 4f 75 74 2b 2b 20 3d 20 30 78      *zOut++ = 0x
1870: 45 30 20 2b 20 28 75 6e 73 69 67 6e 65 64 20 63  E0 + (unsigned c
1880: 68 61 72 29 28 28 63 3e 3e 31 32 29 26 30 78 30  har)((c>>12)&0x0
1890: 46 29 3b 20 20 20 20 5c 0a 20 20 20 20 2a 7a 4f  F);    \.    *zO
18a0: 75 74 2b 2b 20 3d 20 30 78 38 30 20 2b 20 28 75  ut++ = 0x80 + (u
18b0: 6e 73 69 67 6e 65 64 20 63 68 61 72 29 28 28 63  nsigned char)((c
18c0: 3e 3e 36 29 20 26 20 30 78 33 46 29 3b 20 20 20  >>6) & 0x3F);   
18d0: 5c 0a 20 20 20 20 2a 7a 4f 75 74 2b 2b 20 3d 20  \.    *zOut++ = 
18e0: 30 78 38 30 20 2b 20 28 75 6e 73 69 67 6e 65 64  0x80 + (unsigned
18f0: 20 63 68 61 72 29 28 63 20 26 20 30 78 33 46 29   char)(c & 0x3F)
1900: 3b 20 20 20 20 20 20 20 20 5c 0a 20 20 7d 65 6c  ;        \.  }el
1910: 73 65 7b 20 20 20 20 20 20 20 20 20 20 20 20 20  se{             
1920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1940: 20 20 5c 0a 20 20 20 20 2a 7a 4f 75 74 2b 2b 20    \.    *zOut++ 
1950: 3d 20 30 78 46 30 20 2b 20 28 75 6e 73 69 67 6e  = 0xF0 + (unsign
1960: 65 64 20 63 68 61 72 29 28 28 63 3e 3e 31 38 29  ed char)((c>>18)
1970: 20 26 20 30 78 30 37 29 3b 20 20 5c 0a 20 20 20   & 0x07);  \.   
1980: 20 2a 7a 4f 75 74 2b 2b 20 3d 20 30 78 38 30 20   *zOut++ = 0x80 
1990: 2b 20 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72  + (unsigned char
19a0: 29 28 28 63 3e 3e 31 32 29 20 26 20 30 78 33 46  )((c>>12) & 0x3F
19b0: 29 3b 20 20 5c 0a 20 20 20 20 2a 7a 4f 75 74 2b  );  \.    *zOut+
19c0: 2b 20 3d 20 30 78 38 30 20 2b 20 28 75 6e 73 69  + = 0x80 + (unsi
19d0: 67 6e 65 64 20 63 68 61 72 29 28 28 63 3e 3e 36  gned char)((c>>6
19e0: 29 20 26 20 30 78 33 46 29 3b 20 20 20 5c 0a 20  ) & 0x3F);   \. 
19f0: 20 20 20 2a 7a 4f 75 74 2b 2b 20 3d 20 30 78 38     *zOut++ = 0x8
1a00: 30 20 2b 20 28 75 6e 73 69 67 6e 65 64 20 63 68  0 + (unsigned ch
1a10: 61 72 29 28 63 20 26 20 30 78 33 46 29 3b 20 20  ar)(c & 0x3F);  
1a20: 20 20 20 20 20 20 5c 0a 20 20 7d 20 20 20 20 20        \.  }     
1a30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a40: 20 20 20 20 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 5c                 \
1a60: 0a 7d 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 69 66  .}..#endif /* if
1a70: 6e 64 65 66 20 53 51 4c 49 54 45 5f 41 4d 41 4c  ndef SQLITE_AMAL
1a80: 47 41 4d 41 54 49 4f 4e 20 2a 2f 0a 0a 74 79 70  GAMATION */..typ
1a90: 65 64 65 66 20 73 74 72 75 63 74 20 55 6e 69 63  edef struct Unic
1aa0: 6f 64 65 36 31 54 6f 6b 65 6e 69 7a 65 72 20 55  ode61Tokenizer U
1ab0: 6e 69 63 6f 64 65 36 31 54 6f 6b 65 6e 69 7a 65  nicode61Tokenize
1ac0: 72 3b 0a 73 74 72 75 63 74 20 55 6e 69 63 6f 64  r;.struct Unicod
1ad0: 65 36 31 54 6f 6b 65 6e 69 7a 65 72 20 7b 0a 20  e61Tokenizer {. 
1ae0: 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 61   unsigned char a
1af0: 54 6f 6b 65 6e 43 68 61 72 5b 31 32 38 5d 3b 20  TokenChar[128]; 
1b00: 20 2f 2a 20 41 53 43 49 49 20 72 61 6e 67 65 20   /* ASCII range 
1b10: 74 6f 6b 65 6e 20 63 68 61 72 61 63 74 65 72 73  token characters
1b20: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 61 46 6f 6c   */.  char *aFol
1b30: 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  d;              
1b40: 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20        /* Buffer 
1b50: 74 6f 20 66 6f 6c 64 20 74 65 78 74 20 69 6e 74  to fold text int
1b60: 6f 20 2a 2f 0a 20 20 69 6e 74 20 6e 46 6f 6c 64  o */.  int nFold
1b70: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1b80: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
1b90: 66 20 61 46 6f 6c 64 5b 5d 20 69 6e 20 62 79 74  f aFold[] in byt
1ba0: 65 73 20 2a 2f 0a 20 20 69 6e 74 20 65 52 65 6d  es */.  int eRem
1bb0: 6f 76 65 44 69 61 63 72 69 74 69 63 3b 20 20 20  oveDiacritic;   
1bc0: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
1bd0: 69 66 20 72 65 6d 6f 76 65 5f 64 69 61 63 72 69  if remove_diacri
1be0: 74 69 63 73 3d 31 20 69 73 20 73 65 74 20 2a 2f  tics=1 is set */
1bf0: 0a 20 20 69 6e 74 20 6e 45 78 63 65 70 74 69 6f  .  int nExceptio
1c00: 6e 3b 0a 20 20 69 6e 74 20 2a 61 69 45 78 63 65  n;.  int *aiExce
1c10: 70 74 69 6f 6e 3b 0a 0a 20 20 75 6e 73 69 67 6e  ption;..  unsign
1c20: 65 64 20 63 68 61 72 20 61 43 61 74 65 67 6f 72  ed char aCategor
1c30: 79 5b 33 32 5d 3b 20 20 20 20 2f 2a 20 54 72 75  y[32];    /* Tru
1c40: 65 20 66 6f 72 20 74 6f 6b 65 6e 20 63 68 61 72  e for token char
1c50: 20 63 61 74 65 67 6f 72 69 65 73 20 2a 2f 0a 7d   categories */.}
1c60: 3b 0a 0a 2f 2a 20 56 61 6c 75 65 73 20 66 6f 72  ;../* Values for
1c70: 20 65 52 65 6d 6f 76 65 44 69 61 63 72 69 74 69   eRemoveDiacriti
1c80: 63 20 28 6d 75 73 74 20 6d 61 74 63 68 20 69 6e  c (must match in
1c90: 74 65 72 6e 61 6c 73 20 6f 66 20 66 74 73 35 5f  ternals of fts5_
1ca0: 75 6e 69 63 6f 64 65 32 2e 63 29 20 2a 2f 0a 23  unicode2.c) */.#
1cb0: 64 65 66 69 6e 65 20 46 54 53 35 5f 52 45 4d 4f  define FTS5_REMO
1cc0: 56 45 5f 44 49 41 43 52 49 54 49 43 53 5f 4e 4f  VE_DIACRITICS_NO
1cd0: 4e 45 20 20 20 20 30 0a 23 64 65 66 69 6e 65 20  NE    0.#define 
1ce0: 46 54 53 35 5f 52 45 4d 4f 56 45 5f 44 49 41 43  FTS5_REMOVE_DIAC
1cf0: 52 49 54 49 43 53 5f 53 49 4d 50 4c 45 20 20 31  RITICS_SIMPLE  1
1d00: 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f 52 45  .#define FTS5_RE
1d10: 4d 4f 56 45 5f 44 49 41 43 52 49 54 49 43 53 5f  MOVE_DIACRITICS_
1d20: 43 4f 4d 50 4c 45 58 20 32 0a 0a 73 74 61 74 69  COMPLEX 2..stati
1d30: 63 20 69 6e 74 20 66 74 73 35 55 6e 69 63 6f 64  c int fts5Unicod
1d40: 65 41 64 64 45 78 63 65 70 74 69 6f 6e 73 28 0a  eAddExceptions(.
1d50: 20 20 55 6e 69 63 6f 64 65 36 31 54 6f 6b 65 6e    Unicode61Token
1d60: 69 7a 65 72 20 2a 70 2c 20 20 20 20 20 20 20 20  izer *p,        
1d70: 20 20 2f 2a 20 54 6f 6b 65 6e 69 7a 65 72 20 6f    /* Tokenizer o
1d80: 62 6a 65 63 74 20 2a 2f 0a 20 20 63 6f 6e 73 74  bject */.  const
1d90: 20 63 68 61 72 20 2a 7a 2c 20 20 20 20 20 20 20   char *z,       
1da0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68             /* Ch
1db0: 61 72 61 63 74 65 72 73 20 74 6f 20 74 72 65 61  aracters to trea
1dc0: 74 20 61 73 20 65 78 63 65 70 74 69 6f 6e 73 20  t as exceptions 
1dd0: 2a 2f 0a 20 20 69 6e 74 20 62 54 6f 6b 65 6e 43  */.  int bTokenC
1de0: 68 61 72 73 20 20 20 20 20 20 20 20 20 20 20 20  hars            
1df0: 20 20 20 20 20 2f 2a 20 31 20 66 6f 72 20 27 74       /* 1 for 't
1e00: 6f 6b 65 6e 63 68 61 72 73 27 2c 20 30 20 66 6f  okenchars', 0 fo
1e10: 72 20 27 73 65 70 61 72 61 74 6f 72 73 27 20 2a  r 'separators' *
1e20: 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  /.){.  int rc = 
1e30: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74  SQLITE_OK;.  int
1e40: 20 6e 20 3d 20 28 69 6e 74 29 73 74 72 6c 65 6e   n = (int)strlen
1e50: 28 7a 29 3b 0a 20 20 69 6e 74 20 2a 61 4e 65 77  (z);.  int *aNew
1e60: 3b 0a 0a 20 20 69 66 28 20 6e 3e 30 20 29 7b 0a  ;..  if( n>0 ){.
1e70: 20 20 20 20 61 4e 65 77 20 3d 20 28 69 6e 74 2a      aNew = (int*
1e80: 29 73 71 6c 69 74 65 33 5f 72 65 61 6c 6c 6f 63  )sqlite3_realloc
1e90: 36 34 28 70 2d 3e 61 69 45 78 63 65 70 74 69 6f  64(p->aiExceptio
1ea0: 6e 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  n,.             
1eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ec0: 20 20 20 20 20 20 28 6e 2b 70 2d 3e 6e 45 78 63        (n+p->nExc
1ed0: 65 70 74 69 6f 6e 29 2a 73 69 7a 65 6f 66 28 69  eption)*sizeof(i
1ee0: 6e 74 29 29 3b 0a 20 20 20 20 69 66 28 20 61 4e  nt));.    if( aN
1ef0: 65 77 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  ew ){.      int 
1f00: 6e 4e 65 77 20 3d 20 70 2d 3e 6e 45 78 63 65 70  nNew = p->nExcep
1f10: 74 69 6f 6e 3b 0a 20 20 20 20 20 20 63 6f 6e 73  tion;.      cons
1f20: 74 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20  t unsigned char 
1f30: 2a 7a 43 73 72 20 3d 20 28 63 6f 6e 73 74 20 75  *zCsr = (const u
1f40: 6e 73 69 67 6e 65 64 20 63 68 61 72 2a 29 7a 3b  nsigned char*)z;
1f50: 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 75 6e 73  .      const uns
1f60: 69 67 6e 65 64 20 63 68 61 72 20 2a 7a 54 65 72  igned char *zTer
1f70: 6d 20 3d 20 28 63 6f 6e 73 74 20 75 6e 73 69 67  m = (const unsig
1f80: 6e 65 64 20 63 68 61 72 2a 29 26 7a 5b 6e 5d 3b  ned char*)&z[n];
1f90: 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 7a 43  .      while( zC
1fa0: 73 72 3c 7a 54 65 72 6d 20 29 7b 0a 20 20 20 20  sr<zTerm ){.    
1fb0: 20 20 20 20 75 33 32 20 69 43 6f 64 65 3b 0a 20      u32 iCode;. 
1fc0: 20 20 20 20 20 20 20 69 6e 74 20 62 54 6f 6b 65         int bToke
1fd0: 6e 3b 0a 20 20 20 20 20 20 20 20 52 45 41 44 5f  n;.        READ_
1fe0: 55 54 46 38 28 7a 43 73 72 2c 20 7a 54 65 72 6d  UTF8(zCsr, zTerm
1ff0: 2c 20 69 43 6f 64 65 29 3b 0a 20 20 20 20 20 20  , iCode);.      
2000: 20 20 69 66 28 20 69 43 6f 64 65 3c 31 32 38 20    if( iCode<128 
2010: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 70 2d 3e  ){.          p->
2020: 61 54 6f 6b 65 6e 43 68 61 72 5b 69 43 6f 64 65  aTokenChar[iCode
2030: 5d 20 3d 20 28 75 6e 73 69 67 6e 65 64 20 63 68  ] = (unsigned ch
2040: 61 72 29 62 54 6f 6b 65 6e 43 68 61 72 73 3b 0a  ar)bTokenChars;.
2050: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20          }else{. 
2060: 20 20 20 20 20 20 20 20 20 62 54 6f 6b 65 6e 20           bToken 
2070: 3d 20 70 2d 3e 61 43 61 74 65 67 6f 72 79 5b 73  = p->aCategory[s
2080: 71 6c 69 74 65 33 46 74 73 35 55 6e 69 63 6f 64  qlite3Fts5Unicod
2090: 65 43 61 74 65 67 6f 72 79 28 69 43 6f 64 65 29  eCategory(iCode)
20a0: 5d 3b 0a 20 20 20 20 20 20 20 20 20 20 61 73 73  ];.          ass
20b0: 65 72 74 28 20 28 62 54 6f 6b 65 6e 3d 3d 30 20  ert( (bToken==0 
20c0: 7c 7c 20 62 54 6f 6b 65 6e 3d 3d 31 29 20 29 3b  || bToken==1) );
20d0: 20 0a 20 20 20 20 20 20 20 20 20 20 61 73 73 65   .          asse
20e0: 72 74 28 20 28 62 54 6f 6b 65 6e 43 68 61 72 73  rt( (bTokenChars
20f0: 3d 3d 30 20 7c 7c 20 62 54 6f 6b 65 6e 43 68 61  ==0 || bTokenCha
2100: 72 73 3d 3d 31 29 20 29 3b 0a 20 20 20 20 20 20  rs==1) );.      
2110: 20 20 20 20 69 66 28 20 62 54 6f 6b 65 6e 21 3d      if( bToken!=
2120: 62 54 6f 6b 65 6e 43 68 61 72 73 20 26 26 20 73  bTokenChars && s
2130: 71 6c 69 74 65 33 46 74 73 35 55 6e 69 63 6f 64  qlite3Fts5Unicod
2140: 65 49 73 64 69 61 63 72 69 74 69 63 28 69 43 6f  eIsdiacritic(iCo
2150: 64 65 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  de)==0 ){.      
2160: 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20        int i;.   
2170: 20 20 20 20 20 20 20 20 20 66 6f 72 28 69 3d 30           for(i=0
2180: 3b 20 69 3c 6e 4e 65 77 3b 20 69 2b 2b 29 7b 0a  ; i<nNew; i++){.
2190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66                if
21a0: 28 20 28 75 33 32 29 61 4e 65 77 5b 69 5d 3e 69  ( (u32)aNew[i]>i
21b0: 43 6f 64 65 20 29 20 62 72 65 61 6b 3b 0a 20 20  Code ) break;.  
21c0: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
21d0: 20 20 20 20 20 20 20 20 6d 65 6d 6d 6f 76 65 28          memmove(
21e0: 26 61 4e 65 77 5b 69 2b 31 5d 2c 20 26 61 4e 65  &aNew[i+1], &aNe
21f0: 77 5b 69 5d 2c 20 28 6e 4e 65 77 2d 69 29 2a 73  w[i], (nNew-i)*s
2200: 69 7a 65 6f 66 28 69 6e 74 29 29 3b 0a 20 20 20  izeof(int));.   
2210: 20 20 20 20 20 20 20 20 20 61 4e 65 77 5b 69 5d           aNew[i]
2220: 20 3d 20 69 43 6f 64 65 3b 0a 20 20 20 20 20 20   = iCode;.      
2230: 20 20 20 20 20 20 6e 4e 65 77 2b 2b 3b 0a 20 20        nNew++;.  
2240: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
2250: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
2260: 20 20 70 2d 3e 61 69 45 78 63 65 70 74 69 6f 6e    p->aiException
2270: 20 3d 20 61 4e 65 77 3b 0a 20 20 20 20 20 20 70   = aNew;.      p
2280: 2d 3e 6e 45 78 63 65 70 74 69 6f 6e 20 3d 20 6e  ->nException = n
2290: 4e 65 77 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  New;.    }else{.
22a0: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
22b0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20  E_NOMEM;.    }. 
22c0: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
22d0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  .}../*.** Return
22e0: 20 74 72 75 65 20 69 66 20 74 68 65 20 70 2d 3e   true if the p->
22f0: 61 69 45 78 63 65 70 74 69 6f 6e 5b 5d 20 61 72  aiException[] ar
2300: 72 61 79 20 63 6f 6e 74 61 69 6e 73 20 74 68 65  ray contains the
2310: 20 76 61 6c 75 65 20 69 43 6f 64 65 2e 0a 2a 2f   value iCode..*/
2320: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
2330: 55 6e 69 63 6f 64 65 49 73 45 78 63 65 70 74 69  UnicodeIsExcepti
2340: 6f 6e 28 55 6e 69 63 6f 64 65 36 31 54 6f 6b 65  on(Unicode61Toke
2350: 6e 69 7a 65 72 20 2a 70 2c 20 69 6e 74 20 69 43  nizer *p, int iC
2360: 6f 64 65 29 7b 0a 20 20 69 66 28 20 70 2d 3e 6e  ode){.  if( p->n
2370: 45 78 63 65 70 74 69 6f 6e 3e 30 20 29 7b 0a 20  Exception>0 ){. 
2380: 20 20 20 69 6e 74 20 2a 61 20 3d 20 70 2d 3e 61     int *a = p->a
2390: 69 45 78 63 65 70 74 69 6f 6e 3b 0a 20 20 20 20  iException;.    
23a0: 69 6e 74 20 69 4c 6f 20 3d 20 30 3b 0a 20 20 20  int iLo = 0;.   
23b0: 20 69 6e 74 20 69 48 69 20 3d 20 70 2d 3e 6e 45   int iHi = p->nE
23c0: 78 63 65 70 74 69 6f 6e 2d 31 3b 0a 0a 20 20 20  xception-1;..   
23d0: 20 77 68 69 6c 65 28 20 69 48 69 3e 3d 69 4c 6f   while( iHi>=iLo
23e0: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 54   ){.      int iT
23f0: 65 73 74 20 3d 20 28 69 48 69 20 2b 20 69 4c 6f  est = (iHi + iLo
2400: 29 20 2f 20 32 3b 0a 20 20 20 20 20 20 69 66 28  ) / 2;.      if(
2410: 20 69 43 6f 64 65 3d 3d 61 5b 69 54 65 73 74 5d   iCode==a[iTest]
2420: 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75   ){.        retu
2430: 72 6e 20 31 3b 0a 20 20 20 20 20 20 7d 65 6c 73  rn 1;.      }els
2440: 65 20 69 66 28 20 69 43 6f 64 65 3e 61 5b 69 54  e if( iCode>a[iT
2450: 65 73 74 5d 20 29 7b 0a 20 20 20 20 20 20 20 20  est] ){.        
2460: 69 4c 6f 20 3d 20 69 54 65 73 74 2b 31 3b 0a 20  iLo = iTest+1;. 
2470: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
2480: 20 20 20 20 69 48 69 20 3d 20 69 54 65 73 74 2d      iHi = iTest-
2490: 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  1;.      }.    }
24a0: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 30  .  }..  return 0
24b0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 6c 65 74  ;.}../*.** Delet
24c0: 65 20 61 20 22 75 6e 69 63 6f 64 65 36 31 22 20  e a "unicode61" 
24d0: 74 6f 6b 65 6e 69 7a 65 72 2e 0a 2a 2f 0a 73 74  tokenizer..*/.st
24e0: 61 74 69 63 20 76 6f 69 64 20 66 74 73 35 55 6e  atic void fts5Un
24f0: 69 63 6f 64 65 44 65 6c 65 74 65 28 46 74 73 35  icodeDelete(Fts5
2500: 54 6f 6b 65 6e 69 7a 65 72 20 2a 70 54 6f 6b 29  Tokenizer *pTok)
2510: 7b 0a 20 20 69 66 28 20 70 54 6f 6b 20 29 7b 0a  {.  if( pTok ){.
2520: 20 20 20 20 55 6e 69 63 6f 64 65 36 31 54 6f 6b      Unicode61Tok
2530: 65 6e 69 7a 65 72 20 2a 70 20 3d 20 28 55 6e 69  enizer *p = (Uni
2540: 63 6f 64 65 36 31 54 6f 6b 65 6e 69 7a 65 72 2a  code61Tokenizer*
2550: 29 70 54 6f 6b 3b 0a 20 20 20 20 73 71 6c 69 74  )pTok;.    sqlit
2560: 65 33 5f 66 72 65 65 28 70 2d 3e 61 69 45 78 63  e3_free(p->aiExc
2570: 65 70 74 69 6f 6e 29 3b 0a 20 20 20 20 73 71 6c  eption);.    sql
2580: 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 61 46 6f  ite3_free(p->aFo
2590: 6c 64 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  ld);.    sqlite3
25a0: 5f 66 72 65 65 28 70 29 3b 0a 20 20 7d 0a 20 20  _free(p);.  }.  
25b0: 72 65 74 75 72 6e 3b 0a 7d 0a 0a 73 74 61 74 69  return;.}..stati
25c0: 63 20 69 6e 74 20 75 6e 69 63 6f 64 65 53 65 74  c int unicodeSet
25d0: 43 61 74 65 67 6f 72 69 65 73 28 55 6e 69 63 6f  Categories(Unico
25e0: 64 65 36 31 54 6f 6b 65 6e 69 7a 65 72 20 2a 70  de61Tokenizer *p
25f0: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 43  , const char *zC
2600: 61 74 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61  at){.  const cha
2610: 72 20 2a 7a 20 3d 20 7a 43 61 74 3b 0a 0a 20 20  r *z = zCat;..  
2620: 77 68 69 6c 65 28 20 2a 7a 20 29 7b 0a 20 20 20  while( *z ){.   
2630: 20 77 68 69 6c 65 28 20 2a 7a 3d 3d 27 20 27 20   while( *z==' ' 
2640: 7c 7c 20 2a 7a 3d 3d 27 5c 74 27 20 29 20 7a 2b  || *z=='\t' ) z+
2650: 2b 3b 0a 20 20 20 20 69 66 28 20 2a 7a 20 26 26  +;.    if( *z &&
2660: 20 73 71 6c 69 74 65 33 46 74 73 35 55 6e 69 63   sqlite3Fts5Unic
2670: 6f 64 65 43 61 74 50 61 72 73 65 28 7a 2c 20 70  odeCatParse(z, p
2680: 2d 3e 61 43 61 74 65 67 6f 72 79 29 20 29 7b 0a  ->aCategory) ){.
2690: 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c        return SQL
26a0: 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d  ITE_ERROR;.    }
26b0: 0a 20 20 20 20 77 68 69 6c 65 28 20 2a 7a 21 3d  .    while( *z!=
26c0: 27 20 27 20 26 26 20 2a 7a 21 3d 27 5c 74 27 20  ' ' && *z!='\t' 
26d0: 26 26 20 2a 7a 21 3d 27 5c 30 27 20 29 20 7a 2b  && *z!='\0' ) z+
26e0: 2b 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65  +;.  }..  sqlite
26f0: 33 46 74 73 35 55 6e 69 63 6f 64 65 41 73 63 69  3Fts5UnicodeAsci
2700: 69 28 70 2d 3e 61 43 61 74 65 67 6f 72 79 2c 20  i(p->aCategory, 
2710: 70 2d 3e 61 54 6f 6b 65 6e 43 68 61 72 29 3b 0a  p->aTokenChar);.
2720: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
2730: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 72 65  OK;.}../*.** Cre
2740: 61 74 65 20 61 20 22 75 6e 69 63 6f 64 65 36 31  ate a "unicode61
2750: 22 20 74 6f 6b 65 6e 69 7a 65 72 2e 0a 2a 2f 0a  " tokenizer..*/.
2760: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 55  static int fts5U
2770: 6e 69 63 6f 64 65 43 72 65 61 74 65 28 0a 20 20  nicodeCreate(.  
2780: 76 6f 69 64 20 2a 70 55 6e 75 73 65 64 2c 20 0a  void *pUnused, .
2790: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61    const char **a
27a0: 7a 41 72 67 2c 20 69 6e 74 20 6e 41 72 67 2c 0a  zArg, int nArg,.
27b0: 20 20 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72 20    Fts5Tokenizer 
27c0: 2a 2a 70 70 4f 75 74 0a 29 7b 0a 20 20 69 6e 74  **ppOut.){.  int
27d0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
27e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
27f0: 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  Return code */. 
2800: 20 55 6e 69 63 6f 64 65 36 31 54 6f 6b 65 6e 69   Unicode61Tokeni
2810: 7a 65 72 20 2a 70 20 3d 20 30 3b 20 20 20 20 20  zer *p = 0;     
2820: 20 2f 2a 20 4e 65 77 20 74 6f 6b 65 6e 69 7a 65   /* New tokenize
2830: 72 20 6f 62 6a 65 63 74 20 2a 2f 20 0a 0a 20 20  r object */ ..  
2840: 55 4e 55 53 45 44 5f 50 41 52 41 4d 28 70 55 6e  UNUSED_PARAM(pUn
2850: 75 73 65 64 29 3b 0a 0a 20 20 69 66 28 20 6e 41  used);..  if( nA
2860: 72 67 25 32 20 29 7b 0a 20 20 20 20 72 63 20 3d  rg%2 ){.    rc =
2870: 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20   SQLITE_ERROR;. 
2880: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 20 3d 20   }else{.    p = 
2890: 28 55 6e 69 63 6f 64 65 36 31 54 6f 6b 65 6e 69  (Unicode61Tokeni
28a0: 7a 65 72 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c  zer*)sqlite3_mal
28b0: 6c 6f 63 28 73 69 7a 65 6f 66 28 55 6e 69 63 6f  loc(sizeof(Unico
28c0: 64 65 36 31 54 6f 6b 65 6e 69 7a 65 72 29 29 3b  de61Tokenizer));
28d0: 0a 20 20 20 20 69 66 28 20 70 20 29 7b 0a 20 20  .    if( p ){.  
28e0: 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a      const char *
28f0: 7a 43 61 74 20 3d 20 22 4c 2a 20 4e 2a 20 43 6f  zCat = "L* N* Co
2900: 22 3b 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 0a  ";.      int i;.
2910: 20 20 20 20 20 20 6d 65 6d 73 65 74 28 70 2c 20        memset(p, 
2920: 30 2c 20 73 69 7a 65 6f 66 28 55 6e 69 63 6f 64  0, sizeof(Unicod
2930: 65 36 31 54 6f 6b 65 6e 69 7a 65 72 29 29 3b 0a  e61Tokenizer));.
2940: 0a 20 20 20 20 20 20 70 2d 3e 65 52 65 6d 6f 76  .      p->eRemov
2950: 65 44 69 61 63 72 69 74 69 63 20 3d 20 46 54 53  eDiacritic = FTS
2960: 35 5f 52 45 4d 4f 56 45 5f 44 49 41 43 52 49 54  5_REMOVE_DIACRIT
2970: 49 43 53 5f 53 49 4d 50 4c 45 3b 0a 20 20 20 20  ICS_SIMPLE;.    
2980: 20 20 70 2d 3e 6e 46 6f 6c 64 20 3d 20 36 34 3b    p->nFold = 64;
2990: 0a 20 20 20 20 20 20 70 2d 3e 61 46 6f 6c 64 20  .      p->aFold 
29a0: 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  = sqlite3_malloc
29b0: 28 70 2d 3e 6e 46 6f 6c 64 20 2a 20 73 69 7a 65  (p->nFold * size
29c0: 6f 66 28 63 68 61 72 29 29 3b 0a 20 20 20 20 20  of(char));.     
29d0: 20 69 66 28 20 70 2d 3e 61 46 6f 6c 64 3d 3d 30   if( p->aFold==0
29e0: 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d   ){.        rc =
29f0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
2a00: 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 2f 2a       }..      /*
2a10: 20 53 65 61 72 63 68 20 66 6f 72 20 61 20 22 63   Search for a "c
2a20: 61 74 65 67 6f 72 69 65 73 22 20 61 72 67 75 6d  ategories" argum
2a30: 65 6e 74 20 2a 2f 0a 20 20 20 20 20 20 66 6f 72  ent */.      for
2a40: 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45  (i=0; rc==SQLITE
2a50: 5f 4f 4b 20 26 26 20 69 3c 6e 41 72 67 3b 20 69  _OK && i<nArg; i
2a60: 2b 3d 32 29 7b 0a 20 20 20 20 20 20 20 20 69 66  +=2){.        if
2a70: 28 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74 72  ( 0==sqlite3_str
2a80: 69 63 6d 70 28 61 7a 41 72 67 5b 69 5d 2c 20 22  icmp(azArg[i], "
2a90: 63 61 74 65 67 6f 72 69 65 73 22 29 20 29 7b 0a  categories") ){.
2aa0: 20 20 20 20 20 20 20 20 20 20 7a 43 61 74 20 3d            zCat =
2ab0: 20 61 7a 41 72 67 5b 69 2b 31 5d 3b 0a 20 20 20   azArg[i+1];.   
2ac0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 0a       }.      }..
2ad0: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
2ae0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
2af0: 20 20 20 72 63 20 3d 20 75 6e 69 63 6f 64 65 53     rc = unicodeS
2b00: 65 74 43 61 74 65 67 6f 72 69 65 73 28 70 2c 20  etCategories(p, 
2b10: 7a 43 61 74 29 3b 0a 20 20 20 20 20 20 7d 0a 0a  zCat);.      }..
2b20: 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 72        for(i=0; r
2b30: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
2b40: 69 3c 6e 41 72 67 3b 20 69 2b 3d 32 29 7b 0a 20  i<nArg; i+=2){. 
2b50: 20 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61         const cha
2b60: 72 20 2a 7a 41 72 67 20 3d 20 61 7a 41 72 67 5b  r *zArg = azArg[
2b70: 69 2b 31 5d 3b 0a 20 20 20 20 20 20 20 20 69 66  i+1];.        if
2b80: 28 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74 72  ( 0==sqlite3_str
2b90: 69 63 6d 70 28 61 7a 41 72 67 5b 69 5d 2c 20 22  icmp(azArg[i], "
2ba0: 72 65 6d 6f 76 65 5f 64 69 61 63 72 69 74 69 63  remove_diacritic
2bb0: 73 22 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20  s") ){.         
2bc0: 20 69 66 28 20 28 7a 41 72 67 5b 30 5d 21 3d 27   if( (zArg[0]!='
2bd0: 30 27 20 26 26 20 7a 41 72 67 5b 30 5d 21 3d 27  0' && zArg[0]!='
2be0: 31 27 20 26 26 20 7a 41 72 67 5b 30 5d 21 3d 27  1' && zArg[0]!='
2bf0: 32 27 29 20 7c 7c 20 7a 41 72 67 5b 31 5d 20 29  2') || zArg[1] )
2c00: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 63  {.            rc
2c10: 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b   = SQLITE_ERROR;
2c20: 0a 20 20 20 20 20 20 20 20 20 20 7d 65 6c 73 65  .          }else
2c30: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 2d  {.            p-
2c40: 3e 65 52 65 6d 6f 76 65 44 69 61 63 72 69 74 69  >eRemoveDiacriti
2c50: 63 20 3d 20 28 7a 41 72 67 5b 30 5d 20 2d 20 27  c = (zArg[0] - '
2c60: 30 27 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20  0');.           
2c70: 20 61 73 73 65 72 74 28 20 70 2d 3e 65 52 65 6d   assert( p->eRem
2c80: 6f 76 65 44 69 61 63 72 69 74 69 63 3d 3d 46 54  oveDiacritic==FT
2c90: 53 35 5f 52 45 4d 4f 56 45 5f 44 49 41 43 52 49  S5_REMOVE_DIACRI
2ca0: 54 49 43 53 5f 4e 4f 4e 45 0a 20 20 20 20 20 20  TICS_NONE.      
2cb0: 20 20 20 20 20 20 20 20 20 20 20 7c 7c 20 70 2d             || p-
2cc0: 3e 65 52 65 6d 6f 76 65 44 69 61 63 72 69 74 69  >eRemoveDiacriti
2cd0: 63 3d 3d 46 54 53 35 5f 52 45 4d 4f 56 45 5f 44  c==FTS5_REMOVE_D
2ce0: 49 41 43 52 49 54 49 43 53 5f 53 49 4d 50 4c 45  IACRITICS_SIMPLE
2cf0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
2d00: 20 20 7c 7c 20 70 2d 3e 65 52 65 6d 6f 76 65 44    || p->eRemoveD
2d10: 69 61 63 72 69 74 69 63 3d 3d 46 54 53 35 5f 52  iacritic==FTS5_R
2d20: 45 4d 4f 56 45 5f 44 49 41 43 52 49 54 49 43 53  EMOVE_DIACRITICS
2d30: 5f 43 4f 4d 50 4c 45 58 0a 20 20 20 20 20 20 20  _COMPLEX.       
2d40: 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20 20       );.        
2d50: 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 65 6c 73    }.        }els
2d60: 65 0a 20 20 20 20 20 20 20 20 69 66 28 20 30 3d  e.        if( 0=
2d70: 3d 73 71 6c 69 74 65 33 5f 73 74 72 69 63 6d 70  =sqlite3_stricmp
2d80: 28 61 7a 41 72 67 5b 69 5d 2c 20 22 74 6f 6b 65  (azArg[i], "toke
2d90: 6e 63 68 61 72 73 22 29 20 29 7b 0a 20 20 20 20  nchars") ){.    
2da0: 20 20 20 20 20 20 72 63 20 3d 20 66 74 73 35 55        rc = fts5U
2db0: 6e 69 63 6f 64 65 41 64 64 45 78 63 65 70 74 69  nicodeAddExcepti
2dc0: 6f 6e 73 28 70 2c 20 7a 41 72 67 2c 20 31 29 3b  ons(p, zArg, 1);
2dd0: 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 0a 20  .        }else. 
2de0: 20 20 20 20 20 20 20 69 66 28 20 30 3d 3d 73 71         if( 0==sq
2df0: 6c 69 74 65 33 5f 73 74 72 69 63 6d 70 28 61 7a  lite3_stricmp(az
2e00: 41 72 67 5b 69 5d 2c 20 22 73 65 70 61 72 61 74  Arg[i], "separat
2e10: 6f 72 73 22 29 20 29 7b 0a 20 20 20 20 20 20 20  ors") ){.       
2e20: 20 20 20 72 63 20 3d 20 66 74 73 35 55 6e 69 63     rc = fts5Unic
2e30: 6f 64 65 41 64 64 45 78 63 65 70 74 69 6f 6e 73  odeAddExceptions
2e40: 28 70 2c 20 7a 41 72 67 2c 20 30 29 3b 0a 20 20  (p, zArg, 0);.  
2e50: 20 20 20 20 20 20 7d 65 6c 73 65 0a 20 20 20 20        }else.    
2e60: 20 20 20 20 69 66 28 20 30 3d 3d 73 71 6c 69 74      if( 0==sqlit
2e70: 65 33 5f 73 74 72 69 63 6d 70 28 61 7a 41 72 67  e3_stricmp(azArg
2e80: 5b 69 5d 2c 20 22 63 61 74 65 67 6f 72 69 65 73  [i], "categories
2e90: 22 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  ") ){.          
2ea0: 2f 2a 20 6e 6f 2d 6f 70 20 2a 2f 0a 20 20 20 20  /* no-op */.    
2eb0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
2ec0: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
2ed0: 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 20 20  _ERROR;.        
2ee0: 7d 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 7d  }.      }..    }
2ef0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63 20 3d  else{.      rc =
2f00: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
2f10: 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63 21     }.    if( rc!
2f20: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
2f30: 20 20 20 20 66 74 73 35 55 6e 69 63 6f 64 65 44      fts5UnicodeD
2f40: 65 6c 65 74 65 28 28 46 74 73 35 54 6f 6b 65 6e  elete((Fts5Token
2f50: 69 7a 65 72 2a 29 70 29 3b 0a 20 20 20 20 20 20  izer*)p);.      
2f60: 70 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20  p = 0;.    }.   
2f70: 20 2a 70 70 4f 75 74 20 3d 20 28 46 74 73 35 54   *ppOut = (Fts5T
2f80: 6f 6b 65 6e 69 7a 65 72 2a 29 70 3b 0a 20 20 7d  okenizer*)p;.  }
2f90: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
2fa0: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 72  ./*.** Return tr
2fb0: 75 65 20 69 66 2c 20 66 6f 72 20 74 68 65 20 70  ue if, for the p
2fc0: 75 72 70 6f 73 65 73 20 6f 66 20 74 6f 6b 65 6e  urposes of token
2fd0: 69 7a 69 6e 67 20 77 69 74 68 20 74 68 65 20 74  izing with the t
2fe0: 6f 6b 65 6e 69 7a 65 72 0a 2a 2a 20 70 61 73 73  okenizer.** pass
2ff0: 65 64 20 61 73 20 74 68 65 20 66 69 72 73 74 20  ed as the first 
3000: 61 72 67 75 6d 65 6e 74 2c 20 63 6f 64 65 70 6f  argument, codepo
3010: 69 6e 74 20 69 43 6f 64 65 20 69 73 20 63 6f 6e  int iCode is con
3020: 73 69 64 65 72 65 64 20 61 20 74 6f 6b 65 6e 20  sidered a token 
3030: 0a 2a 2a 20 63 68 61 72 61 63 74 65 72 20 28 6e  .** character (n
3040: 6f 74 20 61 20 73 65 70 61 72 61 74 6f 72 29 2e  ot a separator).
3050: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
3060: 74 73 35 55 6e 69 63 6f 64 65 49 73 41 6c 6e 75  ts5UnicodeIsAlnu
3070: 6d 28 55 6e 69 63 6f 64 65 36 31 54 6f 6b 65 6e  m(Unicode61Token
3080: 69 7a 65 72 20 2a 70 2c 20 69 6e 74 20 69 43 6f  izer *p, int iCo
3090: 64 65 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 0a  de){.  return (.
30a0: 20 20 20 20 70 2d 3e 61 43 61 74 65 67 6f 72 79      p->aCategory
30b0: 5b 73 71 6c 69 74 65 33 46 74 73 35 55 6e 69 63  [sqlite3Fts5Unic
30c0: 6f 64 65 43 61 74 65 67 6f 72 79 28 28 75 33 32  odeCategory((u32
30d0: 29 69 43 6f 64 65 29 5d 0a 20 20 20 20 5e 20 66  )iCode)].    ^ f
30e0: 74 73 35 55 6e 69 63 6f 64 65 49 73 45 78 63 65  ts5UnicodeIsExce
30f0: 70 74 69 6f 6e 28 70 2c 20 69 43 6f 64 65 29 0a  ption(p, iCode).
3100: 20 20 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69    );.}..static i
3110: 6e 74 20 66 74 73 35 55 6e 69 63 6f 64 65 54 6f  nt fts5UnicodeTo
3120: 6b 65 6e 69 7a 65 28 0a 20 20 46 74 73 35 54 6f  kenize(.  Fts5To
3130: 6b 65 6e 69 7a 65 72 20 2a 70 54 6f 6b 65 6e 69  kenizer *pTokeni
3140: 7a 65 72 2c 0a 20 20 76 6f 69 64 20 2a 70 43 74  zer,.  void *pCt
3150: 78 2c 0a 20 20 69 6e 74 20 69 55 6e 75 73 65 64  x,.  int iUnused
3160: 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ,.  const char *
3170: 70 54 65 78 74 2c 20 69 6e 74 20 6e 54 65 78 74  pText, int nText
3180: 2c 0a 20 20 69 6e 74 20 28 2a 78 54 6f 6b 65 6e  ,.  int (*xToken
3190: 29 28 76 6f 69 64 2a 2c 20 69 6e 74 2c 20 63 6f  )(void*, int, co
31a0: 6e 73 74 20 63 68 61 72 2a 2c 20 69 6e 74 20 6e  nst char*, int n
31b0: 54 6f 6b 65 6e 2c 20 69 6e 74 20 69 53 74 61 72  Token, int iStar
31c0: 74 2c 20 69 6e 74 20 69 45 6e 64 29 0a 29 7b 0a  t, int iEnd).){.
31d0: 20 20 55 6e 69 63 6f 64 65 36 31 54 6f 6b 65 6e    Unicode61Token
31e0: 69 7a 65 72 20 2a 70 20 3d 20 28 55 6e 69 63 6f  izer *p = (Unico
31f0: 64 65 36 31 54 6f 6b 65 6e 69 7a 65 72 2a 29 70  de61Tokenizer*)p
3200: 54 6f 6b 65 6e 69 7a 65 72 3b 0a 20 20 69 6e 74  Tokenizer;.  int
3210: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
3220: 0a 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72  .  unsigned char
3230: 20 2a 61 20 3d 20 70 2d 3e 61 54 6f 6b 65 6e 43   *a = p->aTokenC
3240: 68 61 72 3b 0a 0a 20 20 75 6e 73 69 67 6e 65 64  har;..  unsigned
3250: 20 63 68 61 72 20 2a 7a 54 65 72 6d 20 3d 20 28   char *zTerm = (
3260: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 2a 29 26  unsigned char*)&
3270: 70 54 65 78 74 5b 6e 54 65 78 74 5d 3b 0a 20 20  pText[nText];.  
3280: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a 7a  unsigned char *z
3290: 43 73 72 20 3d 20 28 75 6e 73 69 67 6e 65 64 20  Csr = (unsigned 
32a0: 63 68 61 72 20 2a 29 70 54 65 78 74 3b 0a 0a 20  char *)pText;.. 
32b0: 20 2f 2a 20 4f 75 74 70 75 74 20 62 75 66 66 65   /* Output buffe
32c0: 72 20 2a 2f 0a 20 20 63 68 61 72 20 2a 61 46 6f  r */.  char *aFo
32d0: 6c 64 20 3d 20 70 2d 3e 61 46 6f 6c 64 3b 0a 20  ld = p->aFold;. 
32e0: 20 69 6e 74 20 6e 46 6f 6c 64 20 3d 20 70 2d 3e   int nFold = p->
32f0: 6e 46 6f 6c 64 3b 0a 20 20 63 6f 6e 73 74 20 63  nFold;.  const c
3300: 68 61 72 20 2a 70 45 6e 64 20 3d 20 26 61 46 6f  har *pEnd = &aFo
3310: 6c 64 5b 6e 46 6f 6c 64 2d 36 5d 3b 0a 0a 20 20  ld[nFold-6];..  
3320: 55 4e 55 53 45 44 5f 50 41 52 41 4d 28 69 55 6e  UNUSED_PARAM(iUn
3330: 75 73 65 64 29 3b 0a 0a 20 20 2f 2a 20 45 61 63  used);..  /* Eac
3340: 68 20 69 74 65 72 61 74 69 6f 6e 20 6f 66 20 74  h iteration of t
3350: 68 69 73 20 6c 6f 6f 70 20 67 6f 62 62 6c 65 73  his loop gobbles
3360: 20 75 70 20 61 20 63 6f 6e 74 69 67 75 6f 75 73   up a contiguous
3370: 20 72 75 6e 20 6f 66 20 73 65 70 61 72 61 74 6f   run of separato
3380: 72 73 2c 0a 20 20 2a 2a 20 74 68 65 6e 20 74 68  rs,.  ** then th
3390: 65 20 6e 65 78 74 20 74 6f 6b 65 6e 2e 20 20 2a  e next token.  *
33a0: 2f 0a 20 20 77 68 69 6c 65 28 20 72 63 3d 3d 53  /.  while( rc==S
33b0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
33c0: 75 33 32 20 69 43 6f 64 65 3b 20 20 20 20 20 20  u32 iCode;      
33d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
33e0: 20 6e 6f 6e 2d 41 53 43 49 49 20 63 6f 64 65 70   non-ASCII codep
33f0: 6f 69 6e 74 20 72 65 61 64 20 66 72 6f 6d 20 69  oint read from i
3400: 6e 70 75 74 20 2a 2f 0a 20 20 20 20 63 68 61 72  nput */.    char
3410: 20 2a 7a 4f 75 74 20 3d 20 61 46 6f 6c 64 3b 0a   *zOut = aFold;.
3420: 20 20 20 20 69 6e 74 20 69 73 3b 0a 20 20 20 20      int is;.    
3430: 69 6e 74 20 69 65 3b 0a 0a 20 20 20 20 2f 2a 20  int ie;..    /* 
3440: 53 6b 69 70 20 61 6e 79 20 73 65 70 61 72 61 74  Skip any separat
3450: 6f 72 20 63 68 61 72 61 63 74 65 72 73 2e 20 2a  or characters. *
3460: 2f 0a 20 20 20 20 77 68 69 6c 65 28 20 31 20 29  /.    while( 1 )
3470: 7b 0a 20 20 20 20 20 20 69 66 28 20 7a 43 73 72  {.      if( zCsr
3480: 3e 3d 7a 54 65 72 6d 20 29 20 67 6f 74 6f 20 74  >=zTerm ) goto t
3490: 6f 6b 65 6e 69 7a 65 5f 64 6f 6e 65 3b 0a 20 20  okenize_done;.  
34a0: 20 20 20 20 69 66 28 20 2a 7a 43 73 72 20 26 20      if( *zCsr & 
34b0: 30 78 38 30 20 29 20 7b 0a 20 20 20 20 20 20 20  0x80 ) {.       
34c0: 20 2f 2a 20 41 20 63 68 61 72 61 63 74 65 72 20   /* A character 
34d0: 6f 75 74 73 69 64 65 20 6f 66 20 74 68 65 20 61  outside of the a
34e0: 73 63 69 69 20 72 61 6e 67 65 2e 20 53 6b 69 70  scii range. Skip
34f0: 20 70 61 73 74 20 69 74 20 69 66 20 69 74 20 69   past it if it i
3500: 73 0a 20 20 20 20 20 20 20 20 2a 2a 20 61 20 73  s.        ** a s
3510: 65 70 61 72 61 74 6f 72 20 63 68 61 72 61 63 74  eparator charact
3520: 65 72 2e 20 4f 72 20 62 72 65 61 6b 20 6f 75 74  er. Or break out
3530: 20 6f 66 20 74 68 65 20 6c 6f 6f 70 20 69 66 20   of the loop if 
3540: 69 74 20 69 73 20 6e 6f 74 2e 20 2a 2f 0a 20 20  it is not. */.  
3550: 20 20 20 20 20 20 69 73 20 3d 20 7a 43 73 72 20        is = zCsr 
3560: 2d 20 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72  - (unsigned char
3570: 2a 29 70 54 65 78 74 3b 0a 20 20 20 20 20 20 20  *)pText;.       
3580: 20 52 45 41 44 5f 55 54 46 38 28 7a 43 73 72 2c   READ_UTF8(zCsr,
3590: 20 7a 54 65 72 6d 2c 20 69 43 6f 64 65 29 3b 0a   zTerm, iCode);.
35a0: 20 20 20 20 20 20 20 20 69 66 28 20 66 74 73 35          if( fts5
35b0: 55 6e 69 63 6f 64 65 49 73 41 6c 6e 75 6d 28 70  UnicodeIsAlnum(p
35c0: 2c 20 69 43 6f 64 65 29 20 29 7b 0a 20 20 20 20  , iCode) ){.    
35d0: 20 20 20 20 20 20 67 6f 74 6f 20 6e 6f 6e 5f 61        goto non_a
35e0: 73 63 69 69 5f 74 6f 6b 65 6e 63 68 61 72 3b 0a  scii_tokenchar;.
35f0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
3600: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 69  }else{.        i
3610: 66 28 20 61 5b 2a 7a 43 73 72 5d 20 29 7b 0a 20  f( a[*zCsr] ){. 
3620: 20 20 20 20 20 20 20 20 20 69 73 20 3d 20 7a 43           is = zC
3630: 73 72 20 2d 20 28 75 6e 73 69 67 6e 65 64 20 63  sr - (unsigned c
3640: 68 61 72 2a 29 70 54 65 78 74 3b 0a 20 20 20 20  har*)pText;.    
3650: 20 20 20 20 20 20 67 6f 74 6f 20 61 73 63 69 69        goto ascii
3660: 5f 74 6f 6b 65 6e 63 68 61 72 3b 0a 20 20 20 20  _tokenchar;.    
3670: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7a 43      }.        zC
3680: 73 72 2b 2b 3b 0a 20 20 20 20 20 20 7d 0a 20 20  sr++;.      }.  
3690: 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 52 75 6e 20    }..    /* Run 
36a0: 74 68 72 6f 75 67 68 20 74 68 65 20 74 6f 6b 65  through the toke
36b0: 6e 63 68 61 72 73 2e 20 46 6f 6c 64 20 74 68 65  nchars. Fold the
36c0: 6d 20 69 6e 74 6f 20 74 68 65 20 6f 75 74 70 75  m into the outpu
36d0: 74 20 62 75 66 66 65 72 20 61 6c 6f 6e 67 0a 20  t buffer along. 
36e0: 20 20 20 2a 2a 20 74 68 65 20 77 61 79 2e 20 20     ** the way.  
36f0: 2a 2f 0a 20 20 20 20 77 68 69 6c 65 28 20 7a 43  */.    while( zC
3700: 73 72 3c 7a 54 65 72 6d 20 29 7b 0a 0a 20 20 20  sr<zTerm ){..   
3710: 20 20 20 2f 2a 20 47 72 6f 77 20 74 68 65 20 6f     /* Grow the o
3720: 75 74 70 75 74 20 62 75 66 66 65 72 20 73 6f 20  utput buffer so 
3730: 74 68 61 74 20 74 68 65 72 65 20 69 73 20 73 75  that there is su
3740: 66 66 69 63 69 65 6e 74 20 73 70 61 63 65 20 74  fficient space t
3750: 6f 20 66 69 74 20 74 68 65 0a 20 20 20 20 20 20  o fit the.      
3760: 2a 2a 20 6c 61 72 67 65 73 74 20 70 6f 73 73 69  ** largest possi
3770: 62 6c 65 20 75 74 66 2d 38 20 63 68 61 72 61 63  ble utf-8 charac
3780: 74 65 72 2e 20 20 2a 2f 0a 20 20 20 20 20 20 69  ter.  */.      i
3790: 66 28 20 7a 4f 75 74 3e 70 45 6e 64 20 29 7b 0a  f( zOut>pEnd ){.
37a0: 20 20 20 20 20 20 20 20 61 46 6f 6c 64 20 3d 20          aFold = 
37b0: 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 36 34  sqlite3_malloc64
37c0: 28 28 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 29  ((sqlite3_int64)
37d0: 6e 46 6f 6c 64 2a 32 29 3b 0a 20 20 20 20 20 20  nFold*2);.      
37e0: 20 20 69 66 28 20 61 46 6f 6c 64 3d 3d 30 20 29    if( aFold==0 )
37f0: 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d  {.          rc =
3800: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
3810: 20 20 20 20 20 20 20 20 20 67 6f 74 6f 20 74 6f           goto to
3820: 6b 65 6e 69 7a 65 5f 64 6f 6e 65 3b 0a 20 20 20  kenize_done;.   
3830: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7a       }.        z
3840: 4f 75 74 20 3d 20 26 61 46 6f 6c 64 5b 7a 4f 75  Out = &aFold[zOu
3850: 74 20 2d 20 70 2d 3e 61 46 6f 6c 64 5d 3b 0a 20  t - p->aFold];. 
3860: 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28 61 46         memcpy(aF
3870: 6f 6c 64 2c 20 70 2d 3e 61 46 6f 6c 64 2c 20 6e  old, p->aFold, n
3880: 46 6f 6c 64 29 3b 0a 20 20 20 20 20 20 20 20 73  Fold);.        s
3890: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 61  qlite3_free(p->a
38a0: 46 6f 6c 64 29 3b 0a 20 20 20 20 20 20 20 20 70  Fold);.        p
38b0: 2d 3e 61 46 6f 6c 64 20 3d 20 61 46 6f 6c 64 3b  ->aFold = aFold;
38c0: 0a 20 20 20 20 20 20 20 20 70 2d 3e 6e 46 6f 6c  .        p->nFol
38d0: 64 20 3d 20 6e 46 6f 6c 64 20 3d 20 6e 46 6f 6c  d = nFold = nFol
38e0: 64 2a 32 3b 0a 20 20 20 20 20 20 20 20 70 45 6e  d*2;.        pEn
38f0: 64 20 3d 20 26 61 46 6f 6c 64 5b 6e 46 6f 6c 64  d = &aFold[nFold
3900: 2d 36 5d 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20  -6];.      }..  
3910: 20 20 20 20 69 66 28 20 2a 7a 43 73 72 20 26 20      if( *zCsr & 
3920: 30 78 38 30 20 29 7b 0a 20 20 20 20 20 20 20 20  0x80 ){.        
3930: 2f 2a 20 41 6e 20 6e 6f 6e 2d 61 73 63 69 69 2d  /* An non-ascii-
3940: 72 61 6e 67 65 20 63 68 61 72 61 63 74 65 72 2e  range character.
3950: 20 46 6f 6c 64 20 69 74 20 69 6e 74 6f 20 74 68   Fold it into th
3960: 65 20 6f 75 74 70 75 74 20 62 75 66 66 65 72 20  e output buffer 
3970: 69 66 0a 20 20 20 20 20 20 20 20 2a 2a 20 69 74  if.        ** it
3980: 20 69 73 20 61 20 74 6f 6b 65 6e 20 63 68 61 72   is a token char
3990: 61 63 74 65 72 2c 20 6f 72 20 62 72 65 61 6b 20  acter, or break 
39a0: 6f 75 74 20 6f 66 20 74 68 65 20 6c 6f 6f 70 20  out of the loop 
39b0: 69 66 20 69 74 20 69 73 20 6e 6f 74 2e 20 2a 2f  if it is not. */
39c0: 0a 20 20 20 20 20 20 20 20 52 45 41 44 5f 55 54  .        READ_UT
39d0: 46 38 28 7a 43 73 72 2c 20 7a 54 65 72 6d 2c 20  F8(zCsr, zTerm, 
39e0: 69 43 6f 64 65 29 3b 0a 20 20 20 20 20 20 20 20  iCode);.        
39f0: 69 66 28 20 66 74 73 35 55 6e 69 63 6f 64 65 49  if( fts5UnicodeI
3a00: 73 41 6c 6e 75 6d 28 70 2c 69 43 6f 64 65 29 7c  sAlnum(p,iCode)|
3a10: 7c 73 71 6c 69 74 65 33 46 74 73 35 55 6e 69 63  |sqlite3Fts5Unic
3a20: 6f 64 65 49 73 64 69 61 63 72 69 74 69 63 28 69  odeIsdiacritic(i
3a30: 43 6f 64 65 29 20 29 7b 0a 20 6e 6f 6e 5f 61 73  Code) ){. non_as
3a40: 63 69 69 5f 74 6f 6b 65 6e 63 68 61 72 3a 0a 20  cii_tokenchar:. 
3a50: 20 20 20 20 20 20 20 20 20 69 43 6f 64 65 20 3d           iCode =
3a60: 20 73 71 6c 69 74 65 33 46 74 73 35 55 6e 69 63   sqlite3Fts5Unic
3a70: 6f 64 65 46 6f 6c 64 28 69 43 6f 64 65 2c 20 70  odeFold(iCode, p
3a80: 2d 3e 65 52 65 6d 6f 76 65 44 69 61 63 72 69 74  ->eRemoveDiacrit
3a90: 69 63 29 3b 0a 20 20 20 20 20 20 20 20 20 20 69  ic);.          i
3aa0: 66 28 20 69 43 6f 64 65 20 29 20 57 52 49 54 45  f( iCode ) WRITE
3ab0: 5f 55 54 46 38 28 7a 4f 75 74 2c 20 69 43 6f 64  _UTF8(zOut, iCod
3ac0: 65 29 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73  e);.        }els
3ad0: 65 7b 0a 20 20 20 20 20 20 20 20 20 20 62 72 65  e{.          bre
3ae0: 61 6b 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  ak;.        }.  
3af0: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 61 5b      }else if( a[
3b00: 2a 7a 43 73 72 5d 3d 3d 30 20 29 7b 0a 20 20 20  *zCsr]==0 ){.   
3b10: 20 20 20 20 20 2f 2a 20 41 6e 20 61 73 63 69 69       /* An ascii
3b20: 2d 72 61 6e 67 65 20 73 65 70 61 72 61 74 6f 72  -range separator
3b30: 20 63 68 61 72 61 63 74 65 72 2e 20 45 6e 64 20   character. End 
3b40: 6f 66 20 74 6f 6b 65 6e 2e 20 2a 2f 0a 20 20 20  of token. */.   
3b50: 20 20 20 20 20 62 72 65 61 6b 3b 20 0a 20 20 20       break; .   
3b60: 20 20 20 7d 65 6c 73 65 7b 0a 20 61 73 63 69 69     }else{. ascii
3b70: 5f 74 6f 6b 65 6e 63 68 61 72 3a 0a 20 20 20 20  _tokenchar:.    
3b80: 20 20 20 20 69 66 28 20 2a 7a 43 73 72 3e 3d 27      if( *zCsr>='
3b90: 41 27 20 26 26 20 2a 7a 43 73 72 3c 3d 27 5a 27  A' && *zCsr<='Z'
3ba0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 2a 7a   ){.          *z
3bb0: 4f 75 74 2b 2b 20 3d 20 2a 7a 43 73 72 20 2b 20  Out++ = *zCsr + 
3bc0: 33 32 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73  32;.        }els
3bd0: 65 7b 0a 20 20 20 20 20 20 20 20 20 20 2a 7a 4f  e{.          *zO
3be0: 75 74 2b 2b 20 3d 20 2a 7a 43 73 72 3b 0a 20 20  ut++ = *zCsr;.  
3bf0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
3c00: 7a 43 73 72 2b 2b 3b 0a 20 20 20 20 20 20 7d 0a  zCsr++;.      }.
3c10: 20 20 20 20 20 20 69 65 20 3d 20 7a 43 73 72 20        ie = zCsr 
3c20: 2d 20 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72  - (unsigned char
3c30: 2a 29 70 54 65 78 74 3b 0a 20 20 20 20 7d 0a 0a  *)pText;.    }..
3c40: 20 20 20 20 2f 2a 20 49 6e 76 6f 6b 65 20 74 68      /* Invoke th
3c50: 65 20 74 6f 6b 65 6e 20 63 61 6c 6c 62 61 63 6b  e token callback
3c60: 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 78 54 6f   */.    rc = xTo
3c70: 6b 65 6e 28 70 43 74 78 2c 20 30 2c 20 61 46 6f  ken(pCtx, 0, aFo
3c80: 6c 64 2c 20 7a 4f 75 74 2d 61 46 6f 6c 64 2c 20  ld, zOut-aFold, 
3c90: 69 73 2c 20 69 65 29 3b 20 0a 20 20 7d 0a 20 20  is, ie); .  }.  
3ca0: 0a 20 74 6f 6b 65 6e 69 7a 65 5f 64 6f 6e 65 3a  . tokenize_done:
3cb0: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
3cc0: 45 5f 44 4f 4e 45 20 29 20 72 63 20 3d 20 53 51  E_DONE ) rc = SQ
3cd0: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 72 65 74 75 72  LITE_OK;.  retur
3ce0: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a  n rc;.}../******
3cf0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3d00: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3d10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3d20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3d30: 2a 2a 2a 2a 0a 2a 2a 20 53 74 61 72 74 20 6f 66  ****.** Start of
3d40: 20 70 6f 72 74 65 72 20 73 74 65 6d 6d 65 72 20   porter stemmer 
3d50: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a  implementation..
3d60: 2a 2f 0a 0a 2f 2a 20 41 6e 79 20 74 6f 6b 65 6e  */../* Any token
3d70: 73 20 6c 61 72 67 65 72 20 74 68 61 6e 20 74 68  s larger than th
3d80: 69 73 20 28 69 6e 20 62 79 74 65 73 29 20 61 72  is (in bytes) ar
3d90: 65 20 70 61 73 73 65 64 20 74 68 72 6f 75 67 68  e passed through
3da0: 20 77 69 74 68 6f 75 74 0a 2a 2a 20 73 74 65 6d   without.** stem
3db0: 6d 69 6e 67 2e 20 2a 2f 0a 23 64 65 66 69 6e 65  ming. */.#define
3dc0: 20 46 54 53 35 5f 50 4f 52 54 45 52 5f 4d 41 58   FTS5_PORTER_MAX
3dd0: 5f 54 4f 4b 45 4e 20 36 34 0a 0a 74 79 70 65 64  _TOKEN 64..typed
3de0: 65 66 20 73 74 72 75 63 74 20 50 6f 72 74 65 72  ef struct Porter
3df0: 54 6f 6b 65 6e 69 7a 65 72 20 50 6f 72 74 65 72  Tokenizer Porter
3e00: 54 6f 6b 65 6e 69 7a 65 72 3b 0a 73 74 72 75 63  Tokenizer;.struc
3e10: 74 20 50 6f 72 74 65 72 54 6f 6b 65 6e 69 7a 65  t PorterTokenize
3e20: 72 20 7b 0a 20 20 66 74 73 35 5f 74 6f 6b 65 6e  r {.  fts5_token
3e30: 69 7a 65 72 20 74 6f 6b 65 6e 69 7a 65 72 3b 20  izer tokenizer; 
3e40: 20 20 20 20 20 20 2f 2a 20 50 61 72 65 6e 74 20        /* Parent 
3e50: 74 6f 6b 65 6e 69 7a 65 72 20 6d 6f 64 75 6c 65  tokenizer module
3e60: 20 2a 2f 0a 20 20 46 74 73 35 54 6f 6b 65 6e 69   */.  Fts5Tokeni
3e70: 7a 65 72 20 2a 70 54 6f 6b 65 6e 69 7a 65 72 3b  zer *pTokenizer;
3e80: 20 20 20 20 20 20 2f 2a 20 50 61 72 65 6e 74 20        /* Parent 
3e90: 74 6f 6b 65 6e 69 7a 65 72 20 69 6e 73 74 61 6e  tokenizer instan
3ea0: 63 65 20 2a 2f 0a 20 20 63 68 61 72 20 61 42 75  ce */.  char aBu
3eb0: 66 5b 46 54 53 35 5f 50 4f 52 54 45 52 5f 4d 41  f[FTS5_PORTER_MA
3ec0: 58 5f 54 4f 4b 45 4e 20 2b 20 36 34 5d 3b 0a 7d  X_TOKEN + 64];.}
3ed0: 3b 0a 0a 2f 2a 0a 2a 2a 20 44 65 6c 65 74 65 20  ;../*.** Delete 
3ee0: 61 20 22 70 6f 72 74 65 72 22 20 74 6f 6b 65 6e  a "porter" token
3ef0: 69 7a 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  izer..*/.static 
3f00: 76 6f 69 64 20 66 74 73 35 50 6f 72 74 65 72 44  void fts5PorterD
3f10: 65 6c 65 74 65 28 46 74 73 35 54 6f 6b 65 6e 69  elete(Fts5Tokeni
3f20: 7a 65 72 20 2a 70 54 6f 6b 29 7b 0a 20 20 69 66  zer *pTok){.  if
3f30: 28 20 70 54 6f 6b 20 29 7b 0a 20 20 20 20 50 6f  ( pTok ){.    Po
3f40: 72 74 65 72 54 6f 6b 65 6e 69 7a 65 72 20 2a 70  rterTokenizer *p
3f50: 20 3d 20 28 50 6f 72 74 65 72 54 6f 6b 65 6e 69   = (PorterTokeni
3f60: 7a 65 72 2a 29 70 54 6f 6b 3b 0a 20 20 20 20 69  zer*)pTok;.    i
3f70: 66 28 20 70 2d 3e 70 54 6f 6b 65 6e 69 7a 65 72  f( p->pTokenizer
3f80: 20 29 7b 0a 20 20 20 20 20 20 70 2d 3e 74 6f 6b   ){.      p->tok
3f90: 65 6e 69 7a 65 72 2e 78 44 65 6c 65 74 65 28 70  enizer.xDelete(p
3fa0: 2d 3e 70 54 6f 6b 65 6e 69 7a 65 72 29 3b 0a 20  ->pTokenizer);. 
3fb0: 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33     }.    sqlite3
3fc0: 5f 66 72 65 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a  _free(p);.  }.}.
3fd0: 0a 2f 2a 0a 2a 2a 20 43 72 65 61 74 65 20 61 20  ./*.** Create a 
3fe0: 22 70 6f 72 74 65 72 22 20 74 6f 6b 65 6e 69 7a  "porter" tokeniz
3ff0: 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  er..*/.static in
4000: 74 20 66 74 73 35 50 6f 72 74 65 72 43 72 65 61  t fts5PorterCrea
4010: 74 65 28 0a 20 20 76 6f 69 64 20 2a 70 43 74 78  te(.  void *pCtx
4020: 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  , .  const char 
4030: 2a 2a 61 7a 41 72 67 2c 20 69 6e 74 20 6e 41 72  **azArg, int nAr
4040: 67 2c 0a 20 20 46 74 73 35 54 6f 6b 65 6e 69 7a  g,.  Fts5Tokeniz
4050: 65 72 20 2a 2a 70 70 4f 75 74 0a 29 7b 0a 20 20  er **ppOut.){.  
4060: 66 74 73 35 5f 61 70 69 20 2a 70 41 70 69 20 3d  fts5_api *pApi =
4070: 20 28 66 74 73 35 5f 61 70 69 2a 29 70 43 74 78   (fts5_api*)pCtx
4080: 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  ;.  int rc = SQL
4090: 49 54 45 5f 4f 4b 3b 0a 20 20 50 6f 72 74 65 72  ITE_OK;.  Porter
40a0: 54 6f 6b 65 6e 69 7a 65 72 20 2a 70 52 65 74 3b  Tokenizer *pRet;
40b0: 0a 20 20 76 6f 69 64 20 2a 70 55 73 65 72 64 61  .  void *pUserda
40c0: 74 61 20 3d 20 30 3b 0a 20 20 63 6f 6e 73 74 20  ta = 0;.  const 
40d0: 63 68 61 72 20 2a 7a 42 61 73 65 20 3d 20 22 75  char *zBase = "u
40e0: 6e 69 63 6f 64 65 36 31 22 3b 0a 0a 20 20 69 66  nicode61";..  if
40f0: 28 20 6e 41 72 67 3e 30 20 29 7b 0a 20 20 20 20  ( nArg>0 ){.    
4100: 7a 42 61 73 65 20 3d 20 61 7a 41 72 67 5b 30 5d  zBase = azArg[0]
4110: 3b 0a 20 20 7d 0a 0a 20 20 70 52 65 74 20 3d 20  ;.  }..  pRet = 
4120: 28 50 6f 72 74 65 72 54 6f 6b 65 6e 69 7a 65 72  (PorterTokenizer
4130: 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  *)sqlite3_malloc
4140: 28 73 69 7a 65 6f 66 28 50 6f 72 74 65 72 54 6f  (sizeof(PorterTo
4150: 6b 65 6e 69 7a 65 72 29 29 3b 0a 20 20 69 66 28  kenizer));.  if(
4160: 20 70 52 65 74 20 29 7b 0a 20 20 20 20 6d 65 6d   pRet ){.    mem
4170: 73 65 74 28 70 52 65 74 2c 20 30 2c 20 73 69 7a  set(pRet, 0, siz
4180: 65 6f 66 28 50 6f 72 74 65 72 54 6f 6b 65 6e 69  eof(PorterTokeni
4190: 7a 65 72 29 29 3b 0a 20 20 20 20 72 63 20 3d 20  zer));.    rc = 
41a0: 70 41 70 69 2d 3e 78 46 69 6e 64 54 6f 6b 65 6e  pApi->xFindToken
41b0: 69 7a 65 72 28 70 41 70 69 2c 20 7a 42 61 73 65  izer(pApi, zBase
41c0: 2c 20 26 70 55 73 65 72 64 61 74 61 2c 20 26 70  , &pUserdata, &p
41d0: 52 65 74 2d 3e 74 6f 6b 65 6e 69 7a 65 72 29 3b  Ret->tokenizer);
41e0: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72 63  .  }else{.    rc
41f0: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
4200: 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53  .  }.  if( rc==S
4210: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
4220: 69 6e 74 20 6e 41 72 67 32 20 3d 20 28 6e 41 72  int nArg2 = (nAr
4230: 67 3e 30 20 3f 20 6e 41 72 67 2d 31 20 3a 20 30  g>0 ? nArg-1 : 0
4240: 29 3b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61  );.    const cha
4250: 72 20 2a 2a 61 7a 41 72 67 32 20 3d 20 28 6e 41  r **azArg2 = (nA
4260: 72 67 32 20 3f 20 26 61 7a 41 72 67 5b 31 5d 20  rg2 ? &azArg[1] 
4270: 3a 20 30 29 3b 0a 20 20 20 20 72 63 20 3d 20 70  : 0);.    rc = p
4280: 52 65 74 2d 3e 74 6f 6b 65 6e 69 7a 65 72 2e 78  Ret->tokenizer.x
4290: 43 72 65 61 74 65 28 70 55 73 65 72 64 61 74 61  Create(pUserdata
42a0: 2c 20 61 7a 41 72 67 32 2c 20 6e 41 72 67 32 2c  , azArg2, nArg2,
42b0: 20 26 70 52 65 74 2d 3e 70 54 6f 6b 65 6e 69 7a   &pRet->pTokeniz
42c0: 65 72 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  er);.  }..  if( 
42d0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
42e0: 0a 20 20 20 20 66 74 73 35 50 6f 72 74 65 72 44  .    fts5PorterD
42f0: 65 6c 65 74 65 28 28 46 74 73 35 54 6f 6b 65 6e  elete((Fts5Token
4300: 69 7a 65 72 2a 29 70 52 65 74 29 3b 0a 20 20 20  izer*)pRet);.   
4310: 20 70 52 65 74 20 3d 20 30 3b 0a 20 20 7d 0a 20   pRet = 0;.  }. 
4320: 20 2a 70 70 4f 75 74 20 3d 20 28 46 74 73 35 54   *ppOut = (Fts5T
4330: 6f 6b 65 6e 69 7a 65 72 2a 29 70 52 65 74 3b 0a  okenizer*)pRet;.
4340: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
4350: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 50  typedef struct P
4360: 6f 72 74 65 72 43 6f 6e 74 65 78 74 20 50 6f 72  orterContext Por
4370: 74 65 72 43 6f 6e 74 65 78 74 3b 0a 73 74 72 75  terContext;.stru
4380: 63 74 20 50 6f 72 74 65 72 43 6f 6e 74 65 78 74  ct PorterContext
4390: 20 7b 0a 20 20 76 6f 69 64 20 2a 70 43 74 78 3b   {.  void *pCtx;
43a0: 0a 20 20 69 6e 74 20 28 2a 78 54 6f 6b 65 6e 29  .  int (*xToken)
43b0: 28 76 6f 69 64 2a 2c 20 69 6e 74 2c 20 63 6f 6e  (void*, int, con
43c0: 73 74 20 63 68 61 72 2a 2c 20 69 6e 74 2c 20 69  st char*, int, i
43d0: 6e 74 2c 20 69 6e 74 29 3b 0a 20 20 63 68 61 72  nt, int);.  char
43e0: 20 2a 61 42 75 66 3b 0a 7d 3b 0a 0a 74 79 70 65   *aBuf;.};..type
43f0: 64 65 66 20 73 74 72 75 63 74 20 50 6f 72 74 65  def struct Porte
4400: 72 52 75 6c 65 20 50 6f 72 74 65 72 52 75 6c 65  rRule PorterRule
4410: 3b 0a 73 74 72 75 63 74 20 50 6f 72 74 65 72 52  ;.struct PorterR
4420: 75 6c 65 20 7b 0a 20 20 63 6f 6e 73 74 20 63 68  ule {.  const ch
4430: 61 72 20 2a 7a 53 75 66 66 69 78 3b 0a 20 20 69  ar *zSuffix;.  i
4440: 6e 74 20 6e 53 75 66 66 69 78 3b 0a 20 20 69 6e  nt nSuffix;.  in
4450: 74 20 28 2a 78 43 6f 6e 64 29 28 63 68 61 72 20  t (*xCond)(char 
4460: 2a 7a 53 74 65 6d 2c 20 69 6e 74 20 6e 53 74 65  *zStem, int nSte
4470: 6d 29 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  m);.  const char
4480: 20 2a 7a 4f 75 74 70 75 74 3b 0a 20 20 69 6e 74   *zOutput;.  int
4490: 20 6e 4f 75 74 70 75 74 3b 0a 7d 3b 0a 0a 23 69   nOutput;.};..#i
44a0: 66 20 30 0a 73 74 61 74 69 63 20 69 6e 74 20 66  f 0.static int f
44b0: 74 73 35 50 6f 72 74 65 72 41 70 70 6c 79 28 63  ts5PorterApply(c
44c0: 68 61 72 20 2a 61 42 75 66 2c 20 69 6e 74 20 2a  har *aBuf, int *
44d0: 70 6e 42 75 66 2c 20 50 6f 72 74 65 72 52 75 6c  pnBuf, PorterRul
44e0: 65 20 2a 61 52 75 6c 65 29 7b 0a 20 20 69 6e 74  e *aRule){.  int
44f0: 20 72 65 74 20 3d 20 2d 31 3b 0a 20 20 69 6e 74   ret = -1;.  int
4500: 20 6e 42 75 66 20 3d 20 2a 70 6e 42 75 66 3b 0a   nBuf = *pnBuf;.
4510: 20 20 50 6f 72 74 65 72 52 75 6c 65 20 2a 70 3b    PorterRule *p;
4520: 0a 0a 20 20 66 6f 72 28 70 3d 61 52 75 6c 65 3b  ..  for(p=aRule;
4530: 20 70 2d 3e 7a 53 75 66 66 69 78 3b 20 70 2b 2b   p->zSuffix; p++
4540: 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 73  ){.    assert( s
4550: 74 72 6c 65 6e 28 70 2d 3e 7a 53 75 66 66 69 78  trlen(p->zSuffix
4560: 29 3d 3d 70 2d 3e 6e 53 75 66 66 69 78 20 29 3b  )==p->nSuffix );
4570: 0a 20 20 20 20 61 73 73 65 72 74 28 20 73 74 72  .    assert( str
4580: 6c 65 6e 28 70 2d 3e 7a 4f 75 74 70 75 74 29 3d  len(p->zOutput)=
4590: 3d 70 2d 3e 6e 4f 75 74 70 75 74 20 29 3b 0a 20  =p->nOutput );. 
45a0: 20 20 20 69 66 28 20 6e 42 75 66 3c 70 2d 3e 6e     if( nBuf<p->n
45b0: 53 75 66 66 69 78 20 29 20 63 6f 6e 74 69 6e 75  Suffix ) continu
45c0: 65 3b 0a 20 20 20 20 69 66 28 20 30 3d 3d 6d 65  e;.    if( 0==me
45d0: 6d 63 6d 70 28 26 61 42 75 66 5b 6e 42 75 66 20  mcmp(&aBuf[nBuf 
45e0: 2d 20 70 2d 3e 6e 53 75 66 66 69 78 5d 2c 20 70  - p->nSuffix], p
45f0: 2d 3e 7a 53 75 66 66 69 78 2c 20 70 2d 3e 6e 53  ->zSuffix, p->nS
4600: 75 66 66 69 78 29 20 29 20 62 72 65 61 6b 3b 0a  uffix) ) break;.
4610: 20 20 7d 0a 0a 20 20 69 66 28 20 70 2d 3e 7a 53    }..  if( p->zS
4620: 75 66 66 69 78 20 29 7b 0a 20 20 20 20 69 6e 74  uffix ){.    int
4630: 20 6e 53 74 65 6d 20 3d 20 6e 42 75 66 20 2d 20   nStem = nBuf - 
4640: 70 2d 3e 6e 53 75 66 66 69 78 3b 0a 20 20 20 20  p->nSuffix;.    
4650: 69 66 28 20 70 2d 3e 78 43 6f 6e 64 3d 3d 30 20  if( p->xCond==0 
4660: 7c 7c 20 70 2d 3e 78 43 6f 6e 64 28 61 42 75 66  || p->xCond(aBuf
4670: 2c 20 6e 53 74 65 6d 29 20 29 7b 0a 20 20 20 20  , nStem) ){.    
4680: 20 20 6d 65 6d 63 70 79 28 26 61 42 75 66 5b 6e    memcpy(&aBuf[n
4690: 53 74 65 6d 5d 2c 20 70 2d 3e 7a 4f 75 74 70 75  Stem], p->zOutpu
46a0: 74 2c 20 70 2d 3e 6e 4f 75 74 70 75 74 29 3b 0a  t, p->nOutput);.
46b0: 20 20 20 20 20 20 2a 70 6e 42 75 66 20 3d 20 6e        *pnBuf = n
46c0: 53 74 65 6d 20 2b 20 70 2d 3e 6e 4f 75 74 70 75  Stem + p->nOutpu
46d0: 74 3b 0a 20 20 20 20 20 20 72 65 74 20 3d 20 70  t;.      ret = p
46e0: 20 2d 20 61 52 75 6c 65 3b 0a 20 20 20 20 7d 0a   - aRule;.    }.
46f0: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 65    }..  return re
4700: 74 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 73 74 61  t;.}.#endif..sta
4710: 74 69 63 20 69 6e 74 20 66 74 73 35 50 6f 72 74  tic int fts5Port
4720: 65 72 49 73 56 6f 77 65 6c 28 63 68 61 72 20 63  erIsVowel(char c
4730: 2c 20 69 6e 74 20 62 59 49 73 56 6f 77 65 6c 29  , int bYIsVowel)
4740: 7b 0a 20 20 72 65 74 75 72 6e 20 28 0a 20 20 20  {.  return (.   
4750: 20 20 20 63 3d 3d 27 61 27 20 7c 7c 20 63 3d 3d     c=='a' || c==
4760: 27 65 27 20 7c 7c 20 63 3d 3d 27 69 27 20 7c 7c  'e' || c=='i' ||
4770: 20 63 3d 3d 27 6f 27 20 7c 7c 20 63 3d 3d 27 75   c=='o' || c=='u
4780: 27 20 7c 7c 20 28 62 59 49 73 56 6f 77 65 6c 20  ' || (bYIsVowel 
4790: 26 26 20 63 3d 3d 27 79 27 29 0a 20 20 29 3b 0a  && c=='y').  );.
47a0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  }..static int ft
47b0: 73 35 50 6f 72 74 65 72 47 6f 62 62 6c 65 56 43  s5PorterGobbleVC
47c0: 28 63 68 61 72 20 2a 7a 53 74 65 6d 2c 20 69 6e  (char *zStem, in
47d0: 74 20 6e 53 74 65 6d 2c 20 69 6e 74 20 62 50 72  t nStem, int bPr
47e0: 65 76 43 6f 6e 73 29 7b 0a 20 20 69 6e 74 20 69  evCons){.  int i
47f0: 3b 0a 20 20 69 6e 74 20 62 43 6f 6e 73 20 3d 20  ;.  int bCons = 
4800: 62 50 72 65 76 43 6f 6e 73 3b 0a 0a 20 20 2f 2a  bPrevCons;..  /*
4810: 20 53 63 61 6e 20 66 6f 72 20 61 20 76 6f 77 65   Scan for a vowe
4820: 6c 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20  l */.  for(i=0; 
4830: 69 3c 6e 53 74 65 6d 3b 20 69 2b 2b 29 7b 0a 20  i<nStem; i++){. 
4840: 20 20 20 69 66 28 20 30 3d 3d 28 62 43 6f 6e 73     if( 0==(bCons
4850: 20 3d 20 21 66 74 73 35 50 6f 72 74 65 72 49 73   = !fts5PorterIs
4860: 56 6f 77 65 6c 28 7a 53 74 65 6d 5b 69 5d 2c 20  Vowel(zStem[i], 
4870: 62 43 6f 6e 73 29 29 20 29 20 62 72 65 61 6b 3b  bCons)) ) break;
4880: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 63 61 6e 20  .  }..  /* Scan 
4890: 66 6f 72 20 61 20 63 6f 6e 73 6f 6e 65 6e 74 20  for a consonent 
48a0: 2a 2f 0a 20 20 66 6f 72 28 69 2b 2b 3b 20 69 3c  */.  for(i++; i<
48b0: 6e 53 74 65 6d 3b 20 69 2b 2b 29 7b 0a 20 20 20  nStem; i++){.   
48c0: 20 69 66 28 20 28 62 43 6f 6e 73 20 3d 20 21 66   if( (bCons = !f
48d0: 74 73 35 50 6f 72 74 65 72 49 73 56 6f 77 65 6c  ts5PorterIsVowel
48e0: 28 7a 53 74 65 6d 5b 69 5d 2c 20 62 43 6f 6e 73  (zStem[i], bCons
48f0: 29 29 20 29 20 72 65 74 75 72 6e 20 69 2b 31 3b  )) ) return i+1;
4900: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 30 3b  .  }.  return 0;
4910: 0a 7d 0a 0a 2f 2a 20 70 6f 72 74 65 72 20 72 75  .}../* porter ru
4920: 6c 65 20 63 6f 6e 64 69 74 69 6f 6e 3a 20 28 6d  le condition: (m
4930: 20 3e 20 30 29 20 2a 2f 0a 73 74 61 74 69 63 20   > 0) */.static 
4940: 69 6e 74 20 66 74 73 35 50 6f 72 74 65 72 5f 4d  int fts5Porter_M
4950: 47 74 30 28 63 68 61 72 20 2a 7a 53 74 65 6d 2c  Gt0(char *zStem,
4960: 20 69 6e 74 20 6e 53 74 65 6d 29 7b 0a 20 20 72   int nStem){.  r
4970: 65 74 75 72 6e 20 21 21 66 74 73 35 50 6f 72 74  eturn !!fts5Port
4980: 65 72 47 6f 62 62 6c 65 56 43 28 7a 53 74 65 6d  erGobbleVC(zStem
4990: 2c 20 6e 53 74 65 6d 2c 20 30 29 3b 0a 7d 0a 0a  , nStem, 0);.}..
49a0: 2f 2a 20 70 6f 72 74 65 72 20 72 75 6c 65 20 63  /* porter rule c
49b0: 6f 6e 64 69 74 69 6f 6e 3a 20 28 6d 20 3e 20 31  ondition: (m > 1
49c0: 29 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ) */.static int 
49d0: 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 28  fts5Porter_MGt1(
49e0: 63 68 61 72 20 2a 7a 53 74 65 6d 2c 20 69 6e 74  char *zStem, int
49f0: 20 6e 53 74 65 6d 29 7b 0a 20 20 69 6e 74 20 6e   nStem){.  int n
4a00: 3b 0a 20 20 6e 20 3d 20 66 74 73 35 50 6f 72 74  ;.  n = fts5Port
4a10: 65 72 47 6f 62 62 6c 65 56 43 28 7a 53 74 65 6d  erGobbleVC(zStem
4a20: 2c 20 6e 53 74 65 6d 2c 20 30 29 3b 0a 20 20 69  , nStem, 0);.  i
4a30: 66 28 20 6e 20 26 26 20 66 74 73 35 50 6f 72 74  f( n && fts5Port
4a40: 65 72 47 6f 62 62 6c 65 56 43 28 26 7a 53 74 65  erGobbleVC(&zSte
4a50: 6d 5b 6e 5d 2c 20 6e 53 74 65 6d 2d 6e 2c 20 31  m[n], nStem-n, 1
4a60: 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  ) ){.    return 
4a70: 31 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  1;.  }.  return 
4a80: 30 3b 0a 7d 0a 0a 2f 2a 20 70 6f 72 74 65 72 20  0;.}../* porter 
4a90: 72 75 6c 65 20 63 6f 6e 64 69 74 69 6f 6e 3a 20  rule condition: 
4aa0: 28 6d 20 3d 20 31 29 20 2a 2f 0a 73 74 61 74 69  (m = 1) */.stati
4ab0: 63 20 69 6e 74 20 66 74 73 35 50 6f 72 74 65 72  c int fts5Porter
4ac0: 5f 4d 45 71 31 28 63 68 61 72 20 2a 7a 53 74 65  _MEq1(char *zSte
4ad0: 6d 2c 20 69 6e 74 20 6e 53 74 65 6d 29 7b 0a 20  m, int nStem){. 
4ae0: 20 69 6e 74 20 6e 3b 0a 20 20 6e 20 3d 20 66 74   int n;.  n = ft
4af0: 73 35 50 6f 72 74 65 72 47 6f 62 62 6c 65 56 43  s5PorterGobbleVC
4b00: 28 7a 53 74 65 6d 2c 20 6e 53 74 65 6d 2c 20 30  (zStem, nStem, 0
4b10: 29 3b 0a 20 20 69 66 28 20 6e 20 26 26 20 30 3d  );.  if( n && 0=
4b20: 3d 66 74 73 35 50 6f 72 74 65 72 47 6f 62 62 6c  =fts5PorterGobbl
4b30: 65 56 43 28 26 7a 53 74 65 6d 5b 6e 5d 2c 20 6e  eVC(&zStem[n], n
4b40: 53 74 65 6d 2d 6e 2c 20 31 29 20 29 7b 0a 20 20  Stem-n, 1) ){.  
4b50: 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 7d 0a    return 1;.  }.
4b60: 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f    return 0;.}../
4b70: 2a 20 70 6f 72 74 65 72 20 72 75 6c 65 20 63 6f  * porter rule co
4b80: 6e 64 69 74 69 6f 6e 3a 20 28 2a 6f 29 20 2a 2f  ndition: (*o) */
4b90: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
4ba0: 50 6f 72 74 65 72 5f 4f 73 74 61 72 28 63 68 61  Porter_Ostar(cha
4bb0: 72 20 2a 7a 53 74 65 6d 2c 20 69 6e 74 20 6e 53  r *zStem, int nS
4bc0: 74 65 6d 29 7b 0a 20 20 69 66 28 20 7a 53 74 65  tem){.  if( zSte
4bd0: 6d 5b 6e 53 74 65 6d 2d 31 5d 3d 3d 27 77 27 20  m[nStem-1]=='w' 
4be0: 7c 7c 20 7a 53 74 65 6d 5b 6e 53 74 65 6d 2d 31  || zStem[nStem-1
4bf0: 5d 3d 3d 27 78 27 20 7c 7c 20 7a 53 74 65 6d 5b  ]=='x' || zStem[
4c00: 6e 53 74 65 6d 2d 31 5d 3d 3d 27 79 27 20 29 7b  nStem-1]=='y' ){
4c10: 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20  .    return 0;. 
4c20: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74 20   }else{.    int 
4c30: 69 3b 0a 20 20 20 20 69 6e 74 20 6d 61 73 6b 20  i;.    int mask 
4c40: 3d 20 30 3b 0a 20 20 20 20 69 6e 74 20 62 43 6f  = 0;.    int bCo
4c50: 6e 73 20 3d 20 30 3b 0a 20 20 20 20 66 6f 72 28  ns = 0;.    for(
4c60: 69 3d 30 3b 20 69 3c 6e 53 74 65 6d 3b 20 69 2b  i=0; i<nStem; i+
4c70: 2b 29 7b 0a 20 20 20 20 20 20 62 43 6f 6e 73 20  +){.      bCons 
4c80: 3d 20 21 66 74 73 35 50 6f 72 74 65 72 49 73 56  = !fts5PorterIsV
4c90: 6f 77 65 6c 28 7a 53 74 65 6d 5b 69 5d 2c 20 62  owel(zStem[i], b
4ca0: 43 6f 6e 73 29 3b 0a 20 20 20 20 20 20 61 73 73  Cons);.      ass
4cb0: 65 72 74 28 20 62 43 6f 6e 73 3d 3d 30 20 7c 7c  ert( bCons==0 ||
4cc0: 20 62 43 6f 6e 73 3d 3d 31 20 29 3b 0a 20 20 20   bCons==1 );.   
4cd0: 20 20 20 6d 61 73 6b 20 3d 20 28 6d 61 73 6b 20     mask = (mask 
4ce0: 3c 3c 20 31 29 20 2b 20 62 43 6f 6e 73 3b 0a 20  << 1) + bCons;. 
4cf0: 20 20 20 7d 0a 20 20 20 20 72 65 74 75 72 6e 20     }.    return 
4d00: 28 28 6d 61 73 6b 20 26 20 30 78 30 30 30 37 29  ((mask & 0x0007)
4d10: 3d 3d 30 78 30 30 30 35 29 3b 0a 20 20 7d 0a 7d  ==0x0005);.  }.}
4d20: 0a 0a 2f 2a 20 70 6f 72 74 65 72 20 72 75 6c 65  ../* porter rule
4d30: 20 63 6f 6e 64 69 74 69 6f 6e 3a 20 28 6d 20 3e   condition: (m >
4d40: 20 31 20 61 6e 64 20 28 2a 53 20 6f 72 20 2a 54   1 and (*S or *T
4d50: 29 29 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  )) */.static int
4d60: 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31   fts5Porter_MGt1
4d70: 5f 61 6e 64 5f 53 5f 6f 72 5f 54 28 63 68 61 72  _and_S_or_T(char
4d80: 20 2a 7a 53 74 65 6d 2c 20 69 6e 74 20 6e 53 74   *zStem, int nSt
4d90: 65 6d 29 7b 0a 20 20 61 73 73 65 72 74 28 20 6e  em){.  assert( n
4da0: 53 74 65 6d 3e 30 20 29 3b 0a 20 20 72 65 74 75  Stem>0 );.  retu
4db0: 72 6e 20 28 7a 53 74 65 6d 5b 6e 53 74 65 6d 2d  rn (zStem[nStem-
4dc0: 31 5d 3d 3d 27 73 27 20 7c 7c 20 7a 53 74 65 6d  1]=='s' || zStem
4dd0: 5b 6e 53 74 65 6d 2d 31 5d 3d 3d 27 74 27 29 20  [nStem-1]=='t') 
4de0: 0a 20 20 20 20 20 20 26 26 20 66 74 73 35 50 6f  .      && fts5Po
4df0: 72 74 65 72 5f 4d 47 74 31 28 7a 53 74 65 6d 2c  rter_MGt1(zStem,
4e00: 20 6e 53 74 65 6d 29 3b 0a 7d 0a 0a 2f 2a 20 70   nStem);.}../* p
4e10: 6f 72 74 65 72 20 72 75 6c 65 20 63 6f 6e 64 69  orter rule condi
4e20: 74 69 6f 6e 3a 20 28 2a 76 2a 29 20 2a 2f 0a 73  tion: (*v*) */.s
4e30: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 50 6f  tatic int fts5Po
4e40: 72 74 65 72 5f 56 6f 77 65 6c 28 63 68 61 72 20  rter_Vowel(char 
4e50: 2a 7a 53 74 65 6d 2c 20 69 6e 74 20 6e 53 74 65  *zStem, int nSte
4e60: 6d 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 66  m){.  int i;.  f
4e70: 6f 72 28 69 3d 30 3b 20 69 3c 6e 53 74 65 6d 3b  or(i=0; i<nStem;
4e80: 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 66   i++){.    if( f
4e90: 74 73 35 50 6f 72 74 65 72 49 73 56 6f 77 65 6c  ts5PorterIsVowel
4ea0: 28 7a 53 74 65 6d 5b 69 5d 2c 20 69 3e 30 29 20  (zStem[i], i>0) 
4eb0: 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  ){.      return 
4ec0: 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72  1;.    }.  }.  r
4ed0: 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 0a 2f 2a 2a  eturn 0;.}.../**
4ee0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4ef0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4f00: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4f10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4f20: 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a  ********.*******
4f30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4f40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4f50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4f60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4f70: 2a 2a 2a 2a 0a 2a 2a 20 47 45 4e 45 52 41 54 45  ****.** GENERATE
4f80: 44 20 43 4f 44 45 20 53 54 41 52 54 53 20 48 45  D CODE STARTS HE
4f90: 52 45 20 28 6d 6b 70 6f 72 74 65 72 73 74 65 70  RE (mkporterstep
4fa0: 73 2e 74 63 6c 29 0a 2a 2f 0a 0a 73 74 61 74 69  s.tcl).*/..stati
4fb0: 63 20 69 6e 74 20 66 74 73 35 50 6f 72 74 65 72  c int fts5Porter
4fc0: 53 74 65 70 34 28 63 68 61 72 20 2a 61 42 75 66  Step4(char *aBuf
4fd0: 2c 20 69 6e 74 20 2a 70 6e 42 75 66 29 7b 0a 20  , int *pnBuf){. 
4fe0: 20 69 6e 74 20 72 65 74 20 3d 20 30 3b 0a 20 20   int ret = 0;.  
4ff0: 69 6e 74 20 6e 42 75 66 20 3d 20 2a 70 6e 42 75  int nBuf = *pnBu
5000: 66 3b 0a 20 20 73 77 69 74 63 68 28 20 61 42 75  f;.  switch( aBu
5010: 66 5b 6e 42 75 66 2d 32 5d 20 29 7b 0a 20 20 20  f[nBuf-2] ){.   
5020: 20 0a 20 20 20 20 63 61 73 65 20 27 61 27 3a 20   .    case 'a': 
5030: 0a 20 20 20 20 20 20 69 66 28 20 6e 42 75 66 3e  .      if( nBuf>
5040: 32 20 26 26 20 30 3d 3d 6d 65 6d 63 6d 70 28 22  2 && 0==memcmp("
5050: 61 6c 22 2c 20 26 61 42 75 66 5b 6e 42 75 66 2d  al", &aBuf[nBuf-
5060: 32 5d 2c 20 32 29 20 29 7b 0a 20 20 20 20 20 20  2], 2) ){.      
5070: 20 20 69 66 28 20 66 74 73 35 50 6f 72 74 65 72    if( fts5Porter
5080: 5f 4d 47 74 31 28 61 42 75 66 2c 20 6e 42 75 66  _MGt1(aBuf, nBuf
5090: 2d 32 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20  -2) ){.         
50a0: 20 2a 70 6e 42 75 66 20 3d 20 6e 42 75 66 20 2d   *pnBuf = nBuf -
50b0: 20 32 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20   2;.        }.  
50c0: 20 20 20 20 7d 0a 20 20 20 20 20 20 62 72 65 61      }.      brea
50d0: 6b 3b 0a 20 20 0a 20 20 20 20 63 61 73 65 20 27  k;.  .    case '
50e0: 63 27 3a 20 0a 20 20 20 20 20 20 69 66 28 20 6e  c': .      if( n
50f0: 42 75 66 3e 34 20 26 26 20 30 3d 3d 6d 65 6d 63  Buf>4 && 0==memc
5100: 6d 70 28 22 61 6e 63 65 22 2c 20 26 61 42 75 66  mp("ance", &aBuf
5110: 5b 6e 42 75 66 2d 34 5d 2c 20 34 29 20 29 7b 0a  [nBuf-4], 4) ){.
5120: 20 20 20 20 20 20 20 20 69 66 28 20 66 74 73 35          if( fts5
5130: 50 6f 72 74 65 72 5f 4d 47 74 31 28 61 42 75 66  Porter_MGt1(aBuf
5140: 2c 20 6e 42 75 66 2d 34 29 20 29 7b 0a 20 20 20  , nBuf-4) ){.   
5150: 20 20 20 20 20 20 20 2a 70 6e 42 75 66 20 3d 20         *pnBuf = 
5160: 6e 42 75 66 20 2d 20 34 3b 0a 20 20 20 20 20 20  nBuf - 4;.      
5170: 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73 65 20    }.      }else 
5180: 69 66 28 20 6e 42 75 66 3e 34 20 26 26 20 30 3d  if( nBuf>4 && 0=
5190: 3d 6d 65 6d 63 6d 70 28 22 65 6e 63 65 22 2c 20  =memcmp("ence", 
51a0: 26 61 42 75 66 5b 6e 42 75 66 2d 34 5d 2c 20 34  &aBuf[nBuf-4], 4
51b0: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28  ) ){.        if(
51c0: 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31   fts5Porter_MGt1
51d0: 28 61 42 75 66 2c 20 6e 42 75 66 2d 34 29 20 29  (aBuf, nBuf-4) )
51e0: 7b 0a 20 20 20 20 20 20 20 20 20 20 2a 70 6e 42  {.          *pnB
51f0: 75 66 20 3d 20 6e 42 75 66 20 2d 20 34 3b 0a 20  uf = nBuf - 4;. 
5200: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
5210: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
5220: 0a 20 20 20 20 63 61 73 65 20 27 65 27 3a 20 0a  .    case 'e': .
5230: 20 20 20 20 20 20 69 66 28 20 6e 42 75 66 3e 32        if( nBuf>2
5240: 20 26 26 20 30 3d 3d 6d 65 6d 63 6d 70 28 22 65   && 0==memcmp("e
5250: 72 22 2c 20 26 61 42 75 66 5b 6e 42 75 66 2d 32  r", &aBuf[nBuf-2
5260: 5d 2c 20 32 29 20 29 7b 0a 20 20 20 20 20 20 20  ], 2) ){.       
5270: 20 69 66 28 20 66 74 73 35 50 6f 72 74 65 72 5f   if( fts5Porter_
5280: 4d 47 74 31 28 61 42 75 66 2c 20 6e 42 75 66 2d  MGt1(aBuf, nBuf-
5290: 32 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  2) ){.          
52a0: 2a 70 6e 42 75 66 20 3d 20 6e 42 75 66 20 2d 20  *pnBuf = nBuf - 
52b0: 32 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  2;.        }.   
52c0: 20 20 20 7d 0a 20 20 20 20 20 20 62 72 65 61 6b     }.      break
52d0: 3b 0a 20 20 0a 20 20 20 20 63 61 73 65 20 27 69  ;.  .    case 'i
52e0: 27 3a 20 0a 20 20 20 20 20 20 69 66 28 20 6e 42  ': .      if( nB
52f0: 75 66 3e 32 20 26 26 20 30 3d 3d 6d 65 6d 63 6d  uf>2 && 0==memcm
5300: 70 28 22 69 63 22 2c 20 26 61 42 75 66 5b 6e 42  p("ic", &aBuf[nB
5310: 75 66 2d 32 5d 2c 20 32 29 20 29 7b 0a 20 20 20  uf-2], 2) ){.   
5320: 20 20 20 20 20 69 66 28 20 66 74 73 35 50 6f 72       if( fts5Por
5330: 74 65 72 5f 4d 47 74 31 28 61 42 75 66 2c 20 6e  ter_MGt1(aBuf, n
5340: 42 75 66 2d 32 29 20 29 7b 0a 20 20 20 20 20 20  Buf-2) ){.      
5350: 20 20 20 20 2a 70 6e 42 75 66 20 3d 20 6e 42 75      *pnBuf = nBu
5360: 66 20 2d 20 32 3b 0a 20 20 20 20 20 20 20 20 7d  f - 2;.        }
5370: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62  .      }.      b
5380: 72 65 61 6b 3b 0a 20 20 0a 20 20 20 20 63 61 73  reak;.  .    cas
5390: 65 20 27 6c 27 3a 20 0a 20 20 20 20 20 20 69 66  e 'l': .      if
53a0: 28 20 6e 42 75 66 3e 34 20 26 26 20 30 3d 3d 6d  ( nBuf>4 && 0==m
53b0: 65 6d 63 6d 70 28 22 61 62 6c 65 22 2c 20 26 61  emcmp("able", &a
53c0: 42 75 66 5b 6e 42 75 66 2d 34 5d 2c 20 34 29 20  Buf[nBuf-4], 4) 
53d0: 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 66  ){.        if( f
53e0: 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 28 61  ts5Porter_MGt1(a
53f0: 42 75 66 2c 20 6e 42 75 66 2d 34 29 20 29 7b 0a  Buf, nBuf-4) ){.
5400: 20 20 20 20 20 20 20 20 20 20 2a 70 6e 42 75 66            *pnBuf
5410: 20 3d 20 6e 42 75 66 20 2d 20 34 3b 0a 20 20 20   = nBuf - 4;.   
5420: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c       }.      }el
5430: 73 65 20 69 66 28 20 6e 42 75 66 3e 34 20 26 26  se if( nBuf>4 &&
5440: 20 30 3d 3d 6d 65 6d 63 6d 70 28 22 69 62 6c 65   0==memcmp("ible
5450: 22 2c 20 26 61 42 75 66 5b 6e 42 75 66 2d 34 5d  ", &aBuf[nBuf-4]
5460: 2c 20 34 29 20 29 7b 0a 20 20 20 20 20 20 20 20  , 4) ){.        
5470: 69 66 28 20 66 74 73 35 50 6f 72 74 65 72 5f 4d  if( fts5Porter_M
5480: 47 74 31 28 61 42 75 66 2c 20 6e 42 75 66 2d 34  Gt1(aBuf, nBuf-4
5490: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 2a  ) ){.          *
54a0: 70 6e 42 75 66 20 3d 20 6e 42 75 66 20 2d 20 34  pnBuf = nBuf - 4
54b0: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
54c0: 20 20 7d 0a 20 20 20 20 20 20 62 72 65 61 6b 3b    }.      break;
54d0: 0a 20 20 0a 20 20 20 20 63 61 73 65 20 27 6e 27  .  .    case 'n'
54e0: 3a 20 0a 20 20 20 20 20 20 69 66 28 20 6e 42 75  : .      if( nBu
54f0: 66 3e 33 20 26 26 20 30 3d 3d 6d 65 6d 63 6d 70  f>3 && 0==memcmp
5500: 28 22 61 6e 74 22 2c 20 26 61 42 75 66 5b 6e 42  ("ant", &aBuf[nB
5510: 75 66 2d 33 5d 2c 20 33 29 20 29 7b 0a 20 20 20  uf-3], 3) ){.   
5520: 20 20 20 20 20 69 66 28 20 66 74 73 35 50 6f 72       if( fts5Por
5530: 74 65 72 5f 4d 47 74 31 28 61 42 75 66 2c 20 6e  ter_MGt1(aBuf, n
5540: 42 75 66 2d 33 29 20 29 7b 0a 20 20 20 20 20 20  Buf-3) ){.      
5550: 20 20 20 20 2a 70 6e 42 75 66 20 3d 20 6e 42 75      *pnBuf = nBu
5560: 66 20 2d 20 33 3b 0a 20 20 20 20 20 20 20 20 7d  f - 3;.        }
5570: 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28  .      }else if(
5580: 20 6e 42 75 66 3e 35 20 26 26 20 30 3d 3d 6d 65   nBuf>5 && 0==me
5590: 6d 63 6d 70 28 22 65 6d 65 6e 74 22 2c 20 26 61  mcmp("ement", &a
55a0: 42 75 66 5b 6e 42 75 66 2d 35 5d 2c 20 35 29 20  Buf[nBuf-5], 5) 
55b0: 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 66  ){.        if( f
55c0: 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 28 61  ts5Porter_MGt1(a
55d0: 42 75 66 2c 20 6e 42 75 66 2d 35 29 20 29 7b 0a  Buf, nBuf-5) ){.
55e0: 20 20 20 20 20 20 20 20 20 20 2a 70 6e 42 75 66            *pnBuf
55f0: 20 3d 20 6e 42 75 66 20 2d 20 35 3b 0a 20 20 20   = nBuf - 5;.   
5600: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c       }.      }el
5610: 73 65 20 69 66 28 20 6e 42 75 66 3e 34 20 26 26  se if( nBuf>4 &&
5620: 20 30 3d 3d 6d 65 6d 63 6d 70 28 22 6d 65 6e 74   0==memcmp("ment
5630: 22 2c 20 26 61 42 75 66 5b 6e 42 75 66 2d 34 5d  ", &aBuf[nBuf-4]
5640: 2c 20 34 29 20 29 7b 0a 20 20 20 20 20 20 20 20  , 4) ){.        
5650: 69 66 28 20 66 74 73 35 50 6f 72 74 65 72 5f 4d  if( fts5Porter_M
5660: 47 74 31 28 61 42 75 66 2c 20 6e 42 75 66 2d 34  Gt1(aBuf, nBuf-4
5670: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 2a  ) ){.          *
5680: 70 6e 42 75 66 20 3d 20 6e 42 75 66 20 2d 20 34  pnBuf = nBuf - 4
5690: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
56a0: 20 20 7d 65 6c 73 65 20 69 66 28 20 6e 42 75 66    }else if( nBuf
56b0: 3e 33 20 26 26 20 30 3d 3d 6d 65 6d 63 6d 70 28  >3 && 0==memcmp(
56c0: 22 65 6e 74 22 2c 20 26 61 42 75 66 5b 6e 42 75  "ent", &aBuf[nBu
56d0: 66 2d 33 5d 2c 20 33 29 20 29 7b 0a 20 20 20 20  f-3], 3) ){.    
56e0: 20 20 20 20 69 66 28 20 66 74 73 35 50 6f 72 74      if( fts5Port
56f0: 65 72 5f 4d 47 74 31 28 61 42 75 66 2c 20 6e 42  er_MGt1(aBuf, nB
5700: 75 66 2d 33 29 20 29 7b 0a 20 20 20 20 20 20 20  uf-3) ){.       
5710: 20 20 20 2a 70 6e 42 75 66 20 3d 20 6e 42 75 66     *pnBuf = nBuf
5720: 20 2d 20 33 3b 0a 20 20 20 20 20 20 20 20 7d 0a   - 3;.        }.
5730: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62 72        }.      br
5740: 65 61 6b 3b 0a 20 20 0a 20 20 20 20 63 61 73 65  eak;.  .    case
5750: 20 27 6f 27 3a 20 0a 20 20 20 20 20 20 69 66 28   'o': .      if(
5760: 20 6e 42 75 66 3e 33 20 26 26 20 30 3d 3d 6d 65   nBuf>3 && 0==me
5770: 6d 63 6d 70 28 22 69 6f 6e 22 2c 20 26 61 42 75  mcmp("ion", &aBu
5780: 66 5b 6e 42 75 66 2d 33 5d 2c 20 33 29 20 29 7b  f[nBuf-3], 3) ){
5790: 0a 20 20 20 20 20 20 20 20 69 66 28 20 66 74 73  .        if( fts
57a0: 35 50 6f 72 74 65 72 5f 4d 47 74 31 5f 61 6e 64  5Porter_MGt1_and
57b0: 5f 53 5f 6f 72 5f 54 28 61 42 75 66 2c 20 6e 42  _S_or_T(aBuf, nB
57c0: 75 66 2d 33 29 20 29 7b 0a 20 20 20 20 20 20 20  uf-3) ){.       
57d0: 20 20 20 2a 70 6e 42 75 66 20 3d 20 6e 42 75 66     *pnBuf = nBuf
57e0: 20 2d 20 33 3b 0a 20 20 20 20 20 20 20 20 7d 0a   - 3;.        }.
57f0: 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
5800: 6e 42 75 66 3e 32 20 26 26 20 30 3d 3d 6d 65 6d  nBuf>2 && 0==mem
5810: 63 6d 70 28 22 6f 75 22 2c 20 26 61 42 75 66 5b  cmp("ou", &aBuf[
5820: 6e 42 75 66 2d 32 5d 2c 20 32 29 20 29 7b 0a 20  nBuf-2], 2) ){. 
5830: 20 20 20 20 20 20 20 69 66 28 20 66 74 73 35 50         if( fts5P
5840: 6f 72 74 65 72 5f 4d 47 74 31 28 61 42 75 66 2c  orter_MGt1(aBuf,
5850: 20 6e 42 75 66 2d 32 29 20 29 7b 0a 20 20 20 20   nBuf-2) ){.    
5860: 20 20 20 20 20 20 2a 70 6e 42 75 66 20 3d 20 6e        *pnBuf = n
5870: 42 75 66 20 2d 20 32 3b 0a 20 20 20 20 20 20 20  Buf - 2;.       
5880: 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20   }.      }.     
5890: 20 62 72 65 61 6b 3b 0a 20 20 0a 20 20 20 20 63   break;.  .    c
58a0: 61 73 65 20 27 73 27 3a 20 0a 20 20 20 20 20 20  ase 's': .      
58b0: 69 66 28 20 6e 42 75 66 3e 33 20 26 26 20 30 3d  if( nBuf>3 && 0=
58c0: 3d 6d 65 6d 63 6d 70 28 22 69 73 6d 22 2c 20 26  =memcmp("ism", &
58d0: 61 42 75 66 5b 6e 42 75 66 2d 33 5d 2c 20 33 29  aBuf[nBuf-3], 3)
58e0: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20   ){.        if( 
58f0: 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 28  fts5Porter_MGt1(
5900: 61 42 75 66 2c 20 6e 42 75 66 2d 33 29 20 29 7b  aBuf, nBuf-3) ){
5910: 0a 20 20 20 20 20 20 20 20 20 20 2a 70 6e 42 75  .          *pnBu
5920: 66 20 3d 20 6e 42 75 66 20 2d 20 33 3b 0a 20 20  f = nBuf - 3;.  
5930: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a        }.      }.
5940: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 0a        break;.  .
5950: 20 20 20 20 63 61 73 65 20 27 74 27 3a 20 0a 20      case 't': . 
5960: 20 20 20 20 20 69 66 28 20 6e 42 75 66 3e 33 20       if( nBuf>3 
5970: 26 26 20 30 3d 3d 6d 65 6d 63 6d 70 28 22 61 74  && 0==memcmp("at
5980: 65 22 2c 20 26 61 42 75 66 5b 6e 42 75 66 2d 33  e", &aBuf[nBuf-3
5990: 5d 2c 20 33 29 20 29 7b 0a 20 20 20 20 20 20 20  ], 3) ){.       
59a0: 20 69 66 28 20 66 74 73 35 50 6f 72 74 65 72 5f   if( fts5Porter_
59b0: 4d 47 74 31 28 61 42 75 66 2c 20 6e 42 75 66 2d  MGt1(aBuf, nBuf-
59c0: 33 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  3) ){.          
59d0: 2a 70 6e 42 75 66 20 3d 20 6e 42 75 66 20 2d 20  *pnBuf = nBuf - 
59e0: 33 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  3;.        }.   
59f0: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 6e 42 75     }else if( nBu
5a00: 66 3e 33 20 26 26 20 30 3d 3d 6d 65 6d 63 6d 70  f>3 && 0==memcmp
5a10: 28 22 69 74 69 22 2c 20 26 61 42 75 66 5b 6e 42  ("iti", &aBuf[nB
5a20: 75 66 2d 33 5d 2c 20 33 29 20 29 7b 0a 20 20 20  uf-3], 3) ){.   
5a30: 20 20 20 20 20 69 66 28 20 66 74 73 35 50 6f 72       if( fts5Por
5a40: 74 65 72 5f 4d 47 74 31 28 61 42 75 66 2c 20 6e  ter_MGt1(aBuf, n
5a50: 42 75 66 2d 33 29 20 29 7b 0a 20 20 20 20 20 20  Buf-3) ){.      
5a60: 20 20 20 20 2a 70 6e 42 75 66 20 3d 20 6e 42 75      *pnBuf = nBu
5a70: 66 20 2d 20 33 3b 0a 20 20 20 20 20 20 20 20 7d  f - 3;.        }
5a80: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62  .      }.      b
5a90: 72 65 61 6b 3b 0a 20 20 0a 20 20 20 20 63 61 73  reak;.  .    cas
5aa0: 65 20 27 75 27 3a 20 0a 20 20 20 20 20 20 69 66  e 'u': .      if
5ab0: 28 20 6e 42 75 66 3e 33 20 26 26 20 30 3d 3d 6d  ( nBuf>3 && 0==m
5ac0: 65 6d 63 6d 70 28 22 6f 75 73 22 2c 20 26 61 42  emcmp("ous", &aB
5ad0: 75 66 5b 6e 42 75 66 2d 33 5d 2c 20 33 29 20 29  uf[nBuf-3], 3) )
5ae0: 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 66 74  {.        if( ft
5af0: 73 35 50 6f 72 74 65 72 5f 4d 47 74 31 28 61 42  s5Porter_MGt1(aB
5b00: 75 66 2c 20 6e 42 75 66 2d 33 29 20 29 7b 0a 20  uf, nBuf-3) ){. 
5b10: 20 20 20 20 20 20 20 20 20 2a 70 6e 42 75 66 20           *pnBuf 
5b20: 3d 20 6e 42 75 66 20 2d 20 33 3b 0a 20 20 20 20  = nBuf - 3;.    
5b30: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20      }.      }.  
5b40: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 0a 20 20      break;.  .  
5b50: 20 20 63 61 73 65 20 27 76 27 3a 20 0a 20 20 20    case 'v': .   
5b60: 20 20 20 69 66 28 20 6e 42 75 66 3e 33 20 26 26     if( nBuf>3 &&
5b70: 20 30 3d 3d 6d 65 6d 63 6d 70 28 22 69 76 65 22   0==memcmp("ive"
5b80: 2c 20 26 61 42 75 66 5b 6e 42 75 66 2d 33 5d 2c  , &aBuf[nBuf-3],
5b90: 20 33 29 20 29 7b 0a 20 20 20 20 20 20 20 20 69   3) ){.        i
5ba0: 66 28 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47  f( fts5Porter_MG
5bb0: 74 31 28 61 42 75 66 2c 20 6e 42 75 66 2d 33 29  t1(aBuf, nBuf-3)
5bc0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 2a 70   ){.          *p
5bd0: 6e 42 75 66 20 3d 20 6e 42 75 66 20 2d 20 33 3b  nBuf = nBuf - 3;
5be0: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
5bf0: 20 7d 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a   }.      break;.
5c00: 20 20 0a 20 20 20 20 63 61 73 65 20 27 7a 27 3a    .    case 'z':
5c10: 20 0a 20 20 20 20 20 20 69 66 28 20 6e 42 75 66   .      if( nBuf
5c20: 3e 33 20 26 26 20 30 3d 3d 6d 65 6d 63 6d 70 28  >3 && 0==memcmp(
5c30: 22 69 7a 65 22 2c 20 26 61 42 75 66 5b 6e 42 75  "ize", &aBuf[nBu
5c40: 66 2d 33 5d 2c 20 33 29 20 29 7b 0a 20 20 20 20  f-3], 3) ){.    
5c50: 20 20 20 20 69 66 28 20 66 74 73 35 50 6f 72 74      if( fts5Port
5c60: 65 72 5f 4d 47 74 31 28 61 42 75 66 2c 20 6e 42  er_MGt1(aBuf, nB
5c70: 75 66 2d 33 29 20 29 7b 0a 20 20 20 20 20 20 20  uf-3) ){.       
5c80: 20 20 20 2a 70 6e 42 75 66 20 3d 20 6e 42 75 66     *pnBuf = nBuf
5c90: 20 2d 20 33 3b 0a 20 20 20 20 20 20 20 20 7d 0a   - 3;.        }.
5ca0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62 72        }.      br
5cb0: 65 61 6b 3b 0a 20 20 0a 20 20 7d 0a 20 20 72 65  eak;.  .  }.  re
5cc0: 74 75 72 6e 20 72 65 74 3b 0a 7d 0a 20 20 0a 0a  turn ret;.}.  ..
5cd0: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 50  static int fts5P
5ce0: 6f 72 74 65 72 53 74 65 70 31 42 32 28 63 68 61  orterStep1B2(cha
5cf0: 72 20 2a 61 42 75 66 2c 20 69 6e 74 20 2a 70 6e  r *aBuf, int *pn
5d00: 42 75 66 29 7b 0a 20 20 69 6e 74 20 72 65 74 20  Buf){.  int ret 
5d10: 3d 20 30 3b 0a 20 20 69 6e 74 20 6e 42 75 66 20  = 0;.  int nBuf 
5d20: 3d 20 2a 70 6e 42 75 66 3b 0a 20 20 73 77 69 74  = *pnBuf;.  swit
5d30: 63 68 28 20 61 42 75 66 5b 6e 42 75 66 2d 32 5d  ch( aBuf[nBuf-2]
5d40: 20 29 7b 0a 20 20 20 20 0a 20 20 20 20 63 61 73   ){.    .    cas
5d50: 65 20 27 61 27 3a 20 0a 20 20 20 20 20 20 69 66  e 'a': .      if
5d60: 28 20 6e 42 75 66 3e 32 20 26 26 20 30 3d 3d 6d  ( nBuf>2 && 0==m
5d70: 65 6d 63 6d 70 28 22 61 74 22 2c 20 26 61 42 75  emcmp("at", &aBu
5d80: 66 5b 6e 42 75 66 2d 32 5d 2c 20 32 29 20 29 7b  f[nBuf-2], 2) ){
5d90: 0a 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28  .        memcpy(
5da0: 26 61 42 75 66 5b 6e 42 75 66 2d 32 5d 2c 20 22  &aBuf[nBuf-2], "
5db0: 61 74 65 22 2c 20 33 29 3b 0a 20 20 20 20 20 20  ate", 3);.      
5dc0: 20 20 2a 70 6e 42 75 66 20 3d 20 6e 42 75 66 20    *pnBuf = nBuf 
5dd0: 2d 20 32 20 2b 20 33 3b 0a 20 20 20 20 20 20 20  - 2 + 3;.       
5de0: 20 72 65 74 20 3d 20 31 3b 0a 20 20 20 20 20 20   ret = 1;.      
5df0: 7d 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  }.      break;. 
5e00: 20 0a 20 20 20 20 63 61 73 65 20 27 62 27 3a 20   .    case 'b': 
5e10: 0a 20 20 20 20 20 20 69 66 28 20 6e 42 75 66 3e  .      if( nBuf>
5e20: 32 20 26 26 20 30 3d 3d 6d 65 6d 63 6d 70 28 22  2 && 0==memcmp("
5e30: 62 6c 22 2c 20 26 61 42 75 66 5b 6e 42 75 66 2d  bl", &aBuf[nBuf-
5e40: 32 5d 2c 20 32 29 20 29 7b 0a 20 20 20 20 20 20  2], 2) ){.      
5e50: 20 20 6d 65 6d 63 70 79 28 26 61 42 75 66 5b 6e    memcpy(&aBuf[n
5e60: 42 75 66 2d 32 5d 2c 20 22 62 6c 65 22 2c 20 33  Buf-2], "ble", 3
5e70: 29 3b 0a 20 20 20 20 20 20 20 20 2a 70 6e 42 75  );.        *pnBu
5e80: 66 20 3d 20 6e 42 75 66 20 2d 20 32 20 2b 20 33  f = nBuf - 2 + 3
5e90: 3b 0a 20 20 20 20 20 20 20 20 72 65 74 20 3d 20  ;.        ret = 
5ea0: 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  1;.      }.     
5eb0: 20 62 72 65 61 6b 3b 0a 20 20 0a 20 20 20 20 63   break;.  .    c
5ec0: 61 73 65 20 27 69 27 3a 20 0a 20 20 20 20 20 20  ase 'i': .      
5ed0: 69 66 28 20 6e 42 75 66 3e 32 20 26 26 20 30 3d  if( nBuf>2 && 0=
5ee0: 3d 6d 65 6d 63 6d 70 28 22 69 7a 22 2c 20 26 61  =memcmp("iz", &a
5ef0: 42 75 66 5b 6e 42 75 66 2d 32 5d 2c 20 32 29 20  Buf[nBuf-2], 2) 
5f00: 29 7b 0a 20 20 20 20 20 20 20 20 6d 65 6d 63 70  ){.        memcp
5f10: 79 28 26 61 42 75 66 5b 6e 42 75 66 2d 32 5d 2c  y(&aBuf[nBuf-2],
5f20: 20 22 69 7a 65 22 2c 20 33 29 3b 0a 20 20 20 20   "ize", 3);.    
5f30: 20 20 20 20 2a 70 6e 42 75 66 20 3d 20 6e 42 75      *pnBuf = nBu
5f40: 66 20 2d 20 32 20 2b 20 33 3b 0a 20 20 20 20 20  f - 2 + 3;.     
5f50: 20 20 20 72 65 74 20 3d 20 31 3b 0a 20 20 20 20     ret = 1;.    
5f60: 20 20 7d 0a 20 20 20 20 20 20 62 72 65 61 6b 3b    }.      break;
5f70: 0a 20 20 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  .  .  }.  return
5f80: 20 72 65 74 3b 0a 7d 0a 20 20 0a 0a 73 74 61 74   ret;.}.  ..stat
5f90: 69 63 20 69 6e 74 20 66 74 73 35 50 6f 72 74 65  ic int fts5Porte
5fa0: 72 53 74 65 70 32 28 63 68 61 72 20 2a 61 42 75  rStep2(char *aBu
5fb0: 66 2c 20 69 6e 74 20 2a 70 6e 42 75 66 29 7b 0a  f, int *pnBuf){.
5fc0: 20 20 69 6e 74 20 72 65 74 20 3d 20 30 3b 0a 20    int ret = 0;. 
5fd0: 20 69 6e 74 20 6e 42 75 66 20 3d 20 2a 70 6e 42   int nBuf = *pnB
5fe0: 75 66 3b 0a 20 20 73 77 69 74 63 68 28 20 61 42  uf;.  switch( aB
5ff0: 75 66 5b 6e 42 75 66 2d 32 5d 20 29 7b 0a 20 20  uf[nBuf-2] ){.  
6000: 20 20 0a 20 20 20 20 63 61 73 65 20 27 61 27 3a    .    case 'a':
6010: 20 0a 20 20 20 20 20 20 69 66 28 20 6e 42 75 66   .      if( nBuf
6020: 3e 37 20 26 26 20 30 3d 3d 6d 65 6d 63 6d 70 28  >7 && 0==memcmp(
6030: 22 61 74 69 6f 6e 61 6c 22 2c 20 26 61 42 75 66  "ational", &aBuf
6040: 5b 6e 42 75 66 2d 37 5d 2c 20 37 29 20 29 7b 0a  [nBuf-7], 7) ){.
6050: 20 20 20 20 20 20 20 20 69 66 28 20 66 74 73 35          if( fts5
6060: 50 6f 72 74 65 72 5f 4d 47 74 30 28 61 42 75 66  Porter_MGt0(aBuf
6070: 2c 20 6e 42 75 66 2d 37 29 20 29 7b 0a 20 20 20  , nBuf-7) ){.   
6080: 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28 26 61         memcpy(&a
6090: 42 75 66 5b 6e 42 75 66 2d 37 5d 2c 20 22 61 74  Buf[nBuf-7], "at
60a0: 65 22 2c 20 33 29 3b 0a 20 20 20 20 20 20 20 20  e", 3);.        
60b0: 20 20 2a 70 6e 42 75 66 20 3d 20 6e 42 75 66 20    *pnBuf = nBuf 
60c0: 2d 20 37 20 2b 20 33 3b 0a 20 20 20 20 20 20 20  - 7 + 3;.       
60d0: 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69   }.      }else i
60e0: 66 28 20 6e 42 75 66 3e 36 20 26 26 20 30 3d 3d  f( nBuf>6 && 0==
60f0: 6d 65 6d 63 6d 70 28 22 74 69 6f 6e 61 6c 22 2c  memcmp("tional",
6100: 20 26 61 42 75 66 5b 6e 42 75 66 2d 36 5d 2c 20   &aBuf[nBuf-6], 
6110: 36 29 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66  6) ){.        if
6120: 28 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74  ( fts5Porter_MGt
6130: 30 28 61 42 75 66 2c 20 6e 42 75 66 2d 36 29 20  0(aBuf, nBuf-6) 
6140: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6d 65 6d  ){.          mem
6150: 63 70 79 28 26 61 42 75 66 5b 6e 42 75 66 2d 36  cpy(&aBuf[nBuf-6
6160: 5d 2c 20 22 74 69 6f 6e 22 2c 20 34 29 3b 0a 20  ], "tion", 4);. 
6170: 20 20 20 20 20 20 20 20 20 2a 70 6e 42 75 66 20           *pnBuf 
6180: 3d 20 6e 42 75 66 20 2d 20 36 20 2b 20 34 3b 0a  = nBuf - 6 + 4;.
6190: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
61a0: 7d 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  }.      break;. 
61b0: 20 0a 20 20 20 20 63 61 73 65 20 27 63 27 3a 20   .    case 'c': 
61c0: 0a 20 20 20 20 20 20 69 66 28 20 6e 42 75 66 3e  .      if( nBuf>
61d0: 34 20 26 26 20 30 3d 3d 6d 65 6d 63 6d 70 28 22  4 && 0==memcmp("
61e0: 65 6e 63 69 22 2c 20 26 61 42 75 66 5b 6e 42 75  enci", &aBuf[nBu
61f0: 66 2d 34 5d 2c 20 34 29 20 29 7b 0a 20 20 20 20  f-4], 4) ){.    
6200: 20 20 20 20 69 66 28 20 66 74 73 35 50 6f 72 74      if( fts5Port
6210: 65 72 5f 4d 47 74 30 28 61 42 75 66 2c 20 6e 42  er_MGt0(aBuf, nB
6220: 75 66 2d 34 29 20 29 7b 0a 20 20 20 20 20 20 20  uf-4) ){.       
6230: 20 20 20 6d 65 6d 63 70 79 28 26 61 42 75 66 5b     memcpy(&aBuf[
6240: 6e 42 75 66 2d 34 5d 2c 20 22 65 6e 63 65 22 2c  nBuf-4], "ence",
6250: 20 34 29 3b 0a 20 20 20 20 20 20 20 20 20 20 2a   4);.          *
6260: 70 6e 42 75 66 20 3d 20 6e 42 75 66 20 2d 20 34  pnBuf = nBuf - 4
6270: 20 2b 20 34 3b 0a 20 20 20 20 20 20 20 20 7d 0a   + 4;.        }.
6280: 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
6290: 6e 42 75 66 3e 34 20 26 26 20 30 3d 3d 6d 65 6d  nBuf>4 && 0==mem
62a0: 63 6d 70 28 22 61 6e 63 69 22 2c 20 26 61 42 75  cmp("anci", &aBu
62b0: 66 5b 6e 42 75 66 2d 34 5d 2c 20 34 29 20 29 7b  f[nBuf-4], 4) ){
62c0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 66 74 73  .        if( fts
62d0: 35 50 6f 72 74 65 72 5f 4d 47 74 30 28 61 42 75  5Porter_MGt0(aBu
62e0: 66 2c 20 6e 42 75 66 2d 34 29 20 29 7b 0a 20 20  f, nBuf-4) ){.  
62f0: 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28 26          memcpy(&
6300: 61 42 75 66 5b 6e 42 75 66 2d 34 5d 2c 20 22 61  aBuf[nBuf-4], "a
6310: 6e 63 65 22 2c 20 34 29 3b 0a 20 20 20 20 20 20  nce", 4);.      
6320: 20 20 20 20 2a 70 6e 42 75 66 20 3d 20 6e 42 75      *pnBuf = nBu
6330: 66 20 2d 20 34 20 2b 20 34 3b 0a 20 20 20 20 20  f - 4 + 4;.     
6340: 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20     }.      }.   
6350: 20 20 20 62 72 65 61 6b 3b 0a 20 20 0a 20 20 20     break;.  .   
6360: 20 63 61 73 65 20 27 65 27 3a 20 0a 20 20 20 20   case 'e': .    
6370: 20 20 69 66 28 20 6e 42 75 66 3e 34 20 26 26 20    if( nBuf>4 && 
6380: 30 3d 3d 6d 65 6d 63 6d 70 28 22 69 7a 65 72 22  0==memcmp("izer"
6390: 2c 20 26 61 42 75 66 5b 6e 42 75 66 2d 34 5d 2c  , &aBuf[nBuf-4],
63a0: 20 34 29 20 29 7b 0a 20 20 20 20 20 20 20 20 69   4) ){.        i
63b0: 66 28 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47  f( fts5Porter_MG
63c0: 74 30 28 61 42 75 66 2c 20 6e 42 75 66 2d 34 29  t0(aBuf, nBuf-4)
63d0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6d 65   ){.          me
63e0: 6d 63 70 79 28 26 61 42 75 66 5b 6e 42 75 66 2d  mcpy(&aBuf[nBuf-
63f0: 34 5d 2c 20 22 69 7a 65 22 2c 20 33 29 3b 0a 20  4], "ize", 3);. 
6400: 20 20 20 20 20 20 20 20 20 2a 70 6e 42 75 66 20           *pnBuf 
6410: 3d 20 6e 42 75 66 20 2d 20 34 20 2b 20 33 3b 0a  = nBuf - 4 + 3;.
6420: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
6430: 7d 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  }.      break;. 
6440: 20 0a 20 20 20 20 63 61 73 65 20 27 67 27 3a 20   .    case 'g': 
6450: 0a 20 20 20 20 20 20 69 66 28 20 6e 42 75 66 3e  .      if( nBuf>
6460: 34 20 26 26 20 30 3d 3d 6d 65 6d 63 6d 70 28 22  4 && 0==memcmp("
6470: 6c 6f 67 69 22 2c 20 26 61 42 75 66 5b 6e 42 75  logi", &aBuf[nBu
6480: 66 2d 34 5d 2c 20 34 29 20 29 7b 0a 20 20 20 20  f-4], 4) ){.    
6490: 20 20 20 20 69 66 28 20 66 74 73 35 50 6f 72 74      if( fts5Port
64a0: 65 72 5f 4d 47 74 30 28 61 42 75 66 2c 20 6e 42  er_MGt0(aBuf, nB
64b0: 75 66 2d 34 29 20 29 7b 0a 20 20 20 20 20 20 20  uf-4) ){.       
64c0: 20 20 20 6d 65 6d 63 70 79 28 26 61 42 75 66 5b     memcpy(&aBuf[
64d0: 6e 42 75 66 2d 34 5d 2c 20 22 6c 6f 67 22 2c 20  nBuf-4], "log", 
64e0: 33 29 3b 0a 20 20 20 20 20 20 20 20 20 20 2a 70  3);.          *p
64f0: 6e 42 75 66 20 3d 20 6e 42 75 66 20 2d 20 34 20  nBuf = nBuf - 4 
6500: 2b 20 33 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  + 3;.        }. 
6510: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62 72 65       }.      bre
6520: 61 6b 3b 0a 20 20 0a 20 20 20 20 63 61 73 65 20  ak;.  .    case 
6530: 27 6c 27 3a 20 0a 20 20 20 20 20 20 69 66 28 20  'l': .      if( 
6540: 6e 42 75 66 3e 33 20 26 26 20 30 3d 3d 6d 65 6d  nBuf>3 && 0==mem
6550: 63 6d 70 28 22 62 6c 69 22 2c 20 26 61 42 75 66  cmp("bli", &aBuf
6560: 5b 6e 42 75 66 2d 33 5d 2c 20 33 29 20 29 7b 0a  [nBuf-3], 3) ){.
6570: 20 20 20 20 20 20 20 20 69 66 28 20 66 74 73 35          if( fts5
6580: 50 6f 72 74 65 72 5f 4d 47 74 30 28 61 42 75 66  Porter_MGt0(aBuf
6590: 2c 20 6e 42 75 66 2d 33 29 20 29 7b 0a 20 20 20  , nBuf-3) ){.   
65a0: 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28 26 61         memcpy(&a
65b0: 42 75 66 5b 6e 42 75 66 2d 33 5d 2c 20 22 62 6c  Buf[nBuf-3], "bl
65c0: 65 22 2c 20 33 29 3b 0a 20 20 20 20 20 20 20 20  e", 3);.        
65d0: 20 20 2a 70 6e 42 75 66 20 3d 20 6e 42 75 66 20    *pnBuf = nBuf 
65e0: 2d 20 33 20 2b 20 33 3b 0a 20 20 20 20 20 20 20  - 3 + 3;.       
65f0: 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69   }.      }else i
6600: 66 28 20 6e 42 75 66 3e 34 20 26 26 20 30 3d 3d  f( nBuf>4 && 0==
6610: 6d 65 6d 63 6d 70 28 22 61 6c 6c 69 22 2c 20 26  memcmp("alli", &
6620: 61 42 75 66 5b 6e 42 75 66 2d 34 5d 2c 20 34 29  aBuf[nBuf-4], 4)
6630: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20   ){.        if( 
6640: 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 28  fts5Porter_MGt0(
6650: 61 42 75 66 2c 20 6e 42 75 66 2d 34 29 20 29 7b  aBuf, nBuf-4) ){
6660: 0a 20 20 20 20 20 20 20 20 20 20 6d 65 6d 63 70  .          memcp
6670: 79 28 26 61 42 75 66 5b 6e 42 75 66 2d 34 5d 2c  y(&aBuf[nBuf-4],
6680: 20 22 61 6c 22 2c 20 32 29 3b 0a 20 20 20 20 20   "al", 2);.     
6690: 20 20 20 20 20 2a 70 6e 42 75 66 20 3d 20 6e 42       *pnBuf = nB
66a0: 75 66 20 2d 20 34 20 2b 20 32 3b 0a 20 20 20 20  uf - 4 + 2;.    
66b0: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73      }.      }els
66c0: 65 20 69 66 28 20 6e 42 75 66 3e 35 20 26 26 20  e if( nBuf>5 && 
66d0: 30 3d 3d 6d 65 6d 63 6d 70 28 22 65 6e 74 6c 69  0==memcmp("entli
66e0: 22 2c 20 26 61 42 75 66 5b 6e 42 75 66 2d 35 5d  ", &aBuf[nBuf-5]
66f0: 2c 20 35 29 20 29 7b 0a 20 20 20 20 20 20 20 20  , 5) ){.        
6700: 69 66 28 20 66 74 73 35 50 6f 72 74 65 72 5f 4d  if( fts5Porter_M
6710: 47 74 30 28 61 42 75 66 2c 20 6e 42 75 66 2d 35  Gt0(aBuf, nBuf-5
6720: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6d  ) ){.          m
6730: 65 6d 63 70 79 28 26 61 42 75 66 5b 6e 42 75 66  emcpy(&aBuf[nBuf
6740: 2d 35 5d 2c 20 22 65 6e 74 22 2c 20 33 29 3b 0a  -5], "ent", 3);.
6750: 20 20 20 20 20 20 20 20 20 20 2a 70 6e 42 75 66            *pnBuf
6760: 20 3d 20 6e 42 75 66 20 2d 20 35 20 2b 20 33 3b   = nBuf - 5 + 3;
6770: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
6780: 20 7d 65 6c 73 65 20 69 66 28 20 6e 42 75 66 3e   }else if( nBuf>
6790: 33 20 26 26 20 30 3d 3d 6d 65 6d 63 6d 70 28 22  3 && 0==memcmp("
67a0: 65 6c 69 22 2c 20 26 61 42 75 66 5b 6e 42 75 66  eli", &aBuf[nBuf
67b0: 2d 33 5d 2c 20 33 29 20 29 7b 0a 20 20 20 20 20  -3], 3) ){.     
67c0: 20 20 20 69 66 28 20 66 74 73 35 50 6f 72 74 65     if( fts5Porte
67d0: 72 5f 4d 47 74 30 28 61 42 75 66 2c 20 6e 42 75  r_MGt0(aBuf, nBu
67e0: 66 2d 33 29 20 29 7b 0a 20 20 20 20 20 20 20 20  f-3) ){.        
67f0: 20 20 6d 65 6d 63 70 79 28 26 61 42 75 66 5b 6e    memcpy(&aBuf[n
6800: 42 75 66 2d 33 5d 2c 20 22 65 22 2c 20 31 29 3b  Buf-3], "e", 1);
6810: 0a 20 20 20 20 20 20 20 20 20 20 2a 70 6e 42 75  .          *pnBu
6820: 66 20 3d 20 6e 42 75 66 20 2d 20 33 20 2b 20 31  f = nBuf - 3 + 1
6830: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
6840: 20 20 7d 65 6c 73 65 20 69 66 28 20 6e 42 75 66    }else if( nBuf
6850: 3e 35 20 26 26 20 30 3d 3d 6d 65 6d 63 6d 70 28  >5 && 0==memcmp(
6860: 22 6f 75 73 6c 69 22 2c 20 26 61 42 75 66 5b 6e  "ousli", &aBuf[n
6870: 42 75 66 2d 35 5d 2c 20 35 29 20 29 7b 0a 20 20  Buf-5], 5) ){.  
6880: 20 20 20 20 20 20 69 66 28 20 66 74 73 35 50 6f        if( fts5Po
6890: 72 74 65 72 5f 4d 47 74 30 28 61 42 75 66 2c 20  rter_MGt0(aBuf, 
68a0: 6e 42 75 66 2d 35 29 20 29 7b 0a 20 20 20 20 20  nBuf-5) ){.     
68b0: 20 20 20 20 20 6d 65 6d 63 70 79 28 26 61 42 75       memcpy(&aBu
68c0: 66 5b 6e 42 75 66 2d 35 5d 2c 20 22 6f 75 73 22  f[nBuf-5], "ous"
68d0: 2c 20 33 29 3b 0a 20 20 20 20 20 20 20 20 20 20  , 3);.          
68e0: 2a 70 6e 42 75 66 20 3d 20 6e 42 75 66 20 2d 20  *pnBuf = nBuf - 
68f0: 35 20 2b 20 33 3b 0a 20 20 20 20 20 20 20 20 7d  5 + 3;.        }
6900: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62  .      }.      b
6910: 72 65 61 6b 3b 0a 20 20 0a 20 20 20 20 63 61 73  reak;.  .    cas
6920: 65 20 27 6f 27 3a 20 0a 20 20 20 20 20 20 69 66  e 'o': .      if
6930: 28 20 6e 42 75 66 3e 37 20 26 26 20 30 3d 3d 6d  ( nBuf>7 && 0==m
6940: 65 6d 63 6d 70 28 22 69 7a 61 74 69 6f 6e 22 2c  emcmp("ization",
6950: 20 26 61 42 75 66 5b 6e 42 75 66 2d 37 5d 2c 20   &aBuf[nBuf-7], 
6960: 37 29 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66  7) ){.        if
6970: 28 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74  ( fts5Porter_MGt
6980: 30 28 61 42 75 66 2c 20 6e 42 75 66 2d 37 29 20  0(aBuf, nBuf-7) 
6990: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6d 65 6d  ){.          mem
69a0: 63 70 79 28 26 61 42 75 66 5b 6e 42 75 66 2d 37  cpy(&aBuf[nBuf-7
69b0: 5d 2c 20 22 69 7a 65 22 2c 20 33 29 3b 0a 20 20  ], "ize", 3);.  
69c0: 20 20 20 20 20 20 20 20 2a 70 6e 42 75 66 20 3d          *pnBuf =
69d0: 20 6e 42 75 66 20 2d 20 37 20 2b 20 33 3b 0a 20   nBuf - 7 + 3;. 
69e0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
69f0: 65 6c 73 65 20 69 66 28 20 6e 42 75 66 3e 35 20  else if( nBuf>5 
6a00: 26 26 20 30 3d 3d 6d 65 6d 63 6d 70 28 22 61 74  && 0==memcmp("at
6a10: 69 6f 6e 22 2c 20 26 61 42 75 66 5b 6e 42 75 66  ion", &aBuf[nBuf
6a20: 2d 35 5d 2c 20 35 29 20 29 7b 0a 20 20 20 20 20  -5], 5) ){.     
6a30: 20 20 20 69 66 28 20 66 74 73 35 50 6f 72 74 65     if( fts5Porte
6a40: 72 5f 4d 47 74 30 28 61 42 75 66 2c 20 6e 42 75  r_MGt0(aBuf, nBu
6a50: 66 2d 35 29 20 29 7b 0a 20 20 20 20 20 20 20 20  f-5) ){.        
6a60: 20 20 6d 65 6d 63 70 79 28 26 61 42 75 66 5b 6e    memcpy(&aBuf[n
6a70: 42 75 66 2d 35 5d 2c 20 22 61 74 65 22 2c 20 33  Buf-5], "ate", 3
6a80: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 2a 70 6e  );.          *pn
6a90: 42 75 66 20 3d 20 6e 42 75 66 20 2d 20 35 20 2b  Buf = nBuf - 5 +
6aa0: 20 33 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20   3;.        }.  
6ab0: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 6e 42      }else if( nB
6ac0: 75 66 3e 34 20 26 26 20 30 3d 3d 6d 65 6d 63 6d  uf>4 && 0==memcm
6ad0: 70 28 22 61 74 6f 72 22 2c 20 26 61 42 75 66 5b  p("ator", &aBuf[
6ae0: 6e 42 75 66 2d 34 5d 2c 20 34 29 20 29 7b 0a 20  nBuf-4], 4) ){. 
6af0: 20 20 20 20 20 20 20 69 66 28 20 66 74 73 35 50         if( fts5P
6b00: 6f 72 74 65 72 5f 4d 47 74 30 28 61 42 75 66 2c  orter_MGt0(aBuf,
6b10: 20 6e 42 75 66 2d 34 29 20 29 7b 0a 20 20 20 20   nBuf-4) ){.    
6b20: 20 20 20 20 20 20 6d 65 6d 63 70 79 28 26 61 42        memcpy(&aB
6b30: 75 66 5b 6e 42 75 66 2d 34 5d 2c 20 22 61 74 65  uf[nBuf-4], "ate
6b40: 22 2c 20 33 29 3b 0a 20 20 20 20 20 20 20 20 20  ", 3);.         
6b50: 20 2a 70 6e 42 75 66 20 3d 20 6e 42 75 66 20 2d   *pnBuf = nBuf -
6b60: 20 34 20 2b 20 33 3b 0a 20 20 20 20 20 20 20 20   4 + 3;.        
6b70: 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  }.      }.      
6b80: 62 72 65 61 6b 3b 0a 20 20 0a 20 20 20 20 63 61  break;.  .    ca
6b90: 73 65 20 27 73 27 3a 20 0a 20 20 20 20 20 20 69  se 's': .      i
6ba0: 66 28 20 6e 42 75 66 3e 35 20 26 26 20 30 3d 3d  f( nBuf>5 && 0==
6bb0: 6d 65 6d 63 6d 70 28 22 61 6c 69 73 6d 22 2c 20  memcmp("alism", 
6bc0: 26 61 42 75 66 5b 6e 42 75 66 2d 35 5d 2c 20 35  &aBuf[nBuf-5], 5
6bd0: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28  ) ){.        if(
6be0: 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30   fts5Porter_MGt0
6bf0: 28 61 42 75 66 2c 20 6e 42 75 66 2d 35 29 20 29  (aBuf, nBuf-5) )
6c00: 7b 0a 20 20 20 20 20 20 20 20 20 20 6d 65 6d 63  {.          memc
6c10: 70 79 28 26 61 42 75 66 5b 6e 42 75 66 2d 35 5d  py(&aBuf[nBuf-5]
6c20: 2c 20 22 61 6c 22 2c 20 32 29 3b 0a 20 20 20 20  , "al", 2);.    
6c30: 20 20 20 20 20 20 2a 70 6e 42 75 66 20 3d 20 6e        *pnBuf = n
6c40: 42 75 66 20 2d 20 35 20 2b 20 32 3b 0a 20 20 20  Buf - 5 + 2;.   
6c50: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c       }.      }el
6c60: 73 65 20 69 66 28 20 6e 42 75 66 3e 37 20 26 26  se if( nBuf>7 &&
6c70: 20 30 3d 3d 6d 65 6d 63 6d 70 28 22 69 76 65 6e   0==memcmp("iven
6c80: 65 73 73 22 2c 20 26 61 42 75 66 5b 6e 42 75 66  ess", &aBuf[nBuf
6c90: 2d 37 5d 2c 20 37 29 20 29 7b 0a 20 20 20 20 20  -7], 7) ){.     
6ca0: 20 20 20 69 66 28 20 66 74 73 35 50 6f 72 74 65     if( fts5Porte
6cb0: 72 5f 4d 47 74 30 28 61 42 75 66 2c 20 6e 42 75  r_MGt0(aBuf, nBu
6cc0: 66 2d 37 29 20 29 7b 0a 20 20 20 20 20 20 20 20  f-7) ){.        
6cd0: 20 20 6d 65 6d 63 70 79 28 26 61 42 75 66 5b 6e    memcpy(&aBuf[n
6ce0: 42 75 66 2d 37 5d 2c 20 22 69 76 65 22 2c 20 33  Buf-7], "ive", 3
6cf0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 2a 70 6e  );.          *pn
6d00: 42 75 66 20 3d 20 6e 42 75 66 20 2d 20 37 20 2b  Buf = nBuf - 7 +
6d10: 20 33 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20   3;.        }.  
6d20: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 6e 42      }else if( nB
6d30: 75 66 3e 37 20 26 26 20 30 3d 3d 6d 65 6d 63 6d  uf>7 && 0==memcm
6d40: 70 28 22 66 75 6c 6e 65 73 73 22 2c 20 26 61 42  p("fulness", &aB
6d50: 75 66 5b 6e 42 75 66 2d 37 5d 2c 20 37 29 20 29  uf[nBuf-7], 7) )
6d60: 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 66 74  {.        if( ft
6d70: 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 28 61 42  s5Porter_MGt0(aB
6d80: 75 66 2c 20 6e 42 75 66 2d 37 29 20 29 7b 0a 20  uf, nBuf-7) ){. 
6d90: 20 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28           memcpy(
6da0: 26 61 42 75 66 5b 6e 42 75 66 2d 37 5d 2c 20 22  &aBuf[nBuf-7], "
6db0: 66 75 6c 22 2c 20 33 29 3b 0a 20 20 20 20 20 20  ful", 3);.      
6dc0: 20 20 20 20 2a 70 6e 42 75 66 20 3d 20 6e 42 75      *pnBuf = nBu
6dd0: 66 20 2d 20 37 20 2b 20 33 3b 0a 20 20 20 20 20  f - 7 + 3;.     
6de0: 20 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73 65     }.      }else
6df0: 20 69 66 28 20 6e 42 75 66 3e 37 20 26 26 20 30   if( nBuf>7 && 0
6e00: 3d 3d 6d 65 6d 63 6d 70 28 22 6f 75 73 6e 65 73  ==memcmp("ousnes
6e10: 73 22 2c 20 26 61 42 75 66 5b 6e 42 75 66 2d 37  s", &aBuf[nBuf-7
6e20: 5d 2c 20 37 29 20 29 7b 0a 20 20 20 20 20 20 20  ], 7) ){.       
6e30: 20 69 66 28 20 66 74 73 35 50 6f 72 74 65 72 5f   if( fts5Porter_
6e40: 4d 47 74 30 28 61 42 75 66 2c 20 6e 42 75 66 2d  MGt0(aBuf, nBuf-
6e50: 37 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  7) ){.          
6e60: 6d 65 6d 63 70 79 28 26 61 42 75 66 5b 6e 42 75  memcpy(&aBuf[nBu
6e70: 66 2d 37 5d 2c 20 22 6f 75 73 22 2c 20 33 29 3b  f-7], "ous", 3);
6e80: 0a 20 20 20 20 20 20 20 20 20 20 2a 70 6e 42 75  .          *pnBu
6e90: 66 20 3d 20 6e 42 75 66 20 2d 20 37 20 2b 20 33  f = nBuf - 7 + 3
6ea0: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
6eb0: 20 20 7d 0a 20 20 20 20 20 20 62 72 65 61 6b 3b    }.      break;
6ec0: 0a 20 20 0a 20 20 20 20 63 61 73 65 20 27 74 27  .  .    case 't'
6ed0: 3a 20 0a 20 20 20 20 20 20 69 66 28 20 6e 42 75  : .      if( nBu
6ee0: 66 3e 35 20 26 26 20 30 3d 3d 6d 65 6d 63 6d 70  f>5 && 0==memcmp
6ef0: 28 22 61 6c 69 74 69 22 2c 20 26 61 42 75 66 5b  ("aliti", &aBuf[
6f00: 6e 42 75 66 2d 35 5d 2c 20 35 29 20 29 7b 0a 20  nBuf-5], 5) ){. 
6f10: 20 20 20 20 20 20 20 69 66 28 20 66 74 73 35 50         if( fts5P
6f20: 6f 72 74 65 72 5f 4d 47 74 30 28 61 42 75 66 2c  orter_MGt0(aBuf,
6f30: 20 6e 42 75 66 2d 35 29 20 29 7b 0a 20 20 20 20   nBuf-5) ){.    
6f40: 20 20 20 20 20 20 6d 65 6d 63 70 79 28 26 61 42        memcpy(&aB
6f50: 75 66 5b 6e 42 75 66 2d 35 5d 2c 20 22 61 6c 22  uf[nBuf-5], "al"
6f60: 2c 20 32 29 3b 0a 20 20 20 20 20 20 20 20 20 20  , 2);.          
6f70: 2a 70 6e 42 75 66 20 3d 20 6e 42 75 66 20 2d 20  *pnBuf = nBuf - 
6f80: 35 20 2b 20 32 3b 0a 20 20 20 20 20 20 20 20 7d  5 + 2;.        }
6f90: 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28  .      }else if(
6fa0: 20 6e 42 75 66 3e 35 20 26 26 20 30 3d 3d 6d 65   nBuf>5 && 0==me
6fb0: 6d 63 6d 70 28 22 69 76 69 74 69 22 2c 20 26 61  mcmp("iviti", &a
6fc0: 42 75 66 5b 6e 42 75 66 2d 35 5d 2c 20 35 29 20  Buf[nBuf-5], 5) 
6fd0: 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 66  ){.        if( f
6fe0: 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 30 28 61  ts5Porter_MGt0(a
6ff0: 42 75 66 2c 20 6e 42 75 66 2d 35 29 20 29 7b 0a  Buf, nBuf-5) ){.
7000: 20 20 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79            memcpy
7010: 28 26 61 42 75 66 5b 6e 42 75 66 2d 35 5d 2c 20  (&aBuf[nBuf-5], 
7020: 22 69 76 65 22 2c 20 33 29 3b 0a 20 20 20 20 20  "ive", 3);.     
7030: 20 20 20 20 20 2a 70 6e 42 75 66 20 3d 20 6e 42       *pnBuf = nB
7040: 75 66 20 2d 20 35 20 2b 20 33 3b 0a 20 20 20 20  uf - 5 + 3;.    
7050: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73      }.      }els
7060: 65 20 69 66 28 20 6e 42 75 66 3e 36 20 26 26 20  e if( nBuf>6 && 
7070: 30 3d 3d 6d 65 6d 63 6d 70 28 22 62 69 6c 69 74  0==memcmp("bilit
7080: 69 22 2c 20 26 61 42 75 66 5b 6e 42 75 66 2d 36  i", &aBuf[nBuf-6
7090: 5d 2c 20 36 29 20 29 7b 0a 20 20 20 20 20 20 20  ], 6) ){.       
70a0: 20 69 66 28 20 66 74 73 35 50 6f 72 74 65 72 5f   if( fts5Porter_
70b0: 4d 47 74 30 28 61 42 75 66 2c 20 6e 42 75 66 2d  MGt0(aBuf, nBuf-
70c0: 36 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  6) ){.          
70d0: 6d 65 6d 63 70 79 28 26 61 42 75 66 5b 6e 42 75  memcpy(&aBuf[nBu
70e0: 66 2d 36 5d 2c 20 22 62 6c 65 22 2c 20 33 29 3b  f-6], "ble", 3);
70f0: 0a 20 20 20 20 20 20 20 20 20 20 2a 70 6e 42 75  .          *pnBu
7100: 66 20 3d 20 6e 42 75 66 20 2d 20 36 20 2b 20 33  f = nBuf - 6 + 3
7110: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
7120: 20 20 7d 0a 20 20 20 20 20 20 62 72 65 61 6b 3b    }.      break;
7130: 0a 20 20 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  .  .  }.  return
7140: 20 72 65 74 3b 0a 7d 0a 20 20 0a 0a 73 74 61 74   ret;.}.  ..stat
7150: 69 63 20 69 6e 74 20 66 74 73 35 50 6f 72 74 65  ic int fts5Porte
7160: 72 53 74 65 70 33 28 63 68 61 72 20 2a 61 42 75  rStep3(char *aBu
7170: 66 2c 20 69 6e 74 20 2a 70 6e 42 75 66 29 7b 0a  f, int *pnBuf){.
7180: 20 20 69 6e 74 20 72 65 74 20 3d 20 30 3b 0a 20    int ret = 0;. 
7190: 20 69 6e 74 20 6e 42 75 66 20 3d 20 2a 70 6e 42   int nBuf = *pnB
71a0: 75 66 3b 0a 20 20 73 77 69 74 63 68 28 20 61 42  uf;.  switch( aB
71b0: 75 66 5b 6e 42 75 66 2d 32 5d 20 29 7b 0a 20 20  uf[nBuf-2] ){.  
71c0: 20 20 0a 20 20 20 20 63 61 73 65 20 27 61 27 3a    .    case 'a':
71d0: 20 0a 20 20 20 20 20 20 69 66 28 20 6e 42 75 66   .      if( nBuf
71e0: 3e 34 20 26 26 20 30 3d 3d 6d 65 6d 63 6d 70 28  >4 && 0==memcmp(
71f0: 22 69 63 61 6c 22 2c 20 26 61 42 75 66 5b 6e 42  "ical", &aBuf[nB
7200: 75 66 2d 34 5d 2c 20 34 29 20 29 7b 0a 20 20 20  uf-4], 4) ){.   
7210: 20 20 20 20 20 69 66 28 20 66 74 73 35 50 6f 72       if( fts5Por
7220: 74 65 72 5f 4d 47 74 30 28 61 42 75 66 2c 20 6e  ter_MGt0(aBuf, n
7230: 42 75 66 2d 34 29 20 29 7b 0a 20 20 20 20 20 20  Buf-4) ){.      
7240: 20 20 20 20 6d 65 6d 63 70 79 28 26 61 42 75 66      memcpy(&aBuf
7250: 5b 6e 42 75 66 2d 34 5d 2c 20 22 69 63 22 2c 20  [nBuf-4], "ic", 
7260: 32 29 3b 0a 20 20 20 20 20 20 20 20 20 20 2a 70  2);.          *p
7270: 6e 42 75 66 20 3d 20 6e 42 75 66 20 2d 20 34 20  nBuf = nBuf - 4 
7280: 2b 20 32 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  + 2;.        }. 
7290: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62 72 65       }.      bre
72a0: 61 6b 3b 0a 20 20 0a 20 20 20 20 63 61 73 65 20  ak;.  .    case 
72b0: 27 73 27 3a 20 0a 20 20 20 20 20 20 69 66 28 20  's': .      if( 
72c0: 6e 42 75 66 3e 34 20 26 26 20 30 3d 3d 6d 65 6d  nBuf>4 && 0==mem
72d0: 63 6d 70 28 22 6e 65 73 73 22 2c 20 26 61 42 75  cmp("ness", &aBu
72e0: 66 5b 6e 42 75 66 2d 34 5d 2c 20 34 29 20 29 7b  f[nBuf-4], 4) ){
72f0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 66 74 73  .        if( fts
7300: 35 50 6f 72 74 65 72 5f 4d 47 74 30 28 61 42 75  5Porter_MGt0(aBu
7310: 66 2c 20 6e 42 75 66 2d 34 29 20 29 7b 0a 20 20  f, nBuf-4) ){.  
7320: 20 20 20 20 20 20 20 20 2a 70 6e 42 75 66 20 3d          *pnBuf =
7330: 20 6e 42 75 66 20 2d 20 34 3b 0a 20 20 20 20 20   nBuf - 4;.     
7340: 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20     }.      }.   
7350: 20 20 20 62 72 65 61 6b 3b 0a 20 20 0a 20 20 20     break;.  .   
7360: 20 63 61 73 65 20 27 74 27 3a 20 0a 20 20 20 20   case 't': .    
7370: 20 20 69 66 28 20 6e 42 75 66 3e 35 20 26 26 20    if( nBuf>5 && 
7380: 30 3d 3d 6d 65 6d 63 6d 70 28 22 69 63 61 74 65  0==memcmp("icate
7390: 22 2c 20 26 61 42 75 66 5b 6e 42 75 66 2d 35 5d  ", &aBuf[nBuf-5]
73a0: 2c 20 35 29 20 29 7b 0a 20 20 20 20 20 20 20 20  , 5) ){.        
73b0: 69 66 28 20 66 74 73 35 50 6f 72 74 65 72 5f 4d  if( fts5Porter_M
73c0: 47 74 30 28 61 42 75 66 2c 20 6e 42 75 66 2d 35  Gt0(aBuf, nBuf-5
73d0: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6d  ) ){.          m
73e0: 65 6d 63 70 79 28 26 61 42 75 66 5b 6e 42 75 66  emcpy(&aBuf[nBuf
73f0: 2d 35 5d 2c 20 22 69 63 22 2c 20 32 29 3b 0a 20  -5], "ic", 2);. 
7400: 20 20 20 20 20 20 20 20 20 2a 70 6e 42 75 66 20           *pnBuf 
7410: 3d 20 6e 42 75 66 20 2d 20 35 20 2b 20 32 3b 0a  = nBuf - 5 + 2;.
7420: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
7430: 7d 65 6c 73 65 20 69 66 28 20 6e 42 75 66 3e 35  }else if( nBuf>5
7440: 20 26 26 20 30 3d 3d 6d 65 6d 63 6d 70 28 22 69   && 0==memcmp("i
7450: 63 69 74 69 22 2c 20 26 61 42 75 66 5b 6e 42 75  citi", &aBuf[nBu
7460: 66 2d 35 5d 2c 20 35 29 20 29 7b 0a 20 20 20 20  f-5], 5) ){.    
7470: 20 20 20 20 69 66 28 20 66 74 73 35 50 6f 72 74      if( fts5Port
7480: 65 72 5f 4d 47 74 30 28 61 42 75 66 2c 20 6e 42  er_MGt0(aBuf, nB
7490: 75 66 2d 35 29 20 29 7b 0a 20 20 20 20 20 20 20  uf-5) ){.       
74a0: 20 20 20 6d 65 6d 63 70 79 28 26 61 42 75 66 5b     memcpy(&aBuf[
74b0: 6e 42 75 66 2d 35 5d 2c 20 22 69 63 22 2c 20 32  nBuf-5], "ic", 2
74c0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 2a 70 6e  );.          *pn
74d0: 42 75 66 20 3d 20 6e 42 75 66 20 2d 20 35 20 2b  Buf = nBuf - 5 +
74e0: 20 32 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20   2;.        }.  
74f0: 20 20 20 20 7d 0a 20 20 20 20 20 20 62 72 65 61      }.      brea
7500: 6b 3b 0a 20 20 0a 20 20 20 20 63 61 73 65 20 27  k;.  .    case '
7510: 75 27 3a 20 0a 20 20 20 20 20 20 69 66 28 20 6e  u': .      if( n
7520: 42 75 66 3e 33 20 26 26 20 30 3d 3d 6d 65 6d 63  Buf>3 && 0==memc
7530: 6d 70 28 22 66 75 6c 22 2c 20 26 61 42 75 66 5b  mp("ful", &aBuf[
7540: 6e 42 75 66 2d 33 5d 2c 20 33 29 20 29 7b 0a 20  nBuf-3], 3) ){. 
7550: 20 20 20 20 20 20 20 69 66 28 20 66 74 73 35 50         if( fts5P
7560: 6f 72 74 65 72 5f 4d 47 74 30 28 61 42 75 66 2c  orter_MGt0(aBuf,
7570: 20 6e 42 75 66 2d 33 29 20 29 7b 0a 20 20 20 20   nBuf-3) ){.    
7580: 20 20 20 20 20 20 2a 70 6e 42 75 66 20 3d 20 6e        *pnBuf = n
7590: 42 75 66 20 2d 20 33 3b 0a 20 20 20 20 20 20 20  Buf - 3;.       
75a0: 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20   }.      }.     
75b0: 20 62 72 65 61 6b 3b 0a 20 20 0a 20 20 20 20 63   break;.  .    c
75c0: 61 73 65 20 27 76 27 3a 20 0a 20 20 20 20 20 20  ase 'v': .      
75d0: 69 66 28 20 6e 42 75 66 3e 35 20 26 26 20 30 3d  if( nBuf>5 && 0=
75e0: 3d 6d 65 6d 63 6d 70 28 22 61 74 69 76 65 22 2c  =memcmp("ative",
75f0: 20 26 61 42 75 66 5b 6e 42 75 66 2d 35 5d 2c 20   &aBuf[nBuf-5], 
7600: 35 29 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66  5) ){.        if
7610: 28 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74  ( fts5Porter_MGt
7620: 30 28 61 42 75 66 2c 20 6e 42 75 66 2d 35 29 20  0(aBuf, nBuf-5) 
7630: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 2a 70 6e  ){.          *pn
7640: 42 75 66 20 3d 20 6e 42 75 66 20 2d 20 35 3b 0a  Buf = nBuf - 5;.
7650: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
7660: 7d 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  }.      break;. 
7670: 20 0a 20 20 20 20 63 61 73 65 20 27 7a 27 3a 20   .    case 'z': 
7680: 0a 20 20 20 20 20 20 69 66 28 20 6e 42 75 66 3e  .      if( nBuf>
7690: 35 20 26 26 20 30 3d 3d 6d 65 6d 63 6d 70 28 22  5 && 0==memcmp("
76a0: 61 6c 69 7a 65 22 2c 20 26 61 42 75 66 5b 6e 42  alize", &aBuf[nB
76b0: 75 66 2d 35 5d 2c 20 35 29 20 29 7b 0a 20 20 20  uf-5], 5) ){.   
76c0: 20 20 20 20 20 69 66 28 20 66 74 73 35 50 6f 72       if( fts5Por
76d0: 74 65 72 5f 4d 47 74 30 28 61 42 75 66 2c 20 6e  ter_MGt0(aBuf, n
76e0: 42 75 66 2d 35 29 20 29 7b 0a 20 20 20 20 20 20  Buf-5) ){.      
76f0: 20 20 20 20 6d 65 6d 63 70 79 28 26 61 42 75 66      memcpy(&aBuf
7700: 5b 6e 42 75 66 2d 35 5d 2c 20 22 61 6c 22 2c 20  [nBuf-5], "al", 
7710: 32 29 3b 0a 20 20 20 20 20 20 20 20 20 20 2a 70  2);.          *p
7720: 6e 42 75 66 20 3d 20 6e 42 75 66 20 2d 20 35 20  nBuf = nBuf - 5 
7730: 2b 20 32 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  + 2;.        }. 
7740: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62 72 65       }.      bre
7750: 61 6b 3b 0a 20 20 0a 20 20 7d 0a 20 20 72 65 74  ak;.  .  }.  ret
7760: 75 72 6e 20 72 65 74 3b 0a 7d 0a 20 20 0a 0a 73  urn ret;.}.  ..s
7770: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 50 6f  tatic int fts5Po
7780: 72 74 65 72 53 74 65 70 31 42 28 63 68 61 72 20  rterStep1B(char 
7790: 2a 61 42 75 66 2c 20 69 6e 74 20 2a 70 6e 42 75  *aBuf, int *pnBu
77a0: 66 29 7b 0a 20 20 69 6e 74 20 72 65 74 20 3d 20  f){.  int ret = 
77b0: 30 3b 0a 20 20 69 6e 74 20 6e 42 75 66 20 3d 20  0;.  int nBuf = 
77c0: 2a 70 6e 42 75 66 3b 0a 20 20 73 77 69 74 63 68  *pnBuf;.  switch
77d0: 28 20 61 42 75 66 5b 6e 42 75 66 2d 32 5d 20 29  ( aBuf[nBuf-2] )
77e0: 7b 0a 20 20 20 20 0a 20 20 20 20 63 61 73 65 20  {.    .    case 
77f0: 27 65 27 3a 20 0a 20 20 20 20 20 20 69 66 28 20  'e': .      if( 
7800: 6e 42 75 66 3e 33 20 26 26 20 30 3d 3d 6d 65 6d  nBuf>3 && 0==mem
7810: 63 6d 70 28 22 65 65 64 22 2c 20 26 61 42 75 66  cmp("eed", &aBuf
7820: 5b 6e 42 75 66 2d 33 5d 2c 20 33 29 20 29 7b 0a  [nBuf-3], 3) ){.
7830: 20 20 20 20 20 20 20 20 69 66 28 20 66 74 73 35          if( fts5
7840: 50 6f 72 74 65 72 5f 4d 47 74 30 28 61 42 75 66  Porter_MGt0(aBuf
7850: 2c 20 6e 42 75 66 2d 33 29 20 29 7b 0a 20 20 20  , nBuf-3) ){.   
7860: 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28 26 61         memcpy(&a
7870: 42 75 66 5b 6e 42 75 66 2d 33 5d 2c 20 22 65 65  Buf[nBuf-3], "ee
7880: 22 2c 20 32 29 3b 0a 20 20 20 20 20 20 20 20 20  ", 2);.         
7890: 20 2a 70 6e 42 75 66 20 3d 20 6e 42 75 66 20 2d   *pnBuf = nBuf -
78a0: 20 33 20 2b 20 32 3b 0a 20 20 20 20 20 20 20 20   3 + 2;.        
78b0: 7d 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66  }.      }else if
78c0: 28 20 6e 42 75 66 3e 32 20 26 26 20 30 3d 3d 6d  ( nBuf>2 && 0==m
78d0: 65 6d 63 6d 70 28 22 65 64 22 2c 20 26 61 42 75  emcmp("ed", &aBu
78e0: 66 5b 6e 42 75 66 2d 32 5d 2c 20 32 29 20 29 7b  f[nBuf-2], 2) ){
78f0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 66 74 73  .        if( fts
7900: 35 50 6f 72 74 65 72 5f 56 6f 77 65 6c 28 61 42  5Porter_Vowel(aB
7910: 75 66 2c 20 6e 42 75 66 2d 32 29 20 29 7b 0a 20  uf, nBuf-2) ){. 
7920: 20 20 20 20 20 20 20 20 20 2a 70 6e 42 75 66 20           *pnBuf 
7930: 3d 20 6e 42 75 66 20 2d 20 32 3b 0a 20 20 20 20  = nBuf - 2;.    
7940: 20 20 20 20 20 20 72 65 74 20 3d 20 31 3b 0a 20        ret = 1;. 
7950: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
7960: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
7970: 0a 20 20 20 20 63 61 73 65 20 27 6e 27 3a 20 0a  .    case 'n': .
7980: 20 20 20 20 20 20 69 66 28 20 6e 42 75 66 3e 33        if( nBuf>3
7990: 20 26 26 20 30 3d 3d 6d 65 6d 63 6d 70 28 22 69   && 0==memcmp("i
79a0: 6e 67 22 2c 20 26 61 42 75 66 5b 6e 42 75 66 2d  ng", &aBuf[nBuf-
79b0: 33 5d 2c 20 33 29 20 29 7b 0a 20 20 20 20 20 20  3], 3) ){.      
79c0: 20 20 69 66 28 20 66 74 73 35 50 6f 72 74 65 72    if( fts5Porter
79d0: 5f 56 6f 77 65 6c 28 61 42 75 66 2c 20 6e 42 75  _Vowel(aBuf, nBu
79e0: 66 2d 33 29 20 29 7b 0a 20 20 20 20 20 20 20 20  f-3) ){.        
79f0: 20 20 2a 70 6e 42 75 66 20 3d 20 6e 42 75 66 20    *pnBuf = nBuf 
7a00: 2d 20 33 3b 0a 20 20 20 20 20 20 20 20 20 20 72  - 3;.          r
7a10: 65 74 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20  et = 1;.        
7a20: 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  }.      }.      
7a30: 62 72 65 61 6b 3b 0a 20 20 0a 20 20 7d 0a 20 20  break;.  .  }.  
7a40: 72 65 74 75 72 6e 20 72 65 74 3b 0a 7d 0a 20 20  return ret;.}.  
7a50: 0a 2f 2a 20 0a 2a 2a 20 47 45 4e 45 52 41 54 45  ./* .** GENERATE
7a60: 44 20 43 4f 44 45 20 45 4e 44 53 20 48 45 52 45  D CODE ENDS HERE
7a70: 20 28 6d 6b 70 6f 72 74 65 72 73 74 65 70 73 2e   (mkportersteps.
7a80: 74 63 6c 29 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  tcl).***********
7a90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7aa0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7ab0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7ac0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7ad0: 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .***************
7ae0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7af0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7b00: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7b10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 73 74  ***********/..st
7b20: 61 74 69 63 20 76 6f 69 64 20 66 74 73 35 50 6f  atic void fts5Po
7b30: 72 74 65 72 53 74 65 70 31 41 28 63 68 61 72 20  rterStep1A(char 
7b40: 2a 61 42 75 66 2c 20 69 6e 74 20 2a 70 6e 42 75  *aBuf, int *pnBu
7b50: 66 29 7b 0a 20 20 69 6e 74 20 6e 42 75 66 20 3d  f){.  int nBuf =
7b60: 20 2a 70 6e 42 75 66 3b 0a 20 20 69 66 28 20 61   *pnBuf;.  if( a
7b70: 42 75 66 5b 6e 42 75 66 2d 31 5d 3d 3d 27 73 27  Buf[nBuf-1]=='s'
7b80: 20 29 7b 0a 20 20 20 20 69 66 28 20 61 42 75 66   ){.    if( aBuf
7b90: 5b 6e 42 75 66 2d 32 5d 3d 3d 27 65 27 20 29 7b  [nBuf-2]=='e' ){
7ba0: 0a 20 20 20 20 20 20 69 66 28 20 28 6e 42 75 66  .      if( (nBuf
7bb0: 3e 34 20 26 26 20 61 42 75 66 5b 6e 42 75 66 2d  >4 && aBuf[nBuf-
7bc0: 34 5d 3d 3d 27 73 27 20 26 26 20 61 42 75 66 5b  4]=='s' && aBuf[
7bd0: 6e 42 75 66 2d 33 5d 3d 3d 27 73 27 29 20 0a 20  nBuf-3]=='s') . 
7be0: 20 20 20 20 20 20 7c 7c 20 28 6e 42 75 66 3e 33        || (nBuf>3
7bf0: 20 26 26 20 61 42 75 66 5b 6e 42 75 66 2d 33 5d   && aBuf[nBuf-3]
7c00: 3d 3d 27 69 27 20 29 0a 20 20 20 20 20 20 29 7b  =='i' ).      ){
7c10: 0a 20 20 20 20 20 20 20 20 2a 70 6e 42 75 66 20  .        *pnBuf 
7c20: 3d 20 6e 42 75 66 2d 32 3b 0a 20 20 20 20 20 20  = nBuf-2;.      
7c30: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 2a  }else{.        *
7c40: 70 6e 42 75 66 20 3d 20 6e 42 75 66 2d 31 3b 0a  pnBuf = nBuf-1;.
7c50: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
7c60: 20 20 65 6c 73 65 20 69 66 28 20 61 42 75 66 5b    else if( aBuf[
7c70: 6e 42 75 66 2d 32 5d 21 3d 27 73 27 20 29 7b 0a  nBuf-2]!='s' ){.
7c80: 20 20 20 20 20 20 2a 70 6e 42 75 66 20 3d 20 6e        *pnBuf = n
7c90: 42 75 66 2d 31 3b 0a 20 20 20 20 7d 0a 20 20 7d  Buf-1;.    }.  }
7ca0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .}..static int f
7cb0: 74 73 35 50 6f 72 74 65 72 43 62 28 0a 20 20 76  ts5PorterCb(.  v
7cc0: 6f 69 64 20 2a 70 43 74 78 2c 20 0a 20 20 69 6e  oid *pCtx, .  in
7cd0: 74 20 74 66 6c 61 67 73 2c 0a 20 20 63 6f 6e 73  t tflags,.  cons
7ce0: 74 20 63 68 61 72 20 2a 70 54 6f 6b 65 6e 2c 20  t char *pToken, 
7cf0: 0a 20 20 69 6e 74 20 6e 54 6f 6b 65 6e 2c 20 0a  .  int nToken, .
7d00: 20 20 69 6e 74 20 69 53 74 61 72 74 2c 20 0a 20    int iStart, . 
7d10: 20 69 6e 74 20 69 45 6e 64 0a 29 7b 0a 20 20 50   int iEnd.){.  P
7d20: 6f 72 74 65 72 43 6f 6e 74 65 78 74 20 2a 70 20  orterContext *p 
7d30: 3d 20 28 50 6f 72 74 65 72 43 6f 6e 74 65 78 74  = (PorterContext
7d40: 2a 29 70 43 74 78 3b 0a 0a 20 20 63 68 61 72 20  *)pCtx;..  char 
7d50: 2a 61 42 75 66 3b 0a 20 20 69 6e 74 20 6e 42 75  *aBuf;.  int nBu
7d60: 66 3b 0a 0a 20 20 69 66 28 20 6e 54 6f 6b 65 6e  f;..  if( nToken
7d70: 3e 46 54 53 35 5f 50 4f 52 54 45 52 5f 4d 41 58  >FTS5_PORTER_MAX
7d80: 5f 54 4f 4b 45 4e 20 7c 7c 20 6e 54 6f 6b 65 6e  _TOKEN || nToken
7d90: 3c 33 20 29 20 67 6f 74 6f 20 70 61 73 73 5f 74  <3 ) goto pass_t
7da0: 68 72 6f 75 67 68 3b 0a 20 20 61 42 75 66 20 3d  hrough;.  aBuf =
7db0: 20 70 2d 3e 61 42 75 66 3b 0a 20 20 6e 42 75 66   p->aBuf;.  nBuf
7dc0: 20 3d 20 6e 54 6f 6b 65 6e 3b 0a 20 20 6d 65 6d   = nToken;.  mem
7dd0: 63 70 79 28 61 42 75 66 2c 20 70 54 6f 6b 65 6e  cpy(aBuf, pToken
7de0: 2c 20 6e 42 75 66 29 3b 0a 0a 20 20 2f 2a 20 53  , nBuf);..  /* S
7df0: 74 65 70 20 31 2e 20 2a 2f 0a 20 20 66 74 73 35  tep 1. */.  fts5
7e00: 50 6f 72 74 65 72 53 74 65 70 31 41 28 61 42 75  PorterStep1A(aBu
7e10: 66 2c 20 26 6e 42 75 66 29 3b 0a 20 20 69 66 28  f, &nBuf);.  if(
7e20: 20 66 74 73 35 50 6f 72 74 65 72 53 74 65 70 31   fts5PorterStep1
7e30: 42 28 61 42 75 66 2c 20 26 6e 42 75 66 29 20 29  B(aBuf, &nBuf) )
7e40: 7b 0a 20 20 20 20 69 66 28 20 66 74 73 35 50 6f  {.    if( fts5Po
7e50: 72 74 65 72 53 74 65 70 31 42 32 28 61 42 75 66  rterStep1B2(aBuf
7e60: 2c 20 26 6e 42 75 66 29 3d 3d 30 20 29 7b 0a 20  , &nBuf)==0 ){. 
7e70: 20 20 20 20 20 63 68 61 72 20 63 20 3d 20 61 42       char c = aB
7e80: 75 66 5b 6e 42 75 66 2d 31 5d 3b 0a 20 20 20 20  uf[nBuf-1];.    
7e90: 20 20 69 66 28 20 66 74 73 35 50 6f 72 74 65 72    if( fts5Porter
7ea0: 49 73 56 6f 77 65 6c 28 63 2c 20 30 29 3d 3d 30  IsVowel(c, 0)==0
7eb0: 20 0a 20 20 20 20 20 20 20 26 26 20 63 21 3d 27   .       && c!='
7ec0: 6c 27 20 26 26 20 63 21 3d 27 73 27 20 26 26 20  l' && c!='s' && 
7ed0: 63 21 3d 27 7a 27 20 26 26 20 63 3d 3d 61 42 75  c!='z' && c==aBu
7ee0: 66 5b 6e 42 75 66 2d 32 5d 20 0a 20 20 20 20 20  f[nBuf-2] .     
7ef0: 20 29 7b 0a 20 20 20 20 20 20 20 20 6e 42 75 66   ){.        nBuf
7f00: 2d 2d 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20  --;.      }else 
7f10: 69 66 28 20 66 74 73 35 50 6f 72 74 65 72 5f 4d  if( fts5Porter_M
7f20: 45 71 31 28 61 42 75 66 2c 20 6e 42 75 66 29 20  Eq1(aBuf, nBuf) 
7f30: 26 26 20 66 74 73 35 50 6f 72 74 65 72 5f 4f 73  && fts5Porter_Os
7f40: 74 61 72 28 61 42 75 66 2c 20 6e 42 75 66 29 20  tar(aBuf, nBuf) 
7f50: 29 7b 0a 20 20 20 20 20 20 20 20 61 42 75 66 5b  ){.        aBuf[
7f60: 6e 42 75 66 2b 2b 5d 20 3d 20 27 65 27 3b 0a 20  nBuf++] = 'e';. 
7f70: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
7f80: 0a 0a 20 20 2f 2a 20 53 74 65 70 20 31 43 2e 20  ..  /* Step 1C. 
7f90: 2a 2f 0a 20 20 69 66 28 20 61 42 75 66 5b 6e 42  */.  if( aBuf[nB
7fa0: 75 66 2d 31 5d 3d 3d 27 79 27 20 26 26 20 66 74  uf-1]=='y' && ft
7fb0: 73 35 50 6f 72 74 65 72 5f 56 6f 77 65 6c 28 61  s5Porter_Vowel(a
7fc0: 42 75 66 2c 20 6e 42 75 66 2d 31 29 20 29 7b 0a  Buf, nBuf-1) ){.
7fd0: 20 20 20 20 61 42 75 66 5b 6e 42 75 66 2d 31 5d      aBuf[nBuf-1]
7fe0: 20 3d 20 27 69 27 3b 0a 20 20 7d 0a 0a 20 20 2f   = 'i';.  }..  /
7ff0: 2a 20 53 74 65 70 73 20 32 20 74 68 72 6f 75 67  * Steps 2 throug
8000: 68 20 34 2e 20 2a 2f 0a 20 20 66 74 73 35 50 6f  h 4. */.  fts5Po
8010: 72 74 65 72 53 74 65 70 32 28 61 42 75 66 2c 20  rterStep2(aBuf, 
8020: 26 6e 42 75 66 29 3b 0a 20 20 66 74 73 35 50 6f  &nBuf);.  fts5Po
8030: 72 74 65 72 53 74 65 70 33 28 61 42 75 66 2c 20  rterStep3(aBuf, 
8040: 26 6e 42 75 66 29 3b 0a 20 20 66 74 73 35 50 6f  &nBuf);.  fts5Po
8050: 72 74 65 72 53 74 65 70 34 28 61 42 75 66 2c 20  rterStep4(aBuf, 
8060: 26 6e 42 75 66 29 3b 0a 0a 20 20 2f 2a 20 53 74  &nBuf);..  /* St
8070: 65 70 20 35 61 2e 20 2a 2f 0a 20 20 61 73 73 65  ep 5a. */.  asse
8080: 72 74 28 20 6e 42 75 66 3e 30 20 29 3b 0a 20 20  rt( nBuf>0 );.  
8090: 69 66 28 20 61 42 75 66 5b 6e 42 75 66 2d 31 5d  if( aBuf[nBuf-1]
80a0: 3d 3d 27 65 27 20 29 7b 0a 20 20 20 20 69 66 28  =='e' ){.    if(
80b0: 20 66 74 73 35 50 6f 72 74 65 72 5f 4d 47 74 31   fts5Porter_MGt1
80c0: 28 61 42 75 66 2c 20 6e 42 75 66 2d 31 29 20 0a  (aBuf, nBuf-1) .
80d0: 20 20 20 20 20 7c 7c 20 28 66 74 73 35 50 6f 72       || (fts5Por
80e0: 74 65 72 5f 4d 45 71 31 28 61 42 75 66 2c 20 6e  ter_MEq1(aBuf, n
80f0: 42 75 66 2d 31 29 20 26 26 20 21 66 74 73 35 50  Buf-1) && !fts5P
8100: 6f 72 74 65 72 5f 4f 73 74 61 72 28 61 42 75 66  orter_Ostar(aBuf
8110: 2c 20 6e 42 75 66 2d 31 29 29 0a 20 20 20 20 29  , nBuf-1)).    )
8120: 7b 0a 20 20 20 20 20 20 6e 42 75 66 2d 2d 3b 0a  {.      nBuf--;.
8130: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20      }.  }..  /* 
8140: 53 74 65 70 20 35 62 2e 20 2a 2f 0a 20 20 69 66  Step 5b. */.  if
8150: 28 20 6e 42 75 66 3e 31 20 26 26 20 61 42 75 66  ( nBuf>1 && aBuf
8160: 5b 6e 42 75 66 2d 31 5d 3d 3d 27 6c 27 20 0a 20  [nBuf-1]=='l' . 
8170: 20 20 26 26 20 61 42 75 66 5b 6e 42 75 66 2d 32    && aBuf[nBuf-2
8180: 5d 3d 3d 27 6c 27 20 26 26 20 66 74 73 35 50 6f  ]=='l' && fts5Po
8190: 72 74 65 72 5f 4d 47 74 31 28 61 42 75 66 2c 20  rter_MGt1(aBuf, 
81a0: 6e 42 75 66 2d 31 29 20 0a 20 20 29 7b 0a 20 20  nBuf-1) .  ){.  
81b0: 20 20 6e 42 75 66 2d 2d 3b 0a 20 20 7d 0a 0a 20    nBuf--;.  }.. 
81c0: 20 72 65 74 75 72 6e 20 70 2d 3e 78 54 6f 6b 65   return p->xToke
81d0: 6e 28 70 2d 3e 70 43 74 78 2c 20 74 66 6c 61 67  n(p->pCtx, tflag
81e0: 73 2c 20 61 42 75 66 2c 20 6e 42 75 66 2c 20 69  s, aBuf, nBuf, i
81f0: 53 74 61 72 74 2c 20 69 45 6e 64 29 3b 0a 0a 20  Start, iEnd);.. 
8200: 70 61 73 73 5f 74 68 72 6f 75 67 68 3a 0a 20 20  pass_through:.  
8210: 72 65 74 75 72 6e 20 70 2d 3e 78 54 6f 6b 65 6e  return p->xToken
8220: 28 70 2d 3e 70 43 74 78 2c 20 74 66 6c 61 67 73  (p->pCtx, tflags
8230: 2c 20 70 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e  , pToken, nToken
8240: 2c 20 69 53 74 61 72 74 2c 20 69 45 6e 64 29 3b  , iStart, iEnd);
8250: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 6f 6b 65 6e 69  .}../*.** Tokeni
8260: 7a 65 20 75 73 69 6e 67 20 74 68 65 20 70 6f 72  ze using the por
8270: 74 65 72 20 74 6f 6b 65 6e 69 7a 65 72 2e 0a 2a  ter tokenizer..*
8280: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  /.static int fts
8290: 35 50 6f 72 74 65 72 54 6f 6b 65 6e 69 7a 65 28  5PorterTokenize(
82a0: 0a 20 20 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72  .  Fts5Tokenizer
82b0: 20 2a 70 54 6f 6b 65 6e 69 7a 65 72 2c 0a 20 20   *pTokenizer,.  
82c0: 76 6f 69 64 20 2a 70 43 74 78 2c 0a 20 20 69 6e  void *pCtx,.  in
82d0: 74 20 66 6c 61 67 73 2c 0a 20 20 63 6f 6e 73 74  t flags,.  const
82e0: 20 63 68 61 72 20 2a 70 54 65 78 74 2c 20 69 6e   char *pText, in
82f0: 74 20 6e 54 65 78 74 2c 0a 20 20 69 6e 74 20 28  t nText,.  int (
8300: 2a 78 54 6f 6b 65 6e 29 28 76 6f 69 64 2a 2c 20  *xToken)(void*, 
8310: 69 6e 74 2c 20 63 6f 6e 73 74 20 63 68 61 72 2a  int, const char*
8320: 2c 20 69 6e 74 20 6e 54 6f 6b 65 6e 2c 20 69 6e  , int nToken, in
8330: 74 20 69 53 74 61 72 74 2c 20 69 6e 74 20 69 45  t iStart, int iE
8340: 6e 64 29 0a 29 7b 0a 20 20 50 6f 72 74 65 72 54  nd).){.  PorterT
8350: 6f 6b 65 6e 69 7a 65 72 20 2a 70 20 3d 20 28 50  okenizer *p = (P
8360: 6f 72 74 65 72 54 6f 6b 65 6e 69 7a 65 72 2a 29  orterTokenizer*)
8370: 70 54 6f 6b 65 6e 69 7a 65 72 3b 0a 20 20 50 6f  pTokenizer;.  Po
8380: 72 74 65 72 43 6f 6e 74 65 78 74 20 73 43 74 78  rterContext sCtx
8390: 3b 0a 20 20 73 43 74 78 2e 78 54 6f 6b 65 6e 20  ;.  sCtx.xToken 
83a0: 3d 20 78 54 6f 6b 65 6e 3b 0a 20 20 73 43 74 78  = xToken;.  sCtx
83b0: 2e 70 43 74 78 20 3d 20 70 43 74 78 3b 0a 20 20  .pCtx = pCtx;.  
83c0: 73 43 74 78 2e 61 42 75 66 20 3d 20 70 2d 3e 61  sCtx.aBuf = p->a
83d0: 42 75 66 3b 0a 20 20 72 65 74 75 72 6e 20 70 2d  Buf;.  return p-
83e0: 3e 74 6f 6b 65 6e 69 7a 65 72 2e 78 54 6f 6b 65  >tokenizer.xToke
83f0: 6e 69 7a 65 28 0a 20 20 20 20 20 20 70 2d 3e 70  nize(.      p->p
8400: 54 6f 6b 65 6e 69 7a 65 72 2c 20 28 76 6f 69 64  Tokenizer, (void
8410: 2a 29 26 73 43 74 78 2c 20 66 6c 61 67 73 2c 20  *)&sCtx, flags, 
8420: 70 54 65 78 74 2c 20 6e 54 65 78 74 2c 20 66 74  pText, nText, ft
8430: 73 35 50 6f 72 74 65 72 43 62 0a 20 20 29 3b 0a  s5PorterCb.  );.
8440: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74 65  }../*.** Registe
8450: 72 20 61 6c 6c 20 62 75 69 6c 74 2d 69 6e 20 74  r all built-in t
8460: 6f 6b 65 6e 69 7a 65 72 73 20 77 69 74 68 20 46  okenizers with F
8470: 54 53 35 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  TS5..*/.int sqli
8480: 74 65 33 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72  te3Fts5Tokenizer
8490: 49 6e 69 74 28 66 74 73 35 5f 61 70 69 20 2a 70  Init(fts5_api *p
84a0: 41 70 69 29 7b 0a 20 20 73 74 72 75 63 74 20 42  Api){.  struct B
84b0: 75 69 6c 74 69 6e 54 6f 6b 65 6e 69 7a 65 72 20  uiltinTokenizer 
84c0: 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72  {.    const char
84d0: 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20 66 74 73   *zName;.    fts
84e0: 35 5f 74 6f 6b 65 6e 69 7a 65 72 20 78 3b 0a 20  5_tokenizer x;. 
84f0: 20 7d 20 61 42 75 69 6c 74 69 6e 5b 5d 20 3d 20   } aBuiltin[] = 
8500: 7b 0a 20 20 20 20 7b 20 22 75 6e 69 63 6f 64 65  {.    { "unicode
8510: 36 31 22 2c 20 7b 66 74 73 35 55 6e 69 63 6f 64  61", {fts5Unicod
8520: 65 43 72 65 61 74 65 2c 20 66 74 73 35 55 6e 69  eCreate, fts5Uni
8530: 63 6f 64 65 44 65 6c 65 74 65 2c 20 66 74 73 35  codeDelete, fts5
8540: 55 6e 69 63 6f 64 65 54 6f 6b 65 6e 69 7a 65 7d  UnicodeTokenize}
8550: 7d 2c 0a 20 20 20 20 7b 20 22 61 73 63 69 69 22  },.    { "ascii"
8560: 2c 20 20 20 20 20 7b 66 74 73 35 41 73 63 69 69  ,     {fts5Ascii
8570: 43 72 65 61 74 65 2c 20 66 74 73 35 41 73 63 69  Create, fts5Asci
8580: 69 44 65 6c 65 74 65 2c 20 66 74 73 35 41 73 63  iDelete, fts5Asc
8590: 69 69 54 6f 6b 65 6e 69 7a 65 20 7d 7d 2c 0a 20  iiTokenize }},. 
85a0: 20 20 20 7b 20 22 70 6f 72 74 65 72 22 2c 20 20     { "porter",  
85b0: 20 20 7b 66 74 73 35 50 6f 72 74 65 72 43 72 65    {fts5PorterCre
85c0: 61 74 65 2c 20 66 74 73 35 50 6f 72 74 65 72 44  ate, fts5PorterD
85d0: 65 6c 65 74 65 2c 20 66 74 73 35 50 6f 72 74 65  elete, fts5Porte
85e0: 72 54 6f 6b 65 6e 69 7a 65 20 7d 7d 2c 0a 20 20  rTokenize }},.  
85f0: 7d 3b 0a 20 20 0a 20 20 69 6e 74 20 72 63 20 3d  };.  .  int rc =
8600: 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20   SQLITE_OK;     
8610: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
8620: 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20  n code */.  int 
8630: 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  i;              
8640: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
8650: 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f 75 67  o iterate throug
8660: 68 20 62 75 69 6c 74 69 6e 20 66 75 6e 63 74 69  h builtin functi
8670: 6f 6e 73 20 2a 2f 0a 0a 20 20 66 6f 72 28 69 3d  ons */..  for(i=
8680: 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  0; rc==SQLITE_OK
8690: 20 26 26 20 69 3c 41 72 72 61 79 53 69 7a 65 28   && i<ArraySize(
86a0: 61 42 75 69 6c 74 69 6e 29 3b 20 69 2b 2b 29 7b  aBuiltin); i++){
86b0: 0a 20 20 20 20 72 63 20 3d 20 70 41 70 69 2d 3e  .    rc = pApi->
86c0: 78 43 72 65 61 74 65 54 6f 6b 65 6e 69 7a 65 72  xCreateTokenizer
86d0: 28 70 41 70 69 2c 0a 20 20 20 20 20 20 20 20 61  (pApi,.        a
86e0: 42 75 69 6c 74 69 6e 5b 69 5d 2e 7a 4e 61 6d 65  Builtin[i].zName
86f0: 2c 0a 20 20 20 20 20 20 20 20 28 76 6f 69 64 2a  ,.        (void*
8700: 29 70 41 70 69 2c 0a 20 20 20 20 20 20 20 20 26  )pApi,.        &
8710: 61 42 75 69 6c 74 69 6e 5b 69 5d 2e 78 2c 0a 20  aBuiltin[i].x,. 
8720: 20 20 20 20 20 20 20 30 0a 20 20 20 20 29 3b 0a         0.    );.
8730: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
8740: 3b 0a 7d 0a                                      ;.}.