Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050514080349

Diff

Diff from 1.7 to:

Annotations

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

Annotated File View

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