Documentation Source Text

Hex Artifact Content
Login

Artifact 40ffcea582cf8aeee2b0af62291168bc9e96d118:


0000: 0a 2f 2a 0a 2a 2a 20 54 68 65 72 65 20 61 72 65  ./*.** There are
0010: 20 61 6c 73 6f 20 74 77 6f 20 53 51 4c 20 75 73   also two SQL us
0020: 65 72 20 66 75 6e 63 74 69 6f 6e 73 20 72 65 67  er functions reg
0030: 69 73 74 65 72 65 64 3a 0a 2a 2a 0a 2a 2a 20 20  istered:.**.**  
0040: 20 72 61 6e 6b 28 29 0a 2a 2a 20 20 20 65 72 61   rank().**   era
0050: 6e 6b 28 29 0a 2a 2a 0a 2a 2a 20 72 61 6e 6b 28  nk().**.** rank(
0060: 29 20 69 6e 74 65 72 70 72 65 74 73 20 74 68 65  ) interprets the
0070: 20 72 65 74 75 72 6e 20 76 61 6c 75 65 20 6f 66   return value of
0080: 20 74 68 65 20 46 54 53 33 20 6d 61 74 63 68 69   the FTS3 matchi
0090: 6e 66 6f 28 29 20 66 75 6e 63 74 69 6f 6e 20 61  nfo() function a
00a0: 6e 64 0a 2a 2a 20 72 65 74 75 72 6e 73 20 61 20  nd.** returns a 
00b0: 73 63 6f 72 65 20 66 6f 72 20 74 68 65 20 6d 61  score for the ma
00c0: 74 63 68 20 28 61 20 72 65 61 6c 20 6e 75 6d 62  tch (a real numb
00d0: 65 72 29 2e 20 54 68 65 20 68 69 67 68 65 72 20  er). The higher 
00e0: 74 68 65 20 73 63 6f 72 65 2c 20 74 68 65 0a 2a  the score, the.*
00f0: 2a 20 6d 6f 72 65 20 72 65 6c 65 76 61 6e 74 20  * more relevant 
0100: 74 68 65 20 64 6f 63 75 6d 65 6e 74 20 69 73 20  the document is 
0110: 63 6f 6e 73 69 64 65 72 65 64 2e 20 54 68 69 73  considered. This
0120: 20 69 73 20 75 73 65 64 20 74 6f 20 6f 72 64 65   is used to orde
0130: 72 20 71 75 65 72 79 0a 2a 2a 20 72 65 73 75 6c  r query.** resul
0140: 74 73 20 77 68 65 6e 20 74 68 65 20 75 73 65 72  ts when the user
0150: 20 73 65 61 72 63 68 73 20 74 68 65 20 64 61 74   searchs the dat
0160: 61 62 61 73 65 2e 20 54 68 65 20 72 61 6e 6b 28  abase. The rank(
0170: 29 20 66 75 6e 63 74 69 6f 6e 20 74 61 6b 65 73  ) function takes
0180: 0a 2a 2a 20 28 6e 43 6f 6c 2b 31 29 20 61 72 67  .** (nCol+1) arg
0190: 75 6d 65 6e 74 73 2c 20 77 68 65 72 65 20 6e 43  uments, where nC
01a0: 6f 6c 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72  ol is the number
01b0: 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74   of columns in t
01c0: 68 65 20 46 54 53 33 0a 2a 2a 20 74 61 62 6c 65  he FTS3.** table
01d0: 2e 20 54 68 65 20 66 69 72 73 74 20 61 72 67 75  . The first argu
01e0: 6d 65 6e 74 20 69 73 20 74 68 65 20 72 65 74 75  ment is the retu
01f0: 72 6e 20 76 61 6c 75 65 20 6f 66 20 6d 61 74 63  rn value of matc
0200: 68 69 6e 66 6f 28 29 2e 20 54 68 65 0a 2a 2a 20  hinfo(). The.** 
0210: 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20  second argument 
0220: 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  is the number of
0230: 20 74 6f 6b 65 6e 73 20 69 6e 20 63 6f 6c 75 6d   tokens in colum
0240: 6e 20 30 20 6f 66 20 74 68 65 20 63 75 72 72 65  n 0 of the curre
0250: 6e 74 20 46 54 53 33 20 0a 2a 2a 20 74 61 62 6c  nt FTS3 .** tabl
0260: 65 20 72 6f 77 2e 20 54 68 65 20 74 68 69 72 64  e row. The third
0270: 20 61 72 67 75 6d 65 6e 74 20 69 73 20 74 68 65   argument is the
0280: 20 6e 75 6d 62 65 72 20 6f 66 20 74 6f 6b 65 6e   number of token
0290: 73 20 69 6e 20 63 6f 6c 75 6d 6e 20 31 2c 20 61  s in column 1, a
02a0: 6e 64 0a 2a 2a 20 73 6f 20 6f 6e 2e 0a 2a 2a 0a  nd.** so on..**.
02b0: 2a 2a 20 46 75 6e 63 74 69 6f 6e 20 65 72 61 6e  ** Function eran
02c0: 6b 28 29 20 69 73 20 63 61 6c 6c 65 64 20 69 6e  k() is called in
02d0: 20 65 78 61 63 74 6c 79 20 74 68 65 20 73 61 6d   exactly the sam
02e0: 65 20 77 61 79 20 61 73 20 72 61 6e 6b 28 29 2e  e way as rank().
02f0: 20 49 6e 73 74 65 61 64 0a 2a 2a 20 6f 66 20 72   Instead.** of r
0300: 65 74 75 72 6e 69 6e 67 20 61 20 73 63 6f 72 65  eturning a score
0310: 2c 20 69 74 20 72 65 74 75 72 6e 73 20 61 6e 20  , it returns an 
0320: 48 54 4d 4c 20 66 6f 72 6d 61 74 74 65 64 20 74  HTML formatted t
0330: 61 62 6c 65 20 63 6f 6e 74 61 69 6e 69 6e 67 0a  able containing.
0340: 2a 2a 20 64 61 74 61 20 74 68 61 74 20 6d 61 79  ** data that may
0350: 20 62 65 20 75 73 65 64 20 74 6f 20 75 6e 64 65   be used to unde
0360: 72 73 74 61 6e 64 20 68 6f 77 20 74 68 65 20 73  rstand how the s
0370: 63 6f 72 65 20 66 6f 72 20 74 68 65 20 63 75 72  core for the cur
0380: 72 65 6e 74 20 72 6f 77 0a 2a 2a 20 77 61 73 20  rent row.** was 
0390: 63 61 6c 63 75 6c 61 74 65 64 2e 0a 2a 2f 0a 0a  calculated..*/..
03a0: 23 69 6e 63 6c 75 64 65 20 3c 74 63 6c 2e 68 3e  #include <tcl.h>
03b0: 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 72 69 6e  .#include <strin
03c0: 67 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 61  g.h>.#include <a
03d0: 73 73 65 72 74 2e 68 3e 0a 23 69 6e 63 6c 75 64  ssert.h>.#includ
03e0: 65 20 3c 63 74 79 70 65 2e 68 3e 0a 23 69 6e 63  e <ctype.h>.#inc
03f0: 6c 75 64 65 20 3c 6d 61 74 68 2e 68 3e 0a 0a 23  lude <math.h>..#
0400: 69 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65 33  include "sqlite3
0410: 2e 68 22 0a 0a 74 79 70 65 64 65 66 20 75 6e 73  .h"..typedef uns
0420: 69 67 6e 65 64 20 69 6e 74 20 75 33 32 3b 0a 74  igned int u32;.t
0430: 79 70 65 64 65 66 20 75 6e 73 69 67 6e 65 64 20  ypedef unsigned 
0440: 63 68 61 72 20 75 38 3b 0a 74 79 70 65 64 65 66  char u8;.typedef
0450: 20 73 71 6c 69 74 65 33 5f 75 69 6e 74 36 34 20   sqlite3_uint64 
0460: 75 36 34 3b 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  u64;../*.** Impl
0470: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 73 65  ementation of se
0480: 61 72 63 68 20 72 65 73 75 6c 74 20 72 61 6e 6b  arch result rank
0490: 69 6e 67 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f  ing function..*/
04a0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 72 61 6e  .static void ran
04b0: 6b 66 75 6e 63 28 73 71 6c 69 74 65 33 5f 63 6f  kfunc(sqlite3_co
04c0: 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 69 6e 74  ntext *pCtx, int
04d0: 20 6e 56 61 6c 2c 20 73 71 6c 69 74 65 33 5f 76   nVal, sqlite3_v
04e0: 61 6c 75 65 20 2a 2a 61 70 56 61 6c 29 7b 0a 20  alue **apVal){. 
04f0: 20 75 33 32 20 2a 61 4d 61 74 63 68 69 6e 66 6f   u32 *aMatchinfo
0500: 3b 0a 20 20 64 6f 75 62 6c 65 20 73 63 6f 72 65  ;.  double score
0510: 20 3d 20 30 2e 30 3b 0a 20 20 69 6e 74 20 69 43   = 0.0;.  int iC
0520: 6f 6c 3b 0a 20 20 69 6e 74 20 69 50 68 72 61 73  ol;.  int iPhras
0530: 65 3b 0a 20 20 69 6e 74 20 6e 43 6f 6c 3b 0a 20  e;.  int nCol;. 
0540: 20 69 6e 74 20 6e 50 68 72 61 73 65 3b 0a 0a 20   int nPhrase;.. 
0550: 20 69 6e 74 20 69 73 45 78 70 6c 61 69 6e 20 3d   int isExplain =
0560: 20 73 71 6c 69 74 65 33 5f 75 73 65 72 5f 64 61   sqlite3_user_da
0570: 74 61 28 70 43 74 78 29 3b 0a 20 20 63 68 61 72  ta(pCtx);.  char
0580: 20 2a 7a 45 78 70 6c 61 69 6e 20 3d 20 30 3b 0a   *zExplain = 0;.
0590: 0a 20 20 69 66 28 20 6e 56 61 6c 3d 3d 30 20 29  .  if( nVal==0 )
05a0: 20 67 6f 74 6f 20 77 6e 61 3b 0a 20 20 61 4d 61   goto wna;.  aMa
05b0: 74 63 68 69 6e 66 6f 20 3d 20 28 75 33 32 20 2a  tchinfo = (u32 *
05c0: 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62  )sqlite3_value_b
05d0: 6c 6f 62 28 61 70 56 61 6c 5b 30 5d 29 3b 0a 20  lob(apVal[0]);. 
05e0: 20 6e 50 68 72 61 73 65 20 3d 20 61 4d 61 74 63   nPhrase = aMatc
05f0: 68 69 6e 66 6f 5b 30 5d 3b 0a 20 20 6e 43 6f 6c  hinfo[0];.  nCol
0600: 20 3d 20 61 4d 61 74 63 68 69 6e 66 6f 5b 31 5d   = aMatchinfo[1]
0610: 3b 0a 20 20 69 66 28 20 6e 56 61 6c 21 3d 6e 43  ;.  if( nVal!=nC
0620: 6f 6c 2b 31 20 29 20 67 6f 74 6f 20 77 6e 61 3b  ol+1 ) goto wna;
0630: 0a 0a 20 20 69 66 28 20 69 73 45 78 70 6c 61 69  ..  if( isExplai
0640: 6e 20 29 20 7a 45 78 70 6c 61 69 6e 20 3d 20 73  n ) zExplain = s
0650: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
0660: 3c 74 61 62 6c 65 20 77 69 64 74 68 3d 31 30 30  <table width=100
0670: 25 25 3e 22 29 3b 0a 0a 20 20 66 6f 72 28 69 43  %%>");..  for(iC
0680: 6f 6c 3d 30 3b 20 69 43 6f 6c 3c 6e 43 6f 6c 3b  ol=0; iCol<nCol;
0690: 20 69 43 6f 6c 2b 2b 29 7b 0a 20 20 20 20 69 6e   iCol++){.    in
06a0: 74 20 6e 54 6f 6b 65 6e 20 3d 20 73 71 6c 69 74  t nToken = sqlit
06b0: 65 33 5f 76 61 6c 75 65 5f 69 6e 74 28 61 70 56  e3_value_int(apV
06c0: 61 6c 5b 69 43 6f 6c 2b 31 5d 29 3b 0a 20 20 20  al[iCol+1]);.   
06d0: 20 64 6f 75 62 6c 65 20 63 6f 6c 73 63 6f 72 65   double colscore
06e0: 20 3d 20 30 2e 30 3b 0a 20 20 20 20 69 66 28 20   = 0.0;.    if( 
06f0: 69 73 45 78 70 6c 61 69 6e 20 29 7b 0a 20 20 20  isExplain ){.   
0700: 20 20 20 7a 45 78 70 6c 61 69 6e 20 3d 20 73 71     zExplain = sq
0710: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25  lite3_mprintf("%
0720: 7a 3c 74 72 3e 3c 74 64 3e 25 64 2e 3c 74 64 3e  z<tr><td>%d.<td>
0730: 28 20 22 2c 20 7a 45 78 70 6c 61 69 6e 2c 20 69  ( ", zExplain, i
0740: 43 6f 6c 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  Col);.    }.    
0750: 66 6f 72 28 69 50 68 72 61 73 65 3d 30 3b 20 69  for(iPhrase=0; i
0760: 50 68 72 61 73 65 3c 6e 50 68 72 61 73 65 3b 20  Phrase<nPhrase; 
0770: 69 50 68 72 61 73 65 2b 2b 29 7b 0a 20 20 20 20  iPhrase++){.    
0780: 20 20 75 33 32 20 6e 47 6c 6f 62 61 6c 20 3d 20    u32 nGlobal = 
0790: 61 4d 61 74 63 68 69 6e 66 6f 5b 32 20 2b 20 69  aMatchinfo[2 + i
07a0: 50 68 72 61 73 65 2a 6e 43 6f 6c 20 2b 20 69 43  Phrase*nCol + iC
07b0: 6f 6c 5d 3b 0a 20 20 20 20 20 20 75 33 32 20 6e  ol];.      u32 n
07c0: 48 69 74 20 3d 20 61 4d 61 74 63 68 69 6e 66 6f  Hit = aMatchinfo
07d0: 5b 32 20 2b 20 6e 50 68 72 61 73 65 2a 6e 43 6f  [2 + nPhrase*nCo
07e0: 6c 20 2b 20 69 50 68 72 61 73 65 2a 6e 43 6f 6c  l + iPhrase*nCol
07f0: 20 2b 20 69 43 6f 6c 5d 3b 0a 0a 20 20 20 20 20   + iCol];..     
0800: 20 69 66 28 20 6e 48 69 74 20 29 20 63 6f 6c 73   if( nHit ) cols
0810: 63 6f 72 65 20 2b 3d 20 28 64 6f 75 62 6c 65 29  core += (double)
0820: 6e 48 69 74 20 2f 20 28 64 6f 75 62 6c 65 29 6e  nHit / (double)n
0830: 47 6c 6f 62 61 6c 3b 0a 20 20 20 20 20 20 69 66  Global;.      if
0840: 28 20 69 73 45 78 70 6c 61 69 6e 20 29 7b 0a 20  ( isExplain ){. 
0850: 20 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61         const cha
0860: 72 20 2a 7a 44 69 76 20 3d 20 28 69 50 68 72 61  r *zDiv = (iPhra
0870: 73 65 3d 3d 30 20 3f 20 22 22 20 3a 20 22 2b 20  se==0 ? "" : "+ 
0880: 22 29 3b 0a 20 20 20 20 20 20 20 20 7a 45 78 70  ");.        zExp
0890: 6c 61 69 6e 20 3d 20 73 71 6c 69 74 65 33 5f 6d  lain = sqlite3_m
08a0: 70 72 69 6e 74 66 28 22 25 7a 25 73 25 64 2f 25  printf("%z%s%d/%
08b0: 64 20 22 2c 20 7a 45 78 70 6c 61 69 6e 2c 20 7a  d ", zExplain, z
08c0: 44 69 76 2c 20 6e 48 69 74 2c 20 6e 47 6c 6f 62  Div, nHit, nGlob
08d0: 61 6c 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  al);.      }.   
08e0: 20 7d 0a 20 20 20 20 63 6f 6c 73 63 6f 72 65 20   }.    colscore 
08f0: 3d 20 63 6f 6c 73 63 6f 72 65 20 2f 20 28 6c 6f  = colscore / (lo
0900: 67 28 31 30 30 2b 6e 54 6f 6b 65 6e 29 2f 6c 6f  g(100+nToken)/lo
0910: 67 28 31 30 29 29 3b 20 0a 20 20 20 20 73 63 6f  g(10)); .    sco
0920: 72 65 20 2b 3d 20 63 6f 6c 73 63 6f 72 65 3b 0a  re += colscore;.
0930: 20 20 20 20 69 66 28 20 69 73 45 78 70 6c 61 69      if( isExplai
0940: 6e 20 29 7b 0a 20 20 20 20 20 20 7a 45 78 70 6c  n ){.      zExpl
0950: 61 69 6e 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  ain = sqlite3_mp
0960: 72 69 6e 74 66 28 0a 20 20 20 20 20 20 20 20 20  rintf(.         
0970: 20 22 25 7a 29 20 2f 20 6c 6f 67 28 31 30 30 2b   "%z) / log(100+
0980: 25 64 29 3c 74 64 3e 20 3d 20 25 2e 34 66 22 2c  %d)<td> = %.4f",
0990: 20 7a 45 78 70 6c 61 69 6e 2c 20 6e 54 6f 6b 65   zExplain, nToke
09a0: 6e 2c 20 63 6f 6c 73 63 6f 72 65 29 3b 0a 20 20  n, colscore);.  
09b0: 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 69    }.  }..  if( i
09c0: 73 45 78 70 6c 61 69 6e 20 29 7b 0a 20 20 20 20  sExplain ){.    
09d0: 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 74  sqlite3_result_t
09e0: 65 78 74 28 70 43 74 78 2c 20 73 71 6c 69 74 65  ext(pCtx, sqlite
09f0: 33 5f 6d 70 72 69 6e 74 66 28 0a 20 20 20 20 20  3_mprintf(.     
0a00: 20 20 20 22 25 7a 3c 74 72 3e 3c 74 64 3e 3c 74     "%z<tr><td><t
0a10: 64 20 77 69 64 74 68 3d 31 30 30 25 25 3e 3c 74  d width=100%%><t
0a20: 64 3e 3d 20 3c 62 3e 25 2e 34 66 3c 2f 62 3e 3c  d>= <b>%.4f</b><
0a30: 2f 74 61 62 6c 65 3e 22 2c 20 7a 45 78 70 6c 61  /table>", zExpla
0a40: 69 6e 2c 20 73 63 6f 72 65 0a 20 20 20 20 29 2c  in, score.    ),
0a50: 20 2d 31 2c 20 73 71 6c 69 74 65 33 5f 66 72 65   -1, sqlite3_fre
0a60: 65 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  e);.  }else{.   
0a70: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
0a80: 64 6f 75 62 6c 65 28 70 43 74 78 2c 20 73 63 6f  double(pCtx, sco
0a90: 72 65 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  re);.  }.  retur
0aa0: 6e 3b 0a 0a 20 77 6e 61 3a 0a 20 20 73 71 6c 69  n;.. wna:.  sqli
0ab0: 74 65 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72  te3_result_error
0ac0: 28 70 43 74 78 2c 22 77 72 6f 6e 67 20 6e 75 6d  (pCtx,"wrong num
0ad0: 62 65 72 20 6f 66 20 61 72 67 75 6d 65 6e 74 73  ber of arguments
0ae0: 20 74 6f 20 66 75 6e 63 74 69 6f 6e 20 72 61 6e   to function ran
0af0: 6b 28 29 22 2c 2d 31 29 3b 0a 7d 0a 0a 69 6e 74  k()",-1);.}..int
0b00: 20 53 71 6c 69 74 65 33 5f 49 6e 69 74 28 54 63   Sqlite3_Init(Tc
0b10: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
0b20: 29 3b 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 69  );..static int i
0b30: 6e 69 74 44 62 28 73 71 6c 69 74 65 33 20 2a 64  nitDb(sqlite3 *d
0b40: 62 2c 20 63 68 61 72 20 2a 2a 70 7a 45 72 72 2c  b, char **pzErr,
0b50: 20 76 6f 69 64 20 2a 70 29 7b 0a 20 20 73 71 6c   void *p){.  sql
0b60: 69 74 65 33 5f 63 72 65 61 74 65 5f 66 75 6e 63  ite3_create_func
0b70: 74 69 6f 6e 28 64 62 2c 20 22 72 61 6e 6b 22 2c  tion(db, "rank",
0b80: 2d 31 2c 20 53 51 4c 49 54 45 5f 55 54 46 38 2c  -1, SQLITE_UTF8,
0b90: 20 30 2c 20 72 61 6e 6b 66 75 6e 63 2c 30 2c 30   0, rankfunc,0,0
0ba0: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 63 72 65  );.  sqlite3_cre
0bb0: 61 74 65 5f 66 75 6e 63 74 69 6f 6e 28 64 62 2c  ate_function(db,
0bc0: 20 22 65 72 61 6e 6b 22 2c 20 2d 31 2c 20 53 51   "erank", -1, SQ
0bd0: 4c 49 54 45 5f 55 54 46 38 2c 20 28 76 6f 69 64  LITE_UTF8, (void
0be0: 2a 29 31 2c 20 72 61 6e 6b 66 75 6e 63 2c 30 2c  *)1, rankfunc,0,
0bf0: 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  0);.}..static in
0c00: 74 20 41 70 70 49 6e 69 74 28 54 63 6c 5f 49 6e  t AppInit(Tcl_In
0c10: 74 65 72 70 20 2a 69 6e 74 65 72 70 29 20 7b 0a  terp *interp) {.
0c20: 20 20 69 6e 74 20 72 63 3b 0a 20 20 72 63 20 3d    int rc;.  rc =
0c30: 20 53 71 6c 69 74 65 33 5f 49 6e 69 74 28 69 6e   Sqlite3_Init(in
0c40: 74 65 72 70 29 3b 0a 20 20 69 66 28 20 72 63 21  terp);.  if( rc!
0c50: 3d 54 43 4c 5f 4f 4b 20 29 20 72 65 74 75 72 6e  =TCL_OK ) return
0c60: 20 72 63 3b 0a 20 20 73 71 6c 69 74 65 33 5f 61   rc;.  sqlite3_a
0c70: 75 74 6f 5f 65 78 74 65 6e 73 69 6f 6e 28 69 6e  uto_extension(in
0c80: 69 74 44 62 29 3b 0a 20 20 72 65 74 75 72 6e 20  itDb);.  return 
0c90: 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 69 6e 74 20 6d  TCL_OK;.}..int m
0ca0: 61 69 6e 28 69 6e 74 20 61 72 67 63 2c 20 63 68  ain(int argc, ch
0cb0: 61 72 20 2a 61 72 67 76 5b 5d 29 20 7b 0a 20 20  ar *argv[]) {.  
0cc0: 54 63 6c 5f 4d 61 69 6e 28 61 72 67 63 2c 20 61  Tcl_Main(argc, a
0cd0: 72 67 76 2c 20 41 70 70 49 6e 69 74 29 3b 0a 20  rgv, AppInit);. 
0ce0: 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a         return 0;.}..