summaryrefslogtreecommitdiff
path: root/tools/build/src/engine/hdrmacro.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/build/src/engine/hdrmacro.c')
-rw-r--r--tools/build/src/engine/hdrmacro.c139
1 files changed, 139 insertions, 0 deletions
diff --git a/tools/build/src/engine/hdrmacro.c b/tools/build/src/engine/hdrmacro.c
new file mode 100644
index 000000000..eb4fe90f4
--- /dev/null
+++ b/tools/build/src/engine/hdrmacro.c
@@ -0,0 +1,139 @@
+/*
+ * 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;
+}