Subversion Repositories wimsdev

Rev

Rev 8161 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
10 reyssat 1
/*    Copyright (C) 2002-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
2
 *
3
 *  This program is free software; you can redistribute it and/or modify
4
 *  it under the terms of the GNU General Public License as published by
5
 *  the Free Software Foundation; either version 2 of the License, or
6
 *  (at your option) any later version.
7
 *
8
 *  This program is distributed in the hope that it will be useful,
9
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 *  GNU General Public License for more details.
12
 *
13
 *  You should have received a copy of the GNU General Public License
14
 *  along with this program; if not, write to the Free Software
15
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
 */
8161 bpr 17
#include "symtext.h"
10 reyssat 18
 
19
char cpbuf[MAX_LINELEN+1];
20
char *cpnext;
21
int noaddw=0;
22
 
23
char Mbuf[MAX_LINELEN+1];
24
char *Mnext;
25
struct {
26
    char *Mptr;
27
    int blkptr;
28
} Mind[MAX_BLOCKS];
29
int Mcnt;
30
 
31
struct liststruct {
32
    listtype lcnt;
33
    listtype *listlen;
34
    listtype *list;
35
} clist;
36
 
37
void cp_oneblock(char *p, struct block *blk, int next);
38
 
8161 bpr 39
/* debugger: show the detail of blocks */
10 reyssat 40
void showblocks(void)
41
{
42
    int i, j, k;
43
    struct block *blk;
44
    if(!debug) return;
45
    for(i=0;i<nextblock;i++) {
8161 bpr 46
      blk=blockbuf+i;
47
      fprintf(stderr,"Block %2d: next=%2d.      ",i,blk->nextblock);
48
      if(blk->fn==mt_string) {
49
          fprintf(stderr,"String %s.\n",blk->string);
50
          continue;
51
      }
52
      if(blk->fn==mt_permpick) {
53
          fprintf(stderr,"Permpick %d items %d lists starting %d\n",
54
               blk->len, blk->lcnt, blk->sublock);
55
          for(j=0;j<blk->lcnt;j++) {
56
            fprintf(stderr,"    list %d: ", j);
57
            for(k=0;k<blk->listlen[j];k++)
58
              fprintf(stderr,"%d ",blk->lists[j][k]);
59
            fprintf(stderr,"\n");
60
          }
61
          continue;
62
      }
63
      if(blk->fn==mt_m) {
64
          fprintf(stderr,"Macro starting %d ending %d\n", blk->sublock,
65
                blockbuf[blk->sublock].mend);
66
          continue;
67
      }
68
      if(blk->fn==mt_neg) {
69
          fprintf(stderr,"Neg starting %d\n", blk->sublock);
70
          continue;
71
      }
72
      if(blk->fn==mt_dic) {
73
          fprintf(stderr,"Dic %s.\n", blk->string);
74
          continue;
75
      }
76
      if(blk->fn==mt_w) {
77
          fprintf(stderr,"Word list.\n");
78
          continue;
79
      }
80
      if(blk->fn==mt_wild) {
81
          fprintf(stderr,"Wild min=%d, max=%d.\n", blk->lstart, blk->len+blk->lstart);
82
          continue;
83
      }
84
      if(blk->fn==mt_out) {
85
          fprintf(stderr,"Output for \"%s\", sub=%d.\n", blk->string,blk->sublock);
86
          continue;
87
      }
88
      fprintf(stderr,"Unknown type!\n");
10 reyssat 89
    }
8161 bpr 90
 
10 reyssat 91
}
92
 
8161 bpr 93
/* remove punctuations */
10 reyssat 94
void depunct(char *p,char *str)
95
{
96
    char *pp;
97
    for(pp=p; *pp; pp++) {
8161 bpr 98
      if(strchr(str,*pp)==NULL) continue;
99
      if(*pp=='.' && pp>p && isdigit(pp[-1]) && isdigit(pp[1])) continue;
100
      *pp=' ';
10 reyssat 101
    }
102
}
103
 
