Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20060805102429

Diff

Diff from 1.10 to:

Annotations

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

Annotated File View

ragge
1.10
1 /*      $Id: token.c,v 1.10 2006/08/05 10:24:29 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
ragge
1.10
37 #ifndef ragge
ragge
1.1
38 /* definition for include file info */
39 struct includ {
40         struct includ *next;
41         char *fname;
42         int lineno;
ragge
1.2
43         int infil;
44         usch *curptr;
ragge
1.6
45         usch *maxread;
ragge
1.3
46         usch *ostr;
ragge
1.6
47         usch *buffer;
48         usch bbuf[NAMEMAX+CPPBUF+1];
49 } *ifiles;
ragge
1.10
50 #endif
ragge
1.1
51
ragge
1.7
52 usch *yyp, *yystryybuf[CPPBUF];
ragge
1.1
53
54 int yylex(void);
55 int yywrap(void);
56
ragge
1.3
57 static struct includ *
58 getbuf(usch *file)
59 {
60         struct includ *ic;
ragge
1.9
61
62         ic = calloc(sizeof(struct includ), 1);
63 #if 0
ragge
1.6
64         usch *ostr = stringbuf;
ragge
1.3
65
ragge
1.6
66 //printf("getbuf1: stringbuf %p\n", stringbuf);
67         stringbuf = (usch *)ROUND((int)stringbuf);
68 //printf("getbuf2: stringbuf %p\n", stringbuf);
69         ic = (struct includ *)stringbuf;
70         stringbuf += sizeof(struct includ);
71         ic->ostr = ostr;
72
73 //printf("getbuf3: stringbuf %p\n", stringbuf);
ragge
1.9
74 #endif
ragge
1.3
75         return ic;
76 }
77
78 static void
79 putbuf(struct includ *ic)
80 {
ragge
1.9
81         free(ic);
82 #if 0
ragge
1.6
83 //printf("putbuf: stringbuf %p\n", stringbuf);
84 if (stringbuf < (usch *)&ic[1])
85 ;//     printf("ERROR!!!\n");
86 else
87         stringbuf = ic->ostr;
88 //printf("putbuf2: stringbuf %p\n", stringbuf);
ragge
1.9
89 #endif
ragge
1.3
90 }
91
ragge
1.2
92 static int
93 input(void)
94 {
ragge
1.3
95         struct includ *ic;
ragge
1.6
96         int len;
ragge
1.3
97
ragge
1.6
98         if (ifiles->curptr < ifiles->maxread) {
ragge
1.9
99 if (*ifiles->curptr == 0)
100 printf("c %d\n", *ifiles->curptr);
ragge
1.2
101                 return *ifiles->curptr++;
ragge
1.6
102 }
ragge
1.3
103         if (ifiles->infil < 0) {
104                 ic = ifiles;
105                 ifiles = ifiles->next;
106                 putbuf(ic);
107                 return input();
108         }
ragge
1.6
109         if ((len = read(ifiles->infilifiles->bufferCPPBUF)) < 0)
ragge
1.2
110                 error("read error on file %s"ifiles->fname);
ragge
1.6
111         if (len == 0)
ragge
1.3
112                 return -1;
113         ifiles->curptr = ifiles->buffer;
ragge
1.6
114         ifiles->maxread = ifiles->buffer + len;
ragge
1.2
115         return input();
116 }
ragge
1.1
117
ragge
1.10
118 #ifdef ragge
119 /*
120  * Get next character from input stream.  If the input buffer is empty,
121  * try to fill it up. If end of stream, return -1.
122  */
123 static int
124 inpch(struct includ *ic)
125 {
126         int len;
127
128         if (ic->curptr < ic->maxread)
129                 return *ic->curptr++;
130
131         if ((len = read(ic->infilic->bufferCPPBUF)) < 0)
132                 error("read error on file %s"ic->fname);
133         if (len == 0)
134                 return -1;
135         ic->curptr = ic->buffer;
136         ic->maxread = ic->buffer + len;
137         return inpch(ic);
138 }
139 /*
140  * Get next character from the current input stream.
141  * Also handles phase 1 and 2 in section 5.1.1.2 "Translation phases"
142  * in the C99 standard (trigraphs and \\n).
143  * Only newlines that are removed here are accounted for, and when found
144  * return GOTNL to tell that a \n must be printed out (to avoid line breaks
145  * in strings etc).
146  */
147 int
148 inch(struct includ *ic)
149 {
150         int c;
151
152         if (ic->curptr < ic->maxread)
153                 c = *ic->curptr++;
154         else
155                 c = inpch(ic);
156
157         if (c != '\\' && c != '?')
158                 return c/* common case */
159         /* first check for trigraphs */
160         if (c == '?') {
161                 if ((c = inpch(ic)) != '?') {
162                         unch(icc);
163                         return '?';
164                 }
165                 switch (c = input()) {
166                 case '='c = '#'break;
167                 case '('c = '['break;
168                 case ')'c = ']'break;
169                 case '<'c = '{'break;
170                 case '>'c = '}'break;
171                 case '/'c = '\\'break;
172                 case '\''c = '^'break;
173                 case '!'c = '|'break;
174                 case '-'c = '~'break;
175                 default:
176                         unch(icc);
177                         unch(ic'?');
178                         return '?';
179                 }
180         }
181         /* search for \\n */
182         if (c == '\\') {
183                 if ((c = inpch(ic)) != '\n') {
184                         unch(icc);
185                         return '\\';
186                 }
187                 ic->lineno++;
188                 c = GOTNL;
189         }
190         return c;
191 }
192
193 void
194 unch(struct includ *icint c)
195 {
196         *--ic->curptr = c;
197 }
198
199 void
200 outch(int c)
201 {
202         putc(cobuf);
203 }
204
205 #endif
206
ragge
1.2
207 static void
208 unput(int c)
209 {
ragge
1.3
210         struct includ *ic;
211
ragge
1.6
212 if (c == 0) {
213 printf("no;;\n");
214 }
215
216         if (ifiles->curptr > ifiles->bbuf) {
ragge
1.3
217                 *--ifiles->curptr = c;
218         } else {
219                 ic = getbuf(NULL);
220                 ic->fname = ifiles->fname;
221                 ic->lineno = ifiles->lineno;
222                 ic->infil = -1;
ragge
1.6
223                 ic->curptr = &ic->bbuf[NAMEMAX+CPPBUF+1];
224                 ic->maxread = ic->curptr;
ragge
1.3
225                 ic->next = ifiles;
226                 ifiles = ic;
ragge
1.2
227                 *--ifiles->curptr = c;
ragge
1.3
228         }
ragge
1.6
229 //printf("unput %d\n", c);
ragge
1.2
230 }
ragge
1.7
231
232 #define UNPUT(c) *--ifiles->curptr = c
233 #define ADJUST(x) { \
234         if (x > (ifiles->maxread-ifiles->curptr)) { \
235                 memcpy(
236
ragge
1.1
237 static int
238 slofgetc(void)
239 {
240         int c;
241
242 again:  switch (c = input()) {
243         case '\\'/* continued lines */
244                 if ((c = input()) == '\n') {
245                         ifiles->lineno++;
246                         putc('\n'obuf);
247                         goto again;
248                 }
249                 cunput(c);
250                 return '\\';
251         case '?'/* trigraphs */
252                 if ((c = input()) != '?') {
253                         cunput(c);
254                         return '?';
255                 }
256                 switch (c = input()) {
257                 case '='c = '#'break;
258                 case '('c = '['break;
259                 case ')'c = ']'break;
260                 case '<'c = '{'break;
261                 case '>'c = '}'break;
262                 case '/'c = '\\'break;
263                 case '\''c = '^'break;
264                 case '!'c = '|'break;
265                 case '-'c = '~'break;
266                 default:
267                         cunput(c);
268                         cunput('?');
269                         return '?';
270                 }
271                 cunput(c);
272                 goto again;
273         default:
274                 return c;
275         }
276 }
277
278 int
ragge
1.2
279 yylex()
ragge
1.1
280 {
281         static int wasnl = 1;
282         int cocrval;
283
ragge
1.7
284 fast:   yystr = yybuf;
ragge
1.1
285         yyp = yystr;
286         c = input();
287         if (c != ' ' && c != '\t' && c != '#')
288                 wasnl = 0;
ragge
1.3
289 #define ONEMORE()       { *yyp++ = c; c = slofgetc(); }
ragge
1.1
290 again:  switch (c) {
291         case -1:
ragge
1.6
292                 rval = 0;
ragge
1.1
293                 break;
294
295         case '\''/* charcon */
296         case '"'/* string */
297 chstr:          oc = c;
ragge
1.9
298                 do {
299                         *yyp++ = c;
300                         if (c == '\\')
301                                 *yyp++ = slofgetc();
302                 } while ((c = slofgetc()) != EOF && c != oc);
303                 *yyp++ = c; *yyp = 0;
ragge
1.1
304                 rval = oc == '"' ? STRING : CHARCON;
305                 break;
306
307         case '0'case '1'case '2'case '3'case '4'
308         case '5'case '6'case '7'case '8'case '9'
309                 *yyp++ = c;
310                 c = slofgetc();
311                 if (yyp[-1] == '0' && (c == 'x' || c == 'X')) {
312                         do {
313                                 ONEMORE();
314                         } while (isxdigit(c));
315                 } else {
316                         while (isdigit(c))
317                                 ONEMORE();
318                 }
319                 if (c != '.' && c != 'e' && c != 'E') {
320                         /* not floating point number */
321                         while (c == 'l' || c == 'L' || c == 'u' || c == 'U') {
322                                 ONEMORE();
323                         }
324                         cunput(c);
325                         *yyp = 0;
326                         rval = NUMBER;
327                         break;
328                 }
329                 /* it's a floating point number here */
330                 if (c == '.') { /* decimal point */
331 F:                      do { /* may be followed by digits */
332                                 ONEMORE();
333                         } while (isdigit(c));
334                         if (c == 'e' || c == 'E') {
335 E:                              ONEMORE();
336                                 if (c == '-' || c == '+') {
337                                         ONEMORE();
338                                 }
339                                 while (isdigit(c))
340                                         ONEMORE();
341                         }
342                         if (c == 'f' || c == 'F' || c == 'l' || c == 'L')
343                                 ONEMORE();
344                         cunput(c);
345                         *yyp = 0;
346                         rval = FPOINT;
347                         break;
348                 } else
349                         goto E;
350
351         case '.':
352                 ONEMORE();
353                 if (isdigit(c))
354                         goto F;
355                 if (c == '.') {
356                         ONEMORE();
357                         if (c == '.') {
358                                 *yyp++ = '.'; *yyp = 0;
359                                 rval = ELLIPS;
360                                 break;
361                         }
362                         cunput(c);
363                         cunput('.');
364                         *--yyp = 0;
365                         rval = '.';
366                         break;
367                 }
368                 cunput(c);
369                 *yyp = 0;
370                 rval = '.';
371                 break;
372
373         case '\\':
374                 c = input();
375                 if (c == '\n') {
376                         ifiles->lineno++;
ragge
1.7
377                         putch('\n');
378                         goto fast;
379                 }
380                 UNPUT(c);
381                 *yyp++ = '\\'; *yyp = 0;
382                 rval = '\\';
ragge
1.1
383                 break;
384                 
385         case '\n':
386                 wasnl = 1;
387                 ifiles->lineno++;
ragge
1.9
388                 *yyp++ = '\n'; *yyp = 0;
ragge
1.1
389                 rval = NL;
ragge
1.9
390                 break;
ragge
1.1
391
392         case '#':
393                 if (wasnl) {
394                         wasnl = 0;
395                         rval = CONTROL;
396                         break;
397                 }
398                 *yyp++ = c;
399                 c = input();
400                 if (c == '#') {
401                         *yyp++ = c;
402                         *yyp = 0;
403                         rval = CONCAT;
404                 } else {
405                         unput(c);
406                         *yyp = 0;
407                         rval = MKSTR;
408                 }
409                 break;
410
411         case ' ':
412         case '\t'/* whitespace */
413                 do {
414                         *yyp++ = c;
415                         c = input();
416                 } while (c == ' ' || c == '\t');
417                 if (wasnl && c == '#') {
418                         wasnl = 0;
419                         rval = CONTROL;
420                 } else {
421                         unput(c);
422                         *yyp = 0;
423                         rval = WSPACE;
424                 }
425                 break;
426
427         case '/':
428                 if ((c = slofgetc()) == '/') {
429                         if (Cflag)
430                                 fprintf(obuf"//");
431                         while ((c = slofgetc()) && c != '\n')
432                                 if (Cflag)
433                                         putc(cobuf);
ragge
1.5
434                         goto again;
ragge
1.1
435                 } else if (c == '*') {
436                         if (Cflag)
437                                 fprintf(obuf"/*");
438                         oc = 0;
439                         do { 
440                                 while ((c = slofgetc()) && c != '*') {
441                                         if (c == '\n') {
442                                                 putc(cobuf);
443                                                 ifiles->lineno++;
444                                         } else if (Cflag)
445                                                 putc(cobuf);
446                                 }
447                                 if (Cflag)
448                                         putc(cobuf);
449                                 if ((c = slofgetc()) == '/')
450                                         break;
451                                 unput(c);
452                         } while (c);
453                         if (Cflag)
454                                 putc(cobuf);
455                         if (tflag) {
ragge
1.2
456                                 rval = yylex();
ragge
1.1
457                         } else {
458                                 *yyp++ = ' '; *yyp = 0;
459                                 rval = WSPACE;
460                         }
461                 } else {
462                         unput(c);
463                         *yyp++ = '/'; *yyp = 0;
464                         rval = '/';
465                 }
466                 break;
467
468         case 'L'/* may be STRING, CHARCON or identifier */
469                 *yyp++ = c;
470                 if ((c = slofgetc()) == '"' || c == '\'')
471                         goto chstr;
472 gotid:          while (isalnum(c) || c == '_') {
473                         *yyp++ = c;
474                         c = slofgetc();
475                 }
476                 *yyp = 0;
477                 unput(c);
478                 rval = IDENT;
479                 break;
480
481         default:
482                 if (isalpha(c) || c == '_')
483                         goto gotid;
484                 yystr[0] = cyystr[1] = 0;
485                 rval = c;
486                 break;
487         }
488         return rval;
489 }
490
ragge
1.4
491 /*
ragge
1.6
492  * A new file included.
493  * If ifiles == NULL, this is the first file and already opened (stdin).
494  * Return 0 on success, -1 on failure to open file.
ragge
1.4
495  */
496 int
497 pushfile(char *file)
498 {
ragge
1.6
499         struct includ ibuf;
500         struct includ *old;
501         struct includ *ic;
ragge
1.8
502         int otrulvl = trulvloflslvl = flslvl;
ragge
1.6
503
504         ic = &ibuf;
ragge
1.9
505         memset(ic0sizeof(struct includ));
ragge
1.6
506         old = ifiles;
ragge
1.9
507 //printf("ifiles %p ic %p\n", ifiles, ic);
ragge
1.4
508
ragge
1.6
509         if (file != NULL) {
ragge
1.4
510                 if ((ic->infil = open(fileO_RDONLY)) < 0)
511                         return -1;
ragge
1.6
512                 ic->fname = file;
513         } else {
514                 ic->infil = 0;
515                 ic->fname = "<stdin>";
516         }
517         ic->buffer = ic->bbuf+NAMEMAX;
ragge
1.4
518         ic->curptr = ic->buffer;
519         ifiles = ic;
ragge
1.6
520         ic->lineno = 0;
521         ic->maxread = ic->curptr;
522         unput('\n');
ragge
1.4
523
ragge
1.10
524 #ifdef ragge
525         scanover(ic);
526 #else
ragge
1.6
527         mainscan();
ragge
1.10
528 #endif
ragge
1.4
529
ragge
1.8
530         if (trulvl != otrulvl || flslvl != oflslvl)
ragge
1.6
531                 error("unterminated conditional");
ragge
1.4
532
ragge
1.6
533         ifiles = old;
ragge
1.9
534 //printf("ifiles2 %p\n", ifiles);
ragge
1.6
535         close(ic->infil);
536         return 0;
ragge
1.4
537 }
ragge
1.1
538
539 /*
540  * Print current position to output file.
541  */
542 void
543 prtline()
544 {
545         fprintf(obuf"# %d \"%s\"\n"ifiles->linenoifiles->fname);
546 }
547
548 void
549 cunput(int c)
550 {
551 extern int dflag;
552 if (dflag)printf(": '%c'(%d)"cc);
553         unput(c);
554 }
555
556 void
557 setline(int line)
558 {
559         if (ifiles)
560                 ifiles->lineno = line-1;
561 }
562
563 void
564 setfile(char *name)
565 {
566         if (ifiles)
ragge
1.6
567                 ifiles->fname = strdup(name);
ragge
1.1
568 }
569
570 int
571 curline()
572 {
573         return ifiles ? ifiles->lineno : 0;
574 }
575
576 char *
577 curfile()
578 {
579         return ifiles ? ifiles->fname : "";
580 }
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-23 21:49 +0200