Subversion Repositories wimsdev

Rev

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
        /* debugger: show the detail of blocks */
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
        blk=blockbuf+i;
46
      blk=blockbuf+i;
46
        fprintf(stderr,"Block %2d: next=%2d.    ",i,blk->nextblock);
47
      fprintf(stderr,"Block %2d: next=%2d.      ",i,blk->nextblock);
47
        if(blk->fn==mt_string) {
48
      if(blk->fn==mt_string) {
48
            fprintf(stderr,"String %s.\n",blk->string);
49
          fprintf(stderr,"String %s.\n",blk->string);
49
            continue;
50
          continue;
50
        }
51
      }
51
        if(blk->fn==mt_permpick) {
52
      if(blk->fn==mt_permpick) {
52
            fprintf(stderr,"Permpick %d items %d lists starting %d\n",
53
          fprintf(stderr,"Permpick %d items %d lists starting %d\n",
53
                   blk->len, blk->lcnt, blk->sublock);
54
               blk->len, blk->lcnt, blk->sublock);
54
            for(j=0;j<blk->lcnt;j++) {
55
          for(j=0;j<blk->lcnt;j++) {
55
                fprintf(stderr,"        list %d: ", j);
56
            fprintf(stderr,"    list %d: ", j);
56
                for(k=0;k<blk->listlen[j];k++)
57
            for(k=0;k<blk->listlen[j];k++)
57
                  fprintf(stderr,"%d ",blk->lists[j][k]);
58
              fprintf(stderr,"%d ",blk->lists[j][k]);
58
                fprintf(stderr,"\n");
59
            fprintf(stderr,"\n");
59
            }
60
          }
60
            continue;
61
          continue;
61
        }
62
      }
62
        if(blk->fn==mt_m) {
63
      if(blk->fn==mt_m) {
63
            fprintf(stderr,"Macro starting %d ending %d\n", blk->sublock,
64
          fprintf(stderr,"Macro starting %d ending %d\n", blk->sublock,
64
                    blockbuf[blk->sublock].mend);
65
                blockbuf[blk->sublock].mend);
65
            continue;
66
          continue;
66
        }
67
      }
67
        if(blk->fn==mt_neg) {
68
      if(blk->fn==mt_neg) {
68
            fprintf(stderr,"Neg starting %d\n", blk->sublock);
69
          fprintf(stderr,"Neg starting %d\n", blk->sublock);
69
            continue;
70
          continue;
70
        }
71
      }
71
        if(blk->fn==mt_dic) {
72
      if(blk->fn==mt_dic) {
72
            fprintf(stderr,"Dic %s.\n", blk->string);
73
          fprintf(stderr,"Dic %s.\n", blk->string);
73
            continue;
74
          continue;
74
        }
75
      }
75
        if(blk->fn==mt_w) {
76
      if(blk->fn==mt_w) {
76
            fprintf(stderr,"Word list.\n");
77
          fprintf(stderr,"Word list.\n");
77
            continue;
78
          continue;
78
        }
79
      }
79
        if(blk->fn==mt_wild) {
80
      if(blk->fn==mt_wild) {
80
            fprintf(stderr,"Wild min=%d, max=%d.\n", blk->lstart, blk->len+blk->lstart);
81
          fprintf(stderr,"Wild min=%d, max=%d.\n", blk->lstart, blk->len+blk->lstart);
81
            continue;
82
          continue;
82
        }
83
      }
83
        if(blk->fn==mt_out) {
84
      if(blk->fn==mt_out) {
84
            fprintf(stderr,"Output for \"%s\", sub=%d.\n", blk->string,blk->sublock);
85
          fprintf(stderr,"Output for \"%s\", sub=%d.\n", blk->string,blk->sublock);
85
            continue;
86
          continue;
86
        }
87
      }
87
        fprintf(stderr,"Unknown type!\n");
88
      fprintf(stderr,"Unknown type!\n");
88
    }
89
    }
89
   
90
 
90
}
91
}
91
 
92
 
92
        /* remove punctuations */
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
        if(strchr(str,*pp)==NULL) continue;
98
      if(strchr(str,*pp)==NULL) continue;
98
        if(*pp=='.' && pp>p && isdigit(pp[-1]) && isdigit(pp[1])) continue;