8161 bpr 104
/* p must have MAX_LINELEN */
10 reyssat 105
void isolate_punct(char *p)
106
{
107
    char buf[MAX_LINELEN+1];
108
    char *p1, *p2;
109
    for(p1=p, p2=buf; *p1 && p2<buf+MAX_LINELEN; p1++) {
8161 bpr 110
      if(myisalnum(*p1) || (*p1&128) || *p1==' ' || *p1=='_') {
111
          *p2++=*p1; continue;
112
      }
113
      if((*p1=='.' || *p1==',') && p1>p && isdigit(p1[-1]) && isdigit(p1[1])) {
114
          *p2++=*p1; continue;
115
      }
116
      if(p2>buf && !myisspace(p2[-1])) *p2++=' ';
117
      *p2++=*p1;
118
      if(p1[1] && !myisspace(p1[1])) *p2++=' ';
10 reyssat 119
    }
8195 bpr 120
    if(p2>=buf+MAX_LINELEN) sym_error("string_too_long");
10 reyssat 121
    *p2=0;
122
    snprintf(p,MAX_LINELEN,"%s",buf);
123
}
124
 
125
void alphaonly(char *p)
126
{
127
    char *pp;
128
    for(pp=p; *pp; pp++) if(!myisalpha(*pp)) *pp=' ';
129
}
130
 
131
void alnumonly(char *p)
132
{
133
    char *pp;
134
    for(pp=p; *pp; pp++) if(!myisalnum(*pp)) *pp=' ';
135
}
136
 
8161 bpr 137
/* buffer must have MAX_LINELEN */
10 reyssat 138
void strfold(char *p)
139
{
140
    char *pp;
141
    singlespace(p);
142
    if(noaddw&2) goto fend;
143
    if(options&op_nocase) for(pp=p; *pp; pp++) *pp=tolower(*pp);
144
    if(options&op_reaccent) reaccent(p);
145
    if(options&op_deaccent) deaccent(p);
146
    if(options&op_alphaonly) alphaonly(p);
147
    if(options&op_alnumonly) alnumonly(p);
148
    isolate_punct(p);
149
    if(options&op_nopunct) depunct(p,char_punct);
150
    if(options&op_nomath) depunct(p,char_math);
151
    if(options&op_noparenth) depunct(p,char_parenth);
152
    if(options&op_nocs) depunct(p,char_cs);
153
    if(options&op_noquote) depunct(p,char_quote);
154
    if(suffixcnt>0) suffix_translate(p);
155
    _translate(p,transdic);
8161 bpr 156
 
10 reyssat 157
fend:
158
    singlespace(p);strip_trailing_spaces(p);
3718 reyssat 159
    if(myisspace(*p)) ovlstrcpy(p,find_word_start(p));
10 reyssat 160
}
161
 
8161 bpr 162
/* at entry p must point to an atom start! */
10 reyssat 163
char *find_atom_end(char *p)
164
{
165
    char *pp;
166
    if(*p=='[') {
8161 bpr 167
      pp=find_matching(p+1,']');
168
      if(pp!=NULL) return pp+1;
8195 bpr 169
      else sym_error("unmatched_parentheses %.20s",p);
10 reyssat 170
    }
171
    return find_word_end(p);
172
}
173
 
174
#define find_atom_start(x) find_word_start(x)
175
#define next_atom(x) find_atom_start(find_atom_end(x))
176
 
