Commit 986b1f13 by Neil Booth Committed by Neil Booth

c-incpath.c (remove_component_p, [...]): Move back to cppfiles.c.

	* c-incpath.c (remove_component_p, simplify_path): Move back to
	cppfiles.c.
	(remove_duplicates): Use cpp_simplify_path.
	* c-incpath.h (simplify_path): Remove.
	* c-lex.c: Don't include c-incpath.h.
	(init_c_lex): Remove simplify_path.
	* cppfiles.c (remove_component_p, cpp_simplify_path): Restore.
	(find_or_create_entry, validate_pch): Revert.

From-SVN: r63669
parent a339cb5b
2003-03-02 Neil Booth <neil@daikokuya.co.uk>
* c-incpath.c (remove_component_p, simplify_path): Move back to
cppfiles.c.
(remove_duplicates): Use cpp_simplify_path.
* c-incpath.h (simplify_path): Remove.
* c-lex.c: Don't include c-incpath.h.
(init_c_lex): Remove simplify_path.
* cppfiles.c (remove_component_p, cpp_simplify_path): Restore.
(find_or_create_entry, validate_pch): Revert.
2003-03-02 Ashif Harji <asharji@uwaterloo.ca>
* gcc.c (default_compilers): Add -no-integrated-cpp flag to invoke
......
......@@ -47,7 +47,6 @@ static void add_env_var_paths PARAMS ((const char *, int));
static void add_standard_paths PARAMS ((const char *, const char *, int));
static void free_path PARAMS ((struct cpp_path *, int));
static void merge_include_chains PARAMS ((cpp_reader *, int));
static int remove_component_p PARAMS ((const char *));
static struct cpp_path *
remove_duplicates PARAMS ((cpp_reader *, struct cpp_path *,
struct cpp_path *, struct cpp_path *, int));
......@@ -177,7 +176,7 @@ remove_duplicates (pfile, head, system, join, verbose)
int reason = REASON_QUIET;
cur = *pcur;
simplify_path (cur->name);
cpp_simplify_path (cur->name);
if (stat (cur->name, &st))
{
......@@ -355,156 +354,3 @@ register_include_chains (pfile, sysroot, iprefix,
cpp_set_include_chains (pfile, heads[QUOTE], heads[BRACKET],
quote_ignores_source_dir);
}
/* 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
/* There's no guarantee that errno will be unchanged, even on
success. Cygwin's lstat(), for example, will often set errno to
ENOSYS. In case of success, reset errno to zero. */
if (result == 0)
errno = 0;
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).
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. Returns PATH. errno is 0 if no error occurred;
nonzero if an error occurred when using stat () or lstat (). */
void
simplify_path (path)
char *path ATTRIBUTE_UNUSED;
{
#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;
#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
/* 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 leading /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 = orig_base = to;
for (;;)
{
int move_base = 0;
while (*from == '/')
from++;
if (*from == '\0')
break;
if (*from == '.')
{
if (from[1] == '\0')
break;
if (from[1] == '/')
{
from += 2;
continue;
}
else if (from[1] == '.' && (from[2] == '/' || from[2] == '\0'))
{
/* Don't simplify if there was no previous component. */
if (absolute && orig_base == to)
{
from += 2;
continue;
}
/* Don't simplify if the previous component was "../",
or if an error has already occurred with (l)stat. */
if (base != to && errno == 0)
{
/* 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;
}
/* Change the empty string to "." so that it is not treated as stdin.
Null terminate. */
if (to == path)
*to++ = '.';
*to = '\0';
#else /* VMS */
errno = 0;
#endif /* !VMS */
}
......@@ -19,6 +19,5 @@ extern void split_quote_chain PARAMS ((void));
extern void add_path PARAMS ((char *, int, int));
extern void register_include_chains PARAMS ((cpp_reader *, const char *,
const char *, int, int, int));
extern void simplify_path PARAMS ((char *));
enum { QUOTE = 0, BRACKET, SYSTEM, AFTER };
......@@ -41,7 +41,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tm_p.h"
#include "splay-tree.h"
#include "debug.h"
#include "c-incpath.h"
#ifdef MULTIBYTE_CHARS
#include "mbchar.h"
......@@ -125,7 +124,6 @@ init_c_lex (filename)
cb->ident = cb_ident;
cb->file_change = cb_file_change;
cb->def_pragma = cb_def_pragma;
cb->simplify_path = simplify_path;
cb->valid_pch = c_common_valid_pch;
cb->read_pch = c_common_read_pch;
......
......@@ -153,6 +153,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
......@@ -160,7 +161,7 @@ static void handle_missing_header PARAMS ((cpp_reader *, const char *, int));
don't try to open it again in future.
The key of each node is the file name, after processing by
simplify_path. The path name may or may not be absolute.
cpp_simplify_path. The path name may or may not be absolute.
The path string has been malloced, as is automatically freed by
registering free () as the splay tree key deletion function.
......@@ -216,15 +217,8 @@ find_or_create_entry (pfile, fname)
splay_tree_node node;
struct include_file *file;
char *name = xstrdup (fname);
int saved_errno = 0;
if (pfile->cb.simplify_path)
{
errno = 0;
(pfile->cb.simplify_path) (name);
saved_errno = errno;
}
cpp_simplify_path (name);
node = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) name);
if (node)
free (name);
......@@ -233,7 +227,7 @@ find_or_create_entry (pfile, fname)
file = xcnew (struct include_file);
file->name = name;
file->header_name = name;
file->err_no = saved_errno;
file->err_no = errno;
node = splay_tree_insert (pfile->all_include_files,
(splay_tree_key) file->name,
(splay_tree_value) file);
......@@ -343,7 +337,7 @@ validate_pch (pfile, filename, pchname)
if (INCLUDE_PCH_P (file))
{
char *f = xstrdup (filename);
(pfile->cb.simplify_path) (f);
cpp_simplify_path (f);
file->header_name = f;
return file;
}
......@@ -1171,3 +1165,156 @@ cpp_set_include_chains (pfile, quote, bracket, quote_ignores_source_dir)
pfile->bracket_include = bracket;
}
}
/* 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
/* There's no guarantee that errno will be unchanged, even on
success. Cygwin's lstat(), for example, will often set errno to
ENOSYS. In case of success, reset errno to zero. */
if (result == 0)
errno = 0;
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).
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. Returns PATH. errno is 0 if no error occurred;
nonzero if an error occurred when using stat () or lstat (). */
void
cpp_simplify_path (path)
char *path ATTRIBUTE_UNUSED;
{
#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;
#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
/* 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 leading /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 = orig_base = to;
for (;;)
{
int move_base = 0;
while (*from == '/')
from++;
if (*from == '\0')
break;
if (*from == '.')
{
if (from[1] == '\0')
break;
if (from[1] == '/')
{
from += 2;
continue;
}
else if (from[1] == '.' && (from[2] == '/' || from[2] == '\0'))
{
/* Don't simplify if there was no previous component. */
if (absolute && orig_base == to)
{
from += 2;
continue;
}
/* Don't simplify if the previous component was "../",
or if an error has already occurred with (l)stat. */
if (base != to && errno == 0)
{
/* 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;
}
/* Change the empty string to "." so that it is not treated as stdin.
Null terminate. */
if (to == path)
*to++ = '.';
*to = '\0';
#else /* VMS */
errno = 0;
#endif /* !VMS */
}
......@@ -402,7 +402,6 @@ struct cpp_callbacks
void (*undef) PARAMS ((cpp_reader *, unsigned int, cpp_hashnode *));
void (*ident) PARAMS ((cpp_reader *, unsigned int, const cpp_string *));
void (*def_pragma) PARAMS ((cpp_reader *, unsigned int));
void (*simplify_path) PARAMS ((char *));
/* Called when the client has a chance to properly register
built-ins with cpp_define() and cpp_assert(). */
void (*register_builtins) PARAMS ((cpp_reader *));
......@@ -741,6 +740,7 @@ extern unsigned char *cpp_quote_string PARAMS ((unsigned char *,
/* In cppfiles.c */
extern int cpp_included PARAMS ((cpp_reader *, const char *));
extern void cpp_make_system_header PARAMS ((cpp_reader *, int, int));
extern void cpp_simplify_path PARAMS ((char *));
/* In cpppch.c */
struct save_macro_data;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment