annotate lwcc/cpp/file.c @ 292:40ecbd5da481 ccdev

Part one of the C preprocessor This is part one of the C preprocessor. It finds and then fails to intepret directives. Also handles line splicing and trigraphs.
author William Astle <lost@l-w.ca>
date Sun, 08 Sep 2013 21:58:12 -0600
parents
children c419b3b3d43f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
292
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
1 /*
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
2 lwcc/cpp/file.c
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
3
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
4 Copyright © 2013 William Astle
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
5
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
6 This file is part of LWTOOLS.
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
7
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
8 LWTOOLS is free software: you can redistribute it and/or modify it under the
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
9 terms of the GNU General Public License as published by the Free Software
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
10 Foundation, either version 3 of the License, or (at your option) any later
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
11 version.
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
12
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
13 This program is distributed in the hope that it will be useful, but WITHOUT
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
16 more details.
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
17
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
18 You should have received a copy of the GNU General Public License along with
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
19 this program. If not, see <http://www.gnu.org/licenses/>.
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
20
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
21
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
22 NOTES:
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
23
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
24 The function fetch_byte() grabs a byte from the input file. It returns
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
25 CPP_EOF if end of file has been reached. The resulting byte has passed
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
26 through three filters, in order:
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
27
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
28 * All CRLF, LFCR, LF, and CR have been converted to CPP_EOL
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
29 * If enabled (--trigraphs), trigraphs have been interpreted
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
30 * \\n (backslash-newline) has been processed (eliminated)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
31
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
32 To obtain a byte without processing \\n, call fetch_byte_tg().
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
33
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
34 */
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
35
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
36 #include <errno.h>
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
37 #include <stdio.h>
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
38 #include <string.h>
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
39
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
40 #include <lw_alloc.h>
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
41
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
42 #include "cpp.h"
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
43
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
44 struct file_stack_e *file_stack = NULL;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
45
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
46 int is_whitespace(int c)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
47 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
48 switch (c)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
49 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
50 case ' ':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
51 case '\t':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
52 case '\r':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
53 case '\n':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
54 return 1;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
55 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
56 return 0;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
57 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
58
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
59 int is_sidchr(c)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
60 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
61 if (c == '_' || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
62 return 1;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
63 return 0;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
64 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
65
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
66 int is_idchr(int c)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
67 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
68 if (c >= '0' && c <= '9')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
69 return 1;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
70 return is_sidchr(c);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
71 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
72
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
73 int is_ep(int c)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
74 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
75 if (c == 'e' || c == 'E' || c == 'p' || c == 'P')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
76 return 1;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
77 return 0;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
78 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
79
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
80 int is_hex(int c)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
81 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
82 if (c >= 'a' && c <= 'f')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
83 return 1;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
84 if (c >= 'A' && c <= 'F')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
85 return 1;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
86 if (c >= '0' && c <= '9')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
87 return 1;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
88 return 0;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
89 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
90
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
91 int is_dec(int c)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
92 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
93 if (c >= '0' && c <= '9')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
94 return 1;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
95 return 0;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
96 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
97
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
98 static void outchr(int c)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
99 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
100 fputc(c, output_fp);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
101 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
102
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
103 static void outstr(char *s)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
104 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
105 while (*s)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
106 outchr(*s++);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
107 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
108
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
109 int fetch_byte_ll(struct file_stack_e *f)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
110 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
111 int c;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
112
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
113 if (f -> eolstate != 0)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
114 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
115 f -> line++;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
116 f -> col = 0;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
117 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
118 c = getc(f -> fp);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
119 f -> col++;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
120 if (f -> eolstate == 1)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
121 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
122 // just saw CR, munch LF
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
123 if (c == 10)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
124 c = getc(f -> fp);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
125 f -> eolstate = 0;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
126 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
127 else if (f -> eolstate == 2)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
128 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
129 // just saw LF, much CR
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
130 if (c == 13)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
131 c = getc(f -> fp);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
132 f -> eolstate = 0;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
133 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
134
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
135 if (c == 10)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
136 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
137 // we have LF - end of line, flag to munch CR
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
138 f -> eolstate = 2;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
139 c = CPP_EOL;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
140 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
141 else if (c == 13)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
142 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
143 // we have CR - end of line, flag to munch LF
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
144 f -> eolstate = 1;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
145 c = CPP_EOL;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
146 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
147 else if (c == EOF)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
148 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
149 c = CPP_EOF;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
150 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
151 return c;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
152 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
153
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
154 int fetch_byte_tg(struct file_stack_e *f)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
155 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
156 int c;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
157
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
158 if (!trigraphs)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
159 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
160 c = fetch_byte_ll(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
161 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
162 else
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
163 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
164 /* we have to do the trigraph shit here */
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
165 if (f -> ra != CPP_NOUNG)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
166 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
167 if (f -> qseen > 0)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
168 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
169 c = '?';
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
170 f -> qseen -= 1;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
171 return c;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
172 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
173 else
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
174 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
175 c = f -> ra;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
176 f -> ra = CPP_NOUNG;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
177 return c;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
178 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
179 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
180
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
181 c = fetch_byte_ll(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
182 while (c == '?')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
183 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
184 f -> qseen++;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
185 c = fetch_byte_ll(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
186 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
187
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
188 if (f -> qseen >= 2)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
189 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
190 // we have a trigraph
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
191 switch (c)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
192 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
193 case '=':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
194 c = '#';
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
195 f -> qseen -= 2;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
196 break;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
197
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
198 case '/':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
199 c = '\\';
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
200 f -> qseen -= 2;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
201 break;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
202
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
203 case '\'':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
204 c = '^';
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
205 f -> qseen -= 2;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
206 break;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
207
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
208 case '(':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
209 c = '[';
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
210 f -> qseen -= 2;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
211 break;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
212
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
213 case ')':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
214 c = ']';
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
215 f -> qseen -= 2;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
216 break;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
217
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
218 case '!':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
219 c = '|';
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
220 f -> qseen -= 2;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
221 break;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
222
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
223 case '<':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
224 c = '{';
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
225 f -> qseen -= 2;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
226 break;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
227
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
228 case '>':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
229 c = '}';
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
230 f -> qseen -= 2;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
231 break;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
232
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
233 case '~':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
234 c = '~';
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
235 f -> qseen -= 2;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
236 break;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
237 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
238 if (f -> qseen > 0)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
239 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
240 f -> ra = c;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
241 c = '?';
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
242 f -> qseen--;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
243 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
244 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
245 else if (f -> qseen > 0)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
246 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
247 f -> ra = c;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
248 c = '?';
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
249 f -> qseen--;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
250 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
251 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
252 return c;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
253 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
254
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
255 int fetch_byte(struct file_stack_e *f)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
256 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
257 int c;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
258
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
259 again:
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
260 if (f -> unget != CPP_NOUNG)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
261 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
262 c = f -> unget;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
263 f -> unget = CPP_NOUNG;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
264 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
265 else
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
266 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
267 c = fetch_byte_tg(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
268 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
269 if (c == '\\')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
270 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
271 int c2;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
272 c2 = fetch_byte_tg(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
273 if (c2 == CPP_EOL)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
274 goto again;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
275 else
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
276 f -> unget = c2;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
277 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
278 f -> curc = c;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
279 return c;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
280 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
281
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
282 static void skip_line(struct file_stack_e *f)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
283 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
284 int c;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
285 while ((c = fetch_byte(f)) != CPP_EOL && c != CPP_EOF)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
286 /* do nothing */ ;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
287 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
288
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
289
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
290 struct
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
291 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
292 char *name;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
293 void (*fn)(struct file_stack_e *);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
294 } directives[] =
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
295 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
296 { NULL, NULL },
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
297 { NULL, NULL }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
298 };
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
299
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
300 /*
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
301 This handles a preprocessing directive. Such a directive goes from the
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
302 next character to be retrieved from f until the first instance of CPP_EOL
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
303 or CPP_EOF.
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
304 */
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
305 void handle_directive(struct file_stack_e *f)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
306 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
307 int c, i;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
308 char kw[20];
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
309
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
310 again:
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
311 while ((c = fetch_byte(f)) == ' ' || c == '\t')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
312 /* do nothing */ ;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
313 if (c == '/')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
314 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
315 // maybe a comment //
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
316 c = fetch_byte(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
317 if (c == '/')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
318 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
319 // line comment
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
320 skip_line(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
321 return;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
322 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
323 if (c == '*')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
324 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
325 // block comment
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
326 while (1)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
327 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
328 c = fetch_byte(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
329 if (c == CPP_EOF)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
330 return;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
331 if (c == '*')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
332 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
333 c = fetch_byte(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
334 if (c == '/')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
335 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
336 // end of comment - try again for directive
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
337 goto again;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
338 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
339 if (c == CPP_EOF)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
340 return;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
341 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
342 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
343 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
344 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
345
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
346 // empty directive - do nothing
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
347 if (c == CPP_EOL)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
348 return;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
349
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
350 if (c < 'a' || c > 'z')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
351 goto out;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
352
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
353 i = 0;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
354 do
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
355 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
356 kw[i++] = c;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
357 if (i == sizeof(kw) - 1)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
358 goto out; // keyword too long
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
359 c = fetch_byte(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
360 } while ((c >= 'a' && c <= 'z') || (c == '_'));
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
361 kw[i++] = '\0';
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
362
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
363 /* we have a keyword here */
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
364 for (i = 0; directives[i].name; i++)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
365 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
366 if (strcmp(directives[i].name, kw) == 0)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
367 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
368 (*directives[i].fn)(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
369 return;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
370 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
371 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
372
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
373 /* if we fall through here, we have an unknown directive */
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
374 out:
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
375 do_error("invalid preprocessor directive");
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
376 skip_line(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
377 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
378
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
379 /*
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
380 Notes:
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
381
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
382 Rather than tokenize the entire file, we run through it interpreting
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
383 things only as much as we need to in order to identify the following:
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
384
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
385 preprocessing directives (#...)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
386 identifiers which might need to be replaced with macros
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
387
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
388 We have to interpret strings, character constants, and numbers to prevent
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
389 false positives in those situations.
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
390
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
391 When we find a preprocessing directive, it is handled with a more
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
392 aggressive tokenization process and then intepreted accordingly.
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
393
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
394 nlws is used to record the fact that only whitespace has occurred at the
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
395 start of a line. Whitespace is defined as comments or isspace(c). It gets
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
396 reset to 1 after each EOL character. If a non-whitespace character is
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
397 encountered, it is set to -1. If the character processing decides it really
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
398 is a whitespace character, it will set nlws back to 1 (block comment).
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
399 Elsewise, it will get set to 0 if it is still -1 when the loop starts again.
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
400
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
401 This is needed so we can identify whitespace interposed before a
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
402 preprocessor directive. This is the only case where it matters for
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
403 the preprocessor.
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
404
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
405 */
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
406 void preprocess_file(struct file_stack_e *f)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
407 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
408 int c;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
409 int nlws = 1;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
410
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
411 while (1)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
412 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
413 c = fetch_byte(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
414 again:
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
415 if (nlws == -1)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
416 nlws = 0;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
417 if (c == CPP_EOF)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
418 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
419 outchr('\n');
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
420 return;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
421 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
422 if (c == CPP_EOL)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
423 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
424 nlws = 1;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
425 outchr('\n');
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
426 continue;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
427 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
428
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
429 if (!is_whitespace(c))
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
430 nlws = -1;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
431
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
432 if (is_sidchr(c))
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
433 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
434 // have identifier here - parse it off
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
435 char *ident = NULL;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
436 int idlen = 0;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
437
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
438 do
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
439 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
440 ident = lw_realloc(ident, idlen + 1);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
441 ident[idlen++] = c;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
442 ident[idlen] = '\0';
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
443 c = fetch_byte(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
444 } while (is_idchr(c));
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
445
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
446 /* do something with the identifier here - macros, etc. */
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
447 outstr(ident);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
448 lw_free(ident);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
449
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
450 goto again;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
451 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
452
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
453 switch (c)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
454 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
455 default:
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
456 outchr(c);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
457 break;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
458
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
459 case '.': // a number - to prevent seeing an identifier in middle of number
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
460 outchr(c);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
461 c = fetch_byte(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
462 if (!is_dec(c))
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
463 goto again;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
464 /* fall through */
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
465 case '0':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
466 case '1':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
467 case '2':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
468 case '3':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
469 case '4':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
470 case '5':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
471 case '6':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
472 case '7':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
473 case '8':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
474 case '9':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
475 do
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
476 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
477 outchr(c);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
478 c = fetch_byte(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
479 if (c == CPP_EOF)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
480 return;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
481 if (is_ep(c))
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
482 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
483 outchr(c);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
484 c = fetch_byte(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
485 if (c == '-' || c == '+')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
486 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
487 outchr(c);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
488 c = fetch_byte(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
489 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
490 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
491 } while ((is_idchr(c)) || (c == '.'));
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
492 goto again;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
493
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
494 case '#':
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
495 if (nlws)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
496 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
497 handle_directive(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
498 /* note: no need to reset nlws */
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
499 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
500 else
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
501 outchr('#');
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
502 break;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
503
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
504 case '\'': // character constant
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
505 outchr('\'');
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
506 while ((c = fetch_byte(f)) != '\'')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
507 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
508 if (c == '\\')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
509 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
510 outchr('\\');
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
511 c = fetch_byte(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
512 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
513 if (c == CPP_EOL)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
514 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
515 do_warning("Unterminated character constant");
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
516 goto again;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
517 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
518 if (c == CPP_EOF)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
519 return;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
520 outchr(c);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
521 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
522 outchr(c);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
523 break;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
524
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
525 case '"': // strings
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
526 outchr(c);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
527 while ((c = fetch_byte(f)) != '"')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
528 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
529 if (c == '\\')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
530 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
531 outchr('\\');
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
532 c = fetch_byte(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
533 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
534 if (c == CPP_EOL)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
535 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
536 do_warning("unterminated string literal");
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
537 goto again;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
538 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
539 if (c == CPP_EOF)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
540 return;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
541 outchr(c);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
542 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
543 outchr(c);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
544 break;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
545
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
546 case '/': // comments
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
547 c = fetch_byte(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
548 if (c == '/')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
549 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
550 // line comment
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
551 outchr(' ');
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
552 do
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
553 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
554 c = fetch_byte(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
555 } while (c != CPP_EOF && c != CPP_EOL);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
556 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
557 else if (c == '*')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
558 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
559 // block comment
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
560 for (;;)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
561 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
562 c = fetch_byte(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
563 if (c == CPP_EOF)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
564 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
565 break;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
566 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
567 if (c == CPP_EOL)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
568 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
569 continue;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
570 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
571 if (c == '*')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
572 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
573 // maybe end of comment
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
574 c = fetch_byte(f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
575 if (c == '/')
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
576 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
577 // end of comment
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
578 break;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
579 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
580 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
581 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
582 // replace comment with a single space
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
583 outchr(' ');
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
584 if (nlws == -1)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
585 nlws = 1;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
586 continue;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
587 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
588 else
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
589 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
590 // restore eaten '/'
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
591 outchr('/');
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
592 // process the character we just fetched
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
593 goto again;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
594 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
595 } // switch
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
596 } // processing loop
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
597 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
598
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
599 int process_file(const char *f)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
600 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
601 struct file_stack_e *nf;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
602 FILE *fp;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
603
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
604 fprintf(stderr, "Processing %s\n", f);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
605
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
606 if (strcmp(f, "-") == 0)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
607 fp = stdin;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
608 else
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
609 fp = fopen(f, "rb");
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
610 if (fp == NULL)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
611 {
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
612 do_warning("Cannot open %s: %s", f, strerror(errno));
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
613 return -1;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
614 }
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
615
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
616 /* push the file onto the file stack */
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
617 nf = lw_alloc(sizeof(struct file_stack_e));
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
618 nf -> fn = f;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
619 nf -> fp = fp;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
620 nf -> next = file_stack;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
621 nf -> line = 1;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
622 nf -> col = 0;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
623 nf -> qseen = 0;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
624 nf -> ra = CPP_NOUNG;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
625 nf -> unget = CPP_NOUNG;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
626 file_stack = nf;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
627
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
628 /* go preprocess the file */
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
629 preprocess_file(nf);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
630
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
631 if (nf -> fp != stdin)
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
632 fclose(nf -> fp);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
633 file_stack = nf -> next;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
634 lw_free(nf);
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
635 return 0;
40ecbd5da481 Part one of the C preprocessor
William Astle <lost@l-w.ca>
parents:
diff changeset
636 }