cppfiles.c 36.5 KB
Newer Older
Zack Weinberg committed
1
/* Part of CPP library.  (include file handling)
Jeff Law committed
2 3
   Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998,
   1999, 2000 Free Software Foundation, Inc.
Zack Weinberg committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   Written by Per Bothner, 1994.
   Based on CCCP program by Paul Rubin, June 1986
   Adapted to ANSI C, Richard Stallman, Jan 1987
   Split out of cpplib.c, Zack Weinberg, Oct 1998

This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
21
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
Zack Weinberg committed
22 23 24 25

#include "config.h"
#include "system.h"
#include "cpplib.h"
26
#include "cpphash.h"
27
#include "intl.h"
28
#include "mkdeps.h"
29
#include "splay-tree.h"
Zack Weinberg committed
30

31 32 33 34 35 36 37 38 39 40 41
#ifdef HAVE_MMAP_FILE
# include <sys/mman.h>
# ifndef MMAP_THRESHOLD
#  define MMAP_THRESHOLD 3 /* Minimum page count to mmap the file.  */
# endif

#else  /* No MMAP_FILE */
#  undef MMAP_THRESHOLD
#  define MMAP_THRESHOLD 0
#endif

Zack Weinberg committed
42 43 44 45
#ifndef O_BINARY
# define O_BINARY 0
#endif

46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
#ifndef INCLUDE_LEN_FUDGE
# define INCLUDE_LEN_FUDGE 0
#endif

/* If errno is inspected immediately after a system call fails, it will be
   nonzero, and no error number will ever be zero.  */
#ifndef ENOENT
# define ENOENT 0
#endif
#ifndef ENOTDIR
# define ENOTDIR 0
#endif
#ifndef ENOMEM
# define ENOMEM 0
#endif

62 63 64 65
/* Suppress warning about function macros used w/o arguments in traditional
   C.  It is unlikely that glibc's strcmp macro helps this file at all.  */
#undef strcmp

66
static struct file_name_map *read_name_map
67 68 69 70
				PARAMS ((cpp_reader *, const char *));
static char *read_filename_string PARAMS ((int, FILE *));
static char *remap_filename 	PARAMS ((cpp_reader *, char *,
					 struct file_name_list *));
71
static struct file_name_list *actual_directory
72
				PARAMS ((cpp_reader *, const char *));
73 74 75
static struct include_file *find_include_file
				PARAMS ((cpp_reader *, const char *,
					 struct file_name_list *));
76
static struct include_file *open_file PARAMS ((cpp_reader *, const char *));
77
static int read_include_file	PARAMS ((cpp_reader *, struct include_file *));
78 79
static int stack_include_file	PARAMS ((cpp_reader *, struct include_file *));
static void purge_cache 	PARAMS ((struct include_file *));
80
static void destroy_include_file_node	PARAMS ((splay_tree_value));
81
static int report_missing_guard		PARAMS ((splay_tree_node, void *));
82

83
#if 0
84
static void hack_vms_include_specification PARAMS ((char *));
85
#endif
Zack Weinberg committed
86

87 88 89 90
/* We use a splay tree to store information about all the include
   files seen in this compilation.  The key of each tree node is the
   physical path to the file.  The value is 0 if the file does not
   exist, or a struct include_file pointer.  */
Zack Weinberg committed
91

92 93 94
static void
destroy_include_file_node (v)
     splay_tree_value v;
95
{
96 97 98
  struct include_file *f = (struct include_file *)v;
  if (f)
    {
99
      purge_cache (f);
100
      free (f);  /* The tree is registered with free to free f->name.  */
101
    }
102
}
Zack Weinberg committed
103

104
void
105
_cpp_init_includes (pfile)
106 107 108
     cpp_reader *pfile;
{
  pfile->all_include_files
109 110 111
    = splay_tree_new ((splay_tree_compare_fn) strcmp,
		      (splay_tree_delete_key_fn) free,
		      destroy_include_file_node);
112
}
Zack Weinberg committed
113

114 115 116 117 118 119 120
void
_cpp_cleanup_includes (pfile)
     cpp_reader *pfile;
{
  splay_tree_delete (pfile->all_include_files);
}

121
/* Given a file name, look it up in the cache; if there is no entry,
122 123 124 125 126 127 128
   create one with a non-NULL value (regardless of success in opening
   the file).  If the file doesn't exist or is inaccessible, this
   entry is flagged so we don't attempt to open it again in the
   future.  If the file isn't open, open it.

   Returns an include_file structure with an open file descriptor on
   success, or NULL on failure.  */
Zack Weinberg committed
129

130
static struct include_file *
131
open_file (pfile, filename)
132 133
     cpp_reader *pfile;
     const char *filename;
134
{
135
  splay_tree_node nd;
136
  struct include_file *file;
Zack Weinberg committed
137

138
  nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) filename);
Zack Weinberg committed
139

140
  if (nd)
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
    {
      file = (struct include_file *) nd->value;

      /* Don't retry opening if we failed previously.  */
      if (file->fd == -2)
	return 0;

      /* -1 indicates a file we've opened previously, and since closed.  */
      if (file->fd != -1)
	return file;
    }
  else
    {
      file = xcnew (struct include_file);
      file->name = xstrdup (filename);
      splay_tree_insert (pfile->all_include_files,
			 (splay_tree_key) file->name,
			 (splay_tree_value) file);
    }
Zack Weinberg committed
160

