Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20060928111007

Diff

Diff from 1.11 to:

Annotations

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

Annotated File View

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