removed some OS/2 remnants
[k8jam.git] / src / hdrmacro.c
blob906ca8ce9d5ef128528a82e6b8911157da2238f9
1 /*
2 * Copyright 1993, 2000 Christopher Seiwald.
4 * This file is part of Jam - see jam.c for Copyright information.
5 */
6 #include "jam.h"
7 #include "lists.h"
8 #include "parse.h"
9 #include "compile.h"
10 #include "rules.h"
11 #include "variable.h"
12 #include "re9.h"
13 #include "hdrmacro.h"
14 #include "hash.h"
15 #include "newstr.h"
16 #include "dstrings.h"
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 * 04/13/94 (seiwald) - added shorthand L0 for null list pointer
37 * 09/10/00 (seiwald) - replaced call to compile_rule with evaluate_rule,
38 * so that headers() doesn't have to mock up a parse structure
39 * just to invoke a rule.
42 /*k8: static LIST *header_macros1(LIST *l, char *file, int rec, HSRegExp *re[]);*/
45 /* this type is used to store a dictionary of file header macros */
46 typedef struct header_macro {
47 const char *symbol;
48 const char *filename; /* we could maybe use a LIST here ?? */
49 } HEADER_MACRO;
51 static struct hash *header_macros_hash = 0;
55 * headers() - scan a target for include files and call HDRRULE
57 //#define MAXINC (10)
59 void macro_headers (TARGET *t) {
60 re9_prog_t *re;
61 re9_prog_prepared_t *pp;
62 re9_sub_t mt[4];
63 const char *errmsg;
64 char buf[4096];
65 FILE *f;
67 if (DEBUG_HEADER) printf("macro header scan for %s\n", t->name);
68 /* this regexp is used to detect lines of the form */
69 /* "#define MACRO <....>" or "#define MACRO "....." */
70 /* in the header macro files */
71 if ((f = fopen(t->boundname, "r")) == 0) return;
72 re = re9_compile("^\\s*#\\s*define\\s+([A-Za-z_][A-Za-z0-9_]*)\\s+[<\"]([^\">]*)[\">].*$", RE9_FLAG_NONUTF8, &errmsg);
73 if (re == NULL) {
74 printf("FATAL: %s\n", errmsg);
75 exit(42);
77 pp = re9_prepare(re);
78 if (pp == NULL) {
79 printf("FATAL: out of memory\n");
80 exit(42);
82 while (fgets(buf, sizeof(buf), f)) {
83 HEADER_MACRO var, *v = &var;
85 mt[0].sp = mt[0].ep = NULL;
86 if (re9_prepared_execute(pp, RE9_FLAG_NONUTF8, buf, mt, 4) > 0) {
87 int l1 = mt[1].ep-mt[1].sp;
88 int l2 = mt[2].ep-mt[2].sp;
89 if (l1 > 0 && l2 > 0) {
90 dstring_t buf1, buf2;
91 dstr_init_buf(&buf1, mt[1].sp, l1);
92 dstr_init_buf(&buf2, mt[2].sp, l2);
93 /* we detected a line that looks like "#define MACRO filename */
94 if (DEBUG_HEADER) printf("macro '%s' used to define filename '%s' in '%s'\n", dstr_cstr(&buf1), dstr_cstr(&buf2), t->boundname);
95 /* add macro definition to hash table */
96 if (!header_macros_hash) header_macros_hash = hashinit(sizeof(HEADER_MACRO), "hdrmacros");
97 v->symbol = (const char *)dstr_cstr(&buf1);
98 v->filename = 0;
99 if (hashenter(header_macros_hash, (HASHDATA **)&v)) {
100 v->symbol = newstr(dstr_cstr(&buf1)); /* never freed */
101 v->filename = newstr(dstr_cstr(&buf2)); /* never freed */
103 dstr_done(&buf2);
104 dstr_done(&buf1);
106 /* XXXX: FOR NOW, WE IGNORE MULTIPLE MACRO DEFINITIONS! */
107 /* WE MIGHT AS WELL USE A LIST TO STORE THEM */
110 fclose(f);
111 re9_prepared_free(pp);
112 re9_free(re);
116 const char *macro_header_get (const char *macro_name) {
117 HEADER_MACRO var, *v = &var;
119 v->symbol = (char*)macro_name;
120 if (header_macros_hash && hashcheck(header_macros_hash, (HASHDATA **)&v)) {
121 if (DEBUG_HEADER) printf("### macro '%s' evaluated to '%s'\n", macro_name, v->filename);
122 return (const char *)v->filename;
124 return 0;