161 162 163 164
  /* We used to open files in nonblocking mode, but that caused more
     problems than it solved.  Do take care not to acquire a
     controlling terminal by mistake (this can't happen on sane
     systems, but paranoia is a virtue).
Zack Weinberg committed
165

166 167
     Use the three-argument form of open even though we aren't
     specifying O_CREAT, to defend against broken system headers.
Zack Weinberg committed
168

169 170 171
     O_BINARY tells some runtime libraries (notably DJGPP) not to do
     newline translation; we can handle DOS line breaks just fine
     ourselves.
172

173
     Special case: the empty string is translated to stdin.  */
174

175
  if (filename[0] == '\0')
176
    file->fd = 0;
177
  else
178
    file->fd = open (filename, O_RDONLY | O_NOCTTY | O_BINARY, 0666);
179

180 181 182 183 184
  if (file->fd != -1 && fstat (file->fd, &file->st) == 0)
    {
      /* Mark a regular, zero-length file never-reread now.  */
      if (S_ISREG (file->st.st_mode) && file->st.st_size == 0)
	file->cmacro = NEVER_REREAD;
185

186 187
      return file;
    }
188 189 190 191 192

  /* Don't issue an error message if the file doesn't exist.  */
  if (errno != ENOENT && errno != ENOTDIR)
    cpp_error_from_errno (pfile, filename);

193 194 195
  /* Create a negative node for this path, and return null.  */
  file->fd = -2;

196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
  return 0;
}

/* Place the file referenced by INC into a new buffer on PFILE's stack.
   Return 1 if successful, 0 if not.  */

static int
stack_include_file (pfile, inc)
     cpp_reader *pfile;
     struct include_file *inc;
{
  cpp_buffer *fp;

  if (DO_NOT_REREAD (inc))
    return 0;

  if (inc->buffer == NULL)
    if (read_include_file (pfile, inc) == 0)
      return 0;

  fp = cpp_push_buffer (pfile, NULL, 0);
  if (fp == 0)
    return 0;

  fp->inc = inc;
  fp->nominal_fname = inc->name;
  fp->buf = inc->buffer;
  fp->rlimit = fp->buf + inc->st.st_size;
  fp->cur = fp->buf;
  fp->lineno = 1;
  fp->line_base = fp->buf;

  /* The ->actual_dir field is only used when ignore_srcdir is not in effect;
     see do_include */
  if (!CPP_OPTION (pfile, ignore_srcdir))
    fp->actual_dir = actual_directory (pfile, inc->name);

  fp->inc->refcnt++;
  pfile->include_depth++;
  pfile->input_stack_listing_current = 0;
  if (pfile->cb.enter_file)
    (*pfile->cb.enter_file) (pfile);
  return 1;
}

/* Read the file referenced by INC into the file cache.

   If fd points to a plain file, we might be able to mmap it; we can
   definitely allocate the buffer all at once.  If fd is a pipe or
   terminal, we can't do either.  If fd is something weird, like a
   block device or a directory, we don't want to read it at all.

   Unfortunately, different systems use different st.st_mode values
   for pipes: some have S_ISFIFO, some S_ISSOCK, some are buggy and
   zero the entire struct stat except a couple fields.  Hence we don't
   even try to figure out what something is, except for plain files,
   directories, and block devices.

   FIXME: Flush file cache and try again if we run out of memory.  */

static int
read_include_file (pfile, inc)
     cpp_reader *pfile;
     struct include_file *inc;
{
  ssize_t size, offset, count;
  U_CHAR *buf;
#if MMAP_THRESHOLD
  static int pagesize = -1;
#endif

  if (S_ISREG (inc->st.st_mode))
268
    {
269 270 271 272 273 274 275 276 277
      /* off_t might have a wider range than ssize_t - in other words,
	 the max size of a file might be bigger than the address
	 space.  We can't handle a file that large.  (Anyone with
	 a single source file bigger than 2GB needs to rethink
	 their coding style.)  Some systems (e.g. AIX 4.1) define
	 SSIZE_MAX to be much smaller than the actual range of the
	 type.  Use INTTYPE_MAXIMUM unconditionally to ensure this
	 does not bite us.  */
      if (inc->st.st_size > INTTYPE_MAXIMUM (ssize_t))
278
	{
279 280
	  cpp_error (pfile, "%s is too large", inc->name);
	  goto fail;
281
	}
282 283
      size = inc->st.st_size;

284
      inc->mapped = 0;
285 286 287 288 289 290 291 292 293 294 295 296
#if MMAP_THRESHOLD
      if (pagesize == -1)
	pagesize = getpagesize ();

      if (size / pagesize >= MMAP_THRESHOLD)
	{
	  buf = (U_CHAR *) mmap (0, size, PROT_READ, MAP_PRIVATE, inc->fd, 0);
	  if (buf == (U_CHAR *)-1)
	    goto perror_fail;
	  inc->mapped = 1;
	}
      else
297
#endif
298
	{
299 300 301 302 303 304 305 306 307 308 309 310 311 312
	  buf = (U_CHAR *) xmalloc (size);
	  offset = 0;
	  while (offset < size)
	    {
	      count = read (inc->fd, buf + offset, size - offset);
	      if (count < 0)
		goto perror_fail;
	      if (count == 0)
		{
		  cpp_warning (pfile, "%s is shorter than expected", inc->name);
		  break;
		}
	      offset += count;
	    }
313
	}
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
    }
  else if (S_ISBLK (inc->st.st_mode))
    {
      cpp_error (pfile, "%s is a block device", inc->name);
      goto fail;
    }
  else if (S_ISDIR (inc->st.st_mode))
    {
      cpp_error (pfile, "%s is a directory", inc->name);
      goto fail;
    }
  else
    {
      /* 8 kilobytes is a sensible starting size.  It ought to be
	 bigger than the kernel pipe buffer, and it's definitely
	 bigger than the majority of C source files.  */
      size = 8 * 1024;
331

332 333 334
      buf = (U_CHAR *) xmalloc (size);
      offset = 0;
      while ((count = read (inc->fd, buf + offset, size - offset)) > 0)
335
	{
336 337 338
	  offset += count;
	  if (offset == size)
	    buf = xrealloc (buf, (size *= 2));
339
	}
340 341 342 343 344 345
      if (count < 0)
	goto perror_fail;

      if (offset < size)
	buf = xrealloc (buf, offset);
      inc->st.st_size = offset;
346
    }
Zack Weinberg committed
347

348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367
  close (inc->fd);
  inc->buffer = buf;
  inc->fd = -1;
  return 1;

