1 /*
2 * Copyright (c) 1983 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 char copyright[] =
10 "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
11 All rights reserved.\n";
12 #endif /* not lint */
13
14 #ifndef lint
15 static char sccsid[] = "@(#)makedefs.c 5.6 (Berkeley) 06/01/90";
16 #endif /* not lint */
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>
37 #include "pathnames.h"
38
39 #define procedure void
40
41 #define streqn(s1, s2, n) (strncmp(s1, s2, n) == 0)
42
43 Boolean force;
44 Boolean copytext;
45
46 String tmpname;
47 String modulename();
48 procedure abnorm();
49
main(argc,argv)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 {
80 tmpname = mktemp(_PATH_TMP);
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
modulename(s)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;
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';
127 }
128 return i;
129 }
130
copy()131 copy()
132 {
133 register char *p;
134 integer nesting;
135 char line[1024];
136
137 while (gets(line) != NULL) {
138 if (streqn(line, "#ifndef public", 14)) {
139 copytext = true;
140 nesting = 1;
141 } else if (streqn(line, "public", 6)) {
142 copydef(line);
143 } else if (copytext) {
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 ) {
163 printf("%s\n", line);
164 }
165 }
166 }
167
copydef(s)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
abnorm(signo)195 procedure abnorm(signo)
196 int signo;
197 {
198 unlink(tmpname);
199 quit(signo);
200 }
201
quit(r)202 quit(r)
203 int r;
204 {
205 exit(r);
206 }
207
208 /*
209 * No special error recovery strategy.
210 */
211
erecover()212 erecover()
213 {
214 }
215