99
      if(*pp=='.' && pp>p && isdigit(pp[-1]) && isdigit(pp[1])) continue;
99
        *pp=' ';
100
      *pp=' ';
100
    }
101
    }
101
}
102
}
102
 
103
 
103
        /* p must have MAX_LINELEN */
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
        if(myisalnum(*p1) || (*p1&128) || *p1==' ' || *p1=='_') {
110
      if(myisalnum(*p1) || (*p1&128) || *p1==' ' || *p1=='_') {
110
            *p2++=*p1; continue;
111
          *p2++=*p1; continue;
111
        }
112
      }
112
        if((*p1=='.' || *p1==',') && p1>p && isdigit(p1[-1]) && isdigit(p1[1])) {
113
      if((*p1=='.' || *p1==',') && p1>p && isdigit(p1[-1]) && isdigit(p1[1])) {
113
            *p2++=*p1; continue;
114
          *p2++=*p1; continue;
114
        }
115
      }
115
        if(p2>buf && !myisspace(p2[-1])) *p2++=' ';
116
      if(p2>buf && !myisspace(p2[-1])) *p2++=' ';
116
        *p2++=*p1;
117
      *p2++=*p1;
117
        if(p1[1] && !myisspace(p1[1])) *p2++=' ';
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
        /* buffer must have MAX_LINELEN */
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
        /* at entry p must point to an atom start! */
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
        pp=find_matching(p+1,']');
167
      pp=find_matching(p+1,']');
167
        if(pp!=NULL) return pp+1;
168
      if(pp!=NULL) return pp+1;
