Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050515210634

Diff

Diff from 1.9 to:

Annotations

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

Annotated File View

ragge
1.9
1 /*      $Id: token.c,v 1.9 2005/05/15 21:06:35 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.9
59
60         ic = calloc(sizeof(struct includ), 1);
61 #if 0
ragge
1.6
62         usch *ostr = stringbuf;
ragge
1.3
63
ragge
1.6
64 //printf("getbuf1: stringbuf %p\n", stringbuf);
65         stringbuf = (usch *)ROUND((int)stringbuf);
66 //printf("getbuf2: stringbuf %p\n", stringbuf);
67         ic = (struct includ *)stringbuf;
68         stringbuf += sizeof(struct includ);
69         ic->ostr = ostr;
70
71 //printf("getbuf3: stringbuf %p\n", stringbuf);
ragge
1.9
72 #endif
ragge
1.3
73         return ic;
74 }
75
76 static void
77 putbuf(struct includ *ic)
78 {
ragge
1.9
79         free(ic);
80 #if 0
ragge
1.6
81 //printf("putbuf: stringbuf %p\n", stringbuf);
82 if (stringbuf < (usch *)&ic[1])
83 ;//     printf("ERROR!!!\n");
84 else
85         stringbuf = ic->ostr;
86 //printf("putbuf2: stringbuf %p\n", stringbuf);
ragge
1.9
87 #endif
ragge
1.3
88 }
89
ragge
1.2
90 static int
91 input(void)
92 {
ragge
1.3
93         struct includ *ic;
ragge
1.6
94         int len;
ragge
1.3
95
ragge
1.6
96         if (ifiles->curptr < ifiles->maxread) {
ragge
1.9
97 if (*ifiles->curptr == 0)
98 printf("c %d\n", *ifiles->curptr);
ragge
1.2
99                 return *ifiles->curptr++;
ragge
1.6
100 }
ragge
1.3
101         if (ifiles->infil < 0) {
102                 ic = ifiles;
103                 ifiles = ifiles->next;
104                 putbuf(ic);
105                 return input();
106         }
ragge
1.6
107         if ((len = read(ifiles->infilifiles->bufferCPPBUF)) < 0)
ragge
1.2
108                 error("read error on file %s"ifiles->fname);
ragge
1.6
109         if (len == 0)
ragge
1.3
110                 return -1;
111         ifiles->curptr = ifiles->buffer;
ragge
1.6
112         ifiles->maxread = ifiles->buffer + len;
ragge
1.2
113         return input();
114 }
ragge
1.1
115
ragge
1.2
116 static void
117 unput(int c)
118 {
ragge
1.3
119         struct includ *ic;
120
ragge
1.6
121 if (c == 0) {
122 printf("no;;\n");
123 }
124
125         if (ifiles->curptr > ifiles->bbuf) {
ragge
1.3
126                 *--ifiles->curptr = c;
127         } else {
128                 ic = getbuf(NULL);
129                 ic->fname = ifiles->fname;
130                 ic->lineno = ifiles->lineno;
131                 ic->infil = -1;
ragge
1.6
132                 ic->curptr = &ic->bbuf[NAMEMAX+CPPBUF+1];
133                 ic->maxread = ic->curptr;
ragge
1.3
134                 ic->next = ifiles;
135                 ifiles = ic;
ragge
1.2
136                 *--ifiles->curptr = c;
ragge
1.3
137         }
ragge
1.6
138 //printf("unput %d\n", c);
ragge
1.2
139 }
ragge
1.7
140
141 #define UNPUT(c) *--ifiles->curptr = c
142 #define ADJUST(x) { \
143         if (x > (ifiles->maxread-ifiles->curptr)) { \
144                 memcpy(
145
ragge
1.1
146 static int
147 slofgetc(void)
148 {
149         int c;
150
151 again:  switch (c = input()) {
152         case '\\'/* continued lines */
153                 if ((c = input()) == '\n') {
154                         ifiles->lineno++;
155                         putc('\n'obuf);
156                         goto again;
157                 }
158                 cunput(c);
159                 return '\\';
160         case '?'/* trigraphs */
161                 if ((c = input()) != '?') {
162                         cunput(c);
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                         cunput(c);
177                         cunput('?');
178                         return '?';
179                 }
180                 cunput(c);
181                 goto again;
182         default:
183                 return c;
184         }
185 }
186
187 int
ragge
1.2
188 yylex()
ragge
1.1
189 {
190         static int wasnl = 1;
191         int cocrval;
192
ragge
1.7
193 fast:   yystr = yybuf;
ragge
1.1
194         yyp = yystr;
195         c = input();
196         if (c != ' ' && c != '\t' && c != '#')
197                 wasnl = 0;
ragge
1.3
198 #define ONEMORE()       { *yyp++ = c; c = slofgetc(); }
ragge
1.1
199 again:  switch (c) {
200         case -1:
ragge
1.6
201                 rval = 0;
ragge
1.1
202                 break;
203
204         case '\''/* charcon */
205         case '"'/* string */
206 chstr:          oc = c;
ragge
1.9
207                 do {
208                         *yyp++ = c;
209                         if (c == '\\')
210                                 *yyp++ = slofgetc();
211                 } while ((c = slofgetc()) != EOF && c != oc);
212                 *yyp++ = c; *yyp = 0;
ragge
1.1
213                 rval = oc == '"' ? STRING : CHARCON;
214                 break;
215
216         case '0'case '1'case '2'case '3'case '4'
217         case '5'case '6'case '7'case '8'case '9'
218                 *yyp++ = c;
219                 c = slofgetc();
220                 if (yyp[-1] == '0' && (c == 'x' || c == 'X')) {
221                         do {
222                                 ONEMORE();
223                         } while (isxdigit(c));
224                 } else {
225                         while (isdigit(c))
226                                 ONEMORE();
227                 }
228                 if (c != '.' && c != 'e' && c != 'E') {
229                         /* not floating point number */
230                         while (c == 'l' || c == 'L' || c == 'u' || c == 'U') {
231                                 ONEMORE();
232                         }
233                         cunput(c);
234                         *yyp = 0;
235                         rval = NUMBER;
236                         break;
237                 }
238                 /* it's a floating point number here */
239                 if (c == '.') { /* decimal point */
240 F:                      do { /* may be followed by digits */
241                                 ONEMORE();
242                         } while (isdigit(c));
243                         if (c == 'e' || c == 'E') {
244 E:                              ONEMORE();
245                                 if (c == '-' || c == '+') {
246                                         ONEMORE();
247                                 }
248                                 while (isdigit(c))
249                                         ONEMORE();
250                         }
251                         if (c == 'f' || c == 'F' || c == 'l' || c == 'L')
252                                 ONEMORE();
253                         cunput(c);
254                         *yyp = 0;
255                         rval = FPOINT;
256                         break;
257                 } else
258                         goto E;
259
260         case '.':
261                 ONEMORE();
262                 if (isdigit(c))
263                         goto F;
264                 if (c == '.') {
265                         ONEMORE();
266                         if (c == '.') {
267                                 *yyp++ = '.'; *yyp = 0;
268                                 rval = ELLIPS;
269                                 break;
270                         }
271                         cunput(c);
272                         cunput('.');
273                         *--yyp = 0;
274                         rval = '.';
275                         break;
276                 }
277                 cunput(c);
278                 *yyp = 0;
279                 rval = '.';
280                 break;
281
282         case '\\':
283                 c = input();
284                 if (c == '\n') {
285                         ifiles->lineno++;
ragge
1.7
286                         putch('\n');
287                         goto fast;
288                 }
289                 UNPUT(c);
290                 *yyp++ = '\\'; *yyp = 0;
291                 rval = '\\';
ragge
1.1
292                 break;
293                 
294         case '\n':
295                 wasnl = 1;
296                 ifiles->lineno++;
ragge
1.9
297                 *yyp++ = '\n'; *yyp = 0;
ragge
1.1
298                 rval = NL;
ragge
1.9
299                 break;
ragge
1.1
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.4
400 /*
ragge
1.6
401  * A new file included.
402  * If ifiles == NULL, this is the first file and already opened (stdin).
403  * Return 0 on success, -1 on failure to open file.
ragge
1.4
404  */
405 int
406 pushfile(char *file)
407 {
ragge
1.6
408         struct includ ibuf;
409         struct includ *old;
410         struct includ *ic;
ragge
1.8
411         int otrulvl = trulvloflslvl = flslvl;
ragge
1.6
412
413         ic = &ibuf;
ragge
1.9
414         memset(ic0sizeof(struct includ));
ragge
1.6
415         old = ifiles;
ragge
1.9
416 //printf("ifiles %p ic %p\n", ifiles, ic);
ragge
1.4
417
ragge
1.6
418         if (file != NULL) {
ragge
1.4
419                 if ((ic->infil = open(fileO_RDONLY)) < 0)
420                         return -1;
ragge
1.6
421                 ic->fname = file;
422         } else {
423                 ic->infil = 0;
424                 ic->fname = "<stdin>";
425         }
426         ic->buffer = ic->bbuf+NAMEMAX;
ragge
1.4
427         ic->curptr = ic->buffer;
428         ifiles = ic;
ragge
1.6
429         ic->lineno = 0;
430         ic->maxread = ic->curptr;
431         unput('\n');
ragge
1.4
432
ragge
1.6
433         mainscan();
ragge
1.4
434
ragge
1.8
435         if (trulvl != otrulvl || flslvl != oflslvl)
ragge
1.6
436                 error("unterminated conditional");
ragge
1.4
437
ragge
1.6
438         ifiles = old;
ragge
1.9
439 //printf("ifiles2 %p\n", ifiles);
ragge
1.6
440         close(ic->infil);
441         return 0;
ragge
1.4
442 }
ragge
1.1
443
444 /*
445  * Print current position to output file.
446  */
447 void
448 prtline()
449 {
450         fprintf(obuf"# %d \"%s\"\n"ifiles->linenoifiles->fname);
451 }
452
453 void
454 cunput(int c)
455 {
456 extern int dflag;
457 if (dflag)printf(": '%c'(%d)"cc);
458         unput(c);
459 }
460
461 void
462 setline(int line)
463 {
464         if (ifiles)
465                 ifiles->lineno = line-1;
466 }
467
468 void
469 setfile(char *name)
470 {
471         if (ifiles)
ragge
1.6
472                 ifiles->fname = strdup(name);
ragge
1.1
473 }
474
475 int
476 curline()
477 {
478         return ifiles ? ifiles->lineno : 0;
479 }
480
481 char *
482 curfile()
483 {
484         return ifiles ? ifiles->fname : "";
485 }
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-10-30 14:04 +0100