Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20120422210740

Diff

Diff from 1.2 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/cc/cxxcom/scan.l

Annotated File View

ragge
1.1
1 %{
plunky
1.2
2 /*      $Id: scan.l,v 1.2 2012/04/22 21:07:41 plunky Exp $      */
ragge
1.1
3
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  */
29 %}
30
31
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})
40
41 %{
42 #include <stdlib.h>
43 #include <errno.h>  
44 #include <string.h>
45 #include <stdarg.h>
46 #include <ctype.h>
47
48 #include "pass1.h"
49 #include "cgram.h"
50
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, nodinit, inoso;
57 static int resw(TWORD, int);
58 static int namechk(void);
59
60 #define CPP_IDENT       2
61 #define CPP_LINE        3
62 #define CPP_HASH        4
63
64 #ifdef STABS
65 #define STABS_LINE(x) if (gflag && cftnsp) stabs_line(x)
66 #else
67 #define STABS_LINE(x)
68 #endif
69 #if defined(FLEX_SCANNER) && YY_FLEX_SUBMINOR_VERSION == 31
70 /* Hack to avoid unnecessary warnings */
71 FILE *yyget_in  (void);
72 FILE *yyget_out  (void);
73 int yyget_leng  (void);
74 char *yyget_text  (void);
75 void yyset_in (FILE *);
76 void yyset_out (FILE *);
77 int yyget_debug  (void);
78 void yyset_debug (int);
79 int yylex_destroy  (void);
80 extern int yyget_lineno (void);
81 extern void yyset_lineno (int);
82 #endif
83
84 %}
85
86 %%
87
88 "__func__"              {
89                                 if (cftnsp == NULL)
90                                         uerror("__func__ outside function");
91                                 yylval.strp = cftnsp->sname; /* XXX - not C99 */
92                                 return(C_STRING);
93                         }
94 "asm"                   { return(C_ASM); }
95 "auto"                  {       return resw(AUTO, C_CLASS); }
96 "_Bool"                 {       return resw(BOOL, C_TYPE); }
97 "break"                 { return(C_BREAK); }
98 "case"                  { return(C_CASE); }
99 "char"                  {       return resw(CHAR, C_TYPE); }
100 "class"                 { yylval.intval = CLNAME; notype=1; return(C_STRUCT); }
101 "_Complex"              {       return resw(COMPLEX, C_TYPE); }
102 "const"                 {       return resw(CON, C_QUALIFIER); }
103 "const_cast"            { yylval.intval = CONST_CAST; return(CXX_CASTS); }
104 "continue"              { return(C_CONTINUE); }
105 "default"               { return(C_DEFAULT); }
106 "delete"                { return(CXX_DELETE); }
107 "do"                    { return(C_DO); }
108 "double"                {       return resw(DOUBLE, C_TYPE); }
109 "dynamic_cast"          { yylval.intval = DYN_CAST; return(CXX_CASTS); }
110 "else"                  { return(C_ELSE); }
111 "enum"                  { notype=1; return(C_ENUM); }
112 "extern"                {       return resw(EXTERN, C_CLASS); }
113 "float"                 {       return resw(FLOAT, C_TYPE); }
114 "for"                   { return(C_FOR); }
115 "goto"                  { notype=1; return(C_GOTO); }
116 "if"                    { return(C_IF); }
117 "_Imaginary"            {       return resw(IMAG, C_TYPE); }
118 "inline"                { return(C_FUNSPEC); }
119 "int"                   {       return resw(INT, C_TYPE); }
120 "long"                  {       return resw(LONG, C_TYPE); }
121 "namespace"             {       return(CXX_NAMESPACE); }
122 "new"                   {       notype = 0; return(CXX_NEW); }
123 "register"              {       return resw(REGISTER, C_CLASS); }
124 "reinterpret_cast"      { yylval.intval = REINT_CAST; return(CXX_CASTS); }
125 "restrict"              { ; /* just ignore */ }
126 "return"                { return(C_RETURN); }
127 "short"                 {       return resw(SHORT, C_TYPE); }
128 "signed"                {       return resw(SIGNED, C_TYPE); }
129 "sizeof"                { return(C_SIZEOF); }
130 "static"                {       return resw(STATIC, C_CLASS); }
131 "static_cast"           { yylval.intval = STATIC_CAST; return(CXX_CASTS); }
132 "struct"                { yylval.intval = STNAME; notype=1; return(C_STRUCT); }
133 "switch"                { return(C_SWITCH); }
134 "template"              { return(CXX_TEMPLATE); }
135 "typedef"               {       return resw(TYPEDEF, C_CLASS); }
136 "typename"              { return(CXX_TYPENAME); }
137 "union"                 { yylval.intval = UNAME; notype=1; return(C_STRUCT); }
138 "unsigned"              {       return resw(UNSIGNED, C_TYPE); }
139 "using"                 { return(CXX_USING); }
140 "void"                  {       return resw(VOID, C_TYPE); }
141 "volatile"              {       return resw(VOL, C_QUALIFIER); }
142 "while"                 { return(C_WHILE); }
143
144 {UL}({UL}|{D})*         { return namechk(); }
145 0[xX]{H}+{IS}?          { yylval.nodep = cvtdig(16); return(C_ICON); }
146 0{D}+{IS}?              { yylval.nodep = cvtdig(8); return(C_ICON); }
147 {D}+{IS}?               { yylval.nodep = cvtdig(10); return(C_ICON); }
148 L'(\\.|[^\\'])+'        { yylval.nodep = wcharcon(); return(C_ICON); }
149 '(\\.|[^\\'])+'         { yylval.nodep = charcon(); return(C_ICON); }
150
151 {D}+{E}{FS}?            { yylval.nodep = floatcon(yytext); return(C_FCON); }
152 {D}*"."{D}+({E})?{FS}?  { yylval.nodep = floatcon(yytext); return(C_FCON); }
153 {D}+"."{D}*({E})?{FS}?  { yylval.nodep = floatcon(yytext); return(C_FCON); }
154 0[xX]{H}*"."{H}+{P}{FS}? { yylval.nodep = fhexcon(yytext); return(C_FCON); }
155 0[xX]{H}+"."{P}{FS}?    { yylval.nodep = fhexcon(yytext); return(C_FCON); }
156 0[xX]{H}+{P}{FS}?       { yylval.nodep = fhexcon(yytext); return(C_FCON); }
157
158 L?\"(\\.|[^\\"])*\"     { yylval.strp = yytext; return C_STRING; }
159
160 "..."                   { return(C_ELLIPSIS); }
161 ">>="                   { yylval.intval = RSEQ; return(C_ASOP); }
162 "<<="                   { yylval.intval = LSEQ; return(C_ASOP); }
163 "+="                    { yylval.intval = PLUSEQ; return(C_ASOP); }
164 "-="                    { yylval.intval = MINUSEQ; return(C_ASOP); }
165 "*="                    { yylval.intval = MULEQ; return(C_ASOP); }
166 "/="                    { yylval.intval = DIVEQ; return(C_ASOP); }
167 "%="                    { yylval.intval = MODEQ; return(C_ASOP); }
168 "&="                    { yylval.intval = ANDEQ; return(C_ASOP); }
169 "^="                    { yylval.intval = EREQ; return(C_ASOP); }
170 "|="                    { yylval.intval = OREQ; return(C_ASOP); }
171 ">>"                    { yylval.intval = RS; return(C_SHIFTOP); }
172 "<<"                    { yylval.intval = LS; return(C_SHIFTOP); }
173 "++"                    { yylval.intval = INCR; return(C_INCOP); }
174 "--"                    { yylval.intval = DECR; return(C_INCOP); }
175 "->"                    { yylval.intval = STREF; return(C_STROP); }
176 "&&"                    { yylval.intval = ANDAND; return(C_ANDAND); }
177 "||"                    { yylval.intval = OROR; return(C_OROR); }
178 "<="                    { yylval.intval = LE; return(C_RELOP); }
179 ">="                    { yylval.intval = GE; return(C_RELOP); }
180 "=="                    { yylval.intval = EQ; return(C_EQUOP); }
181 "!="                    { yylval.intval = NE; return(C_EQUOP); }
182 "::"                    { return(CXX_DUALCC); }
183 ";"                     { notype = 0; return(';'); }
184 ("{"|"<%")              { notype = 0; return('{'); }
185 ("}"|"%>")              { if (rpole) notype = 1; return('}'); }
186 ","                     { if (parbal && !inoso) notype = 0; return(','); }
187 ":"                     { if (doing_init) nodinit--; return(':'); }
188 "="                     { return('='); }
189 "("                     { parbal++; notype = 0; return('('); }
190 ")"                     {       parbal--;
191                                 inoso = 0;
192                                 if (parbal==0) { notype = 0; }
193                                 if (inattr && parlvl == parbal)
194                                         inattr = 0;
195                                 return(')'); }
196 ("["|"<:")              { return('['); }
197 ("]"|":>")              { return(']'); }
198 "."                     { yylval.intval = DOT; return(C_STROP); }
199 "&"                     { return('&'); }
200 "!"                     { yylval.intval = NOT; return(C_UNOP); }
201 "~"                     { yylval.intval = COMPL; return(C_UNOP); }
202 "-"                     { return('-'); }
203 "+"                     { return('+'); }
204 "*"                     { if (parbal && notype == 0) notype = 1; return('*'); }
205 "/"                     { yylval.intval = DIV; return(C_DIVOP); }
206 "%"                     { yylval.intval = MOD; return(C_DIVOP); }
207 "<"                     { yylval.intval = LT; return(C_RELOP); }
208 ">"                     { yylval.intval = GT; return(C_RELOP); }
209 "^"                     { return('^'); }
210 "|"                     { return('|'); }
211 "?"                     { if (doing_init) nodinit++; return('?'); }
212 ^#pragma[ \t].*         { pragma(); }
213 ^#ident[ \t].*          { control(CPP_IDENT); }
214 ^#line[ \t].*           { control(CPP_LINE); }
215 ^#.*                    { control(CPP_HASH); }
216
217 [ \t\v\f]               { }
218 "\n"                    { ++lineno; STABS_LINE(lineno); }
219 .                       { /* ignore bad characters */ }
220
221 %%
222
223 int lineno;
224 char *ftitle = "<stdin>";
225
226 static int
plunky
1.2
227 namechk(void)
ragge
1.1
228 {       
229         struct symtab *s;
230         int i;
231
232         yylval.strp = addname(yytext);
233
234         while ((i = input()) == ' ' || i == '\t')
235                 ;
236         if (i == ':') {
237                 if ((i = input()) == ':')
238                         return CXX_MORENM;
239                 unput(i);
240                 if (doing_init && nodinit == 0)
241                         return(GCC_DESIG);
242                 i = ':';
243         }
244         unput(i);
245
246         if ((i = gcc_keyword(yylval.strp, &yylval.nodep)) > 0)
247                 return i;
248
249         if (notype)
250                 return(C_NAME);
251         s = lookup(yylval.strp, SNOCREAT);
252         return s && s->sclass == TYPEDEF ?  notype=1, C_TYPENAME : C_NAME;
253 }
254
255 int
256 yywrap(void)
257 {
258         if (0) unput(0); /* quiet gcc */
259         return(1);
260 }
261
262 int
263 resw(TWORD t, int rv)
264 {
265         if (inattr) {
266                 yylval.strp = addname(yytext);
267                 return C_NAME;
268         }
269
270         switch (rv) {
271         case C_CLASS:
272                 yylval.nodep = block(CLASS, NIL, NIL, t, 0, 0);
273                 return rv;
274
275         case C_QUALIFIER:
276                 yylval.nodep = block(QUALIFIER, NIL, NIL, 0, 0, 0);
277                 yylval.nodep->n_qual = t;
278                 return rv;
279
280         case C_TYPE:
281                 yylval.nodep = mkty(t, 0, 0);
282                 notype=1;
283                 return(rv);
284
285         default:
286                 cerror("resw");
287         }
288         return 0;
289 }
290
291 #ifndef SOFTFLOAT
292
293 static long double
294 typround(long double dc, char *e, TWORD *tw)
295 {
296         int im = 0;
297
298         *tw = DOUBLE;
299         for (; *e; e++) {
300                 switch (*e) {
301                 case 'f':
302                 case 'F':
303                         *tw = FLOAT;
304                         dc = (float)dc;
305                         break;
306                 case 'l':
307                 case 'L':
308                         *tw = LDOUBLE;
309                         break;
310                 case 'i':
311                 case 'I':
312                         im = 1;
313                         break;
314                 }
315         }
316         if (*tw == DOUBLE)
317                 dc = (double)dc;
318 #ifndef NO_COMPLEX
319         if (im)
320                 *tw += (FIMAG-FLOAT);
321 #endif
322         return dc;
323 }
324
325 /*
326  * XXX floatcon() and fhexcon() should be in support libraries for
327  * the target floating point.
328  */
329 static NODE *
330 f2(char *str)
331 {
332         TWORD tw;
333         NODE *p;
334         long double dc;
335         char *eptr;
336
337 #ifdef HAVE_STRTOLD
338         dc = strtold(str, &eptr); /* XXX - avoid strtod() */
339 #else
340         dc = strtod(str, &eptr); /* XXX - avoid strtod() */
341 #endif
342         dc = typround(dc, eptr, &tw);
343         p = block(FCON, NIL, NIL, tw, 0, 0);
344         p->n_dcon = dc;
345         return p;
346 }
347
348 NODE *
349 floatcon(char *s)
350 {
351         return f2(s);
352 }
353
354 static int
355 h2n(int ch)
356 {
357         if (ch >= '0' && ch <= '9')
358                 return ch - '0';
359         if (ch >= 'a' && ch <= 'f')
360                 return ch - 'a' + 10;
361         return ch - 'A' + 10;
362         
363 }
364
365 NODE *
366 fhexcon(char *c)
367 {
368         TWORD tw;
369         char *ep;
370         long double d;
371         int i, ed;
372         NODE *p;
373
374         d = 0.0;
375         ed = 0;
376         c+= 2; /* skip 0x */
377 #define FSET(n) { d *= 2; if (i & n) d += 1.0; }
378         for (; *c != '.' && *c != 'p' && *c != 'P'; c++) {
379                 i = h2n(*c);
380                 FSET(8); FSET(4); FSET(2); FSET(1);
381         }
382         if (*c != '.' && *c != 'p' && *c != 'P')
383                 cerror("fhexcon");
384         if (*c == '.') {
385                 c++;
386                 for (; *c != 'p' && *c != 'P'; c++) {
387                         i = h2n(*c);
388                         FSET(8); FSET(4); FSET(2); FSET(1);
389                         ed -= 4;
390                 }
391         }
392         if (*c != 'P' && *c != 'p')
393                 cerror("fhexcon2");
394         c++;
395         ed += strtol(c, &ep, 10);
396
397         /* avoid looping in vain. Idea from Fred J. Tydeman */
398         if (ed > 32769) ed = 32769;
399         if (ed < -32769) ed = -32769;
400
401         while (ed > 0)
402                 d *= 2, ed--;
403         while (ed < 0)
404                 d /= 2, ed++;
405         d = typround(d, ep, &tw);
406         p = block(FCON, NIL, NIL, tw, 0, 0);
407         p->n_dcon = d;
408         return p;
409 }
410 #endif
411
412 unsigned int
413 esccon(char **sptr)
414 {
415         char *wr = *sptr;
416         char *owr;
417         char c;
418         unsigned int val;
419         int wsz = 4, esccon_warn = 1;
420
421         switch (*wr++) {
422         case 'a': val = '\a'; break;
423         case 'b': val = '\b'; break;
424         case 'f': val = '\f'; break;
425         case 'n': val = '\n'; break;
426         case 'r': val = '\r'; break;
427         case 't': val = '\t'; break;
428         case 'v': val = '\v'; break;
429         case '\"': val = '\"'; break;
430         case 'x': val = strtoul(wr, &wr, 16); break;
431         /* ISO/IEC 9099:1999 (E) 6.4.3 */
432         case 'U'|(char)0x80:
433                 esccon_warn = 0;
434                 /* FALLTHROUGH */
435         case 'U':
436                 wsz = 8;
437                 /* FALLTHROUGH */
438         case 'u':
439                 owr = wr;
440                 while (wr < (owr + wsz))
441                         if (*wr == '\0')
442                                 break;
443                         else
444                                 ++wr;
445                 if (wr != (owr + wsz)) {
446                         /* incomplete */
447                         val = strtoul(owr, &wr, 16);
448                 } else {
449                         c = owr[wsz];
450                         owr[wsz] = '\0'; /* prevent it from reading too much */
451                         val = strtoul(owr, &wr, 16);
452                         owr[wsz] = c;
453                 }
454                 if (wr != (owr + wsz))
455                         werror("incomplete universal character name");
456                 if (wsz == 4)
457                         val &= 0xFFFF;
458                 if (esccon_warn && ((val >= 0xD800 && val <= 0xDFFF) ||
459                     (val < 0xA0 && val != 0x24 && val != 0x40 && val != 0x60)))
460                         werror("invalid universal character name %04X", val);
461                 break;
462         case '0': case '1': case '2': case '3': case '4': 
463         case '5': case '6': case '7':
464                 val = wr[-1] - '0';
465                 if (*wr >= '0' && *wr <= '7') {
466                         val = (val << 3) + (*wr++ - '0');
467                         if (*wr >= '0' && *wr <= '7')
468                                 val = (val << 3) + (*wr++ - '0');
469                 }
470                 break;
471         default: val = wr[-1];
472         }
473         *sptr = wr;
474         return val;
475 }
476
477 NODE *
478 cvtdig(int radix)
479 {
480         NODE *p;
481         TWORD otype, ntype;
482         unsigned long long v;
483         char *ch = yytext;
484         int n, numl, numu;
485
486         if (radix == 16)
487                 ch += 2; /* Skip 0x */
488         
489         v = 0;
490         while ((*ch >= '0' && *ch <= '9') || (*ch >= 'a' && *ch <= 'f') ||
491             (*ch >= 'A' && *ch <= 'F')) {
492                 v *= radix;
493                 n = *ch;
494                 n = (n <= '9' ? n - '0' : (n > 'F' ? n - 'a' : n - 'A') + 10);
495                 ch++;
496                 v += n;
497         }
498         /* Parse trailing chars */
499         ntype = INT;
500         numl = numu = 0;
501         for (n = 0; n < 3; n++) {
502                 if (*ch == 0)
503                         break;
504                 if ((*ch == 'l' || *ch == 'L') && numl < 2)
505                         ntype+=2, numl++;
506                 else if ((*ch == 'u' || *ch == 'U') && numu < 1)
507                         ntype = ENUNSIGN(ntype), numu++;
508                 else
509                         break;
510                 ch++;
511         }
512         if (*ch)
513                 uerror("constant has too many '%c'", *ch);
514
515         otype = ntype;
516         switch (ntype) {
517         case INT:
518         case LONG:
519         case LONGLONG:
520                 if (radix == 10) {
521                         if (otype == LONGLONG)
522                                 break;
523                         if (v > MAX_LONG) { 
524                                 ntype = LONGLONG;
525                                 if (otype == LONG)
526                                         break;
527                         } else if (v > MAX_INT)
528                                 ntype = LONG;
529                 } else {
530                         if (v > MAX_LONGLONG) {
531                                 ntype = ULONGLONG;
532                                 if (otype == LONGLONG)
533                                         break;
534                         } else if (v > MAX_ULONG) {
535                                 ntype = LONGLONG;
536                         } else if (v > MAX_LONG) {
537                                 ntype = ULONG;
538                                 if (otype == LONG)
539                                         break;
540                         } else if (v > MAX_UNSIGNED) {
541                                 ntype = LONG;
542                         } else if (v > MAX_INT)
543                                 ntype = UNSIGNED;
544                 }
545                 break;
546         case UNSIGNED:
547         case ULONG:
548                 if (v > MAX_ULONG) {
549                         ntype = ULONGLONG;
550                         if (otype == ULONG)
551                                 break;
552                 } else if (v > MAX_UNSIGNED)
553                         ntype = ULONG;
554                 break;  
555         }       
556
557         ntype = ctype(ntype);
558         p = xbcon(v, NULL, ntype);
559         ASGLVAL(p->n_slval, v);
560
561         return p;
562 }
563
564 /*
565  * Convert a character constant to an integer.
566  */
567 NODE *
568 charcon(void)
569 {
570         int lastcon = 0;
571         int val, i = 0;
572         char *pp = yytext;
573
574         if (*pp == 'L')
575                 pp++;
576         pp++;
577         while (*pp != '\'') {
578                 if (*pp++ == '\\') {
579                         val = esccon(&pp);
580                 } else
581                         val = pp[-1];
582                 makecc(val, i);
583                 i++;
584         }
585
586         if (i == 0)
587                 uerror("empty character constant");
588         if (i > (SZINT/SZCHAR) || (i>1))
589                 werror("too many characters in character constant");
590         return bcon(lastcon);
591 }
592
593 NODE *
594 wcharcon(void)
595 {
596         unsigned int lastcon = 0;
597         unsigned int val, i = 0;
598         char *pp = yytext;
599
600         if (*pp == 'L')
601                 pp++;
602         pp++;
603         while (*pp != '\'') {
604                 if (*pp++ == '\\') {
605                         val = esccon(&pp);
606                 } else
607                         val = pp[-1];
608 #if WCHAR_SIZE == 2
609                 lastcon = (lastcon << 16) | (val & 0xFFFF);
610 #else
611                 lastcon = val;
612 #endif
613                 i++;
614         }
615
616         if (i == 0)
617                 uerror("empty wide-character constant");
618         if (i > 1)
619                 werror("too many characters in wide-character constant");
620         return xbcon(lastcon, NULL, ctype(UNSIGNED));
621 }
622
623 void
624 control(int t)
625 {
626         char *wr = yytext;
627         char *eptr;
628         int val;
629
630         wr++;   /* Skip initial '#' */
631         switch (t) {
632         case CPP_IDENT:
633                 return; /* Just skip these for now. */
634
635         case CPP_LINE:
636                 wr += 4;
637                 /* FALLTHROUGH */
638         case CPP_HASH:
639                 val = strtol(wr, &eptr, 10);
640                 if (wr == eptr) /* Illegal string */
641                         goto bad;
642                 wr = eptr;
643                 lineno = val - 1;
644                 while (*wr && *wr != '\"')
645                         wr++;
646                 if (*wr == 0)
647                         return;
648                 if (*wr++ != '\"')
649                         goto bad;
650                 eptr = wr;
651                 while (*wr && *wr != '\"')
652                         wr++;
653                 if (*wr != '\"')
654                         goto bad;
655                 *wr = 0;
656                 ftitle = addstring(eptr);
657 #ifdef STABS
658                 if (gflag)
659                         stabs_file(ftitle);
660 #endif
661         }
662         return;
663 bad:
664         werror("%s: illegal control", yytext);
665 }
666
667 int pragma_allpacked;
668 int pragma_packed, pragma_aligned;
669 char *pragma_renamed;
670
671 static int
672 pragmas_weak(char *str)
673 {
674         struct symtab *sp;
675         char *s1, *s2;
676
677         if ((s1 = pragtok(NULL)) == NULL)
678                 return 1;
679         if ((s2 = pragtok(NULL)) == NULL) {
680                 sp = lookup(addname(s1), SNORMAL);
681                 sp->sap = attr_add(sp->sap, gcc_attr_parse(bdty(NAME, "weak")));
682         } else if (*s2 == '=') {
683                 if ((s2 = pragtok(NULL)) == NULL)
684                         return 1;
685                 sp = lookup(addname(s2), SNORMAL);
686                 sp->sap = attr_add(sp->sap, gcc_attr_parse(bdty(CALL,
687                     bdty(NAME, "aliasweak"), bdty(STRING, s1, 0))));
688         } else
689                 return 1;
690         return 0;
691 }
692
693 char *pragstore;
694
695 /* trivial tokenizer for pragmas */
696 #define ps pragstore
697 char *
698 pragtok(char *sin)
699 {
700         static char ss[2];
701         char *rv;
702
703         if (sin)
704                 ps = sin;
705
706         for (; isspace((int)*ps); ps++)
707                 ;
708         if (*ps == 0)
709                 return NULL;
710         for (rv = ps; isalpha((int)*ps) || isdigit((int)*ps) || *ps == '_'; ps++)
711                 ;
712         ss[0] = *ps;
713         if (rv == ps) {
714                 rv = ss, ps++;
715         } else {
716                 *ps = 0;
717                 rv = tmpstrdup(rv);
718                 *ps = ss[0];
719         }
720         return rv;
721 }
722
723 /* return 1 on error */
724 int
725 eat(int ch)
726 {
727         char *s = pragtok(0);
728         return (s == 0 || *s != ch);
729 }
730
731 static int
732 pragmas_alpack(char *t)
733 {
734         char *s;
735         int ap;
736
737         ap = (s = pragtok(0)) ? atoi(s) : 1;
738         if (strcmp(t, "packed") == 0)
739                 pragma_packed = ap;
740         else
741                 pragma_aligned = ap;
742         return 0;
743 }
744
745
746 /*
747  * Packing control.
748  * still missing push/pop.
749  */
750 static int
751 pragmas_pack(char *t)
752 {
753         char *s;
754
755         if (eat('('))
756                 return 1;
757         s = pragtok(0);
758         if (*s == ')')
759                 return pragma_allpacked = 0;
760
761         if (*s < '0' || *s > '9') /* no number */
762                 return 1;
763         pragma_allpacked = atoi(s);
764         return eat(')');
765 }
766
767 static int
768 pragmas_renamed(char *t)
769 {
770         char *f = pragtok(0);
771
772         if (f == 0)
773                 return 1;
774         pragma_renamed = newstring(f, strlen(f));
775         return 0;
776 }
777
778 static int
779 pragmas_stdc(char *t)
780 {
781         return 0; /* Just ignore */
782 }
783
784 struct pragmas {
785         char *name;
786         int (*fun)(char *);
787 } pragmas[] = {
788         { "pack", pragmas_pack },
789         { "packed", pragmas_alpack },
790         { "aligned", pragmas_alpack },
791         { "rename", pragmas_renamed },
792 #ifdef GCC_COMPAT
793         { "GCC", pragmas_gcc },
794 #endif
795         { "STDC", pragmas_stdc },
796         { "weak", pragmas_weak },
797         { "ident", NULL },
798         { 0 },
799 };
plunky
1.2
800
ragge
1.1
801 /*
802  * got a full pragma line.  Split it up here.
803  */
804 static void
plunky
1.2
805 pragma(void)
ragge
1.1
806 {
807         struct pragmas *p;
808         char *t, *pt;
809
810         if ((t = pragtok(&yytext[7])) != NULL) {
811                 pt = ps;
812                 for (p = pragmas; p->name; p++) {
813                         if (strcmp(t, p->name) == 0) {
814                                 if (p->fun && (*p->fun)(t))
815                                         uerror("bad argument to #pragma");
816                                 return;
817                         }
818                 }
819                 ps = pt;
820                 if (mypragma(t))
821                         return;
822         }
823         warner(Wunknown_pragmas, t, ps);
824 }
825
826 void
827 cunput(char c)
828 {
829         unput(c);
830 }
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-08-28 09:06 +0200