168
        else error("unmatched_parentheses %.20s",p);
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
        /* p must have MAX_LINELEN */
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
        pp=atoms[k]; switch(*pp) {
196
      pp=atoms[k]; switch(*pp) {
196
            case '[': {
197
          case '[': {
197
                pe=find_atom_end(pp); pp++;
198
            pe=find_atom_end(pp); pp++;
198
                if(pe[-1]!=']') break;
199
            if(pe[-1]!=']') break;
199
                if(myislower(*pp)) {
200
            if(myislower(*pp)) {
200
                    for(p1=pp;myisalnum(*p1) || *p1=='_'; p1++);
201
                for(p1=pp;myisalnum(*p1) || *p1=='_'; p1++);
201
                    if(*p1!=':') break;
202
                if(*p1!=':') break;
202
                    *p1++=0; pe[-1]=0;
203
                *p1++=0; pe[-1]=0;
203
                    for(m=0,p2=p1;*p2;m++,p2=p3) {
204
                for(m=0,p2=p1;*p2;m++,p2=p3) {
204
                        p3=find_item_end(p2); if(*p3) *p3++=0;
205
                  p3=find_item_end(p2); if(*p3) *p3++=0;
205
                        atom2[m]=p2;
206
                  atom2[m]=p2;
206
                    }
207
                }
207
                    if(m==0) m=1;
208
                if(m==0) m=1;
208
                    snprintf(tbuf,sizeof(tbuf),"%s",pp);
209
                snprintf(tbuf,sizeof(tbuf),"%s",pp);
209
                    _translate(tbuf,macrodic);
210
                _translate(tbuf,macrodic);
210
                    if(tbuf[0]==0) error("bad_macro %.50s",pp);
211
                if(tbuf[0]==0) error("bad_macro %.50s",pp);
211
                    for(p1=strchr(tbuf,'@'); p1; p1=strchr(p1,'@')) {
212
                for(p1=strchr(tbuf,'@'); p1; p1=strchr(p1,'@')) {
212
                        for(p2=p1+1;isdigit(*p2) || *p2=='-';p2++);
213
                  for(p2=p1+1;isdigit(*p2) || *p2=='-';p2++);
213
                        if(p2==p1+1 || p2>p1+6) error("syntax_error %.20s",p1);
214
                  if(p2==p1+1 || p2>p1+6) error("syntax_error %.20s",p1);
214
                        memmove(vbuf,p1,p2-p1); vbuf[p2-p1]=0;
215
                  memmove(vbuf,p1,p2-p1); vbuf[p2-p1]=0;
215
                        n=atoi(vbuf+1);
216
                  n=atoi(vbuf+1);
216
                        if(n<=0 || n>m) error("wrong_parmcnt macro %.50s",pp);
217
                  if(n<=0 || n>m) error("wrong_parmcnt macro %.50s",pp);
217
                        string_modify(tbuf,p1,p2,atom2[n-1]);
218
                  string_modify(tbuf,p1,p2,atom2[n-1]);
218
                    }
219
                }
219
                    n=strlen(tbuf); if(n<MAX_LINELEN) {
220
                n=strlen(tbuf); if(n<MAX_LINELEN) {
220
                        tbuf[n++]=' '; tbuf[n]=0;
221
                  tbuf[n++]=' '; tbuf[n]=0;
221
                    }
222
                }
222
                    string_modify(p,pp-1,pe,tbuf); pt=pp-1; start=k;
223
                string_modify(p,pp-1,pe,tbuf); pt=pp-1; start=k;
223
                    goto recalc;
224
                goto recalc;
224
                }
225
            }
225
                break;
226
            break;
226
            }
227
          }
227
            case '_': {
228
          case '_': {
228
                pe=find_word_end(pp);
229
            pe=find_word_end(pp);
229
                if(pe-pp>MAX_NAMELEN) error("name_too_long %.20s",pp);
230
            if(pe-pp>MAX_NAMELEN) error("name_too_long %.20s",pp);
230
                memmove(tbuf,pp,pe-pp); tbuf[pe-pp]=0;
231
            memmove(tbuf,pp,pe-pp); tbuf[pe-pp]=0;
231
                _translate(tbuf,macrodic);
232
            _translate(tbuf,macrodic);
232
                if(tbuf[0]==0) break;
233
            if(tbuf[0]==0) break;
233
                pt1=pp; pt2=find_atom_end(pt1); min=k;
234
            pt1=pp; pt2=find_atom_end(pt1); min=k;
234
                for(p1=strchr(tbuf,'@'); p1; p1=strchr(p1,'@')) {
235
            for(p1=strchr(tbuf,'@'); p1; p1=strchr(p1,'@')) {
235
                    for(p2=p1+1;isdigit(*p2) || *p2=='-';p2++);
236
                for(p2=p1+1;isdigit(*p2) || *p2=='-';p2++);
236
                    if(p2==p1+1 || p2>p1+6) error("syntax_error %.20s",p1);
237
                if(p2==p1+1 || p2>p1+6) error("syntax_error %.20s",p1);
237
                    memmove(vbuf,p1,p2-p1); vbuf[p2-p1]=0;
238
                memmove(vbuf,p1,p2-p1); vbuf[p2-p1]=0;
238
                    n=atoi(vbuf+1);
239
                n=atoi(vbuf+1);
239
                    if(n<-4 || n==0 || n>4) error("bad_macro %.20s",atoms[k]);
240
                if(n<-4 || n==0 || n>4) error("bad_macro %.20s",atoms[k]);
240
                    n+=k;
241
                n+=k;
241
                    if(n<0 || n>=i) error("bad_macro_position %.20s",atoms[k]);
242
                if(n<0 || n>=i) error("bad_macro_position %.20s",atoms[k]);
242
                    p3=find_atom_end(atoms[n]);
243
                p3=find_atom_end(atoms[n]);
243
                    if(p3>pt2) pt2=p3;
244
                if(p3>pt2) pt2=p3;
244
                    if(atoms[n]<pt1) {min=n;pt1=atoms[n];}
245
                if(atoms[n]<pt1) {min=n;pt1=atoms[n];}
245
                    memmove(ttbuf,atoms[n],p3-atoms[n]); ttbuf[p3-atoms[n]]=' ';
246
                memmove(ttbuf,atoms[n],p3-atoms[n]); ttbuf[p3-atoms[n]]=' ';
246
                    ttbuf[p3-atoms[n]+1]=0;
247
                ttbuf[p3-atoms[n]+1]=0;
247
                    string_modify(tbuf,p1,p2,ttbuf);
248
                string_modify(tbuf,p1,p2,ttbuf);
248
                }
249
            }
249
                string_modify(p,pt1,pt2,tbuf); pt=pt1; start=min;
250
            string_modify(p,pt1,pt2,tbuf); pt=pt1; start=min;
250
                goto recalc;
251
            goto recalc;
251
            }
252
          }
252
            default: break;
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
        p2=find_word_end(p1); l=p2-p1;
266
      p2=find_word_end(p1); l=p2-p1;
266
        if(*p2) *p2++=0;
267
      if(*p2) *p2++=0;
267
        if(wordchr(wbuf,p1)!=NULL) continue;
268
      if(wordchr(wbuf,p1)!=NULL) continue;
268
        if(wptr-wbuf>=sizeof(wbuf)-l-2) continue;
269
      if(wptr-wbuf>=sizeof(wbuf)-l-2) continue;
269
        if(wptr>wbuf) *wptr++=' ';
270
      if(wptr>wbuf) *wptr++=' ';
270
        memmove(wptr,p1,l); wptr+=l; *wptr=0;
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
        /* p must have MAX_LINELEN */
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
                         (int)(blk-blockbuf), nextblock, p);
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
        p1=find_word_start(p3);
300
      p1=find_word_start(p3);
300
        if(*p1) l++;
301
      if(*p1) l++;
301
        p2=strparchr(p1,'[');
302
      p2=strparchr(p1,'[');
302
        if(p2!=NULL) p3=find_matching(p2+1,']');
303
      if(p2!=NULL) p3=find_matching(p2+1,']');
303
        if(p3==NULL) error("unmatched_parentheses %.20s",p);
304
      if(p3==NULL) error("unmatched_parentheses %.20s",p);
304
        if(p2!=NULL && p2>p1) l++;
305
      if(p2!=NULL && p2>p1) l++;
305
        p3++;
306
      p3++;
306
    } while(p2!=NULL);
