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

source code of libcpp/files.cc