8161 bpr 177
/* p must have MAX_LINELEN */
10 reyssat 178
void macro_trans(char *p)
179
{
180
    char *atoms[MAX_BLOCKS], *atom2[MAX_BLOCKS];
181
    char tbuf[MAX_LINELEN+1], ttbuf[MAX_LINELEN+1], vbuf[8];
182
    char *pt, *pp, *pe, *p1, *p2, *p3;
183
    char *pt1, *pt2;
184
    int i,k,m,n,repcnt,start,min;
8161 bpr 185
 
10 reyssat 186
    if(dic[macrodic].len<=0) return;
187
    repcnt=start=0; pt=p;
188
    recalc:
189
    repcnt++;
8195 bpr 190
    if(repcnt>=MAX_BLOCKS) sym_error("macro_level_overflow %.20s",p);
10 reyssat 191
    for(i=start, pp=find_atom_start(pt); i<MAX_BLOCKS && *pp; pp=next_atom(pp), i++)
192
      atoms[i]=pp;
8195 bpr 193
    if(i>=MAX_BLOCKS-1) sym_error("block_overflow %.20s",p);
10 reyssat 194
    atoms[i]=pp+strlen(pp);
195
    for(k=0;k<i;k++) {
8161 bpr 196
      pp=atoms[k]; switch(*pp) {
197
          case '[': {
198
            pe=find_atom_end(pp); pp++;
199
            if(pe[-1]!=']') break;
200
            if(myislower(*pp)) {
201
                for(p1=pp;myisalnum(*p1) || *p1=='_'; p1++);
202
                if(*p1!=':') break;
203
                *p1++=0; pe[-1]=0;
204
                for(m=0,p2=p1;*p2;m++,p2=p3) {
205
                  p3=find_item_end(p2); if(*p3) *p3++=0;
206
                  atom2[m]=p2;
207
                }
208
                if(m==0) m=1;
209
                snprintf(tbuf,sizeof(tbuf),"%s",pp);
210
                _translate(tbuf,macrodic);
8195 bpr 211
                if(tbuf[0]==0) sym_error("bad_macro %.50s",pp);
8161 bpr 212
                for(p1=strchr(tbuf,'@'); p1; p1=strchr(p1,'@')) {
213
                  for(p2=p1+1;isdigit(*p2) || *p2=='-';p2++);
8195 bpr 214
                  if(p2==p1+1 || p2>p1+6) sym_error("syntax_error %.20s",p1);
8161 bpr 215
                  memmove(vbuf,p1,p2-p1); vbuf[p2-p1]=0;
216
                  n=atoi(vbuf+1);
8195 bpr 217
                  if(n<=0 || n>m) sym_error("wrong_parmcnt macro %.50s",pp);
8161 bpr 218
                  string_modify(tbuf,p1,p2,atom2[n-1]);
219
                }
220
                n=strlen(tbuf); if(n<MAX_LINELEN) {
221
                  tbuf[n++]=' '; tbuf[n]=0;
222
                }
223
                string_modify(p,pp-1,pe,tbuf); pt=pp-1; start=k;
224
                goto recalc;
225
            }
226
            break;
227
          }
228
          case '_': {
229
            pe=find_word_end(pp);
8195 bpr 230
            if(pe-pp>MAX_NAMELEN) sym_error("name_too_long %.20s",pp);
8161 bpr 231
            memmove(tbuf,pp,pe-pp); tbuf[pe-pp]=0;
232
            _translate(tbuf,macrodic);
233
            if(tbuf[0]==0) break;
234
            pt1=pp; pt2=find_atom_end(pt1); min=k;
235
            for(p1=strchr(tbuf,'@'); p1; p1=strchr(p1,'@')) {
236
                for(p2=p1+1;isdigit(*p2) || *p2=='-';p2++);
8195 bpr 237
                if(p2==p1+1 || p2>p1+6) sym_error("syntax_error %.20s",p1);
8161 bpr 238
                memmove(vbuf,p1,p2-p1); vbuf[p2-p1]=0;
239
                n=atoi(vbuf+1);
8195 bpr 240
                if(n<-4 || n==0 || n>4) sym_error("bad_macro %.20s",atoms[k]);
8161 bpr 241
                n+=k;
8195 bpr 242
                if(n<0 || n>=i) sym_error("bad_macro_position %.20s",atoms[k]);
8161 bpr 243
                p3=find_atom_end(atoms[n]);
244
                if(p3>pt2) pt2=p3;
245
                if(atoms[n]<pt1) {min=n;pt1=atoms[n];}
246
                memmove(ttbuf,atoms[n],p3-atoms[n]); ttbuf[p3-atoms[n]]=' ';
247
                ttbuf[p3-atoms[n]+1]=0;
248
                string_modify(tbuf,p1,p2,ttbuf);
249
            }
250
            string_modify(p,pt1,pt2,tbuf); pt=pt1; start=min;
251
            goto recalc;
252
          }
253
          default: break;
254
      }
10 reyssat 255
    }
256
}
257
 
258
char *add2cp(char *p)
259
{
260
    char *pp, *p1, *p2, buf[MAX_LINELEN+1];
261
    int l;
262
    snprintf(buf,sizeof(buf),"%s",p); strfold(buf); l=strlen(buf);
8195 bpr 263
    if((cpnext-cpbuf)+l>=MAX_LINELEN) sym_error("string_too_long");
10 reyssat 264
    pp=cpnext; memmove(pp,buf,l+1); cpnext+=l+1;
265
    if(!noaddw) for(p1=find_word_start(buf); *p1; p1=find_word_start(p2)) {
8161 bpr 266
      p2=find_word_end(p1); l=p2-p1;
267
      if(*p2) *p2++=0;
268
      if(wordchr(wbuf,p1)!=NULL) continue;
269
      if(wptr-wbuf>=sizeof(wbuf)-l-2) continue;
270
      if(wptr>wbuf) *wptr++=' ';
271
      memmove(wptr,p1,l); wptr+=l; *wptr=0;
10 reyssat 272
    }
273
    return pp;
274
}
275
 
