1 | /* |
---|
2 | * Copyright 1993, 2000 Christopher Seiwald. |
---|
3 | * |
---|
4 | * This file is part of Jam - see jam.c for Copyright information. |
---|
5 | */ |
---|
6 | /* This file is ALSO: |
---|
7 | * Copyright 2001-2004 David Abrahams. |
---|
8 | * Distributed under the Boost Software License, Version 1.0. |
---|
9 | * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) |
---|
10 | */ |
---|
11 | |
---|
12 | # include "jam.h" |
---|
13 | # include "lists.h" |
---|
14 | # include "parse.h" |
---|
15 | # include "compile.h" |
---|
16 | # include "rules.h" |
---|
17 | # include "variable.h" |
---|
18 | # include "regexp.h" |
---|
19 | # include "headers.h" |
---|
20 | # include "hdrmacro.h" |
---|
21 | # include "newstr.h" |
---|
22 | |
---|
23 | #ifdef OPT_HEADER_CACHE_EXT |
---|
24 | # include "hcache.h" |
---|
25 | #endif |
---|
26 | |
---|
27 | /* |
---|
28 | * headers.c - handle #includes in source files |
---|
29 | * |
---|
30 | * Using regular expressions provided as the variable $(HDRSCAN), |
---|
31 | * headers() searches a file for #include files and phonies up a |
---|
32 | * rule invocation: |
---|
33 | * |
---|
34 | * $(HDRRULE) <target> : <include files> ; |
---|
35 | * |
---|
36 | * External routines: |
---|
37 | * headers() - scan a target for include files and call HDRRULE |
---|
38 | * |
---|
39 | * Internal routines: |
---|
40 | * headers1() - using regexp, scan a file and build include LIST |
---|
41 | * |
---|
42 | * 04/13/94 (seiwald) - added shorthand L0 for null list pointer |
---|
43 | * 09/10/00 (seiwald) - replaced call to compile_rule with evaluate_rule, |
---|
44 | * so that headers() doesn't have to mock up a parse structure |
---|
45 | * just to invoke a rule. |
---|
46 | */ |
---|
47 | |
---|
48 | #ifndef OPT_HEADER_CACHE_EXT |
---|
49 | static LIST *headers1( LIST *l, char *file, int rec, regexp *re[]); |
---|
50 | #endif |
---|
51 | |
---|
52 | /* |
---|
53 | * headers() - scan a target for include files and call HDRRULE |
---|
54 | */ |
---|
55 | |
---|
56 | # define MAXINC 10 |
---|
57 | |
---|
58 | void |
---|
59 | headers( TARGET *t ) |
---|
60 | { |
---|
61 | LIST *hdrscan; |
---|
62 | LIST *hdrrule; |
---|
63 | LIST *headlist = 0; |
---|
64 | regexp *re[ MAXINC ]; |
---|
65 | int rec = 0; |
---|
66 | |
---|
67 | if( !( hdrscan = var_get( "HDRSCAN" ) ) || |
---|
68 | !( hdrrule = var_get( "HDRRULE" ) ) ) |
---|
69 | return; |
---|
70 | |
---|
71 | if( DEBUG_HEADER ) |
---|
72 | printf( "header scan %s\n", t->name ); |
---|
73 | |
---|
74 | /* Compile all regular expressions in HDRSCAN */ |
---|
75 | |
---|
76 | while( rec < MAXINC && hdrscan ) |
---|
77 | { |
---|
78 | re[rec++] = regex_compile( hdrscan->string ); |
---|
79 | hdrscan = list_next( hdrscan ); |
---|
80 | } |
---|
81 | |
---|
82 | /* Doctor up call to HDRRULE rule */ |
---|
83 | /* Call headers1() to get LIST of included files. */ |
---|
84 | { |
---|
85 | FRAME frame[1]; |
---|
86 | frame_init( frame ); |
---|
87 | lol_add( frame->args, list_new( L0, t->name ) ); |
---|
88 | #ifdef OPT_HEADER_CACHE_EXT |
---|
89 | lol_add( frame->args, hcache( t, rec, re, hdrscan ) ); |
---|
90 | #else |
---|
91 | lol_add( frame->args, headers1( headlist, t->boundname, rec, re ) ); |
---|
92 | #endif |
---|
93 | |
---|
94 | if( lol_get( frame->args, 1 ) ) |
---|
95 | { |
---|
96 | /* The third argument to HDRRULE is the bound name of |
---|
97 | * $(<) */ |
---|
98 | lol_add( frame->args, list_new( L0, t->boundname ) ); |
---|
99 | |
---|
100 | list_free( evaluate_rule( hdrrule->string, frame ) ); |
---|
101 | } |
---|
102 | |
---|
103 | /* Clean up */ |
---|
104 | |
---|
105 | frame_free( frame ); |
---|
106 | } |
---|
107 | } |
---|
108 | |
---|
109 | /* |
---|
110 | * headers1() - using regexp, scan a file and build include LIST |
---|
111 | */ |
---|
112 | |
---|
113 | #ifdef OPT_HEADER_CACHE_EXT |
---|
114 | LIST * |
---|
115 | #else |
---|
116 | static LIST * |
---|
117 | #endif |
---|
118 | headers1( |
---|
119 | LIST *l, |
---|
120 | char *file, |
---|
121 | int rec, |
---|
122 | regexp *re[] ) |
---|
123 | { |
---|
124 | FILE *f; |
---|
125 | char buf[ 1024 ]; |
---|
126 | int i; |
---|
127 | static regexp *re_macros = 0; |
---|
128 | |
---|
129 | |
---|
130 | #ifdef OPT_IMPROVED_PATIENCE_EXT |
---|
131 | static int count = 0; |
---|
132 | ++count; |
---|
133 | if ( ((count == 100) || !( count % 1000 )) && DEBUG_MAKE ) |
---|
134 | printf("...patience...\n"); |
---|
135 | #endif |
---|
136 | |
---|
137 | /* the following regexp is used to detect cases where a */ |
---|
138 | /* file is included through a line line "#include MACRO" */ |
---|
139 | if ( re_macros == 0 ) |
---|
140 | { |
---|
141 | re_macros = regex_compile( |
---|
142 | "^[ ]*#[ ]*include[ ]*([A-Za-z][A-Za-z0-9_]*).*$" ); |
---|
143 | } |
---|
144 | |
---|
145 | |
---|
146 | if( !( f = fopen( file, "r" ) ) ) |
---|
147 | return l; |
---|
148 | |
---|
149 | while( fgets( buf, sizeof( buf ), f ) ) |
---|
150 | { |
---|
151 | for( i = 0; i < rec; i++ ) |
---|
152 | if( regexec( re[i], buf ) && re[i]->startp[1] ) |
---|
153 | { |
---|
154 | re[i]->endp[1][0] = '\0'; |
---|
155 | |
---|
156 | if( DEBUG_HEADER ) |
---|
157 | printf( "header found: %s\n", re[i]->startp[1] ); |
---|
158 | |
---|
159 | l = list_new( l, newstr( re[i]->startp[1] ) ); |
---|
160 | } |
---|
161 | |
---|
162 | /* special treatment for #include MACRO */ |
---|
163 | if ( regexec( re_macros, buf ) && re_macros->startp[1] ) |
---|
164 | { |
---|
165 | char* header_filename; |
---|
166 | |
---|
167 | re_macros->endp[1][0] = '\0'; |
---|
168 | |
---|
169 | if ( DEBUG_HEADER ) |
---|
170 | printf( "macro header found: %s", re_macros->startp[1] ); |
---|
171 | |
---|
172 | header_filename = macro_header_get( re_macros->startp[1] ); |
---|
173 | if (header_filename) |
---|
174 | { |
---|
175 | if ( DEBUG_HEADER ) |
---|
176 | printf( " resolved to '%s'\n", header_filename ); |
---|
177 | l = list_new( l, newstr( header_filename ) ); |
---|
178 | } |
---|
179 | else |
---|
180 | { |
---|
181 | if ( DEBUG_HEADER ) |
---|
182 | printf( " ignored !!\n" ); |
---|
183 | } |
---|
184 | } |
---|
185 | } |
---|
186 | |
---|
187 | fclose( f ); |
---|
188 | |
---|
189 | return l; |
---|
190 | } |
---|
191 | |
---|
192 | void |
---|
193 | regerror( char *s ) |
---|
194 | { |
---|
195 | printf( "re error %s\n", s ); |
---|
196 | } |
---|