Include hconfig.h.
[gcc.git] / gcc / scan.c
1 /* scan.c - Utility functions for scan-decls and patch-header programs.
2 Copyright (C) 1993 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2, or (at your option) any
7 later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #include "scan.h"
19 #include "hconfig.h"
20 #include <ctype.h>
21
22 int lineno = 1;
23 int source_lineno = 1;
24 sstring source_filename;
25
26 void
27 make_sstring_space (str, count)
28 sstring *str;
29 int count;
30 {
31 int cur_pos = str->ptr - str->base;
32 int cur_size = str->limit - str->base;
33 int new_size = cur_pos + count + 100;
34
35 if (new_size <= cur_size)
36 return;
37
38 if (str->base == NULL)
39 str->base = xmalloc (new_size);
40 else
41 str->base = xrealloc (str->base, new_size);
42 str->ptr = str->base + cur_size;
43 str->limit = str->base + new_size;
44 }
45
46 void
47 sstring_append (dst, src)
48 sstring *dst;
49 sstring *src;
50 {
51 register char *d, *s;
52 register count = SSTRING_LENGTH(src);
53 MAKE_SSTRING_SPACE(dst, count + 1);
54 d = dst->ptr;
55 s = src->base;
56 while (--count >= 0) *d++ = *s++;
57 dst->ptr = d;
58 *d = 0;
59 }
60
61 memory_full ()
62 {
63 abort();
64 }
65
66 char *
67 xmalloc (size)
68 unsigned size;
69 {
70 register char *ptr = (char *) malloc (size);
71 if (ptr != 0) return (ptr);
72 memory_full ();
73 /*NOTREACHED*/
74 return 0;
75 }
76
77
78 char *
79 xrealloc (old, size)
80 char *old;
81 unsigned size;
82 {
83 register char *ptr = (char *) realloc (old, size);
84 if (ptr != 0) return (ptr);
85 memory_full ();
86 /*NOTREACHED*/
87 return 0;
88 }
89
90 int
91 scan_ident (fp, s, c)
92 register FILE *fp;
93 register sstring *s;
94 int c;
95 {
96 s->ptr = s->base;
97 if (isalpha(c) || c == '_')
98 {
99 for (;;)
100 {
101 SSTRING_PUT(s, c);
102 c = getc (fp);
103 if (c == EOF || !(isalnum(c) || c == '_'))
104 break;
105 }
106 }
107 MAKE_SSTRING_SPACE(s, 1);
108 *s->ptr = 0;
109 return c;
110 }
111
112 int
113 scan_string (fp, s, init)
114 register FILE *fp;
115 register sstring *s;
116 {
117 int c;
118 for (;;)
119 {
120 c = getc (fp);
121 if (c == EOF || c == '\n')
122 break;
123 if (c == init)
124 {
125 c = getc (fp);
126 break;
127 }
128 if (c == '\\')
129 {
130 c = getc (fp);
131 if (c == EOF)
132 break;
133 if (c == '\n')
134 continue;
135 }
136 SSTRING_PUT(s, c);
137 }
138 MAKE_SSTRING_SPACE(s, 1);
139 *s->ptr = 0;
140 return c;
141 }
142
143 /* Skip horizontal white spaces (spaces, tabs, and C-style comments). */
144
145 int
146 skip_spaces (fp, c)
147 register FILE *fp;
148 int c;
149 {
150 for (;;)
151 {
152 if (c == ' ' || c == '\t')
153 c = getc (fp);
154 else if (c == '/')
155 {
156 c = getc (fp);
157 if (c != '*')
158 {
159 ungetc (c, fp);
160 return '/';
161 }
162 c = getc (fp);
163 for (;;)
164 {
165 if (c == EOF)
166 return EOF;
167 else if (c != '*')
168 {
169 if (c == '\n')
170 source_lineno++, lineno++;
171 c = getc (fp);
172 }
173 else if ((c = getc (fp)) == '/')
174 return getc (fp);
175 }
176 }
177 else
178 break;
179 }
180 return c;
181 }
182
183 int
184 read_upto (fp, str, delim)
185 FILE *fp;
186 sstring *str;
187 int delim;
188 {
189 int ch;
190 for (;;)
191 {
192 ch = getc (fp);
193 if (ch == EOF || ch == delim)
194 break;
195 SSTRING_PUT(str, ch);
196 }
197 MAKE_SSTRING_SPACE(str, 1);
198 *str->ptr = 0;
199 return ch;
200 }
201
202 int
203 get_token (fp, s)
204 register FILE *fp;
205 register sstring *s;
206 {
207 int c;
208 s->ptr = s->base;
209 retry:
210 c = ' ';
211 again:
212 c = skip_spaces (fp, c);
213 if (c == '\n')
214 {
215 source_lineno++;
216 lineno++;
217 goto retry;
218 }
219 if (c == '#')
220 {
221 c = get_token (fp, s);
222 if (c == INT_TOKEN)
223 {
224 source_lineno = atoi (s->base);
225 get_token (fp, &source_filename);
226 }
227 for (;;)
228 {
229 c = getc (fp);
230 if (c == EOF)
231 return EOF;
232 if (c == '\n')
233 goto retry;
234 }
235 }
236 if (c == EOF)
237 return EOF;
238 if (isdigit (c))
239 {
240 do
241 {
242 SSTRING_PUT(s, c);
243 c = getc (fp);
244 } while (c != EOF && isdigit(c));
245 ungetc (c, fp);
246 c = INT_TOKEN;
247 goto done;
248 }
249 if (isalpha (c) || c == '_')
250 {
251 c = scan_ident (fp, s, c);
252 ungetc (c, fp);
253 return IDENTIFIER_TOKEN;
254 }
255 if (c == '\'' || c == '"')
256 {
257 int quote = c;
258 c = scan_string (fp, s, c);
259 ungetc (c, fp);
260 return c == '\'' ? CHAR_TOKEN : STRING_TOKEN;
261 }
262 SSTRING_PUT(s, c);
263 done:
264 MAKE_SSTRING_SPACE(s, 1);
265 *s->ptr = 0;
266 return c;
267 }
268
269 unsigned long
270 hash (str)
271 char *str;
272 {
273 int h = 0;
274 /* Replace this with something faster/better! FIXME! */
275 while (*str) h = (h << 3) + *str++;
276 return h & 0x7FFFFFFF;
277 }