 perror_fail:
  cpp_error_from_errno (pfile, inc->name);
 fail:
  /* Do not try to read this file again.  */
  close (inc->fd);
  inc->fd = -1;
  inc->cmacro = NEVER_REREAD;
  return 0;
}

static void
purge_cache (inc)
     struct include_file *inc;
{
  if (inc->buffer)
368
    {
369
#if MMAP_THRESHOLD
370
      if (inc->mapped)
371
	munmap ((PTR) inc->buffer, inc->st.st_size);
372
      else
373
#endif
374 375
	free ((PTR) inc->buffer);
      inc->buffer = NULL;
376
    }
377 378
}

379 380 381 382
/* Return 1 if the file named by FNAME has been included before in
   any context, 0 otherwise.  */
int
cpp_included (pfile, fname)
Zack Weinberg committed
383
     cpp_reader *pfile;
384
     const char *fname;
Zack Weinberg committed
385
{
386
  struct file_name_list *path;
387
  char *name;
388
  splay_tree_node nd;
389

390
  if (fname[0] == '/')
391
    {
392 393 394
      /* Just look it up.  */
      nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) fname);
      return (nd && nd->value);
395
    }
396 397 398 399 400
      
  /* Search directory path for the file.  */
  name = (char *) alloca (strlen (fname) + pfile->max_include_len
			  + 2 + INCLUDE_LEN_FUDGE);
  for (path = CPP_OPTION (pfile, quote_include); path; path = path->next)
401
    {
402 403 404 405 406 407 408 409 410 411
      memcpy (name, path->name, path->nlen);
      name[path->nlen] = '/';
      strcpy (&name[path->nlen+1], fname);
      _cpp_simplify_pathname (name);
      if (CPP_OPTION (pfile, remap))
	name = remap_filename (pfile, name, path);

      nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) name);
      if (nd && nd->value)
	return 1;
412
    }
413
  return 0;
Zack Weinberg committed
414 415
}

416 417
/* Search for include file FNAME in the include chain starting at
   SEARCH_START.  Return 0 if there is no such file (or it's un-openable),
418
   otherwise an include_file structure.  */
419 420 421

static struct include_file *
find_include_file (pfile, fname, search_start)
422 423
     cpp_reader *pfile;
     const char *fname;
424
     struct file_name_list *search_start;
425
{
426 427 428
  struct file_name_list *path;
  char *name;
  struct include_file *file;
Zack Weinberg committed
429

430
  if (fname[0] == '/')
431
    return open_file (pfile, fname);
432 433 434 435 436
      
  /* Search directory path for the file.  */
  name = (char *) alloca (strlen (fname) + pfile->max_include_len
			  + 2 + INCLUDE_LEN_FUDGE);
  for (path = search_start; path; path = path->next)
Zack Weinberg committed
437
    {
438 439 440 441 442 443 444
      memcpy (name, path->name, path->nlen);
      name[path->nlen] = '/';
      strcpy (&name[path->nlen+1], fname);
      _cpp_simplify_pathname (name);
      if (CPP_OPTION (pfile, remap))
	name = remap_filename (pfile, name, path);

445
      file = open_file (pfile, name);
446
      if (file)
Zack Weinberg committed
447
	{
448 449 450
	  file->sysp = path->sysp;
	  file->foundhere = path;
	  return file;
Zack Weinberg committed
451 452
	}
    }
453
  return 0;
Zack Weinberg committed
454 455
}

456 457 458
/* #line uses this to save artificial file names.  We have to stat the
   file because an all_include_files entry is always either + or -,
   there's no 'I don't know' value.  */
459 460
const char *
_cpp_fake_include (pfile, fname)
Zack Weinberg committed
461
     cpp_reader *pfile;
462
     const char *fname;
Zack Weinberg committed
463
{
464 465
  splay_tree_node nd;
  struct include_file *file;
Zack Weinberg committed
466 467
  char *name;

468 469
  file = find_include_file (pfile, fname, CPP_OPTION (pfile, quote_include));
  if (file)
470 471 472 473 474 475 476 477
    {
      if (file->fd > 0)
	{
	  close (file->fd);
	  file->fd = -1;
	}
      return file->name;
    }
Zack Weinberg committed
478

479 480
  name = xstrdup (fname);
  _cpp_simplify_pathname (name);
Zack Weinberg committed
481

482 483 484 485
  /* We cannot just blindly insert a node, because there's still the
     chance that the node already exists but isn't on the search path.  */
  nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) name);
  if (nd)
Zack Weinberg committed
486
    {
487 488
      free (name);
      return (const char *) nd->key;
Zack Weinberg committed
489
    }
490

491 492 493 494 495 496 497
  file = xcnew (struct include_file);
  file->name = name;
  file->fd = -2;
  splay_tree_insert (pfile->all_include_files, (splay_tree_key) name,
		     (splay_tree_value) file);

  return file->name;
Zack Weinberg committed
498 499
}

500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516
/* Not everyone who wants to set system-header-ness on a buffer can
   see the details of struct include_file.  This is an exported interface
   because fix-header needs it.  */