276
void cp_string(char *p, struct block *blk, int next)
277
{
278
    blk->fn=mt_string;
279
    blk->string=add2cp(p);
280
    blk->len=strlen(blk->string);
281
    blk->nextblock=next;
282
    if(blk==blockbuf+nextblock) nextblock++;
283
}
284
 
8161 bpr 285
/* p must have MAX_LINELEN */
10 reyssat 286
void cp_cutline(char *p, struct block *blk, int next)
287
{
288
    char *p1, *p2, *p3;
289
    char buf[MAX_LINELEN+1];
290
    int l, ll, n, idx, start, end;
291
    struct block *b;
292
 
3813 kbelabas 293
    if(debug>=3) fprintf(stderr,"Cutline %d/%d for %.15s.\n",
8161 bpr 294
                   (int)(blk-blockbuf), nextblock, p);
10 reyssat 295
    for(p1=strstr(p,"[|]"); p1; p1=strstr(p1,"[|]")) memmove(p1," | ",3);
296
    macro_trans(p);
297
    singlespace(p);
298
    p=find_word_start(p); strip_trailing_spaces(p);
299
    l=0; p3=p; do {
8161 bpr 300
      p1=find_word_start(p3);
301
      if(*p1) l++;
302
      p2=strparchr(p1,'[');
303
      if(p2!=NULL) p3=find_matching(p2+1,']');
8195 bpr 304
      if(p3==NULL) sym_error("unmatched_parentheses %.20s",p);
8161 bpr 305
      if(p2!=NULL && p2>p1) l++;
306
      p3++;
10 reyssat 307
    } while(p2!=NULL);
308
    if(l==0) {
8161 bpr 309
      buf[0]=0; cp_string(buf,blk,next);
310
      return;
10 reyssat 311
    }
312
    idx=start=nextblock; nextblock+=l-1; end=nextblock;
8195 bpr 313
    if(nextblock > MAX_BLOCKS) sym_error("block_overflow %.20s",p);
10 reyssat 314
    for(p1=find_word_start(p); *p1; p1=find_word_start(p3)) {
8161 bpr 315
      p2=strparchr(p1,'[');
316
      if(p2==NULL) p2=p1+strlen(p1);
317
      ll=p2-p1;
318
      if(ll>0) {
319
          memmove(buf,p1,ll); buf[ll]=0;
320
          if(idx==start) b=blk; else b=blockbuf+idx-1;
321
          if(idx<end) n=idx; else n=next;
322
          if(debug>=3) fprintf(stderr,"String block %d/%d for %.15s.\n",
323
                   (int)(b-blockbuf), nextblock, buf);
324
          cp_string(buf,b,n);
325
          idx++;
326
      }
327
      if(*p2=='[') {
328
          p2++; p3=find_matching(p2,']');
329
          memmove(buf,p2,p3-p2); buf[p3-p2]=0; p3++;
330
          if(idx==start) b=blk; else b=blockbuf+idx-1;
331
          if(idx<end) n=idx; else n=next;
332
          cp_oneblock(buf,b,n);
333
          idx++;
334
      }
335
      else p3=p2;
10 reyssat 336
    }
337
}
338
 
339
unsigned int objnum(char *p, char delim)
340
{
341
    int i; char *p1, *p2;
342
 
343
    if(*p==0) return 1;
344
    i=0;
345
    for(p1=p; p1; p1=p2, i++) {
8161 bpr 346
      p2=strparchr(p1,delim); if(p2) p2++;
10 reyssat 347
    }
348
    return i;
349
}
350
 
