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:
Nathan Sidwell 2000-06-30 09:47:49 +00:00 committed by Nathan Sidwell
parent 34f9943ef7
commit f3f751adcb
5 changed files with 137 additions and 7 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 *));

View File

@ -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