void
cpp_make_system_header (pfile, pbuf, flag)
     cpp_reader *pfile;
     cpp_buffer *pbuf;
     int flag;
{
  if (flag < 0 || flag > 2)
    cpp_ice (pfile, "cpp_make_system_header: bad flag %d\n", flag);
  else if (!pbuf->inc)
    cpp_ice (pfile, "cpp_make_system_header called on non-file buffer");
  else
    pbuf->inc->sysp = flag;
}

517 518 519 520 521 522 523 524 525 526 527 528 529 530
const char *
cpp_syshdr_flags (pfile, pbuf)
     cpp_reader *pfile ATTRIBUTE_UNUSED;
     cpp_buffer *pbuf;
{
#ifndef NO_IMPLICIT_EXTERN_C
  if (CPP_OPTION (pfile, cplusplus) && pbuf->inc->sysp == 2)
    return " 3 4";
#endif
  if (pbuf->inc->sysp)
    return " 3";
  return "";
}

531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562
/* Report on all files that might benefit from a multiple include guard.
   Triggered by -H.  */
void
_cpp_report_missing_guards (pfile)
     cpp_reader *pfile;
{
  int banner = 0;
  splay_tree_foreach (pfile->all_include_files, report_missing_guard,
		      (PTR) &banner);
}

static int
report_missing_guard (n, b)
     splay_tree_node n;
     void *b;
{
  struct include_file *f = (struct include_file *) n->value;
  int *bannerp = (int *)b;

  if (f && f->cmacro == 0 && f->include_count == 1)
    {
      if (*bannerp == 0)
	{
	  fputs (_("Multiple include guards may be useful for:\n"), stderr);
	  *bannerp = 1;
	}
      fputs (f->name, stderr);
      putc ('\n', stderr);
    }
  return 0;
}

563
#define PRINT_THIS_DEP(p, b) (CPP_PRINT_DEPS(p) > (b||p->system_include_depth))
564
void
Zack Weinberg committed
565
_cpp_execute_include (pfile, f, len, no_reinclude, search_start, angle_brackets)
566
     cpp_reader *pfile;
Zack Weinberg committed
567
     const U_CHAR *f;
568 569 570
     unsigned int len;
     int no_reinclude;
     struct file_name_list *search_start;
Zack Weinberg committed
571
     int angle_brackets;
572
{
573
  struct include_file *inc;
Zack Weinberg committed
574
  char *fname;
575 576 577 578

  if (!search_start)
    {
      if (angle_brackets)
579 580 581
	search_start = CPP_OPTION (pfile, bracket_include);
      else if (CPP_OPTION (pfile, ignore_srcdir))
	search_start = CPP_OPTION (pfile, quote_include);
582 583 584 585 586 587
      else
	search_start = CPP_BUFFER (pfile)->actual_dir;
    }

  if (!search_start)
    {
588
      cpp_error (pfile, "No include path in which to find %s", f);
589 590 591
      return;
    }

Zack Weinberg committed
592 593
  fname = alloca (len + 1);
  memcpy (fname, f, len);
594 595
  fname[len] = '\0';

596
  inc = find_include_file (pfile, fname, search_start);
597

598
  if (inc)
599
    {
600
      /* For -M, add the file to the dependencies on its first inclusion. */
601
      if (!inc->include_count && PRINT_THIS_DEP (pfile, angle_brackets))
602
	deps_add_dep (pfile->deps, inc->name);
603
      inc->include_count++;
604 605

      /* Actually process the file.  */
606
      if (stack_include_file (pfile, inc))
607 608 609
	{
	  if (angle_brackets)
	    pfile->system_include_depth++;
610 611 612 613 614 615 616 617 618 619 620 621

	  if (no_reinclude)
	    inc->cmacro = NEVER_REREAD;

	  /* Handle -H option.  */
	  if (CPP_OPTION (pfile, print_include_names))
	    {
	      cpp_buffer *fp = CPP_BUFFER (pfile);
	      while ((fp = CPP_PREV_BUFFER (fp)) != NULL)
		putc ('.', stderr);
	      fprintf (stderr, " %s\n", inc->name);
	    }
622
	}
623 624
      return;
    }
625 626 627
      
  if (CPP_OPTION (pfile, print_deps_missing_files)
      && PRINT_THIS_DEP (pfile, angle_brackets))
628
    {
629 630 631 632 633 634 635 636 637 638 639 640
      if (!angle_brackets)
	deps_add_dep (pfile->deps, fname);
      else
	{
	  char *p;
	  struct file_name_list *ptr;
	  /* If requested as a system header, assume it belongs in
	     the first system header directory. */
	  if (CPP_OPTION (pfile, bracket_include))
	    ptr = CPP_OPTION (pfile, bracket_include);
	  else
	    ptr = CPP_OPTION (pfile, quote_include);
641

642 643 644 645 646 647 648 649 650 651 652
	  p = (char *) alloca (strlen (ptr->name)
			       + strlen (fname) + 2);
	  if (*ptr->name != '\0')
	    {
	      strcpy (p, ptr->name);
	      strcat (p, "/");
	    }
	  strcat (p, fname);
	  _cpp_simplify_pathname (p);
	  deps_add_dep (pfile->deps, p);
	}
653
    }
654 655 656 657 658 659 660 661 662 663 664
  /* If -M was specified, and this header file won't be added to
     the dependency list, then don't count this as an error,
     because we can still produce correct output.  Otherwise, we
     can't produce correct output, because there may be
     dependencies we need inside the missing file, and we don't
     know what directory this missing file exists in. */
  else if (CPP_PRINT_DEPS (pfile)
	   && ! PRINT_THIS_DEP (pfile, angle_brackets))
    cpp_warning (pfile, "No include path in which to find %s", fname);
  else
    cpp_error_from_errno (pfile, fname);
665 666
}

