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
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);
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. */
234static bool
235open_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
292static bool
293pch_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
367static char *
368maybe_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
388static bool
389find_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. */
469static bool
470search_path_exhausted (cpp_reader *pfile, const char *header, _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
491bool
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. */
725static bool
726read_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. */
811static bool
812read_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. */
838static bool
839is_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
878static bool
879has_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
953bool
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. */
1078void
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. */
1088struct cpp_dir *
1089search_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. */
1129static const char *
1130dir_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. */
1148bool
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
1179static _cpp_file *
1180test_header_unit (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
1192const char *
1193_cpp_find_header_unit (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
1217const char *
1218cpp_probe_header_unit (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
1230static int
1231finish_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 ? &params->prefix : &params->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 = &params->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
1409constexpr signed char
1410base64_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
1434static 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
1445static int
1446finish_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 = &params->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 = &params->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
1582int
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. */
1814void
1815cpp_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. */
1842static void
1843open_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. */
1884static struct cpp_file_hash_entry *
1885search_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. */
1896static _cpp_file *
1897make_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. */
1908static void
1909destroy_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. */
1918static void
1919destroy_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. */
1937static cpp_dir *
1938make_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. */
1972static void
1973allocate_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. */
1982static struct cpp_file_hash_entry *
1983new_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. */
1994static void
1995free_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. */
2009bool
2010cpp_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. */
2026bool
2027cpp_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
2046static hashval_t
2047file_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. */
2060static int
2061file_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. */
2077static int
2078nonexistent_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. */
2084void
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. */
2100void
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. */
2113void
2114cpp_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. */
2123void
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. */
2137void
2138cpp_make_system_header (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. */
2155void
2156cpp_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
2162struct 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. */
2170static int
2171report_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. */
2203static int
2204report_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. */
2211void
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. */
2243int
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. */
2269bool
2270cpp_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. */
2279bool
2280cpp_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. */
2288void
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. */
2332const 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. */
2339struct stat *
2340_cpp_get_file_stat (_cpp_file *file)
2341{
2342 return &file->st;
2343}
2344
2345/* Return the directory where FILE was found. */
2346struct 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 <>. */
2359void
2360cpp_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. */
2384static char *
2385append_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. */
2403static char *
2404read_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. */
2431static void
2432read_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. */
2496static char *
2497remap_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. */
2546static bool
2547validate_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
2581const char *
2582cpp_get_path (struct _cpp_file *f)
2583{
2584 return f->path;
2585}
2586
2587/* Get the directory associated with the _cpp_file F. */
2588
2589cpp_dir *
2590cpp_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
2598cpp_buffer *
2599cpp_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 *
2607cpp_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
2615cpp_buffer *
2616cpp_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
2628struct 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
2638struct 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
2650static struct pchf_data *pchf;
2651
2652/* A qsort ordering function for pchf_entry structures. */
2653
2654static int
2655pchf_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
2662bool
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
2733bool
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
2753struct 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
2773static int
2774pchf_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
2806static bool
2807check_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
2828bool
2829_cpp_has_header (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
2844cpp_converted_source
2845cpp_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

source code of libcpp/files.cc