2 * Copyright 1993, 2000 Christopher Seiwald.
4 * This file is part of Jam - see jam.c for Copyright information.
18 * hdrmacro.c - handle header files that define macros used in
19 * #include statements.
21 * we look for lines like "#define MACRO <....>" or '#define MACRO " "'
22 * in the target file. When found, we
24 * we then phony up a rule invocation like:
26 * $(HDRRULE) <target> : <resolved included files> ;
29 * headers1() - scan a target for "#include MACRO" lines and try
30 * to resolve them when needed
33 * headers1() - using regexp, scan a file and build include LIST
35 * 04/13/94 (seiwald) - added shorthand L0 for null list pointer
36 * 09/10/00 (seiwald) - replaced call to compile_rule with evaluate_rule,
37 * so that headers() doesn't have to mock up a parse structure
38 * just to invoke a rule.
41 /*k8: static LIST *header_macros1(LIST *l, char *file, int rec, HSRegExp *re[]);*/
44 /* this type is used to store a dictionary of file header macros */
45 typedef struct header_macro
{
47 const char* filename
; /* we could maybe use a LIST here ?? */
50 static struct hash
*header_macros_hash
= 0;
54 * headers() - scan a target for include files and call HDRRULE
58 void macro_headers (TARGET
*t
) {
65 if (DEBUG_HEADER
) printf("macro header scan for %s\n", t
->name
);
66 /* this regexp is used to detect lines of the form */
67 /* "#define MACRO <....>" or "#define MACRO "....." */
68 /* in the header macro files */
69 if ((f
= fopen(t
->boundname
, "r")) == 0) return;
70 err
= hsrxCompile(&re
, "^[[:space:]]*#[[:space:]]*define[[:space:]]*([A-Za-z][A-Za-z0-9_]*)[[:space:]]*[<\"]([^\">]*)[\">].*$", HSRX_EXTENDED
);
72 hsrxError(err
, &re
, buf
, sizeof(buf
));
74 printf("FATAL: %s\n", buf
);
77 while (fgets(buf
, sizeof(buf
), f
)) {
78 HEADER_MACRO var
, *v
= &var
;
80 if (hsrxExec(&re
, buf
, 3, mt
, 0) == HSRX_NOERROR
) {
81 char buf1
[MAXSYM
], buf2
[MAXSYM
];
84 l1
= mt
[1].rm_eo
-mt
[1].rm_so
;
85 l2
= mt
[2].rm_eo
-mt
[2].rm_so
;
86 if (l1
> 0 && l2
> 0) {
87 memcpy(buf1
, buf
+mt
[1].rm_so
, l1
); buf1
[l1
] = '\0';
88 memcpy(buf2
, buf
+mt
[2].rm_so
, l2
); buf2
[l2
] = '\0';
89 /* we detected a line that looks like "#define MACRO filename */
90 if (DEBUG_HEADER
) printf("macro '%s' used to define filename '%s' in '%s'\n", buf1
, buf2
, t
->boundname
);
91 /* add macro definition to hash table */
92 if (!header_macros_hash
) header_macros_hash
= hashinit(sizeof(HEADER_MACRO
), "hdrmacros");
93 v
->symbol
= (const char *)buf1
;
95 if (hashenter(header_macros_hash
, (HASHDATA
**)&v
)) {
96 v
->symbol
= newstr(buf1
); /* never freed */
97 v
->filename
= newstr(buf2
); /* never freed */
100 /* XXXX: FOR NOW, WE IGNORE MULTIPLE MACRO DEFINITIONS! */
101 /* WE MIGHT AS WELL USE A LIST TO STORE THEM */
109 const char *macro_header_get (const char *macro_name
) {
110 HEADER_MACRO var
, *v
= &var
;
112 v
->symbol
= (char*)macro_name
;
113 if (header_macros_hash
&& hashcheck(header_macros_hash
, (HASHDATA
**)&v
)) {
114 if (DEBUG_HEADER
) printf("### macro '%s' evaluated to '%s'\n", macro_name
, v
->filename
);
115 return (const char *)v
->filename
;