]> gcc.gnu.org Git - gcc.git/blob - gcc/cppfiles.c
cpplib.h (struct cpp_buffer): Replace dir and dlen members with a struct file_name_li...
[gcc.git] / gcc / cppfiles.c
1 /* Part of CPP library. (include file handling)
2 Copyright (C) 1986, 87, 89, 92 - 95, 1998 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
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
11 later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22 In other words, you are welcome to use, share and improve this program.
23 You are forbidden to forbid anyone else to use, share and improve
24 what you give them. Help stamp out software-hoarding! */
25
26 #include "config.h"
27 #include "system.h"
28 #include "cpplib.h"
29
30 /* The entry points to this file are: find_include_file, finclude,
31 include_hash, append_include_chain, deps_output, and file_cleanup.
32 file_cleanup is only called through CPP_BUFFER(pfile)->cleanup,
33 so it's static anyway. */
34
35 static struct include_hash *redundant_include_p
36 PROTO ((cpp_reader *,
37 struct include_hash *,
38 struct file_name_list *));
39 static struct file_name_map *read_name_map PROTO ((cpp_reader *, char *));
40 static char *read_filename_string PROTO ((int, FILE *));
41 static char *remap_filename PROTO ((cpp_reader *, char *,
42 struct file_name_list *));
43 static long safe_read PROTO ((int, char *, int));
44 static void simplify_pathname PROTO ((char *));
45 static struct file_name_list *actual_directory PROTO ((cpp_reader *, char *));
46
47 #if 0
48 static void hack_vms_include_specification PROTO ((char *));
49 #endif
50
51 /* Windows does not natively support inodes, and neither does MSDOS.
52 VMS has non-numeric inodes. */
53 #ifdef VMS
54 #define INO_T_EQ(a, b) (!bcmp((char *) &(a), (char *) &(b), sizeof (a)))
55 #elif (defined _WIN32 && !defined CYGWIN) || defined __MSDOS__
56 #define INO_T_EQ(a, b) 0
57 #else
58 #define INO_T_EQ(a, b) ((a) == (b))
59 #endif
60
61 /* Append an entry for dir DIR to list LIST, simplifying it if
62 possible. SYS says whether this is a system include directory.
63 *** DIR is modified in place. It must be writable and permanently
64 allocated. LIST is a pointer to the head pointer, because we actually
65 *prepend* the dir, and reverse the list later (in merge_include_chains). */
66 void
67 append_include_chain (pfile, list, dir, sysp)
68 cpp_reader *pfile;
69 struct file_name_list **list;
70 char *dir;
71 int sysp;
72 {
73 struct file_name_list *new;
74 struct stat st;
75 unsigned int len;
76
77 dir = savestring (dir);
78 simplify_pathname (dir);
79 if (stat (dir, &st))
80 {
81 /* Dirs that don't exist are silently ignored. */
82 if (errno != ENOENT)
83 cpp_perror_with_name (pfile, dir);
84 return;
85 }
86
87 if (!S_ISDIR (st.st_mode))
88 {
89 cpp_message (pfile, 1, "%s: %s: Not a directory", progname, dir);
90 return;
91 }
92
93 len = strlen(dir);
94 if (len > pfile->max_include_len)
95 pfile->max_include_len = len;
96
97 new = (struct file_name_list *)xmalloc (sizeof (struct file_name_list));
98 new->name = dir;
99 new->nlen = len;
100 new->next = *list;
101 new->ino = st.st_ino;
102 new->dev = st.st_dev;
103 new->sysp = sysp;
104 new->name_map = NULL;
105
106 *list = new;
107 }
108
109 /* Merge the four include chains together in the order quote, bracket,
110 system, after. Remove duplicate dirs (as determined by
111 INO_T_EQ()). The system_include and after_include chains are never
112 referred to again after this function; all access is through the
113 bracket_include path.
114
115 For the future: Check if the directory is empty (but
116 how?) and possibly preload the include hash. */
117
118 void
119 merge_include_chains (opts)
120 struct cpp_options *opts;
121 {
122 struct file_name_list *prev, *next, *cur, *other;
123 struct file_name_list *quote, *brack, *systm, *after;
124 struct file_name_list *qtail, *btail, *stail, *atail;
125
126 qtail = opts->quote_include;
127 btail = opts->bracket_include;
128 stail = opts->system_include;
129 atail = opts->after_include;
130
131 /* Nreverse the four lists. */
132 prev = 0;
133 for (cur = qtail; cur; cur = next)
134 {
135 next = cur->next;
136 cur->next = prev;
137 prev = cur;
138 }
139 quote = prev;
140
141 prev = 0;
142 for (cur = btail; cur; cur = next)
143 {
144 next = cur->next;
145 cur->next = prev;
146 prev = cur;
147 }
148 brack = prev;
149
150 prev = 0;
151 for (cur = stail; cur; cur = next)
152 {
153 next = cur->next;
154 cur->next = prev;
155 prev = cur;
156 }
157 systm = prev;
158
159 prev = 0;
160 for (cur = atail; cur; cur = next)
161 {
162 next = cur->next;
163 cur->next = prev;
164 prev = cur;
165 }
166 after = prev;
167
168 /* Paste together bracket, system, and after include chains. */
169 if (stail)
170 stail->next = after;
171 else
172 systm = after;
173 if (btail)
174 btail->next = systm;
175 else
176 brack = systm;
177
178 /* This is a bit tricky.
179 First we drop dupes from the quote-include list.
180 Then we drop dupes from the bracket-include list.
181 Finally, if qtail and brack are the same directory,
182 we cut out qtail.
183
184 We can't just merge the lists and then uniquify them because
185 then we may lose directories from the <> search path that should
186 be there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however
187 safe to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written
188 -Ibar -I- -Ifoo -Iquux. */
189
190 for (cur = quote; cur; cur = cur->next)
191 {
192 for (other = quote; other != cur; other = other->next)
193 if (INO_T_EQ (cur->ino, other->ino)
194 && cur->dev == other->dev)
195 {
196 prev->next = cur->next;
197 free (cur->name);
198 free (cur);
199 cur = prev;
200 break;
201 }
202 prev = cur;
203 }
204 qtail = prev;
205
206 for (cur = brack; cur; cur = cur->next)
207 {
208 for (other = brack; other != cur; other = other->next)
209 if (INO_T_EQ (cur->ino, other->ino)
210 && cur->dev == other->dev)
211 {
212 prev->next = cur->next;
213 free (cur->name);
214 free (cur);
215 cur = prev;
216 break;
217 }
218 prev = cur;
219 }
220
221 if (quote)
222 {
223 if (INO_T_EQ (qtail->ino, brack->ino) && qtail->dev == brack->dev)
224 {
225 if (quote == qtail)
226 {
227 free (quote->name);
228 free (quote);
229 quote = brack;
230 }
231 else
232 {
233 cur = quote;
234 while (cur->next != qtail)
235 cur = cur->next;
236 cur->next = brack;
237 free (qtail->name);
238 free (qtail);
239 }
240 }
241 else
242 qtail->next = brack;
243 }
244 else
245 quote = brack;
246
247 opts->quote_include = quote;
248 opts->bracket_include = brack;
249 opts->system_include = NULL;
250 opts->after_include = NULL;
251 }
252
253 /* Look up or add an entry to the table of all includes. This table
254 is indexed by the name as it appears in the #include line. The
255 ->next_this_file chain stores all different files with the same
256 #include name (there are at least three ways this can happen). The
257 hash function could probably be improved a bit. */
258
259 struct include_hash *
260 include_hash (pfile, fname, add)
261 cpp_reader *pfile;
262 char *fname;
263 int add;
264 {
265 unsigned int hash = 0;
266 struct include_hash *l, *m;
267 char *f = fname;
268
269 while (*f)
270 hash += *f++;
271
272 l = pfile->all_include_files[hash % ALL_INCLUDE_HASHSIZE];
273 m = 0;
274 for (; l; m = l, l = l->next)
275 if (!strcmp (l->nshort, fname))
276 return l;
277
278 if (!add)
279 return 0;
280
281 l = (struct include_hash *) xmalloc (sizeof (struct include_hash));
282 l->next = NULL;
283 l->next_this_file = NULL;
284 l->foundhere = NULL;
285 l->buf = NULL;
286 l->limit = NULL;
287 if (m)
288 m->next = l;
289 else
290 pfile->all_include_files[hash % ALL_INCLUDE_HASHSIZE] = l;
291
292 return l;
293 }
294
295 /* Return 0 if the file pointed to by IHASH has never been included before,
296 -1 if it has been included before and need not be again,
297 or a pointer to an IHASH entry which is the file to be reread.
298 "Never before" is with respect to the position in ILIST.
299
300 This will not detect redundancies involving odd uses of the
301 `current directory' rule for "" includes. They aren't quite
302 pathological, but I think they are rare enough not to worry about.
303 The simplest example is:
304
305 top.c:
306 #include "a/a.h"
307 #include "b/b.h"
308
309 a/a.h:
310 #include "../b/b.h"
311
312 and the problem is that for `current directory' includes,
313 ihash->foundhere is not on any of the global include chains,
314 so the test below (i->foundhere == l) may be false even when
315 the directories are in fact the same. */
316
317 static struct include_hash *
318 redundant_include_p (pfile, ihash, ilist)
319 cpp_reader *pfile;
320 struct include_hash *ihash;
321 struct file_name_list *ilist;
322 {
323 struct file_name_list *l;
324 struct include_hash *i;
325
326 if (! ihash->foundhere)
327 return 0;
328
329 for (i = ihash; i; i = i->next_this_file)
330 for (l = ilist; l; l = l->next)
331 if (i->foundhere == l)
332 /* The control_macro works like this: If it's NULL, the file
333 is to be included again. If it's "", the file is never to
334 be included again. If it's a string, the file is not to be
335 included again if the string is the name of a defined macro. */
336 return (i->control_macro
337 && (i->control_macro[0] == '\0'
338 || cpp_lookup (pfile, i->control_macro, -1, -1)))
339 ? (struct include_hash *)-1 : i;
340
341 return 0;
342 }
343
344 static int
345 file_cleanup (pbuf, pfile)
346 cpp_buffer *pbuf;
347 cpp_reader *pfile;
348 {
349 if (pbuf->buf)
350 {
351 free (pbuf->buf);
352 pbuf->buf = 0;
353 }
354 if (pfile->system_include_depth)
355 pfile->system_include_depth--;
356 return 0;
357 }
358
359 /* Search for include file FNAME in the include chain starting at
360 SEARCH_START. Return -2 if this file doesn't need to be included
361 (because it was included already and it's marked idempotent),
362 -1 if an error occurred, or a file descriptor open on the file.
363 *IHASH is set to point to the include hash entry for this file, and
364 *BEFORE is 1 if the file was included before (but needs to be read
365 again). */
366 int
367 find_include_file (pfile, fname, search_start, ihash, before)
368 cpp_reader *pfile;
369 char *fname;
370 struct file_name_list *search_start;
371 struct include_hash **ihash;
372 int *before;
373 {
374 struct file_name_list *l;
375 struct include_hash *ih, *jh;
376 int f, len;
377 char *name;
378
379 ih = include_hash (pfile, fname, 1);
380 jh = redundant_include_p (pfile, ih,
381 fname[0] == '/' ? ABSOLUTE_PATH : search_start);
382
383 if (jh != 0)
384 {
385 *before = 1;
386 *ihash = jh;
387
388 if (jh == (struct include_hash *)-1)
389 return -2;
390 else
391 return open (jh->name, O_RDONLY, 0666);
392 }
393
394 if (ih->foundhere)
395 /* A file is already known by this name, but it's not the same file.
396 Allocate another include_hash block and add it to the next_this_file
397 chain. */
398 {
399 jh = (struct include_hash *)xmalloc (sizeof (struct include_hash));
400 while (ih->next_this_file) ih = ih->next_this_file;
401
402 ih->next_this_file = jh;
403 jh = ih;
404 ih = ih->next_this_file;
405
406 ih->next = NULL;
407 ih->next_this_file = NULL;
408 ih->buf = NULL;
409 ih->limit = NULL;
410 }
411 *before = 0;
412 *ihash = ih;
413 ih->nshort = savestring (fname);
414 ih->control_macro = NULL;
415
416 /* If the pathname is absolute, just open it. */
417 if (fname[0] == '/')
418 {
419 ih->foundhere = ABSOLUTE_PATH;
420 ih->name = ih->nshort;
421 return open (ih->name, O_RDONLY, 0666);
422 }
423
424 /* Search directory path, trying to open the file. */
425
426 len = strlen (fname);
427 name = xmalloc (len + pfile->max_include_len + 2 + INCLUDE_LEN_FUDGE);
428
429 for (l = search_start; l; l = l->next)
430 {
431 bcopy (l->name, name, l->nlen);
432 name[l->nlen] = '/';
433 strcpy (&name[l->nlen+1], fname);
434 simplify_pathname (name);
435 if (CPP_OPTIONS (pfile)->remap)
436 name = remap_filename (pfile, name, l);
437
438 f = open (name, O_RDONLY, 0666);
439 #ifdef EACCES
440 if (f == -1 && errno == EACCES)
441 {
442 cpp_error(pfile, "included file `%s' exists but is not readable",
443 name);
444 return -1;
445 }
446 #endif
447
448 if (f >= 0)
449 {
450 ih->foundhere = l;
451 ih->name = xrealloc (name, strlen (name)+1);
452 return f;
453 }
454 }
455
456 if (jh)
457 {
458 jh->next_this_file = NULL;
459 free (ih);
460 }
461 free (name);
462 *ihash = (struct include_hash *)-1;
463 return -1;
464 }
465
466 /* The file_name_map structure holds a mapping of file names for a
467 particular directory. This mapping is read from the file named
468 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
469 map filenames on a file system with severe filename restrictions,
470 such as DOS. The format of the file name map file is just a series
471 of lines with two tokens on each line. The first token is the name
472 to map, and the second token is the actual name to use. */
473
474 struct file_name_map
475 {
476 struct file_name_map *map_next;
477 char *map_from;
478 char *map_to;
479 };
480
481 #define FILE_NAME_MAP_FILE "header.gcc"
482
483 /* Read a space delimited string of unlimited length from a stdio
484 file. */
485
486 static char *
487 read_filename_string (ch, f)
488 int ch;
489 FILE *f;
490 {
491 char *alloc, *set;
492 int len;
493
494 len = 20;
495 set = alloc = xmalloc (len + 1);
496 if (! is_space[ch])
497 {
498 *set++ = ch;
499 while ((ch = getc (f)) != EOF && ! is_space[ch])
500 {
501 if (set - alloc == len)
502 {
503 len *= 2;
504 alloc = xrealloc (alloc, len + 1);
505 set = alloc + len / 2;
506 }
507 *set++ = ch;
508 }
509 }
510 *set = '\0';
511 ungetc (ch, f);
512 return alloc;
513 }
514
515 /* This structure holds a linked list of file name maps, one per directory. */
516
517 struct file_name_map_list
518 {
519 struct file_name_map_list *map_list_next;
520 char *map_list_name;
521 struct file_name_map *map_list_map;
522 };
523
524 /* Read the file name map file for DIRNAME. */
525
526 static struct file_name_map *
527 read_name_map (pfile, dirname)
528 cpp_reader *pfile;
529 char *dirname;
530 {
531 register struct file_name_map_list *map_list_ptr;
532 char *name;
533 FILE *f;
534
535 for (map_list_ptr = CPP_OPTIONS (pfile)->map_list; map_list_ptr;
536 map_list_ptr = map_list_ptr->map_list_next)
537 if (! strcmp (map_list_ptr->map_list_name, dirname))
538 return map_list_ptr->map_list_map;
539
540 map_list_ptr = ((struct file_name_map_list *)
541 xmalloc (sizeof (struct file_name_map_list)));
542 map_list_ptr->map_list_name = savestring (dirname);
543
544 name = (char *) alloca (strlen (dirname) + strlen (FILE_NAME_MAP_FILE) + 2);
545 strcpy (name, dirname);
546 if (*dirname)
547 strcat (name, "/");
548 strcat (name, FILE_NAME_MAP_FILE);
549 f = fopen (name, "r");
550 if (!f)
551 map_list_ptr->map_list_map = (struct file_name_map *)-1;
552 else
553 {
554 int ch;
555 int dirlen = strlen (dirname);
556
557 while ((ch = getc (f)) != EOF)
558 {
559 char *from, *to;
560 struct file_name_map *ptr;
561
562 if (is_space[ch])
563 continue;
564 from = read_filename_string (ch, f);
565 while ((ch = getc (f)) != EOF && is_hor_space[ch])
566 ;
567 to = read_filename_string (ch, f);
568
569 ptr = ((struct file_name_map *)
570 xmalloc (sizeof (struct file_name_map)));
571 ptr->map_from = from;
572
573 /* Make the real filename absolute. */
574 if (*to == '/')
575 ptr->map_to = to;
576 else
577 {
578 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
579 strcpy (ptr->map_to, dirname);
580 ptr->map_to[dirlen] = '/';
581 strcpy (ptr->map_to + dirlen + 1, to);
582 free (to);
583 }
584
585 ptr->map_next = map_list_ptr->map_list_map;
586 map_list_ptr->map_list_map = ptr;
587
588 while ((ch = getc (f)) != '\n')
589 if (ch == EOF)
590 break;
591 }
592 fclose (f);
593 }
594
595 map_list_ptr->map_list_next = CPP_OPTIONS (pfile)->map_list;
596 CPP_OPTIONS (pfile)->map_list = map_list_ptr;
597
598 return map_list_ptr->map_list_map;
599 }
600
601 /* Remap NAME based on the file_name_map (if any) for LOC. */
602
603 static char *
604 remap_filename (pfile, name, loc)
605 cpp_reader *pfile;
606 char *name;
607 struct file_name_list *loc;
608 {
609 struct file_name_map *map;
610 char *from;
611 char *p, *dir;
612
613 if (! loc->name_map)
614 loc->name_map = read_name_map (pfile,
615 loc->name
616 ? loc->name : ".");
617
618 if (loc->name_map == (struct file_name_map *)-1)
619 return name;
620
621 from = name + strlen (loc->name) + 1;
622
623 for (map = loc->name_map; map; map = map->map_next)
624 if (!strcmp (map->map_from, from))
625 return map->map_to;
626
627 /* Try to find a mapping file for the particular directory we are
628 looking in. Thus #include <sys/types.h> will look up sys/types.h
629 in /usr/include/header.gcc and look up types.h in
630 /usr/include/sys/header.gcc. */
631 p = rindex (name, '/');
632 if (!p)
633 p = name;
634 if (loc && loc->name
635 && strlen (loc->name) == (size_t) (p - name)
636 && !strncmp (loc->name, name, p - name))
637 /* FILENAME is in SEARCHPTR, which we've already checked. */
638 return name;
639
640 if (p == name)
641 {
642 dir = ".";
643 from = name;
644 }
645 else
646 {
647 dir = (char *) alloca (p - name + 1);
648 bcopy (name, dir, p - name);
649 dir[p - name] = '\0';
650 from = p + 1;
651 }
652
653 for (map = read_name_map (pfile, dir); map; map = map->map_next)
654 if (! strcmp (map->map_from, name))
655 return map->map_to;
656
657 return name;
658 }
659
660 /* Read the contents of FD into the buffer on the top of PFILE's stack.
661 IHASH points to the include hash entry for the file associated with
662 FD.
663
664 The caller is responsible for the cpp_push_buffer. */
665
666 int
667 finclude (pfile, fd, ihash)
668 cpp_reader *pfile;
669 int fd;
670 struct include_hash *ihash;
671 {
672 struct stat st;
673 size_t st_size;
674 long i, length;
675 cpp_buffer *fp;
676
677 if (fstat (fd, &st) < 0)
678 goto perror_fail;
679
680 fp = CPP_BUFFER (pfile);
681 fp->nominal_fname = fp->fname = ihash->name;
682 fp->ihash = ihash;
683 fp->system_header_p = (ihash->foundhere != ABSOLUTE_PATH
684 && ihash->foundhere->sysp);
685 fp->lineno = 1;
686 fp->colno = 1;
687 fp->cleanup = file_cleanup;
688
689 /* The ->actual_dir field is only used when ignore_srcdir is not in effect;
690 see do_include */
691 if (!CPP_OPTIONS (pfile)->ignore_srcdir)
692 fp->actual_dir = actual_directory (pfile, fp->fname);
693
694 if (S_ISREG (st.st_mode))
695 {
696 st_size = (size_t) st.st_size;
697 if (st_size != st.st_size || st_size + 2 < st_size)
698 {
699 cpp_error (pfile, "file `%s' too large", ihash->name);
700 goto fail;
701 }
702 fp->buf = (U_CHAR *) xmalloc (st_size + 2);
703 fp->alimit = fp->buf + st_size + 2;
704 fp->cur = fp->buf;
705
706 /* Read the file contents, knowing that st_size is an upper bound
707 on the number of bytes we can read. */
708 length = safe_read (fd, fp->buf, st_size);
709 fp->rlimit = fp->buf + length;
710 if (length < 0)
711 goto perror_fail;
712 }
713 else if (S_ISDIR (st.st_mode))
714 {
715 cpp_pop_buffer (pfile);
716 cpp_error (pfile, "directory `%s' specified in #include", ihash->name);
717 goto fail;
718 }
719 else
720 {
721 /* Cannot count its file size before reading.
722 First read the entire file into heap and
723 copy them into buffer on stack. */
724
725 size_t bsize = 2000;
726
727 st_size = 0;
728 fp->buf = (U_CHAR *) xmalloc (bsize + 2);
729
730 for (;;)
731 {
732 i = safe_read (fd, fp->buf + st_size, bsize - st_size);
733 if (i < 0)
734 goto perror_fail;
735 st_size += i;
736 if (st_size != bsize)
737 break; /* End of file */
738 bsize *= 2;
739 fp->buf = (U_CHAR *) xrealloc (fp->buf, bsize + 2);
740 }
741 fp->cur = fp->buf;
742 length = st_size;
743 }
744
745 /* FIXME: Broken in presence of trigraphs (consider ??/<EOF>)
746 and doesn't warn about a missing newline. */
747 if ((length > 0 && fp->buf[length - 1] != '\n')
748 || (length > 1 && fp->buf[length - 2] == '\\'))
749 fp->buf[length++] = '\n';
750
751 fp->buf[length] = '\0';
752 fp->rlimit = fp->buf + length;
753
754 close (fd);
755 pfile->input_stack_listing_current = 0;
756 return 1;
757
758 perror_fail:
759 cpp_pop_buffer (pfile);
760 cpp_error_from_errno (pfile, ihash->name);
761 fail:
762 close (fd);
763 return 0;
764 }
765
766 static struct file_name_list *
767 actual_directory (pfile, fname)
768 cpp_reader *pfile;
769 char *fname;
770 {
771 char *last_slash, *dir;
772 size_t dlen;
773 struct file_name_list *x;
774
775 dir = savestring (fname);
776 last_slash = rindex (dir, '/');
777 if (last_slash)
778 {
779 if (last_slash == dir)
780 {
781 dlen = 1;
782 last_slash[1] = '\0';
783 }
784 else
785 {
786 dlen = last_slash - dir;
787 *last_slash = '\0';
788 }
789 }
790 else
791 {
792 dir[0] = '.';
793 dir[1] = '\0';
794 dlen = 1;
795 }
796
797 if (dlen > pfile->max_include_len)
798 pfile->max_include_len = dlen;
799
800 for (x = pfile->actual_dirs; x; x = x->alloc)
801 if (!strcmp (x->name, dir))
802 {
803 free (dir);
804 return x;
805 }
806
807 /* Not found, make a new one. */
808 x = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
809 x->name = dir;
810 x->nlen = dlen;
811 x->next = CPP_OPTIONS (pfile)->quote_include;
812 x->alloc = pfile->actual_dirs;
813 x->sysp = 0;
814 x->name_map = NULL;
815
816 pfile->actual_dirs = x;
817 return x;
818 }
819
820 /* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
821 retrying if necessary. If MAX_READ_LEN is defined, read at most
822 that bytes at a time. Return a negative value if an error occurs,
823 otherwise return the actual number of bytes read,
824 which must be LEN unless end-of-file was reached. */
825
826 static long
827 safe_read (desc, ptr, len)
828 int desc;
829 char *ptr;
830 int len;
831 {
832 int left, rcount, nchars;
833
834 left = len;
835 while (left > 0) {
836 rcount = left;
837 #ifdef MAX_READ_LEN
838 if (rcount > MAX_READ_LEN)
839 rcount = MAX_READ_LEN;
840 #endif
841 nchars = read (desc, ptr, rcount);
842 if (nchars < 0)
843 {
844 #ifdef EINTR
845 if (errno == EINTR)
846 continue;
847 #endif
848 return nchars;
849 }
850 if (nchars == 0)
851 break;
852 ptr += nchars;
853 left -= nchars;
854 }
855 return len - left;
856 }
857
858 /* Add output to `deps_buffer' for the -M switch.
859 STRING points to the text to be output.
860 SPACER is ':' for targets, ' ' for dependencies, zero for text
861 to be inserted literally. */
862
863 void
864 deps_output (pfile, string, spacer)
865 cpp_reader *pfile;
866 char *string;
867 int spacer;
868 {
869 int size;
870 int cr = 0;
871
872 if (!*string)
873 return;
874
875 size = strlen (string);
876
877 #ifndef MAX_OUTPUT_COLUMNS
878 #define MAX_OUTPUT_COLUMNS 72
879 #endif
880 if (pfile->deps_column > 0
881 && (pfile->deps_column + size) > MAX_OUTPUT_COLUMNS)
882 {
883 size += 5;
884 cr = 1;
885 pfile->deps_column = 0;
886 }
887
888 if (pfile->deps_size + size + 8 > pfile->deps_allocated_size)
889 {
890 pfile->deps_allocated_size = (pfile->deps_size + size + 50) * 2;
891 pfile->deps_buffer = (char *) xrealloc (pfile->deps_buffer,
892 pfile->deps_allocated_size);
893 }
894
895 if (cr)
896 {
897 bcopy (" \\\n ", &pfile->deps_buffer[pfile->deps_size], 5);
898 pfile->deps_size += 5;
899 }
900
901 if (spacer == ' ' && pfile->deps_column > 0)
902 pfile->deps_buffer[pfile->deps_size++] = ' ';
903 bcopy (string, &pfile->deps_buffer[pfile->deps_size], size);
904 pfile->deps_size += size;
905 pfile->deps_column += size;
906 if (spacer == ':')
907 pfile->deps_buffer[pfile->deps_size++] = ':';
908 pfile->deps_buffer[pfile->deps_size] = 0;
909 }
910
911 /* Simplify a path name in place, deleting redundant components. This
912 reduces OS overhead and guarantees that equivalent paths compare
913 the same (modulo symlinks).
914
915 Transforms made:
916 foo/bar/../quux foo/quux
917 foo/./bar foo/bar
918 foo//bar foo/bar
919 /../quux /quux
920 //quux //quux (POSIX allows leading // as a namespace escape)
921
922 Guarantees no trailing slashes. All transforms reduce the length
923 of the string.
924 */
925 static void
926 simplify_pathname (path)
927 char *path;
928 {
929 char *from, *to;
930 char *base;
931 int absolute = 0;
932
933 #if defined _WIN32 || defined __MSDOS__
934 /* Convert all backslashes to slashes. */
935 for (from = path; *from; from++)
936 if (*from == '\\') *from = '/';
937
938 /* Skip over leading drive letter if present. */
939 if (ISALPHA (path[0]) && path[1] == ':')
940 from = to = &path[2];
941 else
942 from = to = path;
943 #else
944 from = to = path;
945 #endif
946
947 /* Remove redundant initial /s. */
948 if (*from == '/')
949 {
950 absolute = 1;
951 to++;
952 from++;
953 if (*from == '/')
954 {
955 if (*++from == '/')
956 /* 3 or more initial /s are equivalent to 1 /. */
957 while (*++from == '/');
958 else
959 /* On some hosts // differs from /; Posix allows this. */
960 to++;
961 }
962 }
963 base = to;
964
965 for (;;)
966 {
967 while (*from == '/')
968 from++;
969
970 if (from[0] == '.' && from[1] == '/')
971 from += 2;
972 else if (from[0] == '.' && from[1] == '\0')
973 goto done;
974 else if (from[0] == '.' && from[1] == '.' && from[2] == '/')
975 {
976 if (base == to)
977 {
978 if (absolute)
979 from += 3;
980 else
981 {
982 *to++ = *from++;
983 *to++ = *from++;
984 *to++ = *from++;
985 base = to;
986 }
987 }
988 else
989 {
990 to -= 2;
991 while (to > base && *to != '/') to--;
992 if (*to == '/')
993 to++;
994 from += 3;
995 }
996 }
997 else if (from[0] == '.' && from[1] == '.' && from[2] == '\0')
998 {
999 if (base == to)
1000 {
1001 if (!absolute)
1002 {
1003 *to++ = *from++;
1004 *to++ = *from++;
1005 }
1006 }
1007 else
1008 {
1009 to -= 2;
1010 while (to > base && *to != '/') to--;
1011 if (*to == '/')
1012 to++;
1013 }
1014 goto done;
1015 }
1016 else
1017 /* Copy this component and trailing /, if any. */
1018 while ((*to++ = *from++) != '/')
1019 {
1020 if (!to[-1])
1021 {
1022 to--;
1023 goto done;
1024 }
1025 }
1026
1027 }
1028
1029 done:
1030 /* Trim trailing slash */
1031 if (to[0] == '/' && (!absolute || to > path+1))
1032 to--;
1033
1034 /* Change the empty string to "." so that stat() on the result
1035 will always work. */
1036 if (to == path)
1037 *to++ = '.';
1038
1039 *to = '\0';
1040
1041 return;
1042 }
1043
1044 /* It is not clear when this should be used if at all, so I've
1045 disabled it until someone who understands VMS can look at it. */
1046 #if 0
1047
1048 /* Under VMS we need to fix up the "include" specification filename.
1049
1050 Rules for possible conversions
1051
1052 fullname tried paths
1053
1054 name name
1055 ./dir/name [.dir]name
1056 /dir/name dir:name
1057 /name [000000]name, name
1058 dir/name dir:[000000]name, dir:name, dir/name
1059 dir1/dir2/name dir1:[dir2]name, dir1:[000000.dir2]name
1060 path:/name path:[000000]name, path:name
1061 path:/dir/name path:[000000.dir]name, path:[dir]name
1062 path:dir/name path:[dir]name
1063 [path]:[dir]name [path.dir]name
1064 path/[dir]name [path.dir]name
1065
1066 The path:/name input is constructed when expanding <> includes. */
1067
1068
1069 static void
1070 hack_vms_include_specification (fullname)
1071 char *fullname;
1072 {
1073 register char *basename, *unixname, *local_ptr, *first_slash;
1074 int f, check_filename_before_returning, must_revert;
1075 char Local[512];
1076
1077 check_filename_before_returning = 0;
1078 must_revert = 0;
1079 /* See if we can find a 1st slash. If not, there's no path information. */
1080 first_slash = index (fullname, '/');
1081 if (first_slash == 0)
1082 return 0; /* Nothing to do!!! */
1083
1084 /* construct device spec if none given. */
1085
1086 if (index (fullname, ':') == 0)
1087 {
1088
1089 /* If fullname has a slash, take it as device spec. */
1090
1091 if (first_slash == fullname)
1092 {
1093 first_slash = index (fullname+1, '/'); /* 2nd slash ? */
1094 if (first_slash)
1095 *first_slash = ':'; /* make device spec */
1096 for (basename = fullname; *basename != 0; basename++)
1097 *basename = *(basename+1); /* remove leading slash */
1098 }
1099 else if ((first_slash[-1] != '.') /* keep ':/', './' */
1100 && (first_slash[-1] != ':')
1101 && (first_slash[-1] != ']')) /* or a vms path */
1102 {
1103 *first_slash = ':';
1104 }
1105 else if ((first_slash[1] == '[') /* skip './' in './[dir' */
1106 && (first_slash[-1] == '.'))
1107 fullname += 2;
1108 }
1109
1110 /* Get part after first ':' (basename[-1] == ':')
1111 or last '/' (basename[-1] == '/'). */
1112
1113 basename = base_name (fullname);
1114
1115 local_ptr = Local; /* initialize */
1116
1117 /* We are trying to do a number of things here. First of all, we are
1118 trying to hammer the filenames into a standard format, such that later
1119 processing can handle them.
1120
1121 If the file name contains something like [dir.], then it recognizes this
1122 as a root, and strips the ".]". Later processing will add whatever is
1123 needed to get things working properly.
1124
1125 If no device is specified, then the first directory name is taken to be
1126 a device name (or a rooted logical). */
1127
1128 /* Point to the UNIX filename part (which needs to be fixed!)
1129 but skip vms path information.
1130 [basename != fullname since first_slash != 0]. */
1131
1132 if ((basename[-1] == ':') /* vms path spec. */
1133 || (basename[-1] == ']')
1134 || (basename[-1] == '>'))
1135 unixname = basename;
1136 else
1137 unixname = fullname;
1138
1139 if (*unixname == '/')
1140 unixname++;
1141
1142 /* If the directory spec is not rooted, we can just copy
1143 the UNIX filename part and we are done. */
1144
1145 if (((basename - fullname) > 1)
1146 && ( (basename[-1] == ']')
1147 || (basename[-1] == '>')))
1148 {
1149 if (basename[-2] != '.')
1150 {
1151
1152 /* The VMS part ends in a `]', and the preceding character is not a `.'.
1153 -> PATH]:/name (basename = '/name', unixname = 'name')
1154 We strip the `]', and then splice the two parts of the name in the
1155 usual way. Given the default locations for include files in cccp.c,
1156 we will only use this code if the user specifies alternate locations
1157 with the /include (-I) switch on the command line. */
1158
1159 basename -= 1; /* Strip "]" */
1160 unixname--; /* backspace */
1161 }
1162 else
1163 {
1164
1165 /* The VMS part has a ".]" at the end, and this will not do. Later
1166 processing will add a second directory spec, and this would be a syntax
1167 error. Thus we strip the ".]", and thus merge the directory specs.
1168 We also backspace unixname, so that it points to a '/'. This inhibits the
1169 generation of the 000000 root directory spec (which does not belong here
1170 in this case). */
1171
1172 basename -= 2; /* Strip ".]" */
1173 unixname--; /* backspace */
1174 }
1175 }
1176
1177 else
1178
1179 {
1180
1181 /* We drop in here if there is no VMS style directory specification yet.
1182 If there is no device specification either, we make the first dir a
1183 device and try that. If we do not do this, then we will be essentially
1184 searching the users default directory (as if they did a #include "asdf.h").
1185
1186 Then all we need to do is to push a '[' into the output string. Later
1187 processing will fill this in, and close the bracket. */
1188
1189 if ((unixname != fullname) /* vms path spec found. */
1190 && (basename[-1] != ':'))
1191 *local_ptr++ = ':'; /* dev not in spec. take first dir */
1192
1193 *local_ptr++ = '['; /* Open the directory specification */
1194 }
1195
1196 if (unixname == fullname) /* no vms dir spec. */
1197 {
1198 must_revert = 1;
1199 if ((first_slash != 0) /* unix dir spec. */
1200 && (*unixname != '/') /* not beginning with '/' */
1201 && (*unixname != '.')) /* or './' or '../' */
1202 *local_ptr++ = '.'; /* dir is local ! */
1203 }
1204
1205 /* at this point we assume that we have the device spec, and (at least
1206 the opening "[" for a directory specification. We may have directories
1207 specified already.
1208
1209 If there are no other slashes then the filename will be
1210 in the "root" directory. Otherwise, we need to add
1211 directory specifications. */
1212
1213 if (index (unixname, '/') == 0)
1214 {
1215 /* if no directories specified yet and none are following. */
1216 if (local_ptr[-1] == '[')
1217 {
1218 /* Just add "000000]" as the directory string */
1219 strcpy (local_ptr, "000000]");
1220 local_ptr += strlen (local_ptr);
1221 check_filename_before_returning = 1; /* we might need to fool with this later */
1222 }
1223 }
1224 else
1225 {
1226
1227 /* As long as there are still subdirectories to add, do them. */
1228 while (index (unixname, '/') != 0)
1229 {
1230 /* If this token is "." we can ignore it
1231 if it's not at the beginning of a path. */
1232 if ((unixname[0] == '.') && (unixname[1] == '/'))
1233 {
1234 /* remove it at beginning of path. */
1235 if ( ((unixname == fullname) /* no device spec */
1236 && (fullname+2 != basename)) /* starts with ./ */
1237 /* or */
1238 || ((basename[-1] == ':') /* device spec */
1239 && (unixname-1 == basename))) /* and ./ afterwards */
1240 *local_ptr++ = '.'; /* make '[.' start of path. */
1241 unixname += 2;
1242 continue;
1243 }
1244
1245 /* Add a subdirectory spec. Do not duplicate "." */
1246 if ( local_ptr[-1] != '.'
1247 && local_ptr[-1] != '['
1248 && local_ptr[-1] != '<')
1249 *local_ptr++ = '.';
1250
1251 /* If this is ".." then the spec becomes "-" */
1252 if ( (unixname[0] == '.')
1253 && (unixname[1] == '.')
1254 && (unixname[2] == '/'))
1255 {
1256 /* Add "-" and skip the ".." */
1257 if ((local_ptr[-1] == '.')
1258 && (local_ptr[-2] == '['))
1259 local_ptr--; /* prevent [.- */
1260 *local_ptr++ = '-';
1261 unixname += 3;
1262 continue;
1263 }
1264
1265 /* Copy the subdirectory */
1266 while (*unixname != '/')
1267 *local_ptr++= *unixname++;
1268
1269 unixname++; /* Skip the "/" */
1270 }
1271
1272 /* Close the directory specification */
1273 if (local_ptr[-1] == '.') /* no trailing periods */
1274 local_ptr--;
1275
1276 if (local_ptr[-1] == '[') /* no dir needed */
1277 local_ptr--;
1278 else
1279 *local_ptr++ = ']';
1280 }
1281
1282 /* Now add the filename. */
1283
1284 while (*unixname)
1285 *local_ptr++ = *unixname++;
1286 *local_ptr = 0;
1287
1288 /* Now append it to the original VMS spec. */
1289
1290 strcpy ((must_revert==1)?fullname:basename, Local);
1291
1292 /* If we put a [000000] in the filename, try to open it first. If this fails,
1293 remove the [000000], and return that name. This provides flexibility
1294 to the user in that they can use both rooted and non-rooted logical names
1295 to point to the location of the file. */
1296
1297 if (check_filename_before_returning)
1298 {
1299 f = open (fullname, O_RDONLY, 0666);
1300 if (f >= 0)
1301 {
1302 /* The file name is OK as it is, so return it as is. */
1303 close (f);
1304 return 1;
1305 }
1306
1307 /* The filename did not work. Try to remove the [000000] from the name,
1308 and return it. */
1309
1310 basename = index (fullname, '[');
1311 local_ptr = index (fullname, ']') + 1;
1312 strcpy (basename, local_ptr); /* this gets rid of it */
1313
1314 }
1315
1316 return 1;
1317 }
1318 #endif /* VMS */
This page took 0.10008 seconds and 6 git commands to generate.