cpp.texi: Document #pragma GCC dependency
* cpp.texi: Document #pragma GCC dependency * cppfiles.c (open_include_file): Set date to unknown. (_cpp_compare_file_date): New function. (read_include_file): Set file date. * cpphash.h (struct include_file): Add date member. (_cpp_compare_file_date): Prototype. * cpplib.c (parse_include): Add trail parameter. Adjust. (do_include): Adjust parse_include call. (do_import): Likewise. (do_include_next): Likewise. (gcc_pragmas): Add dependency pragma. (do_pragma_dependancy): New pragma. From-SVN: r34808
This commit is contained in:
parent
34f9943ef7
commit
f3f751adcb
@ -1,3 +1,18 @@
|
||||
2000-06-30 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* cpp.texi: Document #pragma GCC dependency
|
||||
* cppfiles.c (open_include_file): Set date to unknown.
|
||||
(_cpp_compare_file_date): New function.
|
||||
(read_include_file): Set file date.
|
||||
* cpphash.h (struct include_file): Add date member.
|
||||
(_cpp_compare_file_date): Prototype.
|
||||
* cpplib.c (parse_include): Add trail parameter. Adjust.
|
||||
(do_include): Adjust parse_include call.
|
||||
(do_import): Likewise.
|
||||
(do_include_next): Likewise.
|
||||
(gcc_pragmas): Add dependency pragma.
|
||||
(do_pragma_dependancy): New pragma.
|
||||
|
||||
2000-06-29 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* dwarf2out.c (output_loc_operands): Don't abort on codes that have
|
||||
|
14
gcc/cpp.texi
14
gcc/cpp.texi
@ -2664,6 +2664,20 @@ the text is ignored and this directive has no effect. Typically
|
||||
@samp{#ident} is only used in header files supplied with those systems
|
||||
where it is meaningful.
|
||||
|
||||
@findex #pragma GCC dependency
|
||||
The @samp{#pragma GCC dependency} allows you to check the relative dates
|
||||
of the current file and another file. If the other file is more
|
||||
recent than the current file, a warning is issued. This is useful if the
|
||||
include file is derived from the other file, and should be regenerated.
|
||||
The other file is searched for using the normal include search path.
|
||||
Optional trailing text can be used to give more information in the
|
||||
warning message.
|
||||
|
||||
@smallexample
|
||||
#pragma GCC dependency "parse.y"
|
||||
#pragma GCC dependency "/usr/include/time.h" rerun /path/to/fixincludes
|
||||
@end smallexample
|
||||
|
||||
@node Output, Invocation, Other Directives, Top
|
||||
@section C Preprocessor Output
|
||||
|
||||
|
@ -227,6 +227,7 @@ open_include_file (pfile, filename)
|
||||
}
|
||||
|
||||
file->fd = fd;
|
||||
file->date = (time_t) -1;
|
||||
return file;
|
||||
}
|
||||
|
||||
@ -465,6 +466,60 @@ _cpp_execute_include (pfile, f, len, no_reinclude, search_start)
|
||||
cpp_error_from_errno (pfile, fname);
|
||||
}
|
||||
|
||||
/* 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
|
||||
_cpp_compare_file_date (pfile, f, len, search_start)
|
||||
cpp_reader *pfile;
|
||||
U_CHAR *f;
|
||||
unsigned int len;
|
||||
struct file_name_list *search_start;
|
||||
{
|
||||
char *fname = (char *)f;
|
||||
int angle_brackets = fname[0] == '<';
|
||||
struct include_file *inc;
|
||||
struct include_file *current_include = cpp_file_buffer (pfile)->inc;
|
||||
|
||||
if (!search_start)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/* Remove quote marks. */
|
||||
fname++;
|
||||
len -= 2;
|
||||
fname[len] = '\0';
|
||||
|
||||
inc = find_include_file (pfile, fname, search_start);
|
||||
|
||||
if (!inc)
|
||||
return -1;
|
||||
if (inc->fd >= 0)
|
||||
{
|
||||
struct stat source;
|
||||
|
||||
if (fstat (inc->fd, &source) < 0)
|
||||
{
|
||||
close (inc->fd);
|
||||
inc->fd = -1;
|
||||
return -1;
|
||||
}
|
||||
inc->date = source.st_mtime;
|
||||
close (inc->fd);
|
||||
inc->fd = -1;
|
||||
}
|
||||
if (inc->date == (time_t)-1 || current_include->date == (time_t)-1)
|
||||
return -1;
|
||||
return inc->date > current_include->date;
|
||||
}
|
||||
|
||||
|
||||
/* Push an input buffer and load it up with the contents of FNAME.
|
||||
If FNAME is "" or NULL, read standard input. */
|
||||
int
|
||||
@ -502,6 +557,8 @@ read_include_file (pfile, inc)
|
||||
|
||||
if (fstat (fd, &st) < 0)
|
||||
goto perror_fail;
|
||||
|
||||
inc->date = st.st_mtime;
|
||||
|
||||
/* 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
|
||||
|
@ -64,6 +64,7 @@ struct include_file
|
||||
int fd; /* file descriptor possibly open on file */
|
||||
unsigned short include_count; /* number of times file has been read */
|
||||
unsigned short sysp; /* file is a system header */
|
||||
time_t date; /* modification date of file, if known */
|
||||
};
|
||||
|
||||
/* The cmacro works like this: If it's NULL, the file is to be
|
||||
@ -193,6 +194,9 @@ extern void _cpp_simplify_pathname PARAMS ((char *));
|
||||
extern void _cpp_execute_include PARAMS ((cpp_reader *, U_CHAR *,
|
||||
unsigned int, int,
|
||||
struct file_name_list *));
|
||||
extern int _cpp_compare_file_date PARAMS ((cpp_reader *, U_CHAR *,
|
||||
unsigned int,
|
||||
struct file_name_list *));
|
||||
extern void _cpp_init_include_table PARAMS ((cpp_reader *));
|
||||
extern const char *_cpp_fake_include PARAMS ((cpp_reader *, const char *));
|
||||
|
||||
|
54
gcc/cpplib.c
54
gcc/cpplib.c
@ -52,7 +52,7 @@ struct if_stack
|
||||
/* Forward declarations. */
|
||||
|
||||
static void validate_else PARAMS ((cpp_reader *, const U_CHAR *));
|
||||
static unsigned int parse_include PARAMS ((cpp_reader *, const U_CHAR *));
|
||||
static unsigned int parse_include PARAMS ((cpp_reader *, const U_CHAR *, int));
|
||||
static void push_conditional PARAMS ((cpp_reader *, int, int,
|
||||
const cpp_hashnode *));
|
||||
static void pass_thru_directive PARAMS ((const U_CHAR *, size_t,
|
||||
@ -398,9 +398,10 @@ do_define (pfile)
|
||||
/* Handle #include and #import. */
|
||||
|
||||
static unsigned int
|
||||
parse_include (pfile, name)
|
||||
parse_include (pfile, name, trail)
|
||||
cpp_reader *pfile;
|
||||
const U_CHAR *name;
|
||||
int trail;
|
||||
{
|
||||
long old_written = CPP_WRITTEN (pfile);
|
||||
enum cpp_ttype token;
|
||||
@ -420,7 +421,7 @@ parse_include (pfile, name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_cpp_get_directive_token (pfile) != CPP_VSPACE)
|
||||
if (!trail && _cpp_get_directive_token (pfile) != CPP_VSPACE)
|
||||
{
|
||||
cpp_error (pfile, "junk at end of #%s", name);
|
||||
_cpp_skip_rest_of_line (pfile);
|
||||
@ -441,7 +442,7 @@ do_include (pfile)
|
||||
unsigned int len;
|
||||
U_CHAR *token;
|
||||
|
||||
len = parse_include (pfile, dtable[T_INCLUDE].name);
|
||||
len = parse_include (pfile, dtable[T_INCLUDE].name, 0);
|
||||
if (len == 0)
|
||||
return 0;
|
||||
token = (U_CHAR *) alloca (len + 1);
|
||||
@ -470,7 +471,7 @@ do_import (pfile)
|
||||
"#import is obsolete, use an #ifndef wrapper in the header file");
|
||||
}
|
||||
|
||||
len = parse_include (pfile, dtable[T_IMPORT].name);
|
||||
len = parse_include (pfile, dtable[T_IMPORT].name, 0);
|
||||
if (len == 0)
|
||||
return 0;
|
||||
token = (U_CHAR *) alloca (len + 1);
|
||||
@ -492,7 +493,7 @@ do_include_next (pfile)
|
||||
U_CHAR *token;
|
||||
struct file_name_list *search_start = 0;
|
||||
|
||||
len = parse_include (pfile, dtable[T_INCLUDE_NEXT].name);
|
||||
len = parse_include (pfile, dtable[T_INCLUDE_NEXT].name, 0);
|
||||
if (len == 0)
|
||||
return 0;
|
||||
token = (U_CHAR *) alloca (len + 1);
|
||||
@ -803,6 +804,7 @@ static int do_pragma_poison PARAMS ((cpp_reader *));
|
||||
static int do_pragma_system_header PARAMS ((cpp_reader *));
|
||||
static int do_pragma_default PARAMS ((cpp_reader *));
|
||||
static int do_pragma_gcc PARAMS ((cpp_reader *));
|
||||
static int do_pragma_dependency PARAMS ((cpp_reader *));
|
||||
|
||||
static const struct pragma_entry top_pragmas[] =
|
||||
{
|
||||
@ -819,6 +821,7 @@ static const struct pragma_entry gcc_pragmas[] =
|
||||
{"implementation", do_pragma_implementation},
|
||||
{"poison", do_pragma_poison},
|
||||
{"system_header", do_pragma_system_header},
|
||||
{"dependency", do_pragma_dependency},
|
||||
{NULL, do_pragma_default}
|
||||
};
|
||||
|
||||
@ -1033,7 +1036,44 @@ do_pragma_system_header (pfile)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Check the modified date of the current include file against a specified
|
||||
file. Issue a diagnostic, if the specified file is newer. We use this to
|
||||
determine if a fixed header should be refixed. */
|
||||
static int
|
||||
do_pragma_dependency (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
U_CHAR *original_name, *name;
|
||||
unsigned len;
|
||||
int ordering;
|
||||
|
||||
len = parse_include (pfile, (const U_CHAR *)"pragma dependency", 1);
|
||||
original_name = (U_CHAR *) alloca (len + 1);
|
||||
name = (U_CHAR *) alloca (len + 1);
|
||||
memcpy (original_name, CPP_PWRITTEN (pfile), len);
|
||||
memcpy (name, CPP_PWRITTEN (pfile), len);
|
||||
original_name[len] = name[len] = 0;
|
||||
|
||||
ordering = _cpp_compare_file_date (pfile, name, len, 0);
|
||||
if (ordering < 0)
|
||||
cpp_warning (pfile, "cannot find source %s", original_name);
|
||||
else if (ordering > 0)
|
||||
{
|
||||
const U_CHAR *text, *limit;
|
||||
_cpp_skip_hspace (pfile);
|
||||
text = CPP_BUFFER (pfile)->cur;
|
||||
_cpp_skip_rest_of_line (pfile);
|
||||
limit = CPP_BUFFER (pfile)->cur;
|
||||
|
||||
cpp_warning (pfile, "current file is older than %s", original_name);
|
||||
if (limit != text)
|
||||
cpp_warning (pfile, "%.*s", (int)(limit - text), text);
|
||||
}
|
||||
_cpp_skip_rest_of_line (pfile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Just ignore #sccs, on systems where we define it at all. */
|
||||
#ifdef SCCS_DIRECTIVE
|
||||
static int
|
||||
|
Loading…
Reference in New Issue
Block a user