/src/binutils-gdb/gas/input-scrub.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* input_scrub.c - Break up input buffers into whole numbers of lines. |
2 | | Copyright (C) 1987-2023 Free Software Foundation, Inc. |
3 | | |
4 | | This file is part of GAS, the GNU Assembler. |
5 | | |
6 | | GAS is free software; you can redistribute it and/or modify |
7 | | it under the terms of the GNU General Public License as published by |
8 | | the Free Software Foundation; either version 3, or (at your option) |
9 | | any later version. |
10 | | |
11 | | GAS is distributed in the hope that it will be useful, |
12 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | GNU General Public License for more details. |
15 | | |
16 | | You should have received a copy of the GNU General Public License |
17 | | along with GAS; see the file COPYING. If not, write to the Free |
18 | | Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA |
19 | | 02110-1301, USA. */ |
20 | | |
21 | | #include "as.h" |
22 | | #include "filenames.h" |
23 | | #include "input-file.h" |
24 | | #include "sb.h" |
25 | | #include "listing.h" |
26 | | |
27 | | /* |
28 | | * O/S independent module to supply buffers of sanitised source code |
29 | | * to rest of assembler. We get sanitised input data of arbitrary length. |
30 | | * We break these buffers on line boundaries, recombine pieces that |
31 | | * were broken across buffers, and return a buffer of full lines to |
32 | | * the caller. |
33 | | * The last partial line begins the next buffer we build and return to caller. |
34 | | * The buffer returned to caller is preceded by BEFORE_STRING and followed |
35 | | * by AFTER_STRING, as sentinels. The last character before AFTER_STRING |
36 | | * is a newline. |
37 | | * Also looks after line numbers, for e.g. error messages. |
38 | | */ |
39 | | |
40 | | /* |
41 | | * We don't care how filthy our buffers are, but our callers assume |
42 | | * that the following sanitation has already been done. |
43 | | * |
44 | | * No comments, reduce a comment to a space. |
45 | | * Reduce a tab to a space unless it is 1st char of line. |
46 | | * All multiple tabs and spaces collapsed into 1 char. Tab only |
47 | | * legal if 1st char of line. |
48 | | * # line file statements converted to .line x;.file y; statements. |
49 | | * Escaped newlines at end of line: remove them but add as many newlines |
50 | | * to end of statement as you removed in the middle, to synch line numbers. |
51 | | */ |
52 | | |
53 | 95.5k | #define BEFORE_STRING ("\n") |
54 | 2.35k | #define AFTER_STRING ("\0") /* memcpy of 0 chars might choke. */ |
55 | 107k | #define BEFORE_SIZE (1) |
56 | 5.85k | #define AFTER_SIZE (1) |
57 | | |
58 | | #ifndef TC_EOL_IN_INSN |
59 | 2.24k | #define TC_EOL_IN_INSN(P) 0 |
60 | | #endif |
61 | | |
62 | | static char *buffer_start; /*->1st char of full buffer area. */ |
63 | | static char *partial_where; /*->after last full line in buffer. */ |
64 | | static size_t partial_size; /* >=0. Number of chars in partial line in buffer. */ |
65 | | |
66 | | /* Because we need AFTER_STRING just after last full line, it clobbers |
67 | | 1st part of partial line. So we preserve 1st part of partial line |
68 | | here. */ |
69 | | static char save_source[AFTER_SIZE]; |
70 | | |
71 | | /* The size of the input buffer we concatenate |
72 | | input_file_give_next_buffer chunks into. Excludes the BEFORE and |
73 | | AFTER counts. */ |
74 | | static size_t buffer_length; |
75 | | |
76 | | /* The index into an sb structure we are reading from. -1 if none. */ |
77 | | static size_t sb_index = -1; |
78 | | |
79 | | /* If we are reading from an sb structure, this is it. */ |
80 | | static sb from_sb; |
81 | | |
82 | | /* Should we do a conditional check on from_sb? */ |
83 | | static enum expansion from_sb_expansion = expanding_none; |
84 | | |
85 | | /* The number of nested sb structures we have included. */ |
86 | | int macro_nest; |
87 | | |
88 | | /* We can have more than one source file open at once, though the info for all |
89 | | but the latest one are saved off in a struct input_save. These files remain |
90 | | open, so we are limited by the number of open files allowed by the |
91 | | underlying OS. We may also sequentially read more than one source file in an |
92 | | assembly. */ |
93 | | |
94 | | /* We must track the physical file and line number for error messages. We also |
95 | | track a "logical" file and line number corresponding to (C?) compiler |
96 | | source line numbers. Whenever we open a file we must fill in |
97 | | physical_input_file. So if it is NULL we have not opened any files yet. */ |
98 | | |
99 | | static const char *physical_input_file; |
100 | | static const char *logical_input_file; |
101 | | |
102 | | /* 1-origin line number in a source file. */ |
103 | | /* A line ends in '\n' or eof. */ |
104 | | static unsigned int physical_input_line; |
105 | | static unsigned int logical_input_line; |
106 | | |
107 | | /* Indicator whether the origin of an update was a .linefile directive. */ |
108 | | static bool is_linefile; |
109 | | |
110 | | /* Struct used to save the state of the input handler during include files */ |
111 | | struct input_save { |
112 | | char * buffer_start; |
113 | | char * partial_where; |
114 | | size_t partial_size; |
115 | | char save_source[AFTER_SIZE]; |
116 | | size_t buffer_length; |
117 | | const char * physical_input_file; |
118 | | const char * logical_input_file; |
119 | | unsigned int physical_input_line; |
120 | | unsigned int logical_input_line; |
121 | | bool is_linefile; |
122 | | size_t sb_index; |
123 | | sb from_sb; |
124 | | enum expansion from_sb_expansion; /* Should we do a conditional check? */ |
125 | | struct input_save * next_saved_file; /* Chain of input_saves. */ |
126 | | char * input_file_save; /* Saved state of input routines. */ |
127 | | char * saved_position; /* Caller's saved position in buf. */ |
128 | | }; |
129 | | |
130 | | static struct input_save *input_scrub_push (char *saved_position); |
131 | | static char *input_scrub_pop (struct input_save *arg); |
132 | | |
133 | | /* Saved information about the file that .include'd this one. When we hit EOF, |
134 | | we automatically pop to that file. */ |
135 | | |
136 | | static struct input_save *next_saved_file; |
137 | | |
138 | | /* Initialize input buffering. */ |
139 | | |
140 | | static void |
141 | | input_scrub_reinit (void) |
142 | 95.5k | { |
143 | 95.5k | input_file_begin (); /* Reinitialize! */ |
144 | 95.5k | logical_input_line = -1u; |
145 | 95.5k | logical_input_file = NULL; |
146 | 95.5k | sb_index = -1; |
147 | | |
148 | 95.5k | buffer_length = input_file_buffer_size () * 2; |
149 | 95.5k | buffer_start = XNEWVEC (char, BEFORE_SIZE + AFTER_SIZE + 1 + buffer_length); |
150 | 95.5k | memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE); |
151 | 95.5k | } |
152 | | |
153 | | /* Push the state of input reading and scrubbing so that we can #include. |
154 | | The return value is a 'void *' (fudged for old compilers) to a save |
155 | | area, which can be restored by passing it to input_scrub_pop(). */ |
156 | | |
157 | | static struct input_save * |
158 | | input_scrub_push (char *saved_position) |
159 | 94.4k | { |
160 | 94.4k | struct input_save *saved; |
161 | | |
162 | 94.4k | saved = XNEW (struct input_save); |
163 | | |
164 | 94.4k | saved->saved_position = saved_position; |
165 | 94.4k | saved->buffer_start = buffer_start; |
166 | 94.4k | saved->partial_where = partial_where; |
167 | 94.4k | saved->partial_size = partial_size; |
168 | 94.4k | saved->buffer_length = buffer_length; |
169 | 94.4k | saved->physical_input_file = physical_input_file; |
170 | 94.4k | saved->logical_input_file = logical_input_file; |
171 | 94.4k | saved->physical_input_line = physical_input_line; |
172 | 94.4k | saved->logical_input_line = logical_input_line; |
173 | 94.4k | saved->is_linefile = is_linefile; |
174 | 94.4k | saved->sb_index = sb_index; |
175 | 94.4k | saved->from_sb = from_sb; |
176 | 94.4k | saved->from_sb_expansion = from_sb_expansion; |
177 | 94.4k | memcpy (saved->save_source, save_source, sizeof (save_source)); |
178 | 94.4k | saved->next_saved_file = next_saved_file; |
179 | 94.4k | saved->input_file_save = input_file_push (); |
180 | | |
181 | 94.4k | input_scrub_reinit (); |
182 | | |
183 | 94.4k | return saved; |
184 | 94.4k | } |
185 | | |
186 | | static char * |
187 | | input_scrub_pop (struct input_save *saved) |
188 | 94.4k | { |
189 | 94.4k | char *saved_position; |
190 | | |
191 | 94.4k | input_scrub_end (); /* Finish off old buffer */ |
192 | | |
193 | 94.4k | input_file_pop (saved->input_file_save); |
194 | 94.4k | saved_position = saved->saved_position; |
195 | 94.4k | buffer_start = saved->buffer_start; |
196 | 94.4k | buffer_length = saved->buffer_length; |
197 | 94.4k | physical_input_file = saved->physical_input_file; |
198 | 94.4k | logical_input_file = saved->logical_input_file; |
199 | 94.4k | physical_input_line = saved->physical_input_line; |
200 | 94.4k | logical_input_line = saved->logical_input_line; |
201 | 94.4k | is_linefile = saved->is_linefile; |
202 | 94.4k | sb_index = saved->sb_index; |
203 | 94.4k | from_sb = saved->from_sb; |
204 | 94.4k | from_sb_expansion = saved->from_sb_expansion; |
205 | 94.4k | partial_where = saved->partial_where; |
206 | 94.4k | partial_size = saved->partial_size; |
207 | 94.4k | next_saved_file = saved->next_saved_file; |
208 | 94.4k | memcpy (save_source, saved->save_source, sizeof (save_source)); |
209 | | |
210 | 94.4k | free (saved); |
211 | 94.4k | return saved_position; |
212 | 94.4k | } |
213 | | |
214 | | void |
215 | | input_scrub_begin (void) |
216 | 1.15k | { |
217 | 1.15k | know (strlen (BEFORE_STRING) == BEFORE_SIZE); |
218 | 1.15k | know (strlen (AFTER_STRING) == AFTER_SIZE |
219 | 0 | || (AFTER_STRING[0] == '\0' && AFTER_SIZE == 1)); |
220 | | |
221 | 0 | physical_input_file = NULL; /* No file read yet. */ |
222 | 1.15k | next_saved_file = NULL; /* At EOF, don't pop to any other file */ |
223 | 1.15k | macro_nest = 0; |
224 | 1.15k | input_scrub_reinit (); |
225 | 1.15k | do_scrub_begin (flag_m68k_mri); |
226 | 1.15k | } |
227 | | |
228 | | void |
229 | | input_scrub_end (void) |
230 | 95.5k | { |
231 | 95.5k | if (buffer_start) |
232 | 95.5k | { |
233 | 95.5k | free (buffer_start); |
234 | 95.5k | buffer_start = 0; |
235 | 95.5k | input_file_end (); |
236 | 95.5k | } |
237 | 95.5k | } |
238 | | |
239 | | /* Start reading input from a new file. |
240 | | Return start of caller's part of buffer. */ |
241 | | |
242 | | char * |
243 | | input_scrub_new_file (const char *filename) |
244 | 1.15k | { |
245 | 1.15k | input_file_open (filename, !flag_no_comments); |
246 | 1.15k | physical_input_file = filename[0] ? filename : _("{standard input}"); |
247 | 1.15k | physical_input_line = 0; |
248 | | |
249 | 1.15k | partial_size = 0; |
250 | 1.15k | return (buffer_start + BEFORE_SIZE); |
251 | 1.15k | } |
252 | | |
253 | | /* Include a file from the current file. Save our state, cause it to |
254 | | be restored on EOF, and begin handling a new file. Same result as |
255 | | input_scrub_new_file. */ |
256 | | |
257 | | char * |
258 | | input_scrub_include_file (const char *filename, char *position) |
259 | 0 | { |
260 | 0 | next_saved_file = input_scrub_push (position); |
261 | 0 | from_sb_expansion = expanding_none; |
262 | 0 | return input_scrub_new_file (filename); |
263 | 0 | } |
264 | | |
265 | | /* Start getting input from an sb structure. This is used when |
266 | | expanding a macro. */ |
267 | | |
268 | | void |
269 | | input_scrub_include_sb (sb *from, char *position, enum expansion expansion) |
270 | 94.4k | { |
271 | 94.4k | int newline; |
272 | | |
273 | 94.4k | if (macro_nest > max_macro_nest) |
274 | 0 | as_fatal (_("macros nested too deeply")); |
275 | 94.4k | ++macro_nest; |
276 | | |
277 | | #ifdef md_macro_start |
278 | | if (expansion == expanding_macro) |
279 | | { |
280 | | md_macro_start (); |
281 | | } |
282 | | #endif |
283 | | |
284 | 94.4k | next_saved_file = input_scrub_push (position); |
285 | | |
286 | | /* Allocate sufficient space: from->len plus optional newline |
287 | | plus two ".linefile " directives, plus a little more for other |
288 | | expansion. */ |
289 | 94.4k | newline = from->len >= 1 && from->ptr[0] != '\n'; |
290 | 94.4k | sb_build (&from_sb, from->len + newline + 2 * sizeof (".linefile") + 30); |
291 | 94.4k | from_sb_expansion = expansion; |
292 | 94.4k | if (newline) |
293 | 58.2k | { |
294 | | /* Add the sentinel required by read.c. */ |
295 | 58.2k | sb_add_char (&from_sb, '\n'); |
296 | 58.2k | } |
297 | 94.4k | sb_scrub_and_add_sb (&from_sb, from); |
298 | | |
299 | | /* Make sure the parser looks at defined contents when it scans for |
300 | | e.g. end-of-line at the end of a macro. */ |
301 | 94.4k | sb_terminate (&from_sb); |
302 | | |
303 | 94.4k | sb_index = 1; |
304 | | |
305 | | /* These variables are reset by input_scrub_push. Restore them |
306 | | since we are, after all, still at the same point in the file. */ |
307 | 94.4k | logical_input_line = next_saved_file->logical_input_line; |
308 | 94.4k | logical_input_file = next_saved_file->logical_input_file; |
309 | 94.4k | } |
310 | | |
311 | | void |
312 | | input_scrub_close (void) |
313 | 1.15k | { |
314 | 1.15k | input_file_close (); |
315 | 1.15k | physical_input_line = 0; |
316 | 1.15k | logical_input_line = -1u; |
317 | 1.15k | } |
318 | | |
319 | | char * |
320 | | input_scrub_next_buffer (char **bufp) |
321 | 156k | { |
322 | 156k | char *limit; /*->just after last char of buffer. */ |
323 | | |
324 | 156k | if (sb_index != (size_t) -1) |
325 | 152k | { |
326 | 152k | if (sb_index >= from_sb.len) |
327 | 94.4k | { |
328 | 94.4k | sb_kill (&from_sb); |
329 | 94.4k | if (from_sb_expansion == expanding_macro) |
330 | 29.0k | { |
331 | 29.0k | cond_finish_check (macro_nest); |
332 | | #ifdef md_macro_end |
333 | | /* Allow the target to clean up per-macro expansion |
334 | | data. */ |
335 | | md_macro_end (); |
336 | | #endif |
337 | 29.0k | } |
338 | 94.4k | --macro_nest; |
339 | 94.4k | partial_where = NULL; |
340 | 94.4k | partial_size = 0; |
341 | 94.4k | if (next_saved_file != NULL) |
342 | 94.4k | *bufp = input_scrub_pop (next_saved_file); |
343 | 94.4k | return partial_where; |
344 | 94.4k | } |
345 | | |
346 | 58.2k | partial_where = from_sb.ptr + from_sb.len; |
347 | 58.2k | partial_size = 0; |
348 | 58.2k | *bufp = from_sb.ptr + sb_index; |
349 | 58.2k | sb_index = from_sb.len; |
350 | 58.2k | return partial_where; |
351 | 152k | } |
352 | | |
353 | 3.57k | if (partial_size) |
354 | 1.13k | { |
355 | 1.13k | memmove (buffer_start + BEFORE_SIZE, partial_where, partial_size); |
356 | 1.13k | memcpy (buffer_start + BEFORE_SIZE, save_source, AFTER_SIZE); |
357 | 1.13k | } |
358 | | |
359 | 3.90k | while (1) |
360 | 3.90k | { |
361 | 3.90k | char *p; |
362 | 3.90k | char *start = buffer_start + BEFORE_SIZE + partial_size; |
363 | | |
364 | 3.90k | *bufp = buffer_start + BEFORE_SIZE; |
365 | 3.90k | limit = input_file_give_next_buffer (start); |
366 | 3.90k | if (!limit) |
367 | 1.33k | { |
368 | 1.33k | if (!partial_size) |
369 | | /* End of this file. */ |
370 | 1.21k | break; |
371 | | |
372 | 118 | as_warn (_("end of file not at end of a line; newline inserted")); |
373 | 118 | p = buffer_start + BEFORE_SIZE + partial_size; |
374 | 118 | *p++ = '\n'; |
375 | 118 | limit = p; |
376 | 118 | } |
377 | 2.57k | else |
378 | 2.57k | { |
379 | | /* Terminate the buffer to avoid confusing TC_EOL_IN_INSN. */ |
380 | 2.57k | *limit = '\0'; |
381 | | |
382 | | /* Find last newline. */ |
383 | 13.0M | for (p = limit - 1; *p != '\n' || TC_EOL_IN_INSN (p); --p) |
384 | 13.0M | if (p < start) |
385 | 329 | goto read_more; |
386 | 2.24k | ++p; |
387 | 2.24k | } |
388 | | |
389 | 2.35k | if (multibyte_handling == multibyte_warn) |
390 | 0 | (void) scan_for_multibyte_characters ((const unsigned char *) p, |
391 | 0 | (const unsigned char *) limit, |
392 | 0 | true /* Generate warnings */); |
393 | | |
394 | | /* We found a newline in the newly read chars. */ |
395 | 2.35k | partial_where = p; |
396 | 2.35k | partial_size = limit - p; |
397 | | |
398 | | /* Save the fragment after that last newline. */ |
399 | 2.35k | memcpy (save_source, partial_where, (int) AFTER_SIZE); |
400 | 2.35k | memcpy (partial_where, AFTER_STRING, (int) AFTER_SIZE); |
401 | 2.35k | return partial_where; |
402 | | |
403 | 329 | read_more: |
404 | | /* Didn't find a newline. Read more text. */ |
405 | 329 | partial_size = limit - (buffer_start + BEFORE_SIZE); |
406 | 329 | if (buffer_length - input_file_buffer_size () < partial_size) |
407 | 92 | { |
408 | | /* Increase the buffer when it doesn't have room for the |
409 | | next block of input. */ |
410 | 92 | buffer_length *= 2; |
411 | 92 | buffer_start = XRESIZEVEC (char, buffer_start, |
412 | 92 | (buffer_length |
413 | 92 | + BEFORE_SIZE + AFTER_SIZE + 1)); |
414 | 92 | } |
415 | 329 | } |
416 | | |
417 | | /* Tell the listing we've finished the file. */ |
418 | 1.21k | LISTING_EOF (); |
419 | | |
420 | | /* If we should pop to another file at EOF, do it. */ |
421 | 1.21k | partial_where = NULL; |
422 | 1.21k | if (next_saved_file) |
423 | 0 | *bufp = input_scrub_pop (next_saved_file); |
424 | | |
425 | 1.21k | return partial_where; |
426 | 3.57k | } |
427 | | |
428 | | /* The remaining part of this file deals with line numbers, error |
429 | | messages and so on. Return TRUE if we opened any file. */ |
430 | | |
431 | | int |
432 | | seen_at_least_1_file (void) |
433 | 0 | { |
434 | 0 | return (physical_input_file != NULL); |
435 | 0 | } |
436 | | |
437 | | void |
438 | | bump_line_counters (void) |
439 | 4.91M | { |
440 | 4.91M | if (sb_index == (size_t) -1) |
441 | 2.04M | ++physical_input_line; |
442 | | |
443 | 4.91M | if (logical_input_line != -1u) |
444 | 3.69M | ++logical_input_line; |
445 | 4.91M | } |
446 | | |
447 | | /* Tells us what the new logical line number and file are. |
448 | | If the line_number is -1, we don't change the current logical line |
449 | | number. |
450 | | If fname is NULL, we don't change the current logical file name, unless |
451 | | bit 3 of flags is set. |
452 | | Returns nonzero if the filename actually changes. */ |
453 | | |
454 | | void |
455 | | new_logical_line_flags (const char *fname, /* DON'T destroy it! We point to it! */ |
456 | | int line_number, |
457 | | int flags) |
458 | 381k | { |
459 | 381k | switch (flags) |
460 | 381k | { |
461 | 9.50k | case 0: |
462 | 9.50k | break; |
463 | 3.36k | case 1: |
464 | 3.36k | if (line_number != -1) |
465 | 0 | abort (); |
466 | 3.36k | break; |
467 | 3.36k | case 1 << 1: |
468 | 1.85k | case 1 << 2: |
469 | | /* FIXME: we could check that include nesting is correct. */ |
470 | 1.85k | break; |
471 | 367k | case 1 << 3: |
472 | 367k | if (line_number < 0 || fname != NULL) |
473 | 0 | abort (); |
474 | 367k | if (next_saved_file == NULL) |
475 | 0 | fname = physical_input_file; |
476 | 367k | else if (next_saved_file->logical_input_file) |
477 | 177k | fname = next_saved_file->logical_input_file; |
478 | 189k | else |
479 | 189k | fname = next_saved_file->physical_input_file; |
480 | 367k | break; |
481 | 0 | default: |
482 | 0 | abort (); |
483 | 381k | } |
484 | | |
485 | 381k | is_linefile = flags != 1 && (flags != 0 || fname); |
486 | | |
487 | 381k | if (line_number >= 0) |
488 | 377k | logical_input_line = line_number; |
489 | 4.18k | else if (line_number == -1 && fname && !*fname && (flags & (1 << 2))) |
490 | 0 | { |
491 | 0 | logical_input_file = physical_input_file; |
492 | 0 | logical_input_line = physical_input_line; |
493 | 0 | fname = NULL; |
494 | 0 | } |
495 | | |
496 | 381k | if (fname |
497 | 381k | && (logical_input_file == NULL |
498 | 379k | || filename_cmp (logical_input_file, fname))) |
499 | 14.7k | logical_input_file = fname; |
500 | 381k | } |
501 | | |
502 | | void |
503 | | new_logical_line (const char *fname, int line_number) |
504 | 267 | { |
505 | 267 | new_logical_line_flags (fname, line_number, 0); |
506 | 267 | } |
507 | | |
508 | | void |
509 | | as_report_context (void) |
510 | 7.53M | { |
511 | 7.53M | const struct input_save *saved = next_saved_file; |
512 | 7.53M | enum expansion expansion = from_sb_expansion; |
513 | 7.53M | int indent = 1; |
514 | | |
515 | 7.53M | if (!macro_nest) |
516 | 3.70M | return; |
517 | | |
518 | 3.82M | do |
519 | 4.29M | { |
520 | 4.29M | if (expansion != expanding_macro) |
521 | 4.27M | /* Nothing. */; |
522 | 27.5k | else if (saved->logical_input_file != NULL |
523 | 27.5k | && saved->logical_input_line != -1u) |
524 | 25.4k | as_info_where (saved->logical_input_file, saved->logical_input_line, |
525 | 25.4k | indent, _("macro invoked from here")); |
526 | 2.15k | else |
527 | 2.15k | as_info_where (saved->physical_input_file, saved->physical_input_line, |
528 | 2.15k | indent, _("macro invoked from here")); |
529 | | |
530 | 4.29M | expansion = saved->from_sb_expansion; |
531 | 4.29M | ++indent; |
532 | 4.29M | } |
533 | 4.29M | while ((saved = saved->next_saved_file) != NULL); |
534 | 3.82M | } |
535 | | |
536 | | /* Return the current physical input file name and line number, if known */ |
537 | | |
538 | | const char * |
539 | | as_where_physical (unsigned int *linep) |
540 | 3.12M | { |
541 | 3.12M | if (physical_input_file != NULL) |
542 | 3.12M | { |
543 | 3.12M | if (linep != NULL) |
544 | 3.12M | *linep = physical_input_line; |
545 | 3.12M | return physical_input_file; |
546 | 3.12M | } |
547 | | |
548 | 0 | if (linep != NULL) |
549 | 0 | *linep = 0; |
550 | 0 | return NULL; |
551 | 3.12M | } |
552 | | |
553 | | /* Return the file name and line number at the top most macro |
554 | | invocation, unless .file / .line were used inside a macro. */ |
555 | | |
556 | | const char * |
557 | | as_where (unsigned int *linep) |
558 | 882k | { |
559 | 882k | const char *file = as_where_top (linep); |
560 | | |
561 | 882k | if (macro_nest && is_linefile) |
562 | 459k | { |
563 | 459k | const struct input_save *saved = next_saved_file; |
564 | 459k | enum expansion expansion = from_sb_expansion; |
565 | | |
566 | 459k | do |
567 | 525k | { |
568 | 525k | if (expansion != expanding_macro) |
569 | 523k | /* Nothing. */; |
570 | 1.82k | else if (saved->logical_input_file != NULL |
571 | 1.82k | && (linep == NULL || saved->logical_input_line != -1u)) |
572 | 1.27k | { |
573 | 1.27k | if (linep != NULL) |
574 | 1.27k | *linep = saved->logical_input_line; |
575 | 1.27k | file = saved->logical_input_file; |
576 | 1.27k | } |
577 | 553 | else if (saved->physical_input_file != NULL) |
578 | 553 | { |
579 | 553 | if (linep != NULL) |
580 | 553 | *linep = saved->physical_input_line; |
581 | 553 | file = saved->physical_input_file; |
582 | 553 | } |
583 | | |
584 | 525k | expansion = saved->from_sb_expansion; |
585 | 525k | } |
586 | 525k | while ((saved = saved->next_saved_file) != NULL); |
587 | 459k | } |
588 | | |
589 | 882k | return file; |
590 | 882k | } |
591 | | |
592 | | /* Return the current file name and line number. */ |
593 | | |
594 | | const char * |
595 | | as_where_top (unsigned int *linep) |
596 | 8.53M | { |
597 | 8.53M | if (logical_input_file != NULL |
598 | 8.53M | && (linep == NULL || logical_input_line != -1u)) |
599 | 5.40M | { |
600 | 5.40M | if (linep != NULL) |
601 | 5.40M | *linep = logical_input_line; |
602 | 5.40M | return logical_input_file; |
603 | 5.40M | } |
604 | | |
605 | 3.12M | return as_where_physical (linep); |
606 | 8.53M | } |