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