10 if(c < '0' || c > '9')
13 while(c >= '0' && c <= '9') {
30 if(cp <= symb+NSYMB-UTFmax)
38 if(cp <= symb+NSYMB-UTFmax)
41 if(c >= Runeself || isalnum(c) || c == '_')
47 if(cp > symb+NSYMB-UTFmax)
48 yyerror("symbol too large: %s", symb);
57 if(c < Runeself && !isalpha(c) && c != '_') {
80 if(getc() != '.' || getc() != '.')
81 yyerror("bad dots in macro");
83 return slookup("__VA_ARGS__");
113 yyerror("comment across newline");
131 strncpy(symb, cp, NSYMB);
132 if(symb[NSYMB-1] != '\0'){
133 yyerror("macro too long: %s", cp);
136 p = strchr(symb, '=');
140 l = strlen(p) + 2; /* +1 null, +1 nargs */
142 memcpy(s->macro, p-1, l);
145 s->macro = "\0001"; /* \000 is nargs */
148 print("#define (-D) %s %s\n", s->name, s->macro+1);
157 "ifdef", 0, /* macif(0) */
158 "ifndef", 0, /* macif(1) */
159 "else", 0, /* macif(2) */
179 s = slookup("endif");
180 for(i=0; mactab[i].macname; i++)
181 if(strcmp(s->name, mactab[i].macname) == 0) {
188 yyerror("unknown #: %s", s->name);
200 yyerror("syntax in #undef");
211 char *args[NARG], *base;
212 int n, i, c, len, dots;
219 yyerror("macro redefined: %s", s->name);
229 a = getsymdots(&dots);
233 yyerror("too many arguments in #define: %s", s->name);
253 if(c >= Runeself || isalpha(c) || c == '_') {
257 if(strcmp(symb, args[i]) == 0)
261 base = allocn(base, len, i);
262 memcpy(base+len, symb, i);
266 base = allocn(base, len, 2);
268 base[len++] = 'a' + i;
273 base = allocn(base, len, 1);
279 if(c == '"' || c == '\''){
280 base = allocn(base, len, 1);
308 yyerror("comment and newline in define: %s", s->name);
315 base = allocn(base, len, 1);
333 base = allocn(base, len, 1);
341 base = allocn(base, len, 1);
344 base = allocn(base, len, 1);
350 yyerror("eof in a macro: %s", s->name);
355 base = allocn(base, len, 1);
364 print("#define %s %s\n", s->name, s->macro+1);
369 yyerror("syntax in #define");
371 yyerror("syntax in #define: %s", s->name);
376 macexpand(Sym *s, char *b, int blen)
380 char *arg[NARG], *cp, *ob, *eb, *ecp, dots;
384 strncpy(b, s->macro+1, blen);
385 if(b[blen-1] != '\0')
388 print("#expand %s %s\n", s->name, b);
392 nargs = (char)(*s->macro & ~VARMAC) - 1;
393 dots = *s->macro & VARMAC;
404 ecp = cp + sizeof(buf)-UTFmax;
457 while((c = getc()) != '\n')
467 if(n == nargs && dots) {
491 yyerror("argument mismatch expanding: %s", s->name);
523 memmove(b, arg[c], l);
528 print("#expand %s %s\n", s->name, ob);
532 yyerror("syntax in macro expansion: %s", s->name);
537 yyerror("too much text in macro expansion: %s", s->name);
545 char str[STRINGSZ], *hp;
560 if(hp >= &str[STRINGSZ-1]){
561 yyerror("name too long for #include");
572 for(i=0; i<ninclude; i++) {
573 if(i == 0 && c0 == '>')
575 c = snprint(symb, NSYMB, "%s/%s", include[i], str);;
576 while(strncmp(symb, "./", 2) == 0){
578 memmove(symb, symb+2, c+1);
585 snprint(symb, NSYMB, "%s", str);
588 newfile(strdup(symb), f);
593 yyerror("syntax in #include");
610 if(c == ' ' || c == '\t') {
617 strcpy(symb, "<noname>");
635 c = strlen(symb) + 1;
643 yyerror("syntax in #line");
660 if((s->macro != 0) ^ f)
680 if(strcmp(s->name, "endif") == 0) {
688 if(strcmp(s->name, "ifdef") == 0 || strcmp(s->name, "ifndef") == 0) {
692 if(l == 0 && f != 2 && strcmp(s->name, "else") == 0) {
699 yyerror("syntax in #if(n)def");
713 if(s && strcmp(s->name, "lib") == 0)
715 if(s && strcmp(s->name, "pack") == 0) {
719 if(s && strcmp(s->name, "fpround") == 0) {
723 if(s && strcmp(s->name, "profile") == 0) {
727 if(s && strcmp(s->name, "varargck") == 0) {
731 if(s && strcmp(s->name, "incomplete") == 0) {
735 while(getnsc() != '\n')
761 * put pragma-line in as a funny history
763 c = strlen(symb) + 1;
764 h = alloc(sizeof(Hist));
766 memcpy(h->name, symb, c);
781 yyerror("syntax in #pragma lib");
792 if(c < 0 || c == '\n')
798 linehist(char *f, int offset)
803 * overwrite the last #line directive if
804 * no alloc has happened since the last one
806 if(newflag == 0 && ehist != H && offset != 0 && ehist->offset != 0)
807 if(f && ehist->name && strcmp(f, ehist->name) == 0) {
808 ehist->line = lineno;
809 ehist->offset = offset;
816 print("%4ld: %s (#line %d)\n", lineno, f, offset);
818 print("%4ld: %s\n", lineno, f);
820 print("%4ld: <pop>\n", lineno);
823 h = alloc(sizeof(Hist));