2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-16 13:22:11 +00:00
Files
build/v2/engine/hdrmacro.c
Steven Watanabe ceacd17a2c Fix alias violations in hash.
[SVN r77190]
2012-03-03 21:46:53 +00:00

143 lines
4.0 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 "object.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.
*/
/* 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 == 0 )
{
OBJECT * 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;
}