| 1 | /* Copyright (c) 1982 Regents of the University of California */ |
| 2 | |
| 3 | static char sccsid[] = "@(#)makedefs.c 1.2 %G%"; |
| 4 | |
| 5 | /* |
| 6 | * Create a definitions file (e.g. .h) from an implementation file (e.g. .c). |
| 7 | * |
| 8 | * Usage is "makedefs source.c source.h" where source.h is to be created. |
| 9 | * |
| 10 | * Lines beginning with "public" or within a "#ifndef public ... #endif" |
| 11 | * block are copied to the new file. Initializations (e.g. "int x = 3") are |
| 12 | * omitted ("int x;" is output). |
| 13 | * |
| 14 | * Normally a temporary definitions file is created and compared to |
| 15 | * the given destination. If they are different, the temporary file |
| 16 | * is copied on top of the destination. This is so that dependencies |
| 17 | * when using "make" are not triggered. |
| 18 | * |
| 19 | * The "-f" option overrides this and forces the destination file to be created. |
| 20 | */ |
| 21 | |
| 22 | #include "defs.h" |
| 23 | #include <signal.h> |
| 24 | |
| 25 | #define procedure void |
| 26 | |
| 27 | Boolean force; |
| 28 | Boolean copytext; |
| 29 | |
| 30 | String tmpname; |
| 31 | String modulename(); |
| 32 | procedure abnorm(); |
| 33 | |
| 34 | main(argc, argv) |
| 35 | int argc; |
| 36 | String argv[]; |
| 37 | { |
| 38 | extern String mktemp(); |
| 39 | String name; |
| 40 | File tmp; |
| 41 | Integer r; |
| 42 | Integer index; |
| 43 | |
| 44 | if (streq(argv[1], "-f")) { |
| 45 | force = true; |
| 46 | index = 2; |
| 47 | } else { |
| 48 | force = false; |
| 49 | index = 1; |
| 50 | } |
| 51 | if (argc - index > 2) { |
| 52 | fatal("usage: makedefs [ -f ] file.c [ file.h ]\n"); |
| 53 | } |
| 54 | tmp = nil; |
| 55 | if (freopen(argv[index], "r", stdin) == NULL) { |
| 56 | fatal("can't read %s", argv[index]); |
| 57 | } |
| 58 | signal(SIGINT, abnorm); |
| 59 | signal(SIGQUIT, abnorm); |
| 60 | if (index + 1 < argc) { |
| 61 | if (force) { |
| 62 | tmpname = argv[index + 1]; |
| 63 | } else { |
| 64 | tmpname = mktemp("/tmp/makedefsXXXXXX"); |
| 65 | } |
| 66 | tmp = freopen(tmpname, "w", stdout); |
| 67 | if (tmp == nil) { |
| 68 | fatal("can't write %s", tmpname); |
| 69 | } |
| 70 | } |
| 71 | copytext = false; |
| 72 | name = modulename(argv[index]); |
| 73 | printf("#ifndef %s\n", name); |
| 74 | printf("#define %s\n", name); |
| 75 | copy(); |
| 76 | printf("#endif\n"); |
| 77 | if (tmp != NULL and not force) { |
| 78 | fclose(tmp); |
| 79 | r = call("cmp", stdin, stderr, "-s", tmpname, argv[2], nil); |
| 80 | if (r != 0) { |
| 81 | r = call("cp", stdin, stderr, tmpname, argv[2], nil); |
| 82 | if (r != 0) { |
| 83 | fprintf(stderr, "can't create %s\n", argv[2]); |
| 84 | } |
| 85 | } |
| 86 | unlink(tmpname); |
| 87 | } |
| 88 | quit(0); |
| 89 | } |
| 90 | |
| 91 | String modulename(s) |
| 92 | String s; |
| 93 | { |
| 94 | String r, i, j; |
| 95 | static char buf[256]; |
| 96 | |
| 97 | strcpy(buf, s); |
| 98 | i = rindex(buf, '/'); |
| 99 | if (i == nil) { |
| 100 | i = buf; |
| 101 | } |
| 102 | for (j = i; *j != '.'; j++); |
| 103 | *j++ = '_'; |
| 104 | *j++ = 'h'; |
| 105 | *j = '\0'; |
| 106 | return buf; |
| 107 | } |
| 108 | |
| 109 | copy() |
| 110 | { |
| 111 | register char *p; |
| 112 | char line[1024]; |
| 113 | |
| 114 | while (gets(line) != NULL) { |
| 115 | if (strncmp(line, "#ifndef public", 14) == 0) { |
| 116 | copytext = true; |
| 117 | } else if (strncmp(line, "#endif", 6) == 0) { |
| 118 | copytext = false; |
| 119 | } else if (strncmp(line, "public", 6) == 0) { |
| 120 | copydef(line); |
| 121 | } else if (copytext) { |
| 122 | printf("%s\n", line); |
| 123 | } |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | copydef(s) |
| 128 | String s; |
| 129 | { |
| 130 | register char *p; |
| 131 | register Boolean isproc; |
| 132 | |
| 133 | isproc = false; |
| 134 | for (p = &s[7]; *p != '\0' and *p != '='; p++) { |
| 135 | if (*p == '(') { |
| 136 | isproc = true; |
| 137 | printf("(/* "); |
| 138 | } else if (*p == ')' and isproc and *(p+1) == '\0') { |
| 139 | printf(" */)"); |
| 140 | } else { |
| 141 | putchar(*p); |
| 142 | } |
| 143 | } |
| 144 | if (isproc or *p == '=') { |
| 145 | putchar(';'); |
| 146 | } |
| 147 | putchar('\n'); |
| 148 | } |
| 149 | |
| 150 | /* |
| 151 | * Terminate program. |
| 152 | */ |
| 153 | |
| 154 | procedure abnorm(signo) |
| 155 | int signo; |
| 156 | { |
| 157 | unlink(tmpname); |
| 158 | quit(signo); |
| 159 | } |
| 160 | |
| 161 | quit(r) |
| 162 | int r; |
| 163 | { |
| 164 | exit(r); |
| 165 | } |
| 166 | |
| 167 | /* |
| 168 | * No special error recovery strategy. |
| 169 | */ |
| 170 | |
| 171 | erecover() |
| 172 | { |
| 173 | } |