Rev 12047 | Rev 12196 | 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) 1998-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 | |||
7673 | bpr | 18 | /* This is part of wims source. |
8155 | bpr | 19 | * This file does computations and output. |
20 | */ |
||
8185 | bpr | 21 | #include "wims.h" |
10 | reyssat | 22 | |
23 | int _sort_numeric, _sort_nocase; |
||
24 | typedef struct SORT_STRUCT {char *str; double val; int serial;} SORT_STRUCT; |
||
25 | struct SORT_STRUCT sort_sep[MAX_SORT_ITEM+1]; |
||
26 | |||
27 | void secure_exec(void) |
||
28 | { |
||
29 | if((untrust&6)==0) return; |
||
30 | module_error("Illegal_command"); |
||
31 | } |
||
32 | |||
7673 | bpr | 33 | /* internal comparers */ |
10 | reyssat | 34 | int __sorter(const void *p1, const void *p2) |
35 | { |
||
36 | struct SORT_STRUCT *pp1, *pp2; |
||
7404 | bpr | 37 | |
10 | reyssat | 38 | pp1=(struct SORT_STRUCT *) p1; pp2=(struct SORT_STRUCT *) p2; |
39 | if(_sort_numeric) { |
||
7673 | bpr | 40 | double dd=(pp1->val)-(pp2->val); |
41 | if(dd>0) return 1; |
||
42 | if(dd<0) return -1; |
||
43 | return 0; |
||
10 | reyssat | 44 | } |
45 | if(_sort_nocase) return strcasecmp(pp1->str,pp2->str); |
||
46 | else return strcmp(pp1->str,pp2->str); |
||
47 | } |
||
48 | |||
49 | int _char_sorter(const void *c1, const void *c2) |
||
50 | { |
||
51 | if(_sort_nocase) return tolower(*(char *)c1)-tolower(*(char *)c2); |
||
52 | else return *(char *)c1-*(char *)c2; |
||
53 | } |
||
54 | |||
55 | enum {sort_char, sort_word, sort_item, sort_line, sort_row, |
||
56 | sort_numeric, sort_nocase, sort_reverse |
||
57 | }; |
||
58 | struct {char *name; int type; |
||
59 | } sort_keyw[]={ |
||
7673 | bpr | 60 | {"char",sort_char}, |
61 | {"chars",sort_char}, |
||
62 | {"character",sort_char}, |
||
63 | {"characters",sort_char}, |
||
64 | {"word",sort_word}, |
||
65 | {"words",sort_word}, |
||
66 | {"item",sort_item}, |
||
67 | {"items",sort_item}, |
||
68 | {"line",sort_line}, |
||
69 | {"lines",sort_line}, |
||
70 | {"list",sort_item}, |
||
71 | {"numeric",sort_numeric}, |
||
72 | {"numerical",sort_numeric}, |
||
73 | {"nocase",sort_nocase}, |
||
74 | {"ignorecase",sort_nocase}, |
||
75 | {"reverse",sort_reverse}, |
||
76 | {"row",sort_row}, |
||
77 | {"rows",sort_row} |
||
10 | reyssat | 78 | }; |
79 | #define sort_keyw_no (sizeof(sort_keyw)/sizeof(sort_keyw[0])) |
||
80 | |||
7673 | bpr | 81 | /* string sort */ |
10 | reyssat | 82 | void calc_sort(char *p) |
83 | { |
||
84 | char *p1, *p2, buf[MAX_LINELEN+1], *csep[MAX_SORT_ITEM+1]; |
||
85 | char fs=0; |
||
86 | int (*cutfn)(char *p,char *list[],int max); |
||
87 | int nocase=0, reverse=0, numeric=0, type; |
||
88 | int i,j,l,t,total; |
||
7404 | bpr | 89 | |
10 | reyssat | 90 | cutfn=NULL; |
91 | for(i=0,p1=find_word_start(p);i>=0;p1=find_word_start(p2)) { |
||
7673 | bpr | 92 | p2=find_word_end(p1); if(*p2!=0) *p2++=0; |
93 | for(i=0;i<sort_keyw_no && strcasecmp(p1,sort_keyw[i].name)!=0;i++); |
||
94 | if(i>=sort_keyw_no) module_error("syntax_error"); |
||
95 | switch(type=sort_keyw[i].type) { |
||
96 | case sort_nocase: nocase=1; break; |
||
97 | case sort_reverse: reverse=1; break; |
||
98 | case sort_numeric: numeric=1; break; |
||
99 | case sort_char: i=-1; break; |
||
100 | case sort_word: cutfn=cutwords; fs=' '; i=-1; break; |
||
101 | case sort_item: cutfn=cutitems; fs=','; i=-1; break; |
||
102 | case sort_row: |
||
103 | case sort_line: cutfn=cutlines; fs='\n'; i=-1; break; |
||
104 | } |
||
10 | reyssat | 105 | } |
106 | if(p1[0]=='o' && p1[1]=='f' && myisspace(p1[2])) p1=find_word_start(p1+2); |
||
107 | mystrncpy(buf,p1,sizeof(buf)); substit(buf); *p=0; |
||
108 | t=0; if(type==sort_row) t=rows2lines(buf); |
||
109 | _sort_nocase=nocase; _sort_numeric=numeric; |
||
110 | if(cutfn) { |
||
7673 | bpr | 111 | char ordbuf[MAX_LINELEN+1]; |
112 | total=cutfn(buf,csep,MAX_SORT_ITEM+1); |
||
113 | if(total<=0 || total>MAX_SORT_ITEM) return; |
||
114 | for(i=0;i<total;i++) { |
||
115 | sort_sep[i].str=csep[i]; |
||
116 | if(numeric) sort_sep[i].val=evalue(csep[i]); |
||
117 | } |
||
118 | for(i=0;i<total;i++) sort_sep[i].serial=i+1; |
||
119 | qsort(sort_sep,total,sizeof(sort_sep[0]),__sorter); |
||
120 | p1=p;p2=ordbuf;ordbuf[0]=0; |
||
121 | for(i=0;i<total;i++) { |
||
122 | if(reverse) j=total-1-i; else j=i; |
||
123 | l=strlen(sort_sep[j].str); |
||
124 | if(p1-p+l>=MAX_LINELEN-1) module_error("cmd_output_too_long"); |
||
125 | if(p1>p) *p1++=fs; |
||
126 | memmove(p1,sort_sep[j].str,l+1); p1+=l; |
||
127 | if(i>0) *p2++=','; |
||
128 | mystrncpy(p2,int2str(sort_sep[j].serial), |
||
129 | MAX_LINELEN-(p2-ordbuf)-1); |
||
130 | p2+=strlen(p2); |
||
131 | } |
||
132 | force_setvar("wims_sort_order",ordbuf); |
||
10 | reyssat | 133 | } |
134 | else { /* case of chars */ |
||
7673 | bpr | 135 | qsort(buf,strlen(buf),1,_char_sorter); |
136 | total=strlen(buf); |
||
137 | if(reverse) { |
||
138 | for(i=total-1;i>=0;i--) *(p+total-i-1)=buf[i]; |
||
139 | *(p+total)=0; |
||
140 | } |
||
141 | else memmove(p,buf,total+1); |
||
10 | reyssat | 142 | } |
143 | if(t) lines2rows(p); |
||
144 | } |
||
145 | |||
7673 | bpr | 146 | /* Print a debug output */ |
10 | reyssat | 147 | void calc_debug(char *p) |
148 | { |
||
149 | secure_exec(); setvar("debug",p); module_error("debug"); |
||
150 | } |
||
151 | |||
7673 | bpr | 152 | /* execute a command thru wimslogd */ |
10 | reyssat | 153 | void calc_daemon(char *p) |
154 | { |
||
155 | if(!trusted_module() || is_class_module) {*p=0; return;} |
||
156 | _daemoncmd(p); |
||
157 | } |
||
158 | |||
159 | void _get_exec_error(char *errorfname, char *cmdname) |
||
160 | { |
||
161 | char *p2; |
||
162 | char obuf[MAX_LINELEN+1]; |
||
163 | int l; |
||
164 | if(errorfname) accessfile(obuf,"e","%s",errorfname); |
||
165 | else { |
||
7673 | bpr | 166 | l=read(mxtab[multiexec_index].pipe_stderr[0],obuf,MAX_LINELEN/4); |
167 | if(l<0 || l>MAX_LINELEN) l=0; |
||
168 | obuf[l]=0; |
||
10 | reyssat | 169 | } |
170 | if(obuf[0]) { |
||
7673 | bpr | 171 | p2=find_word_end(obuf); |
172 | if((manageable<1 || strcasecmp(tmp_debug,"yes")!=0) && |
||
173 | !trusted_module() && |
||
174 | strncmp(p2," not_INStalled",strlen(" not_INStalled"))==0) { |
||
175 | *p2=0; setvar("missing_software",obuf); |
||
176 | snprintf(p2+1,MAX_LINELEN-strlen(obuf)-8,"missing_%s",obuf); |
||
177 | if(!outputing) user_error(p2+1); |
||
178 | } |
||
179 | p2=getvar("wims_exec_error"); if(p2==NULL) p2=""; |
||
180 | snprintf(tmplbuf,sizeof(tmplbuf),"%s\nERROR from %s:\n%s",p2,cmdname,obuf); |
||
181 | force_setvar("wims_exec_error",tmplbuf); |
||
10 | reyssat | 182 | } |
183 | } |
||
184 | |||
8155 | bpr | 185 | /* execute an external program |
186 | * The output of the external program should be put into |
||
187 | * a file session_directory/session/cmd.tmp. |
||
188 | */ |
||
10 | reyssat | 189 | void calc_exec(char *p) |
190 | { |
||
191 | int i,j,k; |
||
192 | char *cmd, *parm, *pp; |
||
193 | char namebuf[MAX_EXEC_NAME+1], cmdstr[MAX_LINELEN+256], obuf[MAX_LINELEN+1]; |
||
194 | char outfname[MAX_FNAME+1], errorfname[MAX_FNAME+1], |
||
195 | typefname[MAX_FNAME+1], varfname[MAX_FNAME+1]; |
||
196 | char *abuf[2]={NULL,NULL}; |
||
197 | WORKING_FILE wf; |
||
198 | if(robot_access || time(0)>=limtimex-1) { |
||
7673 | bpr | 199 | *p=0;return; |
10 | reyssat | 200 | } |
201 | cmd=find_word_start(p); if(*cmd==0) return; /* No command. */ |
||
202 | parm=find_word_end(cmd);j=parm-cmd;parm=find_word_start(parm); |
||
203 | if(j>MAX_EXEC_NAME) { |
||
7673 | bpr | 204 | wrong_command: |
205 | setvar(error_data_string,namebuf); module_error("bad_cmd"); |
||
206 | *p=0; return; /* should not occur */ |
||
10 | reyssat | 207 | } |
208 | memmove(namebuf,cmd,j); namebuf[j]=0; |
||
7673 | bpr | 209 | /* Specifying parent directory in command name is of course |
210 | * prohibited. |
||
211 | * The module developper cannot start from root, for bin_dir |
||
8155 | bpr | 212 | * will be prefixed to cmd. |
213 | */ |
||
10 | reyssat | 214 | if(strstr(namebuf,parent_dir_string)!=NULL) { |
7673 | bpr | 215 | setvar(error_data_string,namebuf); module_error("illegal_cmd"); |
216 | *p=0; return; |
||
10 | reyssat | 217 | } |
218 | snprintf(cmdstr,sizeof(cmdstr),"%s/%s",bin_dir,namebuf); |
||
219 | if(ftest(cmdstr)!=is_exec) goto wrong_command; |
||
220 | abuf[0]=cmdstr; |
||
221 | mkfname(outfname,"%s/exec.out",tmp_dir); |
||
222 | mkfname(errorfname,"%s/exec.err",tmp_dir); |
||
223 | mkfname(typefname,"%s/exec.type",tmp_dir); |
||
224 | unlink(typefname); |
||
225 | mkfname(varfname,"%s/exec.var",tmp_dir); |
||
226 | unlink(varfname); |
||
227 | if(!trusted_module()) setenv("untrust","yes",1); else unsetenv("untrust"); |
||
228 | if(strcmp(parm,"about")!=0 && multiexec(namebuf,abuf)) { |
||
7673 | bpr | 229 | fd_set rset; |
230 | struct timeval t; |
||
231 | int v1, v2, fd; |
||
7404 | bpr | 232 | |
7673 | bpr | 233 | i=strlen(parm); |
234 | fd=mxtab[multiexec_index].pipe_stdin[1]; |
||
235 | (void)write(fd,parm,i); |
||
236 | (void)write(fd,multiexec_random,strlen(multiexec_random)); |
||
237 | *p=0; i=0; k=MAX_LINELEN; fd=mxtab[multiexec_index].pipe_stdout[0]; |
||
238 | while(k>0) { |
||
239 | FD_ZERO(&rset); FD_SET(fd,&rset); |
||
240 | t.tv_sec=0; t.tv_usec=100000; v1=0; v2=300; /* 3 seconds */ |
||
241 | if(select(fd+1,&rset,NULL,NULL,&t)<=0) { |
||
242 | v1++; if(v1>=v2) break; |
||
243 | else continue; |
||
244 | } |
||
245 | j=read(fd,p+i,k); |
||
246 | if(j<0 || j>k) break; |
||
247 | i+=j; k-=j; p[i]=0; |
||
248 | pp=strstr(p,multiexec_random); |
||
249 | if(pp) {*pp=0; break;} |
||
250 | } |
||
251 | fd=mxtab[multiexec_index].pipe_stderr[0]; |
||
252 | FD_ZERO(&rset); FD_SET(fd,&rset); |
||
253 | t.tv_sec=0; t.tv_usec=0; |
||
254 | if(select(fd+1,&rset,NULL,NULL,&t)>0) |
||
255 | _get_exec_error(NULL,namebuf); |
||
256 | strip_trailing_spaces(p); |
||
257 | return; |
||
10 | reyssat | 258 | } |
259 | exportall(); setenv("wims_exec_parm",parm,1); |
||
260 | execredirected(cmdstr,NULL,outfname,errorfname,abuf); |
||
261 | if(open_working_file(&wf,varfname)==0) { |
||
7673 | bpr | 262 | char *pt, *pv; |
263 | while(wgetline(tmplbuf,MAX_LINELEN, &wf)!=EOF) { |
||
264 | pt=find_word_start(tmplbuf); pv=strchr(pt,'='); |
||
265 | if(pv==NULL || pv<=tmplbuf) continue; |
||
266 | *pv=0; pv=find_word_start(++pv); |
||
267 | *find_word_end(pt)=0; |
||
268 | strip_trailing_spaces(pv); |
||
269 | setvar(pt,pv); |
||
270 | } |
||
271 | close_working_file(&wf,0); |
||
10 | reyssat | 272 | } |
273 | read_tmp_file(p,"exec.out"); |
||
274 | read_tmp_file(obuf,"exec.type"); |
||
275 | if(obuf[0]) k=atoi(obuf); else k=0; |
||
276 | for(i=2;i<=k && i<256;i++) { |
||
7673 | bpr | 277 | char nbuf[32]; |
278 | snprintf(nbuf,sizeof(nbuf),"exec.out.%d",i); |
||
279 | read_tmp_file(obuf,nbuf); |
||
280 | if(obuf[0]) { |
||
281 | snprintf(nbuf,sizeof(nbuf),"wims_exec_out_%d",i); |
||
282 | force_setvar(nbuf,obuf); |
||
283 | } |
||
10 | reyssat | 284 | } |
285 | strip_trailing_spaces(p); |
||
286 | _get_exec_error(errorfname,namebuf); |
||
287 | return; |
||
288 | } |
||
289 | |||
7673 | bpr | 290 | /* execute external program in the module directory. |
8155 | bpr | 291 | * For privileged modules only |
292 | */ |
||
10 | reyssat | 293 | void calc_mexec(char *p) |
294 | { |
||
295 | char *public_bin; |
||
296 | if(robot_access) return; |
||
297 | if(trusted_module()!=1 || is_class_module) { |
||
7673 | bpr | 298 | module_error("not_trusted"); *p=0; return; |
10 | reyssat | 299 | } |
7673 | bpr | 300 | /* The following is useless, because mexec content is often given |
8155 | bpr | 301 | * by variables |
302 | */ |
||
10 | reyssat | 303 | /* if(strstr(p,PARENT_DIR_STRING)!=NULL) { |
7673 | bpr | 304 | setvar("wims_error_data",p); |
305 | module_error("illegal_fname"); *p=0; return; |
||
10 | reyssat | 306 | } |
307 | */ public_bin=bin_dir; bin_dir=module_prefix; |
||
308 | exec_is_module=1; |
||
309 | calc_exec(p); bin_dir=public_bin; |
||
310 | exec_is_module=0; |
||
311 | } |
||
312 | |||
313 | void _calc_exec(char *p, char *arg0, char *arg1, int n) |
||
314 | { |
||
315 | char *abuf[8]; |
||
316 | char outfname[MAX_FNAME+1], errorfname[MAX_FNAME+1]; |
||
317 | |||
318 | if(robot_access) {*p=0; return;} |
||
319 | if(!trusted_module() || is_class_module) { |
||
7673 | bpr | 320 | if(strcasecmp(tmp_debug,"yes")==0) |
321 | accessfile(p,"w","%s/%s.cmd",tmp_dir,arg0); |
||
322 | abuf[0]="bin/ch..root"; |
||
323 | abuf[1]="&"; abuf[2]=arg0; abuf[3]=p; |
||
324 | abuf[4]=NULL; |
||
10 | reyssat | 325 | } |
326 | else { |
||
7673 | bpr | 327 | /* if(strstr(p,PARENT_DIR_STRING)!=NULL) { |
328 | setvar("wims_error_data",p); |
||
329 | module_error("illegal_fname"); *p=0; return; |
||
330 | } |
||
331 | */ |
||
332 | abuf[0]=arg0; abuf[1]=arg1; abuf[n]=p; abuf[n+1]=NULL; |
||
10 | reyssat | 333 | } |
334 | mkfname(outfname,"%s/exec.out",tmp_dir); |
||
335 | mkfname(errorfname,"%s/exec.err",tmp_dir); |
||
336 | wrapexec=1; exportall(); |
||
337 | execredirected(abuf[0],NULL,outfname,errorfname,abuf); |
||
338 | read_tmp_file(p,"exec.out"); |
||
339 | _get_exec_error(errorfname,arg0); |
||
340 | } |
||
341 | |||
7673 | bpr | 342 | /* call shell. */ |
10 | reyssat | 343 | void calc_sh(char *p) |
344 | { |
||
345 | _calc_exec(p,"sh","-c",2); |
||
346 | } |
||
347 | |||
7673 | bpr | 348 | /* call perl. */ |
10 | reyssat | 349 | void calc_perl(char *p) |
350 | { |
||
351 | _calc_exec(p,"perl","-e",2); |
||
352 | } |
||
353 | |||
7673 | bpr | 354 | /* simple evaluation of string */ |
10 | reyssat | 355 | void calc_evalue(char *p) |
356 | { |
||
357 | double d; |
||
358 | d=evalue(p); float2str(d,p); return; |
||
359 | } |
||
360 | |||
7673 | bpr | 361 | /* substitute math variables */ |
10 | reyssat | 362 | void calc_mathsubst(char *p) |
363 | { |
||
364 | char *expr, *val, *nam, *pp; |
||
365 | char buf[MAX_LINELEN+1]; |
||
366 | expr=wordchr(p,"in"); if(expr==NULL) goto error; |
||
3718 | reyssat | 367 | ovlstrcpy(buf,find_word_start(expr+strlen("in")));substit(buf); |
10 | reyssat | 368 | *expr=0; substit(p); |
369 | val=strchr(p,'='); |
||
370 | if(val==NULL) { |
||
7673 | bpr | 371 | error: |
372 | module_error("mathsubst_syntax"); *p=0;return; |
||
10 | reyssat | 373 | } |
374 | nam=find_word_start(p); *val=0; |
||
375 | val=find_word_start(val+1); |
||
376 | for(pp=val+strlen(val)-1;pp>=val && isspace(*pp);*pp--=0); |
||
377 | *find_word_end(nam)=0; |
||
378 | if(*nam==0) goto error; |
||
379 | if(*nam) for(pp=varchr(buf,nam);pp!=NULL;pp=varchr(pp,nam)) { |
||
7673 | bpr | 380 | string_modify(buf,pp,pp+strlen(nam),"%s",val); |
381 | pp+=strlen(val); |
||
10 | reyssat | 382 | } |
3718 | reyssat | 383 | ovlstrcpy(p,buf); |
10 | reyssat | 384 | } |
385 | |||
7673 | bpr | 386 | /* substitute and evaluate. */ |
10 | reyssat | 387 | void calc_evalsubst(char *p) |
388 | { |
||
389 | calc_mathsubst(p); |
||
390 | calc_evalue(p); |
||
391 | } |
||
392 | |||
7673 | bpr | 393 | /* Nothing needs to be done in the function; |
8155 | bpr | 394 | * substitution is done or not by tag in the structure. |
395 | */ |
||
10 | reyssat | 396 | void calc_subst(char *p) |
397 | { |
||
398 | } |
||
399 | |||
400 | int _randrep(char *p) |
||
401 | { |
||
402 | char *rep; |
||
403 | int i; |
||
404 | rep=wordchr(p,"repeat"); if(rep==NULL) return 1; |
||
405 | *rep=0; rep+=strlen("repeat"); i=evalue(rep); |
||
11125 | georgesk | 406 | if(i<1) i=1; |
407 | if(i>MAX_VALUE_LIST) i=MAX_VALUE_LIST; |
||
10 | reyssat | 408 | return i; |
409 | } |
||
410 | |||
7673 | bpr | 411 | /* integer random */ |
10 | reyssat | 412 | void calc_randint(char *p) |
413 | { |
||
414 | int lbound, ubound, n, i, t; |
||
415 | char *p1, *parm[2]; |
||
416 | |||
417 | t=_randrep(p); n=cutitems(p,parm,2); |
||
418 | if(n<=0) { |
||
7673 | bpr | 419 | snprintf(p,3,"0"); return; /* Random without bound: return 0. */ |
10 | reyssat | 420 | } |
421 | lbound=evalue(parm[0]); |
||
7673 | bpr | 422 | /* Missing ubound: random between +-1 and lbound. */ |
10 | reyssat | 423 | if(n<=1) {if(lbound<0) ubound=-1; else ubound=1;} |
424 | else ubound=evalue(parm[1]); |
||
425 | if(lbound>ubound) {i=lbound; lbound=ubound; ubound=i;} |
||
426 | for(i=0,p1=p;i<t;i++) { |
||
7673 | bpr | 427 | if(i>0) *p1++=','; |
428 | mystrncpy(p1,int2str((int) irand(ubound-lbound+1)+lbound), |
||
429 | MAX_LINELEN-(p1-p)-1); |
||
430 | p1+=strlen(p1); |
||
10 | reyssat | 431 | } |
432 | return; |
||
433 | } |
||
434 | |||
7673 | bpr | 435 | /* floating random */ |
10 | reyssat | 436 | void calc_randdouble(char *p) |
437 | { |
||
438 | double lbound, ubound; |
||
439 | int n, i, t; |
||
440 | char *parm[2], *p1; |
||
7404 | bpr | 441 | |
10 | reyssat | 442 | t=_randrep(p); n=cutitems(p,parm,2); |
443 | if(n<=0) { |
||
7673 | bpr | 444 | snprintf(p,3,"0"); return; /* Random without bound: return 0. */ |
10 | reyssat | 445 | } |
446 | lbound=evalue(parm[0]); |
||
447 | if(n<=1) ubound=0; /* Missing ubound: random between 0 and lbound. */ |
||
448 | else ubound=evalue(parm[1]); |
||
449 | for(i=0,p1=p;i<t;i++) { |
||
7673 | bpr | 450 | float2str(drand(ubound-lbound)+lbound,tmplbuf); |
451 | mystrncpy(p1,tmplbuf,MAX_LINELEN-(p1-p)); |
||
452 | p1+=strlen(p1); |
||
453 | if(i<t-1 && p1-p<MAX_LINELEN) *p1++=','; |
||
10 | reyssat | 454 | } |
455 | *p1=0; return; |
||
456 | } |
||
457 | |||
7673 | bpr | 458 | /* Takes randomly a record in a datafile */ |
10 | reyssat | 459 | void calc_randfile(char *p) |
460 | { |
||
461 | char *pp, n[MAX_FNAME+1]; |
||
462 | int i, j; |
||
7404 | bpr | 463 | |
10 | reyssat | 464 | pp=find_word_start(p); *find_word_end(pp)=0; |
465 | mystrncpy(n,pp,sizeof(n)); |
||
466 | i=datafile_recordnum(pp); |
||
467 | if(i<=0) { /* zero records */ |
||
7673 | bpr | 468 | *p=0; return; |
10 | reyssat | 469 | } |
470 | j=irand(i); datafile_fnd_record(n,j+1,p); |
||
471 | return; |
||
472 | } |
||
473 | |||
7673 | bpr | 474 | /* random char, word, line, item in a string */ |
10 | reyssat | 475 | void calc_randchar(char *p) |
476 | { |
||
477 | p[0]=p[(int) irand(strlen(p))];p[1]=0; |
||
478 | } |
||
479 | |||
480 | void calc_randitem(char *p) |
||
481 | { |
||
6790 | bpr | 482 | int i; |
10 | reyssat | 483 | i=itemnum(p); |
6790 | bpr | 484 | (void) fnd_item(p,irand(i)+1,tmplbuf); |
10 | reyssat | 485 | mystrncpy(p,tmplbuf,MAX_LINELEN); |
486 | } |
||
487 | |||
488 | void calc_randline(char *p) |
||
489 | { |
||
490 | int i; |
||
491 | i=linenum(p); fnd_line(p,irand(i)+1,tmplbuf); |
||
492 | mystrncpy(p,tmplbuf,MAX_LINELEN); |
||
493 | } |
||
494 | |||
495 | void calc_randrow(char *p) |
||
496 | { |
||
497 | rows2lines(p); calc_randline(p); |
||
498 | } |
||
499 | |||
500 | void calc_randword(char *p) |
||
501 | { |
||
502 | int i; |
||
503 | i=wordnum(p); fnd_word(p,irand(i)+1,tmplbuf); |
||
504 | mystrncpy(p,tmplbuf,MAX_LINELEN); |
||
505 | } |
||
506 | |||
7673 | bpr | 507 | /* random permutation of {1,...,n} */ |
10 | reyssat | 508 | void calc_randperm(char *p) |
509 | { |
||
510 | int n, i, j, k, t, pt, type; |
||
511 | double v; |
||
512 | char buf1[MAX_LINELEN+1],buf2[MAX_LINELEN+1]; |
||
513 | char *list[MAX_RANDPERM]; |
||
514 | int table[MAX_RANDPERM]; |
||
515 | char *p1,*p2,*pp; |
||
7404 | bpr | 516 | |
10 | reyssat | 517 | t=0; pt=0; pp=p; |
518 | p1=find_word_start(p); p2=find_word_end(p1); |
||
519 | if(p2-p1==strlen("even") && strncasecmp(p1,"even",strlen("even"))==0) { |
||
7673 | bpr | 520 | t=1; pp=p2; |
10 | reyssat | 521 | } |
522 | if(p2-p1==strlen("odd") && strncasecmp(p1,"odd",strlen("odd"))==0) { |
||
7673 | bpr | 523 | t=-1; pp=p2; |
10 | reyssat | 524 | } |
7404 | bpr | 525 | |
10 | reyssat | 526 | p1=find_item_end(pp); if(*p1==',') { |
7673 | bpr | 527 | type=1; n=cutitems(pp,list,MAX_RANDPERM); v=0; |
10 | reyssat | 528 | } |
529 | else { |
||
7673 | bpr | 530 | v=evalue(pp); n=v; type=0; |
10 | reyssat | 531 | } |
8171 | bpr | 532 | if(n==1 && !isfinite(v)) {ovlstrcpy(p,pp); goto shorder;} |
10 | reyssat | 533 | if(n<=0) {*p=0; return;} |
534 | if(n==1 && type==0) { |
||
7673 | bpr | 535 | ovlstrcpy(p,"1"); |
536 | shorder: force_setvar("wims_shuffle_order","1"); return; |
||
10 | reyssat | 537 | } |
538 | if(n>MAX_RANDPERM) n=MAX_RANDPERM; |
||
539 | for(i=0;i<n;i++) table[i]=i; |
||
8155 | bpr | 540 | /* Uniformity of this algorithm is easy to show by induction. */ |
10 | reyssat | 541 | for(i=0;i<n-1;i++) { |
7673 | bpr | 542 | j=irand(n-i)+i; if(j==i) continue; |
543 | k=table[i]; table[i]=table[j]; table[j]=k; |
||
544 | pt++; |
||
10 | reyssat | 545 | } |
546 | pt&=1; |
||
547 | if((t==1 && pt==1) || (t==-1 && pt==0)) { |
||
7673 | bpr | 548 | k=table[0]; table[0]=table[1]; table[1]=k; |
10 | reyssat | 549 | } |
550 | if(type) {mystrncpy(buf1,list[table[0]],MAX_LINELEN); p1=buf1+strlen(buf1);} |
||
551 | else buf1[0]=0; |
||
552 | mystrncpy(buf2,int2str(table[0]+1),MAX_LINELEN); p2=buf2+strlen(buf2); |
||
553 | for(i=1;i<n;i++) { |
||
7673 | bpr | 554 | if(type) { |
555 | j=strlen(list[table[i]]); |
||
556 | if(p1-buf1+j>=MAX_LINELEN-1) module_error("cmd_output_too_long"); |
||
557 | *p1++=','; memmove(p1,list[table[i]],j+1); p1+=j; |
||
558 | } |
||
559 | *p2++=','; |
||
560 | mystrncpy(p2,int2str(table[i]+1), MAX_LINELEN-(p2-buf2)-1); |
||
561 | p2+=strlen(p2); |
||
10 | reyssat | 562 | } |
563 | if(type) mystrncpy(p,buf1,MAX_LINELEN); |
||
564 | else mystrncpy(p,buf2,MAX_LINELEN); |
||
565 | force_setvar("wims_shuffle_order",buf2); |
||
566 | } |
||
567 | |||
7673 | bpr | 568 | /* Computes number of lines in the parm. */ |
10 | reyssat | 569 | void calc_linenum(char *p) |
570 | { |
||
571 | int i=linenum(p); mystrncpy(p,int2str(i),MAX_LINELEN); |
||
572 | } |
||
573 | |||
7673 | bpr | 574 | /* Computes number of lines in the parm. */ |
10 | reyssat | 575 | void calc_rownum(char *p) |
576 | { |
||
577 | int i=rownum(p); mystrncpy(p,int2str(i),MAX_LINELEN); |
||
578 | } |
||
579 | |||
7673 | bpr | 580 | /* Computes number of items in the list p. */ |
10 | reyssat | 581 | void calc_itemnum(char *p) |
582 | { |
||
583 | int i=itemnum(p); mystrncpy(p,int2str(i),MAX_LINELEN); |
||
584 | } |
||
585 | |||
7673 | bpr | 586 | /* Computes number of records in the datafile p. */ |
10 | reyssat | 587 | void calc_recordnum(char *p) |
588 | { |
||
589 | int i; |
||
590 | i=datafile_recordnum(p); mystrncpy(p,int2str(i),MAX_LINELEN); |
||
591 | } |
||
592 | |||
7673 | bpr | 593 | /* Computes number of words in the parm. */ |
10 | reyssat | 594 | void calc_wordnum(char *p) |
595 | { |
||
596 | int i=wordnum(p); mystrncpy(p,int2str(i),MAX_LINELEN); |
||
597 | } |
||
598 | |||
7673 | bpr | 599 | /* string length */ |
10 | reyssat | 600 | void calc_lengthof(char *p) |
601 | { |
||
602 | int i; |
||
7404 | bpr | 603 | /* Strip leading and trailing spaces? */ |
10 | reyssat | 604 | i=strlen(p); mystrncpy(p,int2str(i),MAX_LINELEN); |
605 | } |
||
606 | |||
607 | char *_blockof_one(char *buf, |
||
7673 | bpr | 608 | unsigned int len, |
609 | char *(fnd_fn)(char *pl, int n, char bbuf[]), |
||
610 | int i, char bbuf[]) |
||
10 | reyssat | 611 | { |
612 | if(i<0 || i>len || (i==0 && fnd_fn!=datafile_fnd_record) ) { |
||
7673 | bpr | 613 | bbuf[0]=0; return bbuf; |
10 | reyssat | 614 | } |
615 | return fnd_fn(buf,i,bbuf); |
||
616 | } |
||
617 | |||
618 | void _blockof(char *p, |
||
7673 | bpr | 619 | unsigned int (len_fn)(char *pl), |
620 | char *(fnd_fn)(char *pl, int n, char bbuf[]), |
||
621 | char *append_char, |
||
622 | char *msg_str) |
||
10 | reyssat | 623 | { |
624 | int i,j,l,started; |
||
625 | char *pp, *pe, *po, *pnext; |
||
626 | char buf[MAX_LINELEN+1], obuf[MAX_LINELEN+1], bbuf[MAX_LINELEN+1]; |
||
627 | pp=wordchr(p,"of"); |
||
628 | if(pp==NULL) { |
||
7673 | bpr | 629 | setvar(error_data_string,msg_str); |
630 | module_error("no_of"); *p=0; return; |
||
10 | reyssat | 631 | } |
632 | *pp=0; pp=find_word_start(pp+strlen("of")+1); |
||
633 | mystrncpy(buf,pp,sizeof(buf)); substit(buf); |
||
634 | obuf[0]=0; started=0; po=obuf; |
||
635 | pp=strparstr(p,"to"); |
||
636 | while(*pp!=0 && ((pp>p && !isspace(*(pp-1))) || !isspace(*(pp+2)))) |
||
637 | pp=strparstr(pp+2,"to"); |
||
638 | if(*pp==0) pp=strparstr(p,".."); |
||
639 | if(*pp!=0) { |
||
7673 | bpr | 640 | int t=len_fn(buf); |
641 | *pp=0; pe=find_word_start(pp+2); |
||
642 | i=evalue(p); j=evalue(pe); pnext=buf; |
||
11125 | georgesk | 643 | if(i<0) i=t+i+1; |
644 | if(i<1) i=1; |
||
645 | if(j<0) j=t+j+1; |
||
646 | if(j>t) j=t; |
||
7673 | bpr | 647 | for(; i<=j; i++) { |
648 | if(started==0 || fnd_fn==datafile_fnd_record) |
||
649 | pp=_blockof_one(buf,t,fnd_fn,i,bbuf); |
||
650 | else |
||
651 | pp=_blockof_one(pnext,1,fnd_fn,1,bbuf); |
||
652 | l=strlen(pp); pnext=fnd_nextpos; |
||
653 | if(l+(po-obuf)>=MAX_LINELEN-3) { |
||
654 | too_long: user_error("cmd_output_too_long"); return; |
||
655 | } |
||
656 | if(started) {ovlstrcpy(po,append_char); po+=strlen(po);} |
||
657 | memmove(po,pp,l); po+=l; *po=0; started++; |
||
658 | } |
||
10 | reyssat | 659 | } |
660 | else { |
||
7673 | bpr | 661 | char *p1,*p2,ibuf[MAX_LINELEN+1]; |
662 | int t=len_fn(buf); |
||
663 | mystrncpy(ibuf,p,sizeof(ibuf)); substit(ibuf); |
||
664 | for(p1=ibuf;*p1;p1=find_word_start(p2)) { |
||
665 | p2=find_item_end(p1); if(*p2) *p2++=0; |
||
666 | i=evalue(p1); |
||
667 | if(i<0) i=t+i+1; |
||
668 | if(i>t || i<0) continue; |
||
669 | pp=_blockof_one(buf,t,fnd_fn,i,bbuf);l=strlen(pp); |
||
670 | if(l+(po-obuf)>=MAX_LINELEN-3) goto too_long; |
||
671 | if(started) {ovlstrcpy(po,append_char); po+=strlen(po);} |
||
672 | memmove(po,pp,l); po+=l; *po=0; started++; |
||
673 | } |
||
10 | reyssat | 674 | } |
675 | mystrncpy(p,obuf,MAX_LINELEN); |
||
676 | } |
||
677 | |||
7673 | bpr | 678 | /* pick lines */ |
10 | reyssat | 679 | void calc_lineof(char *p) |
680 | { |
||
681 | _blockof(p,linenum,fnd_line,"\n","line"); |
||
682 | } |
||
683 | |||
7673 | bpr | 684 | /* pick rows */ |
10 | reyssat | 685 | void calc_rowof(char *p) |
686 | { |
||
7673 | bpr | 687 | char *cc, tbuf[MAX_LINELEN+1]; /* called by substit(); no right to use tmplbuf */ |
10 | reyssat | 688 | mystrncpy(tbuf,p,sizeof(tbuf)); substit(tbuf); |
689 | if(strchr(tbuf,'\n')==NULL && strchr(tbuf,';')!=NULL) cc=";"; |
||
690 | else cc="\n"; |
||
691 | _blockof(p,rownum,fnd_row,cc,"row"); |
||
692 | } |
||
693 | |||
7673 | bpr | 694 | /* pick items */ |
10 | reyssat | 695 | void calc_itemof(char *p) |
696 | { |
||
697 | _blockof(p,itemnum,fnd_item,", ","item"); |
||
698 | } |
||
699 | |||
7673 | bpr | 700 | /* pick records in datafile */ |
10 | reyssat | 701 | void calc_recordof(char *p) |
702 | { |
||
703 | _blockof(p,datafile_recordnum,datafile_fnd_record,"\n:","record"); |
||
704 | } |
||
705 | |||
7673 | bpr | 706 | /* pick words */ |
10 | reyssat | 707 | void calc_wordof(char *p) |
708 | { |
||
709 | _blockof(p,wordnum,fnd_word," ","word"); |
||
710 | } |
||
711 | |||
7673 | bpr | 712 | /* pick characters */ |
10 | reyssat | 713 | void calc_charof(char *p) |
714 | { |
||
715 | _blockof(p,charnum,fnd_char,"","char"); |
||
716 | } |
||
717 | |||
718 | char *append_obj[]={ |
||
9375 | bpr | 719 | "item","line","word","semicolon","colon" |
10 | reyssat | 720 | }; |
9378 | schaersvoo | 721 | char apch_list[]={',','\n',' ',';',':'}; |
10 | reyssat | 722 | #define append_obj_no (sizeof(append_obj)/sizeof(append_obj[0])) |
723 | |||
7673 | bpr | 724 | /* append object to string */ |
10 | reyssat | 725 | void calc_append(char *p) |
726 | { |
||
727 | char append_char, *p1,*p2,*p3,*p4; |
||
728 | int i,l1,l2; |
||
729 | p1=find_word_start(p);p2=find_word_end(p1); |
||
730 | if(*p2!=0) *p2++=0; |
||
731 | for(i=0;i<append_obj_no && strcmp(p1,append_obj[i])!=0;i++); |
||
732 | if(i>=append_obj_no) { |
||
7673 | bpr | 733 | synterr: |
734 | module_error("append_syntax"); |
||
735 | *p=0; return; |
||
10 | reyssat | 736 | } |
737 | append_char=apch_list[i]; |
||
738 | p3=wordchr(p2,"to"); |
||
739 | if(p3==NULL) goto synterr; |
||
740 | for(p4=p3-1;p4>p2 && isspace(*(p4-1));p4--); |
||
2652 | reyssat | 741 | if(p4<=p2) goto synterr; |
10 | reyssat | 742 | *p4=0;p3=find_word_start(p3+strlen("to")); |
3718 | reyssat | 743 | memmove(tmplbuf,p2,p4-p2); tmplbuf[p4-p2]=0; ovlstrcpy(p,p3); |
10 | reyssat | 744 | substit(tmplbuf);substit(p); |
745 | l1=strlen(p); l2=strlen(tmplbuf); |
||
746 | if(l1+l2>=MAX_LINELEN-1) user_error("cmd_output_too_long"); |
||
747 | p3=find_word_start(p); p4=p+l1; |
||
748 | if(*p3) *p4++=append_char; |
||
749 | memmove(p4,tmplbuf,l2); p4[l2]=0; |
||
750 | } |
||
751 | |||
7673 | bpr | 752 | /* character translation */ |
10 | reyssat | 753 | void calc_translate(char *p) |
754 | { |
||
755 | int i, internal; |
||
756 | char *q[3]; |
||
757 | char bf[3][MAX_LINELEN+1]; |
||
758 | char fn[3][MAX_FNAME+1], *arglist[8]; |
||
759 | |||
760 | q[0]=find_word_start(p); internal=0; |
||
761 | if(strncasecmp(q[0],"internal",strlen("internal"))==0 && |
||
762 | isspace(*(q[0]+strlen("internal")))) { |
||
7673 | bpr | 763 | q[0]=find_word_start(q[0]+strlen("internal")); |
764 | internal=1; |
||
10 | reyssat | 765 | } |
766 | q[1]=wordchr(q[0],"to"); q[2]=wordchr(q[0],"in"); |
||
767 | if(q[1]==NULL || q[2]==NULL) { |
||
7673 | bpr | 768 | module_error("tr_syntax"); *p=0; return; |
10 | reyssat | 769 | } |
770 | *q[1]=0; *q[2]=0; |
||
771 | q[1]=find_word_start(q[1]+strlen("to")); |
||
772 | q[2]=find_word_start(q[2]+strlen("in")); |
||
773 | for(i=0;i<3;i++) { |
||
7673 | bpr | 774 | strip_trailing_spaces(q[i]); |
775 | mystrncpy(bf[i],q[i],sizeof(bf[i]));substit(bf[i]); |
||
10 | reyssat | 776 | } |
777 | if(bf[0][0]==0) goto bailout; |
||
7404 | bpr | 778 | if(internal || strstr(tmp_dir,"sessions")==NULL || (strpbrk(bf[0],"\\[-")==NULL && |
7673 | bpr | 779 | strpbrk(bf[1],"\\[-")==NULL)) { /* direct internal translation */ |
780 | char *pp; |
||
781 | if(strlen(bf[1])<strlen(bf[0])) bf[0][strlen(bf[1])]=0; |
||
782 | for(pp=strpbrk(bf[2],bf[0]);pp!=NULL && *pp!=0 && pp<bf[2]+MAX_LINELEN; |
||
783 | pp=strpbrk(pp+1,bf[0])) { |
||
784 | for(i=0;bf[0][i]!=*pp && bf[0][i]!=0;i++); |
||
785 | if(bf[0][i]!=0) *pp=bf[1][i]; |
||
786 | } |
||
787 | bailout: mystrncpy(p,bf[2],MAX_LINELEN); |
||
788 | return; |
||
10 | reyssat | 789 | } |
790 | mkfname(fn[0],"%s/tr.in",tmp_dir); |
||
791 | mkfname(fn[1],"%s/tr.out",tmp_dir); |
||
792 | accessfile(bf[2],"w",fn[0]); |
||
793 | arglist[0]=tr_prog; arglist[1]=bf[0]; arglist[2]=bf[1]; |
||
794 | arglist[3]=NULL; exportall(); |
||
795 | execredirected(tr_prog,fn[0],fn[1],"/dev/null",arglist); |
||
796 | read_tmp_file(p,"tr.out"); |
||
797 | strip_trailing_spaces(p); |
||
798 | } |
||
799 | |||
7673 | bpr | 800 | /* internal common routine for positionof */ |
10 | reyssat | 801 | void _pos(char *hay, char *stitch, int style, char *out, |
7673 | bpr | 802 | char *(fnd_obj)(char *p, int n, char bf[]), |
803 | unsigned int (objnum)(char *p)) |
||
10 | reyssat | 804 | { |
805 | int i,n,t; |
||
806 | char buf[MAX_LINELEN+1], nbuf[10]; |
||
7404 | bpr | 807 | |
10 | reyssat | 808 | n=objnum(hay); |
809 | for(i=1;i<=n;i++) { |
||
7673 | bpr | 810 | fnd_obj(hay,i,buf); |
811 | if(strcmp(buf,stitch)!=0) continue; |
||
812 | t=strlen(out); if(t>MAX_LINELEN-12) return; |
||
813 | if(t>0) strcat(out,","); |
||
814 | snprintf(nbuf,sizeof(nbuf),"%d",i); strcat(out,nbuf); |
||
10 | reyssat | 815 | } |
816 | } |
||
817 | |||
7673 | bpr | 818 | /* return positions of searched for objects */ |
10 | reyssat | 819 | void calc_pos(char *p) |
820 | { |
||
821 | char buf[2][MAX_LINELEN+1]; |
||
822 | char *p1, *p2; |
||
823 | int style; |
||
7404 | bpr | 824 | |
10 | reyssat | 825 | p1=find_word_start(p); p2=wordchr(p1,"in"); |
826 | if(p2==NULL) module_error("syntax_error"); |
||
827 | *p2=0;p2=find_word_start(p2+strlen("in")); |
||
828 | strip_trailing_spaces(p1); |
||
3718 | reyssat | 829 | ovlstrcpy(buf[0],p1);*find_word_end(buf[0])=0; style=0; |
10 | reyssat | 830 | if(strcmp(buf[0],"word")==0) style=1; |
831 | else { |
||
7673 | bpr | 832 | if(strcmp(buf[0],"item")==0) style=2; |
833 | else { |
||
834 | if(strcmp(buf[0],"line")==0) style=3; |
||
835 | else { |
||
836 | if(strcmp(buf[0],"char")==0) style=4; |
||
837 | } |
||
838 | } |
||
10 | reyssat | 839 | } |
840 | if(style>0) p1=find_word_start(find_word_end(p1)); |
||
3718 | reyssat | 841 | ovlstrcpy(buf[0],p1); ovlstrcpy(buf[1],p2); |
10 | reyssat | 842 | substit(buf[0]); substit(buf[1]); *p=0; |
843 | switch(style) { |
||
7673 | bpr | 844 | case 0: { /* string */ |
845 | char *pp, nbuf[10]; |
||
846 | int i,t; |
||
847 | for(pp=strstr(buf[1],buf[0]);pp!=NULL;pp=strstr(pp+1,buf[0])) { |
||
848 | i=pp-buf[1]; t=strlen(p); if(t>MAX_LINELEN-12) return; |
||
849 | if(t>0) strcat(p,","); |
||
850 | snprintf(nbuf,sizeof(nbuf),"%d",i); strcat(p,nbuf); |
||
851 | } |
||
852 | return; |
||
853 | } |
||
854 | case 1: { /* word */ |
||
855 | _pos(buf[1],buf[0],style,p,fnd_word,wordnum); |
||
856 | return; |
||
857 | } |
||
858 | case 2: { /* item */ |
||
859 | _pos(buf[1],buf[0],style,p,fnd_item,itemnum); |
||
860 | return; |
||
861 | } |
||
862 | case 3: { /* line */ |
||
863 | _pos(buf[1],buf[0],style,p,fnd_line,linenum); |
||
864 | return; |
||
865 | } |
||
866 | case 4: { /* char */ |
||
867 | _pos(buf[1],buf[0],style,p,fnd_char,charnum); |
||
868 | return; |
||
869 | } |
||
10 | reyssat | 870 | } |
871 | } |
||
872 | |||
7673 | bpr | 873 | /* internal routine for calc_replace. */ |
10 | reyssat | 874 | void _obj_replace(char *orig, char *by, char *in, int num, |
7673 | bpr | 875 | char separator, char *result, |
876 | char *(fnd_obj)(char *p, int n, char bf[]), |
||
877 | unsigned int (objnum)(char *p), |
||
878 | char *(objchr)(char *p,char *w)) |
||
10 | reyssat | 879 | { |
880 | int i; |
||
881 | char *p1, *p2; |
||
7404 | bpr | 882 | |
3718 | reyssat | 883 | ovlstrcpy(result,in); |
10 | reyssat | 884 | if(num!=0) { |
7673 | bpr | 885 | num=objnum(in); i=evalue(orig); |
886 | if(i==0) module_error("bad_index"); |
||
887 | if(i<0) i=num+i+1; |
||
888 | if(i>num || i<1) return; |
||
889 | if(separator==0) { /* char */ |
||
890 | result[i-1]=by[0]; return; |
||
891 | } |
||
892 | fnd_obj(result,i,orig); p1=fnd_position; |
||
893 | if(i<num) { |
||
894 | fnd_obj(result,i+1,orig); p2=fnd_position; |
||
895 | } |
||
896 | else p2=result+strlen(result); |
||
897 | if(p1==NULL || p2==NULL) internal_error("_obj_replace() error."); |
||
898 | if(i<num) { |
||
899 | i=strlen(by); by[i++]=separator;by[i]=0; |
||
900 | } |
||
901 | string_modify(result,p1,p2,"%s",by); |
||
10 | reyssat | 902 | } |
903 | else { |
||
7673 | bpr | 904 | if(separator==0) { |
905 | if(orig[0]==0 || by[0]==0) return; |
||
906 | for(p1=strchr(result,orig[0]);p1!=NULL;p1=strchr(p1+1,orig[0])) |
||
907 | *p1=by[0]; |
||
908 | return; |
||
909 | } |
||
910 | if(strlen(orig)+strlen(by)==0) return; |
||
911 | for(p1=objchr(result,orig);p1!=NULL;p1=objchr(p1+strlen(by)+1,orig)) { |
||
912 | string_modify(result,p1,p1+strlen(orig),"%s",by); |
||
913 | } |
||
10 | reyssat | 914 | } |
915 | } |
||
916 | |||
7673 | bpr | 917 | /* replacement */ |
10 | reyssat | 918 | void calc_replace(char *p) |
919 | { |
||
920 | int i,style,num,internal; |
||
921 | char *q[3], *pp; |
||
922 | char bf[4][MAX_LINELEN+17]; |
||
923 | char fn[3][MAX_FNAME+1], *arglist[8]; |
||
924 | char regexp_char='/'; |
||
925 | |||
926 | style=num=0; |
||
927 | q[0]=find_word_start(p); internal=0; |
||
928 | if(strncasecmp(q[0],"internal",strlen("internal"))==0 && |
||
929 | isspace(*(q[0]+strlen("internal")))) { |
||
7673 | bpr | 930 | q[0]=find_word_start(q[0]+strlen("internal")); |
931 | internal=1; |
||
10 | reyssat | 932 | } |
933 | q[1]=wordchr(q[0],"by"); q[2]=wordchr(q[0],"in"); |
||
934 | if(q[1]==NULL || q[2]==NULL) { |
||
7673 | bpr | 935 | module_error("replace_syntax"); *p=0; return; |
10 | reyssat | 936 | } |
937 | *q[1]=0; *q[2]=0; |
||
938 | q[1]=find_word_start(q[1]+strlen("by")); |
||
939 | q[2]=find_word_start(q[2]+strlen("in")); |
||
940 | mystrncpy(bf[0],q[0],sizeof(bf[0])); |
||
941 | pp=find_word_end(bf[0]); if(*pp) *(pp++)=0; |
||
942 | if(strcmp(bf[0],"word")==0) style=1; |
||
943 | else { |
||
7673 | bpr | 944 | if(strcmp(bf[0],"item")==0) style=2; |
945 | else { |
||
946 | if(strcmp(bf[0],"line")==0) style=3; |
||
947 | else { |
||
948 | if(strcmp(bf[0],"char")==0) style=4; |
||
949 | } |
||
950 | } |
||
10 | reyssat | 951 | } |
952 | if(style>0) { |
||
7673 | bpr | 953 | q[0]=find_word_start(find_word_end(q[0])); |
954 | mystrncpy(bf[0],q[0],sizeof(bf[0])); |
||
955 | pp=find_word_end(bf[0]); if(*pp) *(pp++)=0; |
||
956 | if(strcmp(bf[0],"number")==0) { |
||
957 | num=1; q[0]=find_word_start(pp); |
||
958 | } |
||
10 | reyssat | 959 | } |
960 | for(i=0;i<3;i++) { |
||
7673 | bpr | 961 | strip_trailing_spaces(q[i]); |
962 | mystrncpy(bf[i],q[i],sizeof(bf[i])); |
||
963 | substit(bf[i]); |
||
10 | reyssat | 964 | } |
965 | if(bf[0][0]==0) {mystrncpy(p,bf[2],MAX_LINELEN); return;} |
||
966 | switch(style) { |
||
7673 | bpr | 967 | case 1: { /* word */ |
968 | _obj_replace(bf[0],bf[1],bf[2],num,' ',p, |
||
969 | fnd_word,wordnum,wordchr); |
||
970 | return; |
||
971 | } |
||
972 | case 2: { /* item */ |
||
973 | _obj_replace(bf[0],bf[1],bf[2],num,',',p, |
||
974 | fnd_item,itemnum,itemchr); |
||
975 | return; |
||
976 | } |
||
977 | case 3: { /* line */ |
||
978 | _obj_replace(bf[0],bf[1],bf[2],num,'\n',p, |
||
979 | fnd_line,linenum,linechr); |
||
980 | return; |
||
981 | } |
||
982 | case 4: { /* char */ |
||
983 | if(bf[1][0]==0) bf[1][0]=' '; |
||
984 | if(bf[0][0]==0) return; |
||
985 | _obj_replace(bf[0],bf[1],bf[2],num,0,p, |
||
986 | fnd_char,charnum,charchr); |
||
987 | return; |
||
988 | } |
||
989 | default: break; |
||
10 | reyssat | 990 | } |
991 | if(internal || strstr(tmp_dir,"sessions")==NULL || (strpbrk(bf[0],"\\[^.*$")==NULL && |
||
992 | strpbrk(bf[1],"\\[^.*$")==NULL)) { |
||
7673 | bpr | 993 | /* No regexp, direct replace */ |
994 | char *pp; |
||
995 | for(pp=strstr(bf[2],bf[0]);pp<bf[2]+MAX_LINELEN && pp!=NULL; |
||
996 | pp=strstr(pp+strlen(bf[1]),bf[0])) { |
||
997 | string_modify(bf[2],pp,pp+strlen(bf[0]),"%s",bf[1]); |
||
998 | } |
||
999 | mystrncpy(p,bf[2],MAX_LINELEN);return; |
||
10 | reyssat | 1000 | } |
1001 | mkfname(fn[0],"%s/sed.in",tmp_dir); |
||
1002 | mkfname(fn[1],"%s/sed.out",tmp_dir); |
||
1003 | accessfile(bf[2],"w",fn[0]); |
||
1004 | snprintf(bf[3],sizeof(bf[3]),"s%c%s%c%s%cg", |
||
7673 | bpr | 1005 | regexp_char,bf[0],regexp_char,bf[1],regexp_char); |
10 | reyssat | 1006 | arglist[0]=sed_prog; arglist[1]=bf[3]; arglist[2]=NULL; |
1007 | execredirected(sed_prog,fn[0],fn[1],"/dev/null",arglist); |
||
1008 | read_tmp_file(p,"sed.out"); |
||
1009 | strip_trailing_spaces(p); |
||
1010 | } |
||
1011 | |||
7673 | bpr | 1012 | /* transforms a string to hexadecimal code, upper-case */ |
10 | reyssat | 1013 | void calc_hex(char *p) |
1014 | { |
||
1015 | unsigned char *p1, orig[MAX_LINELEN+1]; |
||
1016 | char *p2; |
||
1017 | char *hex="0123456789ABCDEF"; |
||
7404 | bpr | 1018 | |
3247 | bpr | 1019 | mystrncpy((char*)orig,p,MAX_LINELEN); |
10 | reyssat | 1020 | for(p1=orig, p2=p; *p1 && p2-p<MAX_LINELEN-2; p1++) { |
7673 | bpr | 1021 | *p2++=hex[(*p1>>4)&15]; *p2++=hex[*p1&15]; |
10 | reyssat | 1022 | } |
7404 | bpr | 1023 | *p2=0; |
10 | reyssat | 1024 | } |
1025 | |||
7673 | bpr | 1026 | /* transforms to lower/upper cases */ |
10 | reyssat | 1027 | void calc_tolower(char *p) |
1028 | { |
||
1029 | char *pp; |
||
1030 | for(pp=p;*pp;pp++) *pp=tolower(*pp); |
||
1031 | } |
||
1032 | |||
1033 | void calc_toupper(char *p) |
||
1034 | { |
||
1035 | char *pp; |
||
1036 | for(pp=p;*pp;pp++) *pp=toupper(*pp); |
||
1037 | } |
||
1038 | |||
7673 | bpr | 1039 | /* strip leading and trailing spaces */ |
10 | reyssat | 1040 | void calc_trim(char *p) |
1041 | { |
||
1042 | char *s; |
||
1043 | s=find_word_start(p); |
||
1044 | if(s>p) memmove(p,s,MAX_LINELEN-(s-p)+1); |
||
1045 | strip_trailing_spaces(p); |
||
1046 | } |
||
1047 | |||
7673 | bpr | 1048 | /* output date. Uses Linux 'date' utility. */ |
10 | reyssat | 1049 | void calc_date(char *p) |
1050 | { |
||
1051 | char *p1, *p2, *p3; |
||
1052 | if(!trusted_module() || is_class_module) { |
||
7673 | bpr | 1053 | if(strstr(p,"..")!=NULL) return; |
1054 | for(p1=find_word_start(p); *p1; p1=find_word_start(p2)) { |
||
1055 | p2=find_word_end(p1); |
||
1056 | while(*p1=='\'' || *p1=='"') p1++; |
||
1057 | if(*p1!='-') continue; |
||
1058 | for(p3=p1+1;p3<p2;p3++) if(strchr("rs",*p3)!=NULL) return; |
||
1059 | } |
||
10 | reyssat | 1060 | } |
1061 | wrapexec=1; |
||
1062 | call_ssh("date %s >%s/date.out 2>/dev/null",p,tmp_dir); |
||
1063 | read_tmp_file(p,"date.out"); |
||
1064 | } |
||
1065 | |||
7673 | bpr | 1066 | /* ls, or dir */ |
10 | reyssat | 1067 | void calc_listfile(char *p) |
1068 | { |
||
1069 | char *pp; |
||
7404 | bpr | 1070 | |
7673 | bpr | 1071 | /* only for trusted modules */ |
10 | reyssat | 1072 | if(!trusted_module() || is_class_module) { |
7673 | bpr | 1073 | module_error("not_trusted"); *p=0; return; |
10 | reyssat | 1074 | } |
7673 | bpr | 1075 | /* security measures. */ |
10 | reyssat | 1076 | for(pp=p;*pp;pp++) if(isspace(*pp) || *pp==';') *pp=' '; |
1077 | if(strstr(p,parent_dir_string)!=NULL) { |
||
7673 | bpr | 1078 | setvar(error_data_string,p); |
1079 | module_error("illegal_fname"); return; |
||
10 | reyssat | 1080 | } |
1081 | wrapexec=1; |
||
1082 | call_sh("ls %s >%s/ls.out 2>%s/ls.err", |
||
7673 | bpr | 1083 | p,tmp_dir,tmp_dir); |
10 | reyssat | 1084 | read_tmp_file(p,"ls.out"); |
1085 | } |
||
1086 | |||
12047 | bpr | 1087 | void calc_fileexists(char *p) |
1088 | { |
||
1089 | char *pp, *fname; |
||
1090 | /* security measures. */ |
||
1091 | for(pp=p;*pp;pp++) if(isspace(*pp) || *pp==';') *pp=' '; |
||
1092 | if(strstr(p,parent_dir_string)!=NULL) { |
||
1093 | setvar(error_data_string,p); |
||
1094 | module_error("illegal_fname"); return mystrncpy(p,"no",MAX_LINELEN); |
||
1095 | } |
||
1096 | if(strncmp(p,"wimshome/",9)==0){ |
||
1097 | if(robot_access || !trusted_module() || is_class_module){ |
||
1098 | module_error("illegal_fname"); return mystrncpy(p,"no",MAX_LINELEN); |
||
1099 | } |
||
1100 | else |
||
1101 | { |
||
1102 | fname=strchr(p,'/'); |
||
1103 | if(ftest(mkfname(NULL,"%s/%s",getvar("wims_home"),fname))==is_file) |
||
12074 | bpr | 1104 | return mystrncpy(p,"yes",MAX_LINELEN); |
12047 | bpr | 1105 | } |
1106 | } |
||
1107 | if(ftest(mkfname(NULL,"%s",p))==is_file) return mystrncpy(p,"yes",MAX_LINELEN); |
||
1108 | else return mystrncpy(p,"no",MAX_LINELEN); |
||
1109 | } |
||
1110 | |||
7673 | bpr | 1111 | /* instex static: static tex inserts */ |
10 | reyssat | 1112 | void calc_instexst(char *p) |
1113 | { |
||
1114 | char nbuf[MAX_FNAME+1], bufc[MAX_LINELEN+1]; |
||
1115 | char buf2[1024], altbuf[1024], buf[MAX_LINELEN+1], urlbuf[MAX_LINELEN+1]; |
||
1116 | char *b, *at, *al, *md1, *md2; |
||
1117 | int t, border, vspace; |
||
1118 | struct stat st,stc; |
||
1119 | char *p1, *p2, *p3, *ppp, *pt; |
||
1120 | |||
1121 | if(robot_access) {*p=0; return;} |
||
1122 | p1=find_word_start(p); p2=find_word_end(p1); |
||
1123 | p3=p2-4; vspace=0; |
||
1124 | fix_tex_size(); |
||
7404 | bpr | 1125 | t=untrust; untrust=0; |
10 | reyssat | 1126 | if(find_module_file(m_file.name,bufc,0)) module_error(m_file.name); |
1127 | else stat(bufc,&stc); |
||
1128 | untrust=t; |
||
1129 | if(*p3=='.' && (memcmp(p3+1,"gif",3)==0 || memcmp(p3+1,"png",3)==0)) { |
||
7673 | bpr | 1130 | char mbuf[MAX_LINELEN+1]; |
1131 | if(*p2!=0) *p2++=0; |
||
1132 | p2=find_word_start(p2); |
||
1133 | ovlstrcpy(mbuf,p1); substit(mbuf); |
||
1134 | if(strstr(mbuf,parent_dir_string)!=NULL) { |
||
1135 | setvar(error_data_string,mbuf); |
||
1136 | module_error("illegal_fname"); return; |
||
1137 | } |
||
1138 | mkfname(nbuf,"%s/%s",module_prefix,mbuf); |
||
10 | reyssat | 1139 | } |
1140 | else { |
||
7673 | bpr | 1141 | ppp=getvar(ro_name[ro_module]); |
1142 | if(ppp==NULL) internal_error("calc_instexst(): module name vanishes."); |
||
1143 | p2=p1; |
||
1144 | mkfname(nbuf,"w/instex/%d/%s/%s_%d.gif", |
||
1145 | current_tex_size,ppp,m_file.name,m_file.l); |
||
10 | reyssat | 1146 | } |
1147 | snprintf(urlbuf,sizeof(urlbuf),"%s%s?%X",ref_base,nbuf, |
||
7673 | bpr | 1148 | (unsigned short int) stc.st_mtime); |
10 | reyssat | 1149 | mystrncpy(buf,nbuf,sizeof(buf)); |
1150 | if((ppp=strrchr(buf,'/'))!=NULL) { |
||
7673 | bpr | 1151 | *ppp=0;mkdirs(buf); |
10 | reyssat | 1152 | } |
1153 | b=getvar("ins_border"); |
||
1154 | at=getvar("ins_attr"); |
||
1155 | al=getvar("ins_align"); |
||
1156 | if(at==NULL) at=""; |
||
11125 | georgesk | 1157 | if(al==NULL) al=""; |
1158 | al=find_word_start(al); |
||
6265 | bpr | 1159 | if(*al!=0) snprintf(buf2,sizeof(buf2),"vertical-align:%s",al); else buf2[0]=0; |
10 | reyssat | 1160 | if(b==NULL || *b==0) border=0; |
1161 | else border=atoi(b); |
||
11125 | georgesk | 1162 | if(border<0) border=0; |
1163 | if(border>100) border=100; |
||
10 | reyssat | 1164 | if(instex_ready(p2,urlbuf)) goto prt; |
1165 | if(stat(nbuf,&st)!=0 || st.st_mtime<stc.st_mtime || st.st_size<45) { |
||
7673 | bpr | 1166 | setenv("texgif_style",instex_style,1); |
1167 | setenv("texgif_src",p2,1); |
||
1168 | setenv("texgif_outfile",nbuf,1); |
||
1169 | setenv("texgif_tmpdir",tmp_dir,1); exportall(); |
||
1170 | wrapexec=0; call_ssh("%s &>%s/instexst.log",tex2gif,tmp_dir); |
||
1171 | setenv("instexst_src","",1); |
||
10 | reyssat | 1172 | } |
1173 | prt: md1=md2=""; |
||
1174 | if(strcasecmp(al,"middle")==0) { |
||
7673 | bpr | 1175 | md1=mathalign_sup1; md2=mathalign_sup2; |
1176 | vspace=5; |
||
10 | reyssat | 1177 | } |
1178 | if(ins_alt[0]==0) mystrncpy(ins_alt,p2,sizeof(ins_alt)); |
||
1179 | if(strchr(ins_alt,'"')!=NULL || strlen(ins_alt)>256) ins_alt[0]=0; |
||
1180 | pt=getvar("wims_ins_alt"); if(pt==NULL) pt=""; |
||
1181 | if(ins_alt[0] && strcmp(pt,"none")!=0) |
||
1182 | snprintf(altbuf,sizeof(altbuf)," alt=\"%s\"",ins_alt); |
||
3522 | bpr | 1183 | else snprintf(altbuf,sizeof(altbuf)," alt=\"\""); |
6265 | bpr | 1184 | snprintf(p,MAX_LINELEN,"%s<img src=\"%s\" style=\"border:solid;border-width:%dpx;margin-bottom:%dpx;%s\" %s %s />%s", |
7673 | bpr | 1185 | md1,urlbuf,border,vspace,buf2,at,altbuf,md2); |
10 | reyssat | 1186 | setvar("ins_attr",""); ins_alt[0]=0; |
1187 | setvar("ins_url",urlbuf); |
||
1188 | } |
||
1189 | |||
7673 | bpr | 1190 | /* extract non-empty lines or items */ |
10 | reyssat | 1191 | void calc_nonempty(char *p) |
1192 | { |
||
1193 | int type, i, cnt; |
||
1194 | char *p1, *p2, buf[MAX_LINELEN+1], out[MAX_LINELEN+1]; |
||
1195 | p1=find_word_start(p); p2=find_word_end(p1); |
||
1196 | if(*p2) *p2++=0; else { |
||
7673 | bpr | 1197 | *p=0; return; |
10 | reyssat | 1198 | } |
1199 | type=0; |
||
1200 | if(strcasecmp(p1,"item")==0 || strcasecmp(p1,"items")==0) type=1; |
||
1201 | if(type==0 && (strcasecmp(p1,"line")==0 || strcasecmp(p1,"lines")==0)) |
||
1202 | type=2; |
||
1203 | if(type==0 && (strcasecmp(p1,"row")==0 || strcasecmp(p1,"rows")==0)) |
||
1204 | type=3; |
||
1205 | if(type==0) module_error("syntax_error"); |
||
1206 | out[0]=out[1]=0; |
||
1207 | switch(type) { |
||
7673 | bpr | 1208 | case 1: { /* items */ |
1209 | cnt=itemnum(p2); |
||
1210 | for(i=1; i<=cnt; i++) { |
||
1211 | fnd_item(p2,i,buf); |
||
1212 | if(*find_word_start(buf)) { |
||
1213 | strcat(out,",");strcat(out,buf); |
||
1214 | } |
||
1215 | } |
||
1216 | break; |
||
1217 | } |
||
1218 | case 2: { /* lines */ |
||
1219 | lines: cnt=linenum(p2); |
||
1220 | for(i=1; i<=cnt; i++) { |
||
1221 | fnd_line(p2,i,buf); |
||
1222 | if(*find_word_start(buf)) { |
||
1223 | strcat(out,"\n");strcat(out,buf); |
||
1224 | } |
||
1225 | } |
||
1226 | break; |
||
1227 | } |
||
1228 | case 3: { /* rows */ |
||
1229 | int t=rows2lines(p2); |
||
1230 | if(t==0) goto lines; |
||
1231 | cnt=linenum(p2); |
||
1232 | for(i=1; i<=cnt; i++) { |
||
1233 | fnd_line(p2,i,buf); |
||
1234 | if(*find_word_start(buf)) { |
||
1235 | strcat(out,";");strcat(out,buf); |
||
1236 | } |
||
1237 | } |
||
1238 | break; |
||
1239 | } |
||
1240 | default: break; |
||
10 | reyssat | 1241 | } |
3718 | reyssat | 1242 | ovlstrcpy(p,out+1); |
10 | reyssat | 1243 | } |
1244 | |||
7673 | bpr | 1245 | /* returns a list with unique items */ |
10 | reyssat | 1246 | void calc_listuniq(char *p) |
1247 | { |
||
1248 | int i,n; |
||
1249 | char lout[MAX_LINELEN+2], *ll; |
||
1250 | char *cut[MAX_LIST]; |
||
1251 | lout[0]=lout[1]=0; |
||
1252 | n=cutitems(p,cut,MAX_LIST); for(i=0;i<n;i++) { |
||
7673 | bpr | 1253 | ll=cut[i]; |
1254 | if(*ll && itemchr(lout,ll)==NULL && |
||
1255 | strlen(lout)+strlen(ll)<MAX_LINELEN-2) { |
||
1256 | strcat(lout,",");strcat(lout,ll); |
||
1257 | } |
||
10 | reyssat | 1258 | } |
3718 | reyssat | 1259 | ovlstrcpy(p,lout+1); |
10 | reyssat | 1260 | } |
1261 | |||
7673 | bpr | 1262 | /* returns intersection of 2 lists */ |
10 | reyssat | 1263 | void calc_listintersect(char *p) |
1264 | { |
||
1265 | char l1[MAX_LINELEN+1],l2[MAX_LINELEN+1],lout[MAX_LINELEN+2]; |
||
1266 | char *cut[MAX_LIST]; |
||
1267 | char *pp, *ll; |
||
1268 | int i,n; |
||
7404 | bpr | 1269 | |
10 | reyssat | 1270 | pp=wordchr(p,"and"); |
1271 | if(pp==NULL) module_error("syntax_error"); |
||
3718 | reyssat | 1272 | *pp=0;ovlstrcpy(l1,p); ovlstrcpy(l2,pp+strlen("and")); |
10 | reyssat | 1273 | lout[0]=lout[1]=0; substit(l1); substit(l2); |
1274 | n=cutitems(l1,cut,MAX_LIST); if(n<=0) {*p=0; return;} |
||
1275 | for(i=0;i<n;i++) { |
||
7673 | bpr | 1276 | ll=cut[i]; |
1277 | if(ll[0] && itemchr(l2,ll)!=NULL && itemchr(lout,ll)==NULL && |
||
1278 | strlen(lout)+strlen(ll)<MAX_LINELEN-2) { |
||
1279 | strcat(lout,",");strcat(lout,ll); |
||
1280 | } |
||
10 | reyssat | 1281 | } |
3718 | reyssat | 1282 | ovlstrcpy(p,lout+1); |
10 | reyssat | 1283 | } |
1284 | |||
7673 | bpr | 1285 | /* returns union of 2 lists */ |
10 | reyssat | 1286 | void calc_listunion(char *p) |
1287 | { |
||
1288 | char l1[MAX_LINELEN+1],l2[MAX_LINELEN+1],lout[MAX_LINELEN+2]; |
||
1289 | char *cut[MAX_LIST]; |
||
1290 | char *pp, *ll; |
||
1291 | int i,n; |
||
7404 | bpr | 1292 | |
10 | reyssat | 1293 | pp=wordchr(p,"and"); |
1294 | if(pp==NULL) module_error("syntax_error"); |
||
3718 | reyssat | 1295 | *pp=0;ovlstrcpy(l1,p); ovlstrcpy(l2,pp+strlen("and")); |
10 | reyssat | 1296 | lout[0]=lout[1]=0; substit(l1); substit(l2); |
1297 | n=cutitems(l1,cut,MAX_LIST); for(i=0;i<n;i++) { |
||
7673 | bpr | 1298 | ll=cut[i]; |
1299 | if(ll[0] && itemchr(lout,ll)==NULL && |
||
1300 | strlen(lout)+strlen(ll)<MAX_LINELEN-2) { |
||
1301 | strcat(lout,",");strcat(lout,ll); |
||
1302 | } |
||
10 | reyssat | 1303 | } |
1304 | n=cutitems(l2,cut,MAX_LIST); for(i=0;i<n;i++) { |
||
7673 | bpr | 1305 | ll=cut[i]; |
1306 | if(ll[0] && itemchr(lout,ll)==NULL && |
||
1307 | strlen(lout)+strlen(ll)<MAX_LINELEN-2) { |
||
1308 | strcat(lout,",");strcat(lout,ll); |
||
1309 | } |
||
10 | reyssat | 1310 | } |
3718 | reyssat | 1311 | ovlstrcpy(p,lout+1); |
10 | reyssat | 1312 | } |
1313 | |||
7673 | bpr | 1314 | /* returns items of list2 not in list1 */ |
10 | reyssat | 1315 | void calc_listcomplement(char *p) |
1316 | { |
||
1317 | char l1[MAX_LINELEN+1],l2[MAX_LINELEN+1],lout[MAX_LINELEN+2]; |
||
1318 | char *cut[MAX_LIST]; |
||
1319 | char *pp, *ll; |
||
1320 | int i,n; |
||
7404 | bpr | 1321 | |
10 | reyssat | 1322 | pp=wordchr(p,"in"); |
1323 | if(pp==NULL) module_error("syntax_error"); |
||
3718 | reyssat | 1324 | *pp=0;ovlstrcpy(l1,p); ovlstrcpy(l2,pp+strlen("in")); |
10 | reyssat | 1325 | lout[0]=lout[1]=0; substit(l1); substit(l2); |
1326 | n=cutitems(l2,cut,MAX_LIST); if(n<=0) {*p=0; return;} |
||
1327 | for(i=0;i<n;i++) { |
||
7673 | bpr | 1328 | ll=cut[i]; |
1329 | if(ll[0] && itemchr(l1,ll)==NULL && itemchr(lout,ll)==NULL && |
||
1330 | strlen(lout)+strlen(ll)<MAX_LINELEN-2) { |
||
1331 | strcat(lout,",");strcat(lout,ll); |
||
1332 | } |
||
10 | reyssat | 1333 | } |
3718 | reyssat | 1334 | ovlstrcpy(p,lout+1); |
10 | reyssat | 1335 | } |
1336 | |||
7673 | bpr | 1337 | /* Consult a dictionary to translate a string */ |
10 | reyssat | 1338 | /* |
1339 | void calc_dictionary(char *p) |
||
1340 | { |
||
1341 | char *pp; |
||
1342 | char name[MAX_LINELEN+1], str[MAX_LINELEN+1]; |
||
1343 | int t; |
||
1344 | pp=wordchr(p,"for"); |
||
1345 | if(pp==NULL || pp<=p) module_error("syntax_error"); |
||
7404 | bpr | 1346 | *(find_word_end(pp-1))=0; |
3718 | reyssat | 1347 | ovlstrcpy(name,p); substit(name); |
10 | reyssat | 1348 | pp=find_word_start(pp+strlen("for")); t=0; |
7404 | bpr | 1349 | if(memcmp(pp,"word",strlen("word"))==0 && |
1350 | (isspace(*(pp+strlen("word"))) || |
||
7673 | bpr | 1351 | (*(pp+strlen("word"))=='s' && isspace(*(pp+strlen("words")))))) { |
1352 | pp=find_word_start(pp+strlen("words")); t=1; |
||
10 | reyssat | 1353 | } |
7404 | bpr | 1354 | if(memcmp(pp,"line",strlen("line"))==0 && |
1355 | (isspace(*(pp+strlen("line"))) || |
||
7673 | bpr | 1356 | (*(pp+strlen("line"))=='s' && isspace(*(pp+strlen("lines")))))) { |
1357 | pp=find_word_start(pp+strlen("lines")); t=1; |
||
10 | reyssat | 1358 | } |
1359 | if(memcmp(pp,"list",strlen("list"))==0 && isspace(*(pp+strlen("list")))) { |
||
7673 | bpr | 1360 | pp=find_word_start(pp+strlen("list")); |
10 | reyssat | 1361 | } |
1362 | if(memcmp(pp,"items",strlen("items"))==0 && isspace(*(pp+strlen("items")))) { |
||
7673 | bpr | 1363 | pp=find_word_start(pp+strlen("items")); |
10 | reyssat | 1364 | } |
1365 | if(memcmp(pp,"item",strlen("item"))==0 && isspace(*(pp+strlen("item")))) { |
||
7673 | bpr | 1366 | pp=find_word_start(pp+strlen("item")); |
10 | reyssat | 1367 | } |
3718 | reyssat | 1368 | ovlstrcpy(str,pp); substit(str); |
10 | reyssat | 1369 | switch(t) { |
7673 | bpr | 1370 | case 1: { |
1371 | calc_words2items(str); break; |
||
1372 | } |
||
1373 | case 2: { |
||
1374 | calc_lines2items(str); break; |
||
1375 | } |
||
1376 | default: break; |
||
10 | reyssat | 1377 | } |
1378 | } |
||
1379 | */ |
||
1380 | |||
1381 | void calc_module(char *p) |
||
1382 | { |
||
1383 | char *p1,*p2, ind_buf[MAX_LINELEN+1], buf[MAX_FNAME+1]; |
||
1384 | char *tp; |
||
7404 | bpr | 1385 | |
10 | reyssat | 1386 | p1=find_word_start(p); p2=find_word_end(p1); |
1387 | if(*p2!=0) *p2++=0; |
||
1388 | p2=find_word_start(p2); *find_word_end(p2)=0; |
||
1389 | if(*p1==0) {empty: *p=0; return;} |
||
1390 | if(*p2==0) { |
||
7673 | bpr | 1391 | snprintf(buf,sizeof(buf),"module_%s",p1); |
1392 | p1=getvar(buf); if(p1==NULL) p1=""; |
||
1393 | mystrncpy(p,p1,MAX_LINELEN); return; |
||
10 | reyssat | 1394 | } |
1395 | mkfname(buf,"%s/%s/INDEX",module_dir,p2); |
||
1396 | tp=readfile(buf,ind_buf,MAX_LINELEN); |
||
1397 | if(tp==NULL) { |
||
7673 | bpr | 1398 | mkfname(buf,"%s/%s/index",module_dir,p2); |
1399 | tp=readfile(buf,ind_buf,MAX_LINELEN); |
||
10 | reyssat | 1400 | } |
1401 | if(tp==NULL && p2[strlen(p2)-3]!='.') { |
||
7673 | bpr | 1402 | mkfname(buf,"%s/%s.%s/INDEX",module_dir,p2,lang); |
1403 | tp=readfile(buf,ind_buf,MAX_LINELEN); if(tp==NULL) { |
||
1404 | mkfname(buf,"%s/%s.%s/index",module_dir,p2,lang); |
||
1405 | tp=readfile(buf,ind_buf,MAX_LINELEN); |
||
1406 | } |
||
1407 | if(tp==NULL) { |
||
1408 | int i; |
||
1409 | for(i=0;i<available_lang_no;i++) { |
||
1410 | mkfname(buf,"%s/%s.%s/INDEX",module_dir,p2,available_lang[i]); |
||
1411 | tp=readfile(buf,ind_buf,MAX_LINELEN); if(tp) break; |
||
1412 | mkfname(buf,"%s/%s.%s/index",module_dir,p2, |
||
1413 | available_lang[i]); |
||
1414 | tp=readfile(buf,ind_buf,MAX_LINELEN); if(tp) break; |
||
1415 | } |
||
1416 | } |
||
10 | reyssat | 1417 | } |
7673 | bpr | 1418 | if(tp==NULL) goto empty; /* module not found */ |
10 | reyssat | 1419 | _getdef(ind_buf,p1,p); |
1420 | } |
||
1421 | |||
7673 | bpr | 1422 | /* strip enclosing parentheses */ |
10 | reyssat | 1423 | void calc_declosing(char *p) |
1424 | { |
||
1425 | strip_enclosing_par(p); |
||
1426 | } |
||
1427 | |||
7673 | bpr | 1428 | /* remove html tag, very rudimentary. */ |
10 | reyssat | 1429 | void calc_detag(char *p) |
1430 | { |
||
1431 | char *p1, *p2; |
||
1432 | for(p1=strchr(p,'<'); p1!=NULL; p1=strchr(p1,'<')) { |
||
7673 | bpr | 1433 | p2=strchr(p1,'>'); if(p2==NULL) p1++; |
1434 | else ovlstrcpy(p1,p2+1); |
||
10 | reyssat | 1435 | } |
1436 | } |
||
1437 | |||
8155 | bpr | 1438 | /* prepare a string to be inserted into a form input or textarea as is */ |
10 | reyssat | 1439 | void calc_reinput(char *p) |
1440 | { |
||
1441 | char *p1; |
||
1442 | for(p1=strchr(p,'&'); p1!=NULL; p1=strchr(p1,'&')) { |
||
7673 | bpr | 1443 | p1++; string_modify(p,p1,p1,"amp;"); |
10 | reyssat | 1444 | } |
1445 | for(p1=strchr(p,'<'); p1!=NULL; p1=strchr(++p1,'<')) |
||
1446 | string_modify(p,p1,p1+1,"<"); |
||
1447 | } |
||
1448 | |||
7673 | bpr | 1449 | /* get a definition from a file. Trusted modules only. */ |
10 | reyssat | 1450 | void calc_defof(char *p) |
1451 | { |
||
1452 | char *p1; |
||
1453 | char fbuf[MAX_FNAME+1], nbuf[MAX_LINELEN+1], tbuf[MAX_LINELEN+1]; |
||
7404 | bpr | 1454 | |
10 | reyssat | 1455 | secure_exec(); |
1456 | p1=wordchr(p,"in"); if(p1==NULL) module_error("syntax_error"); |
||
1457 | *p1=0; p1=find_word_start(p1+strlen("in")); |
||
1458 | mystrncpy(nbuf,p,sizeof(nbuf)); mystrncpy(tbuf,p1,sizeof(tbuf)); |
||
1459 | substit(nbuf); substit(tbuf); |
||
1460 | p1=find_word_start(tbuf); *find_word_end(p1)=0; |
||
1461 | if(find_module_file(p1,fbuf,0)) {*p=0; return;} |
||
1462 | p1=find_word_start(nbuf); strip_trailing_spaces(p1); |
||
1463 | getdef(fbuf,p1,p); |
||
1464 | } |
||
1465 | |||
7673 | bpr | 1466 | /* check host */ |
10 | reyssat | 1467 | void calc_checkhost(char *p) |
1468 | { |
||
1469 | int t; |
||
3718 | reyssat | 1470 | if(robot_access || !trusted_module()) ovlstrcpy(p,"0"); |
10 | reyssat | 1471 | else { |
7673 | bpr | 1472 | t=checkhost(p); mystrncpy(p,int2str(t),MAX_LINELEN); |
10 | reyssat | 1473 | } |
1474 | } |
||
1475 | |||
1476 | #define MAX_COLUMNS 256 |
||
1477 | |||
7673 | bpr | 1478 | /* A rudimentary database facility */ |
10 | reyssat | 1479 | void calc_select(char *p) |
1480 | { |
||
1481 | char *p1, *p2, *p3, *bufp, c, sep; |
||
1482 | char buf1[MAX_LINELEN+1], buf2[MAX_LINELEN+1]; |
||
1483 | char buf[MAX_LINELEN+1]; |
||
1484 | int i,j,lmax; |
||
1485 | p2=wordchr(p,"where"); if(p2==NULL) module_error("syntax_error"); |
||
1486 | *p2=0; p2+=strlen("where"); |
||
1487 | p2=find_word_start(p2); strip_trailing_spaces(p2); |
||
1488 | p1=find_word_start(p) ; strip_trailing_spaces(p1); |
||
1489 | if(*p1==0 || *p2==0) module_error("syntax_error"); |
||
3718 | reyssat | 1490 | ovlstrcpy(buf1,p1); ovlstrcpy(buf2,p2); sep='\n'; |
7673 | bpr | 1491 | /* buf1: data; buf2: condition. */ |
7404 | bpr | 1492 | substit(buf1); |
7673 | bpr | 1493 | if(strstr(buf2,"column")!=NULL) { /* matrix */ |
1494 | lmax=0; if(rows2lines(buf1)) sep=';'; |
||
1495 | for(p1=strstr(buf2,"column"); p1; p1=strstr(p1+1,"column")) { |
||
1496 | if(p1>buf2 && isalnum(*(p1-1))) continue; |
||
1497 | p2=find_word_start(p1+strlen("column")); |
||
1498 | for(p3=p2; myisdigit(*p3); p3++); |
||
1499 | if(p3==p2) continue; |
||
1500 | c=*p3; *p3=0; i=atoi(p2); *p3=c; |
||
1501 | if(i<=0 || i>MAX_COLUMNS) continue; |
||
1502 | if(i>lmax) lmax=i; |
||
1503 | string_modify(buf2,p1,p3,"$(wims_select_col_%d)",i); |
||
1504 | } |
||
1505 | buf[0]=0; bufp=buf; |
||
1506 | for(p1=buf1; *p1; p1=p2) { |
||
1507 | char ibuf[MAX_LINELEN+1], nbuf[MAX_NAMELEN+1]; |
||
1508 | p2=strchr(p1,'\n'); |
||
1509 | if(p2==NULL) p2=p1+strlen(p1); else *p2++=0; |
||
1510 | if(*find_word_start(p1)==0) continue; |
||
1511 | for(j=1;j<=lmax;j++) { |
||
1512 | snprintf(nbuf,sizeof(nbuf),"wims_select_col_%d",j); |
||
1513 | fnd_item(p1,j,ibuf); force_setvar(nbuf,ibuf); |
||
1514 | } |
||
1515 | ovlstrcpy(ibuf,buf2); if(compare(ibuf,0,0)) { |
||
1516 | snprintf(bufp,MAX_LINELEN-(bufp-buf),"%s%c",p1,sep); |
||
1517 | bufp+=strlen(bufp); |
||
1518 | } |
||
1519 | } |
||
10 | reyssat | 1520 | } |
7673 | bpr | 1521 | else { /* datafile */ |
1522 | module_error("syntax_error"); |
||
7404 | bpr | 1523 | |
10 | reyssat | 1524 | } |
1525 | if(buf[0]!=0) buf[strlen(buf)-1]=0; |
||
1526 | mystrncpy(p,buf,MAX_LINELEN); |
||
1527 | } |
||
1528 | |||
7673 | bpr | 1529 | /* Extract a column from a matrix */ |
10 | reyssat | 1530 | void calc_columnof(char *p) |
1531 | { |
||
1532 | char *p1, *p2, *bufp, sep; |
||
1533 | char buf1[MAX_LINELEN+1], buf2[MAX_LINELEN+1]; |
||
1534 | char buf[MAX_LINELEN+1]; |
||
1535 | p2=wordchr(p,"of"); if(p2==NULL) module_error("syntax_error"); |
||
1536 | *p2=0; p2+=strlen("of"); |
||
1537 | p2=find_word_start(p2); strip_trailing_spaces(p2); |
||
1538 | p1=find_word_start(p) ; strip_trailing_spaces(p1); |
||
1539 | if(*p1==0) module_error("syntax_error"); |
||
1540 | if(*p2==0) {*p=0; return;} |
||
3718 | reyssat | 1541 | ovlstrcpy(buf1,p1); ovlstrcpy(buf2,p2); sep='\n'; |
7673 | bpr | 1542 | /* buf1: number(s); buf2: matrix. */ |
7404 | bpr | 1543 | substit(buf1); substit(buf2); |
10 | reyssat | 1544 | if(rows2lines(buf2)) sep=';'; |
1545 | if(strchr(buf1,',')==NULL && wordchr(buf1,"to")==NULL |
||
1546 | && strstr(buf1,"..")==NULL) sep=','; |
||
1547 | buf[0]=0; bufp=buf; |
||
1548 | for(p1=buf2; *p1; p1=p2) { |
||
7673 | bpr | 1549 | char ibuf[MAX_LINELEN+1]; |
1550 | p2=strchr(p1,'\n'); |
||
1551 | if(p2==NULL) p2=p1+strlen(p1); else *p2++=0; |
||
1552 | snprintf(ibuf,sizeof(ibuf),"%s of %s",buf1,p1); |
||
1553 | calc_itemof(ibuf); |
||
1554 | snprintf(bufp,MAX_LINELEN-(bufp-buf),"%s%c",ibuf,sep); |
||
1555 | bufp+=strlen(bufp); |
||
10 | reyssat | 1556 | } |
1557 | if(buf[0]!=0) buf[strlen(buf)-1]=0; |
||
1558 | mystrncpy(p,buf,MAX_LINELEN); |
||
1559 | } |
||
1560 | |||
7673 | bpr | 1561 | /* find roots of a function or equation in a given zone */ |
10 | reyssat | 1562 | void calc_solve(char *p) |
1563 | { |
||
1564 | char *pp, *fp, *forp; |
||
1565 | char buf[MAX_LINELEN+1], vbuf[MAX_LINELEN+1]; |
||
8176 | bpr | 1566 | double v, dd, start, stop, step, old, v1, v2, v3, d1, d3; |
10 | reyssat | 1567 | int i, pos; |
7404 | bpr | 1568 | |
10 | reyssat | 1569 | forp=wordchr(p,"for"); |
1570 | if(forp==NULL) { syntax: module_error("syntax_error"); *p=0; return; } |
||
1571 | *forp=0; forp+=strlen("for"); |
||
1572 | fp=find_word_start(p); strip_trailing_spaces(fp); |
||
1573 | if(*fp==0) goto syntax; |
||
1574 | i=cutfor(forp,NULL); if(i<0 || forstruct.type==for_in) goto syntax; |
||
1575 | if(i>0) {*p=0; return;} |
||
1576 | start=forstruct.from; stop=forstruct.to; forp=forstruct.var; |
||
1577 | mystrncpy(buf,fp,sizeof(buf)); substitute(buf); |
||
1578 | *p=0; pp=strchr(buf,'='); if(pp!=NULL) { |
||
7673 | bpr | 1579 | if(strlen(buf)>=MAX_LINELEN-16) return; |
1580 | strcat(buf,")"); |
||
1581 | string_modify(buf,pp,pp+1,"-("); |
||
10 | reyssat | 1582 | } |
1583 | i=0; for(fp=varchr(buf,forp); fp!=NULL; fp=varchr(fp,forp)) { |
||
7673 | bpr | 1584 | string_modify(buf,fp,fp+strlen(forp),EV_X); fp+=strlen(EV_X); i++; |
10 | reyssat | 1585 | } |
1586 | if(i==0 || start==stop) return; |
||
1587 | evalue_compile(buf); pos=eval_getpos(EV_X); |
||
1588 | if(start>stop) {dd=start; start=stop; stop=dd;} |
||
1589 | step=(stop-start)/100; if(step==0) return; |
||
1590 | pp=p; old=0; |
||
1591 | for(v=start; v<=stop; v+=step, old=dd) { |
||
7673 | bpr | 1592 | eval_setval(pos,v); |
7847 | bpr | 1593 | dd=checked_eval(buf); |
7673 | bpr | 1594 | if(v==start) continue; |
8171 | bpr | 1595 | if(!isfinite(old) || !isfinite(dd) || (old>0 && dd>0) || (old<0 && dd<0)) |
7673 | bpr | 1596 | continue; |
1597 | if(dd==0 && v<stop) continue; |
||
8176 | bpr | 1598 | v1=v-step; v2=v; d1=old; |
7673 | bpr | 1599 | for(i=0;i<30;i++) { |
1600 | v3=(v1+v2)/2; eval_setval(pos,v3); |
||
7847 | bpr | 1601 | d3=checked_eval(buf); |
8171 | bpr | 1602 | if(!isfinite(d3)) goto next; |
7673 | bpr | 1603 | if((d1>0 && d3>0) || (d1<0 && d3<0)) {d1=d3; v1=v3;} |
8176 | bpr | 1604 | else {v2=v3;} |
7673 | bpr | 1605 | } |
1606 | float2str(v3,vbuf); if(pp-p+strlen(vbuf)<MAX_LINELEN-1) { |
||
11125 | georgesk | 1607 | if(pp>p) *pp++=','; |
1608 | ovlstrcpy(pp,vbuf); |
||
7673 | bpr | 1609 | pp+=strlen(pp); |
1610 | } |
||
1611 | else break; |
||
1612 | next: ; |
||
10 | reyssat | 1613 | } |
1614 | } |
||
1615 | |||
7673 | bpr | 1616 | /* type: 1=values, 2=sum, 3=product, 4=recursion, 5=subst */ |
10 | reyssat | 1617 | void _values(char *p, int type) |
1618 | { |
||
1619 | char *pp, *fp, *forp; |
||
1620 | char vbuf[MAX_LINELEN+1], buf[MAX_LINELEN+1], fbuf[MAX_LINELEN+1], tbuf[MAX_LINELEN+1]; |
||
1621 | char *f[64]; |
||
1622 | double v, dd, start, stop, step, v0; |
||
1623 | int i, k, fcnt, pos, posr; |
||
7404 | bpr | 1624 | |
10 | reyssat | 1625 | forp=wordchr(p,"for"); |
1626 | if(forp==NULL) { syntax: module_error("syntax_error"); *p=0; return; } |
||
1627 | *forp=0; forp+=strlen("for"); forp=find_word_start(forp); |
||
1628 | fp=find_word_start(p); strip_trailing_spaces(fp); |
||
1629 | if(*fp==0) goto syntax; |
||
1630 | if(type<5) i=cutfor(forp,NULL); else i=cutfor(forp,tbuf); |
||
11125 | georgesk | 1631 | if(i<0) goto syntax; |
1632 | if(i>0) {*p=0; return;} |
||
10 | reyssat | 1633 | start=forstruct.from; stop=forstruct.to; step=forstruct.step; |
1634 | forp=forstruct.var; |
||
1635 | mystrncpy(buf,fp,sizeof(buf)); substitute(buf); |
||
1636 | for(fp=varchr(buf,forp); fp!=NULL; fp=varchr(fp,forp)) { |
||
7673 | bpr | 1637 | string_modify(buf,fp,fp+strlen(forp),EV_X); fp+=strlen(EV_X); |
10 | reyssat | 1638 | } |
1639 | for(fp=varchr(buf,"last"); fp!=NULL; fp=varchr(fp,"last")) { |
||
7673 | bpr | 1640 | string_modify(buf,fp,fp+strlen("last"),EV_S); fp+=strlen(EV_S); |
10 | reyssat | 1641 | } |
1642 | fcnt=pos=posr=0; |
||
1643 | if(type==5) goto skip; |
||
1644 | fcnt=itemnum(buf); if(fcnt>64) fcnt=64; pp=fbuf; |
||
1645 | for(k=0; k<fcnt; k++) { |
||
7673 | bpr | 1646 | fnd_item(buf,k+1,vbuf); evalue_compile(vbuf); |
1647 | if(pp-fbuf+strlen(vbuf)<MAX_LINELEN-1) { |
||
1648 | f[k]=pp; ovlstrcpy(pp,vbuf); pp+=strlen(pp)+1; |
||
1649 | } |
||
1650 | else f[k]=""; |
||
10 | reyssat | 1651 | } |
1652 | pos=eval_getpos(EV_X); posr=eval_getpos(EV_S); |
||
1653 | skip: |
||
1654 | if(step==0) step=1;/* if(step<0) step=-step; |
||
1655 | if(stop<start) {dd=start; start=stop; stop=dd;} */ |
||
1656 | *p=0; v0=0; |
||
1657 | switch(type) { |
||
7673 | bpr | 1658 | case 4: |
1659 | case 1: { |
||
1660 | pp=getvar("recursion_start"); |
||
1661 | if(pp==NULL || *pp==0) v0=0; |
||
1662 | else { |
||
8176 | bpr | 1663 | v0=evalue(pp); if(!isfinite(v0)) return; |
7673 | bpr | 1664 | } |
1665 | break; |
||
1666 | } |
||
1667 | case 2: v0=0; break; |
||
1668 | case 3: v0=1; break; |
||
1669 | case 5: break; |
||
10 | reyssat | 1670 | } |
1671 | pp=p; |
||
1672 | if(type==5) { |
||
7673 | bpr | 1673 | char *ps, *pt, buf2[MAX_LINELEN+1]; |
1674 | int l,ln; |
||
1675 | *p=0; l=strlen(buf); if(l>=MAX_LINELEN) return; |
||
1676 | for(i=0,v=start; i<MAX_VALUE_LIST && v*step<=stop*step; v+=step, i++) { |
||
1677 | if(forstruct.type==for_from) { |
||
1678 | float2str(v,vbuf); ps=vbuf; |
||
1679 | } |
||
1680 | else ps=forstruct.pos[i]; |
||
1681 | ovlstrcpy(buf2,buf); l=strlen(ps);ln=strlen(EV_X); |
||
1682 | for(pt=varchr(buf2,EV_X);pt!=NULL;pt=varchr(pt+l,EV_X)) |
||
1683 | string_modify(buf2,pt,pt+ln,"%s",ps); |
||
1684 | if(pp-p+strlen(buf2)>=MAX_LINELEN-1) return; |
||
11125 | georgesk | 1685 | if(pp>p) *pp++=','; |
1686 | ovlstrcpy(pp,buf2); |
||
7673 | bpr | 1687 | pp+=strlen(pp); |
1688 | } |
||
1689 | return; |
||
10 | reyssat | 1690 | } |
1691 | for(i=0,v=start; i<MAX_VALUE_LIST && v*step<=stop*step; v+=step, i++) { |
||
7673 | bpr | 1692 | if(forstruct.type==for_from) eval_setval(pos,v); |
1693 | else eval_setval(pos,forstruct.list[i]); |
||
1694 | eval_setval(posr,v0); |
||
1695 | for(k=0; k<fcnt; k++) { |
||
7847 | bpr | 1696 | dd=checked_eval(f[k]); |
7673 | bpr | 1697 | switch(type) { |
1698 | case 1: { /* values */ |
||
1699 | float2str(dd,vbuf); |
||
1700 | if(pp-p+strlen(vbuf)<MAX_LINELEN-1) { |
||
11125 | georgesk | 1701 | if(pp>p) *pp++=','; |
1702 | ovlstrcpy(pp,vbuf); |
||
7673 | bpr | 1703 | pp+=strlen(pp); |
1704 | } |
||
1705 | v0=dd; break; |
||
1706 | } |
||
1707 | case 2: { /* sum */ |
||
1708 | v0=v0+dd; break; |
||
1709 | } |
||
1710 | case 3: { /* product */ |
||
1711 | v0=v0*dd; break; |
||
1712 | } |
||
1713 | case 4: { /* recursion */ |
||
1714 | v0=dd; break; |
||
1715 | } |
||
1716 | } |
||
1717 | } |
||
10 | reyssat | 1718 | } |
1719 | if(type!=1) float2str(v0,p); |
||
1720 | } |
||
1721 | |||
7673 | bpr | 1722 | /* cut a function into values */ |
10 | reyssat | 1723 | void calc_values(char *p) |
1724 | { _values(p,1); } |
||
1725 | |||
7673 | bpr | 1726 | /* compute sum */ |
10 | reyssat | 1727 | void calc_sum(char *p) |
1728 | { _values(p,2); } |
||
1729 | |||
7673 | bpr | 1730 | /* compute product */ |
10 | reyssat | 1731 | void calc_product(char *p) |
1732 | { _values(p,3); } |
||
1733 | |||
7673 | bpr | 1734 | /* simple recursion */ |
10 | reyssat | 1735 | void calc_recursion(char *p) |
1736 | { _values(p,4); } |
||
1737 | |||
7673 | bpr | 1738 | /* List substitution */ |
10 | reyssat | 1739 | void calc_makelist(char *p) |
1740 | { _values(p,5); } |
||
1741 | |||
7673 | bpr | 1742 | /* level curve data */ |
10 | reyssat | 1743 | void calc_leveldata(char *p) |
1744 | { |
||
1745 | leveldata ld; |
||
1746 | char *sizep, *rangep, *fp, *levelp, *stepp; |
||
1747 | char *pp,*p2,fbuf[MAX_LINELEN+1],buf[MAX_LINELEN+1]; |
||
1748 | double d[4]; |
||
1749 | int i; |
||
7404 | bpr | 1750 | |
10 | reyssat | 1751 | sizep=wordchr(p,"size"); |
1752 | rangep=wordchr(p,"ranges"); |
||
1753 | fp=wordchr(p,"function"); |
||
1754 | levelp=wordchr(p,"levels"); |
||
1755 | stepp=wordchr(p,"step"); |
||
1756 | if(sizep==NULL || rangep==NULL || fp==NULL) { |
||
7673 | bpr | 1757 | syntax: module_error("syntax_error"); *p=0; return; |
10 | reyssat | 1758 | } |
1759 | *sizep=0; sizep+=strlen("size"); |
||
1760 | *rangep=0; rangep+=strlen("ranges"); |
||
1761 | *fp=0; fp+=strlen("function"); |
||
1762 | if(levelp!=NULL) {*levelp=0; levelp+=strlen("levels");} |
||
1763 | else levelp="0"; |
||
1764 | if(stepp!=NULL) {*stepp=0; stepp+=strlen("step");} |
||
1765 | else stepp="0"; |
||
1766 | mystrncpy(fbuf,fp,sizeof(fbuf)); substitute(fbuf); |
||
1767 | ld.fn=fbuf; |
||
1768 | ld.xname="x"; ld.yname="y"; ld.grain=evalue(stepp); |
||
1769 | mystrncpy(buf,sizep,sizeof(buf)); substitute(buf); |
||
1770 | for(i=0,pp=buf;i<2;i++,pp=p2) { |
||
7673 | bpr | 1771 | if(*pp==0) goto syntax; |
1772 | p2=find_item_end(pp); if(*p2) *p2++=0; |
||
1773 | d[i]=evalue(pp); |
||
10 | reyssat | 1774 | } |
1775 | ld.xsize=d[0]; ld.ysize=d[1]; |
||
1776 | mystrncpy(buf,rangep,sizeof(buf)); substitute(buf); |
||
1777 | for(i=0,pp=buf;i<4;i++,pp=p2) { |
||
7673 | bpr | 1778 | if(*pp==0) goto syntax; |
1779 | p2=find_item_end(pp); if(*p2) *p2++=0; |
||
1780 | d[i]=evalue(pp); |
||
10 | reyssat | 1781 | } |
1782 | ld.xrange[0]=d[0]; ld.xrange[1]=d[1]; ld.yrange[0]=d[3]; ld.yrange[1]=d[2]; |
||
1783 | mystrncpy(buf,levelp,sizeof(buf)); substitute(buf); |
||
1784 | ld.levelcnt=itemnum(buf); if(ld.levelcnt>LEVEL_LIM) ld.levelcnt=LEVEL_LIM; |
||
1785 | for(i=0,pp=buf;i<ld.levelcnt;i++,pp=p2) { |
||
7673 | bpr | 1786 | if(*pp==0) goto syntax; |
1787 | p2=find_item_end(pp); if(*p2) *p2++=0; |
||
1788 | ld.levels[i]=evalue(pp); |
||
10 | reyssat | 1789 | } |
1790 | levelcurve(&ld); |
||
1791 | for(i=0, pp=p; i<ld.datacnt && pp<p+MAX_LINELEN-16; i++) { |
||
7673 | bpr | 1792 | float2str(ld.xdata[i],buf); |
1793 | if(pp-p+strlen(buf)<MAX_LINELEN-1) { |
||
11129 | georgesk | 1794 | if(pp>p) *pp++=';'; |
1795 | ovlstrcpy(pp,buf); pp+=strlen(pp); |
||
7673 | bpr | 1796 | } |
1797 | float2str(ld.ydata[i],buf); |
||
1798 | if(pp-p+strlen(buf)<MAX_LINELEN-1) { |
||
11125 | georgesk | 1799 | if(pp>p) *pp++=','; |
1800 | ovlstrcpy(pp,buf); pp+=strlen(pp); |
||
7673 | bpr | 1801 | } |
10 | reyssat | 1802 | } |
1803 | } |
||
1804 | |||
7673 | bpr | 1805 | /* internal routine with no security check */ |
10 | reyssat | 1806 | void _lookup(char *p, char *fname) |
1807 | { |
||
1808 | char buf1[MAX_LINELEN+1]; |
||
1809 | char *p1, *p2, *mbuf; |
||
1810 | |||
1811 | mbuf=readfile(fname,NULL,WORKFILE_LIMIT); |
||
1812 | if(mbuf==NULL) {abort: *p=0; return;} |
||
1813 | p1=find_word_start(p); strip_trailing_spaces(p1); |
||
1814 | snprintf(buf1,sizeof(buf1),"%s:",p1); substit(buf1); |
||
1815 | for(p1=strstr(mbuf,buf1); |
||
7673 | bpr | 1816 | p1!=NULL && p1>mbuf && *(p1-1)!='\n'; |
1817 | p1=strstr(p1+1,buf1)); |
||
10 | reyssat | 1818 | if(p1==NULL) {free(mbuf); goto abort;} |
1819 | p1+=strlen(buf1); |
||
1820 | for(p2=strchr(p1,'\n'); p2!=NULL; p2=strchr(p2+1,'\n')) { |
||
7673 | bpr | 1821 | if(p2>p1 && *(p2-1)=='\\') {*(p2-1)=' '; continue;} |
1822 | else break; |
||
10 | reyssat | 1823 | } |
1824 | if(p2==NULL) p2=p1+strlen(p1); else *p2=0; |
||
1825 | mystrncpy(p,p1,MAX_LINELEN); free(mbuf); |
||
1826 | } |
||
1827 | |||
7673 | bpr | 1828 | /* lookup a definition in a definition file */ |
10 | reyssat | 1829 | void calc_lookup(char *p) |
1830 | { |
||
1831 | char buf2[MAX_LINELEN+1], buf3[MAX_FNAME+1]; |
||
1832 | char *p2; |
||
7404 | bpr | 1833 | |
10 | reyssat | 1834 | p2=wordchr(p,"in"); if(p2==NULL) {abort: *p=0; return;} |
1835 | *p2=0;p2=find_word_start(p2+2); |
||
1836 | mystrncpy(buf2,p2,sizeof(buf2)); substit(buf2); |
||
1837 | *find_word_end(buf2)=0; |
||
1838 | if(strstr(buf2,parent_dir_string)!=NULL) { |
||
7673 | bpr | 1839 | force_setvar("wims_error_data",buf2); module_error("illegal_cmd"); |
10 | reyssat | 1840 | } |
1841 | if(strncmp(buf2,"bases/",strlen("bases/"))!=0) { |
||
7673 | bpr | 1842 | if(datafile_check(buf2)!=0 || find_module_file(buf2,buf3,0)!=0) |
1843 | goto abort; |
||
1844 | _lookup(p,buf3); |
||
10 | reyssat | 1845 | } |
7404 | bpr | 1846 | else _lookup(p,buf2); |
10 | reyssat | 1847 | } |
1848 | |||
7673 | bpr | 1849 | /* Hide name of a file. Only in module directory or in gifs/ */ |
10 | reyssat | 1850 | void calc_rename(char *p) |
1851 | { |
||
1852 | char buf1[MAX_LINELEN+1], buf2[MAX_LINELEN+1]; |
||
1853 | char *p1, *ext, *s; |
||
6790 | bpr | 1854 | int t; |
7404 | bpr | 1855 | |
10 | reyssat | 1856 | if(robot_access || strstr(p,"getfile")!=NULL) return; |
1857 | p1=find_word_start(p); *find_word_end(p1)=0; |
||
1858 | if(strncmp(p1,ref_name,strlen(ref_name))==0) p1+=strlen(ref_name); |
||
3718 | reyssat | 1859 | if(p1>p) ovlstrcpy(p,p1); |
10 | reyssat | 1860 | if(strstr(p,parent_dir_string)!=NULL || |
1861 | strncmp(p,"modules/adm/",strlen("modules/adm/"))==0) { |
||
7673 | bpr | 1862 | badfile: force_setvar("wims_error_data",p); module_error("illegal_cmd"); |
10 | reyssat | 1863 | } |
1864 | if(strncmp(p,module_dir,strlen(module_dir))!=0 && |
||
1865 | strncmp(p,"modules/data/",strlen("modules/data/"))!=0 && |
||
382 | bpr | 1866 | strncmp(p,"scripts/data/",strlen("scripts/data/"))!=0 && |
10 | reyssat | 1867 | strncmp(p,"gifs",strlen("gifs"))!=0) goto badfile; |
1868 | mkfname(buf1,"%s/getfile",session_prefix); mkdirs(buf1); |
||
1869 | mkfname(buf1,"%s/.rename",session_prefix); |
||
1870 | mystrncpy(buf2,p,sizeof(buf2)); _lookup(buf2,buf1); |
||
7673 | bpr | 1871 | if(buf2[0]!=0) { /* already */ |
1872 | mystrncpy(p,buf2,MAX_LINELEN); return; |
||
10 | reyssat | 1873 | } |
1874 | if(cwdbuf[0]==0) return; |
||
1875 | p1=p+strlen(p)-1; |
||
1876 | while(p1>p && isalnum(*p1)) p1--; |
||
1877 | if(p1>p && *p1=='.') ext=p1; else ext=""; |
||
1878 | rerand: t=random(); |
||
1879 | mkfname(buf1,"%s/%s",cwdbuf,p); |
||
1880 | mkfname(buf2,"%s/getfile/rename-%u%s",session_prefix,t,ext); |
||
1881 | if(ftest(buf2)>=0) goto rerand; |
||
6790 | bpr | 1882 | (void) symlink(buf1,buf2); |
10 | reyssat | 1883 | s=getvar("wims_session"); if(s==NULL) return; |
1884 | if(good_httpd) snprintf(buf1,sizeof(buf1), |
||
7673 | bpr | 1885 | "getfile/rename-%u%s?session=%s", t,ext,s); |
1082 | bpr | 1886 | else snprintf(buf1,sizeof(buf1),"%s?cmd=getfile&+session=%s&+special_parm=rename-%u%s", |
7673 | bpr | 1887 | ref_name, s, t,ext); |
10 | reyssat | 1888 | snprintf(buf2,sizeof(buf2),"%s:%s\n",p,buf1); |
1889 | accessfile(buf2,"a","%s/.rename",session_prefix); |
||
1890 | mystrncpy(p,buf1,MAX_LINELEN); |
||
1891 | } |
||
1892 | |||
7673 | bpr | 1893 | /* Pick up and translate imgrename(...) within a string */ |
10 | reyssat | 1894 | void calc_imgrename(char *p) |
1895 | { |
||
1896 | char buf[MAX_LINELEN+1], buf2[MAX_LINELEN+1]; |
||
1897 | char *p1, *p2, *p3, *p4; |
||
7404 | bpr | 1898 | |
10 | reyssat | 1899 | for(p1=varchr(p,"imgrename"); p1!=NULL; p1=varchr(p1,"imgrename")) { |
7673 | bpr | 1900 | p2=find_word_start(p1+strlen("imgrename")); |
1901 | if(*p2!='(') {p1=p2; continue;} |
||
1902 | p2++; p3=find_matching(p2,')'); |
||
1903 | if(*p3!=')') {p1=p2-1; continue;} |
||
1904 | p2=find_word_start(p2); p4=find_word_end(p2); |
||
1905 | memmove(buf,p2,p4-p2); buf[p4-p2]=0; |
||
1906 | calc_rename(buf); *p3=0; |
||
1907 | snprintf(buf2,sizeof(buf2),"<img src=\"%s\"%s alt=\"\" />",buf, p4); |
||
1908 | *p3=')'; p3++; |
||
1909 | string_modify(p,p1,p3,"%s",buf2); |
||
1910 | p1+=strlen(buf2); |
||
10 | reyssat | 1911 | } |
7404 | bpr | 1912 | |
10 | reyssat | 1913 | } |
1914 | |||
7673 | bpr | 1915 | /* internal use only */ |
10 | reyssat | 1916 | void calc_unhttp(char *p) |
1917 | { |
||
1918 | _http2env(tmplbuf,p); mystrncpy(p,tmplbuf,MAX_LINELEN); |
||
1919 | } |
||
1920 | |||
1921 | /* |
||
1922 | char *saltchar="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./"; |
||
1923 | */ |
||
1924 | |||
1925 | void calc_passcheck(char *p) |
||
1926 | { |
||
7404 | bpr | 1927 | |
10 | reyssat | 1928 | } |
1929 | |||
1930 | void calc_passcrypt(char *p) |
||
1931 | { |
||
1932 | #ifdef HAVE_CRYPT |
||
1933 | char saltstr[4]; |
||
1934 | char *p1, *p2, *pp, *s, buf[MAX_LINELEN+1]; |
||
1935 | saltstr[0]='N'; saltstr[1]='v'; saltstr[2]=0; buf[0]=0; pp=buf; |
||
1936 | for(p1=find_word_start(p);*p1;p1=find_word_start(p2)) { |
||
7673 | bpr | 1937 | p2=find_word_end(p1); if(*p2) *p2++=0; |
1938 | pp=pp+strlen(pp); |
||
1939 | if(pp>buf) s=" "; else s=""; |
||
1940 | if(*p1=='*') |
||
1941 | snprintf(pp,MAX_LINELEN-(pp-buf),"%s%s",s,p1); |
||
1942 | else |
||
1943 | snprintf(pp,MAX_LINELEN-(pp-buf),"%s*%s",s,crypt(p1,saltstr)); |
||
10 | reyssat | 1944 | } |
3718 | reyssat | 1945 | ovlstrcpy(p,buf); |
10 | reyssat | 1946 | #endif |
1947 | } |
||
1948 | |||
1949 | void exec_readproc(char *p); |
||
1950 | |||
7673 | bpr | 1951 | /* crypted mail interface */ |
10 | reyssat | 1952 | void calc_mailurl(char *p) |
1953 | { |
||
1954 | char *p0, buf[MAX_LINELEN+1]; |
||
7404 | bpr | 1955 | |
10 | reyssat | 1956 | if(robot_access) {*p=0; return;} |
1957 | snprintf(buf,sizeof(buf),"mailurl.proc %s",p); |
||
1958 | exec_readproc(buf); |
||
1959 | p0=getvar("mailurl_"); if(p0==NULL) p0=""; |
||
1960 | mystrncpy(p,p0,MAX_LINELEN); |
||
1961 | } |
||
1962 | |||
7673 | bpr | 1963 | /* get option word in a string */ |
10 | reyssat | 1964 | void calc_getopt(char *p) |
1965 | { |
||
1966 | char *p1, *p2, *p3, *p4; |
||
1967 | char buf1[MAX_LINELEN+1], buf2[MAX_LINELEN+1]; |
||
7404 | bpr | 1968 | |
10 | reyssat | 1969 | p1=wordchr(p,"in"); if(p1==NULL) module_error("syntax error"); |
1970 | *p1=0; p1=find_word_start(p1+3); |
||
1971 | mystrncpy(buf1,p,MAX_LINELEN); mystrncpy(buf2,p1,MAX_LINELEN); |
||
1972 | substitute(buf1); substitute(buf2); |
||
1973 | p1=find_word_start(buf1); *find_word_end(p1)=0; |
||
1974 | for(p2=buf2;*p2;p2++) { |
||
7673 | bpr | 1975 | if(myisspace(*p2)) *p2=' '; |
1976 | if(*p2=='=') *p2=' '; |
||
10 | reyssat | 1977 | } |
1978 | *p=0; |
||
1979 | p2=wordchr(buf2,p1); if(p2==NULL) return; |
||
1980 | for(p3=find_word_end(p2);myisspace(*p3);p3++) { |
||
7673 | bpr | 1981 | if(*p3==' ') { |
1982 | p3=find_word_start(p3); |
||
1983 | switch(*p3) { |
||
1984 | case '"': { |
||
1985 | p4=strchr(p3+1,'"'); |
||
1986 | goto tested; |
||
1987 | } |
||
1988 | case '(': { |
||
1989 | p4=find_matching(p3+1,')'); |
||
1990 | goto tested; |
||
1991 | } |
||
1992 | case '[': { |
||
1993 | p4=find_matching(p3+1,']'); |
||
1994 | goto tested; |
||
1995 | } |
||
1996 | case '{': { |
||
1997 | p4=find_matching(p3+1,'}'); |
||
1998 | tested: |
||
1999 | if(p4) { |
||
2000 | p3++; *p4=0; break; |
||
2001 | } |
||
2002 | else goto nomatch; |
||
2003 | } |
||
2004 | default: { |
||
2005 | nomatch: |
||
2006 | *find_word_end(p3)=0; |
||
2007 | } |
||
2008 | } |
||
2009 | mystrncpy(p,p3,MAX_LINELEN); |
||
2010 | return; |
||
2011 | } |
||
10 | reyssat | 2012 | } |
2013 | *find_word_end(p2)=0; |
||
2014 | mystrncpy(p,p2,MAX_LINELEN); |
||
2015 | } |
||
2016 | |||
7673 | bpr | 2017 | /* internal */ |
10 | reyssat | 2018 | void _embraced(char buf[], void (app)(char *p)) |
2019 | { |
||
2020 | char *p1, *p2, buf2[MAX_LINELEN+1]; |
||
2021 | for(p1=strchr(buf,'{'); p1; p1=strchr(p1,'{')) { |
||
7673 | bpr | 2022 | p2=find_matching(p1+1,'}'); |
2023 | if(p2==NULL) module_error("unmatched_parentheses"); |
||
2024 | *p2=0; mystrncpy(buf2,p1+1,sizeof(buf2)); app(buf2); |
||
2025 | string_modify(buf,p1,p2+1,buf2); |
||
10 | reyssat | 2026 | } |
2027 | } |
||
2028 | |||
7673 | bpr | 2029 | /* embraced operations */ |
10 | reyssat | 2030 | void calc_embraced(char *p) |
2031 | { |
||
2032 | char *p1, *p2, buf[MAX_LINELEN+1]; |
||
2033 | |||
2034 | p1=find_word_start(p); p2=find_word_end(p1); |
||
2035 | if(*p2==0) {*p=0; return;} |
||
2036 | *p2++=0; p2=find_word_start(p2); |
||
2037 | mystrncpy(buf,p2,sizeof(buf)); substit(buf); |
||
11125 | georgesk | 2038 | if(p1>p) ovlstrcpy(p,p1); |
2039 | substit(p); |
||
10 | reyssat | 2040 | if(strcmp(p,"randitem")==0) {_embraced(buf,calc_randitem); goto end;} |
2041 | if(strcmp(p,"extract")==0) { |
||
7673 | bpr | 2042 | p1=strchr(buf,'{'); if(p1!=NULL) { |
2043 | p2=find_matching(++p1,'}'); |
||
2044 | if(p2!=NULL) { |
||
2045 | memmove(buf,p1,p2-p1); buf[p2-p1]=0; |
||
2046 | } |
||
2047 | else buf[0]=0; |
||
2048 | } |
||
2049 | else buf[0]=0; |
||
2050 | goto end; |
||
10 | reyssat | 2051 | } |
2052 | if(strcmp(p,"delete")==0) { |
||
7673 | bpr | 2053 | for(p1=strchr(buf,'{'); p1; p1=strchr(p1,'{')) { |
2054 | p2=find_matching(p1+1,'}'); |
||
2055 | if(p2) ovlstrcpy(p1,p2+1); else p1++; |
||
2056 | } |
||
2057 | goto end; |
||
10 | reyssat | 2058 | } |
2059 | module_error("syntax_error"); |
||
7404 | bpr | 2060 | |
10 | reyssat | 2061 | end: |
2062 | mystrncpy(p,buf,MAX_LINELEN); |
||
2063 | } |
||
2064 | |||
2065 | void calc_rows2lines(char *p) |
||
7673 | bpr | 2066 | { rows2lines(p); } |
10 | reyssat | 2067 | |
2068 | void calc_lines2rows(char *p) |
||
7673 | bpr | 2069 | { lines2rows(p); } |
10 | reyssat | 2070 | |
7673 | bpr | 2071 | /* check whether datamodules exist */ |
10 | reyssat | 2072 | void calc_checkdata(char *p) |
2073 | { |
||
2074 | char *p1, *p2, buf[MAX_LINELEN+1], nbuf[MAX_FNAME+1]; |
||
2075 | struct stat st; |
||
7404 | bpr | 2076 | |
10 | reyssat | 2077 | memmove(p,"yes",4); |
2078 | p1=getvar("module_data"); |
||
2079 | if(p1==NULL || *p1==0) return; |
||
2080 | snprintf(buf,sizeof(buf),"%s",p1); |
||
2081 | for(p2=buf; *p2; p2++) if(*p2==',' || *p2==';') *p2=' '; |
||
2082 | if(strstr(buf,"..")!=NULL) { |
||
7673 | bpr | 2083 | snprintf(p,MAX_LINELEN,"badly_defined_data_module"); |
2084 | return; |
||
10 | reyssat | 2085 | } |
2086 | for(p1=find_word_start(buf); *p1; p1=find_word_start(p2)) { |
||
7673 | bpr | 2087 | p2=find_word_end(p1); if(*p2) *p2++=0; |
2088 | snprintf(nbuf,sizeof(nbuf),"%s/%s/INDEX",module_dir,p1); |
||
2089 | if(stat(nbuf,&st)<0) { |
||
2090 | snprintf(nbuf,sizeof(nbuf),"%s/%s/index",module_dir,p1); |
||
2091 | if(stat(nbuf,&st)<0) { |
||
2092 | snprintf(p,MAX_LINELEN,"%s",p1); |
||
2093 | return; |
||
2094 | } |
||
2095 | } |
||
10 | reyssat | 2096 | } |
2097 | } |
||
2098 | |||
7673 | bpr | 2099 | /* tag!=0 if we don't want automatic substit(). */ |
10 | reyssat | 2100 | MYFUNCTION calc_routine[]={ |
7673 | bpr | 2101 | {"TeXmath", 0, texmath}, |
2102 | {"add", 1, calc_sum}, |
||
2103 | {"append", 1, calc_append}, |
||
2104 | {"call", 0, calc_exec}, |
||
2105 | {"char", 1, calc_charof}, |
||
2106 | {"charcnt", 0, calc_lengthof}, |
||
2107 | {"charcount", 0, calc_lengthof}, |
||
2108 | {"charno", 0, calc_lengthof}, |
||
2109 | {"charnum", 0, calc_lengthof}, |
||
2110 | {"chars", 1, calc_charof}, |
||
2111 | {"checkdata", 0, calc_checkdata}, |
||
2112 | {"checkdatamodule",0, calc_checkdata}, |
||
2113 | {"checkhost", 0, calc_checkhost}, |
||
2114 | {"column", 1, calc_columnof}, |
||
2115 | {"columns", 1, calc_columnof}, |
||
2116 | {"daemon", 0, calc_daemon}, |
||
2117 | {"date", 0, calc_date}, |
||
2118 | {"deaccent", 0, deaccent}, |
||
2119 | {"debug", 0, calc_debug}, |
||
2120 | {"declosing", 0, calc_declosing}, |
||
2121 | {"definitionof", 1, calc_defof}, |
||
2122 | {"defof", 1, calc_defof}, |
||
2123 | {"detag", 0, calc_detag}, |
||
2124 | /* {"dictionary", 1, calc_dictionary}, */ |
||
2125 | {"dir", 0, calc_listfile}, |
||
2126 | {"embraced", 1, calc_embraced}, |
||
2127 | {"encyclo", 0, pedia}, |
||
2128 | {"encyclopedia", 0, pedia}, |
||
2129 | {"eval", 0, calc_evalue}, |
||
2130 | {"evalsubst", 1, calc_evalsubst}, |
||
2131 | {"evalsubstit", 1, calc_evalsubst}, |
||
2132 | {"evalsubstitute",1, calc_evalsubst}, |
||
2133 | {"evalue", 0, calc_evalue}, |
||
2134 | {"evaluesubst", 1, calc_evalsubst}, |
||
2135 | {"evaluesubstit", 1, calc_evalsubst}, |
||
2136 | {"evaluesubstitute",1, calc_evalsubst}, |
||
2137 | {"examdep", 0, calc_examdep}, |
||
2138 | {"examscore", 0, calc_examscore}, |
||
2139 | {"exec", 0, calc_exec}, |
||
2140 | {"execute", 0, calc_exec}, |
||
12047 | bpr | 2141 | {"fileexists", 0, calc_fileexists}, |
7673 | bpr | 2142 | {"filelist", 0, calc_listfile}, |
12047 | bpr | 2143 | {"filexists", 0, calc_fileexists}, |
7673 | bpr | 2144 | {"getdef", 1, calc_defof}, |
2145 | {"getopt", 1, calc_getopt}, |
||
2146 | {"getscore", 0, calc_getscore}, |
||
2147 | {"getscorebest", 0, calc_getscorebest}, |
||
2148 | {"getscorelast", 0, calc_getscorelast}, |
||
2149 | {"getscorelevel", 0, calc_getscorelevel}, |
||
2150 | {"getscoremean",0, calc_getscoremean}, |
||
2151 | {"getscorepercent",0, calc_getscorepercent}, |
||
2152 | {"getscorequality",0, calc_getscoremean}, |
||
2153 | {"getscoreremain",0, calc_getscoreremain}, |
||
2154 | {"getscorerequire",0, calc_getscorerequire}, |
||
2155 | {"getscorestatus",0, calc_getscorestatus}, |
||
2156 | {"getscoretry", 0, calc_getscoretry}, |
||
2157 | {"getscoreweight",0, calc_getscoreweight}, |
||
2158 | {"hex", 0, calc_hex}, |
||
2159 | {"htmlmath", 0, htmlmath}, |
||
2160 | {"httpquery", 0, tohttpquery}, |
||
2161 | {"imgrename", 0, calc_imgrename}, |
||
2162 | {"instexst", 1, calc_instexst}, |
||
2163 | {"instexstatic", 1, calc_instexst}, |
||
2164 | {"item", 1, calc_itemof}, |
||
2165 | {"itemcnt", 0, calc_itemnum}, |
||
2166 | {"itemcount", 0, calc_itemnum}, |
||
2167 | {"itemno", 0, calc_itemnum}, |
||
2168 | {"itemnum", 0, calc_itemnum}, |
||
2169 | {"items", 1, calc_itemof}, |
||
2170 | {"items2lines", 0, items2lines}, |
||
2171 | {"items2words", 0, items2words}, |
||
2172 | {"itemstolines", 0, items2lines}, |
||
2173 | {"itemstowords", 0, items2words}, |
||
2174 | {"lengthof", 0, calc_lengthof}, |
||
2175 | {"leveldata", 1, calc_leveldata}, |
||
2176 | {"levelpoints", 1, calc_leveldata}, |
||
2177 | {"line", 1, calc_lineof}, |
||
2178 | {"linecnt", 0, calc_linenum}, |
||
2179 | {"linecount", 0, calc_linenum}, |
||
2180 | {"lineno", 0, calc_linenum}, |
||
2181 | {"linenum", 0, calc_linenum}, |
||
2182 | {"lines", 1, calc_lineof}, |
||
2183 | {"lines2items", 0, lines2items}, |
||
2184 | {"lines2list", 0, lines2items}, |
||
2185 | {"lines2rows", 0, calc_lines2rows}, |
||
2186 | {"lines2words", 0, lines2words}, |
||
2187 | {"linestoitems", 0, lines2items}, |
||
2188 | {"linestolist", 0, lines2items}, |
||
2189 | {"linestowords", 0, lines2words}, |
||
2190 | {"list2lines", 0, items2lines}, |
||
2191 | {"list2words", 0, items2words}, |
||
2192 | {"listcomplement",1, calc_listcomplement}, |
||
2193 | {"listfile", 0, calc_listfile}, |
||
2194 | {"listfiles", 0, calc_listfile}, |
||
2195 | {"listintersect", 1, calc_listintersect}, |
||
2196 | {"listintersection",1, calc_listintersect}, |
||
2197 | {"listtolines", 0, items2lines}, |
||
2198 | {"listtowords", 0, items2words}, |
||
2199 | {"listunion", 1, calc_listunion}, |
||
2200 | {"listuniq", 0, calc_listuniq}, |
||
2201 | {"listunique", 0, calc_listuniq}, |
||
2202 | {"listvar", 0, mathvarlist}, |
||
2203 | {"lookup", 1, calc_lookup}, |
||
2204 | {"lower", 0, calc_tolower}, |
||
2205 | {"lowercase", 0, calc_tolower}, |
||
2206 | {"ls", 0, calc_listfile}, |
||
2207 | {"mailurl", 0, calc_mailurl}, |
||
2208 | {"makelist", 1, calc_makelist}, |
||
2209 | {"math2html", 0, htmlmath}, |
||
2210 | {"math2mathml", 0,mathmlmath}, |
||
2211 | {"math2tex", 0, texmath}, |
||
2212 | {"mathmlmath", 0, mathmlmath}, |
||
2213 | {"mathsubst", 1, calc_mathsubst}, |
||
2214 | {"mathsubstit", 1, calc_mathsubst}, |
||
2215 | {"mathsubstitute",1, calc_mathsubst}, |
||
2216 | {"mexec", 0, calc_mexec}, |
||
2217 | {"module", 0, calc_module}, |
||
2218 | {"multiply", 1, calc_product}, |
||
2219 | {"non_empty", 0, calc_nonempty}, |
||
2220 | {"nonempty", 0, calc_nonempty}, |
||
2221 | {"nospace", 0, nospace}, |
||
2222 | {"nosubst", 1, calc_subst}, |
||
2223 | {"nosubstit", 1, calc_subst}, |
||
2224 | {"nosubstitute", 1, calc_subst}, |
||
2225 | {"passcheck", 0, calc_passcheck}, |
||
2226 | {"passcrypt", 0, calc_passcrypt}, |
||
2227 | {"pedia", 0, pedia}, |
||
2228 | {"perl", 0, calc_perl}, |
||
2229 | {"position", 1, calc_pos}, |
||
2230 | {"positionof", 1, calc_pos}, |
||
2231 | {"positions", 1, calc_pos}, |
||
2232 | {"prod", 1, calc_product}, |
||
2233 | {"product", 1, calc_product}, |
||
2234 | {"randchar", 0, calc_randchar}, |
||
2235 | {"randdouble", 0, calc_randdouble}, |
||
2236 | {"randfile", 0, calc_randfile}, |
||
2237 | {"randfloat", 0, calc_randdouble}, |
||
2238 | {"randint", 0, calc_randint}, |
||
2239 | {"randitem", 0, calc_randitem}, |
||
2240 | {"randline", 0, calc_randline}, |
||
2241 | {"random", 0, calc_randdouble}, |
||
2242 | {"randperm", 0, calc_randperm}, |
||
2243 | {"randpermute", 0, calc_randperm}, |
||
2244 | {"randreal", 0, calc_randdouble}, |
||
2245 | {"randrecord", 0, calc_randfile}, |
||
2246 | {"randrow", 0, calc_randrow}, |
||
2247 | {"randword", 0, calc_randword}, |
||
2248 | {"rawmath", 0, rawmath}, |
||
2249 | {"rawmatrix", 0, rawmatrix}, |
||
2250 | {"reaccent", 0, reaccent}, |
||
2251 | {"record", 1, calc_recordof}, |
||
2252 | {"recordcnt", 0, calc_recordnum}, |
||
2253 | {"recordcount", 0, calc_recordnum}, |
||
2254 | {"recordno", 0, calc_recordnum}, |
||
2255 | {"recordnum", 0, calc_recordnum}, |
||
2256 | {"records", 1, calc_recordof}, |
||
2257 | {"recursion", 1, calc_recursion}, |
||
2258 | {"reinput", 0, calc_reinput}, |
||
2259 | {"rename", 0, calc_rename}, |
||
2260 | {"replace", 1, calc_replace}, |
||
2261 | {"rootof", 1, calc_solve}, |
||
2262 | {"row", 1, calc_rowof}, |
||
2263 | {"rowcnt", 0, calc_rownum}, |
||
2264 | {"rowcount", 0, calc_rownum}, |
||
2265 | {"rowno", 0, calc_rownum}, |
||
2266 | {"rownum", 0, calc_rownum}, |
||
2267 | {"rows", 1, calc_rowof}, |
||
2268 | {"rows2lines", 0, calc_rows2lines}, |
||
2269 | {"run", 0, calc_exec}, |
||
2270 | {"select", 1, calc_select}, |
||
2271 | {"sh", 0, calc_sh}, |
||
2272 | {"shuffle", 0, calc_randperm}, |
||
2273 | {"singlespace", 0, singlespace}, |
||
2274 | {"slashsubst", 0, slashsubst}, |
||
2275 | {"solve", 1, calc_solve}, |
||
2276 | {"sort", 1, calc_sort}, |
||
2277 | /* {"sql", 0, calc_sql}, */ |
||
2278 | {"staticinstex", 1, calc_instexst}, |
||
2279 | {"stinstex", 1, calc_instexst}, |
||
2280 | {"subst", 0, calc_subst}, |
||
2281 | {"substit", 0, calc_subst}, |
||
2282 | {"substitute", 0, calc_subst}, |
||
2283 | {"sum", 1, calc_sum}, |
||
2284 | {"system", 0, calc_sh}, |
||
2285 | {"texmath", 0, texmath}, |
||
2286 | {"text", 1, text}, |
||
2287 | {"tohex", 0, calc_hex}, |
||
2288 | {"tolower", 0, calc_tolower}, |
||
2289 | {"toupper", 0, calc_toupper}, |
||
2290 | {"translate", 1, calc_translate}, |
||
2291 | {"trim", 0, calc_trim}, |
||
2292 | {"unhttp", 0, calc_unhttp}, |
||
2293 | {"upper", 0, calc_toupper}, |
||
2294 | {"uppercase", 0, calc_toupper}, |
||
2295 | {"values", 1, calc_values}, |
||
2296 | {"varlist", 0, mathvarlist}, |
||
2297 | {"word", 1, calc_wordof}, |
||
2298 | {"wordcnt", 0, calc_wordnum}, |
||
2299 | {"wordcount", 0, calc_wordnum}, |
||
2300 | {"wordno", 0, calc_wordnum}, |
||
2301 | {"wordnum", 0, calc_wordnum}, |
||
2302 | {"words", 1, calc_wordof}, |
||
2303 | {"words2items", 0, words2items}, |
||
2304 | {"words2lines", 0, words2lines}, |
||
2305 | {"words2list", 0, words2items}, |
||
2306 | {"wordstoitems", 0, words2items}, |
||
2307 | {"wordstolines", 0, words2lines}, |
||
2308 | {"wordstolist", 0, words2items} |
||
10 | reyssat | 2309 | }; |
8185 | bpr | 2310 | int CALC_FN_NO=(sizeof(calc_routine)/sizeof(calc_routine[0])); |
10 | reyssat | 2311 |