307
    } while(p2!=NULL);
307
    if(l==0) {
308
    if(l==0) {
308
        buf[0]=0; cp_string(buf,blk,next);
309
      buf[0]=0; cp_string(buf,blk,next);
309
        return;
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
        p2=strparchr(p1,'[');
315
      p2=strparchr(p1,'[');
315
        if(p2==NULL) p2=p1+strlen(p1);
316
      if(p2==NULL) p2=p1+strlen(p1);
316
        ll=p2-p1;
317
      ll=p2-p1;
317
        if(ll>0) {
318
      if(ll>0) {
318
            memmove(buf,p1,ll); buf[ll]=0;
319
          memmove(buf,p1,ll); buf[ll]=0;
319
            if(idx==start) b=blk; else b=blockbuf+idx-1;
320
          if(idx==start) b=blk; else b=blockbuf+idx-1;
320
            if(idx<end) n=idx; else n=next;
321
          if(idx<end) n=idx; else n=next;
321
            if(debug>=3) fprintf(stderr,"String block %d/%d for %.15s.\n",
322
          if(debug>=3) fprintf(stderr,"String block %d/%d for %.15s.\n",
322
                         (int)(b-blockbuf), nextblock, buf);
323
                   (int)(b-blockbuf), nextblock, buf);
323
            cp_string(buf,b,n);
324
          cp_string(buf,b,n);
324
            idx++;
325
          idx++;
325
        }
326
      }
326
        if(*p2=='[') {
327
      if(*p2=='[') {
327
            p2++; p3=find_matching(p2,']');
328
          p2++; p3=find_matching(p2,']');
328
            memmove(buf,p2,p3-p2); buf[p3-p2]=0; p3++;
329
          memmove(buf,p2,p3-p2); buf[p3-p2]=0; p3++;
329
            if(idx==start) b=blk; else b=blockbuf+idx-1;
330
          if(idx==start) b=blk; else b=blockbuf+idx-1;
330
            if(idx<end) n=idx; else n=next;
331
          if(idx<end) n=idx; else n=next;
331
            cp_oneblock(buf,b,n);
332
          cp_oneblock(buf,b,n);
332
            idx++;
333
          idx++;
333
        }
334
      }
334
        else p3=p2;
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
        p2=strparchr(p1,delim); if(p2) p2++;
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
        blk->listlen[i]=clist.listlen[i];
367
      blk->listlen[i]=clist.listlen[i];
367
        blk->lists[i]=listbuf+nextlist+t;
368
      blk->lists[i]=listbuf+nextlist+t;
368
        t+=clist.listlen[i];
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
        pe=strparchr(pp,delim);
375
      pe=strparchr(pp,delim);
375
        if(pe==NULL) pe=pp+strlen(pp); else *pe++=0;
376
      if(pe==NULL) pe=pp+strlen(pp); else *pe++=0;
376
        snprintf(buf,sizeof(buf),"%s",pp);
377
      snprintf(buf,sizeof(buf),"%s",pp);
377
        cp_cutline(buf,blockbuf+idx,next);
378
      cp_cutline(buf,blockbuf+idx,next);
378
    }
379
    }
