Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050511193259

Diff

Diff from 1.6 to:

Annotations

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

Annotated File View

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