diff options
Diffstat (limited to 'jam-files/engine/hdrmacro.c')
-rw-r--r-- | jam-files/engine/hdrmacro.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/jam-files/engine/hdrmacro.c b/jam-files/engine/hdrmacro.c new file mode 100644 index 00000000..43031d48 --- /dev/null +++ b/jam-files/engine/hdrmacro.c @@ -0,0 +1,137 @@ +/* + * 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. + */ + +/* 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; + HEADER_MACRO *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; + HEADER_MACRO * 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; +} |