Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050306155806

Diff

Diff from 1.1 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/cc/cpp/token.c

Annotated File View

ragge
1.1
1 /*      $Id: token.c,v 1.1 2005/03/06 15:58:06 ragge Exp $      */
2
3 /*
4  * Copyright (c) 2004 Anders Magnusson. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include <stdlib.h>
30 #include <string.h>
31 #include <ctype.h>
32
33 #include "cpp.h"
34
35 /* definition for include file info */
36 struct includ {
37         struct includ *next;
38         char *fname;
39         int lineno;
40         FILE *ifil;
41 } *ifiles;
42
43 usch *yypyystr[CPPBUF];
44
45 int yylex(void);
46 int nyylex(void);
47 int yywrap(void);
48 #if 0
49
50 "\n"                    { return nyylex(); }
51 .                       { return nyylex(); }
52
53 #endif
54
55 #define input() fgetc(ifiles->ifil)
56 #define unput(c) ungetc(c, ifiles->ifil)
57 static int
58 slofgetc(void)
59 {
60         int c;
61
62 again:  switch (c = input()) {
63         case '\\'/* continued lines */
64                 if ((c = input()) == '\n') {
65                         ifiles->lineno++;
66                         putc('\n'obuf);
67                         goto again;
68                 }
69                 cunput(c);
70                 return '\\';
71         case '?'/* trigraphs */
72                 if ((c = input()) != '?') {
73                         cunput(c);
74                         return '?';
75                 }
76                 switch (c = input()) {
77                 case '='c = '#'break;
78                 case '('c = '['break;
79                 case ')'c = ']'break;
80                 case '<'c = '{'break;
81                 case '>'c = '}'break;
82                 case '/'c = '\\'break;
83                 case '\''c = '^'break;
84                 case '!'c = '|'break;
85                 case '-'c = '~'break;
86                 default:
87                         cunput(c);
88                         cunput('?');
89                         return '?';
90                 }
91                 cunput(c);
92                 goto again;
93         default:
94                 return c;
95         }
96 }
97
98 int yylex() { return nyylex(); }
99
100 int
101 nyylex()
102 {
103         static int wasnl = 1;
104         int cocrval;
105
106         yyp = yystr;
107         c = input();
108         if (c != ' ' && c != '\t' && c != '#')
109                 wasnl = 0;
110 #define ONEMORE()       { *yyp++ = c; c = slofgetc(); }
111 again:  switch (c) {
112         case -1:
113                 rval = yywrap() ? 0 : nyylex();
114                 break;
115
116         case '\''/* charcon */
117         case '"'/* string */
118 chstr:          oc = c;
119                 do {
120                         *yyp++ = c;
121                         if (c == '\\')
122                                 *yyp++ = slofgetc();
123                 } while ((c = slofgetc()) != EOF && c != oc);
124                 *yyp++ = c; *yyp = 0;
125                 rval = oc == '"' ? STRING : CHARCON;
126                 break;
127
128         case '0'case '1'case '2'case '3'case '4'
129         case '5'case '6'case '7'case '8'case '9'
130                 *yyp++ = c;
131                 c = slofgetc();
132                 if (yyp[-1] == '0' && (c == 'x' || c == 'X')) {
133                         do {
134                                 ONEMORE();
135                         } while (isxdigit(c));
136                 } else {
137                         while (isdigit(c))
138                                 ONEMORE();
139                 }
140                 if (c != '.' && c != 'e' && c != 'E') {
141                         /* not floating point number */
142                         while (c == 'l' || c == 'L' || c == 'u' || c == 'U') {
143                                 ONEMORE();
144                         }
145                         cunput(c);
146                         *yyp = 0;
147                         rval = NUMBER;
148                         break;
149                 }
150                 /* it's a floating point number here */
151                 if (c == '.') { /* decimal point */
152 F:                      do { /* may be followed by digits */
153                                 ONEMORE();
154                         } while (isdigit(c));
155                         if (c == 'e' || c == 'E') {
156 E:                              ONEMORE();
157                                 if (c == '-' || c == '+') {
158                                         ONEMORE();
159                                 }
160                                 while (isdigit(c))
161                                         ONEMORE();
162                         }
163                         if (c == 'f' || c == 'F' || c == 'l' || c == 'L')
164                                 ONEMORE();
165                         cunput(c);
166                         *yyp = 0;
167                         rval = FPOINT;
168                         break;
169                 } else
170                         goto E;
171
172         case '.':
173                 ONEMORE();
174                 if (isdigit(c))
175                         goto F;
176                 if (c == '.') {
177                         ONEMORE();
178                         if (c == '.') {
179                                 *yyp++ = '.'; *yyp = 0;
180                                 rval = ELLIPS;
181                                 break;
182                         }
183                         cunput(c);
184                         cunput('.');
185                         *--yyp = 0;
186                         rval = '.';
187                         break;
188                 }
189                 cunput(c);
190                 *yyp = 0;
191                 rval = '.';
192                 break;
193
194         case '\\':
195                 c = input();
196                 if (c == '\n') {
197                         ifiles->lineno++;
198                         putc('\n'obuf);
199                         c = input();
200                         goto again;
201                 } else {
202                         cunput(c);
203                         *yyp++ = '\\'; *yyp = 0;
204                         rval = '\\';
205                 }
206                 break;
207                 
208         case '\n':
209                 wasnl = 1;
210                 ifiles->lineno++;
211                 *yyp++ = c; *yyp = 0;
212                 rval = NL;
213                 break;
214
215         case '#':
216                 if (wasnl) {
217                         wasnl = 0;
218                         rval = CONTROL;
219                         break;
220                 }
221                 *yyp++ = c;
222                 c = input();
223                 if (c == '#') {
224                         *yyp++ = c;
225                         *yyp = 0;
226                         rval = CONCAT;
227                 } else {
228                         unput(c);
229                         *yyp = 0;
230                         rval = MKSTR;
231                 }
232                 break;
233
234         case ' ':
235         case '\t'/* whitespace */
236                 do {
237                         *yyp++ = c;
238                         c = input();
239                 } while (c == ' ' || c == '\t');
240                 if (wasnl && c == '#') {
241                         wasnl = 0;
242                         rval = CONTROL;
243                 } else {
244                         unput(c);
245                         *yyp = 0;
246                         rval = WSPACE;
247                 }
248                 break;
249
250         case '/':
251                 if ((c = slofgetc()) == '/') {
252                         if (Cflag)
253                                 fprintf(obuf"//");
254                         while ((c = slofgetc()) && c != '\n')
255                                 if (Cflag)
256                                         putc(cobuf);
257                         *yyp++ = c; *yyp = 0;
258                         rval = c;
259                 } else if (c == '*') {
260                         if (Cflag)
261                                 fprintf(obuf"/*");
262                         oc = 0;
263                         do { 
264                                 while ((c = slofgetc()) && c != '*') {
265                                         if (c == '\n') {
266                                                 putc(cobuf);
267                                                 ifiles->lineno++;
268                                         } else if (Cflag)
269                                                 putc(cobuf);
270                                 }
271                                 if (Cflag)
272                                         putc(cobuf);
273                                 if ((c = slofgetc()) == '/')
274                                         break;
275                                 unput(c);
276                         } while (c);
277                         if (Cflag)
278                                 putc(cobuf);
279                         if (tflag) {
280                                 rval = nyylex();
281                         } else {
282                                 *yyp++ = ' '; *yyp = 0;
283                                 rval = WSPACE;
284                         }
285                 } else {
286                         unput(c);
287                         *yyp++ = '/'; *yyp = 0;
288                         rval = '/';
289                 }
290                 break;
291
292         case 'L'/* may be STRING, CHARCON or identifier */
293                 *yyp++ = c;
294                 if ((c = slofgetc()) == '"' || c == '\'')
295                         goto chstr;
296 gotid:          while (isalnum(c) || c == '_') {
297                         *yyp++ = c;
298                         c = slofgetc();
299                 }
300                 *yyp = 0;
301                 unput(c);
302                 rval = IDENT;
303                 break;
304
305         default:
306                 if (isalpha(c) || c == '_')
307                         goto gotid;
308                 yystr[0] = cyystr[1] = 0;
309                 rval = c;
310                 break;
311         }
312         return rval;
313 }
314
315 /*
316  * A new file included.
317  * If ifiles == NULL, this is the first file and already opened (stdin).
318  * Return 0 on success, -1 on failure to open file.
319  */
320 int
321 pushfile(char *file)
322 {
323         struct includ *ic;
324
325         ic = malloc(sizeof(struct includ));
326         ic->fname = strdup(file);
327         ic->lineno = 1;
328         if (ifiles != NULL) {
329                 if ((ic->ifil = fopen(file"r")) == NULL)
330                         return -1;
331         } else
332                 ic->ifil = stdin;
333         ic->next = ifiles;
334         ifiles = ic;
335
336         return 0;
337 }
338
339 /*
340  * End of included file (or everything).
341  */
342 void
343 popfile()
344 {
345         struct includ *ic;
346
347         ic = ifiles;
348         ifiles = ifiles->next;
349         fclose(ic->ifil);
350         free(ic->fname);
351         free(ic);
352         prtline();
353 }
354
355 /*
356  * Print current position to output file.
357  */
358 void
359 prtline()
360 {
361         fprintf(obuf"# %d \"%s\"\n"ifiles->linenoifiles->fname);
362 }
363
364 void
365 cunput(int c)
366 {
367 extern int dflag;
368 if (dflag)printf(": '%c'(%d)"cc);
369         unput(c);
370 }
371
372 int
373 yywrap()
374 {
375         if (ifiles->next == 0)
376                 return 1;
377         popfile();
378         return 0;
379 }
380
381 void
382 setline(int line)
383 {
384         if (ifiles)
385                 ifiles->lineno = line-1;
386 }
387
388 void
389 setfile(char *name)
390 {
391         if (ifiles)
392                 free(ifiles->fname), ifiles->fname = strdup(name);
393 }
394
395 int
396 curline()
397 {
398         return ifiles ? ifiles->lineno : 0;
399 }
400
401 char *
402 curfile()
403 {
404         return ifiles ? ifiles->fname : "";
405 }
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-22 11:51 +0200