Rev 11132 | Rev 15775 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 11132 | Rev 12247 | ||
---|---|---|---|
Line 22... | Line 22... | ||
22 | #include "oef2wims.h" |
22 | #include "oef2wims.h" |
23 | 23 | ||
24 | /* critical error situation */ |
24 | /* critical error situation */ |
25 | void oef_error(char *s) |
25 | void oef_error(char *s) |
26 | { |
26 | { |
27 |
|
27 | /* fputs(s,stderr); */ |
28 |
|
28 | if(badpar!=NULL) { |
29 |
|
29 | char *p; int i,t,v; |
30 |
|
30 | char buf[128]; |
31 |
|
31 | for(p=inpbuf,t=1;p<badpar;p++) if(*p=='\n') t++; |
32 |
|
32 | for(p=badpar-1;p>=inpbuf && *p!='\n'; p--); |
33 |
|
33 | p++; v=badpar-p+1; |
34 |
|
34 | snprintf(buf,sizeof(buf),"%s",p); |
35 |
|
35 | for(i=0,p=buf;i<3 && *p;p++) if(*p=='\n') i++; |
36 |
|
36 | *p=0; |
37 |
|
37 | printf("\nERROR %s '%c' at line %d col %d.\n", |
38 |
|
38 | s,*badpar,t,v); |
39 |
|
39 | for(i=1;i<v;i++) putchar(' '); |
40 |
|
40 | printf("!\n%s\n",buf); |
41 |
|
41 | } |
42 |
|
42 | else printf("\nERROR %s\n",s); |
43 |
|
43 | exit(1); |
44 | } |
44 | } |
45 | 45 | ||
46 | char *substit(char *p) |
46 | char *substit(char *p) |
47 | { |
47 | { |
48 |
|
48 | char *pp; |
49 |
|
49 | while((pp=strchr(p,'$'))!=NULL) *pp=' '; |
50 |
|
50 | return p; |
51 | } |
51 | } |
52 | 52 | ||
53 | /* replace newline by tab */ |
53 | /* replace newline by tab */ |
54 | void replace_newline(char *p) |
54 | void replace_newline(char *p) |
55 | { |
55 | { |
56 |
|
56 | for(;*p;p++) { |
57 |
|
57 | if(*p==' ') *p=' '; |
58 |
|
58 | if(*p=='\n') *p=' '; |
59 |
|
59 | } |
60 | } |
60 | } |
61 | 61 | ||
62 | /* variable substitution. buffer p must have MAX_LINELEN */ |
62 | /* variable substitution. buffer p must have MAX_LINELEN */ |
63 | void subst(char *p) |
63 | void subst(char *p) |
64 | { |
64 | { |
65 |
|
65 | char *pp, *pe, nbuf[MAX_NAMELEN]; |
66 |
|
66 | int i; |
67 | 67 | ||
68 |
|
68 | for(pp=p;pp-p<MAX_LINELEN && *pp; pp++) { |
69 |
|
69 | if(*pp=='$') { |
70 |
|
70 | string_modify(p,pp,pp+1,"$"); |
71 |
|
71 | pp+=3; |
72 |
|
72 | continue; |
73 |
|
73 | } |
74 |
|
74 | if(*pp=='!' && isalnum(*(pp+1))) { |
75 |
|
75 | string_modify(p,pp,pp+1,"!"); |
76 |
|
76 | pp+=3; continue; |
77 |
|
77 | } |
78 |
|
78 | if(*pp!='\\') continue; |
79 |
|
79 | if(*(pp+1)=='\\') { |
80 |
|
80 | pp++; continue; |
81 |
|
81 | } |
82 |
|
82 | if(!isalpha(*(pp+1))) continue; |
83 |
|
83 | for(pe=pp+1;isalnum(*pe) || *pe=='_'; pe++); |
84 |
|
84 | if(pe-pp>=MAX_NAMELEN) continue; |
85 |
|
85 | memmove(nbuf,pp+1,pe-pp-1);nbuf[pe-pp-1]=0; |
86 |
|
86 | for(i=varcnt-1;i>=1 && strcmp(nbuf,param[i].name)!=0;i--); |
87 |
|
87 | if(i>=1) { |
88 |
|
88 | if(deftag) param[i].save=1; |
89 |
|
89 | if(*pe=='[') { |
90 |
|
90 | char *pt, tbuf[MAX_LINELEN+1], vbuf[MAX_LINELEN+1]; |
91 |
|
91 | int l; |
92 |
|
92 | pt=find_matching(pe+1,']'); if(pt!=NULL && pt-pe<MAX_LINELEN) { |
93 |
|
93 | pe++; memmove(tbuf,pe,pt-pe); tbuf[pt-pe]=0; pe=pt+1; |
94 |
|
94 | subst(tbuf); |
95 |
|
95 | for(pt=strchr(tbuf,'\\');pt;pt=strchr(pt,'\\')) |
96 |
|
96 | string_modify(tbuf,pt,pt+1,"$m_"); |
97 |
|
97 | snprintf(vbuf,sizeof(vbuf),"$(val%d[%s])",i,tbuf); |
98 |
|
98 | l=strlen(vbuf); |
99 |
|
99 | string_modify(p,pp,pe,"%s",vbuf); |
100 |
|
100 | pp+=l-1;continue; |
101 |
|
101 | } |
102 |
|
102 | } |
103 |
|
103 | string_modify(p,pp,pe,"$val%d",i); |
104 |
|
104 | } |
105 |
|
105 | else if(wordchr(mdef,nbuf)!=NULL) string_modify(p,pp,pp+1,"$m_"); |
106 |
|
106 | } |
107 | } |
107 | } |
108 | 108 | ||
109 | void repsubst(char *p) |
109 | void repsubst(char *p) |
110 | { |
110 | { |
111 |
|
111 | char *p1; |
112 |
|
112 | for(p1=strstr(p,"\\reply"); p1!=NULL; p1=strstr(p1+1,"\\reply")) { |
113 |
|
113 | if(p1>p && *(p1-1)=='\\') continue; |
114 |
|
114 | string_modify(p,p1,p1+strlen("\\reply"),"$m_reply"); |
115 |
|
115 | } |
116 |
|
116 | for(p1=strstr(p,"\\result"); p1!=NULL; p1=strstr(p1+1,"\\result")) { |
117 |
|
117 | if(p1>p && *(p1-1)=='\\') continue; |
118 |
|
118 | string_modify(p,p1,p1+strlen("\\result"),"$m_result"); |
119 |
|
119 | } |
120 |
|
120 | for(p1=strstr(p,"\\choice"); p1!=NULL; p1=strstr(p1+1,"\\choice")) { |
121 |
|
121 | if(p1>p && *(p1-1)=='\\') continue; |
122 |
|
122 | string_modify(p,p1,p1+strlen("\\choice"),"$m_choice"); |
123 |
|
123 | } |
124 |
|
124 | for(p1=strstr(p,"\\step"); p1!=NULL; p1=strstr(p1+1,"\\step")) { |
125 |
|
125 | if(p1>p && *(p1-1)=='\\') continue; |
126 |
|
126 | string_modify(p,p1,p1+strlen("\\step"),"$m_step"); |
127 |
|
127 | } |
128 |
|
128 | for(p1=strstr(p,"\\sc_reply"); p1!=NULL; p1=strstr(p1+1,"\\sc_reply")) { |
129 |
|
129 | if(p1>p && *(p1-1)=='\\') continue; |
130 |
|
130 | string_modify(p,p1,p1+strlen("\\sc_reply"),"$m_sc_reply"); |
131 |
|
131 | } |
132 |
|
132 | for(p1=strstr(p,"\\sc_choice"); p1!=NULL; p1=strstr(p1+1,"\\sc_choice")) { |
133 |
|
133 | if(p1>p && *(p1-1)=='\\') continue; |
134 |
|
134 | string_modify(p,p1,p1+strlen("\\sc_choice"),"$m_sc_choice"); |
135 |
|
135 | } |
136 |
|
136 | for(p1=strstr(p,"\\reply_"); p1!=NULL; p1=strstr(p1+1,"\\reply_")) { |
137 |
|
137 | if(p1>p && *(p1-1)=='\\') continue; |
138 |
|
138 | string_modify(p,p1,p1+strlen("\\reply_"),"$m_reply_"); |
139 |
|
139 | } |
140 | } |
140 | } |
141 | 141 | ||
142 | 142 | ||
143 | /* find matching parenthesis. |
143 | /* find matching parenthesis. |
144 | * The entrance point should be after the opening |
144 | * The entrance point should be after the opening |
145 | * parenthesis. |
145 | * parenthesis. |
146 | * Returns NULL if unmatched. |
146 | * Returns NULL if unmatched. |
147 | */ |
147 | */ |
148 | char *find_matching2(char *p, char c) |
148 | char *find_matching2(char *p, char c) |
149 | { |
149 | { |
150 |
|
150 | char *pp, *pp2, *ppar,*pbrk, *pbrc; |
151 |
|
151 | int parenth, brak, brace; |
152 |
|
152 | if(c=='|') { |
153 |
|
153 | for(pp=p;*pp!=0;pp++) { |
154 |
|
154 | pp2=pp; |
155 |
|
155 | switch(*pp) { |
156 |
|
156 | case '|': return pp; |
157 |
|
157 | case '(': { |
158 |
|
158 | pp=find_matching(pp+1,')'); |
159 |
|
159 | if(pp==NULL) {if(badpar==NULL) badpar=pp2; return NULL;} |
160 |
|
160 | break; |
161 |
|
161 | } |
162 |
|
162 | case '[': { |
163 |
|
163 | pp=find_matching(pp+1,']'); |
164 |
|
164 | if(pp==NULL) {if(badpar==NULL) badpar=pp2; return NULL;} |
165 |
|
165 | break; |
166 |
|
166 | } |
167 |
|
167 | case '{': { |
168 |
|
168 | pp=find_matching(pp+1,'}'); |
169 |
|
169 | if(pp==NULL) {if(badpar==NULL) badpar=pp2; return NULL;} |
170 |
|
170 | break; |
171 |
|
171 | } |
172 |
|
172 | case ')': |
173 |
|
173 | case ']': |
174 |
|
174 | case '}': badpar=pp; return NULL; |
175 | 175 | ||
176 |
|
176 | default: break; |
177 |
|
177 | } |
178 |
|
178 | } |
179 |
|
179 | return NULL; |
180 |
|
180 | } |
181 |
|
181 | parenth=brak=brace=0; ppar=pbrc=pbrk=NULL; |
182 |
|
182 | for(pp=p; *pp!=0; pp++) { |
183 |
|
183 | switch(*pp) { |
184 |
|
184 | case '[': if(brak==0) pbrk=pp; brak++; break; |
185 |
|
185 | case ']': brak--; break; |
186 |
|
186 | case '(': if(parenth==0) ppar=pp; parenth++; break; |
187 |
|
187 | case ')': parenth--; break; |
188 |
|
188 | case '{': if(brace==0) pbrc=pp; brace++; break; |
189 |
|
189 | case '}': brace--; break; |
190 |
|
190 | default: continue; |
191 |
|
191 | } |
192 |
|
192 | if(parenth<0 || brak<0 || brace<0) { |
193 |
|
193 | if(badpar==NULL) { |
194 |
|
194 | if(parenth>0) badpar=ppar; |
195 |
|
195 | if(brace>0) badpar=pbrc; |
196 |
|
196 | if(brak>0) badpar=pbrk; |
197 |
|
197 | } |
198 |
|
198 | if(parenth>0 || brak>0 || brace>0) return NULL; |
199 |
|
199 | if(*pp!=c) { |
200 |
|
200 | if(badpar==NULL) badpar=pp; |
201 |
|
201 | return NULL; |
202 |
|
202 | } |
203 |
|
203 | else break; |
204 |
|
204 | } |
205 |
|
205 | } |
206 |
|
206 | if(*pp!=c) return NULL; |
207 |
|
207 | return pp; |
208 | } |
208 | } |
209 | 209 | ||
210 | /* Check whether parentheses are balanced in a given string. |
210 | /* Check whether parentheses are balanced in a given string. |
211 | * Returns 0 if OK. |
211 | * Returns 0 if OK. |
212 | * style=0: simple check. style<>0: strong check. |
212 | * style=0: simple check. style<>0: strong check. |
213 | */ |
213 | */ |
214 | int checkparentheses(char *p, int style) |
214 | int checkparentheses(char *p, int style) |
215 | { |
215 | { |
216 |
|
216 | int i,j,k; |
217 |
|
217 | j=strlen(p); |
218 |
|
218 | if(j>=MAX_FILELEN) return 65535; |
219 |
|
219 | if(style!=0) { |
220 |
|
220 | char *pp, *pe, c; |
221 |
|
221 | for(pp=p;pp<p+j;pp++) { |
222 |
|
222 | switch (*pp) { |
223 |
|
223 | case ')': |
224 |
|
224 | case ']': |
225 |
|
225 | case '}': {badpar=pp; return -1;} |
226 |
|
226 | case '(': c=')'; goto find; |
227 |
|
227 | case '[': c=']'; goto find; |
228 |
|
228 | case '{': c='}'; |
229 |
|
229 | find: { |
230 |
|
230 | pe=find_matching2(pp+1,c); |
231 |
|
231 | if(pe==NULL) { |
232 |
|
232 | if(badpar==NULL) badpar=pp; |
233 |
|
233 | return 1; |
234 | } |
- | |
235 | else pp=pe; |
- | |
236 | } |
234 | } |
237 |
|
235 | else pp=pe; |
238 |
|
236 | } |
- | 237 | default: break; |
|
239 | } |
238 | } |
240 | return 0; |
- | |
241 | } |
239 | } |
- | 240 | return 0; |
|
- | 241 | } |
|
242 |
|
242 | for(i=k=0;i<j && k>=0;i++) { |
243 |
|
243 | if(*(p+i)=='(') k++; |
244 | if(*(p+i)==')') k--; |
244 | if(*(p+i)==')') k--; |
245 |
|
245 | } |
246 |
|
246 | return k; |
247 | } |
247 | } |
248 | - |