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
|
343
|
166 static int next_eof;
|
|
167
|
327
|
168 extern void
|
|
169 getline(void)
|
|
170 {
|
|
171 int i;
|
|
172 int c;
|
|
173
|
343
|
174 if (next_eof) {
|
|
175 next_eof=0;
|
|
176 error(EOFERR);
|
|
177 }
|
327
|
178 do {
|
|
179 if (chinput) {
|
|
180 if (! *chinput) {
|
|
181 chinput=0;
|
|
182 continue;
|
|
183 }
|
|
184 chptr=linebuf;
|
|
185 i=0;
|
|
186 while((*chptr++=c=*chinput++)&&(c!='\n')) {
|
|
187 if (++i > LBUFSIZE-2) error(LNERR);
|
|
188 }
|
|
189 } else {
|
|
190 lineno++;
|
|
191 glineno++;
|
|
192 chptr=linebuf;
|
|
193 i=0;
|
|
194 while ((*chptr++ = c = getc(filep->fcb)) != '\n') {
|
|
195 if (++i > LBUFSIZE-2) error(LNERR);
|
|
196 if (c==EOF) {
|
343
|
197 next_eof=1;
|
|
198 --chptr;
|
|
199 break;
|
327
|
200 }
|
|
201 }
|
|
202 }
|
|
203 *chptr = '\0';
|
343
|
204 if (lsrc && !asmf && !macro_if_skip && linebuf[0]) gen_comment(linebuf);
|
327
|
205 if (*(chptr = linebuf) == '#' && !in_comment && !in_quote) {
|
|
206 if (macro_processing()) return;
|
|
207 }
|
|
208 } while(!in_quote && (macro_if_skip || linebuf[0] == '#'));
|
|
209 }
|
|
210
|
|
211 /* preprocessor directive */
|
|
212
|
|
213 /* line continuation \\ */
|
|
214
|
|
215 extern void
|
|
216 check_macro_eof()
|
|
217 {
|
|
218 int c;
|
|
219 for(c=0;c<LBUFSIZE-3&&chptr[c];c++);
|
|
220 if (c>0&&chptr[c-1]=='\\') {
|
|
221 return;
|
|
222 } else if (c>0&&chptr[c-1]=='\n') {
|
|
223 if (c>0&&chptr[c-2]=='\\') {
|
|
224 return;
|
|
225 } else {
|
|
226 c--;
|
|
227 }
|
|
228 }
|
|
229 chptr[c] = ';';
|
|
230 chptr[c+1] = '\n';
|
|
231 chptr[c+2] = 0;
|
|
232 }
|
|
233
|
|
234 static void
|
|
235 macro_if()
|
|
236 {
|
|
237 int i;
|
|
238 ch= *chptr;
|
|
239 in_macro_if = 1;
|
|
240 check_macro_eof();
|
|
241 getsym(0);
|
|
242 /* i=cexpr(expr(1)); #if allow undefined symbols.. */
|
|
243 i=expr(1);
|
|
244 in_macro_if = 0;
|
|
245 if (car(i)==CONST) i=cadr(i);
|
|
246 else i=0;
|
|
247 if (ch) {
|
|
248 if (chptr[-1]==ch) {
|
|
249 /* we are fall into getch(), which lost the last ch */
|
|
250 /* chptr[-1]==ch check is fanatic, but ... */
|
|
251 chptr--;
|
|
252 } else error(-1);
|
|
253 }
|
|
254 macro_if_depth = macro_if_current;
|
|
255 macro_if_skip = !i;
|
|
256 }
|
|
257
|
|
258 static int
|
|
259 macro_processing()
|
|
260 {
|
|
261 int i;
|
|
262 int c;
|
|
263 int mode_save;
|
|
264
|
|
265 ++chptr;
|
|
266 while (*chptr==' '||*chptr=='\t') ++chptr;
|
|
267 if (macroeq("ifdef") || macroeq("ifndef")) {
|
|
268 c = (chptr[-4]=='n');
|
|
269 macro_if_current++;
|
|
270 if (!macro_if_skip) {
|
|
271 mode_save = mode; mode = IFDEF;
|
|
272 ch= *chptr;
|
|
273 i = getsym(0);
|
|
274 mode = mode_save;
|
|
275 macro_if_depth = macro_if_current;
|
|
276 macro_if_skip = (!i)^c;
|
|
277 }
|
|
278 return 0;
|
|
279 } else if (macroeq("elif")) {
|
|
280 if (macro_if_current==0) {
|
|
281 error(MCERR); /* extra #else */
|
|
282 return 0;
|
|
283 }
|
|
284 if (macro_if_current == macro_if_depth) {
|
|
285 if (!macro_if_skip || macro_if_skip==2) {
|
|
286 macro_if_skip=2;
|
|
287 return 0;
|
|
288 }
|
|
289 macro_if();
|
|
290 }
|
|
291 return 0;
|
|
292 } else if (macroeq("if")) {
|
|
293 macro_if_current++;
|
|
294 if (!macro_if_skip) {
|
|
295 macro_if();
|
|
296 }
|
|
297 return 0;
|
|
298 } else if (macroeq("else")) {
|
|
299 if (macro_if_current==0) {
|
|
300 error(MCERR); /* extra #else */
|
|
301 return 0;
|
|
302 }
|
|
303 if (macro_if_current == macro_if_depth) {
|
|
304 if (macro_if_skip==2) ;
|
|
305 else if (macro_if_skip) macro_if_skip=0;
|
|
306 else macro_if_skip=1;
|
|
307 }
|
|
308 return skip_rest_of_line();
|
|
309 } else if (macroeq("endif")) {
|
|
310 if (macro_if_current == macro_if_depth) {
|
|
311 macro_if_skip = 0;
|
|
312 macro_if_depth = --macro_if_current;
|
|
313 } else {
|
|
314 if (macro_if_current<=0) {
|
|
315 error(MCERR); /* extra #if */
|
|
316 return 0;
|
|
317 }
|
|
318 macro_if_current--;
|
|
319 }
|
|
320 return skip_rest_of_line();
|
|
321 }
|
|
322 if (macro_if_skip) return 0;
|
|
323 if (macroeq("define")) {
|
|
324 ch= *chptr;
|
|
325 macro_define0();
|
|
326 *(chptr = linebuf) = '\0';
|
|
327 } else if (macroeq("undef")) {
|
|
328 i=mode;
|
|
329 mode=IFDEF;
|
|
330 ch= *chptr;
|
|
331 if (getsym(0)) {
|
|
332 if (nptr->sc == MACRO) {
|
|
333 nptr->sc = EMPTY;
|
|
334 } else if (nptr->sc == FMACRO) {
|
|
335 nptr->sc = EMPTY;
|
|
336 /* we cannot reclaim it's arg */
|
|
337 } else error(MCERR);
|
|
338 }
|
|
339 mode=i;
|
|
340 } else if (macroeq("include")) {
|
|
341 if(filep+1 >= filestack + FILES) error(FILERR);
|
|
342 if ( ((filep+1)->fcb=getfname()) == NULL) error(FILERR);
|
|
343 (filep+1)->ln=lineno;
|
|
344 lineno=0;
|
|
345 ++filep;
|
|
346 *(chptr = linebuf) = '\0';
|
|
347 #if ASM_CODE
|
|
348 } else if (macroeq("asm")) {
|
|
349 if (asmf) error(MCERR);
|
|
350 asmf = 1;
|
|
351 getline();
|
|
352 while (asmf) {
|
|
353 gen_source(linebuf);
|
|
354 getline();
|
|
355 }
|
|
356 } else if (macroeq("endasm")) {
|
|
357 if (!asmf) error(MCERR);
|
|
358 asmf = 0;
|
|
359 #endif
|
|
360 } else if (macroeq(" "))
|
|
361 getline();
|
|
362 else error(MCERR);
|
|
363 return 0;
|
|
364 }
|
|
365
|
|
366 extern int
|
|
367 macroeq(char *s)
|
|
368 {
|
|
369 char *p;
|
|
370
|
|
371 for (p = chptr; *s;) if (*s++ != *p++) return 0;
|
|
372 chptr = p;
|
|
373 return 1;
|
|
374 }
|
|
375
|
|
376 /* macro interpreter */
|
|
377
|
|
378 extern void
|
|
379 macro_define(char *macro)
|
|
380 {
|
|
381 char *chptr_save;
|
|
382 int chsave;
|
|
383
|
|
384 chptr_save = chptr;
|
|
385 chsave = ch;
|
|
386 chptr = macro;
|
|
387 ch= *chptr++;
|
|
388 macro_define0();
|
|
389 chptr = chptr_save;
|
|
390 ch = chsave;
|
|
391 }
|
|
392
|
|
393 static void
|
|
394 macro_define0()
|
|
395 {
|
|
396 int i,args,c;
|
|
397 char *scheapp;
|
|
398
|
|
399 i=mode;
|
|
400 mode=MDECL;
|
|
401 // ch= *chptr; ??
|
|
402 // fprintf(stderr,"macro def: ch %c *chptr %c\n",ch,*chptr);
|
|
403 getsym(0);
|
|
404 // fprintf(stderr,"macro def: %s =>",name);
|
|
405 if (nptr->sc != EMPTY) { /* override existing macro */
|
|
406 }
|
|
407 args = 0;
|
|
408 if (ch=='(') {
|
|
409 nptr->sc = FMACRO;
|
|
410 args = macro_args(&cheapp,cheap+CHEAPSIZE,&chptr);
|
|
411 } else {
|
|
412 nptr->sc = MACRO;
|
|
413 nptr->ty = -1;
|
|
414 }
|
|
415 // equal is allowed for -Dhoge=aho option
|
|
416 if (ch=='=') chptr++;
|
|
417 while((c=*chptr)==' '||c=='\t') chptr++;
|
|
418 nptr->dsp = list2((int)cheapp,args); /* macro body */
|
|
419 scheapp = cheapp;
|
|
420 while ((*cheapp++ = c = *chptr++)
|
|
421 && c != '\n') {
|
|
422 if (c=='/'&&chptr[0]=='/') {
|
|
423 cheapp--; while(*chptr++); break;
|
|
424 } else if (c=='/'&&chptr[0]=='*') {
|
|
425 cheapp--; chptr++;
|
|
426 while((c = *chptr++)) {
|
|
427 if (c=='*'&&chptr[0]=='/') {
|
|
428 c = *chptr++; break;
|
|
429 }
|
|
430 }
|
|
431 if (!c) break;
|
|
432 } else if (c=='\\' && (*chptr=='\n'||*chptr==0)) {
|
|
433 chptr++;
|
|
434 cheapp--;
|
|
435 getline();
|
|
436 }
|
|
437 }
|
|
438 *cheapp++ = '\0';
|
|
439 while(cheapp>scheapp&&(*cheapp=='\n'||*cheapp==0)) cheapp--;
|
|
440 *++cheapp = '\0'; cheapp++;
|
|
441 if (cheapp >= cheap+CHEAPSIZE) /* too late? */
|
|
442 error(STRERR);
|
|
443 // fprintf(stderr,"%s\n",(char *)car(nptr->dsp));
|
|
444 mode=i;
|
|
445 }
|
|
446
|
|
447 // create function macro argument list
|
|
448 // return list2((char*)arg,next)
|
|
449
|
|
450 static int
|
|
451 macro_args(char **pcheapp,char *maxcheap,char **pchptr)
|
|
452 {
|
|
453 int c;
|
|
454 int in_quote = 0;
|
|
455 int in_wquote = 0;
|
|
456 int plevel = 0;
|
|
457 char *cheapp = *pcheapp;
|
|
458 char *chptr = *pchptr;
|
|
459 int args = list2((int)cheapp,0);
|
|
460 for(;;) {
|
|
461 *cheapp++ = c = *chptr++;
|
|
462 if (cheapp >= maxcheap) error(MCERR);
|
|
463 if (!c) {
|
|
464 chptr--;
|
|
465 error(MCERR);
|
|
466 *pchptr = chptr;
|
|
467 *pcheapp = cheapp;
|
|
468 return reverse0(args);
|
|
469 }
|
|
470 if (in_quote) {
|
|
471 if (c=='\\') {
|
|
472 if (*chptr != '\n') {
|
|
473 *cheapp++ = *chptr++;
|
|
474 } else {
|
|
475 getline();
|
|
476 }
|
|
477 } else if (c=='\'') {
|
|
478 in_quote = 0;
|
|
479 }
|
|
480 } else if (in_wquote) {
|
|
481 if (c=='\\') {
|
|
482 if (*chptr !='\n') {
|
|
483 *cheapp++ = *chptr++;
|
|
484 } else {
|
|
485 *cheapp = '\n';
|
|
486 getline();
|
|
487 }
|
|
488 } else if (c=='"') {
|
|
489 in_wquote = 0;
|
|
490 }
|
|
491 } else if (c=='"') {
|
|
492 in_wquote = 1;
|
|
493 } else if (c=='\'') {
|
|
494 in_quote = 1;
|
|
495 } if (plevel==0) {
|
|
496 if (c==',') {
|
|
497 cheapp[-1] = 0;
|
|
498 args = list2((int)cheapp,args);
|
|
499 } else if (c==')') {
|
|
500 cheapp[-1] = 0;
|
|
501 break;
|
|
502 } else if (c=='(') {
|
|
503 plevel++;
|
|
504 } else if (c=='\\') {
|
|
505 if (*chptr=='\n') {
|
|
506 cheapp--;
|
|
507 getline();
|
|
508 }
|
|
509 // } else if (c==' '||c=='\t') {
|
|
510 // cheapp--;
|
|
511 } else if (c=='\n') {
|
|
512 cheapp--;
|
|
513 getline();
|
|
514 chptr = *pchptr;
|
|
515 }
|
|
516 } else if (c==')') {
|
|
517 plevel--;
|
|
518 } else if (c=='(') {
|
|
519 plevel++;
|
|
520 } else if (c=='\n') {
|
|
521 cheapp--;
|
|
522 getline();
|
|
523 chptr = *pchptr;
|
|
524 }
|
|
525 }
|
|
526 *pchptr = chptr;
|
|
527 *pcheapp = cheapp;
|
|
528 return reverse0(args);
|
|
529 }
|
|
530
|
|
531 /* output macro expansion result into macrobuf (macropp) */
|
|
532
|
|
533 static int
|
|
534 macro_function(int macrop,char **pchptr,NMTBL *nptr,int history)
|
|
535 {
|
|
536 int args,sargs,values,evalues;
|
|
537 char *macro;
|
|
538
|
|
539 sargs = args = cadr(nptr->dsp);
|
|
540 values = macro_args(¯opp,macro_buf+MACROSIZE,pchptr);
|
|
541 if (pchptr==&chptr) {
|
|
542 ch = *chptr++;
|
|
543 }
|
|
544 evalues = 0;
|
|
545 while(values) {
|
|
546 evalues = list2(macro_eval(0,(char *)car(values),history),evalues);
|
|
547 values = cadr(values);
|
|
548 }
|
|
549 evalues = reverse0(evalues);
|
|
550 while(args) {
|
|
551 local_define((char *)car(args),mappend(reverse0(car(evalues))));
|
|
552 /* fprintf(stderr,"%s: %s => %s\n",nptr->nm,(char *)car(args),(char *)car(msearch0((char *)car(args))->dsp)); */
|
|
553 args = cadr(args);
|
|
554 evalues = cadr(evalues);
|
|
555 }
|
|
556 macro = (char *)car(nptr->dsp);
|
|
557 macrop = macro_eval(macrop,macro,list2((int)macro,history));
|
|
558 /* fprintf(stderr,"%s: result %s => %s\n",nptr->nm,macro,(char *)car(macrop)); */
|
|
559 args = sargs;
|
|
560 while(args) {
|
|
561 local_undef((char *)car(args));
|
|
562 args = cadr(args);
|
|
563 }
|
|
564 return macrop;
|
|
565 }
|
|
566
|
|
567 static void
|
|
568 local_define(char *macro,char *value)
|
|
569 {
|
|
570 NMTBL *nptr0;
|
|
571 while(*macro==' '||*macro=='\t') macro++;
|
|
572 nptr0 = msearch0(macro);
|
|
573 /* save nptr previous contents in a list */
|
|
574 nptr0->ty=list3(nptr0->sc,nptr0->ty,nptr0->dsp);
|
|
575 /* set new value */
|
|
576 nptr0->sc=LMACRO;
|
|
577 nptr0->dsp=list2((int)value,0);
|
|
578 }
|
|
579
|
|
580 static void
|
|
581 local_undef(char *macro)
|
|
582 {
|
|
583 NMTBL *nptr0;
|
|
584 int save;
|
|
585 nptr0 = msearch0(macro);
|
|
586 save = nptr0->ty;
|
|
587 nptr0->sc=car(save);
|
|
588 nptr0->dsp=caddr(save);
|
|
589 nptr0->ty=cadr(save);
|
|
590 }
|
|
591
|
|
592 static int
|
|
593 macro_eval(int macrop,char *body0,int history)
|
|
594 {
|
|
595 int c;
|
|
596 int in_quote = 0;
|
|
597 int in_wquote = 0;
|
|
598 char *macro;
|
|
599 char *body = body0;
|
|
600 int i;
|
|
601 NMTBL *nptrm;
|
|
602 macrop = list2((int)macropp,macrop);
|
|
603 for(; (c = *body++) ;) {
|
|
604 if (macropp+1>macro_buf+MACROSIZE) error(STRERR);
|
|
605 if (in_quote) {
|
|
606 if (c=='\\') {
|
|
607 *macropp++ = c; c = *body++;
|
|
608 } else if (c=='\'') {
|
|
609 in_quote = 0;
|
|
610 }
|
|
611 } else if (in_wquote) {
|
|
612 if (c=='\\') {
|
|
613 *macropp++ = c; c = *body++;
|
|
614 } else if (c=='"') {
|
|
615 in_wquote = 0;
|
|
616 }
|
|
617 } else if (c=='"') {
|
|
618 in_wquote = 1;
|
|
619 } else if (c=='\'') {
|
|
620 in_quote = 1;
|
|
621 } else if (c=='#' && *body=='#') {
|
|
622 // name concatenation. skip ## and re-eval macro line.
|
|
623 mconcat = 1; body++; continue;
|
|
624 } else if (alpha(c)) {
|
|
625 i = 0;
|
|
626 do { namebuf[i++] = c; c=*body++;} while (alpha(c)||digit(c));
|
|
627 body--; // ungetc
|
|
628 namebuf[i]=0;
|
|
629 nptrm = msearch0(namebuf);
|
|
630 macro = (char *)car(nptrm->dsp);
|
|
631 if (nptrm->sc==LMACRO) {
|
|
632 while((*macropp++ = *macro++));
|
|
633 macropp--;
|
|
634 } else if (nptrm->sc==MACRO && neqname(namebuf,macro)) {
|
|
635 if (macro[0]==0) continue;
|
|
636 *macropp++=0;
|
|
637 macrop=macro_eval(macrop,macro,list2((int)macro,history));
|
|
638 macrop = list2((int)macropp,macrop);
|
|
639 } else if (nptrm->sc==FMACRO) {
|
|
640 if (c==' '||c=='\t') {
|
|
641 while (c==' '||c=='\t') c=*body++;
|
|
642 body--;
|
|
643 }
|
|
644 if(c!='(') error(MCERR);
|
|
645 *macropp++=0; body++;
|
|
646 macrop = macro_function(macrop,&body,nptrm,
|
|
647 list2((int)macro,history));
|
|
648 macrop = list2((int)macropp,macrop);
|
|
649 } else {
|
|
650 macro = namebuf;
|
|
651 while((*macropp++ = *macro++));
|
|
652 macropp--;
|
|
653 }
|
|
654 continue;
|
|
655 }
|
|
656 *macropp++ = c;
|
|
657 }
|
|
658 *macropp++=0;
|
|
659 return macrop;
|
|
660 }
|
|
661
|
|
662
|
|
663 static char *
|
|
664 mappend(int lists)
|
|
665 {
|
|
666 char *p;
|
|
667 char *result = macropp;
|
|
668 while(lists) {
|
|
669 if (macropp>macro_buf+MACROSIZE) error(STRERR);
|
|
670 p = (char *)car(lists);
|
|
671 while((*macropp++=*p++)) if (p[-1]=='\n') macropp[-1]=' ';
|
|
672 macropp--;
|
|
673 lists = cadr(lists);
|
|
674 }
|
|
675 macropp++;
|
|
676 return result;
|
|
677 }
|
|
678
|
|
679 /* end */
|