Subversion Repositories wimsdev

Rev

Rev 8100 | Rev 8161 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*    Copyright (C) 2002-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
  2.  *
  3.  *  This program is free software; you can redistribute it and/or modify
  4.  *  it under the terms of the GNU General Public License as published by
  5.  *  the Free Software Foundation; either version 2 of the License, or
  6.  *  (at your option) any later version.
  7.  *
  8.  *  This program is distributed in the hope that it will be useful,
  9.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.  *  GNU General Public License for more details.
  12.  *
  13.  *  You should have received a copy of the GNU General Public License
  14.  *  along with this program; if not, write to the Free Software
  15.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16.  */
  17.  
  18. /* This program makes comparison between two text strings,
  19.  * according to the symtext syntax. */
  20.  
  21. /* Input data: via environment variables.
  22.  * wims_exec_parm: line 1 = command (comp,expand,wordlist,random,1,2,3,...)
  23.  * line 2 = text to examine (for comp).
  24.  * line 3 and up = symtext syntax.
  25.  * w_symtext: dictionary style.
  26.  * w_symtext_option: option words.
  27.  *
  28.  * Output: two lines.
  29.  * Line 1: ERROR or OK
  30.  * Line 2: result depending on command.
  31.  */
  32.  
  33.  
  34. const char *codechar="_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  35.  
  36. #include "symtext.h"
  37. #include "../../Lib/liblines.c"
  38.  
  39. struct block blockbuf[MAX_BLOCKS];
  40. int nextblock;
  41. listtype listbuf[MAX_LISTS];
  42. int nextlist;
  43. listtype tagbuf[MAX_BLOCKS];
  44. int nexttag;
  45.  
  46. struct poolstruct poolbuf[MAX_POOLS];
  47. int nextpool;
  48.  
  49. int options;
  50. #define op_nocase    (1<<0)
  51. #define op_deaccent  (1<<1)
  52. #define op_reaccent  (1<<2)
  53. #define op_nopunct   (1<<3)
  54. #define op_nomath    (1<<4)
  55. #define op_noparenth (1<<5)
  56. #define op_nocs      (1<<6)
  57. #define op_noquote   (1<<7)
  58. #define op_matchall  (1<<8)
  59. #define op_alphaonly (1<<9)
  60. #define op_alnumonly (1<<10)
  61.  
  62. char cmdbuf[256], stbuf[MAX_LINELEN+1], textbuf[MAX_LINELEN+1];
  63. char wbuf[MAX_LINELEN+1];
  64. char cmdparm[1024];
  65. char defbuf[MAX_LINELEN+1];
  66. char style[MAX_NAMELEN+1];
  67. char styledir[MAX_FNAME+1];
  68. char optionbuf[1024];
  69. char outbuf[4096];
  70. char *outptr, *wptr;
  71. int debug;
  72.  
  73. enum {
  74.     cmd_none, cmd_comp, cmd_debug, cmd_random, cmd_1, cmd_wordlist
  75. };
  76. struct {
  77.     char *name; int value;
  78. } cmdlist[]={
  79.     {"1",       cmd_1},
  80.     {"comp",    cmd_comp},
  81.     {"compare", cmd_comp},
  82.     {"debug",   cmd_debug},
  83.     {"match",   cmd_comp},
  84.     {"rand",    cmd_random},
  85.     {"random",  cmd_random},
  86.     {"wordlist",cmd_wordlist},
  87.     {"words",   cmd_wordlist}
  88. };
  89. #define cmdcnt (sizeof(cmdlist)/sizeof(cmdlist[0]))
  90. int cmd;
  91.  
  92. void error(char *msg,...)
  93. {
  94.     va_list vp;
  95.     char buf[1024];
  96.  
  97.     va_start(vp,msg);
  98.     vsnprintf(buf,sizeof(buf),msg,vp);
  99.     va_end(vp);
  100.     printf("ERROR\n%s\n",buf);
  101.     exit(1);
  102. }
  103.  
  104. void _error(char *msg)
  105. {
  106.     error(msg);
  107. }
  108.  
  109. /* read-in a file into buffer. Use open() and read().
  110.  * Return buffer address which will be malloc'ed if buf=NULL.
  111.  */
  112. char *readfile(char *fname, char buf[], long int buflen)
  113. {
  114.     int fd, t;
  115.     struct stat st;
  116.     long int l, lc;
  117.     char *bf;
  118.     t=0; if(buf) buf[0]=0;
  119.     if(stat(fname,&st)) return NULL;
  120.     l=st.st_size; if(l<0) return NULL;
  121.     if(l>=buflen) {
  122.      if(buflen<MAX_LINELEN) l=buflen-1;
  123.      else error("file_too_long %s",fname);
  124.     }
  125.     fd=open(fname,O_RDONLY); if(fd==-1) return NULL;
  126.     if(buf==NULL) bf=xmalloc(l+8); else {bf=buf;if(l==0) {t=1; l=buflen-1;}}
  127.     lc=read(fd,bf,l); close(fd);
  128.     if(lc<0 || lc>l || (lc!=l && t==0))
  129.       {if(buf==NULL) free(bf); else buf[0]=0; return NULL;}
  130.     bf[lc]=0; _tolinux(bf); return bf;
  131. }
  132.  
  133. /* get option word in a string */
  134. void _getopt(char *name, char *p)
  135. {
  136.     char *p1, *p2, *p3, *p4;
  137.     char buf[MAX_LINELEN+1];
  138.  
  139.     snprintf(buf,sizeof(buf),"%s",p);
  140.     p1=find_word_start(name);
  141.     for(p2=buf;*p2;p2++) {
  142.       if(myisspace(*p2)) *p2=' ';
  143.       if(*p2=='=') *p2='        ';
  144.     }
  145.     *p=0;
  146.     p2=wordchr(buf,p1); if(p2==NULL) return;
  147.     for(p3=find_word_end(p2);myisspace(*p3);p3++) {
  148.       if(*p3==' ') {
  149.          p3=find_word_start(p3);
  150.          switch(*p3) {
  151.             case '"': {
  152.               p4=strchr(p3+1,'"');
  153.               goto tested;
  154.             }
  155.             case '(': {
  156.               p4=find_matching(p3+1,')');
  157.               goto tested;
  158.             }
  159.             case '[': {
  160.               p4=find_matching(p3+1,']');
  161.               goto tested;
  162.             }
  163.             case '{': {
  164.               p4=find_matching(p3+1,'}');
  165.               tested:
  166.               if(p4) {
  167.                 p3++; *p4=0; break;
  168.               }
  169.               else goto nomatch;
  170.           }
  171.           default: {
  172.               nomatch:
  173.               *find_word_end(p3)=0;
  174.           }
  175.          }
  176.          mystrncpy(p,p3,MAX_LINELEN);
  177.          return;
  178.        }
  179.     }
  180.     *find_word_end(p2)=0;
  181.     memmove(p,p2,strlen(p2)+1);
  182. }
  183.  
  184. void _getdef(char buf[], char *name, char value[])
  185. {
  186.     char *p1, *p2, *p3, *p4;
  187.  
  188.     if(*name==0) goto nothing;     /* this would create segfault. */
  189.     for(p1=strstr(buf,name); p1!=NULL; p1=strstr(p1+1,name)) {
  190.      p2=find_word_start(p1+strlen(name));
  191.      if((p1>buf && !isspace(*(p1-1))) || *p2!='=') continue;
  192.      p3=p1; while(p3>buf && *(p3-1)!='\n') p3--;
  193.      p3=find_word_start(p3);
  194.      if(p3<p1 && *p3!='!') continue;
  195.      if(p3<p1) {
  196.          p3++; p4=find_word_end(p3);
  197.          if(find_word_start(p4)!=p1) continue;
  198.          if(p4-p3!=3 || (strncmp(p3,"set",3)!=0 &&
  199.             strncmp(p3,"let",3)!=0 &&
  200.             strncmp(p3,"def",3)!=0)) {
  201.            if(p4-p3!=6 || strncmp(p3,"define",6)!=0) continue;
  202.          }
  203.      }
  204.      p2++;p3=strchr(p2,'\n'); if(p3==NULL) p3=p2+strlen(p2);
  205.      p2=find_word_start(p2);
  206.      if(p2>p3) goto nothing;
  207.      if(p3-p2>=MAX_LINELEN) error("string_too_long def %s",name);
  208.      memmove(value,p2,p3-p2); value[p3-p2]=0;
  209.      strip_trailing_spaces(value); return;
  210.     }
  211. nothing:
  212.     value[0]=0; return;
  213. }
  214.  
  215. char fnbuf[MAX_FNAME+1];
  216.  
  217. /* make a filename and check length */
  218. char *mkfname(char buf[], char *s,...)
  219. {
  220.     va_list vp;
  221.     char *p;
  222.  
  223.     if(buf==NULL) p=fnbuf; else p=buf;
  224.     va_start(vp,s);
  225.     vsnprintf(p,MAX_FNAME,s,vp);
  226.     va_end(vp);
  227.     if(strlen(p)>=MAX_FNAME-1) error("name_too_long %.20s",p);
  228.     return p;
  229. }
  230.  
  231.  
  232. #include "translate.c"
  233. #include "match.c"
  234. #include "compile.c"
  235.  
  236. void getparms(void)
  237. {
  238.     char *p, *p2, *p3, lbuf[8];
  239.     char buf[MAX_LINELEN+1], pbuf[MAX_LINELEN+1];
  240.     struct stat st;
  241.     int i;
  242.  
  243.     cmd=0;
  244.     p=getenv("wims_exec_parm");
  245.     if(p==NULL) return;
  246.     snprintf(pbuf,sizeof(pbuf),"%s",p);
  247.     rows2lines(pbuf);
  248.     p2=strchr(pbuf,'\n'); if(p2==NULL) return; else *p2++=0;
  249.     p=find_word_start(pbuf);
  250.     p3=find_word_end(p); if(p3-p>=sizeof(cmdbuf)) return;
  251.     if(*p==0) return; else *p3++=0;
  252.     memmove(cmdbuf,p,p3-p); cmdbuf[p3-p]=0;
  253.     p=p2; p2=strchr(p,'\n'); if(p2==NULL) p2=p+strlen(p); else *p2++=0;
  254.     if(p2<=find_word_start(p)) return;
  255.     if(p2-p<sizeof(textbuf)) {
  256.        memmove(textbuf,p,p2-p); textbuf[p2-p]=0;
  257.     }
  258.     p=p2; p2=p+strlen(p);
  259.     if(p2>p && p2-p<sizeof(stbuf)) {
  260.      memmove(stbuf,p,p2-p); stbuf[p2-p]=0;
  261.     }
  262.     i=search_list(cmdlist,cmdcnt,sizeof(cmdlist[0]),cmdbuf);
  263.     if(i>=0) cmd=cmdlist[i].value;
  264.     else error("bad_command %.20s",cmdbuf);
  265.     snprintf(cmdparm,sizeof(cmdparm),"%s",p2);
  266.  
  267.     options=0;
  268.     p=getenv("w_module_language"); if(p==NULL) p="";
  269.     snprintf(lbuf,sizeof(lbuf),"%2s",p);
  270.     if(*p3) {
  271.       snprintf(buf,sizeof(buf),"%s",p3);
  272.       _getopt("style",buf);
  273.       snprintf(style,sizeof(style),"%s",find_word_start(buf));
  274.       *find_word_end(style)=0;
  275.       snprintf(buf,sizeof(buf),"%s",p3);
  276.       _getopt("language",buf);
  277.       if(buf[0]) snprintf(lbuf,sizeof(lbuf),"%2s",buf);
  278.     }
  279.     lbuf[2]=0;
  280.     if(!myisalpha(lbuf[0]) || !myisalpha(lbuf[1])) ovlstrcpy(lbuf,"en");
  281.     styledir[0]=defbuf[0]=optionbuf[0]=buf[0]=0;
  282.     if(*style) {
  283.       p=getenv("module_dir");
  284.       if(p==NULL) {               /* non-wims operation */
  285.           snprintf(styledir,sizeof(styledir),"%s",style);
  286.       }
  287.       else {
  288.           for(i=0;i<MAX_NAMELEN && myisalnum(style[i]);i++);
  289.           style[i]=0;
  290.           if(style[0]) {            /* style defined */
  291.              if(*p!='/' && strstr(p,"..")==NULL) {      /* check module dir */
  292.                 snprintf(styledir,sizeof(styledir),"%s/symtext/%s/%s/def",p,lbuf,style);
  293.                 if(stat(styledir,&st)) styledir[0]=0;
  294.              }
  295.              if(styledir[0]==0) {      /* check default */
  296.                 snprintf(styledir,sizeof(styledir),"%s/symtext/%s/%s/def",defaultdir,lbuf,style);
  297.                 if(stat(styledir,&st)) error("style_not_found %s",style);
  298.              }
  299.           }
  300.       }
  301.       if(styledir[0]) {            /* get def */
  302.           readfile(styledir,defbuf,sizeof(defbuf));
  303.           styledir[strlen(styledir)-4]=0;
  304.           suffix_dic(mkfname(NULL,"%s/suffix",styledir));
  305.           transdic=diccnt;
  306.           if(prepare_dic("trans")==NULL) transdic=-1;
  307.           dic[transdic].unknown_type=unk_leave;
  308.           macrodic=diccnt;
  309.           if(prepare_dic("macros")==NULL) macrodic=-1;
  310.           dic[macrodic].unknown_type=unk_delete;
  311.       }
  312.     }
  313.     _getdef(defbuf,"option",buf);
  314.     snprintf(optionbuf,sizeof(optionbuf),"%s %s",p3,buf);
  315.     if(wordchr(optionbuf,"nocase")!=NULL) options|=op_nocase;
  316.     if(wordchr(optionbuf,"deaccent")!=NULL) options|=op_deaccent;
  317.     if(wordchr(optionbuf,"reaccent")!=NULL) options|=op_reaccent;
  318.     if(wordchr(optionbuf,"nopunct")!=NULL) options|=op_nopunct;
  319.     if(wordchr(optionbuf,"nomath")!=NULL) options|=op_nomath;
  320.     if(wordchr(optionbuf,"noparenthesis")!=NULL) options|=op_noparenth;
  321.     if(wordchr(optionbuf,"noparentheses")!=NULL) options|=op_noparenth;
  322.     if(wordchr(optionbuf,"nocs")!=NULL) options|=op_nocs;
  323.     if(wordchr(optionbuf,"noquote")!=NULL) options|=op_noquote;
  324.     if(wordchr(optionbuf,"matchall")!=NULL) options|=op_matchall;
  325.     if(wordchr(optionbuf,"abconly")!=NULL) options|=op_alphaonly;
  326.     if(wordchr(optionbuf,"onlyabc")!=NULL) options|=op_alphaonly;
  327.     if(wordchr(optionbuf,"alnumonly")!=NULL) options|=op_alnumonly;
  328.     if(wordchr(optionbuf,"onlyalnum")!=NULL) options|=op_alnumonly;
  329.  
  330.     if(cmd==cmd_comp || cmd==cmd_debug) {
  331.       _getopt("debug",optionbuf);
  332.       if(optionbuf[0]) {
  333.           i=atoi(optionbuf);
  334.           if(i>0 || strcmp(optionbuf,"0")==0) debug=i; else debug=1;
  335.           if(debug>0) cmd=cmd_debug;
  336.       }
  337.     }
  338.     strip_enclosing_par(textbuf);
  339.     strfold(textbuf);
  340. }
  341.  
  342. int verify_tables(void)
  343. {
  344.     if(verify_order(builtin,builtincnt,sizeof(builtin[0]))) return -1;
  345.     if(verify_order(cmdlist,cmdcnt,sizeof(cmdlist[0]))) return -1;
  346.  
  347.     return 0;
  348. }
  349. void (*string_modify)(char *start, char *bad_beg, char *bad_end, char *good,...)=string_modify1;
  350.  
  351. int main(int argc, char *argv[])
  352. {
  353.     int i, n, mat;
  354.     char *p1, *p2;
  355.     char lbuf[MAX_LINELEN+1];
  356.  
  357.     if(argc>1 && strcmp(argv[1],"-t")==0) {
  358.       if(verify_tables()==0) {
  359.          printf("Table orders OK.\n");
  360.          return 0;
  361.       }
  362.       else return 1;
  363.     }
  364.     error1=error2=_error; debug=0;
  365.     wptr=wbuf; wbuf[0]=0;
  366.     getparms();
  367.     Mnext=Mbuf; Mcnt=0;
  368.     switch(cmd) {
  369.       case cmd_comp: {
  370.          comp:
  371.          n=linenum(stbuf);
  372.          for(mat=0,i=1,p1=stbuf;i<=n;i++,p1=p2) {
  373.             p2=find_line_end(p1); if(*p2) *p2++=0;
  374.             p1=find_word_start(p1);
  375.             if(*p1==0) continue;
  376.             snprintf(lbuf,sizeof(lbuf),"%s",p1);
  377.             compile(lbuf);
  378.             mat=match(textbuf);
  379.             if(mat) {
  380.                 printf("MATCH %d %s\n",i,outbuf);
  381.                 if((options&op_matchall)==0) break;
  382.             }
  383.           }
  384.           if(debug) fprintf(stderr,"word list: %s\n",wbuf);
  385.           break;
  386.       }
  387.       case cmd_debug: {
  388.           if(debug==0) debug=1;
  389.           fprintf(stderr,"debug=%d.\n",debug);
  390.           for(i=0;i<diccnt;i++)
  391.             fprintf(stderr,"Dictionary %d: %s, %d entries.\n",
  392.                   i+1,dic[i].name,dic[i].len);
  393.           goto comp;
  394.       }
  395.       case cmd_random: {
  396.  
  397.           break;
  398.       }
  399.       case cmd_wordlist: {
  400.  
  401.           break;
  402.       }
  403.       case cmd_1: {
  404.  
  405.           break;
  406.       }
  407.  
  408.       case cmd_none:
  409.       default: return 1;
  410.     }
  411.     return 0;
  412. }
  413.  
  414.