351
void _permpick(char *p, int n, struct block *blk, int next, char delim)
352
{
353
    int i, t, idx;
354
    char buf[MAX_LINELEN+1];
355
    char *pp, *pe;
8161 bpr 356
 
10 reyssat 357
    idx=nextblock; nextblock+=n;
8195 bpr 358
    if(nextblock > MAX_BLOCKS) sym_error("block_overflow %.20s",p);
10 reyssat 359
    blk->len=n;
360
    blk->sublock=idx;
361
    blk->fn=mt_permpick;
362
    blk->lcnt=clist.lcnt;
363
    blk->nextblock=next;
8195 bpr 364
    if(nextlist+n > MAX_LISTS) sym_error("list_overflow %.20s",p);
10 reyssat 365
    blk->listlen=listbuf+nextlist; nextlist+=n;
366
    for(i=t=0; i<clist.lcnt; i++) {
8161 bpr 367
      blk->listlen[i]=clist.listlen[i];
368
      blk->lists[i]=listbuf+nextlist+t;
369
      t+=clist.listlen[i];
10 reyssat 370
    }
8195 bpr 371
    if(nextlist+t > MAX_LISTS) sym_error("list_overflow %.20s",p);
10 reyssat 372
    memmove(listbuf+nextlist,clist.list,t*sizeof(listtype));
373
    nextlist+=t;
374
    for(i=0, pp=find_word_start(p);i<n;i++,idx++,pp=find_word_start(pe)) {
8161 bpr 375
      pe=strparchr(pp,delim);
376
      if(pe==NULL) pe=pp+strlen(pp); else *pe++=0;
377
      snprintf(buf,sizeof(buf),"%s",pp);
378
      cp_cutline(buf,blockbuf+idx,next);
10 reyssat 379
    }
380
}
381
 
8161 bpr 382
/* alt for two flavours */
10 reyssat 383
void _alt(char *p, struct block *blk, int next, char delim)
384
{
385
    int n;
386
    listtype ltab[]={-1};
387
    listtype len[]={1};
8161 bpr 388
 
10 reyssat 389
    clist.lcnt=1; clist.listlen=len; clist.list=ltab;
390
    n=objnum(p,delim); if(n==0) n=1;
391
    _permpick(p,n,blk,next,delim);
392
}
393
 
394
void cp_alt(char *p, struct block *blk, int next)
395
{
396
    _alt(p,blk,next,',');
397
}
398
 
399
void cp_alt2(char *p, struct block *blk, int next)
400
{
401
    _alt(p,blk,next,'|');
402
}
403
 
404
void cp_aperm(char *p, struct block *blk, int next)
405
{
406
    int i, n;
407
    listtype ltab[MAX_BLOCKS];
408
    listtype len;
409
 
8195 bpr 410
    n=objnum(p,','); if(n<4) sym_error("wrong_parmcnt ins %.20s",p);
411
    if(n>=MAX_BLOCKS/2) sym_error("block_overflow %.20s",p);
10 reyssat 412
    clist.lcnt=1; len=2*n-5; clist.listlen=&len;
413
    for(i=0;i<n-2;i++) ltab[2*i]=-2;
414
    for(i=0;i<n-4;i++) ltab[2*i+1]=0;
415
    ltab[len-2]=1;
416
    clist.list=ltab;
417
    _permpick(p,n,blk,blk-blockbuf,',');
418
    blk->lstart=2;
419
}
420
 
421
void cp_apick(char *p, struct block *blk, int next)
422
{
423
    int i, n, t;
424
    char *p1;
425
    listtype ltab[MAX_BLOCKS];
426
    listtype len;
427
 
8195 bpr 428
    n=objnum(p,','); if(n<4) sym_error("wrong_parmcnt ins %.20s",p);
429
    if(n>=MAX_BLOCKS/2) sym_error("block_overflow %.20s",p);
10 reyssat 430
    p1=find_item_end(p); if(*p1) *p1++=0;
8195 bpr 431
    t=atoi(p); if(t<=0 || t>n-3) sym_error("syntax_error ins %.20s",p);
10 reyssat 432
    clist.lcnt=1; len=2*t-1; clist.listlen=&len;
433
    for(i=0;i<t;i++) ltab[2*i]=-2;
434
    for(i=0;i<t-1;i++) ltab[2*i+1]=0;
435
    ltab[len-2]=1;
436
    clist.list=ltab;
437
    _permpick(p1,n,blk,blk-blockbuf,',');
438
    blk->lstart=2;
439
}
440
 
