fixed pkg-config rule
[k8jam.git] / src / headers.c
blob97e42b68bfad12981d7e3bed3a1de80a57e3834b
1 /*
2 * Copyright 1993, 2000 Christopher Seiwald.
4 * This file is part of Jam - see jam.c for Copyright information.
5 */
7 /*
8 * headers.c - handle #includes in source files
10 * Using regular expressions provided as the variable $(HDRSCAN),
11 * headers() searches a file for #include files and phonies up a
12 * rule invocation:
14 * $(HDRRULE) <target> : <include files> ;
16 * External routines:
17 * headers() - scan a target for include files and call HDRRULE
19 * Internal routines:
20 * headers1() - using regexp, scan a file and build include LIST
22 * 04/13/94 (seiwald) - added shorthand L0 for null list pointer
23 * 09/10/00 (seiwald) - replaced call to compile_rule with evaluate_rule,
24 * so that headers() doesn't have to mock up a parse structure
25 * just to invoke a rule.
26 * 03/02/02 (seiwald) - rules can be invoked via variable names
27 * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr()
28 * 11/04/02 (seiwald) - const-ing for string literals
29 * 12/09/02 (seiwald) - push regexp creation down to headers1().
31 #include "jam.h"
32 #include "lists.h"
33 #include "parse.h"
34 #include "compile.h"
35 #include "rules.h"
36 #include "variable.h"
37 #include "hsregexp.h"
38 #include "headers.h"
39 #include "newstr.h"
40 #include "hdrmacro.h"
41 #include "hcache.h"
45 #ifndef OPT_HEADER_CACHE_EXT
46 static LIST *headers1 (const char *file, LIST *hdrscan);
47 #endif
52 * headers() - scan a target for include files and call HDRRULE
54 #define MAXINC (10)
56 void headers (TARGET *t) {
57 LIST *hdrscan;
58 LIST *hdrrule;
59 LOL lol;
61 if (!(hdrscan = var_get("HDRSCAN")) || !(hdrrule = var_get("HDRRULE"))) return;
62 /* doctor up call to HDRRULE rule */
63 /* call headers1() to get LIST of included files */
64 if (DEBUG_HEADER) printf("header scan %s\n", t->name);
65 lol_init(&lol);
66 lol_add(&lol, list_new(L0, t->name, 1));
68 #ifdef OPT_HEADER_CACHE_EXT
69 lol_add(&lol, hcache(t, hdrscan));
70 #else
71 lol_add(&lol, headers1(t->boundname, hdrscan));
72 #endif
74 lol_add(&lol, hcache(t, hdrscan));
75 if (lol_get(&lol, 1)) list_free(evaluate_rule(hdrrule->string, &lol, L0));
76 /* clean up */
77 lol_free(&lol);
82 * headers1() - using regexp, scan a file and build include LIST
85 #ifndef OPT_HEADER_CACHE_EXT
86 static
87 #endif
89 LIST *headers1 (const char *file, LIST *hdrscan) {
90 FILE *f;
91 int i, err;
92 int rec = 0;
93 LIST *result = 0;
94 HSRegExp re[MAXINC];
95 HSRegExp re_macros;
96 HSRxMatch mt[4];
97 char buf[4096], buf2[MAXSYM];
99 if (!(f = fopen(file, "r"))) return result;
100 while (rec < MAXINC && hdrscan) {
101 //printf("header re %d: [%s]\n", rec, hdrscan->string);
102 err = hsrxCompile(&re[rec++], hdrscan->string, HSRX_EXTENDED);
103 if (err != 0) {
104 hsrxError(err, &re[rec-1], buf, sizeof(buf));
105 printf("FATAL: %s\n", buf);
106 exit(42);
108 hdrscan = list_next(hdrscan);
110 /* the following regexp is used to detect cases where a */
111 /* file is included through a line line "#include MACRO" */
112 err = hsrxCompile(&re_macros, "^[[:space:]]*#[[:space:]]*include[[:space:]]*([A-Za-z][A-Za-z0-9_]*).*$", HSRX_EXTENDED);
113 if (err != 0) {
114 hsrxError(err, &re_macros, buf, sizeof(buf));
115 printf("FATAL: %s\n", buf);
116 exit(42);
118 if (DEBUG_HEADER) printf("header processing: [%s] (%d)\n", file, rec);
119 while (fgets(buf, sizeof(buf), f)) {
120 for (i = 0; i < rec; ++i) {
121 if (hsrxExec(&re[i], buf, 2, mt, 0) == HSRX_NOERROR/* && mt[1].rm_eo > mt[1].rm_so*/) {
122 /* copy and terminate extracted string */
123 int l = mt[1].rm_eo-mt[1].rm_so;
125 memcpy(buf2, buf+mt[1].rm_so, l); buf2[l] = 0;
126 result = list_new(result, buf2, 0);
127 if (DEBUG_HEADER) printf("header found: %s\n", buf2);
130 /* special treatment for #include MACRO */
131 if (hsrxExec(&re_macros, buf, 2, mt, 0) == HSRX_NOERROR && mt[1].rm_eo > mt[1].rm_so) {
132 const char *header_filename;
133 int l = mt[1].rm_eo-mt[1].rm_so;
135 memcpy(buf2, buf+mt[1].rm_so, l); buf2[l] = 0;
136 if (DEBUG_HEADER) printf("macro header found: %s", buf2);
137 header_filename = macro_header_get(buf2);
138 if (header_filename) {
139 if (DEBUG_HEADER) printf(" resolved to '%s'\n", header_filename);
140 result = list_new(result, header_filename, 0);
141 } else {
142 if (DEBUG_HEADER) printf(" ignored !!\n");
146 hsrxFree(&re_macros);
147 while (rec) hsrxFree(&re[--rec]);
148 fclose(f);
150 return result;