667 668 669 670
/* Locate file F, and determine whether it is newer than PFILE. Return -1,
   if F cannot be located or dated, 1, if it is newer and 0 if older.  */

int
Zack Weinberg committed
671
_cpp_compare_file_date (pfile, f, len, angle_brackets)
672
     cpp_reader *pfile;
Zack Weinberg committed
673
     const U_CHAR *f;
674
     unsigned int len;
Zack Weinberg committed
675
     int angle_brackets;
676
{
Zack Weinberg committed
677 678
  char *fname;
  struct file_name_list *search_start;
679
  struct include_file *inc;
Zack Weinberg committed
680
  struct include_file *current_include = CPP_BUFFER (pfile)->inc;
681

Zack Weinberg committed
682 683 684 685 686 687
  if (angle_brackets)
    search_start = CPP_OPTION (pfile, bracket_include);
  else if (CPP_OPTION (pfile, ignore_srcdir))
    search_start = CPP_OPTION (pfile, quote_include);
  else
    search_start = CPP_BUFFER (pfile)->actual_dir;
688

Zack Weinberg committed
689 690
  fname = alloca (len + 1);
  memcpy (fname, f, len);
691 692 693 694 695
  fname[len] = '\0';
  inc = find_include_file (pfile, fname, search_start);
  
  if (!inc)
    return -1;
696
  if (inc->fd > 0)
697 698 699 700
    {
      close (inc->fd);
      inc->fd = -1;
    }
701 702
    
  return inc->st.st_mtime > current_include->st.st_mtime;
703 704 705
}


706 707 708 709 710 711 712
/* Push an input buffer and load it up with the contents of FNAME.
   If FNAME is "" or NULL, read standard input.  */
int
cpp_read_file (pfile, fname)
     cpp_reader *pfile;
     const char *fname;
{
713
  struct include_file *f;
714

715 716 717
  if (fname == NULL)
    fname = "";

718
  f = open_file (pfile, fname);
719

Zack Weinberg committed
720 721 722 723 724 725
  if (f == NULL)
    {
      cpp_error_from_errno (pfile, fname);
      return 0;
    }

726
  return stack_include_file (pfile, f);
727 728
}

729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749
/* Do appropriate cleanup when a file buffer is popped off the input
   stack.  */
void
_cpp_pop_file_buffer (pfile, buf)
     cpp_reader *pfile;
     cpp_buffer *buf;
{
  struct include_file *inc = buf->inc;

  if (pfile->system_include_depth)
    pfile->system_include_depth--;
  if (pfile->include_depth)
    pfile->include_depth--;
  if (pfile->potential_control_macro)
    {
      if (inc->cmacro != NEVER_REREAD)
	inc->cmacro = pfile->potential_control_macro;
      pfile->potential_control_macro = 0;
    }
  pfile->input_stack_listing_current = 0;

750 751 752
  inc->refcnt--;
  if (inc->refcnt == 0 && DO_NOT_REREAD (inc))
    purge_cache (inc);
753 754
}

755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831
/* The file_name_map structure holds a mapping of file names for a
   particular directory.  This mapping is read from the file named
   FILE_NAME_MAP_FILE in that directory.  Such a file can be used to
   map filenames on a file system with severe filename restrictions,
   such as DOS.  The format of the file name map file is just a series
   of lines with two tokens on each line.  The first token is the name
   to map, and the second token is the actual name to use.  */

struct file_name_map
{
  struct file_name_map *map_next;
  char *map_from;
  char *map_to;
};

#define FILE_NAME_MAP_FILE "header.gcc"

/* Read a space delimited string of unlimited length from a stdio
   file.  */

static char *
read_filename_string (ch, f)
     int ch;
     FILE *f;
{
  char *alloc, *set;
  int len;

  len = 20;
  set = alloc = xmalloc (len + 1);
  if (! is_space(ch))
    {
      *set++ = ch;
      while ((ch = getc (f)) != EOF && ! is_space(ch))
	{
	  if (set - alloc == len)
	    {
	      len *= 2;
	      alloc = xrealloc (alloc, len + 1);
	      set = alloc + len / 2;
	    }
	  *set++ = ch;
	}
    }
  *set = '\0';
  ungetc (ch, f);
  return alloc;
}

/* This structure holds a linked list of file name maps, one per directory.  */

struct file_name_map_list
{
  struct file_name_map_list *map_list_next;
  char *map_list_name;
  struct file_name_map *map_list_map;
};

/* Read the file name map file for DIRNAME.  */

