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