Rev 8161 | 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" |
||
37 | |||
38 | struct block blockbuf[MAX_BLOCKS]; |
||
39 | int nextblock; |
||
40 | listtype listbuf[MAX_LISTS]; |
||
41 | int nextlist; |
||
42 | listtype tagbuf[MAX_BLOCKS]; |
||
43 | int nexttag; |
||
44 | |||
45 | struct poolstruct poolbuf[MAX_POOLS]; |
||
46 | int nextpool; |
||
47 | |||
48 | int options; |
||
49 | |||
50 | char cmdbuf[256], stbuf[MAX_LINELEN+1], textbuf[MAX_LINELEN+1]; |
||
51 | char wbuf[MAX_LINELEN+1]; |
||
52 | char cmdparm[1024]; |
||
53 | char defbuf[MAX_LINELEN+1]; |
||
54 | char style[MAX_NAMELEN+1]; |
||
55 | char styledir[MAX_FNAME+1]; |
||
56 | char optionbuf[1024]; |
||
8161 | bpr | 57 | char outbuf[OUTSIZE]; |
10 | reyssat | 58 | char *outptr, *wptr; |
59 | int debug; |
||
60 | |||
61 | enum { |
||
62 | cmd_none, cmd_comp, cmd_debug, cmd_random, cmd_1, cmd_wordlist |
||
63 | }; |
||
64 | struct { |
||
65 | char *name; int value; |
||
66 | } cmdlist[]={ |
||
8084 | bpr | 67 | {"1", cmd_1}, |
68 | {"comp", cmd_comp}, |
||
69 | {"compare", cmd_comp}, |
||
70 | {"debug", cmd_debug}, |
||
71 | {"match", cmd_comp}, |
||
72 | {"rand", cmd_random}, |
||
73 | {"random", cmd_random}, |
||
10 | reyssat | 74 | {"wordlist",cmd_wordlist}, |
8084 | bpr | 75 | {"words", cmd_wordlist} |
10 | reyssat | 76 | }; |
77 | #define cmdcnt (sizeof(cmdlist)/sizeof(cmdlist[0])) |
||
78 | int cmd; |
||
79 | |||
8195 | bpr | 80 | void sym_error(char *msg,...) |
10 | reyssat | 81 | { |
82 | va_list vp; |
||
83 | char buf[1024]; |
||
84 | |||
85 | va_start(vp,msg); |
||
86 | vsnprintf(buf,sizeof(buf),msg,vp); |
||
87 | va_end(vp); |
||
88 | printf("ERROR\n%s\n",buf); |
||
89 | exit(1); |
||
90 | } |
||
91 | |||
8084 | bpr | 92 | /* read-in a file into buffer. Use open() and read(). |
93 | * Return buffer address which will be malloc'ed if buf=NULL. |
||
94 | */ |
||
10 | reyssat | 95 | char *readfile(char *fname, char buf[], long int buflen) |
96 | { |
||
97 | int fd, t; |
||
98 | struct stat st; |
||
99 | long int l, lc; |
||
100 | char *bf; |
||
101 | t=0; if(buf) buf[0]=0; |
||
102 | if(stat(fname,&st)) return NULL; |
||
103 | l=st.st_size; if(l<0) return NULL; |
||
104 | if(l>=buflen) { |
||
8084 | bpr | 105 | if(buflen<MAX_LINELEN) l=buflen-1; |
8195 | bpr | 106 | else sym_error("file_too_long %s",fname); |
10 | reyssat | 107 | } |
108 | fd=open(fname,O_RDONLY); if(fd==-1) return NULL; |
||
109 | if(buf==NULL) bf=xmalloc(l+8); else {bf=buf;if(l==0) {t=1; l=buflen-1;}} |
||
110 | lc=read(fd,bf,l); close(fd); |
||
8084 | bpr | 111 | if(lc<0 || lc>l || (lc!=l && t==0)) |
112 | {if(buf==NULL) free(bf); else buf[0]=0; return NULL;} |
||
10 | reyssat | 113 | bf[lc]=0; _tolinux(bf); return bf; |
114 | } |
||
115 | |||
8084 | bpr | 116 | /* get option word in a string */ |
10 | reyssat | 117 | void _getopt(char *name, char *p) |
118 | { |
||
119 | char *p1, *p2, *p3, *p4; |
||
120 | char buf[MAX_LINELEN+1]; |
||
8084 | bpr | 121 | |
10 | reyssat | 122 | snprintf(buf,sizeof(buf),"%s",p); |
123 | p1=find_word_start(name); |
||
124 | for(p2=buf;*p2;p2++) { |
||
8084 | bpr | 125 | if(myisspace(*p2)) *p2=' '; |
126 | if(*p2=='=') *p2=' '; |
||
10 | reyssat | 127 | } |
128 | *p=0; |
||
129 | p2=wordchr(buf,p1); if(p2==NULL) return; |
||
130 | for(p3=find_word_end(p2);myisspace(*p3);p3++) { |
||
8084 | bpr | 131 | if(*p3==' ') { |
132 | p3=find_word_start(p3); |
||
133 | switch(*p3) { |
||
134 | case '"': { |
||
135 | p4=strchr(p3+1,'"'); |
||
136 | goto tested; |
||
137 | } |
||
138 | case '(': { |
||
139 | p4=find_matching(p3+1,')'); |
||
140 | goto tested; |
||
141 | } |
||
142 | case '[': { |
||
143 | p4=find_matching(p3+1,']'); |
||
144 | goto tested; |
||
145 | } |
||
146 | case '{': { |
||
147 | p4=find_matching(p3+1,'}'); |
||
148 | tested: |
||
149 | if(p4) { |
||
150 | p3++; *p4=0; break; |
||
151 | } |
||
152 | else goto nomatch; |
||
153 | } |
||
154 | default: { |
||
155 | nomatch: |
||
156 | *find_word_end(p3)=0; |
||
157 | } |
||
158 | } |
||
159 | mystrncpy(p,p3,MAX_LINELEN); |
||
160 | return; |
||
161 | } |
||
10 | reyssat | 162 | } |
163 | *find_word_end(p2)=0; |
||
164 | memmove(p,p2,strlen(p2)+1); |
||
165 | } |
||
166 | |||
167 | void _getdef(char buf[], char *name, char value[]) |
||
168 | { |
||
169 | char *p1, *p2, *p3, *p4; |
||
170 | |||
8084 | bpr | 171 | if(*name==0) goto nothing; /* this would create segfault. */ |
10 | reyssat | 172 | for(p1=strstr(buf,name); p1!=NULL; p1=strstr(p1+1,name)) { |
8084 | bpr | 173 | p2=find_word_start(p1+strlen(name)); |
174 | if((p1>buf && !isspace(*(p1-1))) || *p2!='=') continue; |
||
175 | p3=p1; while(p3>buf && *(p3-1)!='\n') p3--; |
||
176 | p3=find_word_start(p3); |
||
177 | if(p3<p1 && *p3!='!') continue; |
||
178 | if(p3<p1) { |
||
179 | p3++; p4=find_word_end(p3); |
||
180 | if(find_word_start(p4)!=p1) continue; |
||
181 | if(p4-p3!=3 || (strncmp(p3,"set",3)!=0 && |
||
182 | strncmp(p3,"let",3)!=0 && |
||
183 | strncmp(p3,"def",3)!=0)) { |
||
184 | if(p4-p3!=6 || strncmp(p3,"define",6)!=0) continue; |
||
185 | } |
||
186 | } |
||
187 | p2++;p3=strchr(p2,'\n'); if(p3==NULL) p3=p2+strlen(p2); |
||
188 | p2=find_word_start(p2); |
||
189 | if(p2>p3) goto nothing; |
||
8195 | bpr | 190 | if(p3-p2>=MAX_LINELEN) sym_error("string_too_long def %s",name); |
8084 | bpr | 191 | memmove(value,p2,p3-p2); value[p3-p2]=0; |
192 | strip_trailing_spaces(value); return; |
||
10 | reyssat | 193 | } |
194 | nothing: |
||
195 | value[0]=0; return; |
||
196 | } |
||
197 | |||
198 | char fnbuf[MAX_FNAME+1]; |
||
199 | |||
8084 | bpr | 200 | /* make a filename and check length */ |
10 | reyssat | 201 | char *mkfname(char buf[], char *s,...) |
202 | { |
||
203 | va_list vp; |
||
204 | char *p; |
||
205 | |||
206 | if(buf==NULL) p=fnbuf; else p=buf; |
||
207 | va_start(vp,s); |
||
208 | vsnprintf(p,MAX_FNAME,s,vp); |
||
209 | va_end(vp); |
||
8195 | bpr | 210 | if(strlen(p)>=MAX_FNAME-1) sym_error("name_too_long %.20s",p); |
10 | reyssat | 211 | return p; |
212 | } |
||
213 | |||
214 | void getparms(void) |
||
215 | { |
||
216 | char *p, *p2, *p3, lbuf[8]; |
||
217 | char buf[MAX_LINELEN+1], pbuf[MAX_LINELEN+1]; |
||
218 | struct stat st; |
||
219 | int i; |
||
8084 | bpr | 220 | |
10 | reyssat | 221 | cmd=0; |
222 | p=getenv("wims_exec_parm"); |
||
223 | if(p==NULL) return; |
||
224 | snprintf(pbuf,sizeof(pbuf),"%s",p); |
||
225 | rows2lines(pbuf); |
||
226 | p2=strchr(pbuf,'\n'); if(p2==NULL) return; else *p2++=0; |
||
8084 | bpr | 227 | p=find_word_start(pbuf); |
10 | reyssat | 228 | p3=find_word_end(p); if(p3-p>=sizeof(cmdbuf)) return; |
229 | if(*p==0) return; else *p3++=0; |
||
230 | memmove(cmdbuf,p,p3-p); cmdbuf[p3-p]=0; |
||
231 | p=p2; p2=strchr(p,'\n'); if(p2==NULL) p2=p+strlen(p); else *p2++=0; |
||
232 | if(p2<=find_word_start(p)) return; |
||
233 | if(p2-p<sizeof(textbuf)) { |
||
8084 | bpr | 234 | memmove(textbuf,p,p2-p); textbuf[p2-p]=0; |
10 | reyssat | 235 | } |
236 | p=p2; p2=p+strlen(p); |
||
237 | if(p2>p && p2-p<sizeof(stbuf)) { |
||
8084 | bpr | 238 | memmove(stbuf,p,p2-p); stbuf[p2-p]=0; |
10 | reyssat | 239 | } |
240 | i=search_list(cmdlist,cmdcnt,sizeof(cmdlist[0]),cmdbuf); |
||
241 | if(i>=0) cmd=cmdlist[i].value; |
||
8195 | bpr | 242 | else sym_error("bad_command %.20s",cmdbuf); |
10 | reyssat | 243 | snprintf(cmdparm,sizeof(cmdparm),"%s",p2); |
8084 | bpr | 244 | |
10 | reyssat | 245 | options=0; |
246 | p=getenv("w_module_language"); if(p==NULL) p=""; |
||
247 | snprintf(lbuf,sizeof(lbuf),"%2s",p); |
||
248 | if(*p3) { |
||
8084 | bpr | 249 | snprintf(buf,sizeof(buf),"%s",p3); |
250 | _getopt("style",buf); |
||
251 | snprintf(style,sizeof(style),"%s",find_word_start(buf)); |
||
252 | *find_word_end(style)=0; |
||
253 | snprintf(buf,sizeof(buf),"%s",p3); |
||
254 | _getopt("language",buf); |
||
255 | if(buf[0]) snprintf(lbuf,sizeof(lbuf),"%2s",buf); |
||
10 | reyssat | 256 | } |
257 | lbuf[2]=0; |
||
3718 | reyssat | 258 | if(!myisalpha(lbuf[0]) || !myisalpha(lbuf[1])) ovlstrcpy(lbuf,"en"); |
10 | reyssat | 259 | styledir[0]=defbuf[0]=optionbuf[0]=buf[0]=0; |
260 | if(*style) { |
||
8084 | bpr | 261 | p=getenv("module_dir"); |
262 | if(p==NULL) { /* non-wims operation */ |
||
263 | snprintf(styledir,sizeof(styledir),"%s",style); |
||
264 | } |
||
265 | else { |
||
266 | for(i=0;i<MAX_NAMELEN && myisalnum(style[i]);i++); |
||
267 | style[i]=0; |
||
268 | if(style[0]) { /* style defined */ |
||
269 | if(*p!='/' && strstr(p,"..")==NULL) { /* check module dir */ |
||
270 | snprintf(styledir,sizeof(styledir),"%s/symtext/%s/%s/def",p,lbuf,style); |
||
271 | if(stat(styledir,&st)) styledir[0]=0; |
||
272 | } |
||
273 | if(styledir[0]==0) { /* check default */ |
||
274 | snprintf(styledir,sizeof(styledir),"%s/symtext/%s/%s/def",defaultdir,lbuf,style); |
||
8195 | bpr | 275 | if(stat(styledir,&st)) sym_error("style_not_found %s",style); |
8084 | bpr | 276 | } |
277 | } |
||
278 | } |
||
279 | if(styledir[0]) { /* get def */ |
||
280 | readfile(styledir,defbuf,sizeof(defbuf)); |
||
281 | styledir[strlen(styledir)-4]=0; |
||
282 | suffix_dic(mkfname(NULL,"%s/suffix",styledir)); |
||
283 | transdic=diccnt; |
||
284 | if(prepare_dic("trans")==NULL) transdic=-1; |
||
285 | dic[transdic].unknown_type=unk_leave; |
||
286 | macrodic=diccnt; |
||
287 | if(prepare_dic("macros")==NULL) macrodic=-1; |
||
288 | dic[macrodic].unknown_type=unk_delete; |
||
289 | } |
||
10 | reyssat | 290 | } |
291 | _getdef(defbuf,"option",buf); |
||
292 | snprintf(optionbuf,sizeof(optionbuf),"%s %s",p3,buf); |
||
293 | if(wordchr(optionbuf,"nocase")!=NULL) options|=op_nocase; |
||
294 | if(wordchr(optionbuf,"deaccent")!=NULL) options|=op_deaccent; |
||
295 | if(wordchr(optionbuf,"reaccent")!=NULL) options|=op_reaccent; |
||
296 | if(wordchr(optionbuf,"nopunct")!=NULL) options|=op_nopunct; |
||
297 | if(wordchr(optionbuf,"nomath")!=NULL) options|=op_nomath; |
||
298 | if(wordchr(optionbuf,"noparenthesis")!=NULL) options|=op_noparenth; |
||
299 | if(wordchr(optionbuf,"noparentheses")!=NULL) options|=op_noparenth; |
||
300 | if(wordchr(optionbuf,"nocs")!=NULL) options|=op_nocs; |
||
301 | if(wordchr(optionbuf,"noquote")!=NULL) options|=op_noquote; |
||
302 | if(wordchr(optionbuf,"matchall")!=NULL) options|=op_matchall; |
||
303 | if(wordchr(optionbuf,"abconly")!=NULL) options|=op_alphaonly; |
||
304 | if(wordchr(optionbuf,"onlyabc")!=NULL) options|=op_alphaonly; |
||
305 | if(wordchr(optionbuf,"alnumonly")!=NULL) options|=op_alnumonly; |
||
306 | if(wordchr(optionbuf,"onlyalnum")!=NULL) options|=op_alnumonly; |
||
8084 | bpr | 307 | |
10 | reyssat | 308 | if(cmd==cmd_comp || cmd==cmd_debug) { |
8084 | bpr | 309 | _getopt("debug",optionbuf); |
310 | if(optionbuf[0]) { |
||
311 | i=atoi(optionbuf); |
||
312 | if(i>0 || strcmp(optionbuf,"0")==0) debug=i; else debug=1; |
||
313 | if(debug>0) cmd=cmd_debug; |
||
314 | } |
||
10 | reyssat | 315 | } |
316 | strip_enclosing_par(textbuf); |
||
317 | strfold(textbuf); |
||
318 | } |
||
319 | |||
320 | int verify_tables(void) |
||
321 | { |
||
322 | if(verify_order(builtin,builtincnt,sizeof(builtin[0]))) return -1; |
||
323 | if(verify_order(cmdlist,cmdcnt,sizeof(cmdlist[0]))) return -1; |
||
8084 | bpr | 324 | |
10 | reyssat | 325 | return 0; |
326 | } |
||
327 | |||
328 | int main(int argc, char *argv[]) |
||
329 | { |
||
330 | int i, n, mat; |
||
331 | char *p1, *p2; |
||
332 | char lbuf[MAX_LINELEN+1]; |
||
333 | |||
334 | if(argc>1 && strcmp(argv[1],"-t")==0) { |
||
8084 | bpr | 335 | if(verify_tables()==0) { |
336 | printf("Table orders OK.\n"); |
||
337 | return 0; |
||
338 | } |
||
339 | else return 1; |
||
10 | reyssat | 340 | } |
8161 | bpr | 341 | debug=0; |
10 | reyssat | 342 | wptr=wbuf; wbuf[0]=0; |
343 | getparms(); |
||
344 | Mnext=Mbuf; Mcnt=0; |
||
345 | switch(cmd) { |
||
8084 | bpr | 346 | case cmd_comp: { |
347 | comp: |
||
348 | n=linenum(stbuf); |
||
349 | for(mat=0,i=1,p1=stbuf;i<=n;i++,p1=p2) { |
||
350 | p2=find_line_end(p1); if(*p2) *p2++=0; |
||
351 | p1=find_word_start(p1); |
||
352 | if(*p1==0) continue; |
||
353 | snprintf(lbuf,sizeof(lbuf),"%s",p1); |
||
354 | compile(lbuf); |
||
355 | mat=match(textbuf); |
||
356 | if(mat) { |
||
357 | printf("MATCH %d %s\n",i,outbuf); |
||
358 | if((options&op_matchall)==0) break; |
||
359 | } |
||
360 | } |
||
361 | if(debug) fprintf(stderr,"word list: %s\n",wbuf); |
||
362 | break; |
||
363 | } |
||
364 | case cmd_debug: { |
||
365 | if(debug==0) debug=1; |
||
366 | fprintf(stderr,"debug=%d.\n",debug); |
||
367 | for(i=0;i<diccnt;i++) |
||
368 | fprintf(stderr,"Dictionary %d: %s, %d entries.\n", |
||
369 | i+1,dic[i].name,dic[i].len); |
||
370 | goto comp; |
||
371 | } |
||
372 | case cmd_random: { |
||
373 | |||
374 | break; |
||
375 | } |
||
376 | case cmd_wordlist: { |
||
377 | |||
378 | break; |
||
379 | } |
||
380 | case cmd_1: { |
||
381 | |||
382 | break; |
||
383 | } |
||
384 | |||
385 | case cmd_none: |
||
386 | default: return 1; |
||
10 | reyssat | 387 | } |
388 | return 0; |
||
389 | } |
||
390 |