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