Rev 3813 | Rev 8195 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3813 | Rev 8161 | ||
---|---|---|---|
Line 12... | Line 12... | ||
12 | * |
12 | * |
13 | * You should have received a copy of the GNU General Public License |
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 |
14 | * along with this program; if not, write to the Free Software |
15 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
15 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
16 | */ |
16 | */ |
- | 17 | #include "symtext.h" |
|
17 | 18 | ||
18 | char cpbuf[MAX_LINELEN+1]; |
19 | char cpbuf[MAX_LINELEN+1]; |
19 | char *cpnext; |
20 | char *cpnext; |
20 | int noaddw=0; |
21 | int noaddw=0; |
21 | 22 | ||
Line 33... | Line 34... | ||
33 | listtype *list; |
34 | listtype *list; |
34 | } clist; |
35 | } clist; |
35 | 36 | ||
36 | void cp_oneblock(char *p, struct block *blk, int next); |
37 | void cp_oneblock(char *p, struct block *blk, int next); |
37 | 38 | ||
38 |
|
39 | /* debugger: show the detail of blocks */ |
39 | void showblocks(void) |
40 | void showblocks(void) |
40 | { |
41 | { |
41 | int i, j, k; |
42 | int i, j, k; |
42 | struct block *blk; |
43 | struct block *blk; |
43 | if(!debug) return; |
44 | if(!debug) return; |
44 | for(i=0;i<nextblock;i++) { |
45 | for(i=0;i<nextblock;i++) { |
45 |
|
46 | blk=blockbuf+i; |
46 |
|
47 | fprintf(stderr,"Block %2d: next=%2d. ",i,blk->nextblock); |
47 |
|
48 | if(blk->fn==mt_string) { |
48 |
|
49 | fprintf(stderr,"String %s.\n",blk->string); |
49 |
|
50 | continue; |
50 |
|
51 | } |
51 |
|
52 | if(blk->fn==mt_permpick) { |
52 |
|
53 | fprintf(stderr,"Permpick %d items %d lists starting %d\n", |
53 |
|
54 | blk->len, blk->lcnt, blk->sublock); |
54 |
|
55 | for(j=0;j<blk->lcnt;j++) { |
55 |
|
56 | fprintf(stderr," list %d: ", j); |
56 |
|
57 | for(k=0;k<blk->listlen[j];k++) |
57 |
|
58 | fprintf(stderr,"%d ",blk->lists[j][k]); |
58 |
|
59 | fprintf(stderr,"\n"); |
59 |
|
60 | } |
60 |
|
61 | continue; |
61 |
|
62 | } |
62 |
|
63 | if(blk->fn==mt_m) { |
63 |
|
64 | fprintf(stderr,"Macro starting %d ending %d\n", blk->sublock, |
64 |
|
65 | blockbuf[blk->sublock].mend); |
65 |
|
66 | continue; |
66 |
|
67 | } |
67 |
|
68 | if(blk->fn==mt_neg) { |
68 |
|
69 | fprintf(stderr,"Neg starting %d\n", blk->sublock); |
69 |
|
70 | continue; |
70 |
|
71 | } |
71 |
|
72 | if(blk->fn==mt_dic) { |
72 |
|
73 | fprintf(stderr,"Dic %s.\n", blk->string); |
73 |
|
74 | continue; |
74 |
|
75 | } |
75 |
|
76 | if(blk->fn==mt_w) { |
76 |
|
77 | fprintf(stderr,"Word list.\n"); |
77 |
|
78 | continue; |
78 |
|
79 | } |
79 |
|
80 | if(blk->fn==mt_wild) { |
80 |
|
81 | fprintf(stderr,"Wild min=%d, max=%d.\n", blk->lstart, blk->len+blk->lstart); |
81 |
|
82 | continue; |
82 |
|
83 | } |
83 |
|
84 | if(blk->fn==mt_out) { |
84 |
|
85 | fprintf(stderr,"Output for \"%s\", sub=%d.\n", blk->string,blk->sublock); |
85 |
|
86 | continue; |
86 |
|
87 | } |
87 |
|
88 | fprintf(stderr,"Unknown type!\n"); |
88 | } |
89 | } |
89 | 90 | ||
90 | } |
91 | } |
91 | 92 | ||
92 |
|
93 | /* remove punctuations */ |
93 | void depunct(char *p,char *str) |
94 | void depunct(char *p,char *str) |
94 | { |
95 | { |
95 | char *pp; |
96 | char *pp; |
96 | for(pp=p; *pp; pp++) { |
97 | for(pp=p; *pp; pp++) { |
97 |
|
98 | if(strchr(str,*pp)==NULL) continue; |
98 |
|
99 | if(*pp=='.' && pp>p && isdigit(pp[-1]) && isdigit(pp[1])) continue; |
99 |
|
100 | *pp=' '; |
100 | } |
101 | } |
101 | } |
102 | } |
102 | 103 | ||
103 |
|
104 | /* p must have MAX_LINELEN */ |
104 | void isolate_punct(char *p) |
105 | void isolate_punct(char *p) |
105 | { |
106 | { |
106 | char buf[MAX_LINELEN+1]; |
107 | char buf[MAX_LINELEN+1]; |
107 | char *p1, *p2; |
108 | char *p1, *p2; |
108 | for(p1=p, p2=buf; *p1 && p2<buf+MAX_LINELEN; p1++) { |
109 | for(p1=p, p2=buf; *p1 && p2<buf+MAX_LINELEN; p1++) { |
109 |
|
110 | if(myisalnum(*p1) || (*p1&128) || *p1==' ' || *p1=='_') { |
110 |
|
111 | *p2++=*p1; continue; |
111 |
|
112 | } |
112 |
|
113 | if((*p1=='.' || *p1==',') && p1>p && isdigit(p1[-1]) && isdigit(p1[1])) { |
113 |
|
114 | *p2++=*p1; continue; |
114 |
|
115 | } |
115 |
|
116 | if(p2>buf && !myisspace(p2[-1])) *p2++=' '; |
116 |
|
117 | *p2++=*p1; |
117 |
|
118 | if(p1[1] && !myisspace(p1[1])) *p2++=' '; |
118 | } |
119 | } |
119 | if(p2>=buf+MAX_LINELEN) error("string_too_long"); |
120 | if(p2>=buf+MAX_LINELEN) error("string_too_long"); |
120 | *p2=0; |
121 | *p2=0; |
121 | snprintf(p,MAX_LINELEN,"%s",buf); |
122 | snprintf(p,MAX_LINELEN,"%s",buf); |
122 | } |
123 | } |
123 | 124 | ||
124 | void alphaonly(char *p) |
125 | void alphaonly(char *p) |
125 | { |
126 | { |
126 | char *pp; |
127 | char *pp; |
127 | for(pp=p; *pp; pp++) if(!myisalpha(*pp)) *pp=' '; |
128 | for(pp=p; *pp; pp++) if(!myisalpha(*pp)) *pp=' '; |
128 | } |
129 | } |
129 | 130 | ||
130 | void alnumonly(char *p) |
131 | void alnumonly(char *p) |
131 | { |
132 | { |
132 | char *pp; |
133 | char *pp; |
133 | for(pp=p; *pp; pp++) if(!myisalnum(*pp)) *pp=' '; |
134 | for(pp=p; *pp; pp++) if(!myisalnum(*pp)) *pp=' '; |
134 | } |
135 | } |
135 | 136 | ||
136 |
|
137 | /* buffer must have MAX_LINELEN */ |
137 | void strfold(char *p) |
138 | void strfold(char *p) |
138 | { |
139 | { |
139 | char *pp; |
140 | char *pp; |
140 | singlespace(p); |
141 | singlespace(p); |
141 | if(noaddw&2) goto fend; |
142 | if(noaddw&2) goto fend; |
Line 150... | Line 151... | ||
150 | if(options&op_noparenth) depunct(p,char_parenth); |
151 | if(options&op_noparenth) depunct(p,char_parenth); |
151 | if(options&op_nocs) depunct(p,char_cs); |
152 | if(options&op_nocs) depunct(p,char_cs); |
152 | if(options&op_noquote) depunct(p,char_quote); |
153 | if(options&op_noquote) depunct(p,char_quote); |
153 | if(suffixcnt>0) suffix_translate(p); |
154 | if(suffixcnt>0) suffix_translate(p); |
154 | _translate(p,transdic); |
155 | _translate(p,transdic); |
155 | 156 | ||
156 | fend: |
157 | fend: |
157 | singlespace(p);strip_trailing_spaces(p); |
158 | singlespace(p);strip_trailing_spaces(p); |
158 | if(myisspace(*p)) ovlstrcpy(p,find_word_start(p)); |
159 | if(myisspace(*p)) ovlstrcpy(p,find_word_start(p)); |
159 | } |
160 | } |
160 | 161 | ||
161 |
|
162 | /* at entry p must point to an atom start! */ |
162 | char *find_atom_end(char *p) |
163 | char *find_atom_end(char *p) |
163 | { |
164 | { |
164 | char *pp; |
165 | char *pp; |
165 | if(*p=='[') { |
166 | if(*p=='[') { |
166 |
|
167 | pp=find_matching(p+1,']'); |
167 |
|
168 | if(pp!=NULL) return pp+1; |
168 |
|
169 | else error("unmatched_parentheses %.20s",p); |
169 | } |
170 | } |
170 | return find_word_end(p); |
171 | return find_word_end(p); |
171 | } |
172 | } |
172 | 173 | ||
173 | #define find_atom_start(x) find_word_start(x) |
174 | #define find_atom_start(x) find_word_start(x) |
174 | #define next_atom(x) find_atom_start(find_atom_end(x)) |
175 | #define next_atom(x) find_atom_start(find_atom_end(x)) |
175 | 176 | ||
176 |
|
177 | /* p must have MAX_LINELEN */ |
177 | void macro_trans(char *p) |
178 | void macro_trans(char *p) |
178 | { |
179 | { |
179 | char *atoms[MAX_BLOCKS], *atom2[MAX_BLOCKS]; |
180 | char *atoms[MAX_BLOCKS], *atom2[MAX_BLOCKS]; |
180 | char tbuf[MAX_LINELEN+1], ttbuf[MAX_LINELEN+1], vbuf[8]; |
181 | char tbuf[MAX_LINELEN+1], ttbuf[MAX_LINELEN+1], vbuf[8]; |
181 | char *pt, *pp, *pe, *p1, *p2, *p3; |
182 | char *pt, *pp, *pe, *p1, *p2, *p3; |
182 | char *pt1, *pt2; |
183 | char *pt1, *pt2; |
183 | int i,k,m,n,repcnt,start,min; |
184 | int i,k,m,n,repcnt,start,min; |
184 | 185 | ||
185 | if(dic[macrodic].len<=0) return; |
186 | if(dic[macrodic].len<=0) return; |
186 | repcnt=start=0; pt=p; |
187 | repcnt=start=0; pt=p; |
187 | recalc: |
188 | recalc: |
188 | repcnt++; |
189 | repcnt++; |
189 | if(repcnt>=MAX_BLOCKS) error("macro_level_overflow %.20s",p); |
190 | if(repcnt>=MAX_BLOCKS) error("macro_level_overflow %.20s",p); |
190 | for(i=start, pp=find_atom_start(pt); i<MAX_BLOCKS && *pp; pp=next_atom(pp), i++) |
191 | for(i=start, pp=find_atom_start(pt); i<MAX_BLOCKS && *pp; pp=next_atom(pp), i++) |
191 | atoms[i]=pp; |
192 | atoms[i]=pp; |
192 | if(i>=MAX_BLOCKS-1) error("block_overflow %.20s",p); |
193 | if(i>=MAX_BLOCKS-1) error("block_overflow %.20s",p); |
193 | atoms[i]=pp+strlen(pp); |
194 | atoms[i]=pp+strlen(pp); |
194 | for(k=0;k<i;k++) { |
195 | for(k=0;k<i;k++) { |
195 |
|
196 | pp=atoms[k]; switch(*pp) { |
196 |
|
197 | case '[': { |
197 |
|
198 | pe=find_atom_end(pp); pp++; |
198 |
|
199 | if(pe[-1]!=']') break; |
199 |
|
200 | if(myislower(*pp)) { |
200 |
|
201 | for(p1=pp;myisalnum(*p1) || *p1=='_'; p1++); |
201 |
|
202 | if(*p1!=':') break; |
202 |
|
203 | *p1++=0; pe[-1]=0; |
203 |
|
204 | for(m=0,p2=p1;*p2;m++,p2=p3) { |
204 |
|
205 | p3=find_item_end(p2); if(*p3) *p3++=0; |
205 |
|
206 | atom2[m]=p2; |
206 |
|
207 | } |
207 |
|
208 | if(m==0) m=1; |
208 |
|
209 | snprintf(tbuf,sizeof(tbuf),"%s",pp); |
209 |
|
210 | _translate(tbuf,macrodic); |
210 |
|
211 | if(tbuf[0]==0) error("bad_macro %.50s",pp); |
211 |
|
212 | for(p1=strchr(tbuf,'@'); p1; p1=strchr(p1,'@')) { |
212 |
|
213 | for(p2=p1+1;isdigit(*p2) || *p2=='-';p2++); |
213 |
|
214 | if(p2==p1+1 || p2>p1+6) error("syntax_error %.20s",p1); |
214 |
|
215 | memmove(vbuf,p1,p2-p1); vbuf[p2-p1]=0; |
215 |
|
216 | n=atoi(vbuf+1); |
216 |
|
217 | if(n<=0 || n>m) error("wrong_parmcnt macro %.50s",pp); |
217 |
|
218 | string_modify(tbuf,p1,p2,atom2[n-1]); |
218 |
|
219 | } |
219 |
|
220 | n=strlen(tbuf); if(n<MAX_LINELEN) { |
220 |
|
221 | tbuf[n++]=' '; tbuf[n]=0; |
221 |
|
222 | } |
222 |
|
223 | string_modify(p,pp-1,pe,tbuf); pt=pp-1; start=k; |
223 |
|
224 | goto recalc; |
224 |
|
225 | } |
225 |
|
226 | break; |
226 |
|
227 | } |
227 |
|
228 | case '_': { |
228 |
|
229 | pe=find_word_end(pp); |
229 |
|
230 | if(pe-pp>MAX_NAMELEN) error("name_too_long %.20s",pp); |
230 |
|
231 | memmove(tbuf,pp,pe-pp); tbuf[pe-pp]=0; |
231 |
|
232 | _translate(tbuf,macrodic); |
232 |
|
233 | if(tbuf[0]==0) break; |
233 |
|
234 | pt1=pp; pt2=find_atom_end(pt1); min=k; |
234 |
|
235 | for(p1=strchr(tbuf,'@'); p1; p1=strchr(p1,'@')) { |
235 |
|
236 | for(p2=p1+1;isdigit(*p2) || *p2=='-';p2++); |
236 |
|
237 | if(p2==p1+1 || p2>p1+6) error("syntax_error %.20s",p1); |
237 |
|
238 | memmove(vbuf,p1,p2-p1); vbuf[p2-p1]=0; |
238 |
|
239 | n=atoi(vbuf+1); |
239 |
|
240 | if(n<-4 || n==0 || n>4) error("bad_macro %.20s",atoms[k]); |
240 |
|
241 | n+=k; |
241 |
|
242 | if(n<0 || n>=i) error("bad_macro_position %.20s",atoms[k]); |
242 |
|
243 | p3=find_atom_end(atoms[n]); |
243 |
|
244 | if(p3>pt2) pt2=p3; |
244 |
|
245 | if(atoms[n]<pt1) {min=n;pt1=atoms[n];} |
245 |
|
246 | memmove(ttbuf,atoms[n],p3-atoms[n]); ttbuf[p3-atoms[n]]=' '; |
246 |
|
247 | ttbuf[p3-atoms[n]+1]=0; |
247 |
|
248 | string_modify(tbuf,p1,p2,ttbuf); |
248 |
|
249 | } |
249 |
|
250 | string_modify(p,pt1,pt2,tbuf); pt=pt1; start=min; |
250 |
|
251 | goto recalc; |
251 |
|
252 | } |
252 |
|
253 | default: break; |
253 |
|
254 | } |
254 | } |
255 | } |
255 | } |
256 | } |
256 | 257 | ||
257 | char *add2cp(char *p) |
258 | char *add2cp(char *p) |
258 | { |
259 | { |
Line 260... | Line 261... | ||
260 | int l; |
261 | int l; |
261 | snprintf(buf,sizeof(buf),"%s",p); strfold(buf); l=strlen(buf); |
262 | snprintf(buf,sizeof(buf),"%s",p); strfold(buf); l=strlen(buf); |
262 | if((cpnext-cpbuf)+l>=MAX_LINELEN) error("string_too_long"); |
263 | if((cpnext-cpbuf)+l>=MAX_LINELEN) error("string_too_long"); |
263 | pp=cpnext; memmove(pp,buf,l+1); cpnext+=l+1; |
264 | pp=cpnext; memmove(pp,buf,l+1); cpnext+=l+1; |
264 | if(!noaddw) for(p1=find_word_start(buf); *p1; p1=find_word_start(p2)) { |
265 | if(!noaddw) for(p1=find_word_start(buf); *p1; p1=find_word_start(p2)) { |
265 |
|
266 | p2=find_word_end(p1); l=p2-p1; |
266 |
|
267 | if(*p2) *p2++=0; |
267 |
|
268 | if(wordchr(wbuf,p1)!=NULL) continue; |
268 |
|
269 | if(wptr-wbuf>=sizeof(wbuf)-l-2) continue; |
269 |
|
270 | if(wptr>wbuf) *wptr++=' '; |
270 |
|
271 | memmove(wptr,p1,l); wptr+=l; *wptr=0; |
271 | } |
272 | } |
272 | return pp; |
273 | return pp; |
273 | } |
274 | } |
274 | 275 | ||
275 | void cp_string(char *p, struct block *blk, int next) |
276 | void cp_string(char *p, struct block *blk, int next) |
Line 279... | Line 280... | ||
279 | blk->len=strlen(blk->string); |
280 | blk->len=strlen(blk->string); |
280 | blk->nextblock=next; |
281 | blk->nextblock=next; |
281 | if(blk==blockbuf+nextblock) nextblock++; |
282 | if(blk==blockbuf+nextblock) nextblock++; |
282 | } |
283 | } |
283 | 284 | ||
284 |
|
285 | /* p must have MAX_LINELEN */ |
285 | void cp_cutline(char *p, struct block *blk, int next) |
286 | void cp_cutline(char *p, struct block *blk, int next) |
286 | { |
287 | { |
287 | char *p1, *p2, *p3; |
288 | char *p1, *p2, *p3; |
288 | char buf[MAX_LINELEN+1]; |
289 | char buf[MAX_LINELEN+1]; |
289 | int l, ll, n, idx, start, end; |
290 | int l, ll, n, idx, start, end; |
290 | struct block *b; |
291 | struct block *b; |
291 | 292 | ||
292 | if(debug>=3) fprintf(stderr,"Cutline %d/%d for %.15s.\n", |
293 | if(debug>=3) fprintf(stderr,"Cutline %d/%d for %.15s.\n", |
293 |
|
294 | (int)(blk-blockbuf), nextblock, p); |
294 | for(p1=strstr(p,"[|]"); p1; p1=strstr(p1,"[|]")) memmove(p1," | ",3); |
295 | for(p1=strstr(p,"[|]"); p1; p1=strstr(p1,"[|]")) memmove(p1," | ",3); |
295 | macro_trans(p); |
296 | macro_trans(p); |
296 | singlespace(p); |
297 | singlespace(p); |
297 | p=find_word_start(p); strip_trailing_spaces(p); |
298 | p=find_word_start(p); strip_trailing_spaces(p); |
298 | l=0; p3=p; do { |
299 | l=0; p3=p; do { |
299 |
|
300 | p1=find_word_start(p3); |
300 |
|
301 | if(*p1) l++; |
301 |
|
302 | p2=strparchr(p1,'['); |
302 |
|
303 | if(p2!=NULL) p3=find_matching(p2+1,']'); |
303 |
|
304 | if(p3==NULL) error("unmatched_parentheses %.20s",p); |
304 |
|
305 | if(p2!=NULL && p2>p1) l++; |
305 |
|
306 | p3++; |
306 | } while(p2!=NULL); |
307 | } while(p2!=NULL); |
307 | if(l==0) { |
308 | if(l==0) { |
308 |
|
309 | buf[0]=0; cp_string(buf,blk,next); |
309 |
|
310 | return; |
310 | } |
311 | } |
311 | idx=start=nextblock; nextblock+=l-1; end=nextblock; |
312 | idx=start=nextblock; nextblock+=l-1; end=nextblock; |
312 | if(nextblock > MAX_BLOCKS) error("block_overflow %.20s",p); |
313 | if(nextblock > MAX_BLOCKS) error("block_overflow %.20s",p); |
313 | for(p1=find_word_start(p); *p1; p1=find_word_start(p3)) { |
314 | for(p1=find_word_start(p); *p1; p1=find_word_start(p3)) { |
314 |
|
315 | p2=strparchr(p1,'['); |
315 |
|
316 | if(p2==NULL) p2=p1+strlen(p1); |
316 |
|
317 | ll=p2-p1; |
317 |
|
318 | if(ll>0) { |
318 |
|
319 | memmove(buf,p1,ll); buf[ll]=0; |
319 |
|
320 | if(idx==start) b=blk; else b=blockbuf+idx-1; |
320 |
|
321 | if(idx<end) n=idx; else n=next; |
321 |
|
322 | if(debug>=3) fprintf(stderr,"String block %d/%d for %.15s.\n", |
322 |
|
323 | (int)(b-blockbuf), nextblock, buf); |
323 |
|
324 | cp_string(buf,b,n); |
324 |
|
325 | idx++; |
325 |
|
326 | } |
326 |
|
327 | if(*p2=='[') { |
327 |
|
328 | p2++; p3=find_matching(p2,']'); |
328 |
|
329 | memmove(buf,p2,p3-p2); buf[p3-p2]=0; p3++; |
329 |
|
330 | if(idx==start) b=blk; else b=blockbuf+idx-1; |
330 |
|
331 | if(idx<end) n=idx; else n=next; |
331 |
|
332 | cp_oneblock(buf,b,n); |
332 |
|
333 | idx++; |
333 |
|
334 | } |
334 |
|
335 | else p3=p2; |
335 | } |
336 | } |
336 | } |
337 | } |
337 | 338 | ||
338 | unsigned int objnum(char *p, char delim) |
339 | unsigned int objnum(char *p, char delim) |
339 | { |
340 | { |
340 | int i; char *p1, *p2; |
341 | int i; char *p1, *p2; |
341 | 342 | ||
342 | if(*p==0) return 1; |
343 | if(*p==0) return 1; |
343 | i=0; |
344 | i=0; |
344 | for(p1=p; p1; p1=p2, i++) { |
345 | for(p1=p; p1; p1=p2, i++) { |
345 |
|
346 | p2=strparchr(p1,delim); if(p2) p2++; |
346 | } |
347 | } |
347 | return i; |
348 | return i; |
348 | } |
349 | } |
349 | 350 | ||
350 | void _permpick(char *p, int n, struct block *blk, int next, char delim) |
351 | void _permpick(char *p, int n, struct block *blk, int next, char delim) |
351 | { |
352 | { |
352 | int i, t, idx; |
353 | int i, t, idx; |
353 | char buf[MAX_LINELEN+1]; |
354 | char buf[MAX_LINELEN+1]; |
354 | char *pp, *pe; |
355 | char *pp, *pe; |
355 | 356 | ||
356 | idx=nextblock; nextblock+=n; |
357 | idx=nextblock; nextblock+=n; |
357 | if(nextblock > MAX_BLOCKS) error("block_overflow %.20s",p); |
358 | if(nextblock > MAX_BLOCKS) error("block_overflow %.20s",p); |
358 | blk->len=n; |
359 | blk->len=n; |
359 | blk->sublock=idx; |
360 | blk->sublock=idx; |
360 | blk->fn=mt_permpick; |
361 | blk->fn=mt_permpick; |
361 | blk->lcnt=clist.lcnt; |
362 | blk->lcnt=clist.lcnt; |
362 | blk->nextblock=next; |
363 | blk->nextblock=next; |
363 | if(nextlist+n > MAX_LISTS) error("list_overflow %.20s",p); |
364 | if(nextlist+n > MAX_LISTS) error("list_overflow %.20s",p); |
364 | blk->listlen=listbuf+nextlist; nextlist+=n; |
365 | blk->listlen=listbuf+nextlist; nextlist+=n; |
365 | for(i=t=0; i<clist.lcnt; i++) { |
366 | for(i=t=0; i<clist.lcnt; i++) { |
366 |
|
367 | blk->listlen[i]=clist.listlen[i]; |
367 |
|
368 | blk->lists[i]=listbuf+nextlist+t; |
368 |
|
369 | t+=clist.listlen[i]; |
369 | } |
370 | } |
370 | if(nextlist+t > MAX_LISTS) error("list_overflow %.20s",p); |
371 | if(nextlist+t > MAX_LISTS) error("list_overflow %.20s",p); |
371 | memmove(listbuf+nextlist,clist.list,t*sizeof(listtype)); |
372 | memmove(listbuf+nextlist,clist.list,t*sizeof(listtype)); |
372 | nextlist+=t; |
373 | nextlist+=t; |
373 | for(i=0, pp=find_word_start(p);i<n;i++,idx++,pp=find_word_start(pe)) { |
374 | for(i=0, pp=find_word_start(p);i<n;i++,idx++,pp=find_word_start(pe)) { |
374 |
|
375 | pe=strparchr(pp,delim); |
375 |
|
376 | if(pe==NULL) pe=pp+strlen(pp); else *pe++=0; |
376 |
|
377 | snprintf(buf,sizeof(buf),"%s",pp); |
377 |
|
378 | cp_cutline(buf,blockbuf+idx,next); |
378 | } |
379 | } |
379 | } |
380 | } |
380 | 381 | ||
381 |
|
382 | /* alt for two flavours */ |
382 | void _alt(char *p, struct block *blk, int next, char delim) |
383 | void _alt(char *p, struct block *blk, int next, char delim) |
383 | { |
384 | { |
384 | int n; |
385 | int n; |
385 | listtype ltab[]={-1}; |
386 | listtype ltab[]={-1}; |
386 | listtype len[]={1}; |
387 | listtype len[]={1}; |
387 | 388 | ||
388 | clist.lcnt=1; clist.listlen=len; clist.list=ltab; |
389 | clist.lcnt=1; clist.listlen=len; clist.list=ltab; |
389 | n=objnum(p,delim); if(n==0) n=1; |
390 | n=objnum(p,delim); if(n==0) n=1; |
390 | _permpick(p,n,blk,next,delim); |
391 | _permpick(p,n,blk,next,delim); |
391 | } |
392 | } |
392 | 393 | ||
Line 460... | Line 461... | ||
460 | void cp_dperm(char *p, struct block *blk, int next) |
461 | void cp_dperm(char *p, struct block *blk, int next) |
461 | { |
462 | { |
462 | int n; |
463 | int n; |
463 | listtype ltab[]={0,1,2,2,3,0}; |
464 | listtype ltab[]={0,1,2,2,3,0}; |
464 | listtype len[]={3,3}; |
465 | listtype len[]={3,3}; |
465 | 466 | ||
466 | clist.lcnt=2; clist.listlen=len; clist.list=ltab; |
467 | clist.lcnt=2; clist.listlen=len; clist.list=ltab; |
467 | n=objnum(p,','); |
468 | n=objnum(p,','); |
468 | if(n!=4) error("wrong_parmcnt dperm %.20s",p); |
469 | if(n!=4) error("wrong_parmcnt dperm %.20s",p); |
469 | _permpick(p,n,blk,blk-blockbuf,','); |
470 | _permpick(p,n,blk,blk-blockbuf,','); |
470 | } |
471 | } |
Line 500... | Line 501... | ||
500 | 501 | ||
501 | void cp_m(char *p, struct block *blk, int next) |
502 | void cp_m(char *p, struct block *blk, int next) |
502 | { |
503 | { |
503 | int i, idx; |
504 | int i, idx; |
504 | char buf[MAX_LINELEN+1]; |
505 | char buf[MAX_LINELEN+1]; |
505 | 506 | ||
506 | i=objnum(p,','); if(i!=1) error("wrong_parmcnt m %.20s",p); |
507 | i=objnum(p,','); if(i!=1) error("wrong_parmcnt m %.20s",p); |
507 | blk->fn=mt_m; |
508 | blk->fn=mt_m; |
508 | blk->string=NULL; |
509 | blk->string=NULL; |
509 | blk->len=1; |
510 | blk->len=1; |
510 | blk->nextblock=next; |
511 | blk->nextblock=next; |
511 | p=find_word_start(p);singlespace(p);strip_trailing_spaces(p); |
512 | p=find_word_start(p);singlespace(p);strip_trailing_spaces(p); |
512 | for(i=0;i<Mcnt && strcmp(p,Mind[i].Mptr)!=0;i++); |
513 | for(i=0;i<Mcnt && strcmp(p,Mind[i].Mptr)!=0;i++); |
513 | if(nextblock >= MAX_BLOCKS-2) error("block_overflow %.20s",p); |
514 | if(nextblock >= MAX_BLOCKS-2) error("block_overflow %.20s",p); |
514 | if(i<Mcnt) blk->sublock=Mind[i].blkptr; |
515 | if(i<Mcnt) blk->sublock=Mind[i].blkptr; |
515 | else { |
516 | else { |
516 |
|
517 | i=strlen(p); |
517 |
|
518 | if(Mnext-Mbuf+i >= MAX_LINELEN-1) error("Mbuf_overflow %.20s",p); |
518 |
|
519 | if(Mcnt >= MAX_BLOCKS) error("Mind_overflow %.20s",p); |
519 |
|
520 | Mind[Mcnt].Mptr=Mnext; Mind[Mcnt].blkptr=nextblock; |
520 |
|
521 | Mcnt++; |
521 |
|
522 | memcpy(Mnext,p,i+1); Mnext+=i+1; |
522 |
|
523 | idx=nextblock; blk->sublock=idx; nextblock++; |
523 |
|
524 | snprintf(buf,sizeof(buf),"%s",p); |
524 |
|
525 | cp_cutline(buf,blockbuf+idx,-2); |
525 |
|
526 | blockbuf[idx].mend=nextblock; |
526 | } |
527 | } |
527 | } |
528 | } |
528 | 529 | ||
529 | void cp_neg(char *p, struct block *blk, int next) |
530 | void cp_neg(char *p, struct block *blk, int next) |
530 | { |
531 | { |
Line 594... | Line 595... | ||
594 | { |
595 | { |
595 | _pick(p,blk,next,-3); |
596 | _pick(p,blk,next,-3); |
596 | } |
597 | } |
597 | 598 | ||
598 | void cp_perm(char *p, struct block *blk, int next) |
599 | void cp_perm(char *p, struct block *blk, int next) |
599 | { |
600 | { |
600 | int i, n; |
601 | int i, n; |
601 | listtype ltab[MAX_BLOCKS]; |
602 | listtype ltab[MAX_BLOCKS]; |
602 | listtype len; |
603 | listtype len; |
603 | 604 | ||
604 | n=objnum(p,','); if(n==0) n=1; |
605 | n=objnum(p,','); if(n==0) n=1; |
Line 639... | Line 640... | ||
639 | char *pp, *pe; |
640 | char *pp, *pe; |
640 | n=objnum(p,','); if(n!=1) error("wrong_parmcnt wild %.20s\n",p); |
641 | n=objnum(p,','); if(n!=1) error("wrong_parmcnt wild %.20s\n",p); |
641 | blk->string=""; |
642 | blk->string=""; |
642 | max=min=0; |
643 | max=min=0; |
643 | for(pp=find_word_start(p); *pp; pp=find_word_start(pe)) { |
644 | for(pp=find_word_start(p); *pp; pp=find_word_start(pe)) { |
644 |
|
645 | pe=find_word_end(pp); |
645 |
|
646 | if(pp[0]!='*') error("syntax_error wild %.20s\n",p); |
646 |
|
647 | if(pp[1]!='*') { |
647 |
|
648 | min++; continue; |
648 |
|
649 | } |
649 |
|
650 | if(isdigit(pp[2])) max+=atoi(pp+2); |
650 |
|
651 | else max=MAX_BLOCKS; |
651 | } |
652 | } |
652 | blk->len=max; |
653 | blk->len=max; |
653 | blk->lstart=min; |
654 | blk->lstart=min; |
654 | blk->fn=mt_wild; |
655 | blk->fn=mt_wild; |
655 | blk->nextblock=next; |
656 | blk->nextblock=next; |
656 | } |
657 | } |
657 | 658 | ||
658 | struct { |
- | |
659 | char *name; |
- | |
660 | void (*fn) (char *p, struct block *blk, int next); |
- | |
661 |
|
659 | struct builtin builtin[]={ |
662 |
|
660 | {"Alt", cp_alt}, |
663 | {"Aperm", cp_aperm}, |
661 | {"Aperm", cp_aperm}, |
664 | {"Apick", cp_apick}, |
662 | {"Apick", cp_apick}, |
665 | {"Dic", cp_dic}, |
663 | {"Dic", cp_dic}, |
666 | {"Dperm", cp_dperm}, |
664 | {"Dperm", cp_dperm}, |
667 | {"Ins", cp_ins}, |
665 | {"Ins", cp_ins}, |
Line 678... | Line 676... | ||
678 | {"Rep", cp_rep}, |
676 | {"Rep", cp_rep}, |
679 | {"W", cp_w}, |
677 | {"W", cp_w}, |
680 | {"Wild", cp_wild}, |
678 | {"Wild", cp_wild}, |
681 | }; |
679 | }; |
682 | 680 | ||
683 |
|
681 | int builtincnt=(sizeof(builtin)/sizeof(builtin[0])); |
684 | 682 | ||
685 |
|
683 | /* p must have MAX_LINELEN */ |
686 | void cp_oneblock(char *p, struct block *blk, int next) |
684 | void cp_oneblock(char *p, struct block *blk, int next) |
687 | { |
685 | { |
688 | char *pp, *pe; |
686 | char *pp, *pe; |
689 | int i; |
687 | int i; |
690 | if(debug>=3) fprintf(stderr,"Oneblock %d/%d for %.15s.\n", |
688 | if(debug>=3) fprintf(stderr,"Oneblock %d/%d for %.15s.\n", |
691 |
|
689 | (int)(blk-blockbuf), nextblock, p); |
692 | if(myisupper(*p)) { |
690 | if(myisupper(*p)) { |
693 |
|
691 | for(pe=p; pe-p < MAX_BINAME && myisalpha(*pe); pe++); |
694 |
|
692 | if(*pe==':') { |
695 |
|
693 | *pe++=0; |
696 |
|
694 | i=search_list(builtin,builtincnt,sizeof(builtin[0]),p); |
697 |
|
695 | if(i<0) error("unknown_cmd %.20s",p); |
698 |
|
696 | builtin[i].fn(pe,blk,next); |
699 |
|
697 | blk->nextblock=next; |
700 |
|
698 | return; |
701 |
|
699 | } |
702 | } |
700 | } |
703 | if(*p=='*') { |
701 | if(*p=='*') { |
704 |
|
702 | cp_wild(p,blk,next); |
705 |
|
703 | return; |
706 | } |
704 | } |
707 | pp=strparchr(p,'|'); if(pp==NULL) { |
705 | pp=strparchr(p,'|'); if(pp==NULL) { |
708 |
|
706 | cp_cutline(p,blk,next); |
709 | } |
707 | } |
710 | else cp_alt2(p,blk,next); |
708 | else cp_alt2(p,blk,next); |
711 | } |
709 | } |
712 | 710 | ||
713 |
|
711 | /* p must have MAX_LINELEN */ |
714 | void compile(char *p) |
712 | void compile(char *p) |
715 | { |
713 | { |
716 | nextblock=1; nextlist=0; |
714 | nextblock=1; nextlist=0; |
717 | cpnext=cpbuf; |
715 | cpnext=cpbuf; |
718 | memset(blockbuf,0,sizeof(blockbuf)); |
716 | memset(blockbuf,0,sizeof(blockbuf)); |