Fix copyrights.
[gcc.git] / gcc / cppfiles.c
1 /* Part of CPP library. (include file handling)
2 Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998,
3 1999, 2000 Free Software Foundation, Inc.
4 Written by Per Bothner, 1994.
5 Based on CCCP program by Paul Rubin, June 1986
6 Adapted to ANSI C, Richard Stallman, Jan 1987
7 Split out of cpplib.c, Zack Weinberg, Oct 1998
8
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
12 later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding! */
26
27 #include "config.h"
28 #include "system.h"
29 #include "cpplib.h"
30 #include "intl.h"
31
32 /* The entry points to this file are: find_include_file, finclude,
33 include_hash, append_include_chain, deps_output, and file_cleanup.
34 file_cleanup is only called through CPP_BUFFER(pfile)->cleanup,
35 so it's static anyway. */
36
37 static struct include_hash *redundant_include_p
38 PARAMS ((cpp_reader *,
39 struct include_hash *,
40 struct file_name_list *));
41 static struct file_name_map *read_name_map
42 PARAMS ((cpp_reader *, const char *));
43 static char *read_filename_string PARAMS ((int, FILE *));
44 static char *remap_filename PARAMS ((cpp_reader *, char *,
45 struct file_name_list *));
46 static long read_and_prescan PARAMS ((cpp_reader *, cpp_buffer *,
47 int, size_t));
48 static struct file_name_list *actual_directory
49 PARAMS ((cpp_reader *, const char *));
50 static void initialize_input_buffer PARAMS ((cpp_reader *, int,
51 struct stat *));
52 static int file_cleanup PARAMS ((cpp_buffer *, cpp_reader *));
53 static U_CHAR *find_position PARAMS ((U_CHAR *, U_CHAR *,
54 unsigned long *));
55
56 #if 0
57 static void hack_vms_include_specification PARAMS ((char *));
58 #endif
59
60 /* Windows does not natively support inodes, and neither does MSDOS.
61 Cygwin's emulation can generate non-unique inodes, so don't use it.
62 VMS has non-numeric inodes. */
63 #ifdef VMS
64 #define INO_T_EQ(a, b) (!bcmp((char *) &(a), (char *) &(b), sizeof (a)))
65 #elif (defined _WIN32 && ! defined (_UWIN)) \
66 || defined __MSDOS__
67 #define INO_T_EQ(a, b) 0
68 #else
69 #define INO_T_EQ(a, b) ((a) == (b))
70 #endif
71
72 #ifndef INCLUDE_LEN_FUDGE
73 #define INCLUDE_LEN_FUDGE 0
74 #endif
75
76 /* Merge the four include chains together in the order quote, bracket,
77 system, after. Remove duplicate dirs (as determined by
78 INO_T_EQ()). The system_include and after_include chains are never
79 referred to again after this function; all access is through the
80 bracket_include path.
81
82 For the future: Check if the directory is empty (but
83 how?) and possibly preload the include hash. */
84
85 void
86 merge_include_chains (opts)
87 struct cpp_options *opts;
88 {
89 struct file_name_list *prev, *cur, *other;
90 struct file_name_list *quote, *brack, *systm, *after;
91 struct file_name_list *qtail, *btail, *stail, *atail;
92
93 qtail = opts->pending->quote_tail;
94 btail = opts->pending->brack_tail;
95 stail = opts->pending->systm_tail;
96 atail = opts->pending->after_tail;
97
98 quote = opts->pending->quote_head;
99 brack = opts->pending->brack_head;
100 systm = opts->pending->systm_head;
101 after = opts->pending->after_head;
102
103 /* Paste together bracket, system, and after include chains. */
104 if (stail)
105 stail->next = after;
106 else
107 systm = after;
108 if (btail)
109 btail->next = systm;
110 else
111 brack = systm;
112
113 /* This is a bit tricky.
114 First we drop dupes from the quote-include list.
115 Then we drop dupes from the bracket-include list.
116 Finally, if qtail and brack are the same directory,
117 we cut out qtail.
118
119 We can't just merge the lists and then uniquify them because
120 then we may lose directories from the <> search path that should
121 be there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however
122 safe to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written
123 -Ibar -I- -Ifoo -Iquux.
124
125 Note that this algorithm is quadratic in the number of -I switches,
126 which is acceptable since there aren't usually that many of them. */
127
128 for (cur = quote, prev = NULL; cur; cur = cur->next)
129 {
130 for (other = quote; other != cur; other = other->next)
131 if (INO_T_EQ (cur->ino, other->ino)
132 && cur->dev == other->dev)
133 {
134 if (opts->verbose)
135 fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
136 cur->name);
137
138 prev->next = cur->next;
139 free (cur->name);
140 free (cur);
141 cur = prev;
142 break;
143 }
144 prev = cur;
145 }
146 qtail = prev;
147
148 for (cur = brack; cur; cur = cur->next)
149 {
150 for (other = brack; other != cur; other = other->next)
151 if (INO_T_EQ (cur->ino, other->ino)
152 && cur->dev == other->dev)
153 {
154 if (opts->verbose)
155 fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
156 cur->name);
157
158 prev->next = cur->next;
159 free (cur->name);
160 free (cur);
161 cur = prev;
162 break;
163 }
164 prev = cur;
165 }
166
167 if (quote)
168 {
169 if (INO_T_EQ (qtail->ino, brack->ino) && qtail->dev == brack->dev)
170 {
171 if (quote == qtail)
172 {
173 if (opts->verbose)
174 fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
175 quote->name);
176
177 free (quote->name);
178 free (quote);
179 quote = brack;
180 }
181 else
182 {
183 cur = quote;
184 while (cur->next != qtail)
185 cur = cur->next;
186 cur->next = brack;
187 if (opts->verbose)
188 fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
189 qtail->name);
190
191 free (qtail->name);
192 free (qtail);
193 }
194 }
195 else
196 qtail->next = brack;
197 }
198 else
199 quote = brack;
200
201 opts->quote_include = quote;
202 opts->bracket_include = brack;
203 }
204
205 /* Look up or add an entry to the table of all includes. This table
206 is indexed by the name as it appears in the #include line. The
207 ->next_this_file chain stores all different files with the same
208 #include name (there are at least three ways this can happen). The
209 hash function could probably be improved a bit. */
210
211 struct include_hash *
212 include_hash (pfile, fname, add)
213 cpp_reader *pfile;
214 const char *fname;
215 int add;
216 {
217 unsigned int hash = 0;
218 struct include_hash *l, *m;
219 const char *f = fname;
220
221 while (*f)
222 hash += *f++;
223
224 l = pfile->all_include_files[hash % ALL_INCLUDE_HASHSIZE];
225 m = 0;
226 for (; l; m = l, l = l->next)
227 if (!strcmp (l->nshort, fname))
228 return l;
229
230 if (!add)
231 return 0;
232
233 l = (struct include_hash *) xmalloc (sizeof (struct include_hash));
234 l->next = NULL;
235 l->next_this_file = NULL;
236 l->foundhere = NULL;
237 l->buf = NULL;
238 l->limit = NULL;
239 if (m)
240 m->next = l;
241 else
242 pfile->all_include_files[hash % ALL_INCLUDE_HASHSIZE] = l;
243
244 return l;
245 }
246
247 /* Return 0 if the file pointed to by IHASH has never been included before,
248 -1 if it has been included before and need not be again,
249 or a pointer to an IHASH entry which is the file to be reread.
250 "Never before" is with respect to the position in ILIST.
251
252 This will not detect redundancies involving odd uses of the
253 `current directory' rule for "" includes. They aren't quite
254 pathological, but I think they are rare enough not to worry about.
255 The simplest example is:
256
257 top.c:
258 #include "a/a.h"
259 #include "b/b.h"
260
261 a/a.h:
262 #include "../b/b.h"
263
264 and the problem is that for `current directory' includes,
265 ihash->foundhere is not on any of the global include chains,
266 so the test below (i->foundhere == l) may be false even when
267 the directories are in fact the same. */
268
269 static struct include_hash *
270 redundant_include_p (pfile, ihash, ilist)
271 cpp_reader *pfile;
272 struct include_hash *ihash;
273 struct file_name_list *ilist;
274 {
275 struct file_name_list *l;
276 struct include_hash *i;
277
278 if (! ihash->foundhere)
279 return 0;
280
281 for (i = ihash; i; i = i->next_this_file)
282 for (l = ilist; l; l = l->next)
283 if (i->foundhere == l)
284 /* The control_macro works like this: If it's NULL, the file
285 is to be included again. If it's "", the file is never to
286 be included again. If it's a string, the file is not to be
287 included again if the string is the name of a defined macro. */
288 return (i->control_macro
289 && (i->control_macro[0] == '\0'
290 || cpp_defined (pfile, i->control_macro, -1)))
291 ? (struct include_hash *)-1 : i;
292
293 return 0;
294 }
295
296 static int
297 file_cleanup (pbuf, pfile)
298 cpp_buffer *pbuf;
299 cpp_reader *pfile;
300 {
301 if (pbuf->buf)
302 {
303 free (pbuf->buf);
304 pbuf->buf = 0;
305 }
306 if (pfile->system_include_depth)
307 pfile->system_include_depth--;
308 return 0;
309 }
310
311 /* Search for include file FNAME in the include chain starting at
312 SEARCH_START. Return -2 if this file doesn't need to be included
313 (because it was included already and it's marked idempotent),
314 -1 if an error occurred, or a file descriptor open on the file.
315 *IHASH is set to point to the include hash entry for this file, and
316 *BEFORE is 1 if the file was included before (but needs to be read
317 again). */
318 int
319 find_include_file (pfile, fname, search_start, ihash, before)
320 cpp_reader *pfile;
321 const char *fname;
322 struct file_name_list *search_start;
323 struct include_hash **ihash;
324 int *before;
325 {
326 struct file_name_list *l;
327 struct include_hash *ih, *jh;
328 int f, len;
329 char *name;
330
331 ih = include_hash (pfile, fname, 1);
332 jh = redundant_include_p (pfile, ih,
333 fname[0] == '/' ? ABSOLUTE_PATH : search_start);
334
335 if (jh != 0)
336 {
337 *before = 1;
338 *ihash = jh;
339
340 if (jh == (struct include_hash *)-1)
341 return -2;
342 else
343 return open (jh->name, O_RDONLY, 0666);
344 }
345
346 if (ih->foundhere)
347 /* A file is already known by this name, but it's not the same file.
348 Allocate another include_hash block and add it to the next_this_file
349 chain. */
350 {
351 jh = (struct include_hash *)xmalloc (sizeof (struct include_hash));
352 while (ih->next_this_file) ih = ih->next_this_file;
353
354 ih->next_this_file = jh;
355 jh = ih;
356 ih = ih->next_this_file;
357
358 ih->next = NULL;
359 ih->next_this_file = NULL;
360 ih->buf = NULL;
361 ih->limit = NULL;
362 }
363 *before = 0;
364 *ihash = ih;
365 ih->nshort = xstrdup (fname);
366 ih->control_macro = NULL;
367
368 /* If the pathname is absolute, just open it. */
369 if (fname[0] == '/')
370 {
371 ih->foundhere = ABSOLUTE_PATH;
372 ih->name = ih->nshort;
373 return open (ih->name, O_RDONLY, 0666);
374 }
375
376 /* Search directory path, trying to open the file. */
377
378 len = strlen (fname);
379 name = xmalloc (len + pfile->max_include_len + 2 + INCLUDE_LEN_FUDGE);
380
381 for (l = search_start; l; l = l->next)
382 {
383 bcopy (l->name, name, l->nlen);
384 name[l->nlen] = '/';
385 strcpy (&name[l->nlen+1], fname);
386 simplify_pathname (name);
387 if (CPP_OPTIONS (pfile)->remap)
388 name = remap_filename (pfile, name, l);
389
390 f = open (name, O_RDONLY|O_NONBLOCK|O_NOCTTY, 0666);
391 #ifdef EACCES
392 if (f == -1 && errno == EACCES)
393 {
394 cpp_error(pfile, "included file `%s' exists but is not readable",
395 name);
396 return -1;
397 }
398 #endif
399
400 if (f >= 0)
401 {
402 ih->foundhere = l;
403 ih->name = xrealloc (name, strlen (name)+1);
404 return f;
405 }
406 }
407
408 if (jh)
409 {
410 jh->next_this_file = NULL;
411 free (ih);
412 }
413 free (name);
414 *ihash = (struct include_hash *)-1;
415 return -1;
416 }
417
418 /* The file_name_map structure holds a mapping of file names for a
419 particular directory. This mapping is read from the file named
420 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
421 map filenames on a file system with severe filename restrictions,
422 such as DOS. The format of the file name map file is just a series
423 of lines with two tokens on each line. The first token is the name
424 to map, and the second token is the actual name to use. */
425
426 struct file_name_map
427 {
428 struct file_name_map *map_next;
429 char *map_from;
430 char *map_to;
431 };
432
433 #define FILE_NAME_MAP_FILE "header.gcc"
434
435 /* Read a space delimited string of unlimited length from a stdio
436 file. */
437
438 static char *
439 read_filename_string (ch, f)
440 int ch;
441 FILE *f;
442 {
443 char *alloc, *set;
444 int len;
445
446 len = 20;
447 set = alloc = xmalloc (len + 1);
448 if (! is_space(ch))
449 {
450 *set++ = ch;
451 while ((ch = getc (f)) != EOF && ! is_space(ch))
452 {
453 if (set - alloc == len)
454 {
455 len *= 2;
456 alloc = xrealloc (alloc, len + 1);
457 set = alloc + len / 2;
458 }
459 *set++ = ch;
460 }
461 }
462 *set = '\0';
463 ungetc (ch, f);
464 return alloc;
465 }
466
467 /* This structure holds a linked list of file name maps, one per directory. */
468
469 struct file_name_map_list
470 {
471 struct file_name_map_list *map_list_next;
472 char *map_list_name;
473 struct file_name_map *map_list_map;
474 };
475
476 /* Read the file name map file for DIRNAME. */
477
478 static struct file_name_map *
479 read_name_map (pfile, dirname)
480 cpp_reader *pfile;
481 const char *dirname;
482 {
483 register struct file_name_map_list *map_list_ptr;
484 char *name;
485 FILE *f;
486
487 for (map_list_ptr = CPP_OPTIONS (pfile)->map_list; map_list_ptr;
488 map_list_ptr = map_list_ptr->map_list_next)
489 if (! strcmp (map_list_ptr->map_list_name, dirname))
490 return map_list_ptr->map_list_map;
491
492 map_list_ptr = ((struct file_name_map_list *)
493 xmalloc (sizeof (struct file_name_map_list)));
494 map_list_ptr->map_list_name = xstrdup (dirname);
495
496 name = (char *) alloca (strlen (dirname) + strlen (FILE_NAME_MAP_FILE) + 2);
497 strcpy (name, dirname);
498 if (*dirname)
499 strcat (name, "/");
500 strcat (name, FILE_NAME_MAP_FILE);
501 f = fopen (name, "r");
502 if (!f)
503 map_list_ptr->map_list_map = (struct file_name_map *)-1;
504 else
505 {
506 int ch;
507 int dirlen = strlen (dirname);
508
509 while ((ch = getc (f)) != EOF)
510 {
511 char *from, *to;
512 struct file_name_map *ptr;
513
514 if (is_space(ch))
515 continue;
516 from = read_filename_string (ch, f);
517 while ((ch = getc (f)) != EOF && is_hspace(ch))
518 ;
519 to = read_filename_string (ch, f);
520
521 ptr = ((struct file_name_map *)
522 xmalloc (sizeof (struct file_name_map)));
523 ptr->map_from = from;
524
525 /* Make the real filename absolute. */
526 if (*to == '/')
527 ptr->map_to = to;
528 else
529 {
530 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
531 strcpy (ptr->map_to, dirname);
532 ptr->map_to[dirlen] = '/';
533 strcpy (ptr->map_to + dirlen + 1, to);
534 free (to);
535 }
536
537 ptr->map_next = map_list_ptr->map_list_map;
538 map_list_ptr->map_list_map = ptr;
539
540 while ((ch = getc (f)) != '\n')
541 if (ch == EOF)
542 break;
543 }
544 fclose (f);
545 }
546
547 map_list_ptr->map_list_next = CPP_OPTIONS (pfile)->map_list;
548 CPP_OPTIONS (pfile)->map_list = map_list_ptr;
549
550 return map_list_ptr->map_list_map;
551 }
552
553 /* Remap NAME based on the file_name_map (if any) for LOC. */
554
555 static char *
556 remap_filename (pfile, name, loc)
557 cpp_reader *pfile;
558 char *name;
559 struct file_name_list *loc;
560 {
561 struct file_name_map *map;
562 const char *from, *p, *dir;
563
564 if (! loc->name_map)
565 loc->name_map = read_name_map (pfile,
566 loc->name
567 ? loc->name : ".");
568
569 if (loc->name_map == (struct file_name_map *)-1)
570 return name;
571
572 from = name + strlen (loc->name) + 1;
573
574 for (map = loc->name_map; map; map = map->map_next)
575 if (!strcmp (map->map_from, from))
576 return map->map_to;
577
578 /* Try to find a mapping file for the particular directory we are
579 looking in. Thus #include <sys/types.h> will look up sys/types.h
580 in /usr/include/header.gcc and look up types.h in
581 /usr/include/sys/header.gcc. */
582 p = rindex (name, '/');
583 if (!p)
584 p = name;
585 if (loc && loc->name
586 && strlen (loc->name) == (size_t) (p - name)
587 && !strncmp (loc->name, name, p - name))
588 /* FILENAME is in SEARCHPTR, which we've already checked. */
589 return name;
590
591 if (p == name)
592 {
593 dir = ".";
594 from = name;
595 }
596 else
597 {
598 char * newdir = (char *) alloca (p - name + 1);
599 bcopy (name, newdir, p - name);
600 newdir[p - name] = '\0';
601 dir = newdir;
602 from = p + 1;
603 }
604
605 for (map = read_name_map (pfile, dir); map; map = map->map_next)
606 if (! strcmp (map->map_from, name))
607 return map->map_to;
608
609 return name;
610 }
611
612 /* Read the contents of FD into the buffer on the top of PFILE's stack.
613 IHASH points to the include hash entry for the file associated with
614 FD.
615
616 The caller is responsible for the cpp_push_buffer. */
617
618 int
619 finclude (pfile, fd, ihash)
620 cpp_reader *pfile;
621 int fd;
622 struct include_hash *ihash;
623 {
624 struct stat st;
625 size_t st_size;
626 long length;
627 cpp_buffer *fp;
628
629 if (fstat (fd, &st) < 0)
630 goto perror_fail;
631 if (fcntl (fd, F_SETFL, 0) == -1) /* turn off nonblocking mode */
632 goto perror_fail;
633
634 fp = CPP_BUFFER (pfile);
635
636 /* If fd points to a plain file, we know how big it is, so we can
637 allocate the buffer all at once. If fd is a pipe or terminal, we
638 can't. Most C source files are 4k or less, so we guess that. If
639 fd is something weird, like a block device or a directory, we
640 don't want to read it at all.
641
642 Unfortunately, different systems use different st.st_mode values
643 for pipes: some have S_ISFIFO, some S_ISSOCK, some are buggy and
644 zero the entire struct stat except a couple fields. Hence the
645 mess below.
646
647 In all cases, read_and_prescan will resize the buffer if it
648 turns out there's more data than we thought. */
649
650 if (S_ISREG (st.st_mode))
651 {
652 /* off_t might have a wider range than size_t - in other words,
653 the max size of a file might be bigger than the address
654 space. We can't handle a file that large. (Anyone with
655 a single source file bigger than 4GB needs to rethink
656 their coding style.) */
657 st_size = (size_t) st.st_size;
658 if ((unsigned HOST_WIDEST_INT) st_size
659 != (unsigned HOST_WIDEST_INT) st.st_size)
660 {
661 cpp_error (pfile, "file `%s' is too large", ihash->name);
662 goto fail;
663 }
664 }
665 else if (S_ISFIFO (st.st_mode) || S_ISSOCK (st.st_mode)
666 /* Permit any kind of character device: the sensible ones are
667 ttys and /dev/null, but weeding out the others is too hard. */
668 || S_ISCHR (st.st_mode)
669 /* Some 4.x (x<4) derivatives have a bug that makes fstat() of a
670 socket or pipe return a stat struct with most fields zeroed. */
671 || (st.st_mode == 0 && st.st_nlink == 0 && st.st_size == 0))
672 {
673 /* Cannot get its file size before reading. 4k is a decent
674 first guess. */
675 st_size = 4096;
676 }
677 else
678 {
679 cpp_error (pfile, "`%s' is not a file, pipe, or tty", ihash->name);
680 goto fail;
681 }
682
683 if (pfile->input_buffer == NULL)
684 initialize_input_buffer (pfile, fd, &st);
685
686 /* Read the file, converting end-of-line characters and trigraphs
687 (if enabled). */
688 fp->ihash = ihash;
689 fp->nominal_fname = fp->fname = ihash->name;
690 length = read_and_prescan (pfile, fp, fd, st_size);
691 if (length < 0)
692 goto fail;
693 if (length == 0)
694 ihash->control_macro = ""; /* never re-include */
695
696 close (fd);
697 fp->rlimit = fp->alimit = fp->buf + length;
698 fp->cur = fp->buf;
699 if (ihash->foundhere != ABSOLUTE_PATH)
700 fp->system_header_p = ihash->foundhere->sysp;
701 fp->lineno = 1;
702 fp->colno = 1;
703 fp->line_base = fp->buf;
704 fp->cleanup = file_cleanup;
705
706 /* The ->actual_dir field is only used when ignore_srcdir is not in effect;
707 see do_include */
708 if (!CPP_OPTIONS (pfile)->ignore_srcdir)
709 fp->actual_dir = actual_directory (pfile, fp->fname);
710
711 pfile->input_stack_listing_current = 0;
712 return 1;
713
714 perror_fail:
715 cpp_error_from_errno (pfile, ihash->name);
716 fail:
717 cpp_pop_buffer (pfile);
718 close (fd);
719 return 0;
720 }
721
722 /* Given a path FNAME, extract the directory component and place it
723 onto the actual_dirs list. Return a pointer to the allocated
724 file_name_list structure. These structures are used to implement
725 current-directory "" include searching. */
726
727 static struct file_name_list *
728 actual_directory (pfile, fname)
729 cpp_reader *pfile;
730 const char *fname;
731 {
732 char *last_slash, *dir;
733 size_t dlen;
734 struct file_name_list *x;
735
736 dir = xstrdup (fname);
737 last_slash = rindex (dir, '/');
738 if (last_slash)
739 {
740 if (last_slash == dir)
741 {
742 dlen = 1;
743 last_slash[1] = '\0';
744 }
745 else
746 {
747 dlen = last_slash - dir;
748 *last_slash = '\0';
749 }
750 }
751 else
752 {
753 dir[0] = '.';
754 dir[1] = '\0';
755 dlen = 1;
756 }
757
758 if (dlen > pfile->max_include_len)
759 pfile->max_include_len = dlen;
760
761 for (x = pfile->actual_dirs; x; x = x->alloc)
762 if (!strcmp (x->name, dir))
763 {
764 free (dir);
765 return x;
766 }
767
768 /* Not found, make a new one. */
769 x = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
770 x->name = dir;
771 x->nlen = dlen;
772 x->next = CPP_OPTIONS (pfile)->quote_include;
773 x->alloc = pfile->actual_dirs;
774 x->sysp = CPP_BUFFER (pfile)->system_header_p;
775 x->name_map = NULL;
776
777 pfile->actual_dirs = x;
778 return x;
779 }
780
781 /* Determine the current line and column. Used only by read_and_prescan. */
782 static U_CHAR *
783 find_position (start, limit, linep)
784 U_CHAR *start;
785 U_CHAR *limit;
786 unsigned long *linep;
787 {
788 unsigned long line = *linep;
789 U_CHAR *lbase = start;
790 while (start < limit)
791 {
792 U_CHAR ch = *start++;
793 if (ch == '\n' || ch == '\r')
794 {
795 line++;
796 lbase = start;
797 }
798 }
799 *linep = line;
800 return lbase;
801 }
802
803 /* Read the entire contents of file DESC into buffer BUF. LEN is how
804 much memory to allocate initially; more will be allocated if
805 necessary. Convert end-of-line markers (\n, \r, \r\n, \n\r) to
806 canonical form (\n). If enabled, convert and/or warn about
807 trigraphs. Convert backslash-newline to a one-character escape
808 (\r) and remove it from "embarrassing" places (i.e. the middle of a
809 token). If there is no newline at the end of the file, add one and
810 warn. Returns -1 on failure, or the actual length of the data to
811 be scanned.
812
813 This function does a lot of work, and can be a serious performance
814 bottleneck. It has been tuned heavily; make sure you understand it
815 before hacking. The common case - no trigraphs, Unix style line
816 breaks, backslash-newline set off by whitespace, newline at EOF -
817 has been optimized at the expense of the others. The performance
818 penalty for DOS style line breaks (\r\n) is about 15%.
819
820 Warnings lose particularly heavily since we have to determine the
821 line number, which involves scanning from the beginning of the file
822 or from the last warning. The penalty for the absence of a newline
823 at the end of reload1.c is about 60%. (reload1.c is 329k.)
824
825 If your file has more than one kind of end-of-line marker, you
826 will get messed-up line numbering. */
827
828 /* Table of characters that can't be handled in the inner loop.
829 Keep these contiguous to optimize the performance of the code generated
830 for the switch that uses them. */
831 #define SPECCASE_EMPTY 0
832 #define SPECCASE_NUL 1
833 #define SPECCASE_CR 2
834 #define SPECCASE_BACKSLASH 3
835 #define SPECCASE_QUESTION 4
836
837 static long
838 read_and_prescan (pfile, fp, desc, len)
839 cpp_reader *pfile;
840 cpp_buffer *fp;
841 int desc;
842 size_t len;
843 {
844 U_CHAR *buf = (U_CHAR *) xmalloc (len);
845 U_CHAR *ip, *op, *line_base;
846 U_CHAR *ibase;
847 U_CHAR *speccase = pfile->input_speccase;
848 unsigned long line;
849 unsigned int deferred_newlines;
850 int count;
851 size_t offset;
852
853 offset = 0;
854 op = buf;
855 line_base = buf;
856 line = 1;
857 ibase = pfile->input_buffer + 2;
858 deferred_newlines = 0;
859
860 for (;;)
861 {
862 read_next:
863
864 count = read (desc, pfile->input_buffer + 2, pfile->input_buffer_len);
865 if (count < 0)
866 goto error;
867 else if (count == 0)
868 break;
869
870 offset += count;
871 ip = ibase;
872 ibase = pfile->input_buffer + 2;
873 ibase[count] = ibase[count+1] = '\0';
874
875 if (offset > len)
876 {
877 size_t delta_op;
878 size_t delta_line_base;
879 len *= 2;
880 if (offset > len)
881 /* len overflowed.
882 This could happen if the file is larger than half the
883 maximum address space of the machine. */
884 goto too_big;
885
886 delta_op = op - buf;
887 delta_line_base = line_base - buf;
888 buf = (U_CHAR *) xrealloc (buf, len);
889 op = buf + delta_op;
890 line_base = buf + delta_line_base;
891 }
892
893 for (;;)
894 {
895 unsigned int span = 0;
896
897 /* Deal with \-newline in the middle of a token. */
898 if (deferred_newlines)
899 {
900 while (speccase[ip[span]] == SPECCASE_EMPTY
901 && ip[span] != '\n'
902 && ip[span] != '\t'
903 && ip[span] != ' ')
904 span++;
905 memcpy (op, ip, span);
906 op += span;
907 ip += span;
908 /* If ip[0] is SPECCASE_EMPTY, we have hit white space.
909 Dump out the remaining deferred \-newlines. */
910 if (speccase[ip[0]] == SPECCASE_EMPTY)
911 while (deferred_newlines)
912 deferred_newlines--, *op++ = '\r';
913 span = 0;
914 }
915
916 /* Copy as much as we can without special treatment. */
917 while (speccase[ip[span]] == SPECCASE_EMPTY) span++;
918 memcpy (op, ip, span);
919 op += span;
920 ip += span;
921
922 switch (speccase[*ip++])
923 {
924 case SPECCASE_NUL: /* \0 */
925 ibase[-1] = op[-1];
926 goto read_next;
927
928 case SPECCASE_CR: /* \r */
929 if (ip[-2] == '\n')
930 continue;
931 else if (*ip == '\n')
932 ip++;
933 else if (*ip == '\0')
934 {
935 *--ibase = '\r';
936 goto read_next;
937 }
938 *op++ = '\n';
939 break;
940
941 case SPECCASE_BACKSLASH: /* \ */
942 backslash:
943 {
944 /* If we're at the end of the intermediate buffer,
945 we have to shift the backslash down to the start
946 and come back next pass. */
947 if (*ip == '\0')
948 {
949 *--ibase = '\\';
950 goto read_next;
951 }
952 else if (*ip == '\n')
953 {
954 ip++;
955 if (*ip == '\r') ip++;
956 if (*ip == '\n' || *ip == '\t' || *ip == ' ')
957 *op++ = '\r';
958 else if (op[-1] == '\t' || op[-1] == ' '
959 || op[-1] == '\r' || op[-1] == '\n')
960 *op++ = '\r';
961 else
962 deferred_newlines++;
963 }
964 else if (*ip == '\r')
965 {
966 ip++;
967 if (*ip == '\n') ip++;
968 else if (*ip == '\0')
969 {
970 *--ibase = '\r';
971 *--ibase = '\\';
972 goto read_next;
973 }
974 else if (*ip == '\r' || *ip == '\t' || *ip == ' ')
975 *op++ = '\r';
976 else
977 deferred_newlines++;
978 }
979 else
980 *op++ = '\\';
981 }
982 break;
983
984 case SPECCASE_QUESTION: /* ? */
985 {
986 unsigned int d, t;
987 /* If we're at the end of the intermediate buffer,
988 we have to shift the ?'s down to the start and
989 come back next pass. */
990 d = ip[0];
991 if (d == '\0')
992 {
993 *--ibase = '?';
994 goto read_next;
995 }
996 if (d != '?')
997 {
998 *op++ = '?';
999 break;
1000 }
1001 d = ip[1];
1002 if (d == '\0')
1003 {
1004 *--ibase = '?';
1005 *--ibase = '?';
1006 goto read_next;
1007 }
1008
1009 /* Trigraph map:
1010 * from to from to from to
1011 * ?? = # ?? ) ] ?? ! |
1012 * ?? ( [ ?? ' ^ ?? > }
1013 * ?? / \ ?? < { ?? - ~
1014 */
1015 if (d == '=') t = '#';
1016 else if (d == ')') t = ']';
1017 else if (d == '!') t = '|';
1018 else if (d == '(') t = '[';
1019 else if (d == '\'') t = '^';
1020 else if (d == '>') t = '}';
1021 else if (d == '/') t = '\\';
1022 else if (d == '<') t = '{';
1023 else if (d == '-') t = '~';
1024 else
1025 {
1026 *op++ = '?';
1027 break;
1028 }
1029 ip += 2;
1030 if (CPP_OPTIONS (pfile)->warn_trigraphs)
1031 {
1032 unsigned long col;
1033 line_base = find_position (line_base, op, &line);
1034 col = op - line_base + 1;
1035 if (CPP_OPTIONS (pfile)->trigraphs)
1036 cpp_warning_with_line (pfile, line, col,
1037 "trigraph ??%c converted to %c", d, t);
1038 else
1039 cpp_warning_with_line (pfile, line, col,
1040 "trigraph ??%c ignored", d);
1041 }
1042 if (CPP_OPTIONS (pfile)->trigraphs)
1043 {
1044 if (t == '\\')
1045 goto backslash;
1046 else
1047 *op++ = t;
1048 }
1049 else
1050 {
1051 *op++ = '?';
1052 *op++ = '?';
1053 *op++ = d;
1054 }
1055 }
1056 }
1057 }
1058 }
1059
1060 if (offset == 0)
1061 return 0;
1062
1063 /* Deal with pushed-back chars at true EOF.
1064 This may be any of: ?? ? \ \r \n \\r \\n.
1065 \r must become \n, \\r or \\n must become \r.
1066 We know we have space already. */
1067 if (ibase == pfile->input_buffer)
1068 {
1069 if (*ibase == '?')
1070 {
1071 *op++ = '?';
1072 *op++ = '?';
1073 }
1074 else
1075 *op++ = '\r';
1076 }
1077 else if (ibase == pfile->input_buffer + 1)
1078 {
1079 if (*ibase == '\r')
1080 *op++ = '\n';
1081 else
1082 *op++ = *ibase;
1083 }
1084
1085 if (op[-1] != '\n')
1086 {
1087 unsigned long col;
1088 line_base = find_position (line_base, op, &line);
1089 col = op - line_base + 1;
1090 cpp_warning_with_line (pfile, line, col, "no newline at end of file\n");
1091 if (offset + 1 > len)
1092 {
1093 len += 1;
1094 if (offset + 1 > len)
1095 goto too_big;
1096 buf = (U_CHAR *) xrealloc (buf, len);
1097 op = buf + offset;
1098 }
1099 *op++ = '\n';
1100 }
1101
1102 fp->buf = ((len - offset < 20) ? buf : (U_CHAR *)xrealloc (buf, op - buf));
1103 return op - buf;
1104
1105 too_big:
1106 cpp_error (pfile, "file is too large (>%lu bytes)\n", (unsigned long)offset);
1107 free (buf);
1108 return -1;
1109
1110 error:
1111 cpp_error_from_errno (pfile, fp->fname);
1112 free (buf);
1113 return -1;
1114 }
1115
1116 /* Initialize the `input_buffer' and `input_speccase' tables.
1117 These are only used by read_and_prescan, but they're large and
1118 somewhat expensive to set up, so we want them allocated once for
1119 the duration of the cpp run. */
1120
1121 static void
1122 initialize_input_buffer (pfile, fd, st)
1123 cpp_reader *pfile;
1124 int fd;
1125 struct stat *st;
1126 {
1127 long pipe_buf;
1128 U_CHAR *tmp;
1129
1130 /* Table of characters that cannot be handled by the
1131 read_and_prescan inner loop. The number of non-EMPTY entries
1132 should be as small as humanly possible. */
1133
1134 tmp = (U_CHAR *) xmalloc (1 << CHAR_BIT);
1135 memset (tmp, SPECCASE_EMPTY, 1 << CHAR_BIT);
1136 tmp['\0'] = SPECCASE_NUL;
1137 tmp['\r'] = SPECCASE_CR;
1138 tmp['\\'] = SPECCASE_BACKSLASH;
1139 if (CPP_OPTIONS (pfile)->trigraphs || CPP_OPTIONS (pfile)->warn_trigraphs)
1140 tmp['?'] = SPECCASE_QUESTION;
1141
1142 pfile->input_speccase = tmp;
1143
1144 /* Determine the appropriate size for the input buffer. Normal C
1145 source files are smaller than eight K. If we are reading a pipe,
1146 we want to make sure the input buffer is bigger than the kernel's
1147 pipe buffer. */
1148 pipe_buf = -1;
1149
1150 if (! S_ISREG (st->st_mode))
1151 {
1152 #ifdef _PC_PIPE_BUF
1153 pipe_buf = fpathconf (fd, _PC_PIPE_BUF);
1154 #endif
1155 if (pipe_buf == -1)
1156 {
1157 #ifdef PIPE_BUF
1158 pipe_buf = PIPE_BUF;
1159 #else
1160 pipe_buf = 8192;
1161 #endif
1162 }
1163 }
1164
1165 if (pipe_buf < 8192)
1166 pipe_buf = 8192;
1167 /* PIPE_BUF bytes of buffer proper, 2 to detect running off the end
1168 without address arithmetic all the time, and 2 for pushback in
1169 the case there's a potential trigraph or end-of-line digraph at
1170 the end of a block. */
1171
1172 tmp = (U_CHAR *) xmalloc (pipe_buf + 2 + 2);
1173 pfile->input_buffer = tmp;
1174 pfile->input_buffer_len = pipe_buf;
1175 }
1176
1177 /* Add output to `deps_buffer' for the -M switch.
1178 STRING points to the text to be output.
1179 SPACER is ':' for targets, ' ' for dependencies, zero for text
1180 to be inserted literally. */
1181
1182 void
1183 deps_output (pfile, string, spacer)
1184 cpp_reader *pfile;
1185 const char *string;
1186 int spacer;
1187 {
1188 int size;
1189 int cr = 0;
1190
1191 if (!*string)
1192 return;
1193
1194 size = strlen (string);
1195
1196 #ifndef MAX_OUTPUT_COLUMNS
1197 #define MAX_OUTPUT_COLUMNS 72
1198 #endif
1199 if (pfile->deps_column > 0
1200 && (pfile->deps_column + size) > MAX_OUTPUT_COLUMNS)
1201 {
1202 cr = 5;
1203 pfile->deps_column = 0;
1204 }
1205
1206 if (pfile->deps_size + size + cr + 8 > pfile->deps_allocated_size)
1207 {
1208 pfile->deps_allocated_size = (pfile->deps_size + size + 50) * 2;
1209 pfile->deps_buffer = (char *) xrealloc (pfile->deps_buffer,
1210 pfile->deps_allocated_size);
1211 }
1212
1213 if (cr)
1214 {
1215 bcopy (" \\\n ", &pfile->deps_buffer[pfile->deps_size], 5);
1216 pfile->deps_size += 5;
1217 }
1218
1219 if (spacer == ' ' && pfile->deps_column > 0)
1220 pfile->deps_buffer[pfile->deps_size++] = ' ';
1221 bcopy (string, &pfile->deps_buffer[pfile->deps_size], size);
1222 pfile->deps_size += size;
1223 pfile->deps_column += size + 1; /* count spacer too */
1224 if (spacer == ':')
1225 pfile->deps_buffer[pfile->deps_size++] = ':';
1226 pfile->deps_buffer[pfile->deps_size] = 0;
1227 }
1228
1229 /* Simplify a path name in place, deleting redundant components. This
1230 reduces OS overhead and guarantees that equivalent paths compare
1231 the same (modulo symlinks).
1232
1233 Transforms made:
1234 foo/bar/../quux foo/quux
1235 foo/./bar foo/bar
1236 foo//bar foo/bar
1237 /../quux /quux
1238 //quux //quux (POSIX allows leading // as a namespace escape)
1239
1240 Guarantees no trailing slashes. All transforms reduce the length
1241 of the string.
1242 */
1243 void
1244 simplify_pathname (path)
1245 char *path;
1246 {
1247 char *from, *to;
1248 char *base;
1249 int absolute = 0;
1250
1251 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
1252 /* Convert all backslashes to slashes. */
1253 for (from = path; *from; from++)
1254 if (*from == '\\') *from = '/';
1255
1256 /* Skip over leading drive letter if present. */
1257 if (ISALPHA (path[0]) && path[1] == ':')
1258 from = to = &path[2];
1259 else
1260 from = to = path;
1261 #else
1262 from = to = path;
1263 #endif
1264
1265 /* Remove redundant initial /s. */
1266 if (*from == '/')
1267 {
1268 absolute = 1;
1269 to++;
1270 from++;
1271 if (*from == '/')
1272 {
1273 if (*++from == '/')
1274 /* 3 or more initial /s are equivalent to 1 /. */
1275 while (*++from == '/');
1276 else
1277 /* On some hosts // differs from /; Posix allows this. */
1278 to++;
1279 }
1280 }
1281 base = to;
1282
1283 for (;;)
1284 {
1285 while (*from == '/')
1286 from++;
1287
1288 if (from[0] == '.' && from[1] == '/')
1289 from += 2;
1290 else if (from[0] == '.' && from[1] == '\0')
1291 goto done;
1292 else if (from[0] == '.' && from[1] == '.' && from[2] == '/')
1293 {
1294 if (base == to)
1295 {
1296 if (absolute)
1297 from += 3;
1298 else
1299 {
1300 *to++ = *from++;
1301 *to++ = *from++;
1302 *to++ = *from++;
1303 base = to;
1304 }
1305 }
1306 else
1307 {
1308 to -= 2;
1309 while (to > base && *to != '/') to--;
1310 if (*to == '/')
1311 to++;
1312 from += 3;
1313 }
1314 }
1315 else if (from[0] == '.' && from[1] == '.' && from[2] == '\0')
1316 {
1317 if (base == to)
1318 {
1319 if (!absolute)
1320 {
1321 *to++ = *from++;
1322 *to++ = *from++;
1323 }
1324 }
1325 else
1326 {
1327 to -= 2;
1328 while (to > base && *to != '/') to--;
1329 if (*to == '/')
1330 to++;
1331 }
1332 goto done;
1333 }
1334 else
1335 /* Copy this component and trailing /, if any. */
1336 while ((*to++ = *from++) != '/')
1337 {
1338 if (!to[-1])
1339 {
1340 to--;
1341 goto done;
1342 }
1343 }
1344
1345 }
1346
1347 done:
1348 /* Trim trailing slash */
1349 if (to[0] == '/' && (!absolute || to > path+1))
1350 to--;
1351
1352 /* Change the empty string to "." so that stat() on the result
1353 will always work. */
1354 if (to == path)
1355 *to++ = '.';
1356
1357 *to = '\0';
1358
1359 return;
1360 }
1361
1362 /* It is not clear when this should be used if at all, so I've
1363 disabled it until someone who understands VMS can look at it. */
1364 #if 0
1365
1366 /* Under VMS we need to fix up the "include" specification filename.
1367
1368 Rules for possible conversions
1369
1370 fullname tried paths
1371
1372 name name
1373 ./dir/name [.dir]name
1374 /dir/name dir:name
1375 /name [000000]name, name
1376 dir/name dir:[000000]name, dir:name, dir/name
1377 dir1/dir2/name dir1:[dir2]name, dir1:[000000.dir2]name
1378 path:/name path:[000000]name, path:name
1379 path:/dir/name path:[000000.dir]name, path:[dir]name
1380 path:dir/name path:[dir]name
1381 [path]:[dir]name [path.dir]name
1382 path/[dir]name [path.dir]name
1383
1384 The path:/name input is constructed when expanding <> includes. */
1385
1386
1387 static void
1388 hack_vms_include_specification (fullname)
1389 char *fullname;
1390 {
1391 register char *basename, *unixname, *local_ptr, *first_slash;
1392 int f, check_filename_before_returning, must_revert;
1393 char Local[512];
1394
1395 check_filename_before_returning = 0;
1396 must_revert = 0;
1397 /* See if we can find a 1st slash. If not, there's no path information. */
1398 first_slash = index (fullname, '/');
1399 if (first_slash == 0)
1400 return 0; /* Nothing to do!!! */
1401
1402 /* construct device spec if none given. */
1403
1404 if (index (fullname, ':') == 0)
1405 {
1406
1407 /* If fullname has a slash, take it as device spec. */
1408
1409 if (first_slash == fullname)
1410 {
1411 first_slash = index (fullname+1, '/'); /* 2nd slash ? */
1412 if (first_slash)
1413 *first_slash = ':'; /* make device spec */
1414 for (basename = fullname; *basename != 0; basename++)
1415 *basename = *(basename+1); /* remove leading slash */
1416 }
1417 else if ((first_slash[-1] != '.') /* keep ':/', './' */
1418 && (first_slash[-1] != ':')
1419 && (first_slash[-1] != ']')) /* or a vms path */
1420 {
1421 *first_slash = ':';
1422 }
1423 else if ((first_slash[1] == '[') /* skip './' in './[dir' */
1424 && (first_slash[-1] == '.'))
1425 fullname += 2;
1426 }
1427
1428 /* Get part after first ':' (basename[-1] == ':')
1429 or last '/' (basename[-1] == '/'). */
1430
1431 basename = base_name (fullname);
1432
1433 local_ptr = Local; /* initialize */
1434
1435 /* We are trying to do a number of things here. First of all, we are
1436 trying to hammer the filenames into a standard format, such that later
1437 processing can handle them.
1438
1439 If the file name contains something like [dir.], then it recognizes this
1440 as a root, and strips the ".]". Later processing will add whatever is
1441 needed to get things working properly.
1442
1443 If no device is specified, then the first directory name is taken to be
1444 a device name (or a rooted logical). */
1445
1446 /* Point to the UNIX filename part (which needs to be fixed!)
1447 but skip vms path information.
1448 [basename != fullname since first_slash != 0]. */
1449
1450 if ((basename[-1] == ':') /* vms path spec. */
1451 || (basename[-1] == ']')
1452 || (basename[-1] == '>'))
1453 unixname = basename;
1454 else
1455 unixname = fullname;
1456
1457 if (*unixname == '/')
1458 unixname++;
1459
1460 /* If the directory spec is not rooted, we can just copy
1461 the UNIX filename part and we are done. */
1462
1463 if (((basename - fullname) > 1)
1464 && ( (basename[-1] == ']')
1465 || (basename[-1] == '>')))
1466 {
1467 if (basename[-2] != '.')
1468 {
1469
1470 /* The VMS part ends in a `]', and the preceding character is not a `.'.
1471 -> PATH]:/name (basename = '/name', unixname = 'name')
1472 We strip the `]', and then splice the two parts of the name in the
1473 usual way. Given the default locations for include files in cccp.c,
1474 we will only use this code if the user specifies alternate locations
1475 with the /include (-I) switch on the command line. */
1476
1477 basename -= 1; /* Strip "]" */
1478 unixname--; /* backspace */
1479 }
1480 else
1481 {
1482
1483 /* The VMS part has a ".]" at the end, and this will not do. Later
1484 processing will add a second directory spec, and this would be a syntax
1485 error. Thus we strip the ".]", and thus merge the directory specs.
1486 We also backspace unixname, so that it points to a '/'. This inhibits the
1487 generation of the 000000 root directory spec (which does not belong here
1488 in this case). */
1489
1490 basename -= 2; /* Strip ".]" */
1491 unixname--; /* backspace */
1492 }
1493 }
1494
1495 else
1496
1497 {
1498
1499 /* We drop in here if there is no VMS style directory specification yet.
1500 If there is no device specification either, we make the first dir a
1501 device and try that. If we do not do this, then we will be essentially
1502 searching the users default directory (as if they did a #include "asdf.h").
1503
1504 Then all we need to do is to push a '[' into the output string. Later
1505 processing will fill this in, and close the bracket. */
1506
1507 if ((unixname != fullname) /* vms path spec found. */
1508 && (basename[-1] != ':'))
1509 *local_ptr++ = ':'; /* dev not in spec. take first dir */
1510
1511 *local_ptr++ = '['; /* Open the directory specification */
1512 }
1513
1514 if (unixname == fullname) /* no vms dir spec. */
1515 {
1516 must_revert = 1;
1517 if ((first_slash != 0) /* unix dir spec. */
1518 && (*unixname != '/') /* not beginning with '/' */
1519 && (*unixname != '.')) /* or './' or '../' */
1520 *local_ptr++ = '.'; /* dir is local ! */
1521 }
1522
1523 /* at this point we assume that we have the device spec, and (at least
1524 the opening "[" for a directory specification. We may have directories
1525 specified already.
1526
1527 If there are no other slashes then the filename will be
1528 in the "root" directory. Otherwise, we need to add
1529 directory specifications. */
1530
1531 if (index (unixname, '/') == 0)
1532 {
1533 /* if no directories specified yet and none are following. */
1534 if (local_ptr[-1] == '[')
1535 {
1536 /* Just add "000000]" as the directory string */
1537 strcpy (local_ptr, "000000]");
1538 local_ptr += strlen (local_ptr);
1539 check_filename_before_returning = 1; /* we might need to fool with this later */
1540 }
1541 }
1542 else
1543 {
1544
1545 /* As long as there are still subdirectories to add, do them. */
1546 while (index (unixname, '/') != 0)
1547 {
1548 /* If this token is "." we can ignore it
1549 if it's not at the beginning of a path. */
1550 if ((unixname[0] == '.') && (unixname[1] == '/'))
1551 {
1552 /* remove it at beginning of path. */
1553 if ( ((unixname == fullname) /* no device spec */
1554 && (fullname+2 != basename)) /* starts with ./ */
1555 /* or */
1556 || ((basename[-1] == ':') /* device spec */
1557 && (unixname-1 == basename))) /* and ./ afterwards */
1558 *local_ptr++ = '.'; /* make '[.' start of path. */
1559 unixname += 2;
1560 continue;
1561 }
1562
1563 /* Add a subdirectory spec. Do not duplicate "." */
1564 if ( local_ptr[-1] != '.'
1565 && local_ptr[-1] != '['
1566 && local_ptr[-1] != '<')
1567 *local_ptr++ = '.';
1568
1569 /* If this is ".." then the spec becomes "-" */
1570 if ( (unixname[0] == '.')
1571 && (unixname[1] == '.')
1572 && (unixname[2] == '/'))
1573 {
1574 /* Add "-" and skip the ".." */
1575 if ((local_ptr[-1] == '.')
1576 && (local_ptr[-2] == '['))
1577 local_ptr--; /* prevent [.- */
1578 *local_ptr++ = '-';
1579 unixname += 3;
1580 continue;
1581 }
1582
1583 /* Copy the subdirectory */
1584 while (*unixname != '/')
1585 *local_ptr++= *unixname++;
1586
1587 unixname++; /* Skip the "/" */
1588 }
1589
1590 /* Close the directory specification */
1591 if (local_ptr[-1] == '.') /* no trailing periods */
1592 local_ptr--;
1593
1594 if (local_ptr[-1] == '[') /* no dir needed */
1595 local_ptr--;
1596 else
1597 *local_ptr++ = ']';
1598 }
1599
1600 /* Now add the filename. */
1601
1602 while (*unixname)
1603 *local_ptr++ = *unixname++;
1604 *local_ptr = 0;
1605
1606 /* Now append it to the original VMS spec. */
1607
1608 strcpy ((must_revert==1)?fullname:basename, Local);
1609
1610 /* If we put a [000000] in the filename, try to open it first. If this fails,
1611 remove the [000000], and return that name. This provides flexibility
1612 to the user in that they can use both rooted and non-rooted logical names
1613 to point to the location of the file. */
1614
1615 if (check_filename_before_returning)
1616 {
1617 f = open (fullname, O_RDONLY, 0666);
1618 if (f >= 0)
1619 {
1620 /* The file name is OK as it is, so return it as is. */
1621 close (f);
1622 return 1;
1623 }
1624
1625 /* The filename did not work. Try to remove the [000000] from the name,
1626 and return it. */
1627
1628 basename = index (fullname, '[');
1629 local_ptr = index (fullname, ']') + 1;
1630 strcpy (basename, local_ptr); /* this gets rid of it */
1631
1632 }
1633
1634 return 1;
1635 }
1636 #endif /* VMS */