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