Commit | Line | Data |
---|---|---|
2a24676e | 1 | /* |
8a90f3aa KB |
2 | * Copyright (c) 1983 The Regents of the University of California. |
3 | * All rights reserved. | |
4 | * | |
6ecf3d85 | 5 | * %sccs.include.redist.c% |
2a24676e DF |
6 | */ |
7 | ||
8 | #ifndef lint | |
9 | char copyright[] = | |
8a90f3aa | 10 | "@(#) Copyright (c) 1983 The Regents of the University of California.\n\ |
2a24676e | 11 | All rights reserved.\n"; |
8a90f3aa | 12 | #endif /* not lint */ |
d57a8d8e | 13 | |
2a24676e | 14 | #ifndef lint |
6ecf3d85 | 15 | static char sccsid[] = "@(#)makedefs.c 5.6 (Berkeley) %G%"; |
8a90f3aa | 16 | #endif /* not lint */ |
d57a8d8e ML |
17 | |
18 | /* | |
19 | * Create a definitions file (e.g. .h) from an implementation file (e.g. .c). | |
20 | * | |
21 | * Usage is "makedefs source.c source.h" where source.h is to be created. | |
22 | * | |
23 | * Lines beginning with "public" or within a "#ifndef public ... #endif" | |
24 | * block are copied to the new file. Initializations (e.g. "int x = 3") are | |
25 | * omitted ("int x;" is output). | |
26 | * | |
27 | * Normally a temporary definitions file is created and compared to | |
28 | * the given destination. If they are different, the temporary file | |
29 | * is copied on top of the destination. This is so that dependencies | |
30 | * when using "make" are not triggered. | |
31 | * | |
32 | * The "-f" option overrides this and forces the destination file to be created. | |
33 | */ | |
34 | ||
35 | #include "defs.h" | |
36 | #include <signal.h> | |
dc0e9d50 | 37 | #include "pathnames.h" |
d57a8d8e ML |
38 | |
39 | #define procedure void | |
40 | ||
9606e7b9 DS |
41 | #define streqn(s1, s2, n) (strncmp(s1, s2, n) == 0) |
42 | ||
d57a8d8e ML |
43 | Boolean force; |
44 | Boolean copytext; | |
45 | ||
46 | String tmpname; | |
47 | String modulename(); | |
48 | procedure abnorm(); | |
49 | ||
50 | main(argc, argv) | |
51 | int argc; | |
52 | String argv[]; | |
53 | { | |
54 | extern String mktemp(); | |
55 | String name; | |
56 | File tmp; | |
57 | Integer r; | |
58 | Integer index; | |
59 | ||
60 | if (streq(argv[1], "-f")) { | |
61 | force = true; | |
62 | index = 2; | |
63 | } else { | |
64 | force = false; | |
65 | index = 1; | |
66 | } | |
67 | if (argc - index > 2) { | |
68 | fatal("usage: makedefs [ -f ] file.c [ file.h ]\n"); | |
69 | } | |
70 | tmp = nil; | |
71 | if (freopen(argv[index], "r", stdin) == NULL) { | |
72 | fatal("can't read %s", argv[index]); | |
73 | } | |
74 | signal(SIGINT, abnorm); | |
75 | signal(SIGQUIT, abnorm); | |
76 | if (index + 1 < argc) { | |
77 | if (force) { | |
78 | tmpname = argv[index + 1]; | |
79 | } else { | |
dc0e9d50 | 80 | tmpname = mktemp(_PATH_TMP); |
d57a8d8e ML |
81 | } |
82 | tmp = freopen(tmpname, "w", stdout); | |
83 | if (tmp == nil) { | |
84 | fatal("can't write %s", tmpname); | |
85 | } | |
86 | } | |
87 | copytext = false; | |
88 | name = modulename(argv[index]); | |
89 | printf("#ifndef %s\n", name); | |
90 | printf("#define %s\n", name); | |
91 | copy(); | |
92 | printf("#endif\n"); | |
93 | if (tmp != NULL and not force) { | |
94 | fclose(tmp); | |
95 | r = call("cmp", stdin, stderr, "-s", tmpname, argv[2], nil); | |
96 | if (r != 0) { | |
97 | r = call("cp", stdin, stderr, tmpname, argv[2], nil); | |
98 | if (r != 0) { | |
99 | fprintf(stderr, "can't create %s\n", argv[2]); | |
100 | } | |
101 | } | |
102 | unlink(tmpname); | |
103 | } | |
104 | quit(0); | |
105 | } | |
106 | ||
107 | String modulename(s) | |
108 | String s; | |
109 | { | |
110 | String r, i, j; | |
111 | static char buf[256]; | |
112 | ||
113 | strcpy(buf, s); | |
114 | i = rindex(buf, '/'); | |
115 | if (i == nil) { | |
116 | i = buf; | |
453fc342 DS |
117 | } else { |
118 | ++i; | |
119 | } | |
120 | for (j = i; *j; j++) { | |
121 | if (*j == '.') { | |
122 | *j = '_'; | |
123 | } | |
124 | } | |
125 | if (j > i && *--j == 'c') { | |
126 | *j = 'h'; | |
d57a8d8e | 127 | } |
453fc342 | 128 | return i; |
d57a8d8e ML |
129 | } |
130 | ||
131 | copy() | |
132 | { | |
133 | register char *p; | |
9606e7b9 | 134 | integer nesting; |
d57a8d8e ML |
135 | char line[1024]; |
136 | ||
137 | while (gets(line) != NULL) { | |
9606e7b9 | 138 | if (streqn(line, "#ifndef public", 14)) { |
d57a8d8e | 139 | copytext = true; |
9606e7b9 DS |
140 | nesting = 1; |
141 | } else if (streqn(line, "public", 6)) { | |
d57a8d8e ML |
142 | copydef(line); |
143 | } else if (copytext) { | |
9606e7b9 DS |
144 | if (streqn(line, "#ifdef", 6) or streqn(line, "#ifndef", 7)) { |
145 | ++nesting; | |
146 | printf("%s\n", line); | |
147 | } else if (streqn(line, "#endif", 6)) { | |
148 | --nesting; | |
149 | if (nesting <= 0) { | |
150 | copytext = false; | |
151 | } else { | |
152 | printf("%s\n", line); | |
153 | } | |
154 | } else { | |
155 | printf("%s\n", line); | |
156 | } | |
157 | } else if ( | |
158 | streqn(line, "#ifdef", 6) or | |
159 | streqn(line, "#ifndef", 7) or | |
160 | streqn(line, "#else", 5) or | |
161 | streqn(line, "#endif", 6) | |
162 | ) { | |
d57a8d8e ML |
163 | printf("%s\n", line); |
164 | } | |
165 | } | |
166 | } | |
167 | ||
168 | copydef(s) | |
169 | String s; | |
170 | { | |
171 | register char *p; | |
172 | register Boolean isproc; | |
173 | ||
174 | isproc = false; | |
175 | for (p = &s[7]; *p != '\0' and *p != '='; p++) { | |
176 | if (*p == '(') { | |
177 | isproc = true; | |
178 | printf("(/* "); | |
179 | } else if (*p == ')' and isproc and *(p+1) == '\0') { | |
180 | printf(" */)"); | |
181 | } else { | |
182 | putchar(*p); | |
183 | } | |
184 | } | |
185 | if (isproc or *p == '=') { | |
186 | putchar(';'); | |
187 | } | |
188 | putchar('\n'); | |
189 | } | |
190 | ||
191 | /* | |
192 | * Terminate program. | |
193 | */ | |
194 | ||
195 | procedure abnorm(signo) | |
196 | int signo; | |
197 | { | |
198 | unlink(tmpname); | |
199 | quit(signo); | |
200 | } | |
201 | ||
202 | quit(r) | |
203 | int r; | |
204 | { | |
205 | exit(r); | |
206 | } | |
207 | ||
208 | /* | |
209 | * No special error recovery strategy. | |
210 | */ | |
211 | ||
212 | erecover() | |
213 | { | |
214 | } |