441
void cp_dic(char *p, struct block *blk, int next)
442
{
443
    int i, n;
444
    char *p1, *p2;
445
    n=objnum(p,',');
8195 bpr 446
    if(n!=1) sym_error("wrong_parmcnt dic %.20s",p);
10 reyssat 447
    p1=find_word_start(p); p2=find_word_end(p1);
448
    if(*p2) *p2++=0;
449
    p2=find_word_start(p2);
450
    i=getdic(p1);
8195 bpr 451
    if(i<0) sym_error("bad_dictionary %.20s",p1);
10 reyssat 452
    noaddw=3;
453
    blk->string=add2cp(p2);
454
    noaddw=0;
455
    blk->len=strlen(blk->string);
456
    blk->lind1=i;
457
    blk->fn=mt_dic;
458
    blk->nextblock=next;
459
}
460
 
461
void cp_dperm(char *p, struct block *blk, int next)
462
{
463
    int n;
464
    listtype ltab[]={0,1,2,2,3,0};
465
    listtype len[]={3,3};
8161 bpr 466
 
10 reyssat 467
    clist.lcnt=2; clist.listlen=len; clist.list=ltab;
468
    n=objnum(p,',');
8195 bpr 469
    if(n!=4) sym_error("wrong_parmcnt dperm %.20s",p);
10 reyssat 470
    _permpick(p,n,blk,blk-blockbuf,',');
471
}
472
 
473
void cp_ins(char *p, struct block *blk, int next)
474
{
475
    int i, n;
476
    listtype ltab[MAX_BLOCKS];
477
    listtype len;
478
 
8195 bpr 479
    n=objnum(p,','); if(n<3) sym_error("wrong_parmcnt ins %.20s",p);
480
    if(n>=MAX_BLOCKS/2) sym_error("block_overflow %.20s",p);
10 reyssat 481
    clist.lcnt=1; len=2*n-2; clist.listlen=&len;
482
    for(i=1;i<n;i++) ltab[2*i-2]=i;
483
    for(i=1;i<len;i+=2) ltab[i]=-12;
484
    ltab[len-1]=-13;
485
    clist.list=ltab;
486
    _permpick(p,n,blk,blk-blockbuf,',');
487
    blk->lstart=1;
488
}
489
 
490
void cp_iperm(char *p, struct block *blk, int next)
491
{
492
    int n;
493
    listtype ltab[]={0,1,2,2,1,0};
494
    listtype len[]={3,3};
495
 
496
    clist.lcnt=2; clist.listlen=len; clist.list=ltab;
497
    n=objnum(p,',');
8195 bpr 498
    if(n!=3) sym_error("wrong_parmcnt iperm %.20s",p);
10 reyssat 499
    _permpick(p,n,blk,blk-blockbuf,',');
500
}
501
 
502
void cp_m(char *p, struct block *blk, int next)
503
{
504
    int i, idx;
505
    char buf[MAX_LINELEN+1];
8161 bpr 506
 
8195 bpr 507
    i=objnum(p,','); if(i!=1) sym_error("wrong_parmcnt m %.20s",p);
10 reyssat 508
    blk->fn=mt_m;
509
    blk->string=NULL;
510
    blk->len=1;
511
    blk->nextblock=next;
512
    p=find_word_start(p);singlespace(p);strip_trailing_spaces(p);
513
    for(i=0;i<Mcnt && strcmp(p,Mind[i].Mptr)!=0;i++);
8195 bpr 514
    if(nextblock >= MAX_BLOCKS-2) sym_error("block_overflow %.20s",p);
10 reyssat 515
    if(i<Mcnt) blk->sublock=Mind[i].blkptr;
516
    else {
8161 bpr 517
      i=strlen(p);
8195 bpr 518
      if(Mnext-Mbuf+i >= MAX_LINELEN-1) sym_error("Mbuf_overflow %.20s",p);
519
      if(Mcnt >= MAX_BLOCKS) sym_error("Mind_overflow %.20s",p);
8161 bpr 520
      Mind[Mcnt].Mptr=Mnext; Mind[Mcnt].blkptr=nextblock;
521
      Mcnt++;
522
      memcpy(Mnext,p,i+1); Mnext+=i+1;
523
      idx=nextblock; blk->sublock=idx; nextblock++;
524
      snprintf(buf,sizeof(buf),"%s",p);
525
      cp_cutline(buf,blockbuf+idx,-2);
526
      blockbuf[idx].mend=nextblock;
10 reyssat 527
    }
528
}
529
 
