1 | /* Part of CPP library. File handling. |
2 | Copyright (C) 1986-2025 Free Software Foundation, Inc. |
3 | Written by Per Bothner, 1994. |
4 | Based on CCCP program by Paul Rubin, June 1986 |
5 | Adapted to ANSI C, Richard Stallman, Jan 1987 |
6 | Split out of cpplib.c, Zack Weinberg, Oct 1998 |
7 | Reimplemented, Neil Booth, Jul 2003 |
8 | |
9 | This program is free software; you can redistribute it and/or modify it |
10 | under the terms of the GNU General Public License as published by the |
11 | Free Software Foundation; either version 3, or (at your option) any |
12 | later version. |
13 | |
14 | This program is distributed in the hope that it will be useful, |
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | GNU General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU General Public License |
20 | along with this program; see the file COPYING3. If not see |
21 | <http://www.gnu.org/licenses/>. */ |
22 | |
23 | #include "config.h" |
24 | #include "system.h" |
25 | #include "cpplib.h" |
26 | #include "internal.h" |
27 | #include "mkdeps.h" |
28 | #include "obstack.h" |
29 | #include "hashtab.h" |
30 | #include "md5.h" |
31 | #include <dirent.h> |
32 | |
33 | /* Variable length record files on VMS will have a stat size that includes |
34 | record control characters that won't be included in the read size. */ |
35 | #ifdef VMS |
36 | # define FAB_C_VAR 2 /* variable length records (see Starlet fabdef.h) */ |
37 | # define STAT_SIZE_RELIABLE(ST) ((ST).st_fab_rfm != FAB_C_VAR) |
38 | #else |
39 | # define STAT_SIZE_RELIABLE(ST) true |
40 | #endif |
41 | |
42 | #ifdef __DJGPP__ |
43 | #include <io.h> |
44 | /* For DJGPP redirected input is opened in text mode. */ |
45 | # define set_stdin_to_binary_mode() \ |
46 | if (! isatty (0)) setmode (0, O_BINARY) |
47 | #else |
48 | # define set_stdin_to_binary_mode() /* Nothing */ |
49 | #endif |
50 | |
51 | /* This structure represents a file searched for by CPP, whether it |
52 | exists or not. An instance may be pointed to by more than one |
53 | cpp_file_hash_entry; at present no reference count is kept. */ |
54 | struct _cpp_file |
55 | { |
56 | /* Filename as given to #include or command line switch. */ |
57 | const char *name; |
58 | |
59 | /* The full path used to find the file. */ |
60 | const char *path; |
61 | |
62 | /* The full path of the pch file. */ |
63 | const char *pchname; |
64 | |
65 | /* The file's path with the basename stripped. NULL if it hasn't |
66 | been calculated yet. */ |
67 | const char *dir_name; |
68 | |
69 | /* Chain through all files. */ |
70 | struct _cpp_file *next_file; |
71 | |
72 | /* The contents of NAME after calling read_file(). */ |
73 | const uchar *buffer; |
74 | |
75 | /* Pointer to the real start of BUFFER. read_file() might increment |
76 | BUFFER; when freeing, this this pointer must be used instead. */ |
77 | const uchar *buffer_start; |
78 | |
79 | /* The macro, if any, preventing re-inclusion. */ |
80 | const cpp_hashnode *cmacro; |
81 | |
82 | /* The directory in the search path where FILE was found. Used for |
83 | #include_next and determining whether a header is a system |
84 | header. */ |
85 | cpp_dir *dir; |
86 | |
87 | /* As filled in by stat(2) for the file. */ |
88 | struct stat st; |
89 | |
90 | /* Size for #embed, perhaps smaller than st.st_size. */ |
91 | size_t limit; |
92 | |
93 | /* Offset for #embed. */ |
94 | off_t offset; |
95 | |
96 | /* File descriptor. Invalid if -1, otherwise open. */ |
97 | int fd; |
98 | |
99 | /* Zero if this file was successfully opened and stat()-ed, |
100 | otherwise errno obtained from failure. */ |
101 | int err_no; |
102 | |
103 | /* Number of times the file has been stacked for preprocessing. */ |
104 | unsigned short stack_count; |
105 | |
106 | /* If opened with #import or contains #pragma once. */ |
107 | bool once_only : 1; |
108 | |
109 | /* If read() failed before. */ |
110 | bool dont_read : 1; |
111 | |
112 | /* If BUFFER above contains the true contents of the file. */ |
113 | bool buffer_valid : 1; |
114 | |
115 | /* If this file is implicitly preincluded. */ |
116 | bool implicit_preinclude : 1; |
117 | |
118 | /* Set if a header wasn't found with __has_include or __has_include_next |
119 | and error should be emitted if it is included normally. */ |
120 | bool deferred_error : 1; |
121 | |
122 | /* File loaded from #embed. */ |
123 | bool embed : 1; |
124 | |
125 | /* > 0: Known C++ Module header unit, <0: known not. ==0, unknown */ |
126 | int : 2; |
127 | }; |
128 | |
129 | /* A singly-linked list for all searches for a given file name, with |
130 | its head pointed to by a slot in FILE_HASH. The file name is what |
131 | appeared between the quotes in a #include directive; it can be |
132 | determined implicitly from the hash table location or explicitly |
133 | from FILE->name. |
134 | |
135 | FILE is a structure containing details about the file that was |
136 | found with that search, or details of how the search failed. |
137 | |
138 | START_DIR is the starting location of the search in the include |
139 | chain. The current directories for "" includes are also hashed in |
140 | the hash table and therefore unique. Files that are looked up |
141 | without using a search path, such as absolute filenames and file |
142 | names from the command line share a special starting directory so |
143 | they don't cause cache hits with normal include-chain lookups. |
144 | |
145 | If START_DIR is NULL then the entry is for a directory, not a file, |
146 | and the directory is in DIR. Since the starting point in a file |
147 | lookup chain is never NULL, this means that simple pointer |
148 | comparisons against START_DIR can be made to determine cache hits |
149 | in file lookups. |
150 | |
151 | If a cache lookup fails because of e.g. an extra "./" in the path, |
152 | then nothing will break. It is just less efficient as CPP will |
153 | have to do more work re-preprocessing the file, and/or comparing |
154 | its contents against earlier once-only files. |
155 | */ |
156 | struct cpp_file_hash_entry |
157 | { |
158 | struct cpp_file_hash_entry *next; |
159 | cpp_dir *start_dir; |
160 | location_t location; |
161 | union |
162 | { |
163 | _cpp_file *file; |
164 | cpp_dir *dir; |
165 | } u; |
166 | }; |
167 | |
168 | /* Number of entries to put in a cpp_file_hash_entry pool. */ |
169 | #define FILE_HASH_POOL_SIZE 127 |
170 | |
171 | /* A file hash entry pool. We allocate cpp_file_hash_entry object from |
172 | one of these. */ |
173 | struct file_hash_entry_pool |
174 | { |
175 | /* Number of entries used from this pool. */ |
176 | unsigned int file_hash_entries_used; |
177 | /* Next pool in the chain; used when freeing. */ |
178 | struct file_hash_entry_pool *next; |
179 | /* The memory pool. */ |
180 | struct cpp_file_hash_entry pool[FILE_HASH_POOL_SIZE]; |
181 | }; |
182 | |
183 | static bool open_file (_cpp_file *file); |
184 | static bool pch_open_file (cpp_reader *pfile, _cpp_file *file, |
185 | bool *invalid_pch); |
186 | static bool find_file_in_dir (cpp_reader *pfile, _cpp_file *file, |
187 | bool *invalid_pch, location_t loc); |
188 | static bool read_file_guts (cpp_reader *pfile, _cpp_file *file, |
189 | location_t loc, const char *input_charset); |
190 | static bool read_file (cpp_reader *pfile, _cpp_file *file, |
191 | location_t loc); |
192 | static const char *dir_name_of_file (_cpp_file *file); |
193 | static void open_file_failed (cpp_reader *pfile, _cpp_file *file, int, |
194 | location_t); |
195 | static struct cpp_file_hash_entry *search_cache (struct cpp_file_hash_entry *head, |
196 | const cpp_dir *start_dir, |
197 | bool is_embed); |
198 | static _cpp_file *make_cpp_file (cpp_dir *, const char *fname); |
199 | static void destroy_cpp_file (_cpp_file *); |
200 | static cpp_dir *make_cpp_dir (cpp_reader *, const char *dir_name, int sysp); |
201 | static void allocate_file_hash_entries (cpp_reader *pfile); |
202 | static struct cpp_file_hash_entry *new_file_hash_entry (cpp_reader *pfile); |
203 | static int report_missing_guard (void **slot, void *b); |
204 | static hashval_t file_hash_hash (const void *p); |
205 | static int file_hash_eq (const void *p, const void *q); |
206 | static char *read_filename_string (int ch, FILE *f); |
207 | static void read_name_map (cpp_dir *dir); |
208 | static char *remap_filename (cpp_reader *pfile, _cpp_file *file); |
209 | static char *append_file_to_dir (const char *fname, cpp_dir *dir); |
210 | static bool validate_pch (cpp_reader *, _cpp_file *file, const char *pchname); |
211 | static int pchf_save_compare (const void *e1, const void *e2); |
212 | static int pchf_compare (const void *d_p, const void *e_p); |
213 | static bool check_file_against_entries (cpp_reader *, _cpp_file *, bool); |
214 | |
215 | /* Given a filename in FILE->PATH, with the empty string interpreted |
216 | as <stdin>, open it. |
217 | |
218 | On success FILE contains an open file descriptor and stat |
219 | information for the file. On failure the file descriptor is -1 and |
220 | the appropriate errno is also stored in FILE. Returns TRUE iff |
221 | successful. |
222 | |
223 | We used to open files in nonblocking mode, but that caused more |
224 | problems than it solved. Do take care not to acquire a controlling |
225 | terminal by mistake (this can't happen on sane systems, but |
226 | paranoia is a virtue). |
227 | |
228 | Use the three-argument form of open even though we aren't |
229 | specifying O_CREAT, to defend against broken system headers. |
230 | |
231 | O_BINARY tells some runtime libraries (notably DJGPP) not to do |
232 | newline translation; we can handle DOS line breaks just fine |
233 | ourselves. */ |
234 | static bool |
235 | open_file (_cpp_file *file) |
236 | { |
237 | if (file->path[0] == '\0') |
238 | { |
239 | file->fd = 0; |
240 | set_stdin_to_binary_mode (); |
241 | } |
242 | else |
243 | file->fd = open (file: file->path, O_RDONLY | O_NOCTTY | O_BINARY, 0666); |
244 | |
245 | if (file->fd != -1) |
246 | { |
247 | if (fstat (fd: file->fd, buf: &file->st) == 0) |
248 | { |
249 | if (!S_ISDIR (file->st.st_mode)) |
250 | { |
251 | file->err_no = 0; |
252 | return true; |
253 | } |
254 | |
255 | /* Ignore a directory and continue the search. The file we're |
256 | looking for may be elsewhere in the search path. */ |
257 | errno = ENOENT; |
258 | } |
259 | |
260 | close (fd: file->fd); |
261 | file->fd = -1; |
262 | } |
263 | #if defined(_WIN32) && !defined(__CYGWIN__) |
264 | else if (errno == EACCES) |
265 | { |
266 | /* On most UNIX systems, open succeeds on a directory. Above, |
267 | we check if we have opened a directory and if so, set errno |
268 | to ENOENT. However, on Windows, opening a directory |
269 | fails with EACCES. We want to return ENOENT in that |
270 | case too. */ |
271 | if (stat (file->path, &file->st) == 0 |
272 | && S_ISDIR (file->st.st_mode)) |
273 | errno = ENOENT; |
274 | else |
275 | /* The call to stat may have reset errno. */ |
276 | errno = EACCES; |
277 | } |
278 | #endif |
279 | else if (errno == ENOTDIR) |
280 | errno = ENOENT; |
281 | |
282 | file->err_no = errno; |
283 | |
284 | return false; |
285 | } |
286 | |
287 | /* Temporary PCH intercept of opening a file. Try to find a PCH file |
288 | based on FILE->name and FILE->dir, and test those found for |
289 | validity using PFILE->cb.valid_pch. Return true iff a valid file is |
290 | found. Set *INVALID_PCH if a PCH file is found but wasn't valid. */ |
291 | |
292 | static bool |
293 | pch_open_file (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch) |
294 | { |
295 | static const char extension[] = ".gch" ; |
296 | const char *path = file->path; |
297 | size_t len, flen; |
298 | char *pchname; |
299 | struct stat st; |
300 | bool valid = false; |
301 | |
302 | /* No PCH on <stdin> or if not requested. */ |
303 | if (file->name[0] == '\0' || !pfile->cb.valid_pch) |
304 | return false; |
305 | |
306 | /* If the file is not included as first include from either the toplevel |
307 | file or the command-line it is not a valid use of PCH. */ |
308 | for (_cpp_file *f = pfile->all_files; f; f = f->next_file) |
309 | if (f->implicit_preinclude) |
310 | continue; |
311 | else if (pfile->main_file == f) |
312 | break; |
313 | else |
314 | return false; |
315 | |
316 | flen = strlen (s: path); |
317 | len = flen + sizeof (extension); |
318 | pchname = XNEWVEC (char, len); |
319 | memcpy (dest: pchname, src: path, n: flen); |
320 | memcpy (dest: pchname + flen, src: extension, n: sizeof (extension)); |
321 | |
322 | if (stat (file: pchname, buf: &st) == 0) |
323 | { |
324 | DIR *pchdir; |
325 | struct dirent *d; |
326 | size_t dlen, plen = len; |
327 | |
328 | if (!S_ISDIR (st.st_mode)) |
329 | valid = validate_pch (pfile, file, pchname); |
330 | else if ((pchdir = opendir (name: pchname)) != NULL) |
331 | { |
332 | pchname[plen - 1] = '/'; |
333 | while ((d = readdir (dirp: pchdir)) != NULL) |
334 | { |
335 | dlen = strlen (s: d->d_name) + 1; |
336 | if ((strcmp (s1: d->d_name, s2: "." ) == 0) |
337 | || (strcmp (s1: d->d_name, s2: ".." ) == 0)) |
338 | continue; |
339 | if (dlen + plen > len) |
340 | { |
341 | len += dlen + 64; |
342 | pchname = XRESIZEVEC (char, pchname, len); |
343 | } |
344 | memcpy (dest: pchname + plen, src: d->d_name, n: dlen); |
345 | valid = validate_pch (pfile, file, pchname); |
346 | if (valid) |
347 | break; |
348 | } |
349 | closedir (dirp: pchdir); |
350 | } |
351 | if (!valid) |
352 | *invalid_pch = true; |
353 | } |
354 | |
355 | if (valid) |
356 | file->pchname = pchname; |
357 | else |
358 | free (ptr: pchname); |
359 | |
360 | return valid; |
361 | } |
362 | |
363 | /* Canonicalize the path to FILE. Return the canonical form if it is |
364 | shorter, otherwise return NULL. This function does NOT free the |
365 | memory pointed by FILE. */ |
366 | |
367 | static char * |
368 | maybe_shorter_path (const char * file) |
369 | { |
370 | char * file2 = lrealpath (file); |
371 | if (file2 && strlen (s: file2) < strlen (s: file)) |
372 | { |
373 | return file2; |
374 | } |
375 | else |
376 | { |
377 | free (ptr: file2); |
378 | return NULL; |
379 | } |
380 | } |
381 | |
382 | /* Try to open the path FILE->name appended to FILE->dir. This is |
383 | where remap and PCH intercept the file lookup process. Return true |
384 | if the file was found, whether or not the open was successful. |
385 | Set *INVALID_PCH to true if a PCH file is found but wasn't valid. |
386 | Use LOC when emitting any diagnostics. */ |
387 | |
388 | static bool |
389 | find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch, |
390 | location_t loc) |
391 | { |
392 | char *path; |
393 | |
394 | if (CPP_OPTION (pfile, remap) && (path = remap_filename (pfile, file))) |
395 | ; |
396 | else |
397 | if (file->dir->construct) |
398 | path = file->dir->construct (file->name, file->dir); |
399 | else |
400 | path = append_file_to_dir (fname: file->name, dir: file->dir); |
401 | |
402 | if (path) |
403 | { |
404 | hashval_t hv; |
405 | char *copy; |
406 | void **pp; |
407 | |
408 | /* We try to canonicalize system headers. For DOS based file |
409 | * system, we always try to shorten non-system headers, as DOS |
410 | * has a tighter constraint on max path length. */ |
411 | if ((CPP_OPTION (pfile, canonical_system_headers) && file->dir->sysp) |
412 | #ifdef HAVE_DOS_BASED_FILE_SYSTEM |
413 | || !file->dir->sysp |
414 | #endif |
415 | ) |
416 | { |
417 | char * canonical_path = maybe_shorter_path (file: path); |
418 | if (canonical_path) |
419 | { |
420 | /* The canonical path was newly allocated. Let's free the |
421 | non-canonical one. */ |
422 | free (ptr: path); |
423 | path = canonical_path; |
424 | } |
425 | } |
426 | |
427 | hv = htab_hash_string (path); |
428 | if (htab_find_with_hash (pfile->nonexistent_file_hash, path, hv) != NULL) |
429 | { |
430 | file->err_no = ENOENT; |
431 | return false; |
432 | } |
433 | |
434 | file->path = path; |
435 | if (!file->embed && pch_open_file (pfile, file, invalid_pch)) |
436 | return true; |
437 | |
438 | if (open_file (file)) |
439 | return true; |
440 | |
441 | if (file->err_no != ENOENT) |
442 | { |
443 | open_file_failed (pfile, file, 0, loc); |
444 | return true; |
445 | } |
446 | |
447 | /* We copy the path name onto an obstack partly so that we don't |
448 | leak the memory, but mostly so that we don't fragment the |
449 | heap. */ |
450 | copy = (char *) obstack_copy0 (&pfile->nonexistent_file_ob, path, |
451 | strlen (path)); |
452 | free (ptr: path); |
453 | pp = htab_find_slot_with_hash (pfile->nonexistent_file_hash, |
454 | copy, hv, INSERT); |
455 | *pp = copy; |
456 | |
457 | file->path = file->name; |
458 | } |
459 | else |
460 | { |
461 | file->err_no = ENOENT; |
462 | file->path = NULL; |
463 | } |
464 | |
465 | return false; |
466 | } |
467 | |
468 | /* Return true iff the missing_header callback found the given HEADER. */ |
469 | static bool |
470 | search_path_exhausted (cpp_reader *pfile, const char *, _cpp_file *file) |
471 | { |
472 | missing_header_cb func = pfile->cb.missing_header; |
473 | |
474 | /* When the regular search path doesn't work, try context dependent |
475 | headers search paths. */ |
476 | if (func |
477 | && file->dir == NULL) |
478 | { |
479 | if ((file->path = func (pfile, header, &file->dir)) != NULL) |
480 | { |
481 | if (open_file (file)) |
482 | return true; |
483 | free (ptr: (void *)file->path); |
484 | } |
485 | file->path = file->name; |
486 | } |
487 | |
488 | return false; |
489 | } |
490 | |
491 | bool |
492 | _cpp_find_failed (_cpp_file *file) |
493 | { |
494 | return file->err_no != 0; |
495 | } |
496 | |
497 | /* Given a filename FNAME search for such a file in the include path |
498 | starting from START_DIR. If FNAME is the empty string it is |
499 | interpreted as STDIN if START_DIR is PFILE->no_search_path. |
500 | |
501 | If the file is not found in the file cache fall back to the O/S and |
502 | add the result to our cache. |
503 | |
504 | If the file was not found in the filesystem, or there was an error |
505 | opening it, then ERR_NO is nonzero and FD is -1. If the file was |
506 | found, then ERR_NO is zero and FD could be -1 or an open file |
507 | descriptor. FD can be -1 if the file was found in the cache and |
508 | had previously been closed. To open it again pass the return value |
509 | to open_file(). |
510 | |
511 | If KIND is _cpp_FFK_PRE_INCLUDE then it is OK for the file to be |
512 | missing. If present, it is OK for a precompiled header to be |
513 | included after it. |
514 | |
515 | Use LOC as the location for any errors. */ |
516 | |
517 | _cpp_file * |
518 | _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, |
519 | int angle_brackets, _cpp_find_file_kind kind, location_t loc) |
520 | { |
521 | bool invalid_pch = false; |
522 | bool saw_bracket_include = false; |
523 | bool saw_quote_include = false; |
524 | bool saw_embed_include = false; |
525 | struct cpp_dir *found_in_cache = NULL; |
526 | bool is_embed = kind == _cpp_FFK_EMBED || kind == _cpp_FFK_HAS_EMBED; |
527 | |
528 | /* Ensure we get no confusion between cached files and directories. */ |
529 | if (start_dir == NULL) |
530 | cpp_error_at (pfile, CPP_DL_ICE, src_loc: loc, msgid: "NULL directory in %<find_file%>" ); |
531 | |
532 | void **hash_slot |
533 | = htab_find_slot_with_hash (pfile->file_hash, fname, |
534 | htab_hash_string (fname), INSERT); |
535 | |
536 | /* First check the cache before we resort to memory allocation. */ |
537 | cpp_file_hash_entry *entry |
538 | = search_cache (head: (struct cpp_file_hash_entry *) *hash_slot, start_dir, |
539 | is_embed); |
540 | if (entry) |
541 | { |
542 | if (entry->u.file->deferred_error |
543 | && (kind == _cpp_FFK_NORMAL || kind == _cpp_FFK_EMBED)) |
544 | { |
545 | open_file_failed (pfile, file: entry->u.file, angle_brackets, loc); |
546 | entry->u.file->deferred_error = false; |
547 | } |
548 | return entry->u.file; |
549 | } |
550 | |
551 | _cpp_file *file = make_cpp_file (start_dir, fname); |
552 | file->implicit_preinclude |
553 | = (kind == _cpp_FFK_PRE_INCLUDE |
554 | || (pfile->buffer && pfile->buffer->file->implicit_preinclude)); |
555 | file->embed = is_embed; |
556 | |
557 | if (kind == _cpp_FFK_FAKE) |
558 | file->dont_read = true; |
559 | else |
560 | /* Try each path in the include chain. */ |
561 | for (;;) |
562 | { |
563 | if (find_file_in_dir (pfile, file, invalid_pch: &invalid_pch, loc)) |
564 | break; |
565 | |
566 | if (is_embed |
567 | && file->dir == start_dir |
568 | && start_dir != pfile->embed_include |
569 | && start_dir != &pfile->no_search_path) |
570 | file->dir = pfile->embed_include; |
571 | else |
572 | file->dir = file->dir->next; |
573 | if (file->dir == NULL) |
574 | { |
575 | if (!is_embed |
576 | && search_path_exhausted (pfile, header: fname, file)) |
577 | { |
578 | /* Although this file must not go in the cache, |
579 | because the file found might depend on things (like |
580 | the current file) that aren't represented in the |
581 | cache, it still has to go in the list of all files |
582 | so that #import works. */ |
583 | file->next_file = pfile->all_files; |
584 | pfile->all_files = file; |
585 | if (*hash_slot == NULL) |
586 | { |
587 | /* If *hash_slot is NULL, the above |
588 | htab_find_slot_with_hash call just created the |
589 | slot, but we aren't going to store there anything |
590 | of use, so need to remove the newly created entry. |
591 | htab_clear_slot requires that it is non-NULL, so |
592 | store some non-NULL but valid pointer there, |
593 | htab_clear_slot will immediately overwrite it. */ |
594 | *hash_slot = file; |
595 | htab_clear_slot (pfile->file_hash, hash_slot); |
596 | } |
597 | return file; |
598 | } |
599 | |
600 | if (invalid_pch) |
601 | { |
602 | cpp_error (pfile, CPP_DL_ERROR, |
603 | msgid: "one or more PCH files were found," |
604 | " but they were invalid" ); |
605 | if (!cpp_get_options (pfile)->warn_invalid_pch) |
606 | cpp_error (pfile, CPP_DL_NOTE, |
607 | msgid: "use %<-Winvalid-pch%> for more information" ); |
608 | } |
609 | |
610 | if (kind == _cpp_FFK_PRE_INCLUDE) |
611 | { |
612 | free (ptr: (char *) file->name); |
613 | free (ptr: file); |
614 | if (*hash_slot == NULL) |
615 | { |
616 | /* See comment on the above htab_clear_slot call. */ |
617 | *hash_slot = &hash_slot; |
618 | htab_clear_slot (pfile->file_hash, hash_slot); |
619 | } |
620 | return NULL; |
621 | } |
622 | |
623 | if (kind != _cpp_FFK_HAS_INCLUDE && kind != _cpp_FFK_HAS_EMBED) |
624 | open_file_failed (pfile, file, angle_brackets, loc); |
625 | else |
626 | file->deferred_error = true; |
627 | break; |
628 | } |
629 | |
630 | /* Only check the cache for the starting location (done above) |
631 | and the quote and bracket chain heads because there are no |
632 | other possible starting points for searches. */ |
633 | if (file->dir == pfile->bracket_include) |
634 | saw_bracket_include = true; |
635 | else if (file->dir == pfile->quote_include) |
636 | saw_quote_include = true; |
637 | else if (file->dir == pfile->embed_include) |
638 | saw_embed_include = true; |
639 | else |
640 | continue; |
641 | |
642 | entry |
643 | = search_cache (head: (struct cpp_file_hash_entry *) *hash_slot, |
644 | start_dir: file->dir, is_embed); |
645 | if (entry) |
646 | { |
647 | found_in_cache = file->dir; |
648 | break; |
649 | } |
650 | } |
651 | |
652 | if (entry) |
653 | { |
654 | /* Cache for START_DIR too, sharing the _cpp_file structure. */ |
655 | free (ptr: (char *) file->name); |
656 | free (ptr: file); |
657 | file = entry->u.file; |
658 | } |
659 | else |
660 | { |
661 | /* This is a new file; put it in the list. */ |
662 | file->next_file = pfile->all_files; |
663 | pfile->all_files = file; |
664 | } |
665 | |
666 | /* Store this new result in the hash table. */ |
667 | entry = new_file_hash_entry (pfile); |
668 | entry->next = (struct cpp_file_hash_entry *) *hash_slot; |
669 | entry->start_dir = start_dir; |
670 | entry->location = loc; |
671 | entry->u.file = file; |
672 | *hash_slot = (void *) entry; |
673 | |
674 | /* If we passed the quote or bracket chain heads, cache them also. |
675 | This speeds up processing if there are lots of -I options. */ |
676 | if (saw_bracket_include |
677 | && pfile->bracket_include != start_dir |
678 | && found_in_cache != pfile->bracket_include) |
679 | { |
680 | entry = new_file_hash_entry (pfile); |
681 | entry->next = (struct cpp_file_hash_entry *) *hash_slot; |
682 | entry->start_dir = pfile->bracket_include; |
683 | entry->location = loc; |
684 | entry->u.file = file; |
685 | *hash_slot = (void *) entry; |
686 | } |
687 | if (saw_quote_include |
688 | && pfile->quote_include != start_dir |
689 | && found_in_cache != pfile->quote_include) |
690 | { |
691 | entry = new_file_hash_entry (pfile); |
692 | entry->next = (struct cpp_file_hash_entry *) *hash_slot; |
693 | entry->start_dir = pfile->quote_include; |
694 | entry->location = loc; |
695 | entry->u.file = file; |
696 | *hash_slot = (void *) entry; |
697 | } |
698 | if (saw_embed_include |
699 | && pfile->embed_include != start_dir |
700 | && found_in_cache != pfile->embed_include) |
701 | { |
702 | entry = new_file_hash_entry (pfile); |
703 | entry->next = (struct cpp_file_hash_entry *) *hash_slot; |
704 | entry->start_dir = pfile->embed_include; |
705 | entry->location = loc; |
706 | entry->u.file = file; |
707 | *hash_slot = (void *) entry; |
708 | } |
709 | |
710 | return file; |
711 | } |
712 | |
713 | /* Read a file into FILE->buffer, returning true on success. |
714 | |
715 | If FILE->fd is something weird, like a block device, we don't want |
716 | to read it at all. Don't even try to figure out what something is, |
717 | except for plain files and block devices, since there is no |
718 | reliable portable way of doing this. |
719 | |
720 | Use LOC for any diagnostics. |
721 | |
722 | PFILE may be NULL. In this case, no diagnostics are issued. |
723 | |
724 | FIXME: Flush file cache and try again if we run out of memory. */ |
725 | static bool |
726 | read_file_guts (cpp_reader *pfile, _cpp_file *file, location_t loc, |
727 | const char *input_charset) |
728 | { |
729 | ssize_t size, pad, total, count; |
730 | uchar *buf; |
731 | bool regular; |
732 | |
733 | if (S_ISBLK (file->st.st_mode)) |
734 | { |
735 | if (pfile) |
736 | cpp_error_at (pfile, CPP_DL_ERROR, src_loc: loc, |
737 | msgid: "%s is a block device" , file->path); |
738 | return false; |
739 | } |
740 | |
741 | regular = S_ISREG (file->st.st_mode) != 0; |
742 | if (regular) |
743 | { |
744 | /* off_t might have a wider range than ssize_t - in other words, |
745 | the max size of a file might be bigger than the address |
746 | space. We can't handle a file that large. (Anyone with |
747 | a single source file bigger than 2GB needs to rethink |
748 | their coding style.) Some systems (e.g. AIX 4.1) define |
749 | SSIZE_MAX to be much smaller than the actual range of the |
750 | type. Use INTTYPE_MAXIMUM unconditionally to ensure this |
751 | does not bite us. */ |
752 | if (file->st.st_size > INTTYPE_MAXIMUM (ssize_t)) |
753 | { |
754 | if (pfile) |
755 | cpp_error_at (pfile, CPP_DL_ERROR, src_loc: loc, |
756 | msgid: "%s is too large" , file->path); |
757 | return false; |
758 | } |
759 | |
760 | size = file->st.st_size; |
761 | } |
762 | else |
763 | /* 8 kilobytes is a sensible starting size. It ought to be bigger |
764 | than the kernel pipe buffer, and it's definitely bigger than |
765 | the majority of C source files. */ |
766 | size = 8 * 1024; |
767 | |
768 | pad = CPP_BUFFER_PADDING; |
769 | /* The '+ PAD' here is space for the final '\n' and PAD-1 bytes of padding, |
770 | allowing search_line_fast to use (possibly misaligned) vector loads. */ |
771 | buf = XNEWVEC (uchar, size + pad); |
772 | total = 0; |
773 | while ((count = read (fd: file->fd, buf: buf + total, nbytes: size - total)) > 0) |
774 | { |
775 | total += count; |
776 | |
777 | if (total == size) |
778 | { |
779 | if (regular) |
780 | break; |
781 | size *= 2; |
782 | buf = XRESIZEVEC (uchar, buf, size + pad); |
783 | } |
784 | } |
785 | |
786 | if (count < 0) |
787 | { |
788 | if (pfile) |
789 | cpp_errno_filename (pfile, CPP_DL_ERROR, filename: file->path, loc); |
790 | free (ptr: buf); |
791 | return false; |
792 | } |
793 | |
794 | if (pfile && regular && total != size && STAT_SIZE_RELIABLE (file->st)) |
795 | cpp_error_at (pfile, CPP_DL_WARNING, src_loc: loc, |
796 | msgid: "%s is shorter than expected" , file->path); |
797 | |
798 | file->buffer = _cpp_convert_input (pfile, |
799 | input_charset, |
800 | buf, size + pad, total, |
801 | &file->buffer_start, |
802 | &file->st.st_size); |
803 | file->buffer_valid = file->buffer; |
804 | return file->buffer_valid; |
805 | } |
806 | |
807 | /* Convenience wrapper around read_file_guts that opens the file if |
808 | necessary and closes the file descriptor after reading. FILE must |
809 | have been passed through find_file() at some stage. Use LOC for |
810 | any diagnostics. Unlike read_file_guts(), PFILE may not be NULL. */ |
811 | static bool |
812 | read_file (cpp_reader *pfile, _cpp_file *file, location_t loc) |
813 | { |
814 | /* If we already have its contents in memory, succeed immediately. */ |
815 | if (file->buffer_valid) |
816 | return true; |
817 | |
818 | /* If an earlier read failed for some reason don't try again. */ |
819 | if (file->dont_read || file->err_no) |
820 | return false; |
821 | |
822 | if (file->fd == -1 && !open_file (file)) |
823 | { |
824 | open_file_failed (pfile, file, 0, loc); |
825 | return false; |
826 | } |
827 | |
828 | file->dont_read = !read_file_guts (pfile, file, loc, |
829 | CPP_OPTION (pfile, input_charset)); |
830 | close (fd: file->fd); |
831 | file->fd = -1; |
832 | |
833 | return !file->dont_read; |
834 | } |
835 | |
836 | /* Returns TRUE if FILE is already known to be idempotent, and should |
837 | therefore not be read again. */ |
838 | static bool |
839 | is_known_idempotent_file (cpp_reader *pfile, _cpp_file *file, bool import) |
840 | { |
841 | /* Skip once-only files. */ |
842 | if (file->once_only) |
843 | return true; |
844 | |
845 | /* We must mark the file once-only if #import now, before header |
846 | guard checks. Otherwise, undefining the header guard might |
847 | cause the file to be re-stacked. */ |
848 | if (import) |
849 | { |
850 | _cpp_mark_file_once_only (pfile, file); |
851 | |
852 | /* Don't stack files that have been stacked before. */ |
853 | if (file->stack_count) |
854 | return true; |
855 | } |
856 | |
857 | /* Skip if the file had a header guard and the macro is defined. |
858 | PCH relies on this appearing before the PCH handler below. */ |
859 | if (file->cmacro && cpp_macro_p (node: file->cmacro)) |
860 | return true; |
861 | |
862 | /* Handle PCH files immediately; don't stack them. */ |
863 | if (file->pchname) |
864 | { |
865 | pfile->cb.read_pch (pfile, file->pchname, file->fd, file->path); |
866 | file->fd = -1; |
867 | free (ptr: (void *) file->pchname); |
868 | file->pchname = NULL; |
869 | return true; |
870 | } |
871 | |
872 | return false; |
873 | } |
874 | |
875 | /* Return TRUE if file has unique contents, so we should read process |
876 | it. The file's contents must already have been read. */ |
877 | |
878 | static bool |
879 | has_unique_contents (cpp_reader *pfile, _cpp_file *file, bool import, |
880 | location_t loc) |
881 | { |
882 | /* Check the file against the PCH file. This is done before |
883 | checking against files we've already seen, since it may save on |
884 | I/O. */ |
885 | if (check_file_against_entries (pfile, file, import)) |
886 | { |
887 | /* If this isn't a #import, but yet we can't include the file, |
888 | that means that it was #import-ed in the PCH file, |
889 | so we can never include it again. */ |
890 | if (! import) |
891 | _cpp_mark_file_once_only (pfile, file); |
892 | return false; |
893 | } |
894 | |
895 | /* Now we've read the file's contents, we can stack it if there |
896 | are no once-only files. */ |
897 | if (!pfile->seen_once_only) |
898 | return true; |
899 | |
900 | /* We may have read the file under a different name. Look |
901 | for likely candidates and compare file contents to be sure. */ |
902 | for (_cpp_file *f = pfile->all_files; f; f = f->next_file) |
903 | { |
904 | if (f == file) |
905 | continue; /* It'sa me! */ |
906 | |
907 | if (f->embed) |
908 | continue; |
909 | |
910 | if ((import || f->once_only) |
911 | && f->err_no == 0 |
912 | && f->st.st_mtime == file->st.st_mtime |
913 | && f->st.st_size == file->st.st_size) |
914 | { |
915 | _cpp_file *ref_file; |
916 | |
917 | if (f->buffer && !f->buffer_valid) |
918 | { |
919 | /* We already have a buffer but it is not valid, because |
920 | the file is still stacked. Make a new one. */ |
921 | ref_file = make_cpp_file (f->dir, fname: f->name); |
922 | ref_file->path = f->path; |
923 | } |
924 | else |
925 | /* The file is not stacked anymore. We can reuse it. */ |
926 | ref_file = f; |
927 | |
928 | bool same_file_p = (read_file (pfile, file: ref_file, loc) |
929 | /* Size might have changed in read_file(). */ |
930 | && ref_file->st.st_size == file->st.st_size |
931 | && !memcmp (s1: ref_file->buffer, s2: file->buffer, |
932 | n: file->st.st_size)); |
933 | |
934 | if (f->buffer && !f->buffer_valid) |
935 | { |
936 | ref_file->path = 0; |
937 | destroy_cpp_file (ref_file); |
938 | } |
939 | |
940 | if (same_file_p) |
941 | /* Already seen under a different name. */ |
942 | return false; |
943 | } |
944 | } |
945 | |
946 | return true; |
947 | } |
948 | |
949 | /* Place the file referenced by FILE into a new buffer on the buffer |
950 | stack if possible. Returns true if a buffer is stacked. Use LOC |
951 | for any diagnostics. */ |
952 | |
953 | bool |
954 | _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, include_type type, |
955 | location_t loc) |
956 | { |
957 | if (is_known_idempotent_file (pfile, file, import: type == IT_IMPORT)) |
958 | return false; |
959 | |
960 | int sysp = 0; |
961 | char *buf = nullptr; |
962 | |
963 | /* Check C++ module include translation. */ |
964 | if (!file->header_unit && type < IT_HEADER_HWM |
965 | /* Do not include translate include-next. */ |
966 | && type != IT_INCLUDE_NEXT |
967 | && pfile->cb.translate_include) |
968 | buf = (pfile->cb.translate_include |
969 | (pfile, pfile->line_table, loc, file->path)); |
970 | |
971 | if (buf) |
972 | { |
973 | /* We don't increment the line number at the end of a buffer, |
974 | because we don't usually need that location (we're popping an |
975 | include file). However in this case we do want to do the |
976 | increment. So push a writable buffer of two newlines to acheive |
977 | that. (We also need an extra newline, so this looks like a regular |
978 | file, which we do that to to make sure we don't fall off the end in the |
979 | middle of a line. */ |
980 | if (type != IT_CMDLINE) |
981 | { |
982 | static uchar newlines[] = "\n\n\n" ; |
983 | cpp_push_buffer (pfile, newlines, 2, true); |
984 | } |
985 | |
986 | size_t len = strlen (s: buf); |
987 | buf[len] = '\n'; /* See above */ |
988 | cpp_buffer *buffer |
989 | = cpp_push_buffer (pfile, reinterpret_cast<unsigned char *> (buf), |
990 | len, true); |
991 | buffer->to_free = buffer->buf; |
992 | if (type == IT_CMDLINE) |
993 | /* Tell _cpp_pop_buffer to change files. */ |
994 | buffer->file = file; |
995 | |
996 | file->header_unit = +1; |
997 | _cpp_mark_file_once_only (pfile, file); |
998 | } |
999 | else |
1000 | { |
1001 | /* Not a header unit, and we know it. */ |
1002 | file->header_unit = -1; |
1003 | |
1004 | if (!read_file (pfile, file, loc)) |
1005 | return false; |
1006 | |
1007 | if (!has_unique_contents (pfile, file, import: type == IT_IMPORT, loc)) |
1008 | return false; |
1009 | |
1010 | if (pfile->buffer && file->dir) |
1011 | sysp = MAX (pfile->buffer->sysp, file->dir->sysp); |
1012 | |
1013 | /* Add the file to the dependencies on its first inclusion. */ |
1014 | if (CPP_OPTION (pfile, deps.style) > (sysp != 0) |
1015 | && !file->stack_count |
1016 | && file->path[0] |
1017 | && !(pfile->main_file == file |
1018 | && CPP_OPTION (pfile, deps.ignore_main_file))) |
1019 | deps_add_dep (pfile->deps, file->path); |
1020 | |
1021 | /* Clear buffer_valid since _cpp_clean_line messes it up. */ |
1022 | file->buffer_valid = false; |
1023 | file->stack_count++; |
1024 | |
1025 | /* Stack the buffer. */ |
1026 | cpp_buffer *buffer |
1027 | = cpp_push_buffer (pfile, file->buffer, file->st.st_size, |
1028 | CPP_OPTION (pfile, preprocessed) |
1029 | && !CPP_OPTION (pfile, directives_only)); |
1030 | buffer->file = file; |
1031 | buffer->sysp = sysp; |
1032 | buffer->to_free = file->buffer_start; |
1033 | |
1034 | /* Initialize controlling macro state. */ |
1035 | pfile->mi_valid = true; |
1036 | pfile->mi_cmacro = 0; |
1037 | } |
1038 | |
1039 | /* In the case of a normal #include, we're now at the start of the |
1040 | line *following* the #include. A separate location_t for this |
1041 | location makes no sense, until we do the LC_LEAVE. |
1042 | |
1043 | This does not apply if we found a PCH file, we're not a regular |
1044 | include, or we ran out of locations. */ |
1045 | bool decrement = (file->pchname == NULL |
1046 | && type < IT_DIRECTIVE_HWM |
1047 | && (pfile->line_table->highest_location |
1048 | != LINE_MAP_MAX_LOCATION - 1)); |
1049 | |
1050 | if (decrement) |
1051 | pfile->line_table->highest_location--; |
1052 | |
1053 | /* Normally a header unit becomes an __import directive in the current file, |
1054 | but with -include we need something to LC_LEAVE to trigger the file_change |
1055 | hook and continue to the next -include or the main source file. */ |
1056 | if (file->header_unit <= 0 || type == IT_CMDLINE) |
1057 | /* Add line map and do callbacks. */ |
1058 | _cpp_do_file_change (pfile, LC_ENTER, file->path, |
1059 | /* With preamble injection, start on line zero, |
1060 | so the preamble doesn't appear to have been |
1061 | included from line 1. Likewise when |
1062 | starting preprocessed, we expect an initial |
1063 | locating line. */ |
1064 | type == IT_PRE_MAIN ? 0 : 1, sysp); |
1065 | else if (decrement) |
1066 | { |
1067 | /* Adjust the line back one so we appear on the #include line itself. */ |
1068 | const line_map_ordinary *map |
1069 | = LINEMAPS_LAST_ORDINARY_MAP (set: pfile->line_table); |
1070 | linenum_type line = SOURCE_LINE (ord_map: map, loc: pfile->line_table->highest_line); |
1071 | linemap_line_start (set: pfile->line_table, to_line: line - 1, max_column_hint: 0); |
1072 | } |
1073 | |
1074 | return true; |
1075 | } |
1076 | |
1077 | /* Mark FILE to be included once only. */ |
1078 | void |
1079 | _cpp_mark_file_once_only (cpp_reader *pfile, _cpp_file *file) |
1080 | { |
1081 | pfile->seen_once_only = true; |
1082 | file->once_only = true; |
1083 | } |
1084 | |
1085 | /* Return the directory from which searching for FNAME should start, |
1086 | considering the directive TYPE and ANGLE_BRACKETS. If there is |
1087 | nothing left in the path, returns NULL. */ |
1088 | struct cpp_dir * |
1089 | search_path_head (cpp_reader *pfile, const char *fname, int angle_brackets, |
1090 | enum include_type type, bool suppress_diagnostic) |
1091 | { |
1092 | cpp_dir *dir; |
1093 | _cpp_file *file; |
1094 | |
1095 | if (IS_ABSOLUTE_PATH (fname)) |
1096 | return &pfile->no_search_path; |
1097 | |
1098 | /* pfile->buffer is NULL when processing an -include command-line flag. */ |
1099 | file = pfile->buffer == NULL ? pfile->main_file : pfile->buffer->file; |
1100 | |
1101 | /* For #include_next, skip in the search path past the dir in which |
1102 | the current file was found, but if it was found via an absolute |
1103 | path use the normal search logic. */ |
1104 | if (type == IT_INCLUDE_NEXT && file->dir |
1105 | && file->dir != &pfile->no_search_path) |
1106 | dir = file->dir->next; |
1107 | else if (angle_brackets) |
1108 | dir = type == IT_EMBED ? pfile->embed_include : pfile->bracket_include; |
1109 | else if (type == IT_CMDLINE) |
1110 | /* -include and -imacros use the #include "" chain with the |
1111 | preprocessor's cwd prepended. */ |
1112 | return make_cpp_dir (pfile, dir_name: "./" , sysp: false); |
1113 | else if (pfile->quote_ignores_source_dir && type != IT_EMBED) |
1114 | dir = pfile->quote_include; |
1115 | else |
1116 | return make_cpp_dir (pfile, dir_name: dir_name_of_file (file), |
1117 | sysp: pfile->buffer ? pfile->buffer->sysp : 0); |
1118 | |
1119 | if (dir == NULL && !suppress_diagnostic) |
1120 | cpp_error (pfile, CPP_DL_ERROR, |
1121 | msgid: "no include path in which to search for %s" , fname); |
1122 | |
1123 | return dir; |
1124 | } |
1125 | |
1126 | /* Strip the basename from the file's path. It ends with a slash if |
1127 | of nonzero length. Note that this procedure also works for |
1128 | <stdin>, which is represented by the empty string. */ |
1129 | static const char * |
1130 | dir_name_of_file (_cpp_file *file) |
1131 | { |
1132 | if (!file->dir_name) |
1133 | { |
1134 | size_t len = lbasename (file->path) - file->path; |
1135 | char *dir_name = XNEWVEC (char, len + 1); |
1136 | |
1137 | memcpy (dest: dir_name, src: file->path, n: len); |
1138 | dir_name[len] = '\0'; |
1139 | file->dir_name = dir_name; |
1140 | } |
1141 | |
1142 | return file->dir_name; |
1143 | } |
1144 | |
1145 | /* Handles #include-family directives (distinguished by TYPE), |
1146 | including HEADER, and the command line -imacros and -include. |
1147 | Returns true if a buffer was stacked. */ |
1148 | bool |
1149 | _cpp_stack_include (cpp_reader *pfile, const char *fname, int angle_brackets, |
1150 | enum include_type type, location_t loc) |
1151 | { |
1152 | /* For -include command-line flags we have type == IT_CMDLINE. |
1153 | When the first -include file is processed we have the case, where |
1154 | pfile->cur_token == pfile->cur_run->base, we are directly called up |
1155 | by the front end. However in the case of the second -include file, |
1156 | we are called from _cpp_lex_token -> _cpp_get_fresh_line -> |
1157 | cpp_push_include, with pfile->cur_token != pfile->cur_run->base, |
1158 | and pfile->cur_token[-1].src_loc not (yet) initialized. |
1159 | However, when the include file cannot be found, we need src_loc to |
1160 | be initialized to some safe value: 0 means UNKNOWN_LOCATION. */ |
1161 | if (type == IT_CMDLINE && pfile->cur_token != pfile->cur_run->base) |
1162 | pfile->cur_token[-1].src_loc = 0; |
1163 | |
1164 | cpp_dir *dir = search_path_head (pfile, fname, angle_brackets, type); |
1165 | if (!dir) |
1166 | return false; |
1167 | |
1168 | _cpp_file *file = _cpp_find_file (pfile, fname, start_dir: dir, angle_brackets, |
1169 | kind: type == IT_DEFAULT ? _cpp_FFK_PRE_INCLUDE |
1170 | : _cpp_FFK_NORMAL, loc); |
1171 | if (type == IT_DEFAULT && file == NULL) |
1172 | return false; |
1173 | |
1174 | return _cpp_stack_file (pfile, file, type, loc); |
1175 | } |
1176 | |
1177 | /* NAME is a header file name, find the _cpp_file, if any. */ |
1178 | |
1179 | static _cpp_file * |
1180 | (cpp_reader *pfile, const char *name, bool angle, |
1181 | location_t loc) |
1182 | { |
1183 | if (cpp_dir *dir = search_path_head (pfile, fname: name, angle_brackets: angle, type: IT_INCLUDE)) |
1184 | return _cpp_find_file (pfile, fname: name, start_dir: dir, angle_brackets: angle, kind: _cpp_FFK_NORMAL, loc); |
1185 | |
1186 | return nullptr; |
1187 | } |
1188 | |
1189 | /* NAME is a header file name, find the path we'll use to open it and infer that |
1190 | it is a header-unit. */ |
1191 | |
1192 | const char * |
1193 | (cpp_reader *pfile, const char *name, bool angle, |
1194 | location_t loc) |
1195 | { |
1196 | if (_cpp_file *file = test_header_unit (pfile, name, angle, loc)) |
1197 | { |
1198 | if (file->fd > 0) |
1199 | { |
1200 | /* Don't leave it open. */ |
1201 | close (fd: file->fd); |
1202 | file->fd = 0; |
1203 | } |
1204 | |
1205 | file->header_unit = +1; |
1206 | _cpp_mark_file_once_only (pfile, file); |
1207 | |
1208 | return file->path; |
1209 | } |
1210 | |
1211 | return nullptr; |
1212 | } |
1213 | |
1214 | /* NAME is a header file name, find the path we'll use to open it. But do not |
1215 | infer it is a header unit. */ |
1216 | |
1217 | const char * |
1218 | (cpp_reader *pfile, const char *name, bool angle, |
1219 | location_t loc) |
1220 | { |
1221 | if (_cpp_file *file = test_header_unit (pfile, name, angle, loc)) |
1222 | return file->path; |
1223 | |
1224 | return nullptr; |
1225 | } |
1226 | |
1227 | /* Helper function for _cpp_stack_embed. Finish #embed/__has_embed processing |
1228 | after a file is found and data loaded into buffer. */ |
1229 | |
1230 | static int |
1231 | finish_embed (cpp_reader *pfile, _cpp_file *file, |
1232 | struct cpp_embed_params *params) |
1233 | { |
1234 | const uchar *buffer = file->buffer; |
1235 | size_t limit = file->limit; |
1236 | if (params->offset - file->offset > limit) |
1237 | limit = 0; |
1238 | else |
1239 | { |
1240 | buffer += params->offset - file->offset; |
1241 | limit -= params->offset - file->offset; |
1242 | } |
1243 | if (params->limit < limit) |
1244 | limit = params->limit; |
1245 | |
1246 | size_t embed_tokens = 0; |
1247 | if (CPP_OPTION (pfile, lang) != CLK_ASM |
1248 | && limit >= 64) |
1249 | embed_tokens = ((limit - 2) / INT_MAX) + (((limit - 2) % INT_MAX) != 0); |
1250 | |
1251 | size_t max = INTTYPE_MAXIMUM (size_t) / sizeof (cpp_token); |
1252 | if ((embed_tokens ? (embed_tokens > (max - 3) / 2) : (limit > max / 2)) |
1253 | || (limit |
1254 | ? (params->prefix.count > max |
1255 | || params->suffix.count > max |
1256 | || ((embed_tokens ? embed_tokens * 2 + 3 : limit * 2 - 1) |
1257 | + params->prefix.count |
1258 | + params->suffix.count > max)) |
1259 | : params->if_empty.count > max)) |
1260 | { |
1261 | cpp_error_at (pfile, CPP_DL_ERROR, src_loc: params->loc, |
1262 | msgid: "%s is too large" , file->path); |
1263 | return 0; |
1264 | } |
1265 | |
1266 | size_t len = 0; |
1267 | for (size_t i = 0; i < limit; ++i) |
1268 | { |
1269 | if (buffer[i] < 10) |
1270 | len += 2; |
1271 | else if (buffer[i] < 100) |
1272 | len += 3; |
1273 | #if UCHAR_MAX == 255 |
1274 | else |
1275 | len += 4; |
1276 | #else |
1277 | else if (buffer[i] < 1000) |
1278 | len += 4; |
1279 | else |
1280 | { |
1281 | char buf[64]; |
1282 | len += sprintf (buf, "%d" , buffer[i]) + 1; |
1283 | } |
1284 | #endif |
1285 | if (len > INTTYPE_MAXIMUM (ssize_t)) |
1286 | { |
1287 | cpp_error_at (pfile, CPP_DL_ERROR, src_loc: params->loc, |
1288 | msgid: "%s is too large" , file->path); |
1289 | return 0; |
1290 | } |
1291 | if (embed_tokens && i == 0) |
1292 | i = limit - 2; |
1293 | } |
1294 | uchar *s = len ? _cpp_unaligned_alloc (pfile, len) : NULL; |
1295 | _cpp_buff *tok_buff = NULL; |
1296 | cpp_token *tok = &pfile->directive_result, *toks = tok; |
1297 | size_t count = 0; |
1298 | if (limit) |
1299 | count = (params->prefix.count |
1300 | + (embed_tokens ? embed_tokens * 2 + 3 : limit * 2 - 1) |
1301 | + params->suffix.count) - 1; |
1302 | else if (params->if_empty.count) |
1303 | count = params->if_empty.count - 1; |
1304 | if (count) |
1305 | { |
1306 | tok_buff = _cpp_get_buff (pfile, count * sizeof (cpp_token)); |
1307 | toks = (cpp_token *) tok_buff->base; |
1308 | } |
1309 | cpp_embed_params_tokens *prefix |
1310 | = limit ? ¶ms->prefix : ¶ms->if_empty; |
1311 | if (prefix->count) |
1312 | { |
1313 | *tok = *prefix->base_run.base; |
1314 | tok = toks; |
1315 | tokenrun *cur_run = &prefix->base_run; |
1316 | while (cur_run) |
1317 | { |
1318 | size_t cnt = (cur_run->next ? cur_run->limit |
1319 | : prefix->cur_token) - cur_run->base; |
1320 | cpp_token *t = cur_run->base; |
1321 | if (cur_run == &prefix->base_run) |
1322 | { |
1323 | t++; |
1324 | cnt--; |
1325 | } |
1326 | memcpy (dest: tok, src: t, n: cnt * sizeof (cpp_token)); |
1327 | tok += cnt; |
1328 | cur_run = cur_run->next; |
1329 | } |
1330 | } |
1331 | for (size_t i = 0; i < limit; ++i) |
1332 | { |
1333 | tok->src_loc = params->loc; |
1334 | tok->type = CPP_NUMBER; |
1335 | tok->flags = NO_EXPAND; |
1336 | if (i == 0) |
1337 | tok->flags |= PREV_WHITE; |
1338 | tok->val.str.text = s; |
1339 | tok->val.str.len = sprintf (s: (char *) s, format: "%d" , buffer[i]); |
1340 | s += tok->val.str.len + 1; |
1341 | if (tok == &pfile->directive_result) |
1342 | tok = toks; |
1343 | else |
1344 | tok++; |
1345 | if (i < limit - 1) |
1346 | { |
1347 | tok->src_loc = params->loc; |
1348 | tok->type = CPP_COMMA; |
1349 | tok->flags = NO_EXPAND; |
1350 | tok++; |
1351 | } |
1352 | if (i == 0 && embed_tokens) |
1353 | { |
1354 | ++i; |
1355 | for (size_t j = 0; j < embed_tokens; ++j) |
1356 | { |
1357 | tok->src_loc = params->loc; |
1358 | tok->type = CPP_EMBED; |
1359 | tok->flags = NO_EXPAND; |
1360 | tok->val.str.text = &buffer[i]; |
1361 | tok->val.str.len |
1362 | = limit - 1 - i > INT_MAX ? INT_MAX : limit - 1 - i; |
1363 | i += tok->val.str.len; |
1364 | if (tok->val.str.len < 32 && j) |
1365 | { |
1366 | /* Avoid CPP_EMBED with a fewer than 32 bytes, shrink the |
1367 | previous CPP_EMBED by 64 and grow this one by 64. */ |
1368 | tok[-2].val.str.len -= 64; |
1369 | tok->val.str.text -= 64; |
1370 | tok->val.str.len += 64; |
1371 | } |
1372 | tok++; |
1373 | tok->src_loc = params->loc; |
1374 | tok->type = CPP_COMMA; |
1375 | tok->flags = NO_EXPAND; |
1376 | tok++; |
1377 | } |
1378 | --i; |
1379 | } |
1380 | } |
1381 | if (limit && params->suffix.count) |
1382 | { |
1383 | tokenrun *cur_run = ¶ms->suffix.base_run; |
1384 | cpp_token *orig_tok = tok; |
1385 | while (cur_run) |
1386 | { |
1387 | size_t cnt = (cur_run->next ? cur_run->limit |
1388 | : params->suffix.cur_token) - cur_run->base; |
1389 | cpp_token *t = cur_run->base; |
1390 | memcpy (dest: tok, src: t, n: cnt * sizeof (cpp_token)); |
1391 | tok += cnt; |
1392 | cur_run = cur_run->next; |
1393 | } |
1394 | orig_tok->flags |= PREV_WHITE; |
1395 | } |
1396 | pfile->directive_result.flags |= PREV_WHITE; |
1397 | if (count) |
1398 | { |
1399 | _cpp_push_token_context (pfile, NULL, toks, count); |
1400 | pfile->context->buff = tok_buff; |
1401 | } |
1402 | return limit ? 1 : 2; |
1403 | } |
1404 | |
1405 | /* Helper function for initialization of base64_dec table. |
1406 | Can't rely on ASCII compatibility, so check each letter |
1407 | separately. */ |
1408 | |
1409 | constexpr signed char |
1410 | base64_dec_fn (unsigned char c) |
1411 | { |
1412 | return (c == 'A' ? 0 : c == 'B' ? 1 : c == 'C' ? 2 : c == 'D' ? 3 |
1413 | : c == 'E' ? 4 : c == 'F' ? 5 : c == 'G' ? 6 : c == 'H' ? 7 |
1414 | : c == 'I' ? 8 : c == 'J' ? 9 : c == 'K' ? 10 : c == 'L' ? 11 |
1415 | : c == 'M' ? 12 : c == 'N' ? 13 : c == 'O' ? 14 : c == 'P' ? 15 |
1416 | : c == 'Q' ? 16 : c == 'R' ? 17 : c == 'S' ? 18 : c == 'T' ? 19 |
1417 | : c == 'U' ? 20 : c == 'V' ? 21 : c == 'W' ? 22 : c == 'X' ? 23 |
1418 | : c == 'Y' ? 24 : c == 'Z' ? 25 |
1419 | : c == 'a' ? 26 : c == 'b' ? 27 : c == 'c' ? 28 : c == 'd' ? 29 |
1420 | : c == 'e' ? 30 : c == 'f' ? 31 : c == 'g' ? 32 : c == 'h' ? 33 |
1421 | : c == 'i' ? 34 : c == 'j' ? 35 : c == 'k' ? 36 : c == 'l' ? 37 |
1422 | : c == 'm' ? 38 : c == 'n' ? 39 : c == 'o' ? 40 : c == 'p' ? 41 |
1423 | : c == 'q' ? 42 : c == 'r' ? 43 : c == 's' ? 44 : c == 't' ? 45 |
1424 | : c == 'u' ? 46 : c == 'v' ? 47 : c == 'w' ? 48 : c == 'x' ? 49 |
1425 | : c == 'y' ? 50 : c == 'z' ? 51 |
1426 | : c == '0' ? 52 : c == '1' ? 53 : c == '2' ? 54 : c == '3' ? 55 |
1427 | : c == '4' ? 56 : c == '5' ? 57 : c == '6' ? 58 : c == '7' ? 59 |
1428 | : c == '8' ? 60 : c == '9' ? 61 : c == '+' ? 62 : c == '/' ? 63 |
1429 | : -1); |
1430 | } |
1431 | |
1432 | /* base64 decoding table. */ |
1433 | |
1434 | static constexpr signed char base64_dec[] = { |
1435 | #define B64D0(x) base64_dec_fn (x) |
1436 | #define B64D1(x) B64D0 (x), B64D0 (x + 1), B64D0 (x + 2), B64D0 (x + 3) |
1437 | #define B64D2(x) B64D1 (x), B64D1 (x + 4), B64D1 (x + 8), B64D1 (x + 12) |
1438 | #define B64D3(x) B64D2 (x), B64D2 (x + 16), B64D2 (x + 32), B64D2 (x + 48) |
1439 | B64D3 (0), B64D3 (64), B64D3 (128), B64D3 (192) |
1440 | }; |
1441 | |
1442 | /* Helper function for _cpp_stack_embed. Handle #embed/__has_embed with |
1443 | gnu::base64 parameter. */ |
1444 | |
1445 | static int |
1446 | finish_base64_embed (cpp_reader *pfile, const char *fname, bool angle, |
1447 | struct cpp_embed_params *params) |
1448 | { |
1449 | size_t len, end, i, j, base64_len = 0, cnt; |
1450 | uchar *buf = NULL, *q, pbuf[4], qbuf[3]; |
1451 | const uchar *base64_str; |
1452 | if (angle || strcmp (s1: fname, s2: "." )) |
1453 | { |
1454 | if (!params->has_embed) |
1455 | cpp_error_at (pfile, CPP_DL_ERROR, src_loc: params->loc, |
1456 | msgid: "%<gnu::base64%> parameter can be only used with " |
1457 | "%<\".\"%>" ); |
1458 | return 0; |
1459 | } |
1460 | tokenrun *cur_run = ¶ms->base64.base_run; |
1461 | cpp_token *tend, *tok; |
1462 | while (cur_run) |
1463 | { |
1464 | tend = cur_run->next ? cur_run->limit : params->base64.cur_token; |
1465 | for (tok = cur_run->base; tok < tend; ++tok) |
1466 | { |
1467 | if (tok->val.str.len < 2 |
1468 | || tok->val.str.text[0] != '"' |
1469 | || tok->val.str.text[tok->val.str.len - 1] != '"') |
1470 | { |
1471 | fail: |
1472 | cpp_error_at (pfile, CPP_DL_ERROR, src_loc: params->loc, |
1473 | msgid: "%<gnu::base64%> argument not valid base64 " |
1474 | "encoded string" ); |
1475 | free (ptr: buf); |
1476 | return 0; |
1477 | } |
1478 | if (tok->val.str.len - 2 > (~(size_t) 0) - base64_len) |
1479 | goto fail; |
1480 | base64_len += tok->val.str.len - 2; |
1481 | } |
1482 | cur_run = cur_run->next; |
1483 | } |
1484 | if ((base64_len & 3) != 0) |
1485 | goto fail; |
1486 | len = base64_len / 4 * 3; |
1487 | end = len; |
1488 | |
1489 | if (params->has_embed) |
1490 | q = qbuf; |
1491 | else |
1492 | { |
1493 | buf = XNEWVEC (uchar, len ? len : 1); |
1494 | q = buf; |
1495 | } |
1496 | cur_run = ¶ms->base64.base_run; |
1497 | tend = cur_run->next ? cur_run->limit : params->base64.cur_token; |
1498 | tok = cur_run->base; |
1499 | base64_str = tok->val.str.text + 1; |
1500 | cnt = tok->val.str.len - 2; |
1501 | ++tok; |
1502 | for (i = 0; i < end; i += 3) |
1503 | { |
1504 | for (j = 0; j < 4; ++j) |
1505 | { |
1506 | while (cnt == 0) |
1507 | { |
1508 | if (tok == tend) |
1509 | { |
1510 | cur_run = cur_run->next; |
1511 | tend = (cur_run->next ? cur_run->limit |
1512 | : params->base64.cur_token); |
1513 | tok = cur_run->base; |
1514 | } |
1515 | base64_str = tok->val.str.text + 1; |
1516 | cnt = tok->val.str.len - 2; |
1517 | ++tok; |
1518 | } |
1519 | pbuf[j] = *base64_str; |
1520 | base64_str++; |
1521 | --cnt; |
1522 | } |
1523 | if (pbuf[3] == '=' && i + 3 >= end) |
1524 | { |
1525 | end = len - 3; |
1526 | --len; |
1527 | if (pbuf[2] == '=') |
1528 | --len; |
1529 | break; |
1530 | } |
1531 | int a = base64_dec[pbuf[0]]; |
1532 | int b = base64_dec[pbuf[1]]; |
1533 | int c = base64_dec[pbuf[2]]; |
1534 | int d = base64_dec[pbuf[3]]; |
1535 | if (a == -1 || b == -1 || c == -1 || d == -1) |
1536 | goto fail; |
1537 | q[0] = (a << 2) | (b >> 4); |
1538 | q[1] = (b << 4) | (c >> 2); |
1539 | q[2] = (c << 6) | d; |
1540 | if (!params->has_embed) |
1541 | q += 3; |
1542 | } |
1543 | if (len != end) |
1544 | { |
1545 | int a = base64_dec[pbuf[0]]; |
1546 | int b = base64_dec[pbuf[1]]; |
1547 | if (a == -1 || b == -1) |
1548 | goto fail; |
1549 | q[0] = (a << 2) | (b >> 4); |
1550 | if (len - end == 2) |
1551 | { |
1552 | int c = base64_dec[pbuf[2]]; |
1553 | if (c == -1) |
1554 | goto fail; |
1555 | q[1] = (b << 4) | (c >> 2); |
1556 | if ((c & 3) != 0) |
1557 | goto fail; |
1558 | } |
1559 | else if ((b & 15) != 0) |
1560 | goto fail; |
1561 | } |
1562 | if (params->has_embed) |
1563 | return len ? 1 : 2; |
1564 | _cpp_file *file = make_cpp_file (NULL, fname: "" ); |
1565 | file->embed = 1; |
1566 | file->next_file = pfile->all_files; |
1567 | pfile->all_files = file; |
1568 | params->limit = -1; |
1569 | params->offset = 0; |
1570 | file->limit = len; |
1571 | file->buffer = buf; |
1572 | file->path = xstrdup ("<base64>" ); |
1573 | return finish_embed (pfile, file, params); |
1574 | } |
1575 | |
1576 | /* Try to load FNAME with #embed/__has_embed parameters PARAMS. |
1577 | If !PARAMS->has_embed, return new token in pfile->directive_result |
1578 | (first token) and rest in a pushed non-macro context. |
1579 | Returns 0 for not found/errors, 1 for non-empty resource and 2 |
1580 | for empty resource. */ |
1581 | |
1582 | int |
1583 | _cpp_stack_embed (cpp_reader *pfile, const char *fname, bool angle, |
1584 | struct cpp_embed_params *params) |
1585 | { |
1586 | if (params->base64.count) |
1587 | return finish_base64_embed (pfile, fname, angle, params); |
1588 | cpp_dir *dir = search_path_head (pfile, fname, angle_brackets: angle, type: IT_EMBED, |
1589 | suppress_diagnostic: params->has_embed); |
1590 | if (!dir) |
1591 | return 0; |
1592 | _cpp_file *file = _cpp_find_file (pfile, fname, start_dir: dir, angle_brackets: angle, |
1593 | kind: params->has_embed |
1594 | ? _cpp_FFK_HAS_EMBED : _cpp_FFK_EMBED, |
1595 | loc: params->loc); |
1596 | if (!file) |
1597 | return 0; |
1598 | if (file->dont_read || file->err_no) |
1599 | return 0; |
1600 | _cpp_file *orig_file = file; |
1601 | if (file->buffer_valid |
1602 | && (!S_ISREG (file->st.st_mode) |
1603 | || file->offset + (cpp_num_part) 0 > params->offset |
1604 | || (file->limit < file->st.st_size - file->offset + (size_t) 0 |
1605 | && (params->offset - file->offset > (cpp_num_part) file->limit |
1606 | || file->limit - (params->offset |
1607 | - file->offset) < params->limit)))) |
1608 | { |
1609 | bool found = false; |
1610 | if (S_ISREG (file->st.st_mode)) |
1611 | { |
1612 | while (file->next_file |
1613 | && file->next_file->embed |
1614 | && file->next_file->buffer_valid |
1615 | && file->next_file->dir == file->dir |
1616 | && strcmp (s1: file->name, s2: file->next_file->name) == 0 |
1617 | && strcmp (s1: file->path, s2: file->next_file->path) == 0) |
1618 | { |
1619 | file = file->next_file; |
1620 | if (file->offset + (cpp_num_part) 0 <= params->offset |
1621 | && (file->limit >= (file->st.st_size - file->offset |
1622 | + (size_t) 0) |
1623 | || (params->offset |
1624 | - file->offset <= (cpp_num_part) file->limit |
1625 | && file->limit - (params->offset |
1626 | - file->offset) >= params->limit))) |
1627 | { |
1628 | found = true; |
1629 | break; |
1630 | } |
1631 | } |
1632 | } |
1633 | if (!found) |
1634 | { |
1635 | _cpp_file *file2 = make_cpp_file (file->dir, fname: file->name); |
1636 | file2->path = xstrdup (file->path); |
1637 | file2->next_file = file->next_file; |
1638 | file2->embed = true; |
1639 | file->next_file = file2; |
1640 | file = file2; |
1641 | } |
1642 | } |
1643 | if (!file->buffer_valid) |
1644 | { |
1645 | if (file->fd == -1 && !open_file (file)) |
1646 | { |
1647 | if (params->has_embed) |
1648 | file->deferred_error = true; |
1649 | else |
1650 | open_file_failed (pfile, file, 0, params->loc); |
1651 | return 0; |
1652 | } |
1653 | if (S_ISBLK (file->st.st_mode)) |
1654 | { |
1655 | if (params->has_embed) |
1656 | { |
1657 | close (fd: file->fd); |
1658 | file->fd = -1; |
1659 | return 0; |
1660 | } |
1661 | cpp_error_at (pfile, CPP_DL_ERROR, src_loc: params->loc, |
1662 | msgid: "%s is a block device" , file->path); |
1663 | fail: |
1664 | close (fd: file->fd); |
1665 | file->fd = -1; |
1666 | file->dont_read = true; |
1667 | return 0; |
1668 | } |
1669 | |
1670 | if (CPP_OPTION (pfile, deps.style) |
1671 | && !params->has_embed |
1672 | && file == orig_file |
1673 | && file->path[0]) |
1674 | deps_add_dep (pfile->deps, file->path); |
1675 | |
1676 | bool regular = S_ISREG (file->st.st_mode) != 0; |
1677 | ssize_t size, total, count; |
1678 | uchar *buf; |
1679 | if (regular) |
1680 | { |
1681 | cpp_num_part limit; |
1682 | if (file->st.st_size + (cpp_num_part) 0 < params->offset) |
1683 | limit = 0; |
1684 | else if (file->st.st_size - params->offset < params->limit) |
1685 | limit = file->st.st_size - params->offset; |
1686 | else |
1687 | limit = params->limit; |
1688 | if (params->has_embed) |
1689 | return limit != 0 ? 1 : 2; |
1690 | if (limit > INTTYPE_MAXIMUM (ssize_t)) |
1691 | { |
1692 | cpp_error_at (pfile, CPP_DL_ERROR, src_loc: params->loc, |
1693 | msgid: "%s is too large" , file->path); |
1694 | goto fail; |
1695 | } |
1696 | if (lseek (fd: file->fd, offset: params->offset, SEEK_CUR) |
1697 | != (off_t) params->offset) |
1698 | { |
1699 | cpp_errno_filename (pfile, CPP_DL_ERROR, filename: file->path, |
1700 | loc: params->loc); |
1701 | goto fail; |
1702 | } |
1703 | file->offset = params->offset; |
1704 | file->limit = limit; |
1705 | size = limit; |
1706 | } |
1707 | else if (params->has_embed) |
1708 | return 2; |
1709 | else if (params->limit > 8 * 1024) |
1710 | size = 8 * 1024; |
1711 | else |
1712 | size = params->limit; |
1713 | buf = XNEWVEC (uchar, size ? size : 1); |
1714 | total = 0; |
1715 | |
1716 | if (!regular && params->offset) |
1717 | { |
1718 | uchar *buf2 = buf; |
1719 | ssize_t size2 = size; |
1720 | cpp_num_part total2 = params->offset; |
1721 | |
1722 | if (params->offset > 8 * 1024 && size < 8 * 1024) |
1723 | { |
1724 | size2 = 32 * 1024; |
1725 | buf2 = XNEWVEC (uchar, size2); |
1726 | } |
1727 | do |
1728 | { |
1729 | if ((cpp_num_part) size2 > total2) |
1730 | size2 = total2; |
1731 | count = read (fd: file->fd, buf: buf2, nbytes: size2); |
1732 | if (count < 0) |
1733 | { |
1734 | cpp_errno_filename (pfile, CPP_DL_ERROR, filename: file->path, |
1735 | loc: params->loc); |
1736 | if (buf2 != buf) |
1737 | free (ptr: buf2); |
1738 | free (ptr: buf); |
1739 | goto fail; |
1740 | } |
1741 | total2 -= count; |
1742 | } |
1743 | while (total2); |
1744 | if (buf2 != buf) |
1745 | free (ptr: buf2); |
1746 | } |
1747 | |
1748 | while ((count = read (fd: file->fd, buf: buf + total, nbytes: size - total)) > 0) |
1749 | { |
1750 | total += count; |
1751 | if (total == size) |
1752 | { |
1753 | if (regular || size + (cpp_num_part) 0 == params->limit) |
1754 | break; |
1755 | size = (size_t) size * 2; |
1756 | if (size < 0) |
1757 | { |
1758 | if (params->limit <= INTTYPE_MAXIMUM (ssize_t)) |
1759 | size = params->limit; |
1760 | else |
1761 | { |
1762 | cpp_error_at (pfile, CPP_DL_ERROR, src_loc: params->loc, |
1763 | msgid: "%s is too large" , file->path); |
1764 | free (ptr: buf); |
1765 | goto fail; |
1766 | } |
1767 | } |
1768 | else if (size + (cpp_num_part) 0 > params->limit) |
1769 | size = params->limit; |
1770 | buf = XRESIZEVEC (uchar, buf, size); |
1771 | } |
1772 | } |
1773 | |
1774 | if (count < 0) |
1775 | { |
1776 | cpp_errno_filename (pfile, CPP_DL_ERROR, filename: file->path, loc: params->loc); |
1777 | free (ptr: buf); |
1778 | goto fail; |
1779 | } |
1780 | |
1781 | if (regular && total != size && STAT_SIZE_RELIABLE (file->st)) |
1782 | { |
1783 | cpp_error_at (pfile, CPP_DL_WARNING, src_loc: params->loc, |
1784 | msgid: "%s is shorter than expected" , file->path); |
1785 | file->limit = total; |
1786 | } |
1787 | else if (!regular) |
1788 | { |
1789 | file->offset = params->offset; |
1790 | file->limit = total; |
1791 | } |
1792 | |
1793 | file->buffer_start = buf; |
1794 | file->buffer = buf; |
1795 | file->buffer_valid = 1; |
1796 | close (fd: file->fd); |
1797 | file->fd = -1; |
1798 | } |
1799 | else if (params->has_embed) |
1800 | { |
1801 | if (params->offset - file->offset > file->limit) |
1802 | return 2; |
1803 | size_t limit = file->limit - (params->offset - file->offset); |
1804 | return limit && params->limit ? 1 : 2; |
1805 | } |
1806 | |
1807 | return finish_embed (pfile, file, params); |
1808 | } |
1809 | |
1810 | /* Retrofit the just-entered main file asif it was an include. This |
1811 | will permit correct include_next use, and mark it as a system |
1812 | header if that's where it resides. We use filesystem-appropriate |
1813 | prefix matching of the include path to locate the main file. */ |
1814 | void |
1815 | cpp_retrofit_as_include (cpp_reader *pfile) |
1816 | { |
1817 | /* We should be the outermost. */ |
1818 | gcc_assert (!pfile->buffer->prev); |
1819 | |
1820 | if (const char *name = pfile->main_file->name) |
1821 | { |
1822 | /* Locate name on the include dir path, using a prefix match. */ |
1823 | size_t name_len = strlen (s: name); |
1824 | for (cpp_dir *dir = pfile->quote_include; dir; dir = dir->next) |
1825 | if (dir->len < name_len |
1826 | && IS_DIR_SEPARATOR (name[dir->len]) |
1827 | && !filename_ncmp (s1: name, s2: dir->name, n: dir->len)) |
1828 | { |
1829 | pfile->main_file->dir = dir; |
1830 | if (dir->sysp) |
1831 | cpp_make_system_header (pfile, 1, 0); |
1832 | break; |
1833 | } |
1834 | } |
1835 | |
1836 | /* Initialize controlling macro state. */ |
1837 | pfile->mi_valid = true; |
1838 | pfile->mi_cmacro = 0; |
1839 | } |
1840 | |
1841 | /* Could not open FILE. The complication is dependency output. */ |
1842 | static void |
1843 | open_file_failed (cpp_reader *pfile, _cpp_file *file, int angle_brackets, |
1844 | location_t loc) |
1845 | { |
1846 | int sysp = pfile->line_table->highest_line > 1 && pfile->buffer ? pfile->buffer->sysp : 0; |
1847 | bool print_dep = CPP_OPTION (pfile, deps.style) > (angle_brackets || !!sysp); |
1848 | |
1849 | errno = file->err_no; |
1850 | if (print_dep && CPP_OPTION (pfile, deps.missing_files) && errno == ENOENT) |
1851 | { |
1852 | deps_add_dep (pfile->deps, file->name); |
1853 | /* If the preprocessor output (other than dependency information) is |
1854 | being used, we must also flag an error. */ |
1855 | if (CPP_OPTION (pfile, deps.need_preprocessor_output)) |
1856 | cpp_errno_filename (pfile, CPP_DL_FATAL, |
1857 | filename: file->path ? file->path : file->name, |
1858 | loc); |
1859 | } |
1860 | else |
1861 | { |
1862 | /* If we are not outputting dependencies, or if we are and dependencies |
1863 | were requested for this file, or if preprocessor output is needed |
1864 | in addition to dependency information, this is an error. |
1865 | |
1866 | Otherwise (outputting dependencies but not for this file, and not |
1867 | using the preprocessor output), we can still produce correct output |
1868 | so it's only a warning. */ |
1869 | if (CPP_OPTION (pfile, deps.style) == DEPS_NONE |
1870 | || print_dep |
1871 | || CPP_OPTION (pfile, deps.need_preprocessor_output)) |
1872 | cpp_errno_filename (pfile, CPP_DL_FATAL, |
1873 | filename: file->path ? file->path : file->name, |
1874 | loc); |
1875 | else |
1876 | cpp_errno_filename (pfile, CPP_DL_WARNING, |
1877 | filename: file->path ? file->path : file->name, |
1878 | loc); |
1879 | } |
1880 | } |
1881 | |
1882 | /* Search in the chain beginning at HEAD for a file whose search path |
1883 | started at START_DIR != NULL. */ |
1884 | static struct cpp_file_hash_entry * |
1885 | search_cache (struct cpp_file_hash_entry *head, const cpp_dir *start_dir, |
1886 | bool is_embed) |
1887 | { |
1888 | while (head && (head->start_dir != start_dir |
1889 | || head->u.file->embed != is_embed)) |
1890 | head = head->next; |
1891 | |
1892 | return head; |
1893 | } |
1894 | |
1895 | /* Allocate a new _cpp_file structure. */ |
1896 | static _cpp_file * |
1897 | make_cpp_file (cpp_dir *dir, const char *fname) |
1898 | { |
1899 | _cpp_file *file = XCNEW (_cpp_file); |
1900 | file->fd = -1; |
1901 | file->dir = dir; |
1902 | file->name = xstrdup (fname); |
1903 | |
1904 | return file; |
1905 | } |
1906 | |
1907 | /* Release a _cpp_file structure. */ |
1908 | static void |
1909 | destroy_cpp_file (_cpp_file *file) |
1910 | { |
1911 | free (ptr: (void *) file->buffer_start); |
1912 | free (ptr: (void *) file->name); |
1913 | free (ptr: (void *) file->path); |
1914 | free (ptr: file); |
1915 | } |
1916 | |
1917 | /* Release all the files allocated by this reader. */ |
1918 | static void |
1919 | destroy_all_cpp_files (cpp_reader *pfile) |
1920 | { |
1921 | _cpp_file *iter = pfile->all_files; |
1922 | while (iter) |
1923 | { |
1924 | _cpp_file *next = iter->next_file; |
1925 | destroy_cpp_file (file: iter); |
1926 | iter = next; |
1927 | } |
1928 | } |
1929 | |
1930 | /* A hash of directory names. The directory names are the path names |
1931 | of files which contain a #include "", the included file name is |
1932 | appended to this directories. |
1933 | |
1934 | To avoid duplicate entries we follow the convention that all |
1935 | non-empty directory names should end in a '/'. DIR_NAME must be |
1936 | stored in permanently allocated memory. */ |
1937 | static cpp_dir * |
1938 | make_cpp_dir (cpp_reader *pfile, const char *dir_name, int sysp) |
1939 | { |
1940 | struct cpp_file_hash_entry *entry, **hash_slot; |
1941 | cpp_dir *dir; |
1942 | |
1943 | hash_slot = (struct cpp_file_hash_entry **) |
1944 | htab_find_slot_with_hash (pfile->dir_hash, dir_name, |
1945 | htab_hash_string (dir_name), |
1946 | INSERT); |
1947 | |
1948 | /* Have we already hashed this directory? */ |
1949 | for (entry = *hash_slot; entry; entry = entry->next) |
1950 | if (entry->start_dir == NULL) |
1951 | return entry->u.dir; |
1952 | |
1953 | dir = XCNEW (cpp_dir); |
1954 | dir->next = pfile->quote_include; |
1955 | dir->name = (char *) dir_name; |
1956 | dir->len = strlen (s: dir_name); |
1957 | dir->sysp = sysp; |
1958 | dir->construct = 0; |
1959 | |
1960 | /* Store this new result in the hash table. */ |
1961 | entry = new_file_hash_entry (pfile); |
1962 | entry->next = *hash_slot; |
1963 | entry->start_dir = NULL; |
1964 | entry->location = pfile->line_table->highest_location; |
1965 | entry->u.dir = dir; |
1966 | *hash_slot = entry; |
1967 | |
1968 | return dir; |
1969 | } |
1970 | |
1971 | /* Create a new block of memory for file hash entries. */ |
1972 | static void |
1973 | allocate_file_hash_entries (cpp_reader *pfile) |
1974 | { |
1975 | struct file_hash_entry_pool *pool = XNEW (struct file_hash_entry_pool); |
1976 | pool->file_hash_entries_used = 0; |
1977 | pool->next = pfile->file_hash_entries; |
1978 | pfile->file_hash_entries = pool; |
1979 | } |
1980 | |
1981 | /* Return a new file hash entry. */ |
1982 | static struct cpp_file_hash_entry * |
1983 | new_file_hash_entry (cpp_reader *pfile) |
1984 | { |
1985 | unsigned int idx; |
1986 | if (pfile->file_hash_entries->file_hash_entries_used == FILE_HASH_POOL_SIZE) |
1987 | allocate_file_hash_entries (pfile); |
1988 | |
1989 | idx = pfile->file_hash_entries->file_hash_entries_used++; |
1990 | return &pfile->file_hash_entries->pool[idx]; |
1991 | } |
1992 | |
1993 | /* Free the file hash entry pools. */ |
1994 | static void |
1995 | free_file_hash_entries (cpp_reader *pfile) |
1996 | { |
1997 | struct file_hash_entry_pool *iter = pfile->file_hash_entries; |
1998 | while (iter) |
1999 | { |
2000 | struct file_hash_entry_pool *next = iter->next; |
2001 | free (ptr: iter); |
2002 | iter = next; |
2003 | } |
2004 | } |
2005 | |
2006 | /* Returns TRUE if a file FNAME has ever been successfully opened. |
2007 | This routine is not intended to correctly handle filenames aliased |
2008 | by links or redundant . or .. traversals etc. */ |
2009 | bool |
2010 | cpp_included (cpp_reader *pfile, const char *fname) |
2011 | { |
2012 | struct cpp_file_hash_entry *entry; |
2013 | |
2014 | entry = (struct cpp_file_hash_entry *) |
2015 | htab_find_with_hash (pfile->file_hash, fname, htab_hash_string (fname)); |
2016 | |
2017 | while (entry && (entry->start_dir == NULL || entry->u.file->err_no)) |
2018 | entry = entry->next; |
2019 | |
2020 | return entry != NULL; |
2021 | } |
2022 | |
2023 | /* Returns TRUE if a file FNAME has ever been successfully opened |
2024 | before LOCATION. This routine is not intended to correctly handle |
2025 | filenames aliased by links or redundant . or .. traversals etc. */ |
2026 | bool |
2027 | cpp_included_before (cpp_reader *pfile, const char *fname, |
2028 | location_t location) |
2029 | { |
2030 | struct cpp_file_hash_entry *entry |
2031 | = (struct cpp_file_hash_entry *) |
2032 | htab_find_with_hash (pfile->file_hash, fname, htab_hash_string (fname)); |
2033 | |
2034 | if (IS_ADHOC_LOC (loc: location)) |
2035 | location = get_location_from_adhoc_loc (pfile->line_table, location); |
2036 | |
2037 | while (entry && (entry->start_dir == NULL || entry->u.file->err_no |
2038 | || entry->location > location)) |
2039 | entry = entry->next; |
2040 | |
2041 | return entry != NULL; |
2042 | } |
2043 | |
2044 | /* Calculate the hash value of a file hash entry P. */ |
2045 | |
2046 | static hashval_t |
2047 | file_hash_hash (const void *p) |
2048 | { |
2049 | struct cpp_file_hash_entry *entry = (struct cpp_file_hash_entry *) p; |
2050 | const char *hname; |
2051 | if (entry->start_dir) |
2052 | hname = entry->u.file->name; |
2053 | else |
2054 | hname = entry->u.dir->name; |
2055 | |
2056 | return htab_hash_string (hname); |
2057 | } |
2058 | |
2059 | /* Compare a string Q against a file hash entry P. */ |
2060 | static int |
2061 | file_hash_eq (const void *p, const void *q) |
2062 | { |
2063 | struct cpp_file_hash_entry *entry = (struct cpp_file_hash_entry *) p; |
2064 | const char *fname = (const char *) q; |
2065 | const char *hname; |
2066 | |
2067 | if (entry->start_dir) |
2068 | hname = entry->u.file->name; |
2069 | else |
2070 | hname = entry->u.dir->name; |
2071 | |
2072 | return filename_cmp (s1: hname, s2: fname) == 0; |
2073 | } |
2074 | |
2075 | /* Compare entries in the nonexistent file hash table. These are just |
2076 | strings. */ |
2077 | static int |
2078 | nonexistent_file_hash_eq (const void *p, const void *q) |
2079 | { |
2080 | return filename_cmp (s1: (const char *) p, s2: (const char *) q) == 0; |
2081 | } |
2082 | |
2083 | /* Initialize everything in this source file. */ |
2084 | void |
2085 | _cpp_init_files (cpp_reader *pfile) |
2086 | { |
2087 | pfile->file_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq, |
2088 | NULL, xcalloc, free); |
2089 | pfile->dir_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq, |
2090 | NULL, xcalloc, free); |
2091 | allocate_file_hash_entries (pfile); |
2092 | pfile->nonexistent_file_hash = htab_create_alloc (127, htab_hash_string, |
2093 | nonexistent_file_hash_eq, |
2094 | NULL, xcalloc, free); |
2095 | obstack_specify_allocation (&pfile->nonexistent_file_ob, 0, 0, |
2096 | xmalloc, free); |
2097 | } |
2098 | |
2099 | /* Finalize everything in this source file. */ |
2100 | void |
2101 | _cpp_cleanup_files (cpp_reader *pfile) |
2102 | { |
2103 | htab_delete (pfile->file_hash); |
2104 | htab_delete (pfile->dir_hash); |
2105 | htab_delete (pfile->nonexistent_file_hash); |
2106 | obstack_free (&pfile->nonexistent_file_ob, 0); |
2107 | free_file_hash_entries (pfile); |
2108 | destroy_all_cpp_files (pfile); |
2109 | } |
2110 | |
2111 | /* Make the parser forget about files it has seen. This can be useful |
2112 | for resetting the parser to start another run. */ |
2113 | void |
2114 | cpp_clear_file_cache (cpp_reader *pfile) |
2115 | { |
2116 | _cpp_cleanup_files (pfile); |
2117 | pfile->file_hash_entries = NULL; |
2118 | pfile->all_files = NULL; |
2119 | _cpp_init_files (pfile); |
2120 | } |
2121 | |
2122 | /* Enter a file name in the hash for the sake of cpp_included. */ |
2123 | void |
2124 | _cpp_fake_include (cpp_reader *pfile, const char *fname) |
2125 | { |
2126 | /* It does not matter what are the contents of fake_source_dir, it will never |
2127 | be inspected; we just use its address to uniquely signify that this file |
2128 | was added as a fake include, so a later call to _cpp_find_file (to include |
2129 | the file for real) won't find the fake one in the hash table. */ |
2130 | static cpp_dir fake_source_dir; |
2131 | _cpp_find_file (pfile, fname, start_dir: &fake_source_dir, angle_brackets: 0, kind: _cpp_FFK_FAKE, loc: 0); |
2132 | } |
2133 | |
2134 | /* Not everyone who wants to set system-header-ness on a buffer can |
2135 | see the details of a buffer. This is an exported interface because |
2136 | fix-header needs it. */ |
2137 | void |
2138 | (cpp_reader *pfile, int syshdr, int externc) |
2139 | { |
2140 | int flags = 0; |
2141 | const class line_maps *line_table = pfile->line_table; |
2142 | const line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set: line_table); |
2143 | /* 1 = system header, 2 = system header to be treated as C. */ |
2144 | if (syshdr) |
2145 | flags = 1 + (externc != 0); |
2146 | pfile->buffer->sysp = flags; |
2147 | _cpp_do_file_change (pfile, LC_RENAME, ORDINARY_MAP_FILE_NAME (ord_map: map), |
2148 | SOURCE_LINE (ord_map: map, loc: pfile->line_table->highest_line), |
2149 | flags); |
2150 | } |
2151 | |
2152 | /* Allow the client to change the current file. Used by the front end |
2153 | to achieve pseudo-file names like <built-in>. |
2154 | If REASON is LC_LEAVE, then NEW_NAME must be NULL. */ |
2155 | void |
2156 | cpp_change_file (cpp_reader *pfile, enum lc_reason reason, |
2157 | const char *new_name) |
2158 | { |
2159 | _cpp_do_file_change (pfile, reason, new_name, 1, 0); |
2160 | } |
2161 | |
2162 | struct report_missing_guard_data |
2163 | { |
2164 | cpp_reader *pfile; |
2165 | const char **paths; |
2166 | size_t count; |
2167 | }; |
2168 | |
2169 | /* Callback function for htab_traverse. */ |
2170 | static int |
2171 | report_missing_guard (void **slot, void *d) |
2172 | { |
2173 | struct cpp_file_hash_entry *entry = (struct cpp_file_hash_entry *) *slot; |
2174 | struct report_missing_guard_data *data |
2175 | = (struct report_missing_guard_data *) d; |
2176 | |
2177 | /* Skip directories. */ |
2178 | if (entry->start_dir != NULL) |
2179 | { |
2180 | _cpp_file *file = entry->u.file; |
2181 | |
2182 | /* We don't want MI guard advice for the main file. */ |
2183 | if (!file->once_only |
2184 | && file->cmacro == NULL |
2185 | && file->stack_count == 1 |
2186 | && data->pfile->main_file != file) |
2187 | { |
2188 | if (data->paths == NULL) |
2189 | { |
2190 | data->paths = XCNEWVEC (const char *, data->count); |
2191 | data->count = 0; |
2192 | } |
2193 | |
2194 | data->paths[data->count++] = file->path; |
2195 | } |
2196 | } |
2197 | |
2198 | /* Keep traversing the hash table. */ |
2199 | return 1; |
2200 | } |
2201 | |
2202 | /* Comparison function for qsort. */ |
2203 | static int |
2204 | report_missing_guard_cmp (const void *p1, const void *p2) |
2205 | { |
2206 | return strcmp (s1: *(const char *const *) p1, s2: *(const char *const *) p2); |
2207 | } |
2208 | |
2209 | /* Report on all files that might benefit from a multiple include guard. |
2210 | Triggered by -H. */ |
2211 | void |
2212 | _cpp_report_missing_guards (cpp_reader *pfile) |
2213 | { |
2214 | struct report_missing_guard_data data; |
2215 | |
2216 | data.pfile = pfile; |
2217 | data.paths = NULL; |
2218 | data.count = htab_elements (pfile->file_hash); |
2219 | htab_traverse (pfile->file_hash, report_missing_guard, &data); |
2220 | |
2221 | if (data.paths != NULL) |
2222 | { |
2223 | size_t i; |
2224 | |
2225 | /* Sort the paths to avoid outputting them in hash table |
2226 | order. */ |
2227 | qsort (base: data.paths, nmemb: data.count, size: sizeof (const char *), |
2228 | compar: report_missing_guard_cmp); |
2229 | fputs (_("Multiple include guards may be useful for:\n" ), |
2230 | stderr); |
2231 | for (i = 0; i < data.count; i++) |
2232 | { |
2233 | fputs (data.paths[i], stderr); |
2234 | putc ('\n', stderr); |
2235 | } |
2236 | free (ptr: data.paths); |
2237 | } |
2238 | } |
2239 | |
2240 | /* Locate HEADER, and determine whether it is newer than the current |
2241 | file. If it cannot be located or dated, return -1, if it is |
2242 | newer, return 1, otherwise 0. */ |
2243 | int |
2244 | _cpp_compare_file_date (cpp_reader *pfile, const char *fname, |
2245 | int angle_brackets) |
2246 | { |
2247 | _cpp_file *file; |
2248 | struct cpp_dir *dir; |
2249 | |
2250 | dir = search_path_head (pfile, fname, angle_brackets, type: IT_INCLUDE); |
2251 | if (!dir) |
2252 | return -1; |
2253 | |
2254 | file = _cpp_find_file (pfile, fname, start_dir: dir, angle_brackets, kind: _cpp_FFK_NORMAL, loc: 0); |
2255 | if (file->err_no) |
2256 | return -1; |
2257 | |
2258 | if (file->fd != -1) |
2259 | { |
2260 | close (fd: file->fd); |
2261 | file->fd = -1; |
2262 | } |
2263 | |
2264 | return file->st.st_mtime > pfile->buffer->file->st.st_mtime; |
2265 | } |
2266 | |
2267 | /* Pushes the given file onto the buffer stack. Returns nonzero if |
2268 | successful. */ |
2269 | bool |
2270 | cpp_push_include (cpp_reader *pfile, const char *fname) |
2271 | { |
2272 | return _cpp_stack_include (pfile, fname, angle_brackets: false, type: IT_CMDLINE, |
2273 | loc: pfile->line_table->highest_line); |
2274 | } |
2275 | |
2276 | /* Pushes the given file, implicitly included at the start of a |
2277 | compilation, onto the buffer stack but without any errors if the |
2278 | file is not found. Returns nonzero if successful. */ |
2279 | bool |
2280 | cpp_push_default_include (cpp_reader *pfile, const char *fname) |
2281 | { |
2282 | return _cpp_stack_include (pfile, fname, angle_brackets: true, type: IT_DEFAULT, |
2283 | loc: pfile->line_table->highest_line); |
2284 | } |
2285 | |
2286 | /* Do appropriate cleanup when a file INC's buffer is popped off the |
2287 | input stack. */ |
2288 | void |
2289 | _cpp_pop_file_buffer (cpp_reader *pfile, _cpp_file *file, |
2290 | const unsigned char *to_free) |
2291 | { |
2292 | /* Record the inclusion-preventing macro, which could be NULL |
2293 | meaning no controlling macro. */ |
2294 | if (pfile->mi_valid && file->cmacro == NULL) |
2295 | { |
2296 | file->cmacro = pfile->mi_cmacro; |
2297 | if (pfile->mi_cmacro |
2298 | && pfile->mi_def_cmacro |
2299 | && pfile->cb.get_suggestion) |
2300 | { |
2301 | auto mi_cmacro = (const char *) NODE_NAME (pfile->mi_cmacro); |
2302 | auto mi_def_cmacro = (const char *) NODE_NAME (pfile->mi_def_cmacro); |
2303 | const char *names[] = { mi_def_cmacro, NULL }; |
2304 | if (pfile->cb.get_suggestion (pfile, mi_cmacro, names) |
2305 | && cpp_warning_with_line (pfile, CPP_W_HEADER_GUARD, |
2306 | pfile->mi_loc, 0, |
2307 | msgid: "header guard %qs followed by " |
2308 | "%<#define%> of a different macro" , |
2309 | mi_cmacro)) |
2310 | cpp_error_at (pfile, CPP_DL_NOTE, src_loc: pfile->mi_def_loc, |
2311 | msgid: "%qs is defined here; did you mean %qs?" , |
2312 | mi_def_cmacro, mi_cmacro); |
2313 | } |
2314 | } |
2315 | |
2316 | /* Invalidate control macros in the #including file. */ |
2317 | pfile->mi_valid = false; |
2318 | |
2319 | if (to_free) |
2320 | { |
2321 | if (to_free == file->buffer_start) |
2322 | { |
2323 | file->buffer_start = NULL; |
2324 | file->buffer = NULL; |
2325 | file->buffer_valid = false; |
2326 | } |
2327 | free (ptr: (void *) to_free); |
2328 | } |
2329 | } |
2330 | |
2331 | /* Return the file name associated with FILE. */ |
2332 | const char * |
2333 | _cpp_get_file_name (_cpp_file *file) |
2334 | { |
2335 | return file->name; |
2336 | } |
2337 | |
2338 | /* Inteface to file statistics record in _cpp_file structure. */ |
2339 | struct stat * |
2340 | _cpp_get_file_stat (_cpp_file *file) |
2341 | { |
2342 | return &file->st; |
2343 | } |
2344 | |
2345 | /* Return the directory where FILE was found. */ |
2346 | struct cpp_dir * |
2347 | _cpp_get_file_dir (_cpp_file *file) |
2348 | { |
2349 | return file->dir; |
2350 | } |
2351 | |
2352 | /* Set the include chain for "" to QUOTE, for <> to BRACKET. If |
2353 | QUOTE_IGNORES_SOURCE_DIR, then "" includes do not look in the |
2354 | directory of the including file. |
2355 | |
2356 | If BRACKET does not lie in the QUOTE chain, it is set to QUOTE. |
2357 | |
2358 | EMBED is include chain for #embed <>. */ |
2359 | void |
2360 | cpp_set_include_chains (cpp_reader *pfile, cpp_dir *quote, cpp_dir *bracket, |
2361 | cpp_dir *embed, int quote_ignores_source_dir) |
2362 | { |
2363 | pfile->quote_include = quote; |
2364 | pfile->bracket_include = quote; |
2365 | pfile->quote_ignores_source_dir = quote_ignores_source_dir; |
2366 | pfile->embed_include = embed; |
2367 | |
2368 | for (; quote; quote = quote->next) |
2369 | { |
2370 | quote->name_map = NULL; |
2371 | quote->len = strlen (s: quote->name); |
2372 | if (quote == bracket) |
2373 | pfile->bracket_include = bracket; |
2374 | } |
2375 | for (; embed; embed = embed->next) |
2376 | { |
2377 | embed->name_map = NULL; |
2378 | embed->len = strlen (s: embed->name); |
2379 | } |
2380 | } |
2381 | |
2382 | /* Append the file name to the directory to create the path, but don't |
2383 | turn / into // or // into ///; // may be a namespace escape. */ |
2384 | static char * |
2385 | append_file_to_dir (const char *fname, cpp_dir *dir) |
2386 | { |
2387 | size_t dlen, flen; |
2388 | char *path; |
2389 | |
2390 | dlen = dir->len; |
2391 | flen = strlen (s: fname); |
2392 | path = XNEWVEC (char, dlen + 1 + flen + 1); |
2393 | memcpy (dest: path, src: dir->name, n: dlen); |
2394 | if (dlen && !IS_DIR_SEPARATOR (path[dlen - 1])) |
2395 | path[dlen++] = '/'; |
2396 | memcpy (dest: &path[dlen], src: fname, n: flen + 1); |
2397 | |
2398 | return path; |
2399 | } |
2400 | |
2401 | /* Read a space delimited string of unlimited length from a stdio |
2402 | file F. */ |
2403 | static char * |
2404 | read_filename_string (int ch, FILE *f) |
2405 | { |
2406 | char *alloc, *set; |
2407 | int len; |
2408 | |
2409 | len = 20; |
2410 | set = alloc = XNEWVEC (char, len + 1); |
2411 | if (! is_space (ch)) |
2412 | { |
2413 | *set++ = ch; |
2414 | while ((ch = getc (f)) != EOF && ! is_space (ch)) |
2415 | { |
2416 | if (set - alloc == len) |
2417 | { |
2418 | len *= 2; |
2419 | alloc = XRESIZEVEC (char, alloc, len + 1); |
2420 | set = alloc + len / 2; |
2421 | } |
2422 | *set++ = ch; |
2423 | } |
2424 | } |
2425 | *set = '\0'; |
2426 | ungetc (c: ch, stream: f); |
2427 | return alloc; |
2428 | } |
2429 | |
2430 | /* Read the file name map file for DIR. */ |
2431 | static void |
2432 | read_name_map (cpp_dir *dir) |
2433 | { |
2434 | static const char FILE_NAME_MAP_FILE[] = "header.gcc" ; |
2435 | char *name; |
2436 | FILE *f; |
2437 | size_t len, count = 0, room = 9; |
2438 | |
2439 | len = dir->len; |
2440 | name = (char *) alloca (len + sizeof (FILE_NAME_MAP_FILE) + 1); |
2441 | memcpy (dest: name, src: dir->name, n: len); |
2442 | if (len && !IS_DIR_SEPARATOR (name[len - 1])) |
2443 | name[len++] = '/'; |
2444 | strcpy (dest: name + len, src: FILE_NAME_MAP_FILE); |
2445 | f = fopen (name, "r" ); |
2446 | |
2447 | dir->name_map = XNEWVEC (const char *, room); |
2448 | |
2449 | /* Silently return NULL if we cannot open. */ |
2450 | if (f) |
2451 | { |
2452 | int ch; |
2453 | |
2454 | while ((ch = getc (f)) != EOF) |
2455 | { |
2456 | char *to; |
2457 | |
2458 | if (is_space (ch)) |
2459 | continue; |
2460 | |
2461 | if (count + 2 > room) |
2462 | { |
2463 | room += 8; |
2464 | dir->name_map = XRESIZEVEC (const char *, dir->name_map, room); |
2465 | } |
2466 | |
2467 | dir->name_map[count] = read_filename_string (ch, f); |
2468 | while ((ch = getc (f)) != EOF && is_hspace (ch)) |
2469 | ; |
2470 | |
2471 | to = read_filename_string (ch, f); |
2472 | if (IS_ABSOLUTE_PATH (to)) |
2473 | dir->name_map[count + 1] = to; |
2474 | else |
2475 | { |
2476 | dir->name_map[count + 1] = append_file_to_dir (fname: to, dir); |
2477 | free (ptr: to); |
2478 | } |
2479 | |
2480 | count += 2; |
2481 | while ((ch = getc (f)) != '\n') |
2482 | if (ch == EOF) |
2483 | break; |
2484 | } |
2485 | |
2486 | fclose (stream: f); |
2487 | } |
2488 | |
2489 | /* Terminate the list of maps. */ |
2490 | dir->name_map[count] = NULL; |
2491 | } |
2492 | |
2493 | /* Remap a FILE's name based on the file_name_map, if any, for |
2494 | FILE->dir. If the file name has any directory separators, |
2495 | recursively check those directories too. */ |
2496 | static char * |
2497 | remap_filename (cpp_reader *pfile, _cpp_file *file) |
2498 | { |
2499 | const char *fname, *p; |
2500 | char *new_dir, *p3; |
2501 | cpp_dir *dir; |
2502 | size_t index, len; |
2503 | |
2504 | dir = file->dir; |
2505 | fname = file->name; |
2506 | |
2507 | for (;;) |
2508 | { |
2509 | if (!dir->name_map) |
2510 | read_name_map (dir); |
2511 | |
2512 | for (index = 0; dir->name_map[index]; index += 2) |
2513 | if (!filename_cmp (s1: dir->name_map[index], s2: fname)) |
2514 | return xstrdup (dir->name_map[index + 1]); |
2515 | if (IS_ABSOLUTE_PATH (fname)) |
2516 | return NULL; |
2517 | p = strchr (s: fname, c: '/'); |
2518 | #ifdef HAVE_DOS_BASED_FILE_SYSTEM |
2519 | { |
2520 | const char *p2 = strchr (fname, '\\'); |
2521 | if (!p || (p2 && p > p2)) |
2522 | p = p2; |
2523 | } |
2524 | #endif |
2525 | if (!p || p == fname) |
2526 | return NULL; |
2527 | |
2528 | len = dir->len + (p - fname + 1); |
2529 | new_dir = XNEWVEC (char, len + 2); |
2530 | p3 = new_dir + dir->len; |
2531 | memcpy (dest: new_dir, src: dir->name, n: dir->len); |
2532 | if (dir->len && !IS_DIR_SEPARATOR (dir->name[dir->len - 1])) |
2533 | { |
2534 | *p3++ = '/'; |
2535 | len++; |
2536 | } |
2537 | memcpy (dest: p3, src: fname, n: p - fname + 1); |
2538 | new_dir[len] = '\0'; |
2539 | |
2540 | dir = make_cpp_dir (pfile, dir_name: new_dir, sysp: dir->sysp); |
2541 | fname = p + 1; |
2542 | } |
2543 | } |
2544 | |
2545 | /* Returns true if PCHNAME is a valid PCH file for FILE. */ |
2546 | static bool |
2547 | validate_pch (cpp_reader *pfile, _cpp_file *file, const char *pchname) |
2548 | { |
2549 | const char *saved_path = file->path; |
2550 | bool valid = false; |
2551 | |
2552 | file->path = pchname; |
2553 | if (open_file (file)) |
2554 | { |
2555 | valid = 1 & pfile->cb.valid_pch (pfile, pchname, file->fd); |
2556 | |
2557 | if (!valid) |
2558 | { |
2559 | close (fd: file->fd); |
2560 | file->fd = -1; |
2561 | } |
2562 | |
2563 | if (CPP_OPTION (pfile, print_include_names)) |
2564 | { |
2565 | unsigned int i; |
2566 | for (i = 1; i < pfile->line_table->depth; i++) |
2567 | putc ('.', stderr); |
2568 | fprintf (stderr, format: "%c %s\n" , |
2569 | valid ? '!' : 'x', pchname); |
2570 | } |
2571 | } |
2572 | |
2573 | file->path = saved_path; |
2574 | return valid; |
2575 | } |
2576 | |
2577 | /* Get the path associated with the _cpp_file F. The path includes |
2578 | the base name from the include directive and the directory it was |
2579 | found in via the search path. */ |
2580 | |
2581 | const char * |
2582 | cpp_get_path (struct _cpp_file *f) |
2583 | { |
2584 | return f->path; |
2585 | } |
2586 | |
2587 | /* Get the directory associated with the _cpp_file F. */ |
2588 | |
2589 | cpp_dir * |
2590 | cpp_get_dir (struct _cpp_file *f) |
2591 | { |
2592 | return f->dir; |
2593 | } |
2594 | |
2595 | /* Get the cpp_buffer currently associated with the cpp_reader |
2596 | PFILE. */ |
2597 | |
2598 | cpp_buffer * |
2599 | cpp_get_buffer (cpp_reader *pfile) |
2600 | { |
2601 | return pfile->buffer; |
2602 | } |
2603 | |
2604 | /* Get the _cpp_file associated with the cpp_buffer B. */ |
2605 | |
2606 | _cpp_file * |
2607 | cpp_get_file (cpp_buffer *b) |
2608 | { |
2609 | return b->file; |
2610 | } |
2611 | |
2612 | /* Get the previous cpp_buffer given a cpp_buffer B. The previous |
2613 | buffer is the buffer that included the given buffer. */ |
2614 | |
2615 | cpp_buffer * |
2616 | cpp_get_prev (cpp_buffer *b) |
2617 | { |
2618 | return b->prev; |
2619 | } |
2620 | |
2621 | /* This data structure holds the list of header files that were seen |
2622 | while the PCH was being built. The 'entries' field is kept sorted |
2623 | in memcmp() order; yes, this means that on little-endian systems, |
2624 | it's sorted initially by the least-significant byte of 'size', but |
2625 | that's OK. The code does rely on having entries with the same size |
2626 | next to each other. */ |
2627 | |
2628 | struct pchf_entry { |
2629 | /* The size of this file. This is used to save running a MD5 checksum |
2630 | if the sizes don't match. */ |
2631 | off_t size; |
2632 | /* The MD5 checksum of this file. */ |
2633 | unsigned char sum[16]; |
2634 | /* Is this file to be included only once? */ |
2635 | bool once_only; |
2636 | }; |
2637 | |
2638 | struct pchf_data { |
2639 | /* Number of pchf_entry structures. */ |
2640 | size_t count; |
2641 | |
2642 | /* Are there any values with once_only set? |
2643 | This is used as an optimisation, it means we don't have to search |
2644 | the structure if we're processing a regular #include. */ |
2645 | bool have_once_only; |
2646 | |
2647 | struct pchf_entry entries[1]; |
2648 | }; |
2649 | |
2650 | static struct pchf_data *pchf; |
2651 | |
2652 | /* A qsort ordering function for pchf_entry structures. */ |
2653 | |
2654 | static int |
2655 | pchf_save_compare (const void *e1, const void *e2) |
2656 | { |
2657 | return memcmp (s1: e1, s2: e2, n: sizeof (struct pchf_entry)); |
2658 | } |
2659 | |
2660 | /* Create and write to F a pchf_data structure. */ |
2661 | |
2662 | bool |
2663 | _cpp_save_file_entries (cpp_reader *pfile, FILE *fp) |
2664 | { |
2665 | size_t count = 0; |
2666 | struct pchf_data *result; |
2667 | size_t result_size; |
2668 | _cpp_file *f; |
2669 | bool ret; |
2670 | |
2671 | for (f = pfile->all_files; f; f = f->next_file) |
2672 | ++count; |
2673 | |
2674 | result_size = (sizeof (struct pchf_data) |
2675 | + sizeof (struct pchf_entry) * (count - 1)); |
2676 | result = XCNEWVAR (struct pchf_data, result_size); |
2677 | |
2678 | result->count = 0; |
2679 | result->have_once_only = false; |
2680 | |
2681 | for (f = pfile->all_files; f; f = f->next_file) |
2682 | { |
2683 | size_t count; |
2684 | |
2685 | /* This should probably never happen, since if a read error occurred |
2686 | the PCH file shouldn't be written... */ |
2687 | if (f->dont_read || f->err_no) |
2688 | continue; |
2689 | |
2690 | if (f->stack_count == 0) |
2691 | continue; |
2692 | |
2693 | count = result->count++; |
2694 | |
2695 | result->entries[count].once_only = f->once_only; |
2696 | /* |= is avoided in the next line because of an HP C compiler bug */ |
2697 | result->have_once_only = result->have_once_only | f->once_only; |
2698 | if (f->buffer_valid) |
2699 | md5_buffer (buffer: (const char *)f->buffer, |
2700 | len: f->st.st_size, resblock: result->entries[count].sum); |
2701 | else |
2702 | { |
2703 | FILE *ff; |
2704 | int oldfd = f->fd; |
2705 | |
2706 | if (!open_file (file: f)) |
2707 | { |
2708 | open_file_failed (pfile, file: f, angle_brackets: 0, loc: 0); |
2709 | free (ptr: result); |
2710 | return false; |
2711 | } |
2712 | ff = fdopen (f->fd, "rb" ); |
2713 | md5_stream (stream: ff, resblock: result->entries[count].sum); |
2714 | fclose (stream: ff); |
2715 | f->fd = oldfd; |
2716 | } |
2717 | result->entries[count].size = f->st.st_size; |
2718 | } |
2719 | |
2720 | result_size = (sizeof (struct pchf_data) |
2721 | + sizeof (struct pchf_entry) * (result->count - 1)); |
2722 | |
2723 | qsort (base: result->entries, nmemb: result->count, size: sizeof (struct pchf_entry), |
2724 | compar: pchf_save_compare); |
2725 | |
2726 | ret = fwrite (result, result_size, 1, fp) == 1; |
2727 | free (ptr: result); |
2728 | return ret; |
2729 | } |
2730 | |
2731 | /* Read the pchf_data structure from F. */ |
2732 | |
2733 | bool |
2734 | _cpp_read_file_entries (cpp_reader *pfile ATTRIBUTE_UNUSED, FILE *f) |
2735 | { |
2736 | struct pchf_data d; |
2737 | |
2738 | if (fread (&d, sizeof (struct pchf_data) - sizeof (struct pchf_entry), 1, f) |
2739 | != 1) |
2740 | return false; |
2741 | |
2742 | pchf = XNEWVAR (struct pchf_data, sizeof (struct pchf_data) |
2743 | + sizeof (struct pchf_entry) * (d.count - 1)); |
2744 | memcpy (dest: pchf, src: &d, n: sizeof (struct pchf_data) - sizeof (struct pchf_entry)); |
2745 | if (fread (pchf->entries, sizeof (struct pchf_entry), d.count, f) |
2746 | != d.count) |
2747 | return false; |
2748 | return true; |
2749 | } |
2750 | |
2751 | /* The parameters for pchf_compare. */ |
2752 | |
2753 | struct pchf_compare_data |
2754 | { |
2755 | /* The size of the file we're looking for. */ |
2756 | off_t size; |
2757 | |
2758 | /* The MD5 checksum of the file, if it's been computed. */ |
2759 | unsigned char sum[16]; |
2760 | |
2761 | /* Is SUM valid? */ |
2762 | bool sum_computed; |
2763 | |
2764 | /* Do we need to worry about entries that don't have ONCE_ONLY set? */ |
2765 | bool check_included; |
2766 | |
2767 | /* The file that we're searching for. */ |
2768 | _cpp_file *f; |
2769 | }; |
2770 | |
2771 | /* bsearch comparison function; look for D_P in E_P. */ |
2772 | |
2773 | static int |
2774 | pchf_compare (const void *d_p, const void *e_p) |
2775 | { |
2776 | const struct pchf_entry *e = (const struct pchf_entry *)e_p; |
2777 | struct pchf_compare_data *d = (struct pchf_compare_data *)d_p; |
2778 | int result; |
2779 | |
2780 | result = memcmp (s1: &d->size, s2: &e->size, n: sizeof (off_t)); |
2781 | if (result != 0) |
2782 | return result; |
2783 | |
2784 | if (! d->sum_computed) |
2785 | { |
2786 | _cpp_file *const f = d->f; |
2787 | |
2788 | md5_buffer (buffer: (const char *)f->buffer, len: f->st.st_size, resblock: d->sum); |
2789 | d->sum_computed = true; |
2790 | } |
2791 | |
2792 | result = memcmp (s1: d->sum, s2: e->sum, n: 16); |
2793 | if (result != 0) |
2794 | return result; |
2795 | |
2796 | if (d->check_included || e->once_only) |
2797 | return 0; |
2798 | else |
2799 | return 1; |
2800 | } |
2801 | |
2802 | /* Check that F is not in a list read from a PCH file (if any). |
2803 | Assumes that f->buffer_valid is true. Return TRUE if the file |
2804 | should not be read. */ |
2805 | |
2806 | static bool |
2807 | check_file_against_entries (cpp_reader *pfile ATTRIBUTE_UNUSED, |
2808 | _cpp_file *f, |
2809 | bool check_included) |
2810 | { |
2811 | struct pchf_compare_data d; |
2812 | |
2813 | if (pchf == NULL |
2814 | || (! check_included && ! pchf->have_once_only)) |
2815 | return false; |
2816 | |
2817 | d.size = f->st.st_size; |
2818 | d.sum_computed = false; |
2819 | d.f = f; |
2820 | d.check_included = check_included; |
2821 | return bsearch (key: &d, base: pchf->entries, nmemb: pchf->count, size: sizeof (struct pchf_entry), |
2822 | compar: pchf_compare) != NULL; |
2823 | } |
2824 | |
2825 | /* Return true if the file FNAME is found in the appropriate include file path |
2826 | as indicated by ANGLE_BRACKETS. */ |
2827 | |
2828 | bool |
2829 | (cpp_reader *pfile, const char *fname, int angle_brackets, |
2830 | enum include_type type) |
2831 | { |
2832 | cpp_dir *start_dir = search_path_head (pfile, fname, angle_brackets, type, |
2833 | /* suppress_diagnostic = */ true); |
2834 | if (!start_dir) |
2835 | return false; |
2836 | _cpp_file *file = _cpp_find_file (pfile, fname, start_dir, angle_brackets, |
2837 | kind: _cpp_FFK_HAS_INCLUDE, loc: 0); |
2838 | return file->err_no != ENOENT; |
2839 | } |
2840 | |
2841 | /* Read a file and convert to input charset, the same as if it were being read |
2842 | by a cpp_reader. */ |
2843 | |
2844 | cpp_converted_source |
2845 | cpp_get_converted_source (const char *fname, const char *input_charset) |
2846 | { |
2847 | cpp_converted_source res = {}; |
2848 | _cpp_file file = {}; |
2849 | file.fd = -1; |
2850 | file.name = lbasename (fname); |
2851 | file.path = fname; |
2852 | if (!open_file (file: &file)) |
2853 | return res; |
2854 | const bool ok = read_file_guts (NULL, file: &file, loc: 0, input_charset); |
2855 | close (fd: file.fd); |
2856 | if (!ok) |
2857 | return res; |
2858 | res.to_free = (char *) file.buffer_start; |
2859 | res.data = (char *) file.buffer; |
2860 | res.len = file.st.st_size; |
2861 | return res; |
2862 | } |
2863 | |