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