Bump the version number to 2.2.
[herrie-working.git] / misc / cdepcalc.c
blob422612b0451b44e3988a51c0ef6c1febaa9473f1
1 /*
2 * Copyright (c) 2006-2008 Ed Schouten <ed@80386.nl>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
27 #include <sys/types.h>
28 #include <dirent.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
33 struct header;
34 struct header_depend;
36 struct header {
37 char *filename;
38 struct header_depend *depends;
39 struct header *next;
42 struct header_depend {
43 struct header *header;
44 struct header_depend *next;
47 struct header *headerlist = NULL;
49 static int
50 depend_add(struct header *from, struct header *to)
52 struct header_depend *hd, *hdp, *hdn;
54 /* We can't depend on ourself. Prevent duplicates. */
55 if (from == to)
56 return (-1);
57 for (hd = to->depends; hd != NULL; hd = hd->next) {
58 if (hd->header == from)
59 return (-1);
62 /* Add item itself */
63 hd = malloc(sizeof(struct header_depend));
64 hd->header = from;
66 hdp = to->depends;
67 if (hdp == NULL || strcmp(hd->header->filename,
68 hdp->header->filename) < 0) {
69 /* Add it to the beginning */
70 hd->next = hdp;
71 to->depends = hd;
72 } else {
73 /* Add it after an existing item */
74 for (hdp = to->depends; hdp != NULL; hdp = hdp->next) {
75 hdn = hdp->next;
76 if (hdn == NULL || strcmp(hd->header->filename,
77 hdn->header->filename) < 0) {
78 /* Insert it in between */
79 hd->next = hdp->next;
80 hdp->next = hd;
81 break;
86 return (0);
89 static void
90 depend_copy(struct header *from, struct header *to)
92 struct header_depend *hd;
94 if (depend_add(from, to) != 0)
95 return;
96 for (hd = from->depends; hd != NULL; hd = hd->next)
97 depend_add(hd->header, to);
100 static struct header *
101 file_scan(const char *filename)
103 int cmp;
104 struct header *h, *hp, *hn, *hs;
105 char fbuf[2048], *eol;
106 FILE *fp;
108 if (strcmp(filename, "conftest.c") == 0 ||
109 strcmp(filename, "stdinc.h") == 0)
110 return (NULL);
112 hp = headerlist;
113 if (hp != NULL) {
114 cmp = strcmp(filename, hp->filename);
115 if (cmp == 0) {
116 return (hp);
117 } else if (cmp < 0) {
118 /* Item cannot be in the list - add to beginning */
119 hp = NULL;
120 } else {
121 /* Item may be in the list - look it up */
122 for (hp = headerlist; hp != NULL; hp = hp->next) {
123 hn = hp->next;
124 if (hn == NULL)
125 break;
126 cmp = strcmp(filename, hn->filename);
127 if (cmp == 0)
128 /* We've found it */
129 return (hn);
130 else if (cmp < 0)
131 /* Add in between */
132 break;
137 fp = fopen(filename, "r");
138 if (fp == NULL) {
139 fprintf(stderr, "Failed to open %s\n", filename);
140 return (NULL);
143 /* We can read it - we must track it */
144 h = malloc(sizeof(struct header));
145 h->filename = strdup(filename);
146 h->depends = NULL;
147 h->next = NULL;
149 /* Add it alphabetically to the list */
150 if (hp == NULL) {
151 h->next = headerlist;
152 headerlist = h;
153 } else {
154 h->next = hp->next;
155 hp->next = h;
158 /* Scan the file */
159 while (fgets(fbuf, sizeof fbuf, fp) != NULL) {
160 if (strncmp(fbuf, "#include \"", 10) == 0) {
161 eol = strchr(fbuf + 10, '"');
162 if (eol == NULL)
163 continue;
164 *eol = '\0';
166 hs = file_scan(fbuf + 10);
167 if (hs != NULL)
168 depend_copy(hs, h);
172 return (h);
176 main(int argc, char *argv[])
178 int first;
179 char *ext;
180 DIR *srcdir;
181 FILE *out;
182 struct dirent *fent;
183 struct header *h;
184 struct header_depend *hd;
186 srcdir = opendir(".");
187 if (srcdir == NULL) {
188 fprintf(stderr, "Failed to open current directory\n");
189 return (1);
192 while ((fent = readdir(srcdir)) != NULL) {
193 /* Only scan C source code */
194 ext = strchr(fent->d_name, '.');
195 if (ext == NULL || strcmp(ext, ".c") != 0)
196 continue;
197 file_scan(fent->d_name);
199 closedir(srcdir);
201 out = fopen("../depends", "w");
202 if (out == NULL) {
203 fprintf(stderr, "Failed to open output file\n");
204 return (1);
207 for (h = headerlist; h != NULL; h = h->next) {
208 /* Only print C source code - skip conftest */
209 ext = strchr(h->filename, '.');
210 if (ext == NULL || strcmp(ext, ".c") != 0)
211 continue;
212 fprintf(out, "DEPENDS_");
213 fwrite(h->filename, 1, ext - h->filename, out);
214 fprintf(out, "=\"");
215 first = 1;
216 for (hd = h->depends; hd != NULL; hd = hd->next) {
217 /* Only print header files */
218 ext = strchr(hd->header->filename, '.');
219 if (ext == NULL || strcmp(ext, ".h") != 0)
220 continue;
221 if (first)
222 first = 0;
223 else
224 fprintf(out, " ");
225 fwrite(hd->header->filename, 1,
226 ext - hd->header->filename, out);
228 fprintf(out, "\"\n");
230 #if 0
231 /* Regular Makefile-style output */
232 ext = strchr(h->filename, '.');
233 if (ext == NULL || strcmp(ext, ".c") != 0)
234 continue;
235 fwrite(h->filename, 1, ext - h->filename, out);
236 fprintf(out, ".o: %s", h->filename);
237 for (hd = h->depends; hd != NULL; hd = hd->next)
238 fprintf(out, " %s", hd->header->filename);
239 fprintf(out, "\n");
240 #endif
242 fclose(out);
244 return (0);