static struct file_name_map *
read_name_map (pfile, dirname)
     cpp_reader *pfile;
     const char *dirname;
{
  register struct file_name_map_list *map_list_ptr;
  char *name;
  FILE *f;

  for (map_list_ptr = CPP_OPTION (pfile, map_list); map_list_ptr;
       map_list_ptr = map_list_ptr->map_list_next)
    if (! strcmp (map_list_ptr->map_list_name, dirname))
      return map_list_ptr->map_list_map;

  map_list_ptr = ((struct file_name_map_list *)
		  xmalloc (sizeof (struct file_name_map_list)));
  map_list_ptr->map_list_name = xstrdup (dirname);
832
  map_list_ptr->map_list_map = NULL;
833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949

  name = (char *) alloca (strlen (dirname) + strlen (FILE_NAME_MAP_FILE) + 2);
  strcpy (name, dirname);
  if (*dirname)
    strcat (name, "/");
  strcat (name, FILE_NAME_MAP_FILE);
  f = fopen (name, "r");
  if (!f)
    map_list_ptr->map_list_map = (struct file_name_map *)-1;
  else
    {
      int ch;
      int dirlen = strlen (dirname);

      while ((ch = getc (f)) != EOF)
	{
	  char *from, *to;
	  struct file_name_map *ptr;

	  if (is_space(ch))
	    continue;
	  from = read_filename_string (ch, f);
	  while ((ch = getc (f)) != EOF && is_hspace(ch))
	    ;
	  to = read_filename_string (ch, f);

	  ptr = ((struct file_name_map *)
		 xmalloc (sizeof (struct file_name_map)));
	  ptr->map_from = from;

	  /* Make the real filename absolute.  */
	  if (*to == '/')
	    ptr->map_to = to;
	  else
	    {
	      ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
	      strcpy (ptr->map_to, dirname);
	      ptr->map_to[dirlen] = '/';
	      strcpy (ptr->map_to + dirlen + 1, to);
	      free (to);
	    }	      

	  ptr->map_next = map_list_ptr->map_list_map;
	  map_list_ptr->map_list_map = ptr;

	  while ((ch = getc (f)) != '\n')
	    if (ch == EOF)
	      break;
	}
      fclose (f);
    }
  
  map_list_ptr->map_list_next = CPP_OPTION (pfile, map_list);
  CPP_OPTION (pfile, map_list) = map_list_ptr;

  return map_list_ptr->map_list_map;
}  

/* Remap NAME based on the file_name_map (if any) for LOC. */

static char *
remap_filename (pfile, name, loc)
     cpp_reader *pfile;
     char *name;
     struct file_name_list *loc;
{
  struct file_name_map *map;
  const char *from, *p, *dir;

  if (! loc->name_map)
    loc->name_map = read_name_map (pfile,
				   loc->name
				   ? loc->name : ".");

  if (loc->name_map == (struct file_name_map *)-1)
    return name;
  
  from = name + strlen (loc->name) + 1;
  
  for (map = loc->name_map; map; map = map->map_next)
    if (!strcmp (map->map_from, from))
      return map->map_to;

  /* Try to find a mapping file for the particular directory we are
     looking in.  Thus #include <sys/types.h> will look up sys/types.h
     in /usr/include/header.gcc and look up types.h in
     /usr/include/sys/header.gcc.  */
  p = strrchr (name, '/');
  if (!p)
    p = name;
  if (loc && loc->name
      && strlen (loc->name) == (size_t) (p - name)
      && !strncmp (loc->name, name, p - name))
    /* FILENAME is in SEARCHPTR, which we've already checked.  */
    return name;

  if (p == name)
    {
      dir = ".";
      from = name;
    }
  else
    {
      char * newdir = (char *) alloca (p - name + 1);
      memcpy (newdir, name, p - name);
      newdir[p - name] = '\0';
      dir = newdir;
      from = p + 1;
    }
  
  for (map = read_name_map (pfile, dir); map; map = map->map_next)
    if (! strcmp (map->map_from, name))
      return map->map_to;

  return name;
}

Zack Weinberg committed
950 951 952 953 954
/* Given a path FNAME, extract the directory component and place it
   onto the actual_dirs list.  Return a pointer to the allocated
   file_name_list structure.  These structures are used to implement
   current-directory "" include searching. */

955 956 957
static struct file_name_list *
actual_directory (pfile, fname)
     cpp_reader *pfile;
958
     const char *fname;
959 960 961 962 963
{
  char *last_slash, *dir;
  size_t dlen;
  struct file_name_list *x;
  
964
  dir = xstrdup (fname);
965
  last_slash = strrchr (dir, '/');
966 967 968 969 970 971 972 973 974 975 976 977 978 979 980
  if (last_slash)
    {
      if (last_slash == dir)
        {
	  dlen = 1;
	  last_slash[1] = '\0';
	}
      else
	{
	  dlen = last_slash - dir;
	  *last_slash = '\0';
	}
    }
  else
    {
981 982
      free (dir);
      dir = xstrdup (".");
983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999
      dlen = 1;
    }

  if (dlen > pfile->max_include_len)
    pfile->max_include_len = dlen;

  for (x = pfile->actual_dirs; x; x = x->alloc)
    if (!strcmp (x->name, dir))
      {
	free (dir);
	return x;
      }

  /* Not found, make a new one. */
  x = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
  x->name = dir;
  x->nlen = dlen;
1000
  x->next = CPP_OPTION (pfile, quote_include);
1001
  x->alloc = pfile->actual_dirs;
1002
  x->sysp = CPP_BUFFER (pfile)->inc->sysp;
1003 1004 1005 1006 1007 1008
  x->name_map = NULL;

  pfile->actual_dirs = x;
  return x;
}

1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022
/* Simplify a path name in place, deleting redundant components.  This
   reduces OS overhead and guarantees that equivalent paths compare
   the same (modulo symlinks).

   Transforms made:
   foo/bar/../quux	foo/quux
   foo/./bar		foo/bar
   foo//bar		foo/bar
   /../quux		/quux
   //quux		//quux  (POSIX allows leading // as a namespace escape)

   Guarantees no trailing slashes. All transforms reduce the length
   of the string.
 */
1023
void
1024
_cpp_simplify_pathname (path)
1025
    char *path;
