140 |
} |
} |
141 |
|
|
142 |
|
|
143 |
/*-----------------------------------------------------------------. |
/*---------------------------------------------------------------. |
144 |
| Read one literal character from FINPUT. Process \-escapes. | |
| Read one literal character from FINPUT, process \-escapes, and | |
145 |
| Append the char to OUT and assign it *PCODE. Return 1 unless the | |
| return the character. | |
146 |
| character is an unescaped `term' or \n report error for \n. | |
`---------------------------------------------------------------*/ |
|
`-----------------------------------------------------------------*/ |
|
147 |
|
|
148 |
int |
char |
149 |
literalchar (struct obstack *out, int *pcode, char term) |
literalchar (void) |
150 |
{ |
{ |
151 |
int c; |
int c; |
152 |
int code; |
int res; |
|
int wasquote = 0; |
|
153 |
|
|
154 |
c = xgetc (finput); |
c = xgetc (finput); |
155 |
if (c == '\n') |
if (c == '\n') |
156 |
{ |
{ |
157 |
complain (_("unescaped newline in constant")); |
complain (_("unescaped newline in constant")); |
158 |
ungetc (c, finput); |
ungetc (c, finput); |
159 |
code = '?'; |
res = '?'; |
|
wasquote = 1; |
|
160 |
} |
} |
161 |
else if (c != '\\') |
else if (c != '\\') |
162 |
{ |
{ |
163 |
code = c; |
res = c; |
|
if (c == term) |
|
|
wasquote = 1; |
|
164 |
} |
} |
165 |
else |
else |
166 |
{ |
{ |
167 |
c = xgetc (finput); |
c = xgetc (finput); |
168 |
if (c == 't') |
if (c == 't') |
169 |
code = '\t'; |
res = '\t'; |
170 |
else if (c == 'n') |
else if (c == 'n') |
171 |
code = '\n'; |
res = '\n'; |
172 |
else if (c == 'a') |
else if (c == 'a') |
173 |
code = '\007'; |
res = '\007'; |
174 |
else if (c == 'r') |
else if (c == 'r') |
175 |
code = '\r'; |
res = '\r'; |
176 |
else if (c == 'f') |
else if (c == 'f') |
177 |
code = '\f'; |
res = '\f'; |
178 |
else if (c == 'b') |
else if (c == 'b') |
179 |
code = '\b'; |
res = '\b'; |
180 |
else if (c == 'v') |
else if (c == 'v') |
181 |
code = '\013'; |
res = '\013'; |
182 |
else if (c == '\\') |
else if (c == '\\') |
183 |
code = '\\'; |
res = '\\'; |
184 |
else if (c == '\'') |
else if (c == '\'') |
185 |
code = '\''; |
res = '\''; |
186 |
else if (c == '\"') |
else if (c == '\"') |
187 |
code = '\"'; |
res = '\"'; |
188 |
else if (c <= '7' && c >= '0') |
else if (c <= '7' && c >= '0') |
189 |
{ |
{ |
190 |
code = 0; |
res = 0; |
191 |
while (c <= '7' && c >= '0') |
while (c <= '7' && c >= '0') |
192 |
{ |
{ |
193 |
code = (code * 8) + (c - '0'); |
res = (res * 8) + (c - '0'); |
194 |
if (code >= 256 || code < 0) |
if (res >= 256 || res < 0) |
195 |
{ |
{ |
196 |
complain (_("octal value outside range 0...255: `\\%o'"), |
complain (_("octal value outside range 0...255: `\\%o'"), |
197 |
code); |
res); |
198 |
code &= 0xFF; |
res &= 0xFF; |
199 |
break; |
break; |
200 |
} |
} |
201 |
c = xgetc (finput); |
c = xgetc (finput); |
205 |
else if (c == 'x') |
else if (c == 'x') |
206 |
{ |
{ |
207 |
c = xgetc (finput); |
c = xgetc (finput); |
208 |
code = 0; |
res = 0; |
209 |
while (1) |
while (1) |
210 |
{ |
{ |
211 |
if (c >= '0' && c <= '9') |
if (c >= '0' && c <= '9') |
212 |
code *= 16, code += c - '0'; |
res *= 16, res += c - '0'; |
213 |
else if (c >= 'a' && c <= 'f') |
else if (c >= 'a' && c <= 'f') |
214 |
code *= 16, code += c - 'a' + 10; |
res *= 16, res += c - 'a' + 10; |
215 |
else if (c >= 'A' && c <= 'F') |
else if (c >= 'A' && c <= 'F') |
216 |
code *= 16, code += c - 'A' + 10; |
res *= 16, res += c - 'A' + 10; |
217 |
else |
else |
218 |
break; |
break; |
219 |
if (code >= 256 || code < 0) |
if (res >= 256 || res < 0) |
220 |
{ |
{ |
221 |
complain (_("hexadecimal value above 255: `\\x%x'"), code); |
complain (_("hexadecimal value above 255: `\\x%x'"), res); |
222 |
code &= 0xFF; |
res &= 0xFF; |
223 |
break; |
break; |
224 |
} |
} |
225 |
c = xgetc (finput); |
c = xgetc (finput); |
232 |
badchar[0] = c; |
badchar[0] = c; |
233 |
complain (_("unknown escape sequence: `\\' followed by `%s'"), |
complain (_("unknown escape sequence: `\\' followed by `%s'"), |
234 |
quote (badchar)); |
quote (badchar)); |
235 |
code = '?'; |
res = '?'; |
236 |
} |
} |
237 |
} /* has \ */ |
} /* has \ */ |
238 |
|
|
239 |
if (out) |
return res; |
|
obstack_1grow (out, code); |
|
|
*pcode = code; |
|
|
return !wasquote; |
|
240 |
} |
} |
241 |
|
|
242 |
|
|
348 |
/* parse the literal token and compute character code in code */ |
/* parse the literal token and compute character code in code */ |
349 |
|
|
350 |
{ |
{ |
351 |
int code; |
int code = literalchar (); |
352 |
|
|
353 |
obstack_1grow (&token_obstack, '\''); |
obstack_1grow (&token_obstack, '\''); |
354 |
literalchar (&token_obstack, &code, '\''); |
obstack_1grow (&token_obstack, code); |
355 |
|
|
356 |
c = getc (finput); |
c = getc (finput); |
357 |
if (c != '\'') |
if (c != '\'') |
358 |
{ |
{ |
|
int discode; |
|
359 |
complain (_("use \"...\" for multi-character literal tokens")); |
complain (_("use \"...\" for multi-character literal tokens")); |
360 |
while (1) |
while (literalchar () != '\'') |
361 |
if (!literalchar (0, &discode, '\'')) |
/* Skip. */; |
|
break; |
|
362 |
} |
} |
363 |
obstack_1grow (&token_obstack, '\''); |
obstack_1grow (&token_obstack, '\''); |
364 |
obstack_1grow (&token_obstack, '\0'); |
obstack_1grow (&token_obstack, '\0'); |
378 |
|
|
379 |
obstack_1grow (&token_obstack, '\"'); |
obstack_1grow (&token_obstack, '\"'); |
380 |
/* Read up to and including ". */ |
/* Read up to and including ". */ |
381 |
while (literalchar (&token_obstack, &code, '\"')) |
do |
382 |
/* nothing */; |
{ |
383 |
|
code = literalchar (); |
384 |
|
obstack_1grow (&token_obstack, code); |
385 |
|
} |
386 |
|
while (code != '\"'); |
387 |
obstack_1grow (&token_obstack, '\0'); |
obstack_1grow (&token_obstack, '\0'); |
388 |
token_buffer = obstack_finish (&token_obstack); |
token_buffer = obstack_finish (&token_obstack); |
389 |
|
|
537 |
arg_offset = obstack_object_size (&token_obstack); |
arg_offset = obstack_object_size (&token_obstack); |
538 |
/* Read up to and including `"'. Do not append the closing |
/* Read up to and including `"'. Do not append the closing |
539 |
`"' in the output: it's not part of the ARG. */ |
`"' in the output: it's not part of the ARG. */ |
540 |
while (literalchar (NULL, &code, '"')) |
while ((code = literalchar ()) != '"') |
541 |
obstack_1grow (&token_obstack, code); |
obstack_1grow (&token_obstack, code); |
542 |
} |
} |
543 |
/* else: should be an error. */ |
/* else: should be an error. */ |