Subversion Repositories wimsdev

Rev

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

Rev Author Line No. Line
10 reyssat 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
 
8084 bpr 18
/* This program makes comparison between two text strings,
19
 * according to the symtext syntax. */
10 reyssat 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.
8084 bpr 27
 *
10 reyssat 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"
8122 bpr 37
#include "../../Lib/liblines.c"
10 reyssat 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;
8084 bpr 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)
10 reyssat 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[]={
8084 bpr 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},
10 reyssat 86
    {"wordlist",cmd_wordlist},
8084 bpr 87
    {"words",   cmd_wordlist}
10 reyssat 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
 
8084 bpr 109
/* read-in a file into buffer. Use open() and read().
110
 * Return buffer address which will be malloc'ed if buf=NULL.
111
 */
10 reyssat 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) {
8084 bpr 122
     if(buflen<MAX_LINELEN) l=buflen-1;
123
     else error("file_too_long %s",fname);
10 reyssat 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);
8084 bpr 128
    if(lc<0 || lc>l || (lc!=l && t==0))
129
      {if(buf==NULL) free(bf); else buf[0]=0; return NULL;}
10 reyssat 130
    bf[lc]=0; _tolinux(bf); return bf;
131
}
132
 
8084 bpr 133
/* get option word in a string */
10 reyssat 134
void _getopt(char *name, char *p)
135
{
136
    char *p1, *p2, *p3, *p4;
137
    char buf[MAX_LINELEN+1];
8084 bpr 138
 
10 reyssat 139
    snprintf(buf,sizeof(buf),"%s",p);
140
    p1=find_word_start(name);
141
    for(p2=buf;*p2;p2++) {
8084 bpr 142
      if(myisspace(*p2)) *p2=' ';
143
      if(*p2=='=') *p2='        ';
10 reyssat 144
    }
145
    *p=0;
146
    p2=wordchr(buf,p1); if(p2==NULL) return;
147
    for(p3=find_word_end(p2);myisspace(*p3);p3++) {
8084 bpr 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
       }
10 reyssat 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
 
8084 bpr 188
    if(*name==0) goto nothing;     /* this would create segfault. */
10 reyssat 189
    for(p1=strstr(buf,name); p1!=NULL; p1=strstr(p1+1,name)) {
8084 bpr 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;
10 reyssat 210
    }
211
nothing:
212
    value[0]=0; return;
213
}
214
 
215
char fnbuf[MAX_FNAME+1];
216
 
8084 bpr 217
/* make a filename and check length */
10 reyssat 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
 
8122 bpr 231
 
10 reyssat 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;
8084 bpr 242
 
10 reyssat 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;
8084 bpr 249
    p=find_word_start(pbuf);
10 reyssat 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)) {
8084 bpr 256
       memmove(textbuf,p,p2-p); textbuf[p2-p]=0;
10 reyssat 257
    }
258
    p=p2; p2=p+strlen(p);
259
    if(p2>p && p2-p<sizeof(stbuf)) {
8084 bpr 260
     memmove(stbuf,p,p2-p); stbuf[p2-p]=0;
10 reyssat 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);
8084 bpr 266
 
10 reyssat 267
    options=0;
268
    p=getenv("w_module_language"); if(p==NULL) p="";
269
    snprintf(lbuf,sizeof(lbuf),"%2s",p);
270
    if(*p3) {
8084 bpr 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);
10 reyssat 278
    }
279
    lbuf[2]=0;
3718 reyssat 280
    if(!myisalpha(lbuf[0]) || !myisalpha(lbuf[1])) ovlstrcpy(lbuf,"en");
10 reyssat 281
    styledir[0]=defbuf[0]=optionbuf[0]=buf[0]=0;
282
    if(*style) {
8084 bpr 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
      }
10 reyssat 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;
8084 bpr 329
 
10 reyssat 330
    if(cmd==cmd_comp || cmd==cmd_debug) {
8084 bpr 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
      }
10 reyssat 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;
8084 bpr 346
 
10 reyssat 347
    return 0;
348
}
8086 bpr 349
void (*string_modify)(char *start, char *bad_beg, char *bad_end, char *good,...)=string_modify1;
10 reyssat 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) {
8084 bpr 358
      if(verify_tables()==0) {
359
         printf("Table orders OK.\n");
360
         return 0;
361
      }
362
      else return 1;
10 reyssat 363
    }
364
    error1=error2=_error; debug=0;
365
    wptr=wbuf; wbuf[0]=0;
366
    getparms();
367
    Mnext=Mbuf; Mcnt=0;
368
    switch(cmd) {
8084 bpr 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;
10 reyssat 410
    }
411
    return 0;
412
}
413