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