2 * Copyright 1993, 2000 Christopher Seiwald.
3 * This file is part of Jam - see jam.c for Copyright information.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
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
48 /* this type is used to store a dictionary of file header macros */
49 typedef struct header_macro
{
51 const char *filename
; /* we could maybe use a LIST here ?? */
54 static struct hash
*header_macros_hash
= 0;
58 * headers() - scan a target for include files and call HDRRULE
62 void macro_headers (TARGET
*t
) {
65 int line_size
= 16384;
66 char *buf
; /* line_size size */
69 if (DEBUG_HEADER
) printf("macro header scan for %s\n", t
->name
);
70 /* this regexp is used to detect lines of the form */
71 /* "#define MACRO <....>" or "#define MACRO "....." */
72 /* in the header macro files */
73 if ((f
= fopen(t
->boundname
, "r")) == 0) return;
74 re
= regexp_compile("^\\s*#\\s*define\\s+([A-Za-z_][A-Za-z0-9_]*)\\s+[<\"]([^\">]+)[\">].*$", 0);
75 if ((buf
= malloc(line_size
)) == NULL
) { fprintf(stderr
, "FATAL: out of memory!\n"); abort(); }
78 while (fgets(buf
, sizeof(buf
), f
)) {
79 HEADER_MACRO var
, *v
= &var
;
80 mt
[0].sp
= mt
[0].ep
= NULL
;
81 if (regexp_execute(re
, buf
, mt
, 4) > 0) {
82 int l1
= mt
[1].ep
-mt
[1].sp
;
83 int l2
= mt
[2].ep
-mt
[2].sp
;
84 if (l1
> 0 && l2
> 0) {
85 dstr_set_buf(&buf1
, mt
[1].sp
, l1
);
86 dstr_set_buf(&buf2
, mt
[2].sp
, l2
);
87 /* we detected a line that looks like "#define MACRO filename */
88 if (DEBUG_HEADER
) printf("macro '%s' used to define filename '%s' in '%s'\n", dstr_cstr(&buf1
), dstr_cstr(&buf2
), t
->boundname
);
89 /* add macro definition to hash table */
90 if (!header_macros_hash
) header_macros_hash
= hashinit(sizeof(HEADER_MACRO
), "hdrmacros");
91 v
->symbol
= (const char *)dstr_cstr(&buf1
);
93 if (hashenter(header_macros_hash
, (HASHDATA
**)&v
)) {
94 v
->symbol
= newstr(dstr_cstr(&buf1
)); /* never freed */
95 v
->filename
= newstr(dstr_cstr(&buf2
)); /* never freed */
98 /* XXXX: FOR NOW, WE IGNORE MULTIPLE MACRO DEFINITIONS! */
99 /* WE MIGHT AS WELL USE A LIST TO STORE THEM */
110 const char *macro_header_get (const char *macro_name
) {
111 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
;