379
}
380
}
380
 
381
 
381
        /* alt for two flavours */
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
        i=strlen(p);
517
      i=strlen(p);
517
        if(Mnext-Mbuf+i >= MAX_LINELEN-1) error("Mbuf_overflow %.20s",p);
518
      if(Mnext-Mbuf+i >= MAX_LINELEN-1) error("Mbuf_overflow %.20s",p);
518
        if(Mcnt >= MAX_BLOCKS) error("Mind_overflow %.20s",p);
519
      if(Mcnt >= MAX_BLOCKS) error("Mind_overflow %.20s",p);
519
        Mind[Mcnt].Mptr=Mnext; Mind[Mcnt].blkptr=nextblock;
520
      Mind[Mcnt].Mptr=Mnext; Mind[Mcnt].blkptr=nextblock;
520
        Mcnt++;
521
      Mcnt++;
521
        memcpy(Mnext,p,i+1); Mnext+=i+1;
522
      memcpy(Mnext,p,i+1); Mnext+=i+1;
522
        idx=nextblock; blk->sublock=idx; nextblock++;
523
      idx=nextblock; blk->sublock=idx; nextblock++;
523
        snprintf(buf,sizeof(buf),"%s",p);
524
      snprintf(buf,sizeof(buf),"%s",p);
524
        cp_cutline(buf,blockbuf+idx,-2);
525
      cp_cutline(buf,blockbuf+idx,-2);
525
        blockbuf[idx].mend=nextblock;
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
        pe=find_word_end(pp);
645
      pe=find_word_end(pp);
645
        if(pp[0]!='*') error("syntax_error wild %.20s\n",p);
646
      if(pp[0]!='*') error("syntax_error wild %.20s\n",p);
646
        if(pp[1]!='*') {
647
      if(pp[1]!='*') {
647
            min++; continue;
648
          min++; continue;
648
        }
649
      }
649
        if(isdigit(pp[2])) max+=atoi(pp+2);
650
      if(isdigit(pp[2])) max+=atoi(pp+2);
650
        else max=MAX_BLOCKS;
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
} builtin[]={
659
struct builtin builtin[]={
662
        {"Alt",         cp_alt},
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
#define builtincnt (sizeof(builtin)/sizeof(builtin[0]))
681
int builtincnt=(sizeof(builtin)/sizeof(builtin[0]));
684
 
682
 
685
        /* p must have MAX_LINELEN */
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
                         (int)(blk-blockbuf), nextblock, p);
689
                   (int)(blk-blockbuf), nextblock, p);
692
    if(myisupper(*p)) {
690
    if(myisupper(*p)) {
693
        for(pe=p; pe-p < MAX_BINAME && myisalpha(*pe); pe++);
691
      for(pe=p; pe-p < MAX_BINAME && myisalpha(*pe); pe++);
694
        if(*pe==':') {
692
      if(*pe==':') {
695
            *pe++=0;
693
          *pe++=0;
696
            i=search_list(builtin,builtincnt,sizeof(builtin[0]),p);
694
          i=search_list(builtin,builtincnt,sizeof(builtin[0]),p);
697
            if(i<0) error("unknown_cmd %.20s",p);
695
          if(i<0) error("unknown_cmd %.20s",p);
698
            builtin[i].fn(pe,blk,next);
696
          builtin[i].fn(pe,blk,next);
699
            blk->nextblock=next;
697
          blk->nextblock=next;
700
            return;
698
          return;
701
        }
699
      }
702
    }
700
    }
703
    if(*p=='*') {
701
    if(*p=='*') {
704
        cp_wild(p,blk,next);
702
      cp_wild(p,blk,next);
705
        return;
703
      return;
706
    }
704
    }
707
    pp=strparchr(p,'|'); if(pp==NULL) {
705
    pp=strparchr(p,'|'); if(pp==NULL) {
708
        cp_cutline(p,blk,next);
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
        /* p must have MAX_LINELEN */
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));