* config/arm/netbsd.h (TARGET_OS_CPP_BUILTINS): Use
[official-gcc.git] / gcc / cpptrad.c
blobd5c2126a55ac1b49c3d62d94447b29c8fdad6e93
1 /* CPP Library - traditional lexical analysis and macro expansion.
2 Copyright (C) 2002 Free Software Foundation, Inc.
3 Contributed by Neil Booth, May 2002
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option) any
8 later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 #include "config.h"
20 #include "system.h"
21 #include "cpplib.h"
22 #include "cpphash.h"
24 /* Lexing TODO: Handle -C, maybe -CC, and space in escaped newlines.
25 Stop cpplex.c from recognizing comments and directives during its
26 lexing pass. */
28 static const uchar *handle_newline PARAMS ((cpp_reader *, const uchar *));
29 static const uchar *skip_escaped_newlines PARAMS ((cpp_reader *,
30 const uchar *));
31 static cpp_hashnode *lex_identifier PARAMS ((cpp_reader *, const uchar *));
32 static const uchar *skip_comment PARAMS ((cpp_reader *, const uchar *));
33 static void scan_out_logical_line PARAMS ((cpp_reader *pfile));
34 static void check_output_buffer PARAMS ((cpp_reader *, size_t));
35 static void restore_buff PARAMS ((cpp_reader *));
37 /* Ensures we have N bytes' space in the output buffer, and
38 reallocates it if not. */
39 static void
40 check_output_buffer (pfile, n)
41 cpp_reader *pfile;
42 size_t n;
44 if (n > (size_t) (pfile->trad_out_limit - pfile->trad_out_cur))
46 size_t size = pfile->trad_out_cur - pfile->trad_out_base;
47 size_t new_size = (size + n) * 3 / 2;
49 pfile->trad_out_base
50 = (uchar *) xrealloc (pfile->trad_out_base, new_size);
51 pfile->trad_out_limit = pfile->trad_out_base + new_size;
52 pfile->trad_out_cur = pfile->trad_out_base + size;
56 /* To be called whenever a newline character is encountered in the
57 input file, at CUR. Handles DOS, MAC and Unix ends of line, and
58 returns the character after the newline sequence. */
59 static const uchar *
60 handle_newline (pfile, cur)
61 cpp_reader *pfile;
62 const uchar *cur;
64 pfile->line++;
65 if (cur[0] + cur[1] == '\r' + '\n')
66 cur++;
67 pfile->buffer->line_base = cur + 1;
68 return cur + 1;
71 /* CUR points to any character in the buffer, not necessarily a
72 backslash. Advances CUR until all escaped newlines are skipped,
73 and returns the new position. */
74 static const uchar *
75 skip_escaped_newlines (pfile, cur)
76 cpp_reader *pfile;
77 const uchar *cur;
79 while (*cur == '\\' && is_vspace (cur[1]))
80 cur = handle_newline (pfile, cur + 1);
82 return cur;
85 /* CUR points to the character after the asterisk introducing a
86 comment. Returns the position after the comment. */
87 static const uchar *
88 skip_comment (pfile, cur)
89 cpp_reader *pfile;
90 const uchar *cur;
92 unsigned int from_line = pfile->line;
93 unsigned int c = 0, prevc;
94 const uchar *limit = pfile->buffer->rlimit;
96 while (cur < limit)
98 prevc = c;
99 c = *cur++;
101 if (c == '/')
103 if (prevc == '*')
104 break;
105 if (*cur == '*' && cur[1] != '/'
106 && CPP_OPTION (pfile, warn_comments))
107 cpp_error_with_line (pfile, DL_WARNING, pfile->line, 0,
108 "\"/*\" within comment");
110 else if (is_vspace (c))
111 cur = handle_newline (pfile, cur - 1);
114 if (c != '/' || prevc != '*')
115 cpp_error_with_line (pfile, DL_ERROR, from_line, 0,
116 "unterminated comment");
118 return cur;
121 /* Lexes and outputs an identifier starting at CUR, which is assumed
122 to point to a valid first character of an identifier. Returns
123 the hashnode, and updates trad_out_cur. */
124 static cpp_hashnode *
125 lex_identifier (pfile, cur)
126 cpp_reader *pfile;
127 const uchar *cur;
129 size_t len;
130 uchar *out = pfile->trad_out_cur;
135 *out++ = *cur++;
136 while (ISIDNUM (*cur));
137 cur = skip_escaped_newlines (pfile, cur);
139 while (ISIDNUM (*cur));
141 pfile->buffer->cur = cur;
142 len = out - pfile->trad_out_cur;
143 pfile->trad_out_cur = out;
144 return (cpp_hashnode *) ht_lookup (pfile->hash_table, pfile->trad_out_cur,
145 len, HT_ALLOC);
148 /* Overlays the true file buffer temporarily with text of length LEN
149 starting at START. The true buffer is restored upon calling
150 restore_buff(). */
151 void
152 _cpp_overlay_buffer (pfile, start, len)
153 cpp_reader *pfile;
154 const uchar *start;
155 size_t len;
157 cpp_buffer *buffer = pfile->buffer;
159 buffer->saved_cur = buffer->cur;
160 buffer->saved_rlimit = buffer->rlimit;
161 buffer->saved_line_base = buffer->line_base;
163 buffer->cur = start;
164 buffer->line_base = start;
165 buffer->rlimit = start + len;
168 /* Restores a buffer overlaid by _cpp_overlay_buffer(). */
169 static void
170 restore_buff (pfile)
171 cpp_reader *pfile;
173 cpp_buffer *buffer = pfile->buffer;
175 buffer->cur = buffer->saved_cur;
176 buffer->rlimit = buffer->saved_rlimit;
177 buffer->line_base = buffer->saved_line_base;
180 /* Reads a logical line into the output buffer. Returns TRUE if there
181 is more text left in the buffer. */
182 bool
183 _cpp_read_logical_line_trad (pfile)
184 cpp_reader *pfile;
186 cpp_buffer *buffer;
187 unsigned int first_line;
189 restore_buff (pfile);
191 first_line = pfile->line = pfile->trad_line;
193 buffer = pfile->buffer;
194 if (buffer->cur == buffer->rlimit)
196 bool stop = true;
198 /* Don't pop the last buffer. */
199 if (buffer->prev)
201 stop = buffer->return_at_eof;
202 _cpp_pop_buffer (pfile);
205 if (stop)
206 return false;
209 pfile->trad_out_cur = pfile->trad_out_base;
210 scan_out_logical_line (pfile);
211 pfile->trad_line = pfile->line;
212 pfile->line = first_line;
213 _cpp_overlay_buffer (pfile, pfile->trad_out_base,
214 pfile->trad_out_cur - pfile->trad_out_base);
215 return true;
218 /* Copies the next logical line in the current buffer to the output
219 buffer. The output is guaranteed to terminate with a NUL
220 character. */
221 static void
222 scan_out_logical_line (pfile)
223 cpp_reader *pfile;
225 cpp_buffer *buffer = pfile->buffer;
226 const uchar *cur = buffer->cur;
227 unsigned int c, quote = 0;
228 uchar *out;
230 check_output_buffer (pfile, buffer->rlimit - cur);
231 out = pfile->trad_out_cur;
233 for (;;)
235 c = *cur++;
236 *out++ = c;
238 /* There are only a few entities we need to catch: comments,
239 identifiers, newlines, escaped newlines, # and '\0'. */
240 switch (c)
242 case '\0':
243 if (cur - 1 != buffer->rlimit)
244 break;
245 cur--;
246 if (!buffer->from_stage3)
247 cpp_error (pfile, DL_PEDWARN, "no newline at end of file");
248 pfile->line++;
249 if (0)
251 case '\r': case '\n':
252 cur = handle_newline (pfile, cur - 1);
254 out[-1] = '\n';
255 out[0] = '\0';
256 buffer->cur = cur;
257 pfile->trad_out_cur = out;
258 return;
260 case '"':
261 case '\'':
262 if (c == quote)
263 quote = 0;
264 else if (!quote)
265 quote = c;
266 break;
268 case '\\':
269 if (is_vspace (*cur))
270 out--, cur = skip_escaped_newlines (pfile, cur - 1);
271 else
273 /* Skip escaped quotes here, it's easier than above, but
274 take care to first skip escaped newlines. */
275 cur = skip_escaped_newlines (pfile, cur);
276 if (*cur == '\\' || *cur == '"' || *cur == '\'')
277 *out++ = *cur++;
279 break;
281 case '/':
282 /* Traditional CPP does not recognize comments within
283 literals. */
284 if (!quote)
286 cur = skip_escaped_newlines (pfile, cur);
287 if (*cur == '*')
288 out--, cur = skip_comment (pfile, cur + 1);
290 break;
292 case '_':
293 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
294 case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
295 case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
296 case 's': case 't': case 'u': case 'v': case 'w': case 'x':
297 case 'y': case 'z':
298 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
299 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
300 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
301 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
302 case 'Y': case 'Z':
304 cpp_hashnode *node;
306 pfile->trad_out_cur = --out;
307 node = lex_identifier (pfile, cur - 1);
308 out = pfile->trad_out_cur;
309 cur = buffer->cur;
311 break;
313 default:
314 break;