added "jammod" command and "genman" module
[k8jam.git] / src / hdrmacro.c
blob7a6a3ed6f6c1b5f68f8941e76b822273110ca3ec
1 /*
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, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 * hdrmacro.c - handle header files that define macros used in
20 * #include statements.
22 * we look for lines like "#define MACRO <....>" or '#define MACRO " "'
23 * in the target file. When found, we
25 * we then phony up a rule invocation like:
27 * $(HDRRULE) <target> : <resolved included files> ;
29 * External routines:
30 * headers1() - scan a target for "#include MACRO" lines and try
31 * to resolve them when needed
33 * Internal routines:
34 * headers1() - using regexp, scan a file and build include LIST
36 #include "jam.h"
37 #include "lists.h"
38 #include "parse.h"
39 #include "compile.h"
40 #include "rules.h"
41 #include "variable.h"
42 #include "re9.h"
43 #include "hdrmacro.h"
44 #include "hash.h"
45 #include "newstr.h"
46 #include "dstrings.h"
49 /* this type is used to store a dictionary of file header macros */
50 typedef struct header_macro {
51 const char *symbol;
52 const char *filename; /* we could maybe use a LIST here ?? */
53 } HEADER_MACRO;
55 static struct hash *header_macros_hash = 0;
59 * headers() - scan a target for include files and call HDRRULE
61 //#define MAXINC (10)
63 void macro_headers (TARGET *t) {
64 regexp_t *re;
65 re9_sub_t mt[4];
66 int line_size = 16384;
67 char *buf; /* line_size size */
68 dstring_t buf1, buf2;
69 FILE *f;
70 if (DEBUG_HEADER) printf("macro header scan for %s\n", t->name);
71 /* this regexp is used to detect lines of the form */
72 /* "#define MACRO <....>" or "#define MACRO "....." */
73 /* in the header macro files */
74 if ((f = fopen(t->boundname, "r")) == 0) return;
75 re = regexp_compile("^\\s*#\\s*define\\s+([A-Za-z_][A-Za-z0-9_]*)\\s+[<\"]([^\">]+)[\">].*$", 0);
76 if ((buf = malloc(line_size)) == NULL) { fprintf(stderr, "FATAL: out of memory!\n"); abort(); }
77 dstr_init(&buf1);
78 dstr_init(&buf2);
79 while (fgets(buf, sizeof(buf), f)) {
80 HEADER_MACRO var, *v = &var;
81 mt[0].sp = mt[0].ep = NULL;
82 if (regexp_execute(re, buf, mt, 4) > 0) {
83 int l1 = mt[1].ep-mt[1].sp;
84 int l2 = mt[2].ep-mt[2].sp;
85 if (l1 > 0 && l2 > 0) {
86 dstr_set_buf(&buf1, mt[1].sp, l1);
87 dstr_set_buf(&buf2, mt[2].sp, l2);
88 /* we detected a line that looks like "#define MACRO filename */
89 if (DEBUG_HEADER) printf("macro '%s' used to define filename '%s' in '%s'\n", dstr_cstr(&buf1), dstr_cstr(&buf2), t->boundname);
90 /* add macro definition to hash table */
91 if (!header_macros_hash) header_macros_hash = hashinit(sizeof(HEADER_MACRO), "hdrmacros");
92 v->symbol = (const char *)dstr_cstr(&buf1);
93 v->filename = 0;
94 if (hashenter(header_macros_hash, (HASHDATA **)&v)) {
95 v->symbol = newstr(dstr_cstr(&buf1)); /* never freed */
96 v->filename = newstr(dstr_cstr(&buf2)); /* never freed */
99 /* XXXX: FOR NOW, WE IGNORE MULTIPLE MACRO DEFINITIONS! */
100 /* WE MIGHT AS WELL USE A LIST TO STORE THEM */
103 dstr_done(&buf2);
104 dstr_done(&buf1);
105 free(buf);
106 fclose(f);
107 regexp_free(re);
111 const char *macro_header_get (const char *macro_name) {
112 HEADER_MACRO var, *v = &var;
113 v->symbol = (char*)macro_name;
114 if (header_macros_hash && hashcheck(header_macros_hash, (HASHDATA **)&v)) {
115 if (DEBUG_HEADER) printf("### macro '%s' evaluated to '%s'\n", macro_name, v->filename);
116 return (const char *)v->filename;
118 return 0;