327
|
1 /* Micro-C Preprocessor Part */ /* $Id$ */
|
|
2
|
|
3 #include <stdio.h>
|
|
4 #include "mc.h"
|
|
5 #include "mc-parse.h"
|
|
6 #include "mc-macro.h"
|
|
7 #include "mc-code.h"
|
|
8
|
|
9 extern struct {int fd,ln;char *name0;int inc;FILE *fcb;} *filep,filestack[FILES];
|
|
10
|
|
11 int in_macro_if = 0;
|
|
12 char *chinput;
|
|
13
|
|
14 static char *macropp,macro_buf[MACROSIZE];
|
|
15 static int mconcat=0;
|
|
16
|
|
17 static void macro_define0();
|
|
18 static int macro_args(char **pcheapp,char *maxcheap,char **pchptr);
|
|
19 static int macro_function(int macrop,char **pchptr,NMTBL *nptr,int history);
|
|
20 static void local_define(char *macro,char *value);
|
|
21 static void local_undef(char *macro);
|
|
22 static int macro_eval(int macrop,char *body0,int history);
|
|
23 static char * mappend(int lists);
|
|
24 static int macro_processing();
|
|
25
|
|
26 static void
|
|
27 gen_source(char *s)
|
|
28 {
|
|
29 printf("%s",s);
|
|
30 }
|
|
31
|
|
32 extern void
|
|
33 macro_expansion(NMTBL *nptrm)
|
|
34 {
|
|
35 int i = mode;
|
|
36 int macrop = 0;
|
|
37 int slfree = lfree;
|
|
38 mode = STAT;
|
|
39
|
|
40 macropp = macro_buf;
|
|
41 if (nptrm->sc == FMACRO) {
|
|
42 macrop=macro_function(macrop,&chptr,nptrm,0);
|
|
43 } else {
|
|
44 macrop=macro_eval(macrop,(char *)car(nptrm->dsp),0);
|
|
45 }
|
|
46 macropp = macro_buf;
|
|
47 mappend(reverse0(macrop));
|
|
48 macropp[-1] ='\n';
|
|
49 *macropp =0;
|
|
50 while (mconcat) {
|
|
51 // ## re-eval macro
|
|
52 printf("## %s",macro_buf);
|
|
53 mconcat = 0;
|
|
54 macrop = 0;
|
|
55 macropp = macro_buf;
|
|
56 macrop=macro_eval(macrop,macro_buf,0);
|
|
57 macropp = macro_buf;
|
|
58 mappend(reverse0(macrop));
|
|
59 macropp[-1] ='\n';
|
|
60 *macropp =0;
|
|
61 }
|
|
62 mconcat = 0;
|
|
63 lfree = slfree;
|
|
64 if (lsrc && !asmf && nptrm->sc==FMACRO) gen_comment(macro_buf);
|
|
65 macropp[-1] =0;
|
|
66 if (macro_buf[0]==0) {
|
|
67 mode = i;
|
|
68 return;
|
|
69 }
|
|
70 chptrsave = glist2((int)chptr,chptrsave);
|
|
71 chsave = glist2(ch,chsave);
|
|
72 chptr = macro_buf;
|
|
73 ch = *chptr++;
|
|
74 mode = i;
|
|
75 }
|
|
76
|
|
77 /* file inclusion */
|
|
78
|
|
79 static char *
|
|
80 expand_file_name(char *path,char *name,int pos,int lbufsize)
|
|
81 {
|
|
82 char *p = name+pos;
|
|
83 int i,j;
|
|
84 j = 0;
|
|
85 for(i=0;path[i];i++,j++); for(i=0;name[i];i++,j++);
|
|
86 if (pos+j+1>lbufsize) { error(FILERR); return ""; }
|
|
87 while((name[pos++] = *path++));
|
|
88 pos--;
|
|
89 if (name[pos]!='/') name[pos]='/';
|
|
90 for(i = 0; ((name[pos++] = name[i++])););
|
|
91 return p;
|
|
92 }
|
|
93
|
|
94 static FILE *
|
|
95 getfname(void)
|
|
96 {
|
|
97 int i,end='"',err=0;
|
|
98 char *s,*p,**pp,name[LBUFSIZE];
|
|
99 FILE *fp;
|
|
100
|
|
101 getch();
|
|
102 if(skipspc()=='"') { end = '"';
|
|
103 } else if (ch=='<') { end = '>';
|
|
104 } else { error(INCERR); err=1;
|
|
105 }
|
|
106 for(i=0;(getch()!=end && ch!='\n');) {
|
|
107 if(i<LBUFSIZE-1) name[i++]=ch;
|
|
108 }
|
|
109 if(ch=='\n') error(INCERR);
|
|
110 if (err) return filep->fcb;
|
|
111 name[i]=0;
|
|
112 fp = fopen(name,"r") ;
|
|
113 if (fp) {
|
|
114 p = name;
|
|
115 } else {
|
|
116 for(pp=(end=='>'||filep->inc=='>')
|
|
117 ?l_include_path:include_path;*pp;pp++) {
|
|
118 p = expand_file_name(*pp,name,i+1,LBUFSIZE);
|
|
119 if ((fp = fopen(p,"r"))) break ;
|
|
120 }
|
|
121 }
|
|
122 if(!fp) { error(FILERR); return filep->fcb; }
|
|
123 copy_current_file_dir(s=p);
|
|
124 (filep+1)->name0 = cheapp;
|
|
125 (filep+1)->inc = end;
|
|
126 while((*cheapp++ = *s++));
|
|
127 return ( (filep+1)->fcb = fp );
|
|
128 }
|
|
129
|
|
130 /* line input and conversion */
|
|
131
|
|
132 static int macro_if_depth ;
|
|
133 static int macro_if_current ;
|
|
134 static int macro_if_skip ;
|
|
135
|
|
136 static int
|
|
137 skip_rest_of_line()
|
|
138 {
|
|
139 getch();
|
|
140 do {
|
|
141 while(ch!='\n'&&ch!='\r') {
|
|
142 if (!in_comment) {
|
|
143 if (ch=='/') {
|
|
144 getch();
|
|
145 if (ch=='/') in_comment=2;
|
|
146 else if (ch=='*') {
|
|
147 in_comment=1;
|
|
148 } else continue;
|
|
149 }
|
|
150 } else if (ch=='*') {
|
|
151 getch();
|
|
152 if (ch=='/') {
|
|
153 in_comment=0;
|
|
154 return macro_if_skip?0:1;
|
|
155 }
|
|
156 else continue;
|
|
157 }
|
|
158 getch();
|
|
159 }
|
|
160 if (in_comment==1) { getline(); getch(); }
|
|
161 } while(in_comment==1);
|
|
162 in_comment=0;
|
|
163 return 0;
|
|
164 }
|
|
165
|
|
166 extern void
|
|
167 getline(void)
|
|
168 {
|
|
169 int i;
|
|
170 int c;
|
|
171
|
|
172 do {
|
|
173 if (chinput) {
|
|
174 if (! *chinput) {
|
|
175 chinput=0;
|
|
176 continue;
|
|
177 }
|
|
178 chptr=linebuf;
|
|
179 i=0;
|
|
180 while((*chptr++=c=*chinput++)&&(c!='\n')) {
|
|
181 if (++i > LBUFSIZE-2) error(LNERR);
|
|
182 }
|
|
183 } else {
|
|
184 lineno++;
|
|
185 glineno++;
|
|
186 chptr=linebuf;
|
|
187 i=0;
|
|
188 while ((*chptr++ = c = getc(filep->fcb)) != '\n') {
|
|
189 if (++i > LBUFSIZE-2) error(LNERR);
|
|
190 if (c==EOF) {
|
|
191 error(EOFERR);
|
|
192 --chptr;
|
|
193 }
|
|
194 }
|
|
195 }
|
|
196 *chptr = '\0';
|
|
197 if (lsrc && !asmf && !macro_if_skip) gen_comment(linebuf);
|
|
198 if (*(chptr = linebuf) == '#' && !in_comment && !in_quote) {
|
|
199 if (macro_processing()) return;
|
|
200 }
|
|
201 } while(!in_quote && (macro_if_skip || linebuf[0] == '#'));
|
|
202 }
|
|
203
|
|
204 /* preprocessor directive */
|
|
205
|
|
206 /* line continuation \\ */
|
|
207
|
|
208 extern void
|
|
209 check_macro_eof()
|
|
210 {
|
|
211 int c;
|
|
212 for(c=0;c<LBUFSIZE-3&&chptr[c];c++);
|
|
213 if (c>0&&chptr[c-1]=='\\') {
|
|
214 return;
|
|
215 } else if (c>0&&chptr[c-1]=='\n') {
|
|
216 if (c>0&&chptr[c-2]=='\\') {
|
|
217 return;
|
|
218 } else {
|
|
219 c--;
|
|
220 }
|
|
221 }
|
|
222 chptr[c] = ';';
|
|
223 chptr[c+1] = '\n';
|
|
224 chptr[c+2] = 0;
|
|
225 }
|
|
226
|
|
227 static void
|
|
228 macro_if()
|
|
229 {
|
|
230 int i;
|
|
231 ch= *chptr;
|
|
232 in_macro_if = 1;
|
|
233 check_macro_eof();
|
|
234 getsym(0);
|
|
235 /* i=cexpr(expr(1)); #if allow undefined symbols.. */
|
|
236 i=expr(1);
|
|
237 in_macro_if = 0;
|
|
238 if (car(i)==CONST) i=cadr(i);
|
|
239 else i=0;
|
|
240 if (ch) {
|
|
241 if (chptr[-1]==ch) {
|
|
242 /* we are fall into getch(), which lost the last ch */
|
|
243 /* chptr[-1]==ch check is fanatic, but ... */
|
|
244 chptr--;
|
|
245 } else error(-1);
|
|
246 }
|
|
247 macro_if_depth = macro_if_current;
|
|
248 macro_if_skip = !i;
|
|
249 }
|
|
250
|
|
251 static int
|
|
252 macro_processing()
|
|
253 {
|
|
254 int i;
|
|
255 int c;
|
|
256 int mode_save;
|
|
257
|
|
258 ++chptr;
|
|
259 while (*chptr==' '||*chptr=='\t') ++chptr;
|
|
260 if (macroeq("ifdef") || macroeq("ifndef")) {
|
|
261 c = (chptr[-4]=='n');
|
|
262 macro_if_current++;
|
|
263 if (!macro_if_skip) {
|
|
264 mode_save = mode; mode = IFDEF;
|
|
265 ch= *chptr;
|
|
266 i = getsym(0);
|
|
267 mode = mode_save;
|
|
268 macro_if_depth = macro_if_current;
|
|
269 macro_if_skip = (!i)^c;
|
|
270 }
|
|
271 return 0;
|
|
272 } else if (macroeq("elif")) {
|
|
273 if (macro_if_current==0) {
|
|
274 error(MCERR); /* extra #else */
|
|
275 return 0;
|
|
276 }
|
|
277 if (macro_if_current == macro_if_depth) {
|
|
278 if (!macro_if_skip || macro_if_skip==2) {
|
|
279 macro_if_skip=2;
|
|
280 return 0;
|
|
281 }
|
|
282 macro_if();
|
|
283 }
|
|
284 return 0;
|
|
285 } else if (macroeq("if")) {
|
|
286 macro_if_current++;
|
|
287 if (!macro_if_skip) {
|
|
288 macro_if();
|
|
289 }
|
|
290 return 0;
|
|
291 } else if (macroeq("else")) {
|
|
292 if (macro_if_current==0) {
|
|
293 error(MCERR); /* extra #else */
|
|
294 return 0;
|
|
295 }
|
|
296 if (macro_if_current == macro_if_depth) {
|
|
297 if (macro_if_skip==2) ;
|
|
298 else if (macro_if_skip) macro_if_skip=0;
|
|
299 else macro_if_skip=1;
|
|
300 }
|
|
301 return skip_rest_of_line();
|
|
302 } else if (macroeq("endif")) {
|
|
303 if (macro_if_current == macro_if_depth) {
|
|
304 macro_if_skip = 0;
|
|
305 macro_if_depth = --macro_if_current;
|
|
306 } else {
|
|
307 if (macro_if_current<=0) {
|
|
308 error(MCERR); /* extra #if */
|
|
309 return 0;
|
|
310 }
|
|
311 macro_if_current--;
|
|
312 }
|
|
313 return skip_rest_of_line();
|
|
314 }
|
|
315 if (macro_if_skip) return 0;
|
|
316 if (macroeq("define")) {
|
|
317 ch= *chptr;
|
|
318 macro_define0();
|
|
319 *(chptr = linebuf) = '\0';
|
|
320 } else if (macroeq("undef")) {
|
|
321 i=mode;
|
|
322 mode=IFDEF;
|
|
323 ch= *chptr;
|
|
324 if (getsym(0)) {
|
|
325 if (nptr->sc == MACRO) {
|
|
326 nptr->sc = EMPTY;
|
|
327 } else if (nptr->sc == FMACRO) {
|
|
328 nptr->sc = EMPTY;
|
|
329 /* we cannot reclaim it's arg */
|
|
330 } else error(MCERR);
|
|
331 }
|
|
332 mode=i;
|
|
333 } else if (macroeq("include")) {
|
|
334 if(filep+1 >= filestack + FILES) error(FILERR);
|
|
335 if ( ((filep+1)->fcb=getfname()) == NULL) error(FILERR);
|
|
336 (filep+1)->ln=lineno;
|
|
337 lineno=0;
|
|
338 ++filep;
|
|
339 *(chptr = linebuf) = '\0';
|
|
340 #if ASM_CODE
|
|
341 } else if (macroeq("asm")) {
|
|
342 if (asmf) error(MCERR);
|
|
343 asmf = 1;
|
|
344 getline();
|
|
345 while (asmf) {
|
|
346 gen_source(linebuf);
|
|
347 getline();
|
|
348 }
|
|
349 } else if (macroeq("endasm")) {
|
|
350 if (!asmf) error(MCERR);
|
|
351 asmf = 0;
|
|
352 #endif
|
|
353 } else if (macroeq(" "))
|
|
354 getline();
|
|
355 else error(MCERR);
|
|
356 return 0;
|
|
357 }
|
|
358
|
|
359 extern int
|
|
360 macroeq(char *s)
|
|
361 {
|
|
362 char *p;
|
|
363
|
|
364 for (p = chptr; *s;) if (*s++ != *p++) return 0;
|
|
365 chptr = p;
|
|
366 return 1;
|
|
367 }
|
|
368
|
|
369 /* macro interpreter */
|
|
370
|
|
371 extern void
|
|
372 macro_define(char *macro)
|
|
373 {
|
|
374 char *chptr_save;
|
|
375 int chsave;
|
|
376
|
|
377 chptr_save = chptr;
|
|
378 chsave = ch;
|
|
379 chptr = macro;
|
|
380 ch= *chptr++;
|
|
381 macro_define0();
|
|
382 chptr = chptr_save;
|
|
383 ch = chsave;
|
|
384 }
|
|
385
|
|
386 static void
|
|
387 macro_define0()
|
|
388 {
|
|
389 int i,args,c;
|
|
390 char *scheapp;
|
|
391
|
|
392 i=mode;
|
|
393 mode=MDECL;
|
|
394 // ch= *chptr; ??
|
|
395 // fprintf(stderr,"macro def: ch %c *chptr %c\n",ch,*chptr);
|
|
396 getsym(0);
|
|
397 // fprintf(stderr,"macro def: %s =>",name);
|
|
398 if (nptr->sc != EMPTY) { /* override existing macro */
|
|
399 }
|
|
400 args = 0;
|
|
401 if (ch=='(') {
|
|
402 nptr->sc = FMACRO;
|
|
403 args = macro_args(&cheapp,cheap+CHEAPSIZE,&chptr);
|
|
404 } else {
|
|
405 nptr->sc = MACRO;
|
|
406 nptr->ty = -1;
|
|
407 }
|
|
408 // equal is allowed for -Dhoge=aho option
|
|
409 if (ch=='=') chptr++;
|
|
410 while((c=*chptr)==' '||c=='\t') chptr++;
|
|
411 nptr->dsp = list2((int)cheapp,args); /* macro body */
|
|
412 scheapp = cheapp;
|
|
413 while ((*cheapp++ = c = *chptr++)
|
|
414 && c != '\n') {
|
|
415 if (c=='/'&&chptr[0]=='/') {
|
|
416 cheapp--; while(*chptr++); break;
|
|
417 } else if (c=='/'&&chptr[0]=='*') {
|
|
418 cheapp--; chptr++;
|
|
419 while((c = *chptr++)) {
|
|
420 if (c=='*'&&chptr[0]=='/') {
|
|
421 c = *chptr++; break;
|
|
422 }
|
|
423 }
|
|
424 if (!c) break;
|
|
425 } else if (c=='\\' && (*chptr=='\n'||*chptr==0)) {
|
|
426 chptr++;
|
|
427 cheapp--;
|
|
428 getline();
|
|
429 }
|
|
430 }
|
|
431 *cheapp++ = '\0';
|
|
432 while(cheapp>scheapp&&(*cheapp=='\n'||*cheapp==0)) cheapp--;
|
|
433 *++cheapp = '\0'; cheapp++;
|
|
434 if (cheapp >= cheap+CHEAPSIZE) /* too late? */
|
|
435 error(STRERR);
|
|
436 // fprintf(stderr,"%s\n",(char *)car(nptr->dsp));
|
|
437 mode=i;
|
|
438 }
|
|
439
|
|
440 // create function macro argument list
|
|
441 // return list2((char*)arg,next)
|
|
442
|
|
443 static int
|
|
444 macro_args(char **pcheapp,char *maxcheap,char **pchptr)
|
|
445 {
|
|
446 int c;
|
|
447 int in_quote = 0;
|
|
448 int in_wquote = 0;
|
|
449 int plevel = 0;
|
|
450 char *cheapp = *pcheapp;
|
|
451 char *chptr = *pchptr;
|
|
452 int args = list2((int)cheapp,0);
|
|
453 for(;;) {
|
|
454 *cheapp++ = c = *chptr++;
|
|
455 if (cheapp >= maxcheap) error(MCERR);
|
|
456 if (!c) {
|
|
457 chptr--;
|
|
458 error(MCERR);
|
|
459 *pchptr = chptr;
|
|
460 *pcheapp = cheapp;
|
|
461 return reverse0(args);
|
|
462 }
|
|
463 if (in_quote) {
|
|
464 if (c=='\\') {
|
|
465 if (*chptr != '\n') {
|
|
466 *cheapp++ = *chptr++;
|
|
467 } else {
|
|
468 getline();
|
|
469 }
|
|
470 } else if (c=='\'') {
|
|
471 in_quote = 0;
|
|
472 }
|
|
473 } else if (in_wquote) {
|
|
474 if (c=='\\') {
|
|
475 if (*chptr !='\n') {
|
|
476 *cheapp++ = *chptr++;
|
|
477 } else {
|
|
478 *cheapp = '\n';
|
|
479 getline();
|
|
480 }
|
|
481 } else if (c=='"') {
|
|
482 in_wquote = 0;
|
|
483 }
|
|
484 } else if (c=='"') {
|
|
485 in_wquote = 1;
|
|
486 } else if (c=='\'') {
|
|
487 in_quote = 1;
|
|
488 } if (plevel==0) {
|
|
489 if (c==',') {
|
|
490 cheapp[-1] = 0;
|
|
491 args = list2((int)cheapp,args);
|
|
492 } else if (c==')') {
|
|
493 cheapp[-1] = 0;
|
|
494 break;
|
|
495 } else if (c=='(') {
|
|
496 plevel++;
|
|
497 } else if (c=='\\') {
|
|
498 if (*chptr=='\n') {
|
|
499 cheapp--;
|
|
500 getline();
|
|
501 }
|
|
502 // } else if (c==' '||c=='\t') {
|
|
503 // cheapp--;
|
|
504 } else if (c=='\n') {
|
|
505 cheapp--;
|
|
506 getline();
|
|
507 chptr = *pchptr;
|
|
508 }
|
|
509 } else if (c==')') {
|
|
510 plevel--;
|
|
511 } else if (c=='(') {
|
|
512 plevel++;
|
|
513 } else if (c=='\n') {
|
|
514 cheapp--;
|
|
515 getline();
|
|
516 chptr = *pchptr;
|
|
517 }
|
|
518 }
|
|
519 *pchptr = chptr;
|
|
520 *pcheapp = cheapp;
|
|
521 return reverse0(args);
|
|
522 }
|
|
523
|
|
524 /* output macro expansion result into macrobuf (macropp) */
|
|
525
|
|
526 static int
|
|
527 macro_function(int macrop,char **pchptr,NMTBL *nptr,int history)
|
|
528 {
|
|
529 int args,sargs,values,evalues;
|
|
530 char *macro;
|
|
531
|
|
532 sargs = args = cadr(nptr->dsp);
|
|
533 values = macro_args(¯opp,macro_buf+MACROSIZE,pchptr);
|
|
534 if (pchptr==&chptr) {
|
|
535 ch = *chptr++;
|
|
536 }
|
|
537 evalues = 0;
|
|
538 while(values) {
|
|
539 evalues = list2(macro_eval(0,(char *)car(values),history),evalues);
|
|
540 values = cadr(values);
|
|
541 }
|
|
542 evalues = reverse0(evalues);
|
|
543 while(args) {
|
|
544 local_define((char *)car(args),mappend(reverse0(car(evalues))));
|
|
545 /* fprintf(stderr,"%s: %s => %s\n",nptr->nm,(char *)car(args),(char *)car(msearch0((char *)car(args))->dsp)); */
|
|
546 args = cadr(args);
|
|
547 evalues = cadr(evalues);
|
|
548 }
|
|
549 macro = (char *)car(nptr->dsp);
|
|
550 macrop = macro_eval(macrop,macro,list2((int)macro,history));
|
|
551 /* fprintf(stderr,"%s: result %s => %s\n",nptr->nm,macro,(char *)car(macrop)); */
|
|
552 args = sargs;
|
|
553 while(args) {
|
|
554 local_undef((char *)car(args));
|
|
555 args = cadr(args);
|
|
556 }
|
|
557 return macrop;
|
|
558 }
|
|
559
|
|
560 static void
|
|
561 local_define(char *macro,char *value)
|
|
562 {
|
|
563 NMTBL *nptr0;
|
|
564 while(*macro==' '||*macro=='\t') macro++;
|
|
565 nptr0 = msearch0(macro);
|
|
566 /* save nptr previous contents in a list */
|
|
567 nptr0->ty=list3(nptr0->sc,nptr0->ty,nptr0->dsp);
|
|
568 /* set new value */
|
|
569 nptr0->sc=LMACRO;
|
|
570 nptr0->dsp=list2((int)value,0);
|
|
571 }
|
|
572
|
|
573 static void
|
|
574 local_undef(char *macro)
|
|
575 {
|
|
576 NMTBL *nptr0;
|
|
577 int save;
|
|
578 nptr0 = msearch0(macro);
|
|
579 save = nptr0->ty;
|
|
580 nptr0->sc=car(save);
|
|
581 nptr0->dsp=caddr(save);
|
|
582 nptr0->ty=cadr(save);
|
|
583 }
|
|
584
|
|
585 static int
|
|
586 macro_eval(int macrop,char *body0,int history)
|
|
587 {
|
|
588 int c;
|
|
589 int in_quote = 0;
|
|
590 int in_wquote = 0;
|
|
591 char *macro;
|
|
592 char *body = body0;
|
|
593 int i;
|
|
594 NMTBL *nptrm;
|
|
595 macrop = list2((int)macropp,macrop);
|
|
596 for(; (c = *body++) ;) {
|
|
597 if (macropp+1>macro_buf+MACROSIZE) error(STRERR);
|
|
598 if (in_quote) {
|
|
599 if (c=='\\') {
|
|
600 *macropp++ = c; c = *body++;
|
|
601 } else if (c=='\'') {
|
|
602 in_quote = 0;
|
|
603 }
|
|
604 } else if (in_wquote) {
|
|
605 if (c=='\\') {
|
|
606 *macropp++ = c; c = *body++;
|
|
607 } else if (c=='"') {
|
|
608 in_wquote = 0;
|
|
609 }
|
|
610 } else if (c=='"') {
|
|
611 in_wquote = 1;
|
|
612 } else if (c=='\'') {
|
|
613 in_quote = 1;
|
|
614 } else if (c=='#' && *body=='#') {
|
|
615 // name concatenation. skip ## and re-eval macro line.
|
|
616 mconcat = 1; body++; continue;
|
|
617 } else if (alpha(c)) {
|
|
618 i = 0;
|
|
619 do { namebuf[i++] = c; c=*body++;} while (alpha(c)||digit(c));
|
|
620 body--; // ungetc
|
|
621 namebuf[i]=0;
|
|
622 nptrm = msearch0(namebuf);
|
|
623 macro = (char *)car(nptrm->dsp);
|
|
624 if (nptrm->sc==LMACRO) {
|
|
625 while((*macropp++ = *macro++));
|
|
626 macropp--;
|
|
627 } else if (nptrm->sc==MACRO && neqname(namebuf,macro)) {
|
|
628 if (macro[0]==0) continue;
|
|
629 *macropp++=0;
|
|
630 macrop=macro_eval(macrop,macro,list2((int)macro,history));
|
|
631 macrop = list2((int)macropp,macrop);
|
|
632 } else if (nptrm->sc==FMACRO) {
|
|
633 if (c==' '||c=='\t') {
|
|
634 while (c==' '||c=='\t') c=*body++;
|
|
635 body--;
|
|
636 }
|
|
637 if(c!='(') error(MCERR);
|
|
638 *macropp++=0; body++;
|
|
639 macrop = macro_function(macrop,&body,nptrm,
|
|
640 list2((int)macro,history));
|
|
641 macrop = list2((int)macropp,macrop);
|
|
642 } else {
|
|
643 macro = namebuf;
|
|
644 while((*macropp++ = *macro++));
|
|
645 macropp--;
|
|
646 }
|
|
647 continue;
|
|
648 }
|
|
649 *macropp++ = c;
|
|
650 }
|
|
651 *macropp++=0;
|
|
652 return macrop;
|
|
653 }
|
|
654
|
|
655
|
|
656 static char *
|
|
657 mappend(int lists)
|
|
658 {
|
|
659 char *p;
|
|
660 char *result = macropp;
|
|
661 while(lists) {
|
|
662 if (macropp>macro_buf+MACROSIZE) error(STRERR);
|
|
663 p = (char *)car(lists);
|
|
664 while((*macropp++=*p++)) if (p[-1]=='\n') macropp[-1]=' ';
|
|
665 macropp--;
|
|
666 lists = cadr(lists);
|
|
667 }
|
|
668 macropp++;
|
|
669 return result;
|
|
670 }
|
|
671
|
|
672 /* end */
|