Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050416081638

Diff

Diff from 1.5 to:

Annotations

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

Annotated File View

ragge
1.5
1 /*      $Id: token.c,v 1.5 2005/04/16 08:16:38 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);
ragge
1.5
338                         goto again;
ragge
1.1
339                 } else if (c == '*') {
340                         if (Cflag)
341                                 fprintf(obuf"/*");
342                         oc = 0;
343                         do { 
344                                 while ((c = slofgetc()) && c != '*') {
345                                         if (c == '\n') {
346                                                 putc(cobuf);
347                                                 ifiles->lineno++;
348                                         } else if (Cflag)
349                                                 putc(cobuf);
350                                 }
351                                 if (Cflag)
352                                         putc(cobuf);
353                                 if ((c = slofgetc()) == '/')
354                                         break;
355                                 unput(c);
356                         } while (c);
357                         if (Cflag)
358                                 putc(cobuf);
359                         if (tflag) {
ragge
1.2
360                                 rval = yylex();
ragge
1.1
361                         } else {
362                                 *yyp++ = ' '; *yyp = 0;
363                                 rval = WSPACE;
364                         }
365                 } else {
366                         unput(c);
367                         *yyp++ = '/'; *yyp = 0;
368                         rval = '/';
369                 }
370                 break;
371
372         case 'L'/* may be STRING, CHARCON or identifier */
373                 *yyp++ = c;
374                 if ((c = slofgetc()) == '"' || c == '\'')
375                         goto chstr;
376 gotid:          while (isalnum(c) || c == '_') {
377                         *yyp++ = c;
378                         c = slofgetc();
379                 }
380                 *yyp = 0;
381                 unput(c);
382                 rval = IDENT;
383                 break;
384
385         default:
386                 if (isalpha(c) || c == '_')
387                         goto gotid;
388                 yystr[0] = cyystr[1] = 0;
389                 rval = c;
390                 break;
391         }
392         return rval;
393 }
394
ragge
1.4
395 #ifdef NEW_READFILE
396 /*
397  * A new file included.  Read buffers are allocated on the stack and
398  * all subroutines are called from here.  This function will be called
399  * recursive when multiple files are included.
400  */
401 int
402 pushfile(char *file)
403 {
404         struct includ incl, *ic = &incl;
405
406         ic->lineno = 1;
407         if (ifiles != NULL) { /* not if first file */
408                 if ((ic->infil = open(fileO_RDONLY)) < 0)
409                         return -1;
410         } else
411                 ic->infil = 0/* STDIN_FILENO */
412
413         ic->fname = savstr(file); /* XXX - will loose space */
414         savch('\0');
415         ic->curptr = ic->buffer;
416         ic->next = ifiles;
417         ifiles = ic;
418
419         while ((c = qscan()) != 0) {
420                 switch (c) {
421                 case CONTROL:
422                         control();
423                         break;
424
425                 
426
427
428
429 }
430 #else
ragge
1.1
431 /*
432  * A new file included.
433  * If ifiles == NULL, this is the first file and already opened (stdin).
434  * Return 0 on success, -1 on failure to open file.
435  */
436 int
437 pushfile(char *file)
438 {
439         struct includ *ic;
440
ragge
1.3
441 #ifdef NEWBUF
442         ic = getbuf(file);
443 #else
ragge
1.1
444         ic = malloc(sizeof(struct includ));
445         ic->fname = strdup(file);
ragge
1.3
446 #endif
ragge
1.1
447         if (ifiles != NULL) {
ragge
1.2
448 #ifdef NEWBUF
449                 if ((ic->infil = open(fileO_RDONLY)) < 0)
450                         return -1;
451 #else
ragge
1.1
452                 if ((ic->ifil = fopen(file"r")) == NULL)
453                         return -1;
ragge
1.2
454 #endif
ragge
1.1
455         } else
ragge
1.2
456 #ifdef NEWBUF
457                 ic->infil = 0;
458 #else
ragge
1.1
459                 ic->ifil = stdin;
ragge
1.2
460 #endif
461 #ifdef NEWBUF
ragge
1.3
462         ic->curptr = ic->buffer;
ragge
1.2
463 #endif
ragge
1.1
464         ic->next = ifiles;
465         ifiles = ic;
ragge
1.5
466         ic->lineno = 0;
467         unput('\n');
ragge
1.1
468
469         return 0;
470 }
ragge
1.4
471 #endif
ragge
1.1
472
473 /*
474  * End of included file (or everything).
475  */
476 void
477 popfile()
478 {
479         struct includ *ic;
480
481         ic = ifiles;
482         ifiles = ifiles->next;
ragge
1.2
483 #ifdef NEWBUF
484         close(ic->infil);
ragge
1.3
485         putbuf(ic);
ragge
1.2
486 #else
ragge
1.1
487         fclose(ic->ifil);
488         free(ic->fname);
489         free(ic);
ragge
1.3
490 #endif
ragge
1.1
491         prtline();
492 }
493
494 /*
495  * Print current position to output file.
496  */
497 void
498 prtline()
499 {
500         fprintf(obuf"# %d \"%s\"\n"ifiles->linenoifiles->fname);
501 }
502
503 void
504 cunput(int c)
505 {
506 extern int dflag;
507 if (dflag)printf(": '%c'(%d)"cc);
508         unput(c);
509 }
510
511 int
512 yywrap()
513 {
514         if (ifiles->next == 0)
515                 return 1;
516         popfile();
517         return 0;
518 }
519
520 void
521 setline(int line)
522 {
523         if (ifiles)
524                 ifiles->lineno = line-1;
525 }
526
527 void
528 setfile(char *name)
529 {
530         if (ifiles)
531                 free(ifiles->fname), ifiles->fname = strdup(name);
532 }
533
534 int
535 curline()
536 {
537         return ifiles ? ifiles->lineno : 0;
538 }
539
540 char *
541 curfile()
542 {
543         return ifiles ? ifiles->fname : "";
544 }
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-20 14:42 +0100