comparison mc-macro.c @ 861:c005a392e27e

fix for Marvaricks
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 31 Mar 2014 18:33:20 +0900
parents cd0467ebee31
children e253ffedf947
comparison
equal deleted inserted replaced
860:467be346ae47 861:c005a392e27e
61 61
62 ## concatenation requires repeated replace. 62 ## concatenation requires repeated replace.
63 63
64 In macro_function and macro_eavl, 64 In macro_function and macro_eavl,
65 expand result is put into macrop local variable. 65 expand result is put into macrop local variable.
66 list3s(STRING,next,char*) 66 list3s(STRING,next,char*)
67 to generate result, mappend/reverse0 is necessary. 67 to generate result, mappend/reverse0 is necessary.
68 68
69 */ 69 */
70 70
71 extern void 71 void
72 macro_expansion(NMTBL *nptrm) 72 macro_expansion(NMTBL *nptrm)
73 { 73 {
74 int i = mode; 74 int i = mode;
75 int macrop = 0; 75 int macrop = 0;
76 int slfree = lfree; 76 int slfree = lfree;
108 // it is difficult to remove former space on the fly, 108 // it is difficult to remove former space on the fly,
109 // so multi path loop is required 109 // so multi path loop is required
110 110
111 while (mconcat) { 111 while (mconcat) {
112 // ## re-eval macro 112 // ## re-eval macro
113 if (lsrc) printf("## before %s",macropp); 113 if (lsrc) printf("## before %s",macropp);
114 mconcat = 0; 114 mconcat = 0;
115 macrop = 0; 115 macrop = 0;
116 for(s=t=macropp;*s;) { 116 for(s=t=macropp;*s;) {
117 if ((c=*s++)=='#'&&*s=='#') { 117 if ((c=*s++)=='#'&&*s=='#') {
118 if (t>s-3) t=s-2; else t--; 118 if (t>s-3) t=s-2; else t--;
119 while(*t<=' '&&t>macropp) t--; t++; 119 while(*t<=' '&&t>macropp) t--; t++;
120 for(s++;*s && *s<=' ';) s++; 120 for(s++;*s && *s<=' ';) s++;
121 continue; 121 continue;
122 } else if (c==STRING) { 122 } else if (c==STRING) {
123 c = '"'; 123 c = '"';
124 } 124 }
125 *t++=c; 125 *t++=c;
126 } 126 }
127 *t++=0; 127 *t++=0;
128 // evaluate generated result again
129 #if 0 128 #if 0
130 if (1 && lsrc) { 129 if (1 && lsrc) {
131 printf("\n### %s\n",macropp); 130 printf("\n### %s\n",macropp);
132 if (t[-2]!='\n') putchar('\n'); 131 if (t[-2]!='\n') putchar('\n');
133 } 132 }
134 #endif 133 #endif
134 // evaluate generated result again
135 macrop=macro_eval(macrop,macropp,macro_history); 135 macrop=macro_eval(macrop,macropp,macro_history);
136 cheap = reset_cheap(&scheap); 136 cheap = reset_cheap(&scheap);
137 macropp = cheap->ptr; 137 macropp = cheap->ptr;
138 // will not override evaled list 138 // will not override evaled list
139 mappend0(reverse0(macrop),&macropp); 139 mappend0(reverse0(macrop),&macropp);
140 // cheap->ptr[-1] ='\n'; 140 // cheap->ptr[-1] ='\n';
141 cheap->ptr[-1] =0; 141 cheap->ptr[-1] =0;
142 cheap->ptr[0] =0; 142 cheap->ptr[0] =0;
143 cheap = increment_cheap(cheap,&macropp); 143 cheap = increment_cheap(cheap,&macropp);
144 } 144 }
145 cheap = reset_cheap(&scheap); 145 cheap = reset_cheap(&scheap);
146 // genrated macro will be overwrited by cheap, but it's OK, again 146 // genrated macro will be overwrited by cheap, but it's OK, again
147 mconcat = 0; 147 mconcat = 0;
148 set_lfree(slfree); 148 set_lfree(slfree);
149 #if 0 149 #if 0
150 if (lsrc && !asmf && nptrm->sc==FMACRO) { 150 if (lsrc && !asmf && nptrm->sc==FMACRO) {
151 gen_comment(macropp); 151 gen_comment(macropp);
152 if (0 && t[-2]!='\n') putchar('\n'); 152 if (0 && t[-2]!='\n') putchar('\n');
153 } 153 }
154 #endif 154 #endif
155 // push previous chptr, and change it to the generate macro 155 // push previous chptr, and change it to the generate macro
156 chptrsave = glist3s(STRING,chptrsave,chptr); // push old one into the stack 156 chptrsave = glist3s(STRING,chptrsave,chptr); // push old one into the stack
157 chsave = glist2(ch,chsave); 157 chsave = glist2(ch,chsave);
162 162
163 /* file inclusion */ 163 /* file inclusion */
164 164
165 /* 165 /*
166 file name concatenation 166 file name concatenation
167 on cheap 167 on cheap
168 */ 168 */
169 169
170 static char * 170 static char *
171 expand_file_name(char *path,char *name) 171 expand_file_name(char *path,char *name)
172 { 172 {
173 char *p = cheap->ptr; 173 char *p = cheap->ptr;
174 if (! *path) return name; 174 if (! *path) return name;
175 while(( *cheap->ptr = *path++ )) cheap = increment_cheap(cheap,&p); 175 while(( *cheap->ptr = *path++ )) cheap = increment_cheap(cheap,&p);
176 if (cheap->ptr[-1]!='/') { 176 if (cheap->ptr[-1]!='/') {
177 *cheap->ptr = '/'; cheap = increment_cheap(cheap,&p); 177 *cheap->ptr = '/'; cheap = increment_cheap(cheap,&p);
178 } 178 }
179 while(( *cheap->ptr = *name++ )) cheap = increment_cheap(cheap,&p); 179 while(( *cheap->ptr = *name++ )) cheap = increment_cheap(cheap,&p);
180 *cheap->ptr = 0; 180 *cheap->ptr = 0;
181 cheap = increment_cheap(cheap,&p); 181 cheap = increment_cheap(cheap,&p);
182 return p; 182 return p;
216 current_file_name_dir / name 216 current_file_name_dir / name
217 libdir / name 217 libdir / name
218 "name" => name 218 "name" => name
219 current_file_name_dir / name 219 current_file_name_dir / name
220 include_path / name 220 include_path / name
221 (no difference?) 221 (no difference?)
222 next flag ignores the first occurence. 222 next flag ignores the first occurence.
223 */ 223 */
224 224
225 225
226 static FILE * 226 static FILE *
236 if(skipspc()=='"') { end = '"'; 236 if(skipspc()=='"') { end = '"';
237 } else if (ch=='<') { end = '>'; 237 } else if (ch=='<') { end = '>';
238 } else { error(INCERR); err=1; 238 } else { error(INCERR); err=1;
239 } 239 }
240 for(i=0;(getch()!=end && ch!='\n');) { 240 for(i=0;(getch()!=end && ch!='\n');) {
241 *cheap->ptr = ch; 241 *cheap->ptr = ch;
242 cheap = increment_cheap(cheap,&name); 242 cheap = increment_cheap(cheap,&name);
243 } 243 }
244 if(ch=='\n') error(INCERR); 244 if(ch=='\n') error(INCERR);
245 if (err) return filep->fcb; 245 if (err) return filep->fcb;
246 *cheap->ptr = 0; 246 *cheap->ptr = 0;
247 cheap = increment_cheap(cheap,&name); 247 cheap = increment_cheap(cheap,&name);
248 save_cheap(&scheap,cheap); 248 save_cheap(&scheap,cheap);
249 fp = fopen(name,"r") ; 249 fp = fopen(name,"r") ;
250 if (next && fp) { fclose(fp); fp=0; next=0; prev=name; } 250 if (next && fp) { fclose(fp); fp=0; next=0; prev=name; }
251 p = name; 251 p = name;
252 if (!fp) { 252 if (!fp) {
253 // no deferenced on "" and <>? 253 // no deferenced on "" and <>?
254 for(pp=include_path; *pp;pp++) { 254 for(pp=include_path; *pp;pp++) {
255 p = expand_file_name(*pp,name); 255 p = expand_file_name(*pp,name);
256 if(prev && nameeq(p,prev)) continue; 256 if(prev && nameeq(p,prev)) continue;
257 if ((fp = fopen(p,"r"))) { 257 if ((fp = fopen(p,"r"))) {
258 if (next) { 258 if (next) {
259 fclose(fp); fp=0; next=0; prev=p; 259 fclose(fp); fp=0; next=0; prev=p;
260 continue; 260 continue;
261 } else 261 } else
262 break ; 262 break ;
263 } 263 }
264 } 264 }
265 if (!fp /* && (end=='>'||filep->inc=='>') */ ) { // <> case only 265 if (!fp /* && (end=='>'||filep->inc=='>') */ ) { // <> case only
266 for(pp=l_include_path; *pp;pp++) { 266 for(pp=l_include_path; *pp;pp++) {
267 p = expand_file_name(*pp,name); 267 p = expand_file_name(*pp,name);
268 if(prev && nameeq(p,prev)) continue; 268 if(prev && nameeq(p,prev)) continue;
269 if ((fp = fopen(p,"r"))) { 269 if ((fp = fopen(p,"r"))) {
270 if (next) { 270 if (next) {
271 fclose(fp); fp=0; next=0; prev=p; 271 fclose(fp); fp=0; next=0; prev=p;
272 continue; 272 continue;
273 } else 273 } else
274 break ; 274 break ;
275 } 275 }
276 } 276 }
277 } 277 }
278 } 278 }
279 if(!fp) { error(FILERR); return filep->fcb; } 279 if(!fp) { error(FILERR); return filep->fcb; }
280 // we have so search current directory of the included file 280 // we have so search current directory of the included file
281 // keep track the name 281 // keep track the name
282 copy_current_file_dir(s=p); 282 copy_current_file_dir(s=p);
283 // File name determined. Dispose extra copies. 283 // File name determined. Dispose extra copies.
284 cheap = reset_cheap(&scheap); 284 cheap = reset_cheap(&scheap);
285 // Generated name needs copy. 285 // Generated name needs copy.
286 if (p!=name) { 286 if (p!=name) {
287 name = cheap->ptr; 287 name = cheap->ptr;
288 while((*cheap->ptr = *s++)) cheap = increment_cheap(cheap,&name); 288 while((*cheap->ptr = *s++)) cheap = increment_cheap(cheap,&name);
289 *cheap->ptr = 0; 289 *cheap->ptr = 0;
290 cheap = increment_cheap(cheap,&name); 290 cheap = increment_cheap(cheap,&name);
291 } 291 }
292 // should check filep over flow (sigh...) 292 // should check filep over flow (sigh...)
293 (filep+1)->inc = end; 293 (filep+1)->inc = end;
294 (filep+1)->name0 = name; 294 (filep+1)->name0 = name;
295 return ( (filep+1)->fcb = fp ); 295 return ( (filep+1)->fcb = fp );
300 static int macro_if_depth ; 300 static int macro_if_depth ;
301 static int macro_if_current ; 301 static int macro_if_current ;
302 static int macro_if_skip ; 302 static int macro_if_skip ;
303 303
304 /* there may extra non-terminate comment after #if/#else directive */ 304 /* there may extra non-terminate comment after #if/#else directive */
305 /* #endif / * hoge */ 305 /* #endif / * hoge */
306 /* */ 306 /* */
307 /* */ 307 /* */
308 308
309 static int 309 static int
310 skip_rest_of_line() 310 skip_rest_of_line()
311 { 311 {
312 getch(); 312 getch();
313 do { 313 do {
314 while(ch!='\n'&&ch!='\r') { 314 while(ch!='\n'&&ch!='\r') {
315 if (!in_comment) { 315 if (!in_comment) {
316 if (ch=='/') { 316 if (ch=='/') {
317 getch(); 317 getch();
318 if (ch=='/') in_comment=2; 318 if (ch=='/') in_comment=2;
319 else if (ch=='*') { 319 else if (ch=='*') {
320 in_comment=1; 320 in_comment=1;
321 } else continue; 321 } else continue;
322 } 322 }
323 } else if (ch=='*') { 323 } else if (ch=='*') {
324 getch(); 324 getch();
325 if (ch=='/') { 325 if (ch=='/') {
326 in_comment=0; 326 in_comment=0;
327 return macro_if_skip?0:1; 327 return macro_if_skip?0:1;
328 } 328 }
329 else continue; 329 else continue;
330 } 330 }
331 getch(); 331 getch();
332 } 332 }
333 if (in_comment==1) { getline1(); getch(); } 333 if (in_comment==1) { getline1(); getch(); }
334 } while(in_comment==1); 334 } while(in_comment==1);
335 in_comment=0; 335 in_comment=0;
336 return 0; 336 return 0;
337 } 337 }
338 338
339 /* 339 /*
340 getline1 from chptr or chinput (for internal source) 340 getline1 from chptr or chinput (for internal source)
341 with macro processing 341 with macro processing
342 generate comment 342 generate comment
343 generate ST_COMMENT parse tree, in inline mode 343 generate ST_COMMENT parse tree, in inline mode
344 In getch, if chptr is empty, pop chptr stack, if stack is empy 344 In getch, if chptr is empty, pop chptr stack, if stack is empy
345 read from fp. 345 read from fp.
346 */ 346 */
347 347
348 static int next_eof; 348 static int next_eof;
357 int c = 0; 357 int c = 0;
358 char num[10]; // for 32bit 358 char num[10]; // for 32bit
359 char *p; 359 char *p;
360 360
361 if (next_eof) { 361 if (next_eof) {
362 next_eof=0; 362 next_eof=0;
363 error(EOFERR); 363 error(EOFERR);
364 } 364 }
365 do { 365 do {
366 if (chinput) { 366 if (chinput) {
367 // some another input source ( init string ) 367 // some another input source ( init string )
368 if (! *chinput) { 368 if (! *chinput) {
369 chinput=0; 369 chinput=0;
370 continue; 370 continue;
371 } 371 }
372 chptr=linebuf; 372 chptr=linebuf;
373 i=0; 373 i=0;
374 while((*chptr++=c=*chinput++)&&(c!='\n')) { 374 while((*chptr++=c=*chinput++)&&(c!='\n')) {
375 if (++i > LBUFSIZE-2) error(LNERR); 375 if (++i > LBUFSIZE-2) error(LNERR);
376 } 376 }
377 } else { 377 } else {
378 // get the line from input stream 378 // get the line from input stream
379 lineno++; 379 lineno++;
380 glineno++; 380 glineno++;
381 chptr=linebuf; 381 chptr=linebuf;
382 i=0; 382 i=0;
383 while ((*chptr++ = c = getc(filep->fcb)) != '\n') { 383 while ((*chptr++ = c = getc(filep->fcb)) != '\n') {
384 if (++i > LBUFSIZE-2) error(LNERR); 384 if (++i > LBUFSIZE-2) error(LNERR);
385 if (c=='\r') { 385 if (c=='\r') {
386 c = getc(filep->fcb); 386 c = getc(filep->fcb);
387 if (c == '\n') { 387 if (c == '\n') {
388 chptr[-1]='\n'; break; 388 chptr[-1]='\n'; break;
389 } else { 389 } else {
390 // single cr equal to nl 390 // single cr equal to nl
391 ungetc(c,filep->fcb); 391 ungetc(c,filep->fcb);
392 chptr[-1]=c='\n'; i--; break; 392 chptr[-1]=c='\n'; i--; break;
393 } 393 }
394 } 394 }
395 if (c==EOF) { 395 if (c==EOF) {
396 next_eof=1; 396 next_eof=1;
397 --chptr; 397 --chptr;
398 break; 398 break;
399 } 399 }
400 } 400 }
401 } 401 }
402 402
403 *chptr = '\0'; 403 *chptr = '\0';
404 if (lsrc && !asmf && !macro_if_skip && linebuf[0]) { 404 if (lsrc && !asmf && !macro_if_skip && linebuf[0]) {
405 if (!inmode) 405 if (!inmode)
406 gen_comment(linebuf); // #if ed line will not be commented 406 gen_comment(linebuf); // #if ed line will not be commented
407 if (inmode) { 407 if (inmode) {
408 // inline mode 408 // inline mode
409 409
410 // generate inlined line in assembler output 410 // generate inlined line in assembler output
411 411
412 int i=0; 412 int i=0;
413 int c; 413 int c;
414 // should be done in some init 414 // should be done in some init
415 if (!st_cheap) { 415 if (!st_cheap) {
416 st_cheap = cheap1 = new_cheap(); 416 st_cheap = cheap1 = new_cheap();
417 } 417 }
418 418
419 p = st_cheap->ptr; 419 p = st_cheap->ptr;
420 sprintf(num,"%d: ",lineno); 420 sprintf(num,"%d: ",lineno);
421 parse = list4n(ST_COMMENT,parse,lineno,(NMTBL*)p); 421 parse = list4n(ST_COMMENT,parse,lineno,(NMTBL*)p);
422 // should contain file name 422 // should contain file name
423 c = 0; 423 c = 0;
424 while((*st_cheap->ptr = num[c++])) 424 while((*st_cheap->ptr = num[c++]))
425 st_cheap = increment_cheap(st_cheap,&p); 425 st_cheap = increment_cheap(st_cheap,&p);
426 while((c = *st_cheap->ptr = linebuf[i++])) { 426 while((c = *st_cheap->ptr = linebuf[i++])) {
427 st_cheap = increment_cheap(st_cheap,&p); 427 st_cheap = increment_cheap(st_cheap,&p);
428 if (c=='\n') { 428 if (c=='\n') {
429 *st_cheap->ptr = 0; 429 *st_cheap->ptr = 0;
430 st_cheap = increment_cheap(st_cheap,&p); 430 st_cheap = increment_cheap(st_cheap,&p);
431 p = st_cheap->ptr; 431 p = st_cheap->ptr;
432 // parse = list3n(ST_COMMENT,parse,(NMTBL*)p); 432 // parse = list3n(ST_COMMENT,parse,(NMTBL*)p);
433 sprintf(num,"%d: ",lineno); 433 sprintf(num,"%d: ",lineno);
434 c = 0; 434 c = 0;
435 while((*cheap->ptr = num[c++])) 435 while((*cheap->ptr = num[c++]))
436 st_cheap = increment_cheap(st_cheap,&p); 436 st_cheap = increment_cheap(st_cheap,&p);
437 } 437 }
438 } 438 }
439 } 439 }
440 } 440 }
441 p = chptr = linebuf; while(*p==' '||*p=='\t') p++; 441 p = chptr = linebuf; while(*p==' '||*p=='\t') p++;
442 if (*p == '#' && !in_comment && !in_quote) { 442 if (*p == '#' && !in_comment && !in_quote) {
443 // macro directive 443 // macro directive
444 chptr = p; 444 chptr = p;
445 if (macro_processing()) return; 445 if (macro_processing()) return;
446 } 446 }
447 if (c==EOF) break; 447 if (c==EOF) break;
448 } while(!in_quote && (macro_if_skip || linebuf[0] == '#')); 448 } while(!in_quote && (macro_if_skip || linebuf[0] == '#'));
449 } 449 }
450 450
451 /* preprocessor directive */ 451 /* preprocessor directive */
452 452
457 { 457 {
458 int c; 458 int c;
459 // can't be in macro expansion 459 // can't be in macro expansion
460 for(c=0;c<LBUFSIZE-3&&chptr[c];c++); 460 for(c=0;c<LBUFSIZE-3&&chptr[c];c++);
461 if (c>0&&chptr[c-1]=='\\') { 461 if (c>0&&chptr[c-1]=='\\') {
462 return; 462 return;
463 } else if (c>0&&chptr[c-1]=='\n') { 463 } else if (c>0&&chptr[c-1]=='\n') {
464 if (c>0&&chptr[c-2]=='\\') { 464 if (c>0&&chptr[c-2]=='\\') {
465 return; 465 return;
466 } else { 466 } else {
467 c--; 467 c--;
468 } 468 }
469 } 469 }
470 chptr[c] = ';'; 470 chptr[c] = ';';
471 chptr[c+1] = '\n'; 471 chptr[c+1] = '\n';
472 chptr[c+2] = 0; 472 chptr[c+2] = 0;
473 } 473 }
487 if (inmode) i = pexpr(i); // it contain const value only 487 if (inmode) i = pexpr(i); // it contain const value only
488 in_macro_if = 0; 488 in_macro_if = 0;
489 if (car(i)==CONST) i=cadr(i); 489 if (car(i)==CONST) i=cadr(i);
490 else i=0; 490 else i=0;
491 if (ch) { 491 if (ch) {
492 if (chptr[-1]==ch) { 492 if (chptr[-1]==ch) {
493 /* we are fall into getch(), which lost the last ch */ 493 /* we are fall into getch(), which lost the last ch */
494 /* chptr[-1]==ch check is fanatic, but ... */ 494 /* chptr[-1]==ch check is fanatic, but ... */
495 chptr--; 495 chptr--;
496 } else error(-1); 496 } else error(-1);
497 } 497 }
498 macro_if_depth = macro_if_current; 498 macro_if_depth = macro_if_current;
499 macro_if_skip = !i; 499 macro_if_skip = !i;
500 type=stype; 500 type=stype;
501 } 501 }
517 517
518 ++chptr; 518 ++chptr;
519 while (*chptr==' '||*chptr=='\t') ++chptr; 519 while (*chptr==' '||*chptr=='\t') ++chptr;
520 switch(chptr[0]*chptr[1]) { 520 switch(chptr[0]*chptr[1]) {
521 case 'i'*'f': 521 case 'i'*'f':
522 if ((macroeq("ifdef") || macroeq("ifndef"))) { 522 if ((macroeq("ifdef") || macroeq("ifndef"))) {
523 c = (chptr[-4]=='n'); 523 c = (chptr[-4]=='n');
524 macro_if_current++; 524 macro_if_current++;
525 if (!macro_if_skip) { 525 if (!macro_if_skip) {
526 // try getsym in IFDEF mode to avoid symbol define 526 // try getsym in IFDEF mode to avoid symbol define
527 mode_save = mode; mode = IFDEF; 527 mode_save = mode; mode = IFDEF;
528 ch= *chptr; 528 ch= *chptr;
529 i = getsym(0); 529 i = getsym(0);
530 mode = mode_save; 530 mode = mode_save;
531 macro_if_depth = macro_if_current; 531 macro_if_depth = macro_if_current;
532 macro_if_skip = (!i)^c; 532 macro_if_skip = (!i)^c;
533 } 533 }
534 return 0; 534 return 0;
535 } else if (macroeq("if")) { 535 } else if (macroeq("if")) {
536 macro_if_current++; 536 macro_if_current++;
537 if (!macro_if_skip) { 537 if (!macro_if_skip) {
538 macro_if(); 538 macro_if();
539 } 539 }
540 return 0; 540 return 0;
541 } 541 }
542 break; 542 break;
543 case 'e'*'l': 543 case 'e'*'l':
544 if (macroeq("elif")) { 544 if (macroeq("elif")) {
545 if (macro_if_current==0) { 545 if (macro_if_current==0) {
546 error(MCERR); /* extra #else */ 546 error(MCERR); /* extra #else */
547 return 0; 547 return 0;
548 } 548 }
549 if (macro_if_current == macro_if_depth) { 549 if (macro_if_current == macro_if_depth) {
550 if (!macro_if_skip || macro_if_skip==2) { 550 if (!macro_if_skip || macro_if_skip==2) {
551 macro_if_skip=2; 551 macro_if_skip=2;
552 return 0; 552 return 0;
553 } 553 }
554 macro_if(); 554 macro_if();
555 } 555 }
556 return 0; 556 return 0;
557 } else if (macroeq("else")) { 557 } else if (macroeq("else")) {
558 if (macro_if_current==0) { 558 if (macro_if_current==0) {
559 error(MCERR); /* extra #else */ 559 error(MCERR); /* extra #else */
560 return 0; 560 return 0;
561 } 561 }
562 if (macro_if_current == macro_if_depth) { 562 if (macro_if_current == macro_if_depth) {
563 if (macro_if_skip==2) ; 563 if (macro_if_skip==2) ;
564 else if (macro_if_skip) macro_if_skip=0; 564 else if (macro_if_skip) macro_if_skip=0;
565 else macro_if_skip=1; 565 else macro_if_skip=1;
566 } 566 }
567 return skip_rest_of_line(); 567 return skip_rest_of_line();
568 } 568 }
569 break; 569 break;
570 case 'e'*'n': 570 case 'e'*'n':
571 if (macroeq("endif")) { 571 if (macroeq("endif")) {
572 if (macro_if_current == macro_if_depth) { 572 if (macro_if_current == macro_if_depth) {
573 macro_if_skip = 0; 573 macro_if_skip = 0;
574 macro_if_depth = --macro_if_current; 574 macro_if_depth = --macro_if_current;
575 } else { 575 } else {
576 if (macro_if_current<=0) { 576 if (macro_if_current<=0) {
577 error(MCERR); /* extra #if */ 577 error(MCERR); /* extra #if */
578 return 0; 578 return 0;
579 } 579 }
580 macro_if_current--; 580 macro_if_current--;
581 } 581 }
582 return skip_rest_of_line(); 582 return skip_rest_of_line();
583 } 583 }
584 } 584 }
585 if (macro_if_skip) return 0; 585 if (macro_if_skip) return 0;
586 switch(chptr[0]) { 586 switch(chptr[0]) {
587 case 'd': 587 case 'd':
588 if (macroeq("define")) { 588 if (macroeq("define")) {
589 ch= *chptr; 589 ch= *chptr;
590 macro_define0(); 590 macro_define0();
591 *(chptr = linebuf) = '\0'; 591 *(chptr = linebuf) = '\0';
592 return 0; 592 return 0;
593 } 593 }
594 break; 594 break;
595 case 'u': 595 case 'u':
596 if (macroeq("undef")) { 596 if (macroeq("undef")) {
597 i=mode; 597 i=mode;
598 mode=IFDEF; 598 mode=IFDEF;
599 ch= *chptr; 599 ch= *chptr;
600 if (getsym(0)) { 600 if (getsym(0)) {
601 // make it EMPTY 601 // make it EMPTY
602 if (nptr->sc == MACRO) { 602 if (nptr->sc == MACRO) {
603 nptr->sc = EMPTY; 603 nptr->sc = EMPTY;
604 } else if (nptr->sc == FMACRO) { 604 } else if (nptr->sc == FMACRO) {
605 nptr->sc = EMPTY; 605 nptr->sc = EMPTY;
606 /* we cannot reclaim it's arg */ 606 /* we cannot reclaim it's arg */
607 } else error(MCERR); 607 } else error(MCERR);
608 } 608 }
609 mode=i; 609 mode=i;
610 return 0; 610 return 0;
611 } 611 }
612 break; 612 break;
613 case 'i': 613 case 'i':
614 next = 1; 614 next = 1;
615 if (macroeq("include_next")|| (next=0, macroeq("include"))) { 615 if (macroeq("include_next")|| (next=0, macroeq("include"))) {
616 if(filep+1 >= filestack + FILES) error(FILERR); 616 if(filep+1 >= filestack + FILES) error(FILERR);
617 if ( ((filep+1)->fcb=getfname(next)) == NULL) error(FILERR); 617 if ( ((filep+1)->fcb=getfname(next)) == NULL) error(FILERR);
618 (filep+1)->ln=lineno; 618 (filep+1)->ln=lineno;
619 lineno=0; 619 lineno=0;
620 ++filep; 620 ++filep;
621 *(chptr = linebuf) = '\0'; 621 *(chptr = linebuf) = '\0';
622 return 0; 622 return 0;
623 } 623 }
624 break; 624 break;
625 case 'p': 625 case 'p':
626 if (macroeq("pragma")) { 626 if (macroeq("pragma")) {
627 getline1(); 627 getline1();
628 return 0; 628 return 0;
629 } 629 }
630 break; 630 break;
631 #if ASM_CODE 631 #if ASM_CODE
632 // deprecated, use asm function 632 // deprecated, use asm function
633 case 'a': 633 case 'a':
634 if (macroeq("asm")) { 634 if (macroeq("asm")) {
635 if (asmf) error(MCERR); 635 if (asmf) error(MCERR);
636 asmf = 1; 636 asmf = 1;
637 getline1(); 637 getline1();
638 while (asmf) { 638 while (asmf) {
639 printf("%s",linebuf); 639 printf("%s",linebuf);
640 getline1(); 640 getline1();
641 } 641 }
642 return 0; 642 return 0;
643 } 643 }
644 break; 644 break;
645 case 'e': 645 case 'e':
646 if (macroeq("endasm")) { 646 if (macroeq("endasm")) {
647 if (!asmf) error(MCERR); 647 if (!asmf) error(MCERR);
648 asmf = 0; 648 asmf = 0;
649 return 0; 649 return 0;
650 } 650 }
651 break; 651 break;
652 #endif 652 #endif
653 case ' ': case '\t': case '\n': case 0: 653 case ' ': case '\t': case '\n': case 0:
654 getline1(); 654 getline1();
655 return 0; 655 return 0;
656 } 656 }
657 error(MCERR); 657 error(MCERR);
658 return 0; 658 return 0;
659 } 659 }
660 660
688 } 688 }
689 689
690 /* macro define from chptr 690 /* macro define from chptr
691 691
692 body will be copied and stored in nptr->dsp 692 body will be copied and stored in nptr->dsp
693 list3s( STRING, list of argments (if any), char *) 693 list3s( STRING, list of argments (if any), char *)
694 We don't expand macro here, it just copied. 694 We don't expand macro here, it just copied.
695 695
696 */ 696 */
697 697
698 static void 698 static void
709 // fprintf(stderr,"macro def: %s =>",name); 709 // fprintf(stderr,"macro def: %s =>",name);
710 if (nptr->sc != EMPTY) { /* override existing macro */ 710 if (nptr->sc != EMPTY) { /* override existing macro */
711 } 711 }
712 args = 0; 712 args = 0;
713 if (ch=='(') { 713 if (ch=='(') {
714 nptr->sc = FMACRO; 714 nptr->sc = FMACRO;
715 args = macro_args(&chptr); 715 args = macro_args(&chptr);
716 } else { 716 } else {
717 nptr->sc = MACRO; 717 nptr->sc = MACRO;
718 nptr->ty = -1; 718 nptr->ty = -1;
719 } 719 }
720 // equal is allowed for -Dhoge=aho option 720 // equal is allowed for -Dhoge=aho option
721 // if (ch=='=') chptr++; 721 // if (ch=='=') chptr++;
722 while((c=*chptr)==' '||c=='\t') chptr++; 722 while((c=*chptr)==' '||c=='\t') chptr++;
723 nptr->dsp = list3s(MACRO,args,cheap->ptr); /* macro body */ 723 nptr->dsp = list3s(MACRO,args,cheap->ptr); /* macro body */
724 body = (char **)&scaddr(nptr->dsp); 724 body = (char **)&scaddr(nptr->dsp);
725 725
726 // now copy it to the body 726 // now copy it to the body
727 while ((*cheap->ptr = c = *chptr++) 727 while ((*cheap->ptr = c = *chptr++)
728 && c != '\n') { 728 && c != '\n') {
729 cheap = increment_cheap(cheap,body); 729 cheap = increment_cheap(cheap,body);
730 if (c=='/'&&chptr[0]=='/') { 730 if (c=='/'&&chptr[0]=='/') {
731 cheap->ptr--; 731 cheap->ptr--;
732 *cheap->ptr = '\0'; 732 *cheap->ptr = '\0';
733 while(*chptr++); break; 733 while(*chptr++)
734 } else if (c=='/'&&chptr[0]=='*') { 734 ;
735 cheap->ptr--; chptr++; 735 break;
736 for(;;) { 736 } else if (c=='/'&&chptr[0]=='*') {
737 c = *chptr++; 737 cheap->ptr--; chptr++;
738 if (!c) { 738 for(;;) {
739 getline1(); 739 c = *chptr++;
740 continue; 740 if (!c) {
741 } 741 getline1();
742 if (c=='*'&&chptr[0]=='/') { 742 continue;
743 c = *chptr++; break; 743 }
744 } 744 if (c=='*'&&chptr[0]=='/') {
745 } 745 c = *chptr++; break;
746 if (!c) break; 746 }
747 } else if (c=='\\' && (*chptr=='\n'||*chptr==0)) { 747 }
748 chptr++; 748 if (!c) break;
749 cheap->ptr--; 749 } else if (c=='\\' && (*chptr=='\n'||*chptr==0)) {
750 getline1(); 750 chptr++;
751 } 751 cheap->ptr--;
752 getline1();
753 }
752 } 754 }
753 if (c=='\n') { 755 if (c=='\n') {
754 *cheap->ptr = '\0'; 756 *cheap->ptr = '\0';
755 } 757 }
756 cheap = increment_cheap(cheap,body); 758 cheap = increment_cheap(cheap,body);
757 // fprintf(stderr,"%s\n",(char *)car(nptr->dsp)); 759 // fprintf(stderr,"%s\n",(char *)car(nptr->dsp));
758 mode=i; 760 mode=i;
759 } 761 }
774 char *chptr = *pchptr; 776 char *chptr = *pchptr;
775 int args = glist3s(STRING,0,cheap->ptr); 777 int args = glist3s(STRING,0,cheap->ptr);
776 body = (char **)&scaddr(args); 778 body = (char **)&scaddr(args);
777 for(;;) { 779 for(;;) {
778 *cheap->ptr = c = *chptr++; 780 *cheap->ptr = c = *chptr++;
779 cheap = increment_cheap(cheap,body); 781 cheap = increment_cheap(cheap,body);
780 if (c=='\\') { 782 if (c=='\\') {
781 if (*chptr=='\n') { 783 if (*chptr=='\n') {
782 cheap->ptr--; 784 cheap->ptr--;
783 getline1(); 785 getline1();
784 chptr = *pchptr; 786 chptr = *pchptr;
785 continue; 787 continue;
786 } 788 }
787 } 789 }
788 if (!c) { 790 if (!c) {
789 chptr--; 791 chptr--;
790 error(MCERR); 792 error(MCERR);
791 *pchptr = chptr; 793 *pchptr = chptr;
792 return reverse0(args); 794 return reverse0(args);
793 } 795 }
794 if (in_quote) { 796 if (in_quote) {
795 if (c=='\\') { 797 if (c=='\\') {
796 if (*chptr != '\n') { 798 if (*chptr != '\n') {
797 *cheap->ptr = *chptr++; 799 *cheap->ptr = *chptr++;
798 cheap = increment_cheap(cheap,body); 800 cheap = increment_cheap(cheap,body);
799 } else { 801 } else {
800 getline1(); 802 getline1();
801 chptr = *pchptr; 803 chptr = *pchptr;
802 } 804 }
803 } else if (c=='\'') { 805 } else if (c=='\'') {
804 in_quote = 0; 806 in_quote = 0;
805 } 807 }
806 } else if (in_wquote) { 808 } else if (in_wquote) {
807 if (c=='\\') { 809 if (c=='\\') {
808 if (*chptr !='\n') { 810 if (*chptr !='\n') {
809 *cheap->ptr = *chptr++; 811 *cheap->ptr = *chptr++;
810 cheap = increment_cheap(cheap,body); 812 cheap = increment_cheap(cheap,body);
811 } else { 813 } else {
812 *cheap->ptr = '\n'; 814 *cheap->ptr = '\n';
813 getline1(); 815 getline1();
814 chptr = *pchptr; 816 chptr = *pchptr;
815 } 817 }
816 } else if (c=='"') { 818 } else if (c=='"') {
817 in_wquote = 0; 819 in_wquote = 0;
818 } 820 }
819 } else if (c=='"') { 821 } else if (c=='"') {
820 in_wquote = 1; 822 in_wquote = 1;
821 } else if (c=='\'') { 823 } else if (c=='\'') {
822 in_quote = 1; 824 in_quote = 1;
823 } if (plevel==0) { 825 } if (plevel==0) {
824 if (c==',') { 826 if (c==',') {
825 cheap->ptr[-1] = 0; 827 cheap->ptr[-1] = 0;
826 args = list3s(STRING,args,cheap->ptr); 828 args = list3s(STRING,args,cheap->ptr);
827 body = (char **)&scaddr(args); 829 body = (char **)&scaddr(args);
828 } else if (c==')') { 830 } else if (c==')') {
829 cheap->ptr[-1] = 0; 831 cheap->ptr[-1] = 0;
830 break; 832 break;
831 } else if (c=='(') { 833 } else if (c=='(') {
832 plevel++; 834 plevel++;
833 } else if (c=='\\') { 835 } else if (c=='\\') {
834 if (*chptr=='\n') { 836 if (*chptr=='\n') {
835 cheap->ptr--; 837 cheap->ptr--;
836 getline1(); 838 getline1();
837 chptr = *pchptr; 839 chptr = *pchptr;
838 } 840 }
839 // } else if (c==' '||c=='\t') { 841 // } else if (c==' '||c=='\t') {
840 // cheap->ptr--; 842 // cheap->ptr--;
841 } else if (c=='\n') { 843 } else if (c=='\n') {
842 cheap->ptr--; 844 cheap->ptr--;
843 getline1(); 845 getline1();
844 chptr = *pchptr; 846 chptr = *pchptr;
845 } 847 }
846 } else if (c==')') { 848 } else if (c==')') {
847 plevel--; 849 plevel--;
848 } else if (c=='(') { 850 } else if (c=='(') {
849 plevel++; 851 plevel++;
850 } else if (c=='\n') { 852 } else if (c=='\n') {
851 cheap->ptr--; 853 cheap->ptr--;
852 getline1(); 854 getline1();
853 chptr = *pchptr; 855 chptr = *pchptr;
854 } 856 }
855 } 857 }
856 *pchptr = chptr; 858 *pchptr = chptr;
857 return reverse0(args); 859 return reverse0(args);
858 } 860 }
859 861
871 873
872 // make argument list 874 // make argument list
873 sargs = args = cadr(nptr->dsp); 875 sargs = args = cadr(nptr->dsp);
874 values = macro_args(pchptr); 876 values = macro_args(pchptr);
875 if (pchptr==&chptr) { 877 if (pchptr==&chptr) {
876 getch(); 878 getch();
877 // ch = *chptr++; 879 // ch = *chptr++;
878 } 880 }
879 // eval all argument list 881 // eval all argument list
880 int evalues = 0; 882 int evalues = 0;
881 int values0 = values; 883 int values0 = values;
882 while(values) { 884 while(values) {
890 // #define arg1 arg2_value .... 892 // #define arg1 arg2_value ....
891 enter_scope(); 893 enter_scope();
892 while(args) { 894 while(args) {
893 mappend0(reverse0(car(evalues)),&macro); 895 mappend0(reverse0(car(evalues)),&macro);
894 local_define(scaddr(args),macro, scaddr(values)); 896 local_define(scaddr(args),macro, scaddr(values));
895 args = cadr(args); 897 args = cadr(args);
896 evalues = cadr(evalues); 898 evalues = cadr(evalues);
897 values = cadr(values); 899 values = cadr(values);
898 } 900 }
899 // process body replacement 901 // process body replacement
900 macro = scaddr(nptr->dsp); 902 macro = scaddr(nptr->dsp);
901 macrop = macro_eval(macrop,macro,glist3s(STRING,history,nptr->nm)); 903 macrop = macro_eval(macrop,macro,glist3s(STRING,history,nptr->nm));
902 args = sargs; 904 args = sargs;
931 static int 933 static int
932 next_concat(int c, char *body) 934 next_concat(int c, char *body)
933 { 935 {
934 if (c=='#' && body[0]=='#') return 1; 936 if (c=='#' && body[0]=='#') return 1;
935 while((c=*body++)) { 937 while((c=*body++)) {
936 if (c=='#' && body[0]=='#') return 1; 938 if (c=='#' && body[0]=='#') return 1;
937 if (c!=' ' && c!='\t' && c!='\n') return 0; 939 if (c!=' ' && c!='\t' && c!='\n') return 0;
938 } 940 }
939 return 0; 941 return 0;
940 } 942 }
941 943
942 /* 944 /*
943 Evaluate macro string. 945 Evaluate macro string.
944 946
945 This is a recursive interpreter. 947 This is a recursive interpreter.
946 948
947 reuslt: list2("replaced string",next) 949 reuslt: list2("replaced string",next)
948 history is necessary to avoid recursion 950 history is necessary to avoid recursion
949 */ 951 */
950 952
951 static int 953 static int
952 macro_eval(int macrop,char *body0,int history) 954 macro_eval(int macrop,char *body0,int history)
953 { 955 {
963 965
964 macro_history = history; 966 macro_history = history;
965 macrop = list3s(STRING,macrop,cheap->ptr); 967 macrop = list3s(STRING,macrop,cheap->ptr);
966 expand = (char **)&scaddr(macrop); 968 expand = (char **)&scaddr(macrop);
967 for(; (c = *body++) ;) { 969 for(; (c = *body++) ;) {
968 if (in_quote) { 970 if (in_quote) {
969 if (c=='\\') { 971 if (c=='\\') {
970 *cheap->ptr = c; c = *body++; 972 *cheap->ptr = c; c = *body++;
971 cheap = increment_cheap(cheap,expand); 973 cheap = increment_cheap(cheap,expand);
972 } else if (c=='\'') { 974 } else if (c=='\'') {
973 in_quote = 0; 975 in_quote = 0;
974 } 976 }
975 } else if (in_wquote) { 977 } else if (in_wquote) {
976 if (c=='\\') { 978 if (c=='\\') {
977 *cheap->ptr = c; c = *body++; 979 *cheap->ptr = c; c = *body++;
978 cheap = increment_cheap(cheap,expand); 980 cheap = increment_cheap(cheap,expand);
979 } else if (c=='"') { 981 } else if (c=='"') {
980 in_wquote = 0; 982 in_wquote = 0;
981 } 983 }
982 } else if (c=='"') { 984 } else if (c=='"') {
983 in_wquote = 1; prev_concat = 0; 985 in_wquote = 1; prev_concat = 0;
984 } else if (c=='\'') { 986 } else if (c=='\'') {
985 in_quote = 1; prev_concat = 0; 987 in_quote = 1; prev_concat = 0;
986 } else if (c=='#' && *body=='#') { 988 } else if (c=='#' && *body=='#') {
987 mconcat = 1; 989 mconcat = 1;
988 prev_concat = 1; 990 prev_concat = 1;
989 // name concatenation. flag only. remove and re-evaluate 991 // name concatenation. flag only. remove and re-evaluate
990 // in the top level. (and skip space) 992 // in the top level. (and skip space)
991 } else if (!mconcat && c=='#' && alpha(*body)) { 993 } else if (!mconcat && c=='#' && alpha(*body)) {
992 // turn into string next macro literal 994 // turn into string next macro literal
993 string_flag = 1; 995 string_flag = 1;
994 string_mark(expand); 996 string_mark(expand);
995 prev_concat = 0; 997 prev_concat = 0;
996 goto names; 998 goto names;
997 } else if (alpha(c)) { 999 } else if (alpha(c)) {
998 // find a name 1000 // find a name
999 body--; // ungetc 1001 body--; // ungetc
1000 names: 1002 names:
1001 nptrm = get_name(body,&len,NONDEF); 1003 nptrm = get_name(body,&len,NONDEF);
1002 if (!nptrm) { 1004 if (!nptrm) {
1003 while((*cheap->ptr = *body++) && len--) 1005 while((*cheap->ptr = *body++) && len--)
1004 cheap = increment_cheap(cheap,expand); 1006 cheap = increment_cheap(cheap,expand);
1005 body--; 1007 body--;
1006 if (string_flag) { 1008 if (string_flag) {
1007 string_flag = 0; 1009 string_flag = 0;
1008 string_mark(expand); 1010 string_mark(expand);
1009 } 1011 }
1010 continue; 1012 continue;
1011 } 1013 }
1012 body += len; 1014 body += len;
1013 c = *body; 1015 c = *body;
1014 nptrm = name_space_search(nptrm,MACRO); 1016 nptrm = name_space_search(nptrm,MACRO);
1015 if (nptrm->dsp) 1017 if (nptrm->dsp)
1016 macro = scaddr(nptrm->dsp); 1018 macro = scaddr(nptrm->dsp);
1017 else 1019 else
1018 macro=""; 1020 macro="";
1019 if (check_recurse(nptrm->nm,history)) { 1021 if (check_recurse(nptrm->nm,history)) {
1020 // should return the most original one, but how? 1022 // should return the most original one, but how?
1021 // save_cheap/reset_cheap and return here? 1023 // save_cheap/reset_cheap and return here?
1022 macro = nptrm->nm; 1024 macro = nptrm->nm;
1023 goto skip; 1025 goto skip;
1024 } 1026 }
1025 switch(nptrm->sc) { 1027 switch(nptrm->sc) {
1026 case FMACRO: 1028 case FMACRO:
1027 if (c==' '||c=='\t') { 1029 if (c==' '||c=='\t') {
1028 while (c==' '||c=='\t') c=*body++; 1030 while (c==' '||c=='\t') c=*body++;
1029 body--; 1031 body--;
1030 } 1032 }
1031 if(c!='(') { 1033 if(c!='(') {
1032 macro = nptrm->nm; 1034 macro = nptrm->nm;
1033 goto skip; // error(MCERR); this isn't error 1035 goto skip; // error(MCERR); this isn't error
1034 } 1036 }
1035 *cheap->ptr = 0; 1037 *cheap->ptr = 0;
1036 cheap = increment_cheap(cheap,expand); 1038 cheap = increment_cheap(cheap,expand);
1037 body++; 1039 body++;
1038 macrop = macro_function(macrop,&body,nptrm, 1040 macrop = macro_function(macrop,&body,nptrm,
1039 glist3s(STRING,history,nptrm->nm)); 1041 glist3s(STRING,history,nptrm->nm));
1040 macrop = list3s(STRING,macrop,cheap->ptr); 1042 macrop = list3s(STRING,macrop,cheap->ptr);
1041 expand = (char **)&(scaddr(macrop)); 1043 expand = (char **)&(scaddr(macrop));
1042 break; 1044 break;
1043 default: 1045 default:
1044 if (prev_concat) { 1046 if (prev_concat) {
1045 prev_concat = 0; 1047 prev_concat = 0;
1046 macro = nptrm->u.nm; 1048 macro = nptrm->u.nm;
1047 } else if (next_concat(c,body)) { 1049 } else if (next_concat(c,body)) {
1048 prev_concat = 1; 1050 prev_concat = 1;
1049 macro = nptrm->u.nm; 1051 macro = nptrm->u.nm;
1050 } 1052 }
1051 if (macro==0 || !macro[0]) 1053 if (macro==0 || !macro[0])
1052 macro = nptrm->nm; 1054 macro = nptrm->nm;
1053 goto skip; 1055 goto skip;
1054 case MACRO: 1056 case MACRO:
1055 if (neqname(nptrm->nm,macro)) { 1057 if (neqname(nptrm->nm,macro)) {
1056 if (macro[0]==0) { 1058 if (macro[0]==0) {
1057 if (string_flag) { 1059 if (string_flag) {
1058 string_flag = 0; 1060 string_flag = 0;
1059 string_mark(expand); 1061 string_mark(expand);
1060 } 1062 }
1061 continue; 1063 continue;
1062 } 1064 }
1063 *cheap->ptr = 0; 1065 *cheap->ptr = 0;
1064 cheap = increment_cheap(cheap,expand); 1066 cheap = increment_cheap(cheap,expand);
1065 macrop=macro_eval(macrop,macro,glist3s(STRING,history,nptrm->nm)); 1067 macrop=macro_eval(macrop,macro,glist3s(STRING,history,nptrm->nm));
1066 macrop = list3s(STRING,macrop,cheap->ptr); 1068 macrop = list3s(STRING,macrop,cheap->ptr);
1067 expand = (char **)&(scaddr(macrop)); 1069 expand = (char **)&(scaddr(macrop));
1068 break; 1070 break;
1069 } 1071 }
1070 macro = nptrm->nm; 1072 macro = nptrm->nm;
1071 skip: 1073 skip:
1072 case LMACRO: 1074 case LMACRO:
1073 while((*cheap->ptr = *macro++)/* && len-- */) 1075 while((*cheap->ptr = *macro++)/* && len-- */)
1074 cheap = increment_cheap(cheap,expand); 1076 cheap = increment_cheap(cheap,expand);
1075 } 1077 }
1076 if (string_flag) { 1078 if (string_flag) {
1077 string_flag = 0; 1079 string_flag = 0;
1078 string_mark(expand); 1080 string_mark(expand);
1079 } 1081 }
1080 continue; 1082 continue;
1081 } 1083 }
1082 *cheap->ptr = c; 1084 *cheap->ptr = c;
1083 cheap = increment_cheap(cheap,expand); 1085 cheap = increment_cheap(cheap,expand);
1084 } 1086 }
1085 *cheap->ptr = 0; 1087 *cheap->ptr = 0;
1086 cheap = increment_cheap(cheap,expand); 1088 cheap = increment_cheap(cheap,expand);
1087 return macrop; 1089 return macrop;
1088 } 1090 }
1098 char *p; 1100 char *p;
1099 *result = cheap->ptr; 1101 *result = cheap->ptr;
1100 for(;lists;lists = cadr(lists)) { 1102 for(;lists;lists = cadr(lists)) {
1101 p = scaddr(lists); 1103 p = scaddr(lists);
1102 for(;(*cheap->ptr = *p++);cheap = increment_cheap(cheap,result)) { 1104 for(;(*cheap->ptr = *p++);cheap = increment_cheap(cheap,result)) {
1103 // in_quote + \n case ? should be \n. 1105 // in_quote + \n case ? should be \n.
1104 if (p[-1]=='\n') cheap->ptr[0]=' '; 1106 if (p[-1]=='\n') cheap->ptr[0]=' ';
1105 } 1107 }
1106 } 1108 }
1107 cheap = increment_cheap(cheap,result); 1109 cheap = increment_cheap(cheap,result);
1108 return *result; 1110 return *result;
1109 } 1111 }
1110 1112
1115 char *p; 1117 char *p;
1116 *result = cheap->ptr; 1118 *result = cheap->ptr;
1117 for(;lists;lists = cadr(lists)) { 1119 for(;lists;lists = cadr(lists)) {
1118 p = scaddr(lists); 1120 p = scaddr(lists);
1119 for(;(*cheap->ptr=*p++);cheap = increment_cheap(cheap,result)) { 1121 for(;(*cheap->ptr=*p++);cheap = increment_cheap(cheap,result)) {
1120 // in_quote + \n case ? should be \n. 1122 // in_quote + \n case ? should be \n.
1121 // if (p[-1]=='\n') cheap->ptr[0]=' '; 1123 // if (p[-1]=='\n') cheap->ptr[0]=' ';
1122 } 1124 }
1123 } 1125 }
1124 cheap = increment_cheap(cheap,result); 1126 cheap = increment_cheap(cheap,result);
1125 return *result; 1127 return *result;
1126 } 1128 }
1127 1129
1128 extern int 1130 extern int
1129 check_recurse(char *macro,int history) 1131 check_recurse(char *macro,int history)
1130 { 1132 {
1131 for(;history;history = cadr(history)) { 1133 for(;history;history = cadr(history)) {
1132 if (macro==scaddr(history)) { 1134 if (macro==scaddr(history)) {
1133 // fprintf(stderr,"check_recurse: %s %s = ",macro,scaddr(history)); 1135 // fprintf(stderr,"check_recurse: %s %s = ",macro,scaddr(history));
1134 // fprintf(stderr,"1\n"); 1136 // fprintf(stderr,"1\n");
1135 return 1; 1137 return 1;
1136 } 1138 }
1137 } 1139 }
1138 // fprintf(stderr,"0\n"); 1140 // fprintf(stderr,"0\n");
1139 return 0; 1141 return 0;
1140 } 1142 }
1141 1143