530
void cp_neg(char *p, struct block *blk, int next)
531
{
532
    int n, idx;
533
    char buf[MAX_LINELEN+1];
534
    n=objnum(p,','); if(n==0) n=1;
8195 bpr 535
    if(n>1) sym_error("wrong_parmcnt neg %.20s",p);
10 reyssat 536
    blk->fn=mt_neg;
537
    blk->len=1;
538
    blk->nextblock=next;
8195 bpr 539
    if(nextblock >= MAX_BLOCKS) sym_error("block_overflow %.20s",p);
10 reyssat 540
    idx=nextblock; blk->sublock=idx; nextblock++;
541
    snprintf(buf,sizeof(buf),"%s",p);
542
    cp_cutline(buf,blockbuf+idx,blk-blockbuf);
543
}
544
 
545
void cp_none(char *p, struct block *blk, int next)
546
{
547
    blk->fn=mt_nomatch;
548
    blk->string="";
549
    blk->nextblock=next;
550
}
551
 
552
void _pick(char *p, struct block *blk, int next, int type)
553
{
554
    int i, n, t, v;
555
    listtype ltab[MAX_BLOCKS];
556
    listtype len;
557
    char *p1;
558
 
559
    n=objnum(p,','); n--;
8195 bpr 560
    if(n<2) sym_error("wrong_parmcnt pick %.20s",p);
561
    if(n>=MAX_BLOCKS) sym_error("block_overflow %.20s",p);
10 reyssat 562
    p1=strparchr(p,','); *p1++=0;
563
    p=find_word_start(p); v=0;
564
    if(*p=='-') {p++; type-=5;}
565
    else if(*p=='+') {v=2; p++;}
8195 bpr 566
    t=atoi(p); if(t<1 || t>MAX_PICKS || t>n) sym_error("bad_pickcnt %.20s",p);
10 reyssat 567
    clist.lcnt=1; len=t+v; clist.listlen=&len;
568
    for(i=0;i<t;i++) ltab[i]=type;
569
    if(v) {ltab[i++]=-6; ltab[i]=-5;}
570
    clist.list=ltab;
571
    _permpick(p1,n,blk,blk-blockbuf,',');
572
}
573
 
574
void cp_out(char *p, struct block *blk, int next)
575
{
576
    char buf[MAX_LINELEN+1];
577
    char *p1;
578
    int n, idx;
8195 bpr 579
    n=objnum(p,','); if(n!=2) sym_error("wrong_parmcnt out %.20s",p);
10 reyssat 580
    p1=strparchr(p,','); if(p1) *p1++=0; else p1=p+strlen(p);
581
    p=find_word_start(p); *find_word_end(p)=0;
582
    noaddw=3;
583
    blk->string=add2cp(p);
584
    noaddw=0;
585
    blk->len=strlen(blk->string);
586
    blk->fn=mt_out;
587
    blk->nextblock=next;
8195 bpr 588
    if(nextblock >= MAX_BLOCKS) sym_error("block_overflow %.20s",p);
10 reyssat 589
    idx=nextblock; blk->sublock=idx; nextblock++;
590
    snprintf(buf,sizeof(buf),"%s",p1);
591
    cp_cutline(buf,blockbuf+idx,blk-blockbuf);
592
}
593
 
594
void cp_opick(char *p, struct block *blk, int next)
595
{
596
    _pick(p,blk,next,-3);
597
}
598
 
599
void cp_perm(char *p, struct block *blk, int next)
600
{
601
    int i, n;
602
    listtype ltab[MAX_BLOCKS];
603
    listtype len;
604
 
605
    n=objnum(p,','); if(n==0) n=1;
8195 bpr 606
    if(n>=MAX_BLOCKS) sym_error("block_overflow %.20s",p);
10 reyssat 607
    clist.lcnt=1; len=n; clist.listlen=&len;
608
    for(i=0;i<n;i++) ltab[i]=-2;
609
    clist.list=ltab;
610
    _permpick(p,n,blk,blk-blockbuf,',');
611
}
612
 
613
void cp_pick(char *p, struct block *blk, int next)
614
{
615
    _pick(p,blk,next,-2);
616
}
617
 
