* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / linux86-0.16.17 / bcc / preproc.c
blob97e2a96a72171b3b781332743f18b505012dc58b
1 /* preprocessor routines for bcc */
3 /* Copyright (C) 1992 Bruce Evans */
5 #include "bcc.h"
6 #include "input.h"
7 #include "os.h"
8 #include "output.h"
9 #include "parse.h"
10 #include "sc.h"
11 #include "scan.h"
12 #include "table.h"
13 #include "type.h"
15 /* blanksident() - return nonzero if at blanks followed by an identifier */
17 PUBLIC bool_pt blanksident()
19 blanks();
20 return isident();
23 #ifdef BUILTIN_CPP
25 #define MAX_IF 32
26 #define MAX__LINE__ 10 /* enough for 32-bit source unsigneds */
27 #define MAX_MACRO 32
28 #define MAX_PARAM 127 /* max char with no sign on all machines */
30 /* Definition types. These are kept in the 'storage' member of struct
31 * symstruct and must be distinct from 'LOCAL' because dumplocs() doesn't
32 * check.
34 enum
36 DEF_LINE, /* __LINE__ keyword */
37 DEF_NONE /* nothing special */
40 struct ifstruct
42 bool_t elseflag;
43 bool_t ifflag;
46 struct macroposition
48 char *maclineptr;
49 char **paramlist;
50 char *paramspot;
51 bool_t inparam;
52 indn_t nparam;
53 struct symstruct *symptr;
56 PRIVATE char dummyparam[] = { EOL, 0 };
57 PRIVATE fastin_t iflevel; /* depends on zero init */
58 PRIVATE struct ifstruct ifstate;
59 /* elseflag depends on zero init */
60 PRIVATE struct ifstruct ifstack[MAX_IF];
62 PRIVATE struct macroposition macrostack[MAX_MACRO];
64 FORWARD void asmcontrol P((void));
65 FORWARD void warningcntl P((void));
66 FORWARD void errorcntl P((void));
67 FORWARD void control P((void));
68 FORWARD void defineorundefinestring P((char *str, bool_pt defineflag));
69 FORWARD void elifcontrol P((void));
70 FORWARD void elsecontrol P((void));
71 FORWARD void endif P((void));
72 FORWARD fastin_pt getparnames P((void));
73 FORWARD void ifcontrol P((sym_pt ifcase));
74 FORWARD void undef P((void));
76 /* asmcontrol() - process #asm */
78 PRIVATE void asmcontrol()
80 #ifdef ASM_BARE
81 char treasure; /* to save at least one leading blank */
82 #endif
84 asmmode = TRUE;
85 if (expect_statement)
86 return;
88 if (orig_cppmode)
89 outnstr("#asm");
90 else
92 outnstr("!BCC_ASM");
93 dumplocs();
95 #ifndef ASM_BARE
96 cppscan(1);
97 #else
98 while (TRUE)
100 skipline();
101 skipeol();
102 if (eofile)
104 eofin("#asm");
105 break;
107 if (SYMOFCHAR(ch) == SPECIALCHAR)
108 specialchar();
109 treasure = 0;
110 if (SYMOFCHAR(ch) == WHITESPACE)
111 treasure = ch;
112 blanks();
113 if (ch == '#')
115 if (ctext)
117 register char *lptr;
119 comment();
120 if (treasure != 0)
121 outbyte(treasure);
122 lptr = lineptr;
123 while (*lptr++ != EOL) /* XXX - handle COEOL too */
124 outbyte(ch);
125 outnl();
127 gch1();
128 docontrol();
129 if (!asmmode)
130 break;
132 else
134 if (treasure != 0)
135 outbyte(treasure);
136 while (ch != EOL) /* XXX - handle COEOL too */
138 outbyte(ch);
139 gch1();
141 outnl();
144 #endif
145 if (orig_cppmode)
146 outnstr("#endasm");
147 else
148 outnstr("!BCC_ENDASM");
151 PUBLIC void checknotinif()
153 while (iflevel != 0)
155 if (ifstate.ifflag)
156 eofin("true #conditional");
157 else
158 eofin("false #conditional");
159 endif();
163 /* warningcntl() - process #warning */
165 PRIVATE void warningcntl()
167 char estr[256], *ep = estr;
169 if (!orig_cppmode) {
170 *ep++ = '%'; *ep++ = 'w';
172 while( ch != EOL ) {
173 if (ep < estr+sizeof(estr)-2 )
174 *ep++ = ch;
175 gch1();
177 *ep = 0;
179 if (!orig_cppmode)
180 error(estr);
181 else {
182 outstr("#warning");
183 outnstr(estr);
187 /* errorcntl() - process #error */
189 PRIVATE void errorcntl()
191 char estr[256], *ep = estr;
193 while( ch != EOL ) {
194 if (ep < estr+sizeof(estr)-2 )
195 *ep++ = ch;
196 gch1();
198 *ep = 0;
200 if (!orig_cppmode)
201 error(estr);
202 else {
203 outstr("#error");
204 outnstr(estr);
208 /* control() - select and switch to control statement */
210 PRIVATE void control()
212 char sname[NAMESIZE + 1];
213 sym_t ctlcase;
214 struct symstruct *symptr;
215 if (ctext && asmmode)
217 comment();
218 outudec(input.linenumber);
219 outbyte(' ');
220 outline(lineptr);
223 sname[0] = '#'; /* prepare for bad control */
224 sname[1] = 0;
225 while (blanksident())
227 if ((gsymptr = findlorg(gsname)) == NULL ||
228 gsymptr->flags != DEFINITION)
230 strcat(sname, gsname);
231 break;
233 entermac();
235 if (sname[1] == 0 && ch == EOL)
236 return;
237 if (SYMOFCHAR(ch) == INTCONST)
238 { linecontol(); return; }
239 if ((symptr = findlorg(sname)) == NULL)
241 if (ifstate.ifflag)
242 error(" bad control");
243 return;
245 ctlcase = symptr->offset.offsym;
246 if (ifstate.ifflag == FALSE &&
247 (ctlcase < ELIFCNTL || ctlcase > IFNDEFCNTL))
248 return;
249 switch (ctlcase)
251 case ASMCNTL:
252 if (asmmode)
254 if (ifstate.ifflag)
255 error(" bad control");
257 else
258 asmcontrol();
259 break;
260 case DEFINECNTL:
261 define();
262 break;
263 case ELIFCNTL:
264 elifcontrol();
265 break;
266 case ELSECNTL:
267 elsecontrol();
268 break;
269 case ENDASMCNTL:
270 if (!asmmode)
272 if (ifstate.ifflag)
273 error(" bad control");
275 asmmode = FALSE;
276 break;
277 case ENDIFCNTL:
278 endif();
279 break;
280 case IFCNTL:
281 case IFDEFCNTL:
282 case IFNDEFCNTL:
283 ifcontrol(symptr->offset.offsym);
284 break;
285 case INCLUDECNTL:
286 include();
287 break;
288 case LINECNTL:
289 { linecontol(); break; }
290 case UNDEFCNTL:
291 undef();
292 break;
293 case WARNINGCNTL:
294 warningcntl();
295 break;
296 case ERRORCNTL:
297 errorcntl();
298 break;
302 /* define() - process #define */
305 MACRO storage.
306 A symbol recording the macro name is added to the symbol table.
307 This overrides all current scopes of the name (put at head of hash chain).
308 The flags are set to DEFINITION.
309 The indcount is 0 if no parameters, else 1 + number of parameters.
310 The offset field points to the macro string.
311 The macro string is null-terminated but EOL-sentineled.
312 It consists of EOL-terminated substrings followed by parameter numbers,
313 e.g., junk(x,y)=-x+y is stored as '-', EOL, 1, '+', EOL, 2, EOL, 0.
314 Here 1 is for the 1st parameter (start at 1 so 0 can terminate).
315 EOL acts as a sentinel for the scanner.
316 This choice works well because EOL cannot occur in a macro string.
319 PUBLIC void define()
321 char sname[NAMESIZE];
322 char quote;
323 struct symstruct **hashptr;
324 struct symstruct *locmark = NULL; /* for -Wall */
325 char *macstring;
326 fastin_t nparnames;
327 char *oldstring;
328 struct symstruct *symptr;
330 if (!blanksident())
332 error("illegal macro name");
333 return;
335 strcpy(sname, gsname); /* will overwrite gsname if parameters */
336 if (ch == '(')
338 locmark = locptr;
339 newlevel(); /* temp storage for parameter names */
340 nparnames = getparnames() + 1;
342 else
343 nparnames = 0;
344 blanks();
345 macstring = charptr;
346 quote = 0;
347 while (ch != EOL)
349 if (charptr >= char1top) /* check room for char and end of string */
350 macstring = growobject(macstring, 2);
351 if (nparnames && isident())
353 if ((symptr = findlorg(gsname)) != NULL &&
354 symptr->level == level)
356 #ifdef TS
357 ++ts_n_macstring_param;
358 ts_s_macstring += 2;
359 #endif
360 *charptr++ = EOL; /* end current string */
361 *charptr++ = symptr->indcount; /* param to insert */
363 else
365 if (charptr + strlen(gsname) >= chartop) /* null too */
366 macstring = growobject(macstring, strlen(gsname) + 1);
367 #ifdef TS
368 ++ts_n_macstring_ident;
369 ts_s_macstring += strlen(gsname);;
370 #endif
371 strcpy(charptr, gsname);
372 charptr += strlen(gsname); /* discard null */
374 continue;
376 if (ch == '\\')
378 gch1();
379 *charptr = '\\';
380 *(charptr + 1) = ch;
381 #ifdef TS
382 ++ts_n_macstring_quoted;
383 ts_s_macstring += 2;
384 #endif
385 charptr += 2;
386 gch1();
387 continue;
389 if (quote)
391 if (ch == quote)
392 quote = 0;
394 else if (ch == '"' || ch == '\'')
395 quote = ch;
396 else if (ch == '/')
398 if (SYMOFCHAR(*(lineptr + 1)) == SPECIALCHAR)
400 gch1();
401 ch = *--lineptr = '/'; /* pushback */
403 if (*(lineptr + 1) == '*')
405 gch1();
406 skipcomment();
407 #if 0
408 /* comment is space in modern cpp's but they have '##' too */
409 ch = *--lineptr = ' ';
410 #else
411 continue;
412 #endif
415 #ifdef TS
416 ++ts_n_macstring_ordinary;
417 ++ts_s_macstring;
418 #endif
419 *charptr++ = ch;
420 gch1();
423 register char *rcp;
425 /* strip trailing blanks, but watch out for parameters */
426 for (rcp = charptr;
427 rcp > macstring && SYMOFCHAR(*(rcp - 1)) == WHITESPACE
428 && (--rcp == macstring || *(rcp - 1) != EOL); )
429 charptr = rcp;
431 if (charptr+1 >= char1top)
432 macstring = growobject(macstring, 3);
433 #ifdef TS
434 ++ts_n_macstring_term;
435 ts_s_macstring += 3;
436 #endif
437 *charptr++ = ' '; /* Added to prevent tail recursion on expansion */
438 *charptr++ = EOL;
439 *charptr++ = 0;
440 if (nparnames)
442 oldlevel();
443 locptr = locmark;
445 /* if (asmmode) equ(sname, macstring); */
447 if ((symptr = findlorg(sname)) != NULL && symptr->flags == DEFINITION)
449 if (strcmp(macstring, oldstring = symptr->offset.offp) != 0)
450 error("%wredefined macro");
451 if (strlen(macstring) > strlen(oldstring = symptr->offset.offp))
452 symptr->offset.offp = macstring;
453 else
455 strcpy(oldstring, macstring); /* copy if == to avoid test */
456 charptr = macstring;
458 return;
460 symptr = qmalloc(sizeof (struct symstruct) + strlen(sname));
461 #ifdef TS
462 ++ts_n_defines;
463 ts_s_defines += sizeof (struct symstruct) + strlen(sname);
464 #endif
465 addsym(sname, vtype, symptr);
466 symptr->storage = DEF_NONE;
467 symptr->indcount = nparnames;
468 symptr->flags = DEFINITION;
469 symptr->level = GLBLEVEL;
470 symptr->offset.offp = macstring;
471 if (*(hashptr = gethashptr(sname)) != NULL)
473 symptr->next = *hashptr;
474 symptr->next->prev = &symptr->next;
476 *hashptr = symptr;
477 symptr->prev = hashptr;
480 PRIVATE void defineorundefinestring(str, defineflag)
481 char *str; /* "name[=def]" or "name def" */
482 bool_pt defineflag;
484 char *fakeline;
485 unsigned len;
486 bool_t old_eof;
488 len = strlen(str);
489 strcpy(fakeline = (char *) ourmalloc(3 + len + 2 + 2) + 3, str);
490 /* 3 pushback, 2 + 2 guards */
491 #ifdef TS
492 ts_s_fakeline += 3 + len + 2 + 2;
493 ts_s_fakeline_tot += 3 + len + 2 + 2;
494 #endif
496 register char *endfakeline;
498 endfakeline = fakeline + len;
499 endfakeline[0] = EOL; /* guards any trailing backslash */
500 endfakeline[1] = EOL; /* line ends here or before */
502 old_eof = eofile;
503 eofile = TRUE; /* valid after first EOL */
504 ch = *(lineptr = fakeline);
505 if (defineflag)
507 if (blanksident()) /* if not, let define() produce error */
509 blanks();
510 if (ch == '=')
511 *lineptr = ' ';
512 else if (ch == EOL)
514 register char *lptr;
516 lptr = lineptr;
517 lptr[0] = ' ';
518 lptr[1] = '1'; /* 2 extra were allocated for this & EOL */
519 lptr[2] = EOL;
522 ch = *(lineptr = fakeline);
523 define();
525 else
526 undef();
527 eofile = old_eof;
528 #ifdef TS
529 ts_s_fakeline_tot -= len + 2 + 2;
530 #endif
531 ourfree(fakeline - 3);
534 PUBLIC void definestring(str)
535 char *str; /* "name[=def]" or "name def" */
537 defineorundefinestring(str, TRUE);
540 /* docontrol() - process control statement, loop till "#if" is true */
542 PUBLIC void docontrol()
544 while (TRUE)
546 control();
547 skipline();
548 if (ifstate.ifflag)
549 return;
550 while (TRUE)
552 skipeol();
553 if (eofile)
554 return;
555 blanks();
556 if (ch == '#')
558 gch1();
559 break;
561 skipline();
566 /* elifcontrol() - process #elif */
568 PRIVATE void elifcontrol()
570 if (iflevel == 0)
572 error("elif without if");
573 return;
575 if (ifstate.elseflag) {
576 register struct ifstruct *ifptr;
578 ifptr = &ifstack[(int)--iflevel];
579 ifstate.elseflag = ifptr->elseflag;
580 ifstate.ifflag = ifptr->ifflag;
582 ifcontrol(IFCNTL);
583 } else {
584 ifstate.ifflag = ifstate.elseflag;
585 ifstate.elseflag = FALSE;
589 /* elsecontrol() - process #else */
591 PRIVATE void elsecontrol()
593 if (iflevel == 0)
595 error("else without if");
596 return;
598 ifstate.ifflag = ifstate.elseflag;
599 ifstate.elseflag = FALSE;
602 /* endif() - process #endif */
604 PRIVATE void endif()
606 if (iflevel == 0)
608 error("endif without if");
609 return;
612 register struct ifstruct *ifptr;
614 ifptr = &ifstack[(int)--iflevel];
615 ifstate.elseflag = ifptr->elseflag;
616 ifstate.ifflag = ifptr->ifflag;
620 /* entermac() - switch line ptr to macro string */
622 PUBLIC void entermac()
624 char quote;
625 struct symstruct *symptr;
626 char **paramhead;
627 char **paramlist;
628 int ngoodparams;
629 int nparleft;
630 int lpcount;
632 if (maclevel >= MAX_MACRO)
634 limiterror("macros nested too deeply (33 levels)");
635 return;
637 symptr = gsymptr;
638 symptr->name.namea[0] |= 0x80; /* SMUDGE macro definition */
639 ngoodparams = 0;
640 paramhead = NULL;
641 if (symptr->indcount != 0)
643 nparleft = symptr->indcount - 1;
644 if (nparleft == 0)
645 paramhead = NULL;
646 else
647 paramhead = ourmalloc(sizeof *paramlist * nparleft);
648 paramlist = paramhead;
649 #ifdef TS
650 ++ts_n_macparam;
651 ts_s_macparam += sizeof *paramlist * nparleft;
652 ts_s_macparam_tot += sizeof *paramlist * nparleft;
653 #endif
654 blanks();
655 while (ch == EOL && !eofile)
657 skipeol();
658 blanks();
660 if (ch != '(')
662 if (nparleft > 0) /* macro has params, doesn't match bare word */
664 symptr->name.namea[0] &= 0x7f; /* UnSMUDGE macro definition */
665 outstr(symptr->name.namea);
666 return;
668 error("missing '('");
670 else
672 gch1();
673 while (nparleft)
675 --nparleft;
676 ++ngoodparams;
677 *(paramlist++) = charptr;
678 quote = 0;
679 lpcount = 1;
680 while (TRUE)
682 if (ch == '\\')
684 gch1();
685 if (charptr >= char1top)
686 *(paramlist - 1) = growobject(*(paramlist - 1), 2);
687 #ifdef TS
688 ++ts_n_macparam_string_quoted;
689 ++ts_s_macparam_string;
690 ++ts_s_macparam_string_tot;
691 #endif
692 *charptr++ = '\\';
694 else if (quote)
696 if (ch == quote)
697 quote = 0;
699 else if (ch == '"' || ch == '\'')
700 quote = ch;
701 else if (ch == '/')
703 if (SYMOFCHAR(*(lineptr + 1)) == SPECIALCHAR)
705 gch1();
706 ch = *--lineptr = '/'; /* pushback */
708 if (*(lineptr + 1) == '*')
710 gch1();
711 skipcomment();
712 ch = *--lineptr = ' '; /* pushback */
715 else if (ch == '(')
716 ++lpcount;
717 else if ((ch == ')' && --lpcount == 0) ||
718 (ch == ',' && lpcount == 1))
719 break;
720 if (ch == EOL)
721 ch = ' ';
722 if (charptr >= char1top)
723 *(paramlist - 1) = growobject(*(paramlist - 1), 2);
724 #ifdef TS
725 ++ts_n_macparam_string_ordinary;
726 ++ts_s_macparam_string;
727 ++ts_s_macparam_string_tot;
728 #endif
729 *charptr++ = ch;
730 if (*lineptr == EOL)
732 skipeol(); /* macro case disposed of already */
733 if (SYMOFCHAR(ch) == SPECIALCHAR)
734 specialchar();
735 if (eofile)
736 break;
738 else
739 gch1();
741 #ifdef TS
742 ++ts_n_macparam_string_term;
743 ++ts_s_macparam_string;
744 ++ts_s_macparam_string_tot;
745 #endif
746 *charptr++ = EOL;
748 register char *newparam;
749 register char *oldparam;
750 unsigned size;
752 oldparam = *(paramlist - 1);
753 size = (/* size_t */ unsigned) (charptr - oldparam);
754 newparam = ourmalloc(size);
755 #ifdef TS
756 ts_s_macparam_string_alloced += size;
757 ts_s_macparam_string_alloced_tot += size;
758 #endif
759 memcpy(newparam, oldparam, size);
760 *(paramlist - 1) = newparam;
761 #ifdef TS
762 ts_s_macparam_string_tot -= charptr - oldparam;
763 #endif
764 charptr = oldparam;
766 if (ch == ',')
767 gch1();
768 else
769 break;
772 blanks();
773 while (ch == EOL && !eofile)
775 skipeol();
776 blanks();
778 if (eofile)
779 eofin("macro parameter expansion");
780 if (nparleft)
782 error("too few macro parameters");
784 *(paramlist++) = dummyparam;
785 while (--nparleft);
787 if (ch == ')')
788 gch1();
789 else if (ch == ',')
791 error("too many macro parameters");
793 /* XXX - should read and discard extra parameters. Also check
794 * for eof at end.
796 while (ch != ')')
798 if (ch == EOL)
800 skipeol();
801 if (eofile)
802 break;
803 continue;
805 gch1();
808 else
809 error("missing ')'");
812 if (symptr->storage == DEF_LINE)
814 char *str;
816 str = pushudec(symptr->offset.offp + MAX__LINE__, input.linenumber);
817 memcpy(symptr->offset.offp, str, /* size_t */
818 (unsigned) (symptr->offset.offp + MAX__LINE__ + 1 + 1 - str));
822 register struct macroposition *mpptr;
824 mpptr = &macrostack[maclevel];
825 mpptr->paramlist = paramhead;
826 mpptr->maclineptr = lineptr;
827 ch = *(lineptr = symptr->offset.offp);
828 mpptr->inparam = FALSE;
829 mpptr->nparam = ngoodparams;
830 mpptr->symptr = symptr;
831 mpptr->symptr->name.namea[0] |= 0x80; /* SMUDGE macro definition */
832 ++maclevel;
835 comment();
836 outstr("MACRO (level ");
837 outudec((unsigned) maclevel);
838 outstr(") ");
839 outline(lineptr);
843 /* getparnames() - get parameter names during macro definition, return count */
845 PRIVATE fastin_pt getparnames()
847 fastin_t nparnames;
848 struct symstruct *symptr;
850 nparnames = 0;
851 gch1();
852 while (blanksident())
854 if ((symptr = findlorg(gsname)) != NULL &&
855 symptr->level == level)
856 error("repeated parameter");
857 symptr = addloc(gsname, itype);
858 if (nparnames >= MAX_PARAM)
859 limiterror("too many macro parameters (128)");
860 else
861 ++nparnames; /* number params from 1 */
862 symptr->indcount = nparnames; /* param number */
863 blanks();
864 if (ch == ',')
865 gch1();
867 if (ch != ')')
868 error("missing ')'");
869 else
870 gch1();
871 return nparnames;
874 /* ifcontrol - process #if, #ifdef, #ifndef */
876 PRIVATE void ifcontrol(ifcase)
877 sym_pt ifcase;
879 bool_t iftrue;
880 struct symstruct *symptr;
882 if (iflevel >= MAX_IF)
884 limiterror("#if's nested too deeply (33 levels)");
885 return;
888 register struct ifstruct *ifptr;
890 ifptr = &ifstack[(int)iflevel++];
891 ifptr->elseflag = ifstate.elseflag;
892 ifptr->ifflag = ifstate.ifflag;
893 ifstate.elseflag = FALSE; /* prepare for !(if now)||(if future)*/
895 if (ifstate.ifflag)
897 if ((sym_t) ifcase != IFCNTL)
899 iftrue = FALSE;
900 if (blanksident() && (symptr = findlorg(gsname)) != NULL &&
901 symptr->flags == DEFINITION)
902 iftrue = TRUE;
904 else
906 incppexpr = TRUE;
907 nextsym();
908 iftrue = constexpression() != 0;
909 incppexpr = FALSE;
911 if ((!iftrue && (sym_t) ifcase != IFNDEFCNTL) ||
912 (iftrue && (sym_t) ifcase == IFNDEFCNTL))
914 ifstate.elseflag = TRUE;
915 ifstate.ifflag = FALSE;
920 /* ifinit() - initialise if state */
922 PUBLIC void ifinit()
924 ifstate.ifflag = TRUE;
927 PUBLIC int ifcheck()
929 return (ifstate.ifflag == TRUE);
932 /* leavemac() - leave current and further macro substrings till not at end */
934 PUBLIC void leavemac()
936 register struct macroposition *mpptr;
940 mpptr = &macrostack[maclevel - 1];
941 if (mpptr->inparam)
943 lineptr = ++mpptr->paramspot;
944 mpptr->inparam = FALSE;
946 else
948 mpptr->symptr->name.namea[0] &= 0x7F;/* UnSMUDGE macro definition */
949 ch = *++lineptr; /* gch1() would mess up next param == EOL-1 */
950 if (ch != 0)
952 mpptr->paramspot = lineptr;
953 lineptr = mpptr->paramlist[ch - 1];
954 mpptr->inparam = TRUE;
956 else
958 lineptr = mpptr->maclineptr;
959 if (mpptr->nparam != 0)
961 register char **paramlist;
963 #ifdef TS
964 ts_s_macparam_tot -= sizeof *paramlist * mpptr->nparam;
965 #endif
966 paramlist = mpptr->paramlist;
969 #ifdef TS
970 ts_s_macparam_string_alloced_tot -= strchr(*paramlist, EOL) - *paramlist + 1;
971 #endif
972 ourfree(*paramlist++);
974 while (--mpptr->nparam != 0);
975 ourfree(mpptr->paramlist);
977 --maclevel;
981 while ((ch = *lineptr) == EOL && maclevel != 0);
984 PUBLIC void predefine()
986 definestring("__BCC__ 1");
987 definestring("__LINE__ 0123456789"); /* MAX__LINE__ digits */
988 findlorg("__LINE__")->storage = DEF_LINE;
991 PUBLIC char *savedlineptr()
993 return macrostack[0].maclineptr;
996 PUBLIC void skipcomment()
998 /* Skip current char, then everything up to '*' '/' or eof. */
1000 gch1();
1003 while (TRUE)
1006 register char *reglineptr;
1008 reglineptr = lineptr;
1009 symofchar['*'] = SPECIALCHAR;
1010 while (SYMOFCHAR(*reglineptr) != SPECIALCHAR)
1011 ++reglineptr;
1012 symofchar['*'] = STAR;
1013 lineptr = reglineptr;
1014 if (*reglineptr == '*')
1015 break;
1016 ch = *reglineptr;
1018 specialchar();
1019 if (ch == EOL)
1021 skipeol();
1022 if (eofile)
1023 break;
1025 else if (ch != '*')
1026 gch1();
1028 gch1();
1029 if (eofile)
1031 eofin("comment");
1032 return;
1035 while (ch != '/');
1036 gch1();
1039 /* skipline() - skip rest of line */
1041 PUBLIC void skipline()
1043 while (TRUE)
1045 blanks();
1046 if (ch == EOL)
1047 return;
1048 if (ch == '\\')
1050 gch1();
1051 if (ch == EOL) /* XXX - I think blanks() eats \EOL */
1052 return;
1053 gch1(); /* XXX - escape() better? */
1055 else if (ch == '"' || ch == '\'')
1057 stringorcharconst();
1058 charptr = constant.value.s;
1060 else
1061 gch1();
1065 /* undef() - process #undef */
1067 PRIVATE void undef()
1069 struct symstruct *symptr;
1071 if (blanksident() && (symptr = findlorg(gsname)) != NULL &&
1072 symptr->flags == DEFINITION)
1073 delsym(symptr);
1076 PUBLIC void undefinestring(str)
1077 char *str;
1079 defineorundefinestring(str, FALSE);
1082 #endif