Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20140818112734

Diff

Diff from 1.5 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.5
2 /*      $Id: scan.l,v 1.5 2014/08/18 11:27:34 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); }
plunky
1.5
148 L'(\\.|[^\\'])*'        { yylval.nodep = wcharcon(); return(C_ICON); }
149 '(\\.|[^\\'])*'         { yylval.nodep = charcon(); return(C_ICON); }
ragge
1.1
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
ragge
1.3
223 int lineno, issyshdr;
ragge
1.1
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
ragge
1.4
246 #ifdef GCC_COMPAT
ragge
1.1
247         if ((i = gcc_keyword(yylval.strp, &yylval.nodep)) > 0)
248                 return i;
ragge
1.4
249 #endif
ragge
1.1
250
251         if (notype)
252                 return(C_NAME);
253         s = lookup(yylval.strp, SNOCREAT);
254         return s && s->sclass == TYPEDEF ?  notype=1, C_TYPENAME : C_NAME;
255 }
256
257 int
258 yywrap(void)
259 {
260         if (0) unput(0); /* quiet gcc */
261         return(1);
262 }
263
264 int
265 resw(TWORD t, int rv)
266 {
267         if (inattr) {
268                 yylval.strp = addname(yytext);
269                 return C_NAME;
270         }
271
272         switch (rv) {
273         case C_CLASS:
274                 yylval.nodep = block(CLASS, NIL, NIL, t, 0, 0);
275                 return rv;
276
277         case C_QUALIFIER:
278                 yylval.nodep = block(QUALIFIER, NIL, NIL, 0, 0, 0);
279                 yylval.nodep->n_qual = t;
280                 return rv;
281
282         case C_TYPE:
283                 yylval.nodep = mkty(t, 0, 0);
284                 notype=1;
285                 return(rv);
286
287         default:
288                 cerror("resw");
289         }
290         return 0;
291 }
292
293 #ifndef SOFTFLOAT
294
295 static long double
296 typround(long double dc, char *e, TWORD *tw)
297 {
298         int im = 0;
299
300         *tw = DOUBLE;
301         for (; *e; e++) {
302                 switch (*e) {
303                 case 'f':
304                 case 'F':
305                         *tw = FLOAT;
306                         dc = (float)dc;
307                         break;
308                 case 'l':
309                 case 'L':
310                         *tw = LDOUBLE;
311                         break;
312                 case 'i':
313                 case 'I':
314                         im = 1;
315                         break;
316                 }
317         }
318         if (*tw == DOUBLE)
319                 dc = (double)dc;
320 #ifndef NO_COMPLEX
321         if (im)
322                 *tw += (FIMAG-FLOAT);
323 #endif
324         return dc;
325 }
326
327 /*
328  * XXX floatcon() and fhexcon() should be in support libraries for
329  * the target floating point.
330  */
331 static NODE *
332 f2(char *str)
333 {
334         TWORD tw;
335         NODE *p;
336         long double dc;
337         char *eptr;
338
339 #ifdef HAVE_STRTOLD
340         dc = strtold(str, &eptr); /* XXX - avoid strtod() */
341 #else
342         dc = strtod(str, &eptr); /* XXX - avoid strtod() */
343 #endif
344         dc = typround(dc, eptr, &tw);
345         p = block(FCON, NIL, NIL, tw, 0, 0);
346         p->n_dcon = dc;
347         return p;
348 }
349
350 NODE *
351 floatcon(char *s)
352 {
353         return f2(s);
354 }
355
356 static int
357 h2n(int ch)
358 {
359         if (ch >= '0' && ch <= '9')
360                 return ch - '0';
361         if (ch >= 'a' && ch <= 'f')
362                 return ch - 'a' + 10;
363         return ch - 'A' + 10;
364         
365 }
366
367 NODE *
368 fhexcon(char *c)
369 {
370         TWORD tw;
371         char *ep;
372         long double d;
373         int i, ed;
374         NODE *p;
375
376         d = 0.0;
377         ed = 0;
378         c+= 2; /* skip 0x */
379 #define FSET(n) { d *= 2; if (i & n) d += 1.0; }
380         for (; *c != '.' && *c != 'p' && *c != 'P'; c++) {
381                 i = h2n(*c);
382                 FSET(8); FSET(4); FSET(2); FSET(1);
383         }
384         if (*c != '.' && *c != 'p' && *c != 'P')
385                 cerror("fhexcon");
386         if (*c == '.') {
387                 c++;
388                 for (; *c != 'p' && *c != 'P'; c++) {
389                         i = h2n(*c);
390                         FSET(8); FSET(4); FSET(2); FSET(1);
391                         ed -= 4;
392                 }
393         }
394         if (*c != 'P' && *c != 'p')
395                 cerror("fhexcon2");
396         c++;
397         ed += strtol(c, &ep, 10);
398
399         /* avoid looping in vain. Idea from Fred J. Tydeman */
400         if (ed > 32769) ed = 32769;
401         if (ed < -32769) ed = -32769;
402
403         while (ed > 0)
404                 d *= 2, ed--;
405         while (ed < 0)
406                 d /= 2, ed++;
407         d = typround(d, ep, &tw);
408         p = block(FCON, NIL, NIL, tw, 0, 0);
409         p->n_dcon = d;
410         return p;
411 }
412 #endif
413
414 unsigned int
415 esccon(char **sptr)
416 {
417         char *wr = *sptr;
418         char *owr;
419         char c;
420         unsigned int val;
421         int wsz = 4, esccon_warn = 1;
422
423         switch (*wr++) {
424         case 'a': val = '\a'; break;
425         case 'b': val = '\b'; break;
426         case 'f': val = '\f'; break;
427         case 'n': val = '\n'; break;
428         case 'r': val = '\r'; break;
429         case 't': val = '\t'; break;
430         case 'v': val = '\v'; break;
431         case '\"': val = '\"'; break;
432         case 'x': val = strtoul(wr, &wr, 16); break;
433         /* ISO/IEC 9099:1999 (E) 6.4.3 */
434         case 'U'|(char)0x80:
435                 esccon_warn = 0;
436                 /* FALLTHROUGH */
437         case 'U':
438                 wsz = 8;
439                 /* FALLTHROUGH */
440         case 'u':
441                 owr = wr;
442                 while (wr < (owr + wsz))
443                         if (*wr == '\0')
444                                 break;
445                         else
446                                 ++wr;
447                 if (wr != (owr + wsz)) {
448                         /* incomplete */
449                         val = strtoul(owr, &wr, 16);
450                 } else {
451                         c = owr[wsz];
452                         owr[wsz] = '\0'; /* prevent it from reading too much */
453                         val = strtoul(owr, &wr, 16);
454                         owr[wsz] = c;
455                 }
456                 if (wr != (owr + wsz))
457                         werror("incomplete universal character name");
458                 if (wsz == 4)
459                         val &= 0xFFFF;
460                 if (esccon_warn && ((val >= 0xD800 && val <= 0xDFFF) ||
461                     (val < 0xA0 && val != 0x24 && val != 0x40 && val != 0x60)))
462                         werror("invalid universal character name %04X", val);
463                 break;
464         case '0': case '1': case '2': case '3': case '4': 
465         case '5': case '6': case '7':
466                 val = wr[-1] - '0';
467                 if (*wr >= '0' && *wr <= '7') {
468                         val = (val << 3) + (*wr++ - '0');
469                         if (*wr >= '0' && *wr <= '7')
470                                 val = (val << 3) + (*wr++ - '0');
471                 }
472                 break;
473         default: val = wr[-1];
474         }
475         *sptr = wr;
476         return val;
477 }
478
479 NODE *
480 cvtdig(int radix)
481 {
482         NODE *p;
483         TWORD otype, ntype;
484         unsigned long long v;
485         char *ch = yytext;
486         int n, numl, numu;
487
488         if (radix == 16)
489                 ch += 2; /* Skip 0x */
490         
491         v = 0;
492         while ((*ch >= '0' && *ch <= '9') || (*ch >= 'a' && *ch <= 'f') ||
493             (*ch >= 'A' && *ch <= 'F')) {
494                 v *= radix;
495                 n = *ch;
496                 n = (n <= '9' ? n - '0' : (n > 'F' ? n - 'a' : n - 'A') + 10);
497                 ch++;
498                 v += n;
499         }
500         /* Parse trailing chars */
501         ntype = INT;
502         numl = numu = 0;
503         for (n = 0; n < 3; n++) {
504                 if (*ch == 0)
505                         break;
506                 if ((*ch == 'l' || *ch == 'L') && numl < 2)
507                         ntype+=2, numl++;
508                 else if ((*ch == 'u' || *ch == 'U') && numu < 1)
509                         ntype = ENUNSIGN(ntype), numu++;
510                 else
511                         break;
512                 ch++;
513         }
514         if (*ch)
515                 uerror("constant has too many '%c'", *ch);
516
517         otype = ntype;
518         switch (ntype) {
519         case INT:
520         case LONG:
521         case LONGLONG:
522                 if (radix == 10) {
523                         if (otype == LONGLONG)
524                                 break;
525                         if (v > MAX_LONG) { 
526                                 ntype = LONGLONG;
527                                 if (otype == LONG)
528                                         break;
529                         } else if (v > MAX_INT)
530                                 ntype = LONG;
531                 } else {
532                         if (v > MAX_LONGLONG) {
533                                 ntype = ULONGLONG;
534                                 if (otype == LONGLONG)
535                                         break;
536                         } else if (v > MAX_ULONG) {
537                                 ntype = LONGLONG;
538                         } else if (v > MAX_LONG) {
539                                 ntype = ULONG;
540                                 if (otype == LONG)
541                                         break;
542                         } else if (v > MAX_UNSIGNED) {
543                                 ntype = LONG;
544                         } else if (v > MAX_INT)
545                                 ntype = UNSIGNED;
546                 }
547                 break;
548         case UNSIGNED:
549         case ULONG:
550                 if (v > MAX_ULONG) {
551                         ntype = ULONGLONG;
552                         if (otype == ULONG)
553                                 break;
554                 } else if (v > MAX_UNSIGNED)
555                         ntype = ULONG;
556                 break;  
557         }       
558
559         ntype = ctype(ntype);
560         p = xbcon(v, NULL, ntype);
561         ASGLVAL(p->n_slval, v);
562
563         return p;
564 }
565
566 /*
567  * Convert a character constant to an integer.
568  */
569 NODE *
570 charcon(void)
571 {
572         int lastcon = 0;
573         int val, i = 0;
574         char *pp = yytext;
575
plunky
1.5
576         pp++;   /* skip ' */
ragge
1.1
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");
plunky
1.5
588         else if (i > (SZINT/SZCHAR) || (i>1))
ragge
1.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
plunky
1.5
600         pp++;   /* skip L */
601         pp++;   /* skip ' */
ragge
1.1
602         while (*pp != '\'') {
603                 if (*pp++ == '\\') {
604                         val = esccon(&pp);
605                 } else
606                         val = pp[-1];
607 #if WCHAR_SIZE == 2
608                 lastcon = (lastcon << 16) | (val & 0xFFFF);
609 #else
610                 lastcon = val;
611 #endif
612                 i++;
613         }
614
615         if (i == 0)
616                 uerror("empty wide-character constant");
plunky
1.5
617         else if (i > 1)
ragge
1.1
618                 werror("too many characters in wide-character constant");
619         return xbcon(lastcon, NULL, ctype(UNSIGNED));
620 }
621
622 void
623 control(int t)
624 {
625         char *wr = yytext;
626         char *eptr;
627         int val;
628
629         wr++;   /* Skip initial '#' */
630         switch (t) {
631         case CPP_IDENT:
632                 return; /* Just skip these for now. */
633
634         case CPP_LINE:
635                 wr += 4;
636                 /* FALLTHROUGH */
637         case CPP_HASH:
638                 val = strtol(wr, &eptr, 10);
639                 if (wr == eptr) /* Illegal string */
640                         goto bad;
641                 wr = eptr;
642                 lineno = val - 1;
643                 while (*wr && *wr != '\"')
644                         wr++;
645                 if (*wr == 0)
646                         return;
647                 if (*wr++ != '\"')
648                         goto bad;
649                 eptr = wr;
650                 while (*wr && *wr != '\"')
651                         wr++;
652                 if (*wr != '\"')
653                         goto bad;
654                 *wr = 0;
655                 ftitle = addstring(eptr);
656 #ifdef STABS
657                 if (gflag)
658                         stabs_file(ftitle);
659 #endif
660         }
661         return;
662 bad:
663         werror("%s: illegal control", yytext);
664 }
665
666 int pragma_allpacked;
667 int pragma_packed, pragma_aligned;
668 char *pragma_renamed;
669
670 static int
671 pragmas_weak(char *str)
672 {
673         struct symtab *sp;
674         char *s1, *s2;
675
676         if ((s1 = pragtok(NULL)) == NULL)
677                 return 1;
678         if ((s2 = pragtok(NULL)) == NULL) {
679                 sp = lookup(addname(s1), SNORMAL);
ragge
1.4
680 #ifdef GCC_COMPAT
ragge
1.1
681                 sp->sap = attr_add(sp->sap, gcc_attr_parse(bdty(NAME, "weak")));
ragge
1.4
682 #else
683                 sp->sap = 0;
684 #endif
ragge
1.1
685         } else if (*s2 == '=') {
686                 if ((s2 = pragtok(NULL)) == NULL)
687                         return 1;
688                 sp = lookup(addname(s2), SNORMAL);
ragge
1.4
689 #ifdef GCC_COMPAT
ragge
1.1
690                 sp->sap = attr_add(sp->sap, gcc_attr_parse(bdty(CALL,
691                     bdty(NAME, "aliasweak"), bdty(STRING, s1, 0))));
ragge
1.4
692 #else
693                 sp->sap = NULL;
694 #endif
ragge
1.1
695         } else
696                 return 1;
697         return 0;
698 }
699
700 char *pragstore;
701
702 /* trivial tokenizer for pragmas */
703 #define ps pragstore
704 char *
705 pragtok(char *sin)
706 {
707         static char ss[2];
708         char *rv;
709
710         if (sin)
711                 ps = sin;
712
713         for (; isspace((int)*ps); ps++)
714                 ;
715         if (*ps == 0)
716                 return NULL;
717         for (rv = ps; isalpha((int)*ps) || isdigit((int)*ps) || *ps == '_'; ps++)
718                 ;
719         ss[0] = *ps;
720         if (rv == ps) {
721                 rv = ss, ps++;
722         } else {
723                 *ps = 0;
724                 rv = tmpstrdup(rv);
725                 *ps = ss[0];
726         }
727         return rv;
728 }
729
730 /* return 1 on error */
731 int
732 eat(int ch)
733 {
734         char *s = pragtok(0);
735         return (s == 0 || *s != ch);
736 }
737
738 static int
739 pragmas_alpack(char *t)
740 {
741         char *s;
742         int ap;
743
744         ap = (s = pragtok(0)) ? atoi(s) : 1;
745         if (strcmp(t, "packed") == 0)
746                 pragma_packed = ap;
747         else
748                 pragma_aligned = ap;
749         return 0;
750 }
751
752
753 /*
754  * Packing control.
755  * still missing push/pop.
756  */
757 static int
758 pragmas_pack(char *t)
759 {
760         char *s;
761
762         if (eat('('))
763                 return 1;
764         s = pragtok(0);
765         if (*s == ')')
766                 return pragma_allpacked = 0;
767
768         if (*s < '0' || *s > '9') /* no number */
769                 return 1;
770         pragma_allpacked = atoi(s);
771         return eat(')');
772 }
773
774 static int
775 pragmas_renamed(char *t)
776 {
777         char *f = pragtok(0);
778
779         if (f == 0)
780                 return 1;
781         pragma_renamed = newstring(f, strlen(f));
782         return 0;
783 }
784
785 static int
786 pragmas_stdc(char *t)
787 {
788         return 0; /* Just ignore */
789 }
790
791 struct pragmas {
792         char *name;
793         int (*fun)(char *);
794 } pragmas[] = {
795         { "pack", pragmas_pack },
796         { "packed", pragmas_alpack },
797         { "aligned", pragmas_alpack },
798         { "rename", pragmas_renamed },
799 #ifdef GCC_COMPAT
800         { "GCC", pragmas_gcc },
801 #endif
802         { "STDC", pragmas_stdc },
803         { "weak", pragmas_weak },
804         { "ident", NULL },
805         { 0 },
806 };
plunky
1.2
807
ragge
1.1
808 /*
809  * got a full pragma line.  Split it up here.
810  */
811 static void
plunky
1.2
812 pragma(void)
ragge
1.1
813 {
814         struct pragmas *p;
815         char *t, *pt;
816
817         if ((t = pragtok(&yytext[7])) != NULL) {
818                 pt = ps;
819                 for (p = pragmas; p->name; p++) {
820                         if (strcmp(t, p->name) == 0) {
821                                 if (p->fun && (*p->fun)(t))
822                                         uerror("bad argument to #pragma");
823                                 return;
824                         }
825                 }
826                 ps = pt;
827                 if (mypragma(t))
828                         return;
829         }
830         warner(Wunknown_pragmas, t, ps);
831 }
832
833 void
834 cunput(char c)
835 {
836         unput(c);
837 }
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-09-18 23:44 +0200