fixes in shell scripts; added simple CPU detection for 'profile speed' rule
[k8jam.git] / hdrmacro.c
blob664b04e8ef6fa3f5640f7ecbaaa5483d3099fcd7
1 /*
2 * Copyright 1993, 2000 Christopher Seiwald.
4 * This file is part of Jam - see jam.c for Copyright information.
5 */
7 # include "jam.h"
8 # include "lists.h"
9 # include "parse.h"
10 # include "compile.h"
11 # include "rules.h"
12 # include "variable.h"
13 # include "regexp.h"
14 # include "hdrmacro.h"
15 # include "hash.h"
16 # include "newstr.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, regexp *re[]);*/
44 /* this type is used to store a dictionary of file header macros */
45 typedef struct header_macro {
46 const char* symbol;
47 const char* filename; /* we could maybe use a LIST here ?? */
48 } HEADER_MACRO;
50 static struct hash *header_macros_hash = 0;
54 * headers() - scan a target for include files and call HDRRULE
56 # define MAXINC 10
58 void macro_headers (TARGET *t) {
59 regexp *re;
60 FILE *f;
61 char buf[1024];
63 if (DEBUG_HEADER) printf("macro header scan for %s\n", t->name);
64 /* this regexp is used to detect lines of the form */
65 /* "#define MACRO <....>" or "#define MACRO "....." */
66 /* in the header macro files.. */
67 re = regcomp(
68 "^[ ]*#[ ]*define[ ]*([A-Za-z][A-Za-z0-9_]*)[ ]*"
69 "[<\"]([^\">]*)[\">].*$");
71 if ((f = fopen(t->boundname, "r")) == 0) return;
72 while (fgets(buf, sizeof(buf), f)) {
73 HEADER_MACRO var, *v = &var;
75 if (regexec(re, buf) && re->startp[1]) {
76 char buf1[MAXSYM], buf2[MAXSYM];
77 int l1, l2;
79 l1 = re->endp[1]-re->startp[1];
80 l2 = re->endp[2]-re->startp[2];
81 memcpy(buf1, re->startp[1], l1);
82 memcpy(buf2, re->startp[2], l2);
83 buf1[l1] = '\0';
84 buf2[l2] = '\0';
85 /* we detected a line that looks like "#define MACRO filename */
86 if (DEBUG_HEADER) printf("macro '%s' used to define filename '%s' in '%s'\n", buf1, buf2, t->boundname);
87 /* add macro definition to hash table */
88 if (!header_macros_hash) header_macros_hash = hashinit(sizeof(HEADER_MACRO), "hdrmacros");
89 v->symbol = (const char*)buf1;
90 v->filename = 0;
91 if (hashenter(header_macros_hash, (HASHDATA **)&v)) {
92 v->symbol = newstr(buf1); /* never freed */
93 v->filename = newstr(buf2); /* never freed */
95 /* XXXX: FOR NOW, WE IGNORE MULTIPLE MACRO DEFINITIONS !! */
96 /* WE MIGHT AS WELL USE A LIST TO STORE THEM.. */
99 fclose(f);
100 free(re);
104 const char *macro_header_get (const char *macro_name) {
105 HEADER_MACRO var, *v = &var;
107 v->symbol = (char*)macro_name;
108 if (header_macros_hash && hashcheck(header_macros_hash, (HASHDATA **)&v)) {
109 if (DEBUG_HEADER) printf("### macro '%s' evaluated to '%s'\n", macro_name, v->filename);
110 return (const char*) v->filename;
112 return 0;