1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105#include <sys/types.h>
106#include <sys/stat.h>
107#include <sys/mman.h>
108#include <unistd.h>
109#include <fcntl.h>
110#include <string.h>
111#include <stdlib.h>
112#include <stdio.h>
113#include <limits.h>
114#include <ctype.h>
115#include <arpa/inet.h>
116
117
118
119
120
121
122
123
124
125char *target;
126char *depfile;
127char *cmdline;
128
129void usage(void)
130
131{
132 fprintf(stderr, "Usage: fixdep <depfile> <target> <cmdline>\n");
133 exit(1);
134}
135
136
137
138
139void print_cmdline(void)
140{
141 printf("cmd_%s := %s\n\n", target, cmdline);
142}
143
144char * str_config = NULL;
145int size_config = 0;
146int len_config = 0;
147
148
149
150
151
152void grow_config(int len)
153{
154 while (len_config + len > size_config) {
155 if (size_config == 0)
156 size_config = 2048;
157 str_config = realloc(str_config, size_config *= 2);
158 if (str_config == NULL)
159 { perror("fixdep:malloc"); exit(1); }
160 }
161}
162
163
164
165
166
167
168int is_defined_config(const char * name, int len)
169{
170 const char * pconfig;
171 const char * plast = str_config + len_config - len;
172 for ( pconfig = str_config + 1; pconfig < plast; pconfig++ ) {
173 if (pconfig[ -1] == '\n'
174 && pconfig[len] == '\n'
175 && !memcmp(pconfig, name, len))
176 return 1;
177 }
178 return 0;
179}
180
181
182
183
184void define_config(const char * name, int len)
185{
186 grow_config(len + 1);
187
188 memcpy(str_config+len_config, name, len);
189 len_config += len;
190 str_config[len_config++] = '\n';
191}
192
193
194
195
196void clear_config(void)
197{
198 len_config = 0;
199 define_config("", 0);
200}
201
202
203
204
205void use_config(char *m, int slen)
206{
207 char *s = alloca(slen+1);
208 char *p;
209
210 if (is_defined_config(m, slen))
211 return;
212
213 define_config(m, slen);
214
215 memcpy(s, m, slen); s[slen] = 0;
216
217 for (p = s; p < s + slen; p++) {
218 if (*p == '_')
219 *p = '/';
220 else
221 *p = tolower((int)*p);
222 }
223 printf(" $(wildcard include/config/%s.h) \\\n", s);
224}
225
226void parse_config_file(char *map, size_t len)
227{
228
229 unsigned char *end_3 = (unsigned char *)map + len - 3;
230 unsigned char *end_7 = (unsigned char *)map + len - 7;
231 unsigned char *p = (unsigned char *)map;
232 unsigned char *q;
233 int off;
234
235 for (; p <= end_3; p++) {
236
237 if (!(isalnum(*p) || *p == '_'))
238 continue;
239
240
241 if (p < end_7 && p[6] == '_') {
242 if (!memcmp(p, "CONFIG", 6)) goto conf7;
243 if (!memcmp(p, "ENABLE", 6)) goto conf7;
244 if (!memcmp(p, "IF_NOT", 6)) goto conf7;
245 }
246
247
248 if (p[0] == 'I' && p[1] == 'F' && p[2] == '_') {
249 off = 3;
250 goto conf;
251 }
252
253
254 while (p <= end_3 && (isalnum(*p) || *p == '_'))
255 p++;
256 continue;
257
258 conf7: off = 7;
259 conf:
260 p += off;
261 for (q = p; q < end_3+3; q++) {
262 if (!(isalnum(*q) || *q == '_'))
263 break;
264 }
265 if (q != p) {
266 use_config((char*)p, q - p);
267 }
268 }
269}
270
271
272int strrcmp(char *s, char *sub)
273{
274 int slen = strlen(s);
275 int sublen = strlen(sub);
276
277 if (sublen > slen)
278 return 1;
279
280 return memcmp(s + slen - sublen, sub, sublen);
281}
282
283void do_config_file(char *filename)
284{
285 struct stat st;
286 int fd;
287 void *map;
288
289 fd = open(filename, O_RDONLY);
290 if (fd < 0) {
291 fprintf(stderr, "fixdep: ");
292 perror(filename);
293 exit(2);
294 }
295 fstat(fd, &st);
296 if (st.st_size == 0) {
297 close(fd);
298 return;
299 }
300 map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
301 if ((long) map == -1) {
302 perror("fixdep: mmap");
303 close(fd);
304 return;
305 }
306
307 parse_config_file(map, st.st_size);
308
309 munmap(map, st.st_size);
310
311 close(fd);
312}
313
314void parse_dep_file(void *map, size_t len)
315{
316 char *m = map;
317 char *end = m + len;
318 char *p;
319 char *s = alloca(len);
320
321 p = memchr(m, ':', len);
322 if (!p) {
323 fprintf(stderr, "fixdep: parse error\n");
324 exit(1);
325 }
326 memcpy(s, m, p-m); s[p-m] = 0;
327 printf("deps_%s := \\\n", target);
328 m = p+1;
329
330 clear_config();
331
332 while (m < end) {
333 while (m < end && (*m == ' ' || *m == '\\' || *m == '\n' || *m == '\r'))
334 m++;
335 p = m;
336 while (p < end && *p != ' ') p++;
337 if (p == end) {
338 do p--; while (!isalnum((unsigned char)*p));
339 p++;
340 }
341 memcpy(s, m, p-m); s[p-m] = 0;
342 if (strrcmp(s, "include/autoconf.h") &&
343 strrcmp(s, "arch/um/include/uml-config.h") &&
344 strrcmp(s, ".ver")) {
345 printf(" %s \\\n", s);
346 do_config_file(s);
347 }
348 m = p + 1;
349 }
350 printf("\n%s: $(deps_%s)\n\n", target, target);
351 printf("$(deps_%s):\n", target);
352}
353
354void print_deps(void)
355{
356 struct stat st;
357 int fd;
358 void *map;
359
360 fd = open(depfile, O_RDONLY);
361 if (fd < 0) {
362 fprintf(stderr, "fixdep: ");
363 perror(depfile);
364 exit(2);
365 }
366 fstat(fd, &st);
367 if (st.st_size == 0) {
368 fprintf(stderr,"fixdep: %s is empty\n",depfile);
369 close(fd);
370 return;
371 }
372 map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
373 if ((long) map == -1) {
374 perror("fixdep: mmap");
375 close(fd);
376 return;
377 }
378
379 parse_dep_file(map, st.st_size);
380
381 munmap(map, st.st_size);
382
383 close(fd);
384}
385
386void traps(void)
387{
388
389
390
391
392
393
394
395
396
397}
398
399int main(int argc, char **argv)
400{
401 traps();
402
403 if (argc != 4)
404 usage();
405
406 depfile = argv[1];
407 target = argv[2];
408 cmdline = argv[3];
409
410 print_cmdline();
411 print_deps();
412
413 return 0;
414}
415