aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNeil Booth <neil@daikokuya.demon.co.uk>2001-04-06 07:22:01 +0000
committerNeil Booth <neil@gcc.gnu.org>2001-04-06 07:22:01 +0000
commitf9200da26d1cc1df956aa14ba1f6fcfaf730c221 (patch)
treec15a70516f598de133ec9104c90fc14238a59310 /gcc
parent0bda3da7ab8eba3f5c5e3c91ebd191698ebbf288 (diff)
downloadgcc-f9200da26d1cc1df956aa14ba1f6fcfaf730c221.zip
gcc-f9200da26d1cc1df956aa14ba1f6fcfaf730c221.tar.gz
gcc-f9200da26d1cc1df956aa14ba1f6fcfaf730c221.tar.bz2
configure.in: Add check for lstat.
* configure.in: Add check for lstat. * configure, config.in: Regenerate. * cppinit.c (append_include_chain): Make empty path ".". * cpplib.c (do_line): Don't simplify #line paths. * cppfiles.c (remove_component_p): New function. (find_or_create_entry): Acknowledge stat () errors during path simplification. (handle_missing_header): Don't simplify paths. (_cpp_simplify_pathname): Don't simplify VMS paths. Return the empty path untouched. Don't leave a trailing '/'. From-SVN: r41148
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config.in3
-rwxr-xr-xgcc/configure2
-rw-r--r--gcc/configure.in2
-rw-r--r--gcc/cppfiles.c214
-rw-r--r--gcc/cppinit.c4
-rw-r--r--gcc/cpplib.c7
7 files changed, 140 insertions, 105 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c616563..bb179c6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2001-04-06 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * configure.in: Add check for lstat.
+ * configure, config.in: Regenerate.
+ * cppinit.c (append_include_chain): Make empty path ".".
+ * cpplib.c (do_line): Don't simplify #line paths.
+ * cppfiles.c (remove_component_p): New function.
+ (find_or_create_entry): Acknowledge stat () errors during
+ path simplification.
+ (handle_missing_header): Don't simplify paths.
+ (_cpp_simplify_pathname): Don't simplify VMS paths. Return
+ the empty path untouched. Don't leave a trailing '/'.
+
2001-04-06 Benjamin Kosnik <bkoz@redhat.com>
* cppdefault.c (GPLUSPLUS_BACKWARD_INCLUDE_DIR): Add.
diff --git a/gcc/config.in b/gcc/config.in
index 7af8d1e..bc19ffe 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -134,6 +134,9 @@
/* Define if you have the kill function. */
#undef HAVE_KILL
+/* Define if you have the lstat function. */
+#undef HAVE_LSTAT
+
/* Define if you have the munmap function. */
#undef HAVE_MUNMAP
diff --git a/gcc/configure b/gcc/configure
index 8b0d1b8..20383fe 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -3102,7 +3102,7 @@ fi
for ac_func in strtoul bsearch popen \
strchr strrchr kill getrlimit setrlimit atoll atoq \
sysconf isascii gettimeofday strsignal putc_unlocked fputc_unlocked \
- fputs_unlocked getrusage iconv nl_langinfo
+ fputs_unlocked getrusage iconv nl_langinfo lstat
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:3109: checking for $ac_func" >&5
diff --git a/gcc/configure.in b/gcc/configure.in
index ca356f30..1e5f408 100644
--- a/gcc/configure.in
+++ b/gcc/configure.in
@@ -547,7 +547,7 @@ dnl gcc_AC_C_ENUM_BF_UNSIGNED
AC_CHECK_FUNCS(strtoul bsearch popen \
strchr strrchr kill getrlimit setrlimit atoll atoq \
sysconf isascii gettimeofday strsignal putc_unlocked fputc_unlocked \
- fputs_unlocked getrusage iconv nl_langinfo)
+ fputs_unlocked getrusage iconv nl_langinfo lstat)
AC_CHECK_TYPE(ssize_t, int)
diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c
index bff04ae..e242e92 100644
--- a/gcc/cppfiles.c
+++ b/gcc/cppfiles.c
@@ -101,6 +101,7 @@ static int report_missing_guard PARAMS ((splay_tree_node, void *));
static splay_tree_node find_or_create_entry PARAMS ((cpp_reader *,
const char *));
static void handle_missing_header PARAMS ((cpp_reader *, const char *, int));
+static int remove_component_p PARAMS ((const char *));
/* Set up the splay tree we use to store information about all the
file names seen in this compilation. We also have entries for each
@@ -155,7 +156,8 @@ _cpp_never_reread (file)
}
/* Lookup a filename, which is simplified after making a copy, and
- create an entry if none exists. */
+ create an entry if none exists. errno is nonzero iff a (reported)
+ stat() error occurred during simplification. */
static splay_tree_node
find_or_create_entry (pfile, fname)
cpp_reader *pfile;
@@ -208,6 +210,9 @@ open_file (pfile, filename)
splay_tree_node nd = find_or_create_entry (pfile, filename);
struct include_file *file = (struct include_file *) nd->value;
+ if (errno)
+ file->fd = -2;
+
/* Don't retry opening if we failed previously. */
if (file->fd == -2)
return 0;
@@ -643,7 +648,6 @@ handle_missing_header (pfile, fname, angle_brackets)
p[len++] = '/';
}
memcpy (p + len, fname, fname_len + 1);
- _cpp_simplify_pathname (p);
deps_add_dep (pfile->deps, p);
}
}
@@ -1006,6 +1010,26 @@ remap_filename (pfile, name, loc)
return name;
}
+/* Returns true if it is safe to remove the final component of path,
+ when it is followed by a ".." component. We use lstat to avoid
+ symlinks if we have it. If not, we can still catch errors with
+ stat (). */
+static int
+remove_component_p (path)
+ const char *path;
+{
+ struct stat s;
+ int result;
+
+#ifdef HAVE_LSTAT
+ result = lstat (path, &s);
+#else
+ result = stat (path, &s);
+#endif
+
+ return result == 0 && S_ISDIR (s.st_mode);
+}
+
/* Simplify a path name in place, deleting redundant components. This
reduces OS overhead and guarantees that equivalent paths compare
the same (modulo symlinks).
@@ -1017,124 +1041,122 @@ remap_filename (pfile, name, loc)
/../quux /quux
//quux //quux (POSIX allows leading // as a namespace escape)
- Guarantees no trailing slashes. All transforms reduce the length
- of the string. Returns PATH;
- */
+ Guarantees no trailing slashes. All transforms reduce the length
+ of the string. Returns PATH. errno is 0 if no error occurred;
+ nonzero if an error occurred when using stat () or lstat (). */
+
char *
_cpp_simplify_pathname (path)
char *path;
{
- char *from, *to;
- char *base;
- int absolute = 0;
+#ifndef VMS
+ char *from, *to;
+ char *base, *orig_base;
+ int absolute = 0;
+
+ errno = 0;
+ /* Don't overflow the empty path by putting a '.' in it below. */
+ if (*path == '\0')
+ return path;
#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
- /* Convert all backslashes to slashes. */
- for (from = path; *from; from++)
- if (*from == '\\') *from = '/';
+ /* 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
+ /* 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 == '/')
+ /* Remove redundant leading /s. */
+ if (*from == '/')
{
- absolute = 1;
- to++;
- from++;
- 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++;
+ 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 (;;)
+
+ base = orig_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] == '/')
+ int move_base = 0;
+
+ while (*from == '/')
+ from++;
+
+ if (*from == '\0')
+ break;
+
+ if (*from == '.')
{
- if (base == to)
- {
- if (absolute)
- from += 3;
- else
- {
- *to++ = *from++;
- *to++ = *from++;
- *to++ = *from++;
- base = to;
- }
- }
- else
+ if (from[1] == '\0')
+ break;
+ if (from[1] == '/')
{
- to -= 2;
- while (to > base && *to != '/') to--;
- if (*to == '/')
- to++;
- from += 3;
+ from += 2;
+ continue;
}
- }
- else if (from[0] == '.' && from[1] == '.' && from[2] == '\0')
- {
- if (base == to)
+ else if (from[1] == '.' && (from[2] == '/' || from[2] == '\0'))
{
- if (!absolute)
+ /* Don't simplify if there was no previous component. */
+ if (absolute && orig_base == to)
{
- *to++ = *from++;
- *to++ = *from++;
+ from += 2;
+ continue;
}
- }
- 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])
+ /* Don't simplify if the previous component was "../",
+ or if an error has already occurred with (l)stat. */
+ if (base != to && errno == 0)
{
- to--;
- goto done;
+ /* We don't back up if it's a symlink. */
+ *to = '\0';
+ if (remove_component_p (path))
+ {
+ while (to > base && *to != '/')
+ to--;
+ from += 2;
+ continue;
+ }
}
+ move_base = 1;
}
-
+ }
+
+ /* Add the component separator. */
+ if (to > orig_base)
+ *to++ = '/';
+
+ /* Copy this component until the trailing null or '/'. */
+ while (*from != '\0' && *from != '/')
+ *to++ = *from++;
+
+ if (move_base)
+ base = to;
}
- 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 path;
+ /* Change the empty string to "." so that it is not treated as stdin.
+ Null terminate. */
+ if (to == path)
+ *to++ = '.';
+ *to = '\0';
+
+ return path;
+#else /* VMS */
+ errno = 0;
+ return path;
+#endif /* !VMS */
}
diff --git a/gcc/cppinit.c b/gcc/cppinit.c
index 13a0e64..980cdb1 100644
--- a/gcc/cppinit.c
+++ b/gcc/cppinit.c
@@ -211,10 +211,12 @@ append_include_chain (pfile, dir, path, cxx_aware)
struct stat st;
unsigned int len;
+ if (*dir == '\0')
+ dir = xstrdup (".");
_cpp_simplify_pathname (dir);
if (stat (dir, &st))
{
- /* Dirs that don't exist are silently ignored. */
+ /* Dirs that don't exist are silently ignored. */
if (errno != ENOENT)
cpp_notice_from_errno (pfile, dir);
else if (CPP_OPTION (pfile, verbose))
diff --git a/gcc/cpplib.c b/gcc/cpplib.c
index 5a523e0..56ffbb1 100644
--- a/gcc/cpplib.c
+++ b/gcc/cpplib.c
@@ -729,12 +729,7 @@ do_line (pfile)
cpp_get_token (pfile, &token);
if (token.type == CPP_STRING)
{
- char *fname;
- unsigned int len = token.val.str.len + 1;
-
- fname = (char *) _cpp_pool_alloc (&pfile->ident_pool, len);
- memcpy (fname, token.val.str.text, len);
- _cpp_simplify_pathname (fname);
+ const char *fname = (const char *) token.val.str.text;
/* Only accept flags for the # 55 form. */
if (! pfile->state.line_extension)