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.3 (Berkeley) 01/22/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 } 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 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 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 } 215