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