merge mainline changes
[helenos.git] / uspace / app / pcc / cc / ccom / scan.l
blob95a946897379a41cbd9eaa56bd441d8bad06ddc9
1 %{
2 /*      $Id: scan.l,v 1.102 2011/02/16 18:50:42 ragge Exp $     */
4 /*
5  * Copyright (c) 2002 Anders Magnusson. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
32 D                       [0-9]
33 L                       [a-zA-Z_]
34 H                       [a-fA-F0-9]
35 E                       [Ee][+-]?{D}+
36 P                       [Pp][+-]?{D}+
37 FS                      (f|F|l|L)?i?
38 IS                      (u|U|l|L)*
39 UL                      ({L}|\\u{H}{H}{H}{H}|\\U{H}{H}{H}{H}{H}{H}{H}{H})
42 #include <stdlib.h>
43 #include <errno.h>  
44 #include <string.h>
45 #include <stdarg.h>
46 #include <ctype.h>
48 #include "pass1.h"
49 #include "cgram.h"
51 static NODE *cvtdig(int radix);
52 static NODE *charcon(void);
53 static NODE *wcharcon(void);
54 static void control(int);
55 static void pragma(void);
56 int notype, parbal, inattr, parlvl;
57 static int resw(TWORD, int);
59 #define CPP_IDENT       2
60 #define CPP_LINE        3
61 #define CPP_HASH        4
63 #ifdef STABS
64 #define STABS_LINE(x) if (gflag && cftnsp) stabs_line(x)
65 #else
66 #define STABS_LINE(x)
67 #endif
68 #if defined(FLEX_SCANNER) && YY_FLEX_SUBMINOR_VERSION == 31
69 /* Hack to avoid unnecessary warnings */
70 FILE *yyget_in  (void);
71 FILE *yyget_out  (void);
72 int yyget_leng  (void);
73 char *yyget_text  (void);
74 void yyset_in (FILE *);
75 void yyset_out (FILE *);
76 int yyget_debug  (void);
77 void yyset_debug (int);
78 int yylex_destroy  (void);
79 extern int yyget_lineno (void);
80 extern void yyset_lineno (int);
81 #endif
87 "__func__"              {
88                                 if (cftnsp == NULL)
89                                         uerror("__func__ outside function");
90                                 yylval.strp = cftnsp->sname; /* XXX - not C99 */
91                                 return(C_STRING);
92                         }
93 "asm"                   { return(C_ASM); }
94 "auto"                  {       return resw(AUTO, C_CLASS); }
95 "_Bool"                 {       return resw(BOOL, C_TYPE); }
96 "break"                 { return(C_BREAK); }
97 "case"                  { return(C_CASE); }
98 "char"                  {       return resw(CHAR, C_TYPE); }
99 "_Complex"              {       return resw(COMPLEX, C_TYPE); }
100 "const"                 {       return resw(CON, C_QUALIFIER); }
101 "continue"              { return(C_CONTINUE); }
102 "default"               { return(C_DEFAULT); }
103 "do"                    { return(C_DO); }
104 "double"                {       return resw(DOUBLE, C_TYPE); }
105 "else"                  { return(C_ELSE); }
106 "enum"                  { notype=1; return(C_ENUM); }
107 "extern"                {       return resw(EXTERN, C_CLASS); }
108 "float"                 {       return resw(FLOAT, C_TYPE); }
109 "for"                   { return(C_FOR); }
110 "goto"                  { notype=1; return(C_GOTO); }
111 "if"                    { return(C_IF); }
112 "_Imaginary"            {       return resw(IMAG, C_TYPE); }
113 "inline"                { return(C_FUNSPEC); }
114 "int"                   {       return resw(INT, C_TYPE); }
115 "long"                  {       return resw(LONG, C_TYPE); }
116 "register"              {       return resw(REGISTER, C_CLASS); }
117 "restrict"              { ; /* just ignore */ }
118 "return"                { return(C_RETURN); }
119 "short"                 {       return resw(SHORT, C_TYPE); }
120 "signed"                {       return resw(SIGNED, C_TYPE); }
121 "sizeof"                { return(C_SIZEOF); }
122 "static"                {       return resw(STATIC, C_CLASS); }
123 "struct"                { yylval.intval = STNAME; notype=1; return(C_STRUCT); }
124 "switch"                { return(C_SWITCH); }
125 "typedef"               {       return resw(TYPEDEF, C_CLASS); }
126 "union"                 { yylval.intval = UNAME; notype=1; return(C_STRUCT); }
127 "unsigned"              {       return resw(UNSIGNED, C_TYPE); }
128 "void"                  {       return resw(VOID, C_TYPE); }
129 "volatile"              {       return resw(VOL, C_QUALIFIER); }
130 "while"                 { return(C_WHILE); }
132 {UL}({UL}|{D})* {       struct symtab *s;
133                         int i = 0;
135                         yylval.strp = addname(yytext);
136 #ifdef GCC_COMPAT
137                         if ((i = gcc_keyword(yylval.strp, &yylval.nodep)) > 0)
138                                 return i;
139 #endif
140                         if (i == 0) {
141                                 if (notype)
142                                         return(C_NAME);
143                                 s = lookup(yylval.strp, SNOCREAT);
144                                 return s && s->sclass == TYPEDEF ?
145                                     notype=1, C_TYPENAME : C_NAME;
146                         }
147                 }
149 0[xX]{H}+{IS}?          { yylval.nodep = cvtdig(16); return(C_ICON); }
150 0{D}+{IS}?              { yylval.nodep = cvtdig(8); return(C_ICON); }
151 {D}+{IS}?               { yylval.nodep = cvtdig(10); return(C_ICON); }
152 L'(\\.|[^\\'])+'        { yylval.nodep = wcharcon(); return(C_ICON); }
153 '(\\.|[^\\'])+'         { yylval.nodep = charcon(); return(C_ICON); }
155 {D}+{E}{FS}?            { yylval.nodep = floatcon(yytext); return(C_FCON); }
156 {D}*"."{D}+({E})?{FS}?  { yylval.nodep = floatcon(yytext); return(C_FCON); }
157 {D}+"."{D}*({E})?{FS}?  { yylval.nodep = floatcon(yytext); return(C_FCON); }
158 0[xX]{H}*"."{H}+{P}{FS}? { yylval.nodep = fhexcon(yytext); return(C_FCON); }
159 0[xX]{H}+"."{P}{FS}?    { yylval.nodep = fhexcon(yytext); return(C_FCON); }
160 0[xX]{H}+{P}{FS}?       { yylval.nodep = fhexcon(yytext); return(C_FCON); }
162 L?\"(\\.|[^\\"])*\"     { yylval.strp = yytext; return C_STRING; }
164 "..."                   { return(C_ELLIPSIS); }
165 ">>="                   { yylval.intval = RSEQ; return(C_ASOP); }
166 "<<="                   { yylval.intval = LSEQ; return(C_ASOP); }
167 "+="                    { yylval.intval = PLUSEQ; return(C_ASOP); }
168 "-="                    { yylval.intval = MINUSEQ; return(C_ASOP); }
169 "*="                    { yylval.intval = MULEQ; return(C_ASOP); }
170 "/="                    { yylval.intval = DIVEQ; return(C_ASOP); }
171 "%="                    { yylval.intval = MODEQ; return(C_ASOP); }
172 "&="                    { yylval.intval = ANDEQ; return(C_ASOP); }
173 "^="                    { yylval.intval = EREQ; return(C_ASOP); }
174 "|="                    { yylval.intval = OREQ; return(C_ASOP); }
175 ">>"                    { yylval.intval = RS; return(C_SHIFTOP); }
176 "<<"                    { yylval.intval = LS; return(C_SHIFTOP); }
177 "++"                    { yylval.intval = INCR; return(C_INCOP); }
178 "--"                    { yylval.intval = DECR; return(C_INCOP); }
179 "->"                    { yylval.intval = STREF; return(C_STROP); }
180 "&&"                    { yylval.intval = ANDAND; return(C_ANDAND); }
181 "||"                    { yylval.intval = OROR; return(C_OROR); }
182 "<="                    { yylval.intval = LE; return(C_RELOP); }
183 ">="                    { yylval.intval = GE; return(C_RELOP); }
184 "=="                    { yylval.intval = EQ; return(C_EQUOP); }
185 "!="                    { yylval.intval = NE; return(C_EQUOP); }
186 ";"                     { notype = 0; return(';'); }
187 ("{"|"<%")              { notype = 0; return('{'); }
188 ("}"|"%>")              { if (rpole) notype = 1; return('}'); }
189 ","                     { if (parbal) notype = 0; return(','); }
190 ":"                     { return(':'); }
191 "="                     { return('='); }
192 "("                     { parbal++; notype = 0; return('('); }
193 ")"                     {       parbal--;
194                                 if (parbal==0) { notype = 0; }
195                                 if (inattr && parlvl == parbal)
196                                         inattr = 0;
197                                 return(')'); }
198 ("["|"<:")              { return('['); }
199 ("]"|":>")              { return(']'); }
200 "."                     { yylval.intval = DOT; return(C_STROP); }
201 "&"                     { return('&'); }
202 "!"                     { yylval.intval = NOT; return(C_UNOP); }
203 "~"                     { yylval.intval = COMPL; return(C_UNOP); }
204 "-"                     { return('-'); }
205 "+"                     { return('+'); }
206 "*"                     { if (parbal && notype == 0) notype = 1; return('*'); }
207 "/"                     { yylval.intval = DIV; return(C_DIVOP); }
208 "%"                     { yylval.intval = MOD; return(C_DIVOP); }
209 "<"                     { yylval.intval = LT; return(C_RELOP); }
210 ">"                     { yylval.intval = GT; return(C_RELOP); }
211 "^"                     { return('^'); }
212 "|"                     { return('|'); }
213 "?"                     { return('?'); }
214 ^#pragma[ \t].*         { pragma(); }
215 ^#ident[ \t].*          { control(CPP_IDENT); }
216 ^#line[ \t].*           { control(CPP_LINE); }
217 ^#.*                    { control(CPP_HASH); }
219 [ \t\v\f]               { }
220 "\n"                    { ++lineno; STABS_LINE(lineno); }
221 .                       { /* ignore bad characters */ }
225 int lineno;
226 char *ftitle = "<stdin>";
229 yywrap(void)
231         if (0) unput(0); /* quiet gcc */
232         return(1);
236 resw(TWORD t, int rv)
238         if (inattr) {
239                 yylval.strp = addname(yytext);
240                 return C_NAME;
241         }
243         switch (rv) {
244         case C_CLASS:
245                 yylval.nodep = block(CLASS, NIL, NIL, t, 0, 0);
246                 return rv;
248         case C_QUALIFIER:
249                 yylval.nodep = block(QUALIFIER, NIL, NIL, 0, 0, 0);
250                 yylval.nodep->n_qual = t;
251                 return rv;
253         case C_TYPE:
254                 yylval.nodep = mkty(t, 0, MKAP(t));
255                 notype=1;
256                 return(rv);
258         default:
259                 cerror("resw");
260         }
261         return 0;
264 #ifndef SOFTFLOAT
266 static long double
267 typround(long double dc, char *e, TWORD *tw)
269         int im = 0;
271         *tw = DOUBLE;
272         for (; *e; e++) {
273                 switch (*e) {
274                 case 'f':
275                 case 'F':
276                         *tw = FLOAT;
277                         dc = (float)dc;
278                         break;
279                 case 'l':
280                 case 'L':
281                         *tw = LDOUBLE;
282                         break;
283                 case 'i':
284                 case 'I':
285                         im = 1;
286                         break;
287                 }
288         }
289         if (*tw == DOUBLE)
290                 dc = (double)dc;
291 #ifndef NO_COMPLEX
292         if (im)
293                 *tw += (FIMAG-FLOAT);
294 #endif
295         return dc;
299  * XXX floatcon() and fhexcon() should be in support libraries for
300  * the target floating point.
301  */
302 static NODE *
303 f2(char *str)
305         TWORD tw;
306         NODE *p;
307         long double dc;
308         char *eptr;
310 #ifdef HAVE_STRTOLD
311         dc = strtold(str, &eptr); /* XXX - avoid strtod() */
312 #else
313         dc = strtod(str, &eptr); /* XXX - avoid strtod() */
314 #endif
315         dc = typround(dc, eptr, &tw);
316         p = block(FCON, NIL, NIL, tw, 0, MKAP(tw));
317         p->n_dcon = dc;
318         return p;
321 NODE *
322 floatcon(char *s)
324         return f2(s);
327 static int
328 h2n(int ch)
330         if (ch >= '0' && ch <= '9')
331                 return ch - '0';
332         if (ch >= 'a' && ch <= 'f')
333                 return ch - 'a' + 10;
334         return ch - 'A' + 10;
335         
338 NODE *
339 fhexcon(char *c)
341         TWORD tw;
342         char *ep;
343         long double d;
344         int i, ed;
345         NODE *p;
347         d = 0.0;
348         ed = 0;
349         c+= 2; /* skip 0x */
350 #define FSET(n) { d *= 2; if (i & n) d += 1.0; }
351         for (; *c != '.' && *c != 'p' && *c != 'P'; c++) {
352                 i = h2n(*c);
353                 FSET(8); FSET(4); FSET(2); FSET(1);
354         }
355         if (*c != '.' && *c != 'p' && *c != 'P')
356                 cerror("fhexcon");
357         if (*c == '.') {
358                 c++;
359                 for (; *c != 'p' && *c != 'P'; c++) {
360                         i = h2n(*c);
361                         FSET(8); FSET(4); FSET(2); FSET(1);
362                         ed -= 4;
363                 }
364         }
365         if (*c != 'P' && *c != 'p')
366                 cerror("fhexcon2");
367         c++;
368         ed += strtol(c, &ep, 10);
370         /* avoid looping in vain. Idea from Fred J. Tydeman */
371         if (ed > 32769) ed = 32769;
372         if (ed < -32769) ed = -32769;
374         while (ed > 0)
375                 d *= 2, ed--;
376         while (ed < 0)
377                 d /= 2, ed++;
378         d = typround(d, ep, &tw);
379         p = block(FCON, NIL, NIL, tw, 0, MKAP(tw));
380         p->n_dcon = d;
381         return p;
383 #endif
385 unsigned int
386 esccon(char **sptr)
388         char *wr = *sptr;
389         char *owr;
390         char c;
391         unsigned int val;
392         int wsz = 4, esccon_warn = 1;
394         switch (*wr++) {
395         case 'a': val = '\a'; break;
396         case 'b': val = '\b'; break;
397         case 'f': val = '\f'; break;
398         case 'n': val = '\n'; break;
399         case 'r': val = '\r'; break;
400         case 't': val = '\t'; break;
401         case 'v': val = '\v'; break;
402         case '\"': val = '\"'; break;
403         case 'x': val = strtoul(wr, &wr, 16); break;
404         /* ISO/IEC 9099:1999 (E) 6.4.3 */
405         case 'U'|(char)0x80:
406                 esccon_warn = 0;
407                 /* FALLTHROUGH */
408         case 'U':
409                 wsz = 8;
410                 /* FALLTHROUGH */
411         case 'u':
412                 owr = wr;
413                 while (wr < (owr + wsz))
414                         if (*wr == '\0')
415                                 break;
416                         else
417                                 ++wr;
418                 if (wr != (owr + wsz)) {
419                         /* incomplete */
420                         val = strtoul(owr, &wr, 16);
421                 } else {
422                         c = owr[wsz];
423                         owr[wsz] = '\0'; /* prevent it from reading too much */
424                         val = strtoul(owr, &wr, 16);
425                         owr[wsz] = c;
426                 }
427                 if (wr != (owr + wsz))
428                         werror("incomplete universal character name");
429                 if (wsz == 4)
430                         val &= 0xFFFF;
431                 if (esccon_warn && ((val >= 0xD800 && val <= 0xDFFF) ||
432                     (val < 0xA0 && val != 0x24 && val != 0x40 && val != 0x60)))
433                         werror("invalid universal character name %04X", val);
434                 break;
435         case '0': case '1': case '2': case '3': case '4': 
436         case '5': case '6': case '7':
437                 val = wr[-1] - '0';
438                 if (*wr >= '0' && *wr <= '7') {
439                         val = (val << 3) + (*wr++ - '0');
440                         if (*wr >= '0' && *wr <= '7')
441                                 val = (val << 3) + (*wr++ - '0');
442                 }
443                 break;
444         default: val = wr[-1];
445         }
446         *sptr = wr;
447         return val;
450 NODE *
451 cvtdig(int radix)
453         NODE *p;
454         TWORD ntype;
455         unsigned long long v;
456         char *ch = yytext;
457         int n, numl, numu;
459         if (radix == 16)
460                 ch += 2; /* Skip 0x */
461         
462         v = 0;
463         while ((*ch >= '0' && *ch <= '9') || (*ch >= 'a' && *ch <= 'f') ||
464             (*ch >= 'A' && *ch <= 'F')) {
465                 v *= radix;
466                 n = *ch;
467                 n = (n <= '9' ? n - '0' : (n > 'F' ? n - 'a' : n - 'A') + 10);
468                 ch++;
469                 v += n;
470         }
471         /* Parse trailing chars */
472         ntype = INT;
473         numl = numu = 0;
474         for (n = 0; n < 3; n++) {
475                 if (*ch == 0)
476                         break;
477                 if ((*ch == 'l' || *ch == 'L') && numl < 2)
478                         ntype+=2, numl++;
479                 else if ((*ch == 'u' || *ch == 'U') && numu < 1)
480                         ntype = ENUNSIGN(ntype), numu++;
481                 else
482                         break;
483                 ch++;
484         }
485         if (*ch)
486                 uerror("constant has too many '%c'", *ch);
488         if (ntype == INT) {
489                 /* v contains a number. Get type correct */
490                 if (v > MAX_LONGLONG && radix != 10)
491                         ntype = ULONGLONG;
492                 else if (v > MAX_ULONG)
493                         ntype = LONGLONG;
494                 else if (v > MAX_LONG && radix != 10)
495                         ntype = ULONG;
496                 else if (v > MAX_UNSIGNED)
497                         ntype = LONG;
498                 else if (v > MAX_INT && radix != 10)
499                         ntype = UNSIGNED;
500         }
501         ntype = ctype(ntype);
502         p = xbcon(v, NULL, ntype);
503         ASGLVAL(p->n_slval, v);
505         return p;
509  * Convert a character constant to an integer.
510  */
511 NODE *
512 charcon(void)
514         int lastcon = 0;
515         int val, i = 0;
516         char *pp = yytext;
518         if (*pp == 'L')
519                 pp++;
520         pp++;
521         while (*pp != '\'') {
522                 if (*pp++ == '\\') {
523                         val = esccon(&pp);
524                 } else
525                         val = pp[-1];
526                 makecc(val, i);
527                 i++;
528         }
530         if (i == 0)
531                 uerror("empty character constant");
532         if (i > (SZINT/SZCHAR) || (i>1))
533                 werror("too many characters in character constant");
534         return bcon(lastcon);
537 NODE *
538 wcharcon(void)
540         unsigned int lastcon = 0;
541         unsigned int val, i = 0;
542         char *pp = yytext;
544         if (*pp == 'L')
545                 pp++;
546         pp++;
547         while (*pp != '\'') {
548                 if (*pp++ == '\\') {
549                         val = esccon(&pp);
550                 } else
551                         val = pp[-1];
552 #if WCHAR_SIZE == 2
553                 lastcon = (lastcon << 16) | (val & 0xFFFF);
554 #else
555                 lastcon = val;
556 #endif
557                 i++;
558         }
560         if (i == 0)
561                 uerror("empty wide character constant");
562         if (i > 1)
563                 werror("too many characters in wide character constant");
564         return xbcon(lastcon, NULL, ctype(UNSIGNED));
567 void
568 control(int t)
570         char *wr = yytext;
571         char *eptr;
572         int val;
574         wr++;   /* Skip initial '#' */
575         switch (t) {
576         case CPP_IDENT:
577                 return; /* Just skip these for now. */
579         case CPP_LINE:
580                 wr += 4;
581                 /* FALLTHROUGH */
582         case CPP_HASH:
583                 val = strtol(wr, &eptr, 10);
584                 if (wr == eptr) /* Illegal string */
585                         goto bad;
586                 wr = eptr;
587                 lineno = val - 1;
588                 while (*wr && *wr != '\"')
589                         wr++;
590                 if (*wr == 0)
591                         return;
592                 if (*wr++ != '\"')
593                         goto bad;
594                 eptr = wr;
595                 while (*wr && *wr != '\"')
596                         wr++;
597                 if (*wr != '\"')
598                         goto bad;
599                 *wr = 0;
600                 ftitle = addstring(eptr);
601 #ifdef STABS
602                 if (gflag)
603                         stabs_file(ftitle);
604 #endif
605         }
606         return;
607 bad:
608         werror("%s: illegal control", yytext);
611 int pragma_allpacked;
612 int pragma_packed, pragma_aligned;
613 char *pragma_renamed;
615 static int
616 pragmas_weak(char *str)
618         struct symtab *sp;
619         char *s1, *s2;
621         if ((s1 = pragtok(NULL)) == NULL)
622                 return 1;
623         if ((s2 = pragtok(NULL)) == NULL) {
624                 sp = lookup(addname(s1), SNORMAL);
625                 sp->sap = attr_add(sp->sap, gcc_attr_parse(bdty(NAME, "weak")));
626         } else if (*s2 == '=') {
627                 if ((s2 = pragtok(NULL)) == NULL)
628                         return 1;
629                 sp = lookup(addname(s2), SNORMAL);
630                 sp->sap = attr_add(sp->sap, gcc_attr_parse(bdty(CALL,
631                     bdty(NAME, "aliasweak"), bdty(STRING, s1, 0))));
632         } else
633                 return 1;
634         return 0;
637 char *pragstore;
639 /* trivial tokenizer for pragmas */
640 #define ps pragstore
641 char *
642 pragtok(char *sin)
644         static char ss[2];
645         char *rv;
647         if (sin)
648                 ps = sin;
650         for (; isspace((int)*ps); ps++)
651                 ;
652         if (*ps == 0)
653                 return NULL;
654         for (rv = ps; isalpha((int)*ps) || isdigit((int)*ps) || *ps == '_'; ps++)
655                 ;
656         ss[0] = *ps;
657         if (rv == ps) {
658                 rv = ss, ps++;
659         } else {
660                 *ps = 0;
661                 rv = tmpstrdup(rv);
662                 *ps = ss[0];
663         }
664         return rv;
667 /* return 1 on error */
669 eat(int ch)
671         char *s = pragtok(0);
672         return (s == 0 || *s != ch);
675 static int
676 pragmas_alpack(char *t)
678         char *s;
679         int ap;
681         ap = (s = pragtok(0)) ? atoi(s) : 1;
682         if (strcmp(t, "packed") == 0)
683                 pragma_packed = ap;
684         else
685                 pragma_aligned = ap;
686         return 0;
691  * Packing control.
692  * still missing push/pop.
693  */
694 static int
695 pragmas_pack(char *t)
697         char *s;
699         if (eat('('))
700                 return 1;
701         s = pragtok(0);
702         if (*s == ')')
703                 return pragma_allpacked = 0;
705         if (*s < '0' || *s > '9') /* no number */
706                 return 1;
707         pragma_allpacked = atoi(s);
708         return eat(')');
711 static int
712 pragmas_renamed(char *t)
714         char *f = pragtok(0);
716         if (f == 0)
717                 return 1;
718         pragma_renamed = newstring(f, strlen(f));
719         return 0;
722 static int
723 pragmas_stdc(char *t)
725         return 0; /* Just ignore */
728 struct pragmas {
729         char *name;
730         int (*fun)(char *);
731 } pragmas[] = {
732         { "pack", pragmas_pack },
733         { "packed", pragmas_alpack },
734         { "aligned", pragmas_alpack },
735         { "rename", pragmas_renamed },
736 #ifdef GCC_COMPAT
737         { "GCC", pragmas_gcc },
738 #endif
739         { "STDC", pragmas_stdc },
740         { "weak", pragmas_weak },
741         { "ident", NULL },
742         { 0 },
745  * got a full pragma line.  Split it up here.
746  */
747 static void
748 pragma()
750         struct pragmas *p;
751         char *t, *pt;
753         if ((t = pragtok(&yytext[7])) != NULL) {
754                 pt = ps;
755                 for (p = pragmas; p->name; p++) {
756                         if (strcmp(t, p->name) == 0) {
757                                 if (p->fun && (*p->fun)(t))
758                                         uerror("bad argument to #pragma");
759                                 return;
760                         }
761                 }
762                 ps = pt;
763                 if (mypragma(t))
764                         return;
765         }
766         warner(Wunknown_pragmas, t, ps);
769 void
770 cunput(char c)
772         unput(c);