00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "config.h"
00025 #include "system.h"
00026 #include "cpplib.h"
00027 #include "internal.h"
00028 #include "mkdeps.h"
00029 #include "hashtab.h"
00030 #include "md5.h"
00031 #include <dirent.h>
00032
00033
00034
00035 #ifdef VMS
00036 # define FAB_C_VAR 2
00037 # define STAT_SIZE_RELIABLE(ST) ((ST).st_fab_rfm != FAB_C_VAR)
00038 #else
00039 # define STAT_SIZE_RELIABLE(ST) true
00040 #endif
00041
00042 #ifdef __DJGPP__
00043
00044 # define set_stdin_to_binary_mode() \
00045 if (! isatty (0)) setmode (0, O_BINARY)
00046 #else
00047 # define set_stdin_to_binary_mode()
00048 #endif
00049
00050
00051
00052
00053 struct _cpp_file
00054 {
00055
00056 const char *name;
00057
00058
00059 const char *path;
00060
00061
00062 const char *pchname;
00063
00064
00065
00066 const char *dir_name;
00067
00068
00069 struct _cpp_file *next_file;
00070
00071
00072 const uchar *buffer;
00073
00074
00075 const cpp_hashnode *cmacro;
00076
00077
00078
00079
00080 cpp_dir *dir;
00081
00082
00083 struct stat st;
00084
00085
00086 int fd;
00087
00088
00089
00090 int err_no;
00091
00092
00093 unsigned short stack_count;
00094
00095
00096 bool once_only;
00097
00098
00099 bool dont_read;
00100
00101
00102 bool main_file;
00103
00104
00105 bool buffer_valid;
00106
00107
00108 bool pch;
00109 };
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 struct file_hash_entry
00139 {
00140 struct file_hash_entry *next;
00141 cpp_dir *start_dir;
00142 union
00143 {
00144 _cpp_file *file;
00145 cpp_dir *dir;
00146 } u;
00147 };
00148
00149 static bool open_file (_cpp_file *file);
00150 static bool pch_open_file (cpp_reader *pfile, _cpp_file *file,
00151 bool *invalid_pch);
00152 static bool find_file_in_dir (cpp_reader *pfile, _cpp_file *file,
00153 bool *invalid_pch);
00154 static bool read_file_guts (cpp_reader *pfile, _cpp_file *file);
00155 static bool read_file (cpp_reader *pfile, _cpp_file *file);
00156 static bool should_stack_file (cpp_reader *, _cpp_file *file, bool import);
00157 static struct cpp_dir *search_path_head (cpp_reader *, const char *fname,
00158 int angle_brackets, enum include_type);
00159 static const char *dir_name_of_file (_cpp_file *file);
00160 static void open_file_failed (cpp_reader *pfile, _cpp_file *file);
00161 static struct file_hash_entry *search_cache (struct file_hash_entry *head,
00162 const cpp_dir *start_dir);
00163 static _cpp_file *make_cpp_file (cpp_reader *, cpp_dir *, const char *fname);
00164 static void destroy_cpp_file (_cpp_file *);
00165 static cpp_dir *make_cpp_dir (cpp_reader *, const char *dir_name, int sysp);
00166 static void allocate_file_hash_entries (cpp_reader *pfile);
00167 static struct file_hash_entry *new_file_hash_entry (cpp_reader *pfile);
00168 static int report_missing_guard (void **slot, void *b);
00169 static hashval_t file_hash_hash (const void *p);
00170 static int file_hash_eq (const void *p, const void *q);
00171 static char *read_filename_string (int ch, FILE *f);
00172 static void read_name_map (cpp_dir *dir);
00173 static char *remap_filename (cpp_reader *pfile, _cpp_file *file);
00174 static char *append_file_to_dir (const char *fname, cpp_dir *dir);
00175 static bool validate_pch (cpp_reader *, _cpp_file *file, const char *pchname);
00176 static int pchf_save_compare (const void *e1, const void *e2);
00177 static int pchf_compare (const void *d_p, const void *e_p);
00178 static bool check_file_against_entries (cpp_reader *, _cpp_file *, bool);
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 static bool
00200 open_file (_cpp_file *file)
00201 {
00202 if (file->path[0] == '\0')
00203 {
00204 file->fd = 0;
00205 set_stdin_to_binary_mode ();
00206 }
00207 else
00208 file->fd = open (file->path, O_RDONLY | O_NOCTTY | O_BINARY, 0666);
00209
00210 if (file->fd != -1)
00211 {
00212 if (fstat (file->fd, &file->st) == 0)
00213 {
00214 if (!S_ISDIR (file->st.st_mode))
00215 {
00216 file->err_no = 0;
00217 return true;
00218 }
00219
00220
00221
00222 errno = ENOENT;
00223 }
00224
00225 close (file->fd);
00226 file->fd = -1;
00227 }
00228 else if (errno == ENOTDIR)
00229 errno = ENOENT;
00230
00231 file->err_no = errno;
00232
00233 return false;
00234 }
00235
00236
00237
00238
00239
00240
00241 static bool
00242 pch_open_file (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch)
00243 {
00244 static const char extension[] = ".gch";
00245 const char *path = file->path;
00246 size_t len, flen;
00247 char *pchname;
00248 struct stat st;
00249 bool valid = false;
00250
00251
00252 if (file->name[0] == '\0' || !pfile->cb.valid_pch)
00253 return false;
00254
00255 flen = strlen (path);
00256 len = flen + sizeof (extension);
00257 pchname = xmalloc (len);
00258 memcpy (pchname, path, flen);
00259 memcpy (pchname + flen, extension, sizeof (extension));
00260
00261 if (stat (pchname, &st) == 0)
00262 {
00263 DIR *pchdir;
00264 struct dirent *d;
00265 size_t dlen, plen = len;
00266
00267 if (!S_ISDIR (st.st_mode))
00268 valid = validate_pch (pfile, file, pchname);
00269 else if ((pchdir = opendir (pchname)) != NULL)
00270 {
00271 pchname[plen - 1] = '/';
00272 while ((d = readdir (pchdir)) != NULL)
00273 {
00274 dlen = strlen (d->d_name) + 1;
00275 if ((strcmp (d->d_name, ".") == 0)
00276 || (strcmp (d->d_name, "..") == 0))
00277 continue;
00278 if (dlen + plen > len)
00279 {
00280 len += dlen + 64;
00281 pchname = xrealloc (pchname, len);
00282 }
00283 memcpy (pchname + plen, d->d_name, dlen);
00284 valid = validate_pch (pfile, file, pchname);
00285 if (valid)
00286 break;
00287 }
00288 closedir (pchdir);
00289 }
00290 if (valid)
00291 file->pch = true;
00292 else
00293 *invalid_pch = true;
00294 }
00295
00296 if (valid)
00297 file->pchname = pchname;
00298 else
00299 free (pchname);
00300
00301 return valid;
00302 }
00303
00304
00305
00306
00307
00308
00309 static bool
00310 find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch)
00311 {
00312 char *path;
00313
00314 if (CPP_OPTION (pfile, remap) && (path = remap_filename (pfile, file)))
00315 ;
00316 else
00317 if (file->dir->construct)
00318 path = file->dir->construct (file->name, file->dir);
00319 else
00320 path = append_file_to_dir (file->name, file->dir);
00321
00322 if (path)
00323 {
00324 file->path = path;
00325 if (pch_open_file (pfile, file, invalid_pch))
00326 return true;
00327
00328 if (open_file (file))
00329 return true;
00330
00331 if (file->err_no != ENOENT)
00332 {
00333 open_file_failed (pfile, file);
00334 return true;
00335 }
00336
00337 free (path);
00338 file->path = file->name;
00339 }
00340 else
00341 {
00342 file->err_no = ENOENT;
00343 file->path = NULL;
00344 }
00345
00346 return false;
00347 }
00348
00349
00350 static bool
00351 search_path_exhausted (cpp_reader *pfile, const char *header, _cpp_file *file)
00352 {
00353 missing_header_cb func = pfile->cb.missing_header;
00354
00355
00356
00357 if (func
00358 && file->dir == NULL)
00359 {
00360 if ((file->path = func (pfile, header, &file->dir)) != NULL)
00361 {
00362 if (open_file (file))
00363 return true;
00364 free ((void *)file->path);
00365 }
00366 file->path = file->name;
00367 }
00368
00369 return false;
00370 }
00371
00372 bool
00373 _cpp_find_failed (_cpp_file *file)
00374 {
00375 return file->err_no != 0;
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 _cpp_file *
00393 _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool fake)
00394 {
00395 struct file_hash_entry *entry, **hash_slot;
00396 _cpp_file *file;
00397 bool invalid_pch = false;
00398
00399
00400 if (start_dir == NULL)
00401 cpp_error (pfile, CPP_DL_ICE, "NULL directory in find_file");
00402
00403 hash_slot = (struct file_hash_entry **)
00404 htab_find_slot_with_hash (pfile->file_hash, fname,
00405 htab_hash_string (fname),
00406 INSERT);
00407
00408
00409 entry = search_cache (*hash_slot, start_dir);
00410 if (entry)
00411 return entry->u.file;
00412
00413 file = make_cpp_file (pfile, start_dir, fname);
00414
00415
00416 for (; !fake ;)
00417 {
00418 if (find_file_in_dir (pfile, file, &invalid_pch))
00419 break;
00420
00421 file->dir = file->dir->next;
00422 if (file->dir == NULL)
00423 {
00424 if (search_path_exhausted (pfile, fname, file))
00425 {
00426
00427
00428
00429
00430 file->next_file = pfile->all_files;
00431 pfile->all_files = file;
00432 return file;
00433 }
00434
00435 open_file_failed (pfile, file);
00436 if (invalid_pch)
00437 {
00438 cpp_error (pfile, CPP_DL_ERROR,
00439 "one or more PCH files were found, but they were invalid");
00440 if (!cpp_get_options (pfile)->warn_invalid_pch)
00441 cpp_error (pfile, CPP_DL_ERROR,
00442 "use -Winvalid-pch for more information");
00443 }
00444 break;
00445 }
00446
00447
00448
00449
00450 if (file->dir != pfile->bracket_include
00451 && file->dir != pfile->quote_include)
00452 continue;
00453
00454 entry = search_cache (*hash_slot, file->dir);
00455 if (entry)
00456 break;
00457 }
00458
00459 if (entry)
00460 {
00461
00462 free ((char *) file->name);
00463 free (file);
00464 file = entry->u.file;
00465 }
00466 else
00467 {
00468
00469 file->next_file = pfile->all_files;
00470 pfile->all_files = file;
00471 }
00472
00473
00474 entry = new_file_hash_entry (pfile);
00475 entry->next = *hash_slot;
00476 entry->start_dir = start_dir;
00477 entry->u.file = file;
00478 *hash_slot = entry;
00479
00480 return file;
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491 static bool
00492 read_file_guts (cpp_reader *pfile, _cpp_file *file)
00493 {
00494 ssize_t size, total, count;
00495 uchar *buf;
00496 bool regular;
00497
00498 if (S_ISBLK (file->st.st_mode))
00499 {
00500 cpp_error (pfile, CPP_DL_ERROR, "%s is a block device", file->path);
00501 return false;
00502 }
00503
00504 regular = S_ISREG (file->st.st_mode);
00505 if (regular)
00506 {
00507
00508
00509
00510
00511
00512
00513
00514
00515 if (file->st.st_size > INTTYPE_MAXIMUM (ssize_t))
00516 {
00517 cpp_error (pfile, CPP_DL_ERROR, "%s is too large", file->path);
00518 return false;
00519 }
00520
00521 size = file->st.st_size;
00522 }
00523 else
00524
00525
00526
00527 size = 8 * 1024;
00528
00529 buf = xmalloc (size + 1);
00530 total = 0;
00531 while ((count = read (file->fd, buf + total, size - total)) > 0)
00532 {
00533 total += count;
00534
00535 if (total == size)
00536 {
00537 if (regular)
00538 break;
00539 size *= 2;
00540 buf = xrealloc (buf, size + 1);
00541 }
00542 }
00543
00544 if (count < 0)
00545 {
00546 cpp_errno (pfile, CPP_DL_ERROR, file->path);
00547 return false;
00548 }
00549
00550 if (regular && total != size && STAT_SIZE_RELIABLE (file->st))
00551 cpp_error (pfile, CPP_DL_WARNING,
00552 "%s is shorter than expected", file->path);
00553
00554 file->buffer = _cpp_convert_input (pfile, CPP_OPTION (pfile, input_charset),
00555 buf, size, total, &file->st.st_size);
00556 file->buffer_valid = true;
00557
00558 return true;
00559 }
00560
00561
00562
00563
00564 static bool
00565 read_file (cpp_reader *pfile, _cpp_file *file)
00566 {
00567
00568 if (file->buffer_valid)
00569 return true;
00570
00571
00572 if (file->dont_read || file->err_no)
00573 return false;
00574
00575 if (file->fd == -1 && !open_file (file))
00576 {
00577 open_file_failed (pfile, file);
00578 return false;
00579 }
00580
00581 file->dont_read = !read_file_guts (pfile, file);
00582 close (file->fd);
00583 file->fd = -1;
00584
00585 return !file->dont_read;
00586 }
00587
00588
00589
00590 static bool
00591 should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
00592 {
00593 _cpp_file *f;
00594
00595
00596 if (file->once_only)
00597 return false;
00598
00599
00600
00601
00602 if (import)
00603 {
00604 _cpp_mark_file_once_only (pfile, file);
00605
00606
00607 if (file->stack_count)
00608 return false;
00609 }
00610
00611
00612
00613 if (file->cmacro && file->cmacro->type == NT_MACRO)
00614 return false;
00615
00616
00617 if (file->pch)
00618 {
00619 pfile->cb.read_pch (pfile, file->pchname, file->fd, file->path);
00620 close (file->fd);
00621 file->fd = -1;
00622 return false;
00623 }
00624
00625 if (!read_file (pfile, file))
00626 return false;
00627
00628
00629
00630
00631 if (check_file_against_entries (pfile, file, import))
00632 {
00633
00634
00635
00636 if (! import)
00637 _cpp_mark_file_once_only (pfile, file);
00638 return false;
00639 }
00640
00641
00642
00643 if (!pfile->seen_once_only)
00644 return true;
00645
00646
00647
00648 for (f = pfile->all_files; f; f = f->next_file)
00649 {
00650 if (f == file)
00651 continue;
00652
00653 if ((import || f->once_only)
00654 && f->err_no == 0
00655 && f->st.st_mtime == file->st.st_mtime
00656 && f->st.st_size == file->st.st_size)
00657 {
00658 _cpp_file *ref_file;
00659 bool same_file_p = false;
00660
00661 if (f->buffer && !f->buffer_valid)
00662 {
00663
00664
00665 ref_file = make_cpp_file (pfile, f->dir, f->name);
00666 ref_file->path = f->path;
00667 }
00668 else
00669
00670 ref_file = f;
00671
00672 same_file_p = read_file (pfile, ref_file)
00673
00674 && ref_file->st.st_size == file->st.st_size
00675 && !memcmp (ref_file->buffer,
00676 file->buffer,
00677 file->st.st_size);
00678
00679 if (f->buffer && !f->buffer_valid)
00680 {
00681 ref_file->path = 0;
00682 destroy_cpp_file (ref_file);
00683 }
00684
00685 if (same_file_p)
00686 break;
00687 }
00688 }
00689
00690 return f == NULL;
00691 }
00692
00693
00694
00695
00696
00697 bool
00698 _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
00699 {
00700 cpp_buffer *buffer;
00701 int sysp;
00702
00703 if (!should_stack_file (pfile, file, import))
00704 return false;
00705
00706 if (pfile->buffer == NULL || file->dir == NULL)
00707 sysp = 0;
00708 else
00709 sysp = MAX (pfile->buffer->sysp, file->dir->sysp);
00710
00711
00712 if (CPP_OPTION (pfile, deps.style) > !!sysp && !file->stack_count)
00713 {
00714 if (!file->main_file || !CPP_OPTION (pfile, deps.ignore_main_file))
00715 deps_add_dep (pfile->deps, file->path);
00716 }
00717
00718
00719 file->buffer_valid = false;
00720 file->stack_count++;
00721
00722
00723 buffer = cpp_push_buffer (pfile, file->buffer, file->st.st_size,
00724 CPP_OPTION (pfile, preprocessed));
00725 buffer->file = file;
00726 buffer->sysp = sysp;
00727
00728
00729 pfile->mi_valid = true;
00730 pfile->mi_cmacro = 0;
00731
00732
00733 _cpp_do_file_change (pfile, LC_ENTER, file->path, 1, sysp);
00734
00735 return true;
00736 }
00737
00738
00739 void
00740 _cpp_mark_file_once_only (cpp_reader *pfile, _cpp_file *file)
00741 {
00742 pfile->seen_once_only = true;
00743 file->once_only = true;
00744 }
00745
00746
00747
00748
00749 static struct cpp_dir *
00750 search_path_head (cpp_reader *pfile, const char *fname, int angle_brackets,
00751 enum include_type type)
00752 {
00753 cpp_dir *dir;
00754 _cpp_file *file;
00755
00756 if (IS_ABSOLUTE_PATH (fname))
00757 return &pfile->no_search_path;
00758
00759
00760 file = pfile->buffer == NULL ? pfile->main_file : pfile->buffer->file;
00761
00762
00763
00764
00765 if (type == IT_INCLUDE_NEXT && file->dir)
00766 dir = file->dir->next;
00767 else if (angle_brackets)
00768 dir = pfile->bracket_include;
00769 else if (type == IT_CMDLINE)
00770
00771
00772 return make_cpp_dir (pfile, "./", false);
00773 else if (pfile->quote_ignores_source_dir)
00774 dir = pfile->quote_include;
00775 else
00776 return make_cpp_dir (pfile, dir_name_of_file (file),
00777 pfile->buffer ? pfile->buffer->sysp : 0);
00778
00779 if (dir == NULL)
00780 cpp_error (pfile, CPP_DL_ERROR,
00781 "no include path in which to search for %s", fname);
00782
00783 return dir;
00784 }
00785
00786
00787
00788
00789 static const char *
00790 dir_name_of_file (_cpp_file *file)
00791 {
00792 if (!file->dir_name)
00793 {
00794 size_t len = lbasename (file->path) - file->path;
00795 char *dir_name = xmalloc (len + 1);
00796
00797 memcpy (dir_name, file->path, len);
00798 dir_name[len] = '\0';
00799 file->dir_name = dir_name;
00800 }
00801
00802 return file->dir_name;
00803 }
00804
00805
00806
00807
00808 bool
00809 _cpp_stack_include (cpp_reader *pfile, const char *fname, int angle_brackets,
00810 enum include_type type)
00811 {
00812 struct cpp_dir *dir;
00813 _cpp_file *file;
00814
00815 dir = search_path_head (pfile, fname, angle_brackets, type);
00816 if (!dir)
00817 return false;
00818
00819 file = _cpp_find_file (pfile, fname, dir, false);
00820
00821
00822
00823
00824
00825
00826
00827
00828 if (! file->pch && file->err_no == 0 && type != IT_CMDLINE)
00829 pfile->line_table->highest_location--;
00830
00831 return _cpp_stack_file (pfile, file, type == IT_IMPORT);
00832 }
00833
00834
00835 static void
00836 open_file_failed (cpp_reader *pfile, _cpp_file *file)
00837 {
00838 int sysp = pfile->line_table->highest_line > 1 && pfile->buffer ? pfile->buffer->sysp : 0;
00839 bool print_dep = CPP_OPTION (pfile, deps.style) > !!sysp;
00840
00841 errno = file->err_no;
00842 if (print_dep && CPP_OPTION (pfile, deps.missing_files) && errno == ENOENT)
00843 deps_add_dep (pfile->deps, file->name);
00844 else
00845 {
00846
00847
00848 if (CPP_OPTION (pfile, deps.style) && ! print_dep)
00849 cpp_errno (pfile, CPP_DL_WARNING, file->path);
00850 else
00851 cpp_errno (pfile, CPP_DL_ERROR, file->path);
00852 }
00853 }
00854
00855
00856
00857 static struct file_hash_entry *
00858 search_cache (struct file_hash_entry *head, const cpp_dir *start_dir)
00859 {
00860 while (head && head->start_dir != start_dir)
00861 head = head->next;
00862
00863 return head;
00864 }
00865
00866
00867 static _cpp_file *
00868 make_cpp_file (cpp_reader *pfile, cpp_dir *dir, const char *fname)
00869 {
00870 _cpp_file *file;
00871
00872 file = xcalloc (1, sizeof (_cpp_file));
00873 file->main_file = !pfile->buffer;
00874 file->fd = -1;
00875 file->dir = dir;
00876 file->name = xstrdup (fname);
00877
00878 return file;
00879 }
00880
00881
00882 static void
00883 destroy_cpp_file (_cpp_file *file)
00884 {
00885 if (file->buffer)
00886 free ((void *) file->buffer);
00887 free ((void *) file->name);
00888 free (file);
00889 }
00890
00891
00892
00893
00894
00895
00896
00897
00898 static cpp_dir *
00899 make_cpp_dir (cpp_reader *pfile, const char *dir_name, int sysp)
00900 {
00901 struct file_hash_entry *entry, **hash_slot;
00902 cpp_dir *dir;
00903
00904 hash_slot = (struct file_hash_entry **)
00905 htab_find_slot_with_hash (pfile->dir_hash, dir_name,
00906 htab_hash_string (dir_name),
00907 INSERT);
00908
00909
00910 for (entry = *hash_slot; entry; entry = entry->next)
00911 if (entry->start_dir == NULL)
00912 return entry->u.dir;
00913
00914 dir = xcalloc (1, sizeof (cpp_dir));
00915 dir->next = pfile->quote_include;
00916 dir->name = (char *) dir_name;
00917 dir->len = strlen (dir_name);
00918 dir->sysp = sysp;
00919 dir->construct = 0;
00920
00921
00922 entry = new_file_hash_entry (pfile);
00923 entry->next = *hash_slot;
00924 entry->start_dir = NULL;
00925 entry->u.dir = dir;
00926 *hash_slot = entry;
00927
00928 return dir;
00929 }
00930
00931
00932 static void
00933 allocate_file_hash_entries (cpp_reader *pfile)
00934 {
00935 pfile->file_hash_entries_used = 0;
00936 pfile->file_hash_entries_allocated = 127;
00937 pfile->file_hash_entries = xmalloc
00938 (pfile->file_hash_entries_allocated * sizeof (struct file_hash_entry));
00939 }
00940
00941
00942 static struct file_hash_entry *
00943 new_file_hash_entry (cpp_reader *pfile)
00944 {
00945 if (pfile->file_hash_entries_used == pfile->file_hash_entries_allocated)
00946 allocate_file_hash_entries (pfile);
00947
00948 return &pfile->file_hash_entries[pfile->file_hash_entries_used++];
00949 }
00950
00951
00952
00953
00954 bool
00955 cpp_included (cpp_reader *pfile, const char *fname)
00956 {
00957 struct file_hash_entry *entry;
00958
00959 entry = htab_find_with_hash (pfile->file_hash, fname,
00960 htab_hash_string (fname));
00961
00962 while (entry && (entry->start_dir == NULL || entry->u.file->err_no))
00963 entry = entry->next;
00964
00965 return entry != NULL;
00966 }
00967
00968
00969
00970 static hashval_t
00971 file_hash_hash (const void *p)
00972 {
00973 struct file_hash_entry *entry = (struct file_hash_entry *) p;
00974 const char *hname;
00975 if (entry->start_dir)
00976 hname = entry->u.file->name;
00977 else
00978 hname = entry->u.dir->name;
00979
00980 return htab_hash_string (hname);
00981 }
00982
00983
00984 static int
00985 file_hash_eq (const void *p, const void *q)
00986 {
00987 struct file_hash_entry *entry = (struct file_hash_entry *) p;
00988 const char *fname = (const char *) q;
00989 const char *hname;
00990
00991 if (entry->start_dir)
00992 hname = entry->u.file->name;
00993 else
00994 hname = entry->u.dir->name;
00995
00996 return strcmp (hname, fname) == 0;
00997 }
00998
00999
01000 void
01001 _cpp_init_files (cpp_reader *pfile)
01002 {
01003 pfile->file_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq,
01004 NULL, xcalloc, free);
01005 pfile->dir_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq,
01006 NULL, xcalloc, free);
01007 allocate_file_hash_entries (pfile);
01008 }
01009
01010
01011 void
01012 _cpp_cleanup_files (cpp_reader *pfile)
01013 {
01014 htab_delete (pfile->file_hash);
01015 htab_delete (pfile->dir_hash);
01016 }
01017
01018
01019 void
01020 _cpp_fake_include (cpp_reader *pfile, const char *fname)
01021 {
01022 _cpp_find_file (pfile, fname, pfile->buffer->file->dir, true);
01023 }
01024
01025
01026
01027
01028 void
01029 cpp_make_system_header (cpp_reader *pfile, int syshdr, int externc)
01030 {
01031 int flags = 0;
01032 const struct line_maps *line_table = pfile->line_table;
01033 const struct line_map *map = &line_table->maps[line_table->used-1];
01034
01035
01036 if (syshdr)
01037 flags = 1 + (externc != 0);
01038 pfile->buffer->sysp = flags;
01039 _cpp_do_file_change (pfile, LC_RENAME, map->to_file,
01040 SOURCE_LINE (map, pfile->line_table->highest_line), flags);
01041 }
01042
01043
01044
01045
01046 void
01047 cpp_change_file (cpp_reader *pfile, enum lc_reason reason,
01048 const char *new_name)
01049 {
01050 _cpp_do_file_change (pfile, reason, new_name, 1, 0);
01051 }
01052
01053
01054 static int
01055 report_missing_guard (void **slot, void *b)
01056 {
01057 struct file_hash_entry *entry = (struct file_hash_entry *) *slot;
01058 int *bannerp = (int *) b;
01059
01060
01061 if (entry->start_dir != NULL)
01062 {
01063 _cpp_file *file = entry->u.file;
01064
01065
01066 if (file->cmacro == NULL && file->stack_count == 1 && !file->main_file)
01067 {
01068 if (*bannerp == 0)
01069 {
01070 fputs (_("Multiple include guards may be useful for:\n"),
01071 stderr);
01072 *bannerp = 1;
01073 }
01074
01075 fputs (entry->u.file->path, stderr);
01076 putc ('\n', stderr);
01077 }
01078 }
01079
01080 return 0;
01081 }
01082
01083
01084
01085 void
01086 _cpp_report_missing_guards (cpp_reader *pfile)
01087 {
01088 int banner = 0;
01089
01090 htab_traverse (pfile->file_hash, report_missing_guard, &banner);
01091 }
01092
01093
01094
01095
01096 int
01097 _cpp_compare_file_date (cpp_reader *pfile, const char *fname,
01098 int angle_brackets)
01099 {
01100 _cpp_file *file;
01101 struct cpp_dir *dir;
01102
01103 dir = search_path_head (pfile, fname, angle_brackets, IT_INCLUDE);
01104 if (!dir)
01105 return -1;
01106
01107 file = _cpp_find_file (pfile, fname, dir, false);
01108 if (file->err_no)
01109 return -1;
01110
01111 if (file->fd != -1)
01112 {
01113 close (file->fd);
01114 file->fd = -1;
01115 }
01116
01117 return file->st.st_mtime > pfile->buffer->file->st.st_mtime;
01118 }
01119
01120
01121
01122 bool
01123 cpp_push_include (cpp_reader *pfile, const char *fname)
01124 {
01125 return _cpp_stack_include (pfile, fname, false, IT_CMDLINE);
01126 }
01127
01128
01129
01130 void
01131 _cpp_pop_file_buffer (cpp_reader *pfile, _cpp_file *file)
01132 {
01133
01134
01135 if (pfile->mi_valid && file->cmacro == NULL)
01136 file->cmacro = pfile->mi_cmacro;
01137
01138
01139 pfile->mi_valid = false;
01140
01141 if (file->buffer)
01142 {
01143 free ((void *) file->buffer);
01144 file->buffer = NULL;
01145 }
01146 }
01147
01148
01149
01150
01151
01152
01153 void
01154 cpp_set_include_chains (cpp_reader *pfile, cpp_dir *quote, cpp_dir *bracket,
01155 int quote_ignores_source_dir)
01156 {
01157 pfile->quote_include = quote;
01158 pfile->bracket_include = quote;
01159 pfile->quote_ignores_source_dir = quote_ignores_source_dir;
01160
01161 for (; quote; quote = quote->next)
01162 {
01163 quote->name_map = NULL;
01164 quote->len = strlen (quote->name);
01165 if (quote == bracket)
01166 pfile->bracket_include = bracket;
01167 }
01168 }
01169
01170
01171
01172 static char *
01173 append_file_to_dir (const char *fname, cpp_dir *dir)
01174 {
01175 size_t dlen, flen;
01176 char *path;
01177
01178 dlen = dir->len;
01179 flen = strlen (fname);
01180 path = xmalloc (dlen + 1 + flen + 1);
01181 memcpy (path, dir->name, dlen);
01182 if (dlen && path[dlen - 1] != '/')
01183 path[dlen++] = '/';
01184 memcpy (&path[dlen], fname, flen + 1);
01185
01186 return path;
01187 }
01188
01189
01190
01191 static char *
01192 read_filename_string (int ch, FILE *f)
01193 {
01194 char *alloc, *set;
01195 int len;
01196
01197 len = 20;
01198 set = alloc = xmalloc (len + 1);
01199 if (! is_space (ch))
01200 {
01201 *set++ = ch;
01202 while ((ch = getc (f)) != EOF && ! is_space (ch))
01203 {
01204 if (set - alloc == len)
01205 {
01206 len *= 2;
01207 alloc = xrealloc (alloc, len + 1);
01208 set = alloc + len / 2;
01209 }
01210 *set++ = ch;
01211 }
01212 }
01213 *set = '\0';
01214 ungetc (ch, f);
01215 return alloc;
01216 }
01217
01218
01219 static void
01220 read_name_map (cpp_dir *dir)
01221 {
01222 static const char FILE_NAME_MAP_FILE[] = "header.gcc";
01223 char *name;
01224 FILE *f;
01225 size_t len, count = 0, room = 9;
01226
01227 len = dir->len;
01228 name = alloca (len + sizeof (FILE_NAME_MAP_FILE) + 1);
01229 memcpy (name, dir->name, len);
01230 if (len && name[len - 1] != '/')
01231 name[len++] = '/';
01232 strcpy (name + len, FILE_NAME_MAP_FILE);
01233 f = fopen (name, "r");
01234
01235 dir->name_map = xmalloc (room * sizeof (char *));
01236
01237
01238 if (f)
01239 {
01240 int ch;
01241
01242 while ((ch = getc (f)) != EOF)
01243 {
01244 char *to;
01245
01246 if (is_space (ch))
01247 continue;
01248
01249 if (count + 2 > room)
01250 {
01251 room += 8;
01252 dir->name_map = xrealloc (dir->name_map, room * sizeof (char *));
01253 }
01254
01255 dir->name_map[count] = read_filename_string (ch, f);
01256 while ((ch = getc (f)) != EOF && is_hspace (ch))
01257 ;
01258
01259 to = read_filename_string (ch, f);
01260 if (IS_ABSOLUTE_PATH (to))
01261 dir->name_map[count + 1] = to;
01262 else
01263 {
01264 dir->name_map[count + 1] = append_file_to_dir (to, dir);
01265 free (to);
01266 }
01267
01268 count += 2;
01269 while ((ch = getc (f)) != '\n')
01270 if (ch == EOF)
01271 break;
01272 }
01273
01274 fclose (f);
01275 }
01276
01277
01278 dir->name_map[count] = NULL;
01279 }
01280
01281
01282
01283
01284 static char *
01285 remap_filename (cpp_reader *pfile, _cpp_file *file)
01286 {
01287 const char *fname, *p;
01288 char *new_dir;
01289 cpp_dir *dir;
01290 size_t index, len;
01291
01292 dir = file->dir;
01293 fname = file->name;
01294
01295 for (;;)
01296 {
01297 if (!dir->name_map)
01298 read_name_map (dir);
01299
01300 for (index = 0; dir->name_map[index]; index += 2)
01301 if (!strcmp (dir->name_map[index], fname))
01302 return xstrdup (dir->name_map[index + 1]);
01303
01304 p = strchr (fname, '/');
01305 if (!p || p == fname)
01306 return NULL;
01307
01308 len = dir->len + (p - fname + 1);
01309 new_dir = xmalloc (len + 1);
01310 memcpy (new_dir, dir->name, dir->len);
01311 memcpy (new_dir + dir->len, fname, p - fname + 1);
01312 new_dir[len] = '\0';
01313
01314 dir = make_cpp_dir (pfile, new_dir, dir->sysp);
01315 fname = p + 1;
01316 }
01317 }
01318
01319
01320 static bool
01321 validate_pch (cpp_reader *pfile, _cpp_file *file, const char *pchname)
01322 {
01323 const char *saved_path = file->path;
01324 bool valid = false;
01325
01326 file->path = pchname;
01327 if (open_file (file))
01328 {
01329 valid = 1 & pfile->cb.valid_pch (pfile, pchname, file->fd);
01330
01331 if (!valid)
01332 {
01333 close (file->fd);
01334 file->fd = -1;
01335 }
01336
01337 if (CPP_OPTION (pfile, print_include_names))
01338 {
01339 unsigned int i;
01340 for (i = 1; i < pfile->line_table->depth; i++)
01341 putc ('.', stderr);
01342 fprintf (stderr, "%c %s\n",
01343 valid ? '!' : 'x', pchname);
01344 }
01345 }
01346
01347 file->path = saved_path;
01348 return valid;
01349 }
01350
01351
01352
01353
01354
01355 const char *
01356 cpp_get_path (struct _cpp_file *f)
01357 {
01358 return f->path;
01359 }
01360
01361
01362
01363 cpp_dir *
01364 cpp_get_dir (struct _cpp_file *f)
01365 {
01366 return f->dir;
01367 }
01368
01369
01370
01371
01372 cpp_buffer *
01373 cpp_get_buffer (cpp_reader *pfile)
01374 {
01375 return pfile->buffer;
01376 }
01377
01378
01379
01380 _cpp_file *
01381 cpp_get_file (cpp_buffer *b)
01382 {
01383 return b->file;
01384 }
01385
01386
01387
01388
01389 cpp_buffer *
01390 cpp_get_prev (cpp_buffer *b)
01391 {
01392 return b->prev;
01393 }
01394
01395
01396
01397
01398
01399
01400
01401
01402 struct pchf_data {
01403
01404 size_t count;
01405
01406
01407
01408
01409 bool have_once_only;
01410
01411 struct pchf_entry {
01412
01413
01414 off_t size;
01415
01416 unsigned char sum[16];
01417
01418 bool once_only;
01419 } entries[1];
01420 };
01421
01422 static struct pchf_data *pchf;
01423
01424
01425
01426 static int
01427 pchf_save_compare (const void *e1, const void *e2)
01428 {
01429 return memcmp (e1, e2, sizeof (struct pchf_entry));
01430 }
01431
01432
01433
01434 bool
01435 _cpp_save_file_entries (cpp_reader *pfile, FILE *fp)
01436 {
01437 size_t count = 0;
01438 struct pchf_data *result;
01439 size_t result_size;
01440 _cpp_file *f;
01441
01442 for (f = pfile->all_files; f; f = f->next_file)
01443 ++count;
01444
01445 result_size = (sizeof (struct pchf_data)
01446 + sizeof (struct pchf_entry) * (count - 1));
01447 result = xcalloc (result_size, 1);
01448
01449 result->count = 0;
01450 result->have_once_only = false;
01451
01452 for (f = pfile->all_files; f; f = f->next_file)
01453 {
01454 size_t count;
01455
01456
01457
01458 if (f->dont_read || f->err_no)
01459 continue;
01460
01461 if (f->stack_count == 0)
01462 continue;
01463
01464 count = result->count++;
01465
01466 result->entries[count].once_only = f->once_only;
01467
01468 result->have_once_only = result->have_once_only | f->once_only;
01469 if (f->buffer_valid)
01470 md5_buffer ((const char *)f->buffer,
01471 f->st.st_size, result->entries[count].sum);
01472 else
01473 {
01474 FILE *ff;
01475 int oldfd = f->fd;
01476
01477 if (!open_file (f))
01478 {
01479 open_file_failed (pfile, f);
01480 return false;
01481 }
01482 ff = fdopen (f->fd, "rb");
01483 md5_stream (ff, result->entries[count].sum);
01484 fclose (ff);
01485 f->fd = oldfd;
01486 }
01487 result->entries[count].size = f->st.st_size;
01488 }
01489
01490 result_size = (sizeof (struct pchf_data)
01491 + sizeof (struct pchf_entry) * (result->count - 1));
01492
01493 qsort (result->entries, result->count, sizeof (struct pchf_entry),
01494 pchf_save_compare);
01495
01496 return fwrite (result, result_size, 1, fp) == 1;
01497 }
01498
01499
01500
01501 bool
01502 _cpp_read_file_entries (cpp_reader *pfile ATTRIBUTE_UNUSED, FILE *f)
01503 {
01504 struct pchf_data d;
01505
01506 if (fread (&d, sizeof (struct pchf_data) - sizeof (struct pchf_entry), 1, f)
01507 != 1)
01508 return false;
01509
01510 pchf = xmalloc (sizeof (struct pchf_data)
01511 + sizeof (struct pchf_entry) * (d.count - 1));
01512 memcpy (pchf, &d, sizeof (struct pchf_data) - sizeof (struct pchf_entry));
01513 if (fread (pchf->entries, sizeof (struct pchf_entry), d.count, f)
01514 != d.count)
01515 return false;
01516 return true;
01517 }
01518
01519
01520
01521 struct pchf_compare_data
01522 {
01523
01524 off_t size;
01525
01526
01527 unsigned char sum[16];
01528
01529
01530 bool sum_computed;
01531
01532
01533 bool check_included;
01534
01535
01536 _cpp_file *f;
01537 };
01538
01539
01540
01541 static int
01542 pchf_compare (const void *d_p, const void *e_p)
01543 {
01544 const struct pchf_entry *e = (const struct pchf_entry *)e_p;
01545 struct pchf_compare_data *d = (struct pchf_compare_data *)d_p;
01546 int result;
01547
01548 result = memcmp (&d->size, &e->size, sizeof (off_t));
01549 if (result != 0)
01550 return result;
01551
01552 if (! d->sum_computed)
01553 {
01554 _cpp_file *const f = d->f;
01555
01556 md5_buffer ((const char *)f->buffer, f->st.st_size, d->sum);
01557 d->sum_computed = true;
01558 }
01559
01560 result = memcmp (d->sum, e->sum, 16);
01561 if (result != 0)
01562 return result;
01563
01564 if (d->check_included || e->once_only)
01565 return 0;
01566 else
01567 return 1;
01568 }
01569
01570
01571
01572
01573
01574 static bool
01575 check_file_against_entries (cpp_reader *pfile ATTRIBUTE_UNUSED,
01576 _cpp_file *f,
01577 bool check_included)
01578 {
01579 struct pchf_compare_data d;
01580
01581 if (pchf == NULL
01582 || (! check_included && ! pchf->have_once_only))
01583 return false;
01584
01585 d.size = f->st.st_size;
01586 d.sum_computed = false;
01587 d.f = f;
01588 d.check_included = check_included;
01589 return bsearch (&d, pchf->entries, pchf->count, sizeof (struct pchf_entry),
01590 pchf_compare) != NULL;
01591 }