1026 1027 1028 1029 1030
{
    char *from, *to;
    char *base;
    int absolute = 0;

1031
#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144
    /* Convert all backslashes to slashes. */
    for (from = path; *from; from++)
	if (*from == '\\') *from = '/';
    
    /* Skip over leading drive letter if present. */
    if (ISALPHA (path[0]) && path[1] == ':')
	from = to = &path[2];
    else
	from = to = path;
#else
    from = to = path;
#endif
    
    /* Remove redundant initial /s.  */
    if (*from == '/')
    {
	absolute = 1;
	to++;
	from++;
	if (*from == '/')
	{
	    if (*++from == '/')
		/* 3 or more initial /s are equivalent to 1 /.  */
		while (*++from == '/');
	    else
		/* On some hosts // differs from /; Posix allows this.  */
		to++;
	}
    }
    base = to;
    
    for (;;)
    {
	while (*from == '/')
	    from++;

	if (from[0] == '.' && from[1] == '/')
	    from += 2;
	else if (from[0] == '.' && from[1] == '\0')
	    goto done;
	else if (from[0] == '.' && from[1] == '.' && from[2] == '/')
	{
	    if (base == to)
	    {
		if (absolute)
		    from += 3;
		else
		{
		    *to++ = *from++;
		    *to++ = *from++;
		    *to++ = *from++;
		    base = to;
		}
	    }
	    else
	    {
		to -= 2;
		while (to > base && *to != '/') to--;
		if (*to == '/')
		    to++;
		from += 3;
	    }
	}
	else if (from[0] == '.' && from[1] == '.' && from[2] == '\0')
	{
	    if (base == to)
	    {
		if (!absolute)
		{
		    *to++ = *from++;
		    *to++ = *from++;
		}
	    }
	    else
	    {
		to -= 2;
		while (to > base && *to != '/') to--;
		if (*to == '/')
		    to++;
	    }
	    goto done;
	}
	else
	    /* Copy this component and trailing /, if any.  */
	    while ((*to++ = *from++) != '/')
	    {
		if (!to[-1])
		{
		    to--;
		    goto done;
		}
	    }
	
    }
    
 done:
    /* Trim trailing slash */
    if (to[0] == '/' && (!absolute || to > path+1))
	to--;

    /* Change the empty string to "." so that stat() on the result
       will always work. */
    if (to == path)
      *to++ = '.';
    
    *to = '\0';

    return;
}

/* It is not clear when this should be used if at all, so I've
   disabled it until someone who understands VMS can look at it. */
#if 0
Zack Weinberg committed
1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177

/* Under VMS we need to fix up the "include" specification filename.

   Rules for possible conversions

	fullname		tried paths

	name			name
	./dir/name		[.dir]name
	/dir/name		dir:name
	/name			[000000]name, name
	dir/name		dir:[000000]name, dir:name, dir/name
	dir1/dir2/name		dir1:[dir2]name, dir1:[000000.dir2]name
	path:/name		path:[000000]name, path:name
	path:/dir/name		path:[000000.dir]name, path:[dir]name
	path:dir/name		path:[dir]name
	[path]:[dir]name	[path.dir]name
	path/[dir]name		[path.dir]name

   The path:/name input is constructed when expanding <> includes. */


