Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050319093405

Diff

Diff from 1.2 to:

Annotations

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

Annotated File View

ragge
1.2
1 /*      $Id: token.c,v 1.2 2005/03/19 09:34:05 ragge Exp $      */
ragge
1.1
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>
ragge
1.2
32 #include <unistd.h>
33 #include <fcntl.h>
ragge
1.1
34
35 #include "cpp.h"
36
37 /* definition for include file info */
38 struct includ {
39         struct includ *next;
40         char *fname;
41         int lineno;
ragge
1.2
42 #ifdef NEWBUF
43         int infil;
44         usch *inpbuf;
45         usch *curptr;
46         int curlen;
47 #else
ragge
1.1
48         FILE *ifil;
ragge
1.2
49 #endif
ragge
1.1
50 } *ifiles;
51
52 usch *yypyystr[CPPBUF];
ragge
1.2
53 #if 0
54 usch inpbuf[NAMEMAX+CPPBUF], *curimp, *imptop;
55 #endif
ragge
1.1
56
57 int yylex(void);
58 int yywrap(void);
59
ragge
1.2
60 #ifdef NEWBUF
61 static int
62 input(void)
63 {
64         if (ifiles->curptr < ifiles->inpbuf+ifiles->curlen)
65                 return *ifiles->curptr++;
66         if ((ifiles->curlen = read(ifiles->infilifiles->inpbufCPPBUF)) < 0)
67                 error("read error on file %s"ifiles->fname);
68         ifiles->curptr = ifiles->inpbuf;
69         return input();
70 }
ragge
1.1
71
ragge
1.2
72 static void
73 unput(int c)
74 {
75         if (ifiles->curptr > ifiles->inpbuf)
76                 *--ifiles->curptr = c;
77         else
78                 error("out of pushback space");
79 }
80 #else
ragge
1.1
81 #define input() fgetc(ifiles->ifil)
82 #define unput(c) ungetc(c, ifiles->ifil)
ragge
1.2
83 #endif
ragge
1.1
84 static int
85 slofgetc(void)
86 {
87         int c;
88
89 again:  switch (c = input()) {
90         case '\\'/* continued lines */
91                 if ((c = input()) == '\n') {
92                         ifiles->lineno++;
93                         putc('\n'obuf);
94                         goto again;
95                 }
96                 cunput(c);
97                 return '\\';
98         case '?'/* trigraphs */
99                 if ((c = input()) != '?') {
100                         cunput(c);
101                         return '?';
102                 }
103                 switch (c = input()) {
104                 case '='c = '#'break;
105                 case '('c = '['break;
106                 case ')'c = ']'break;
107                 case '<'c = '{'break;
108                 case '>'c = '}'break;
109                 case '/'c = '\\'break;
110                 case '\''c = '^'break;
111                 case '!'c = '|'break;
112                 case '-'c = '~'break;
113                 default:
114                         cunput(c);
115                         cunput('?');
116                         return '?';
117                 }
118                 cunput(c);
119                 goto again;
120         default:
121                 return c;
122         }
123 }
124
125 int
ragge
1.2
126 yylex()
ragge
1.1
127 {
128         static int wasnl = 1;
129         int cocrval;
130
131         yyp = yystr;
132         c = input();
133         if (c != ' ' && c != '\t' && c != '#')
134                 wasnl = 0;
135 #define ONEMORE()       { *yyp++ = c; c = slofgetc(); }
136 again:  switch (c) {
137         case -1:
ragge
1.2
138                 rval = yywrap() ? 0 : yylex();
ragge
1.1
139                 break;
140
141         case '\''/* charcon */
142         case '"'/* string */
143 chstr:          oc = c;
144                 do {
145                         *yyp++ = c;
146                         if (c == '\\')
147                                 *yyp++ = slofgetc();
148                 } while ((c = slofgetc()) != EOF && c != oc);
149                 *yyp++ = c; *yyp = 0;
150                 rval = oc == '"' ? STRING : CHARCON;
151                 break;
152
153         case '0'case '1'case '2'case '3'case '4'
154         case '5'case '6'case '7'case '8'case '9'
155                 *yyp++ = c;
156                 c = slofgetc();
157                 if (yyp[-1] == '0' && (c == 'x' || c == 'X')) {
158                         do {
159                                 ONEMORE();
160                         } while (isxdigit(c));
161                 } else {
162                         while (isdigit(c))
163                                 ONEMORE();
164                 }
165                 if (c != '.' && c != 'e' && c != 'E') {
166                         /* not floating point number */
167                         while (c == 'l' || c == 'L' || c == 'u' || c == 'U') {
168                                 ONEMORE();
169                         }
170                         cunput(c);
171                         *yyp = 0;
172                         rval = NUMBER;
173                         break;
174                 }
175                 /* it's a floating point number here */
176                 if (c == '.') { /* decimal point */
177 F:                      do { /* may be followed by digits */
178                                 ONEMORE();
179                         } while (isdigit(c));
180                         if (c == 'e' || c == 'E') {
181 E:                              ONEMORE();
182                                 if (c == '-' || c == '+') {
183                                         ONEMORE();
184                                 }
185                                 while (isdigit(c))
186                                         ONEMORE();
187                         }
188                         if (c == 'f' || c == 'F' || c == 'l' || c == 'L')
189                                 ONEMORE();
190                         cunput(c);
191                         *yyp = 0;
192                         rval = FPOINT;
193                         break;
194                 } else
195                         goto E;
196
197         case '.':
198                 ONEMORE();
199                 if (isdigit(c))
200                         goto F;
201                 if (c == '.') {
202                         ONEMORE();
203                         if (c == '.') {
204                                 *yyp++ = '.'; *yyp = 0;
205                                 rval = ELLIPS;
206                                 break;
207                         }
208                         cunput(c);
209                         cunput('.');
210                         *--yyp = 0;
211                         rval = '.';
212                         break;
213                 }
214                 cunput(c);
215                 *yyp = 0;
216                 rval = '.';
217                 break;
218
219         case '\\':
220                 c = input();
221                 if (c == '\n') {
222                         ifiles->lineno++;
223                         putc('\n'obuf);
224                         c = input();
225                         goto again;
226                 } else {
227                         cunput(c);
228                         *yyp++ = '\\'; *yyp = 0;
229                         rval = '\\';
230                 }
231                 break;
232                 
233         case '\n':
234                 wasnl = 1;
235                 ifiles->lineno++;
236                 *yyp++ = c; *yyp = 0;
237                 rval = NL;
238                 break;
239
240         case '#':
241                 if (wasnl) {
242                         wasnl = 0;
243                         rval = CONTROL;
244                         break;
245                 }
246                 *yyp++ = c;
247                 c = input();
248                 if (c == '#') {
249                         *yyp++ = c;
250                         *yyp = 0;
251                         rval = CONCAT;
252                 } else {
253                         unput(c);
254                         *yyp = 0;
255                         rval = MKSTR;
256                 }
257                 break;
258
259         case ' ':
260         case '\t'/* whitespace */
261                 do {
262                         *yyp++ = c;
263                         c = input();
264                 } while (c == ' ' || c == '\t');
265                 if (wasnl && c == '#') {
266                         wasnl = 0;
267                         rval = CONTROL;
268                 } else {
269                         unput(c);
270                         *yyp = 0;
271                         rval = WSPACE;
272                 }
273                 break;
274
275         case '/':
276                 if ((c = slofgetc()) == '/') {
277                         if (Cflag)
278                                 fprintf(obuf"//");
279                         while ((c = slofgetc()) && c != '\n')
280                                 if (Cflag)
281                                         putc(cobuf);
282                         *yyp++ = c; *yyp = 0;
283                         rval = c;
284                 } else if (c == '*') {
285                         if (Cflag)
286                                 fprintf(obuf"/*");
287                         oc = 0;
288                         do { 
289                                 while ((c = slofgetc()) && c != '*') {
290                                         if (c == '\n') {
291                                                 putc(cobuf);
292                                                 ifiles->lineno++;
293                                         } else if (Cflag)
294                                                 putc(cobuf);
295                                 }
296                                 if (Cflag)
297                                         putc(cobuf);
298                                 if ((c = slofgetc()) == '/')
299                                         break;
300                                 unput(c);
301                         } while (c);
302                         if (Cflag)
303                                 putc(cobuf);
304                         if (tflag) {
ragge
1.2
305                                 rval = yylex();
ragge
1.1
306                         } else {
307                                 *yyp++ = ' '; *yyp = 0;
308                                 rval = WSPACE;
309                         }
310                 } else {
311                         unput(c);
312                         *yyp++ = '/'; *yyp = 0;
313                         rval = '/';
314                 }
315                 break;
316
317         case 'L'/* may be STRING, CHARCON or identifier */
318                 *yyp++ = c;
319                 if ((c = slofgetc()) == '"' || c == '\'')
320                         goto chstr;
321 gotid:          while (isalnum(c) || c == '_') {
322                         *yyp++ = c;
323                         c = slofgetc();
324                 }
325                 *yyp = 0;
326                 unput(c);
327                 rval = IDENT;
328                 break;
329
330         default:
331                 if (isalpha(c) || c == '_')
332                         goto gotid;
333                 yystr[0] = cyystr[1] = 0;
334                 rval = c;
335                 break;
336         }
337         return rval;
338 }
339
340 /*
341  * A new file included.
342  * If ifiles == NULL, this is the first file and already opened (stdin).
343  * Return 0 on success, -1 on failure to open file.
344  */
345 int
346 pushfile(char *file)
347 {
348         struct includ *ic;
349
350         ic = malloc(sizeof(struct includ));
351         ic->fname = strdup(file);
352         ic->lineno = 1;
353         if (ifiles != NULL) {
ragge
1.2
354 #ifdef NEWBUF
355                 if ((ic->infil = open(fileO_RDONLY)) < 0)
356                         return -1;
357 #else
ragge
1.1
358                 if ((ic->ifil = fopen(file"r")) == NULL)
359                         return -1;
ragge
1.2
360 #endif
ragge
1.1
361         } else
ragge
1.2
362 #ifdef NEWBUF
363                 ic->infil = 0;
364 #else
ragge
1.1
365                 ic->ifil = stdin;
ragge
1.2
366 #endif
367 #ifdef NEWBUF
368         ic->curptr = ic->inpbuf = malloc(CPPBUF);
369 #endif
ragge
1.1
370         ic->next = ifiles;
371         ifiles = ic;
372
373         return 0;
374 }
375
376 /*
377  * End of included file (or everything).
378  */
379 void
380 popfile()
381 {
382         struct includ *ic;
383
384         ic = ifiles;
385         ifiles = ifiles->next;
ragge
1.2
386 #ifdef NEWBUF
387         close(ic->infil);
388 #else
ragge
1.1
389         fclose(ic->ifil);
ragge
1.2
390 #endif
ragge
1.1
391         free(ic->fname);
392         free(ic);
393         prtline();
394 }
395
396 /*
397  * Print current position to output file.
398  */
399 void
400 prtline()
401 {
402         fprintf(obuf"# %d \"%s\"\n"ifiles->linenoifiles->fname);
403 }
404
405 void
406 cunput(int c)
407 {
408 extern int dflag;
409 if (dflag)printf(": '%c'(%d)"cc);
410         unput(c);
411 }
412
413 int
414 yywrap()
415 {
416         if (ifiles->next == 0)
417                 return 1;
418         popfile();
419         return 0;
420 }
421
422 void
423 setline(int line)
424 {
425         if (ifiles)
426                 ifiles->lineno = line-1;
427 }
428
429 void
430 setfile(char *name)
431 {
432         if (ifiles)
433                 free(ifiles->fname), ifiles->fname = strdup(name);
434 }
435
436 int
437 curline()
438 {
439         return ifiles ? ifiles->lineno : 0;
440 }
441
442 char *
443 curfile()
444 {
445         return ifiles ? ifiles->fname : "";
446 }
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-07-11 07:44 +0200