Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050320162112

Diff

Diff from 1.3 to:

Annotations

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

Annotated File View

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