File size: 3,909 Bytes
158b61b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
/*
* Copyright 1993, 2000 Christopher Seiwald.
*
* This file is part of Jam - see jam.c for Copyright information.
*/
/* This file is ALSO:
* Copyright 2001-2004 David Abrahams.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
*/
/*
* hdrmacro.c - handle header files that define macros used in #include
* statements.
*
* we look for lines like "#define MACRO <....>" or '#define MACRO " "' in
* the target file. When found, we then phony up a rule invocation like:
*
* $(HDRRULE) <target> : <resolved included files> ;
*
* External routines:
* headers1() - scan a target for "#include MACRO" lines and try to resolve
* them when needed
*
* Internal routines:
* headers1() - using regexp, scan a file and build include LIST
*/
#include "jam.h"
#include "hdrmacro.h"
#include "compile.h"
#include "hash.h"
#include "lists.h"
#include "object.h"
#include "parse.h"
#include "rules.h"
#include "strings.h"
#include "subst.h"
#include "variable.h"
/* this type is used to store a dictionary of file header macros */
typedef struct header_macro
{
OBJECT * symbol;
OBJECT * filename; /* we could maybe use a LIST here ?? */
} HEADER_MACRO;
static struct hash * header_macros_hash = 0;
/*
* headers() - scan a target for include files and call HDRRULE
*/
#define MAXINC 10
void macro_headers( TARGET * t )
{
static regexp * re = 0;
FILE * f;
char buf[ 1024 ];
if ( DEBUG_HEADER )
printf( "macro header scan for %s\n", object_str( t->name ) );
/* This regexp is used to detect lines of the form
* "#define MACRO <....>" or "#define MACRO "....."
* in the header macro files.
*/
if ( !re )
{
OBJECT * const re_str = object_new(
"^[ ]*#[ ]*define[ ]*([A-Za-z][A-Za-z0-9_]*)[ ]*"
"[<\"]([^\">]*)[\">].*$" );
re = regex_compile( re_str );
object_free( re_str );
}
if ( !( f = fopen( object_str( t->boundname ), "r" ) ) )
return;
while ( fgets( buf, sizeof( buf ), f ) )
{
HEADER_MACRO var;
HEADER_MACRO * v = &var;
if ( regexec( re, buf ) && re->startp[ 1 ] )
{
OBJECT * symbol;
int found;
/* we detected a line that looks like "#define MACRO filename */
( (char *)re->endp[ 1 ] )[ 0 ] = '\0';
( (char *)re->endp[ 2 ] )[ 0 ] = '\0';
if ( DEBUG_HEADER )
printf( "macro '%s' used to define filename '%s' in '%s'\n",
re->startp[ 1 ], re->startp[ 2 ], object_str( t->boundname )
);
/* add macro definition to hash table */
if ( !header_macros_hash )
header_macros_hash = hashinit( sizeof( HEADER_MACRO ),
"hdrmacros" );
symbol = object_new( re->startp[ 1 ] );
v = (HEADER_MACRO *)hash_insert( header_macros_hash, symbol, &found
);
if ( !found )
{
v->symbol = symbol;
v->filename = object_new( re->startp[ 2 ] ); /* never freed */
}
else
object_free( symbol );
/* XXXX: FOR NOW, WE IGNORE MULTIPLE MACRO DEFINITIONS !! */
/* WE MIGHT AS WELL USE A LIST TO STORE THEM.. */
}
}
fclose( f );
}
OBJECT * macro_header_get( OBJECT * macro_name )
{
HEADER_MACRO * v;
if ( header_macros_hash && ( v = (HEADER_MACRO *)hash_find(
header_macros_hash, macro_name ) ) )
{
if ( DEBUG_HEADER )
printf( "### macro '%s' evaluated to '%s'\n", object_str( macro_name
), object_str( v->filename ) );
return v->filename;
}
return 0;
}
|