mirror of
https://github.com/boostorg/build.git
synced 2026-02-14 12:42:11 +00:00
140 lines
3.8 KiB
C
140 lines
3.8 KiB
C
/*
|
|
* 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)
|
|
*/
|
|
|
|
# include "jam.h"
|
|
# include "lists.h"
|
|
# include "parse.h"
|
|
# include "compile.h"
|
|
# include "rules.h"
|
|
# include "variable.h"
|
|
# include "regexp.h"
|
|
# include "hdrmacro.h"
|
|
# include "hash.h"
|
|
# include "newstr.h"
|
|
# include "strings.h"
|
|
|
|
/*
|
|
* 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
|
|
*
|
|
* 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
|
|
*
|
|
* 04/13/94 (seiwald) - added shorthand L0 for null list pointer
|
|
* 09/10/00 (seiwald) - replaced call to compile_rule with evaluate_rule,
|
|
* so that headers() doesn't have to mock up a parse structure
|
|
* just to invoke a rule.
|
|
*/
|
|
|
|
static LIST *header_macros1( LIST *l, char *file, int rec, regexp *re[] );
|
|
|
|
/* this type is used to store a dictionary of file header macros */
|
|
typedef struct header_macro
|
|
{
|
|
char* symbol;
|
|
char* 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", t->name );
|
|
|
|
/* this regexp is used to detect lines of the form */
|
|
/* "#define MACRO <....>" or "#define MACRO "....." */
|
|
/* in the header macro files.. */
|
|
if ( re == 0 )
|
|
{
|
|
re = regex_compile(
|
|
"^[ ]*#[ ]*define[ ]*([A-Za-z][A-Za-z0-9_]*)[ ]*"
|
|
"[<\"]([^\">]*)[\">].*$" );
|
|
}
|
|
|
|
if( !( f = fopen( t->boundname, "r" ) ) )
|
|
return;
|
|
|
|
while( fgets( buf, sizeof( buf ), f ) )
|
|
{
|
|
HEADER_MACRO var, *v = &var;
|
|
|
|
if ( regexec( re, buf ) && re->startp[1] )
|
|
{
|
|
/* we detected a line that looks like "#define MACRO filename */
|
|
re->endp[1][0] = '\0';
|
|
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], t->boundname );
|
|
|
|
/* add macro definition to hash table */
|
|
if ( !header_macros_hash )
|
|
header_macros_hash = hashinit( sizeof( HEADER_MACRO ), "hdrmacros" );
|
|
|
|
v->symbol = re->startp[1];
|
|
v->filename = 0;
|
|
if ( hashenter( header_macros_hash, (HASHDATA **)&v ) )
|
|
{
|
|
v->symbol = newstr( re->startp[1] ); /* never freed */
|
|
v->filename = newstr( re->startp[2] ); /* never freed */
|
|
}
|
|
/* XXXX: FOR NOW, WE IGNORE MULTIPLE MACRO DEFINITIONS !! */
|
|
/* WE MIGHT AS WELL USE A LIST TO STORE THEM.. */
|
|
}
|
|
}
|
|
|
|
fclose( f );
|
|
}
|
|
|
|
|
|
char*
|
|
macro_header_get( const char* macro_name )
|
|
{
|
|
HEADER_MACRO var, *v = &var;
|
|
|
|
v->symbol = (char*)macro_name;
|
|
|
|
if( header_macros_hash && hashcheck( header_macros_hash, (HASHDATA **)&v ) )
|
|
{
|
|
if ( DEBUG_HEADER )
|
|
printf( "### macro '%s' evaluated to '%s'\n", macro_name, v->filename );
|
|
return v->filename;
|
|
}
|
|
return 0;
|
|
}
|
|
|