618
void cp_rep(char *p, struct block *blk, int next)
619
{
620
    int n;
621
    listtype ltab[]={-1,-5};
622
    listtype len[]={2};
623
 
624
    clist.lcnt=1; clist.listlen=len; clist.list=ltab;
625
    n=objnum(p,','); if(n==0) n=1;
626
    _permpick(p,n,blk,blk-blockbuf,',');
627
}
628
 
629
void cp_w(char *p, struct block *blk, int next)
630
{
631
    items2words(p);
632
    blk->string=add2cp(p);
633
    blk->fn=mt_w;
634
    blk->nextblock=next;
635
}
636
 
637
void cp_wild(char *p, struct block *blk, int next)
638
{
639
    int n, min, max;
640
    char *pp, *pe;
8195 bpr 641
    n=objnum(p,','); if(n!=1) sym_error("wrong_parmcnt wild %.20s\n",p);
10 reyssat 642
    blk->string="";
643
    max=min=0;
644
    for(pp=find_word_start(p); *pp; pp=find_word_start(pe)) {
8161 bpr 645
      pe=find_word_end(pp);
8195 bpr 646
      if(pp[0]!='*') sym_error("syntax_error wild %.20s\n",p);
8161 bpr 647
      if(pp[1]!='*') {
648
          min++; continue;
649
      }
650
      if(isdigit(pp[2])) max+=atoi(pp+2);
651
      else max=MAX_BLOCKS;
10 reyssat 652
    }
653
    blk->len=max;
654
    blk->lstart=min;
655
    blk->fn=mt_wild;
656
    blk->nextblock=next;
657
}
658
 
8161 bpr 659
struct builtin builtin[]={
660
      {"Alt",           cp_alt},
10 reyssat 661
        {"Aperm",       cp_aperm},
662
        {"Apick",       cp_apick},
663
        {"Dic",         cp_dic},
664
        {"Dperm",       cp_dperm},
665
        {"Ins",         cp_ins},
666
        {"Iperm",       cp_iperm},
667
        {"M",           cp_m},
668
        {"Neg",         cp_neg},
669
        {"Nomatch",     cp_none},
670
        {"None",        cp_none},
671
        {"Not",         cp_neg},
672
        {"Opick",       cp_opick},
673
        {"Out",         cp_out},
674
        {"Perm",        cp_perm},
675
        {"Pick",        cp_pick},
676
        {"Rep",         cp_rep},
677
        {"W",           cp_w},
678
        {"Wild",        cp_wild},
679
};
680
 
8161 bpr 681
int builtincnt=(sizeof(builtin)/sizeof(builtin[0]));
10 reyssat 682
 
8161 bpr 683
/* p must have MAX_LINELEN */
10 reyssat 684
void cp_oneblock(char *p, struct block *blk, int next)
685
{
686
    char *pp, *pe;
687
    int i;
3813 kbelabas 688
    if(debug>=3) fprintf(stderr,"Oneblock %d/%d for %.15s.\n",
8161 bpr 689
                   (int)(blk-blockbuf), nextblock, p);
10 reyssat 690
    if(myisupper(*p)) {
8161 bpr 691
      for(pe=p; pe-p < MAX_BINAME && myisalpha(*pe); pe++);
692
      if(*pe==':') {
693
          *pe++=0;
694
          i=search_list(builtin,builtincnt,sizeof(builtin[0]),p);
8195 bpr 695
          if(i<0) sym_error("unknown_cmd %.20s",p);
8161 bpr 696
          builtin[i].fn(pe,blk,next);
697
          blk->nextblock=next;
698
          return;
699
      }
10 reyssat 700
    }
701
    if(*p=='*') {
8161 bpr 702
      cp_wild(p,blk,next);
703
      return;
10 reyssat 704
    }
705
    pp=strparchr(p,'|'); if(pp==NULL) {
8161 bpr 706
      cp_cutline(p,blk,next);
10 reyssat 707
    }
708
    else cp_alt2(p,blk,next);
709
}
710
 
8161 bpr 711
/* p must have MAX_LINELEN */
10 reyssat 712
void compile(char *p)
713
{
714
    nextblock=1; nextlist=0;
715
    cpnext=cpbuf;
716
    memset(blockbuf,0,sizeof(blockbuf));
717
    cp_oneblock(p,blockbuf,-1);
718
    showblocks();
719
}
720