static void
hack_vms_include_specification (fullname)
     char *fullname;
{
  register char *basename, *unixname, *local_ptr, *first_slash;
  int f, check_filename_before_returning, must_revert;
  char Local[512];

  check_filename_before_returning = 0;
  must_revert = 0;
  /* See if we can find a 1st slash. If not, there's no path information.  */
1178
  first_slash = strchr (fullname, '/');
Zack Weinberg committed
1179 1180 1181 1182 1183
  if (first_slash == 0)
    return 0;				/* Nothing to do!!! */

  /* construct device spec if none given.  */

1184
  if (strchr (fullname, ':') == 0)
Zack Weinberg committed
1185 1186 1187 1188 1189 1190
    {

      /* If fullname has a slash, take it as device spec.  */

      if (first_slash == fullname)
	{
1191
	  first_slash = strchr (fullname + 1, '/');	/* 2nd slash ? */
Zack Weinberg committed
1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252
	  if (first_slash)
	    *first_slash = ':';				/* make device spec  */
	  for (basename = fullname; *basename != 0; basename++)
	    *basename = *(basename+1);			/* remove leading slash  */
	}
      else if ((first_slash[-1] != '.')		/* keep ':/', './' */
	    && (first_slash[-1] != ':')
	    && (first_slash[-1] != ']'))	/* or a vms path  */
	{
	  *first_slash = ':';
	}
      else if ((first_slash[1] == '[')		/* skip './' in './[dir'  */
	    && (first_slash[-1] == '.'))
	fullname += 2;
    }

  /* Get part after first ':' (basename[-1] == ':')
     or last '/' (basename[-1] == '/').  */

  basename = base_name (fullname);

  local_ptr = Local;			/* initialize */

  /* We are trying to do a number of things here.  First of all, we are
     trying to hammer the filenames into a standard format, such that later
     processing can handle them.
     
     If the file name contains something like [dir.], then it recognizes this
     as a root, and strips the ".]".  Later processing will add whatever is
     needed to get things working properly.
     
     If no device is specified, then the first directory name is taken to be
     a device name (or a rooted logical).  */

  /* Point to the UNIX filename part (which needs to be fixed!)
     but skip vms path information.
     [basename != fullname since first_slash != 0].  */

  if ((basename[-1] == ':')		/* vms path spec.  */
      || (basename[-1] == ']')
      || (basename[-1] == '>'))
    unixname = basename;
  else
    unixname = fullname;

  if (*unixname == '/')
    unixname++;

  /* If the directory spec is not rooted, we can just copy
     the UNIX filename part and we are done.  */

  if (((basename - fullname) > 1)
     && (  (basename[-1] == ']')
        || (basename[-1] == '>')))
    {
      if (basename[-2] != '.')
	{

	/* The VMS part ends in a `]', and the preceding character is not a `.'.
	   -> PATH]:/name (basename = '/name', unixname = 'name')
	   We strip the `]', and then splice the two parts of the name in the
Zack Weinberg committed
1253
	   usual way.  Given the default locations for include files,
Zack Weinberg committed
1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310
	   we will only use this code if the user specifies alternate locations
	   with the /include (-I) switch on the command line.  */

	  basename -= 1;	/* Strip "]" */
	  unixname--;		/* backspace */
	}
      else
	{

	/* The VMS part has a ".]" at the end, and this will not do.  Later
	   processing will add a second directory spec, and this would be a syntax
	   error.  Thus we strip the ".]", and thus merge the directory specs.
	   We also backspace unixname, so that it points to a '/'.  This inhibits the
	   generation of the 000000 root directory spec (which does not belong here
	   in this case).  */

	  basename -= 2;	/* Strip ".]" */
	  unixname--;		/* backspace */
	}
    }

  else

    {

      /* We drop in here if there is no VMS style directory specification yet.
         If there is no device specification either, we make the first dir a
         device and try that.  If we do not do this, then we will be essentially
         searching the users default directory (as if they did a #include "asdf.h").
        
         Then all we need to do is to push a '[' into the output string. Later
         processing will fill this in, and close the bracket.  */

      if ((unixname != fullname)	/* vms path spec found.  */
	 && (basename[-1] != ':'))
	*local_ptr++ = ':';		/* dev not in spec.  take first dir */

      *local_ptr++ = '[';		/* Open the directory specification */
    }

    if (unixname == fullname)		/* no vms dir spec.  */
      {
	must_revert = 1;
	if ((first_slash != 0)		/* unix dir spec.  */
	    && (*unixname != '/')	/* not beginning with '/'  */
	    && (*unixname != '.'))	/* or './' or '../'  */
	  *local_ptr++ = '.';		/* dir is local !  */
      }

  /* at this point we assume that we have the device spec, and (at least
     the opening "[" for a directory specification.  We may have directories
     specified already.

     If there are no other slashes then the filename will be
     in the "root" directory.  Otherwise, we need to add
     directory specifications.  */

1311
  if (strchr (unixname, '/') == 0)
Zack Weinberg committed
1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325
    {
      /* if no directories specified yet and none are following.  */
      if (local_ptr[-1] == '[')
	{
	  /* Just add "000000]" as the directory string */
	  strcpy (local_ptr, "000000]");
	  local_ptr += strlen (local_ptr);
	  check_filename_before_returning = 1; /* we might need to fool with this later */
	}
    }
  else
    {

      /* As long as there are still subdirectories to add, do them.  */
1326
      while (strchr (unixname, '/') != 0)
Zack Weinberg committed
1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396
	{
	  /* If this token is "." we can ignore it
	       if it's not at the beginning of a path.  */
	  if ((unixname[0] == '.') && (unixname[1] == '/'))
	    {
	      /* remove it at beginning of path.  */
	      if (  ((unixname == fullname)		/* no device spec  */
		    && (fullname+2 != basename))	/* starts with ./ */
							/* or  */
		 || ((basename[-1] == ':')		/* device spec  */
		    && (unixname-1 == basename)))	/* and ./ afterwards  */
		*local_ptr++ = '.';		 	/* make '[.' start of path.  */
	      unixname += 2;
	      continue;
	    }

	  /* Add a subdirectory spec. Do not duplicate "." */
	  if (  local_ptr[-1] != '.'
	     && local_ptr[-1] != '['
	     && local_ptr[-1] != '<')
	    *local_ptr++ = '.';

	  /* If this is ".." then the spec becomes "-" */
	  if (  (unixname[0] == '.')
	     && (unixname[1] == '.')
	     && (unixname[2] == '/'))
	    {
	      /* Add "-" and skip the ".." */
	      if ((local_ptr[-1] == '.')
		  && (local_ptr[-2] == '['))
		local_ptr--;			/* prevent [.-  */
	      *local_ptr++ = '-';
	      unixname += 3;
	      continue;
	    }

	  /* Copy the subdirectory */
	  while (*unixname != '/')
	    *local_ptr++= *unixname++;

	  unixname++;			/* Skip the "/" */
	}

      /* Close the directory specification */
      if (local_ptr[-1] == '.')		/* no trailing periods */
	local_ptr--;

      if (local_ptr[-1] == '[')		/* no dir needed */
	local_ptr--;
      else
	*local_ptr++ = ']';
    }

  /* Now add the filename.  */

  while (*unixname)
    *local_ptr++ = *unixname++;
  *local_ptr = 0;

  /* Now append it to the original VMS spec.  */

  strcpy ((must_revert==1)?fullname:basename, Local);

  /* If we put a [000000] in the filename, try to open it first. If this fails,
     remove the [000000], and return that name.  This provides flexibility
     to the user in that they can use both rooted and non-rooted logical names
     to point to the location of the file.  */

  if (check_filename_before_returning)
    {
1397
      f = open (fullname, O_RDONLY|O_NONBLOCK);
Zack Weinberg committed
1398 1399 1400 1401 1402 1403 1404 1405 1406 1407
      if (f >= 0)
	{
	  /* The file name is OK as it is, so return it as is.  */
	  close (f);
	  return 1;
	}

      /* The filename did not work.  Try to remove the [000000] from the name,
	 and return it.  */

1408 1409
      basename = strchr (fullname, '[');
      local_ptr = strchr (fullname, ']') + 1;
Zack Weinberg committed
1410 1411 1412 1413 1414 1415 1416
      strcpy (basename, local_ptr);		/* this gets rid of it */

    }

  return 1;
}
#endif	/* VMS */