Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:gmcgarry:20080415095423

Diff

Diff from 1.12 to:

Annotations

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

Annotated File View

gmcgarry
1.12
1 /*      $Id: token.c,v 1.12 2008/04/15 09:54:23 gmcgarry 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 */
gmcgarry
1.12
38 struct includ *ifiles;
ragge
1.1
39
ragge
1.7
40 usch *yyp, *yystryybuf[CPPBUF];
ragge
1.1
41
42 int yylex(void);
43 int yywrap(void);
44
ragge
1.3
45 static struct includ *
46 getbuf(usch *file)
47 {
48         struct includ *ic;
ragge
1.6
49         usch *ostr = stringbuf;
ragge
1.3
50
ragge
1.6
51         stringbuf = (usch *)ROUND((int)stringbuf);
52         ic = (struct includ *)stringbuf;
53         stringbuf += sizeof(struct includ);
54         ic->ostr = ostr;
55
ragge
1.3
56         return ic;
57 }
58
59 static void
60 putbuf(struct includ *ic)
61 {
ragge
1.6
62 if (stringbuf < (usch *)&ic[1])
ragge
1.11
63 ;
ragge
1.6
64 else
65         stringbuf = ic->ostr;
ragge
1.3
66 }
67
ragge
1.2
68 static int
69 input(void)
70 {
ragge
1.3
71         struct includ *ic;
ragge
1.6
72         int len;
ragge
1.3
73
ragge
1.11
74         if (ifiles->curptr < ifiles->maxread)
ragge
1.2
75                 return *ifiles->curptr++;
ragge
1.11
76
ragge
1.3
77         if (ifiles->infil < 0) {
78                 ic = ifiles;
79                 ifiles = ifiles->next;
80                 putbuf(ic);
81                 return input();
82         }
ragge
1.6
83         if ((len = read(ifiles->infilifiles->bufferCPPBUF)) < 0)
ragge
1.2
84                 error("read error on file %s"ifiles->fname);
ragge
1.6
85         if (len == 0)
ragge
1.3
86                 return -1;
87         ifiles->curptr = ifiles->buffer;
ragge
1.6
88         ifiles->maxread = ifiles->buffer + len;
ragge
1.2
89         return input();
90 }
ragge
1.1
91
ragge
1.2
92 static void
93 unput(int c)
94 {
ragge
1.3
95         struct includ *ic;
96
ragge
1.6
97         if (ifiles->curptr > ifiles->bbuf) {
ragge
1.3
98                 *--ifiles->curptr = c;
99         } else {
100                 ic = getbuf(NULL);
101                 ic->fname = ifiles->fname;
102                 ic->lineno = ifiles->lineno;
103                 ic->infil = -1;
ragge
1.6
104                 ic->curptr = &ic->bbuf[NAMEMAX+CPPBUF+1];
105                 ic->maxread = ic->curptr;
ragge
1.3
106                 ic->next = ifiles;
107                 ifiles = ic;
ragge
1.2
108                 *--ifiles->curptr = c;
ragge
1.3
109         }
ragge
1.2
110 }
ragge
1.7
111
112 #define UNPUT(c) *--ifiles->curptr = c
113
ragge
1.1
114 static int
115 slofgetc(void)
116 {
117         int c;
118
119 again:  switch (c = input()) {
120         case '\\'/* continued lines */
121                 if ((c = input()) == '\n') {
122                         ifiles->lineno++;
123                         putc('\n'obuf);
124                         goto again;
125                 }
126                 cunput(c);
127                 return '\\';
128         case '?'/* trigraphs */
129                 if ((c = input()) != '?') {
130                         cunput(c);
131                         return '?';
132                 }
133                 switch (c = input()) {
134                 case '='c = '#'break;
135                 case '('c = '['break;
136                 case ')'c = ']'break;
137                 case '<'c = '{'break;
138                 case '>'c = '}'break;
139                 case '/'c = '\\'break;
140                 case '\''c = '^'break;
141                 case '!'c = '|'break;
142                 case '-'c = '~'break;
143                 default:
144                         cunput(c);
145                         cunput('?');
146                         return '?';
147                 }
148                 cunput(c);
149                 goto again;
150         default:
151                 return c;
152         }
153 }
154
155 int
ragge
1.2
156 yylex()
ragge
1.1
157 {
158         static int wasnl = 1;
159         int cocrval;
160
ragge
1.7
161 fast:   yystr = yybuf;
ragge
1.1
162         yyp = yystr;
163         c = input();
164         if (c != ' ' && c != '\t' && c != '#')
165                 wasnl = 0;
ragge
1.3
166 #define ONEMORE()       { *yyp++ = c; c = slofgetc(); }
ragge
1.1
167 again:  switch (c) {
168         case -1:
ragge
1.6
169                 rval = 0;
ragge
1.1
170                 break;
171
172         case '\''/* charcon */
173         case '"'/* string */
174 chstr:          oc = c;
ragge
1.11
175                 if (slow == 0) {
176                         do {
177                                 putch(c);
178                                 if (c == '\\')
179                                         putch(slofgetc());
180                         } while ((c = slofgetc()) != EOF && c != oc);
181                         if (c == oc)
182                                 putch(c);
183                         goto fast;
184                 } else {
185                         do {
186                                 *yyp++ = c;
187                                 if (c == '\\')
188                                         *yyp++ = slofgetc();
189                         } while ((c = slofgetc()) != EOF && c != oc);
190                         *yyp++ = c; *yyp = 0;
191                 }
ragge
1.1
192                 rval = oc == '"' ? STRING : CHARCON;
193                 break;
194
195         case '0'case '1'case '2'case '3'case '4'
196         case '5'case '6'case '7'case '8'case '9'
197                 *yyp++ = c;
198                 c = slofgetc();
199                 if (yyp[-1] == '0' && (c == 'x' || c == 'X')) {
200                         do {
201                                 ONEMORE();
202                         } while (isxdigit(c));
203                 } else {
204                         while (isdigit(c))
205                                 ONEMORE();
206                 }
207                 if (c != '.' && c != 'e' && c != 'E') {
208                         /* not floating point number */
209                         while (c == 'l' || c == 'L' || c == 'u' || c == 'U') {
210                                 ONEMORE();
211                         }
212                         cunput(c);
213                         *yyp = 0;
214                         rval = NUMBER;
215                         break;
216                 }
217                 /* it's a floating point number here */
218                 if (c == '.') { /* decimal point */
219 F:                      do { /* may be followed by digits */
220                                 ONEMORE();
221                         } while (isdigit(c));
222                         if (c == 'e' || c == 'E') {
223 E:                              ONEMORE();
224                                 if (c == '-' || c == '+') {
225                                         ONEMORE();
226                                 }
227                                 while (isdigit(c))
228                                         ONEMORE();
229                         }
230                         if (c == 'f' || c == 'F' || c == 'l' || c == 'L')
231                                 ONEMORE();
232                         cunput(c);
233                         *yyp = 0;
234                         rval = FPOINT;
235                         break;
236                 } else
237                         goto E;
238
239         case '.':
240                 ONEMORE();
241                 if (isdigit(c))
242                         goto F;
ragge
1.11
243                 if (!slow) {
244                         UNPUT(c);
245                         putch('.');
246                         goto fast;
247                 }
ragge
1.1
248                 if (c == '.') {
249                         ONEMORE();
250                         if (c == '.') {
251                                 *yyp++ = '.'; *yyp = 0;
252                                 rval = ELLIPS;
253                                 break;
254                         }
255                         cunput(c);
256                         cunput('.');
257                         *--yyp = 0;
258                         rval = '.';
259                         break;
260                 }
261                 cunput(c);
262                 *yyp = 0;
263                 rval = '.';
264                 break;
265
266         case '\\':
267                 c = input();
268                 if (c == '\n') {
269                         ifiles->lineno++;
ragge
1.7
270                         putch('\n');
271                         goto fast;
272                 }
ragge
1.11
273                 if (!slow) {
274                         putch('\\');
275                         goto again;
276                 }
ragge
1.7
277                 UNPUT(c);
278                 *yyp++ = '\\'; *yyp = 0;
279                 rval = '\\';
ragge
1.1
280                 break;
281                 
282         case '\n':
283                 wasnl = 1;
284                 ifiles->lineno++;
285                 rval = NL;
ragge
1.11
286                 if (slow)
287                         break;
288                 if (flslvl == 0) {
289                         if (curline() == 1)
290                                 prtline();
291                         else
292                                 putch('\n');
293                 }
294                 goto fast;
ragge
1.1
295
296         case '#':
297                 if (wasnl) {
298                         wasnl = 0;
299                         rval = CONTROL;
300                         break;
301                 }
ragge
1.11
302                 if (!slow) {
303                         putch('#');
304                         goto fast;
305                 }
ragge
1.1
306                 *yyp++ = c;
307                 c = input();
308                 if (c == '#') {
309                         *yyp++ = c;
310                         *yyp = 0;
311                         rval = CONCAT;
312                 } else {
313                         unput(c);
314                         *yyp = 0;
315                         rval = MKSTR;
316                 }
317                 break;
318
319         case ' ':
320         case '\t'/* whitespace */
321                 do {
322                         *yyp++ = c;
323                         c = input();
324                 } while (c == ' ' || c == '\t');
325                 if (wasnl && c == '#') {
326                         wasnl = 0;
327                         rval = CONTROL;
328                 } else {
329                         unput(c);
330                         *yyp = 0;
331                         rval = WSPACE;
332                 }
333                 break;
334
335         case '/':
336                 if ((c = slofgetc()) == '/') {
337                         if (Cflag)
338                                 fprintf(obuf"//");
339                         while ((c = slofgetc()) && c != '\n')
340                                 if (Cflag)
341                                         putc(cobuf);
ragge
1.5
342                         goto again;
ragge
1.1
343                 } else if (c == '*') {
344                         if (Cflag)
345                                 fprintf(obuf"/*");
346                         oc = 0;
347                         do { 
348                                 while ((c = slofgetc()) && c != '*') {
349                                         if (c == '\n') {
350                                                 putc(cobuf);
351                                                 ifiles->lineno++;
352                                         } else if (Cflag)
353                                                 putc(cobuf);
354                                 }
355                                 if (Cflag)
356                                         putc(cobuf);
357                                 if ((c = slofgetc()) == '/')
358                                         break;
359                                 unput(c);
360                         } while (c);
361                         if (Cflag)
362                                 putc(cobuf);
363                         if (tflag) {
ragge
1.2
364                                 rval = yylex();
ragge
1.1
365                         } else {
366                                 *yyp++ = ' '; *yyp = 0;
367                                 rval = WSPACE;
368                         }
369                 } else {
370                         unput(c);
371                         *yyp++ = '/'; *yyp = 0;
372                         rval = '/';
373                 }
374                 break;
375
376         case 'L'/* may be STRING, CHARCON or identifier */
377                 *yyp++ = c;
378                 if ((c = slofgetc()) == '"' || c == '\'')
379                         goto chstr;
380 gotid:          while (isalnum(c) || c == '_') {
381                         *yyp++ = c;
382                         c = slofgetc();
383                 }
384                 *yyp = 0;
385                 unput(c);
386                 rval = IDENT;
387                 break;
388
389         default:
390                 if (isalpha(c) || c == '_')
391                         goto gotid;
ragge
1.11
392                 if (!slow && c > 5) {
393                         putch(c);
394                         goto fast;
395                 }
ragge
1.1
396                 yystr[0] = cyystr[1] = 0;
397                 rval = c;
398                 break;
399         }
400         return rval;
401 }
402
ragge
1.4
403 /*
ragge
1.6
404  * A new file included.
405  * If ifiles == NULL, this is the first file and already opened (stdin).
406  * Return 0 on success, -1 on failure to open file.
ragge
1.4
407  */
408 int
409 pushfile(char *file)
410 {
ragge
1.6
411         struct includ ibuf;
412         struct includ *old;
413         struct includ *ic;
414
415         ic = &ibuf;
416         old = ifiles;
ragge
1.4
417
ragge
1.11
418         slow = 0;
ragge
1.6
419         if (file != NULL) {
ragge
1.4
420                 if ((ic->infil = open(fileO_RDONLY)) < 0)
421                         return -1;
ragge
1.6
422                 ic->fname = file;
423         } else {
424                 ic->infil = 0;
425                 ic->fname = "<stdin>";
426         }
427         ic->buffer = ic->bbuf+NAMEMAX;
ragge
1.4
428         ic->curptr = ic->buffer;
429         ifiles = ic;
ragge
1.6
430         ic->lineno = 0;
431         ic->maxread = ic->curptr;
432         unput('\n');
ragge
1.4
433
ragge
1.6
434         mainscan();
ragge
1.4
435
ragge
1.11
436         if (trulvl || flslvl)
ragge
1.6
437                 error("unterminated conditional");
ragge
1.4
438
ragge
1.6
439         ifiles = old;
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-08-21 23:59 +0200