makedep: For generated headers, parse the source idl instead.
This avoids having to generate all the headers before make depend.
diff --git a/tools/makedep.c b/tools/makedep.c
index 71c0032..905c93b 100644
--- a/tools/makedep.c
+++ b/tools/makedep.c
@@ -42,6 +42,7 @@
struct list entry;
char *name;
char *filename;
+ char *sourcename; /* source file name for generated headers */
struct _INCL_FILE *included_by; /* file that included this one */
int included_line; /* line where this file was included */
int system; /* is it a system include (#include <name>) */
@@ -107,7 +108,7 @@
/*******************************************************************
* xrealloc
*/
-void *xrealloc (void *ptr, size_t size)
+static void *xrealloc (void *ptr, size_t size)
{
void *res;
assert( size );
@@ -130,7 +131,7 @@
/*******************************************************************
* strmake
*/
-char *strmake( const char* fmt, ... )
+static char *strmake( const char* fmt, ... )
{
int n;
size_t size = 100;
@@ -151,6 +152,17 @@
/*******************************************************************
+ * strendswith
+ */
+static int strendswith( const char* str, const char* end )
+{
+ int l = strlen(str);
+ int m = strlen(end);
+
+ return l >= m && strcmp(str + l - m, end) == 0;
+}
+
+/*******************************************************************
* get_extension
*/
static char *get_extension( char *filename )
@@ -206,23 +218,6 @@
}
/*******************************************************************
- * is_generated
- *
- * Test if a given file type is generated during the make process
- */
-static int is_generated( const char *name )
-{
- static const char * const extensions[] = { ".tab.h", ".mc.rc" };
- size_t i, len = strlen(name);
- for (i = 0; i < sizeof(extensions)/sizeof(extensions[0]); i++)
- {
- if (len <= strlen(extensions[i])) continue;
- if (!strcmp( name + len - strlen(extensions[i]), extensions[i] )) return 1;
- }
- return 0;
-}
-
-/*******************************************************************
* add_include_path
*
* Add a directory to the include path.
@@ -304,7 +299,7 @@
include->name = xstrdup(name);
include->included_by = pFile;
include->included_line = line;
- include->system = system || pFile->system;
+ include->system = system;
list_add_tail( &includes, &include->entry );
found:
pFile->files[pos] = include;
@@ -351,6 +346,66 @@
errno = ENOENT;
+ /* check for generated bison header */
+
+ if (strendswith( pFile->name, ".tab.h" ))
+ {
+ if (src_dir)
+ filename = strmake( "%s/%.*s.y", src_dir, strlen(pFile->name) - 6, pFile->name );
+ else
+ filename = strmake( "%.*s.y", strlen(pFile->name) - 6, pFile->name );
+
+ if ((file = fopen( filename, "r" )))
+ {
+ pFile->sourcename = filename;
+ pFile->filename = xstrdup( pFile->name );
+ /* don't bother to parse it */
+ fclose( file );
+ return NULL;
+ }
+ free( filename );
+ }
+
+ /* check for generated message resource */
+
+ if (strendswith( pFile->name, ".mc.rc" ))
+ {
+ if (src_dir)
+ filename = strmake( "%s/%s", src_dir, pFile->name );
+ else
+ filename = xstrdup( pFile->name );
+
+ filename[strlen(filename) - 3] = 0;
+
+ if ((file = fopen( filename, "r" )))
+ {
+ pFile->sourcename = filename;
+ pFile->filename = xstrdup( pFile->name );
+ /* don't bother to parse it */
+ fclose( file );
+ return NULL;
+ }
+ free( filename );
+ }
+
+ /* check for corresponding idl file in source dir */
+
+ if (strendswith( pFile->name, ".h" ))
+ {
+ if (src_dir)
+ filename = strmake( "%s/%.*s.idl", src_dir, strlen(pFile->name) - 2, pFile->name );
+ else
+ filename = strmake( "%.*s.idl", strlen(pFile->name) - 2, pFile->name );
+
+ if ((file = fopen( filename, "r" )))
+ {
+ pFile->sourcename = filename;
+ pFile->filename = xstrdup( pFile->name );
+ return file;
+ }
+ free( filename );
+ }
+
/* first try name as is */
if ((file = fopen( pFile->name, "r" )))
{
@@ -366,6 +421,28 @@
free( filename );
}
+ /* check for corresponding idl file in global includes */
+
+ if (strendswith( pFile->name, ".h" ))
+ {
+ if (top_src_dir)
+ filename = strmake( "%s/include/%.*s.idl",
+ top_src_dir, strlen(pFile->name) - 2, pFile->name );
+ else if (top_obj_dir)
+ filename = strmake( "%s/include/%.*s.idl",
+ top_obj_dir, strlen(pFile->name) - 2, pFile->name );
+ else
+ filename = NULL;
+
+ if (filename && (file = fopen( filename, "r" )))
+ {
+ pFile->sourcename = filename;
+ pFile->filename = strmake( "%s/include/%s", top_obj_dir, pFile->name );
+ return file;
+ }
+ free( filename );
+ }
+
/* now try in global includes */
if (top_obj_dir)
{
@@ -400,13 +477,13 @@
free( filename );
}
- if (pFile->included_by->system) return NULL; /* ignore if included by a system file */
-
perror( pFile->name );
while (pFile->included_by)
{
+ const char *parent = pFile->included_by->sourcename;
+ if (!parent) parent = pFile->included_by->name;
fprintf( stderr, " %s was first included from %s:%d\n",
- pFile->name, pFile->included_by->name, pFile->included_line );
+ pFile->name, parent, pFile->included_line );
pFile = pFile->included_by;
}
exit(1);
@@ -419,11 +496,21 @@
/*******************************************************************
* parse_idl_file
+ *
+ * If for_h_file is non-zero, it means we are not interested in the idl file
+ * itself, but only in the contents of the .h file that will be generated from it.
*/
-static void parse_idl_file( INCL_FILE *pFile, FILE *file )
+static void parse_idl_file( INCL_FILE *pFile, FILE *file, int for_h_file )
{
char *buffer, *include;
+ if (for_h_file)
+ {
+ /* generated .h file always includes these */
+ add_include( pFile, "rpc.h", 0, 1 );
+ add_include( pFile, "rpcndr.h", 0, 1 );
+ }
+
input_line = 0;
while ((buffer = get_line( file )))
{
@@ -435,24 +522,62 @@
{
p += 6;
while (*p && isspace(*p)) p++;
- if (*p != '\"') continue;
+ if (*p != '"') continue;
+ include = ++p;
+ while (*p && (*p != '"')) p++;
+ if (!*p) fatal_error( "%s:%d: Malformed import directive\n", pFile->filename, input_line );
+ *p = 0;
+ if (for_h_file && strendswith( include, ".idl" )) strcpy( p - 4, ".h" );
+ add_include( pFile, include, input_line, 0 );
+ continue;
}
- else
+
+ if (for_h_file) /* only check for #include inside cpp_quote */
{
+ if (strncmp( p, "cpp_quote", 9 )) continue;
+ p += 9;
+ while (*p && isspace(*p)) p++;
+ if (*p++ != '(') continue;
+ while (*p && isspace(*p)) p++;
+ if (*p++ != '"') continue;
if (*p++ != '#') continue;
while (*p && isspace(*p)) p++;
if (strncmp( p, "include", 7 )) continue;
p += 7;
while (*p && isspace(*p)) p++;
- if (*p != '\"' && *p != '<' ) continue;
+ if (*p == '\\' && p[1] == '"')
+ {
+ p += 2;
+ quote = '"';
+ }
+ else
+ {
+ if (*p++ != '<' ) continue;
+ quote = '>';
+ }
+ include = p;
+ while (*p && (*p != quote)) p++;
+ if (!*p || (quote == '"' && p[-1] != '\\'))
+ fatal_error( "%s:%d: Malformed #include directive inside cpp_quote\n",
+ pFile->filename, input_line );
+ if (quote == '"') p--; /* remove backslash */
+ *p = 0;
+ add_include( pFile, include, input_line, (quote == '>') );
+ continue;
}
+ /* check for normal #include */
+ if (*p++ != '#') continue;
+ while (*p && isspace(*p)) p++;
+ if (strncmp( p, "include", 7 )) continue;
+ p += 7;
+ while (*p && isspace(*p)) p++;
+ if (*p != '\"' && *p != '<' ) continue;
quote = *p++;
if (quote == '<') quote = '>';
include = p;
while (*p && (*p != quote)) p++;
- if (!*p) fatal_error( "%s:%d: Malformed #include or import directive\n",
- pFile->filename, input_line );
+ if (!*p) fatal_error( "%s:%d: Malformed #include directive\n", pFile->filename, input_line );
*p = 0;
add_include( pFile, include, input_line, (quote == '>') );
}
@@ -494,21 +619,17 @@
*/
static void parse_file( INCL_FILE *pFile, int src )
{
- char *ext;
FILE *file;
- if (is_generated( pFile->name ))
- {
- /* file is generated during make, don't try to open it */
- pFile->filename = xstrdup( pFile->name );
- return;
- }
-
file = src ? open_src_file( pFile ) : open_include_file( pFile );
if (!file) return;
- ext = get_extension( pFile->name );
- if (ext && !strcmp( ext, ".idl" )) parse_idl_file( pFile, file );
- else parse_c_file( pFile, file );
+
+ if (pFile->sourcename && strendswith( pFile->sourcename, ".idl" ))
+ parse_idl_file( pFile, file, 1 );
+ else if (strendswith( pFile->filename, ".idl" ))
+ parse_idl_file( pFile, file, 0 );
+ else
+ parse_c_file( pFile, file );
fclose(file);
}