xref: /csrg-svn/old/dbx/makedefs.c (revision 33323)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 char copyright[] =
9 "@(#) Copyright (c) 1983 Regents of the University of California.\n\
10  All rights reserved.\n";
11 #endif not lint
12 
13 #ifndef lint
14 static char sccsid[] = "@(#)makedefs.c	5.2 (Berkeley) 01/12/88";
15 #endif not lint
16 
17 static char rcsid[] = "$Header: makedefs.c,v 1.2 87/03/26 19:14:02 donn Exp $";
18 
19 /*
20  * Create a definitions file (e.g. .h) from an implementation file (e.g. .c).
21  *
22  * Usage is "makedefs source.c source.h" where source.h is to be created.
23  *
24  * Lines beginning with "public" or within a "#ifndef public ... #endif"
25  * block are copied to the new file.  Initializations (e.g. "int x = 3") are
26  * omitted ("int x;" is output).
27  *
28  * Normally a temporary definitions file is created and compared to
29  * the given destination.  If they are different, the temporary file
30  * is copied on top of the destination.  This is so that dependencies
31  * when using "make" are not triggered.
32  *
33  * The "-f" option overrides this and forces the destination file to be created.
34  */
35 
36 #include "defs.h"
37 #include <signal.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 
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("/tmp/makedefsXXXXXX");
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;
117     }
118     for (j = i; *j != '.'; j++);
119     *j++ = '_';
120     *j++ = 'h';
121     *j = '\0';
122     return buf;
123 }
124 
125 copy()
126 {
127     register char *p;
128     integer nesting;
129     char line[1024];
130 
131     while (gets(line) != NULL) {
132 	if (streqn(line, "#ifndef public", 14)) {
133 	    copytext = true;
134 	    nesting = 1;
135 	} else if (streqn(line, "public", 6)) {
136 	    copydef(line);
137 	} else if (copytext) {
138 	    if (streqn(line, "#ifdef", 6) or streqn(line, "#ifndef", 7)) {
139 		++nesting;
140 		printf("%s\n", line);
141 	    } else if (streqn(line, "#endif", 6)) {
142 		--nesting;
143 		if (nesting <= 0) {
144 		    copytext = false;
145 		} else {
146 		    printf("%s\n", line);
147 		}
148 	    } else {
149 		printf("%s\n", line);
150 	    }
151 	} else if (
152 	    streqn(line, "#ifdef", 6) or
153 	    streqn(line, "#ifndef", 7) or
154 	    streqn(line, "#else", 5) or
155 	    streqn(line, "#endif", 6)
156 	) {
157 	    printf("%s\n", line);
158 	}
159     }
160 }
161 
162 copydef(s)
163 String s;
164 {
165     register char *p;
166     register Boolean isproc;
167 
168     isproc = false;
169     for (p = &s[7]; *p != '\0' and *p != '='; p++) {
170 	if (*p == '(') {
171 	    isproc = true;
172 	    printf("(/* ");
173 	} else if (*p == ')' and isproc and *(p+1) == '\0') {
174 	    printf(" */)");
175 	} else {
176 	    putchar(*p);
177 	}
178     }
179     if (isproc or *p == '=') {
180 	putchar(';');
181     }
182     putchar('\n');
183 }
184 
185 /*
186  * Terminate program.
187  */
188 
189 procedure abnorm(signo)
190 int signo;
191 {
192     unlink(tmpname);
193     quit(signo);
194 }
195 
196 quit(r)
197 int r;
198 {
199     exit(r);
200 }
201 
202 /*
203  * No special error recovery strategy.
204  */
205 
206 erecover()
207 {
208 }
209