Mercurial > hg > CbC > old > device
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),¯opp); | 139 mappend0(reverse0(macrop),¯opp); |
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,¯opp); | 143 cheap = increment_cheap(cheap,¯opp); |
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)),¯o); | 895 mappend0(reverse0(car(evalues)),¯o); |
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 |