Annotation of src/usr.bin/gencat/gencat.c, Revision 1.1
1.1 ! deraadt 1:
! 2: /***********************************************************
! 3: Copyright 1990, by Alfalfa Software Incorporated, Cambridge, Massachusetts.
! 4:
! 5: All Rights Reserved
! 6:
! 7: Permission to use, copy, modify, and distribute this software and its
! 8: documentation for any purpose and without fee is hereby granted,
! 9: provided that the above copyright notice appear in all copies and that
! 10: both that copyright notice and this permission notice appear in
! 11: supporting documentation, and that Alfalfa's name not be used in
! 12: advertising or publicity pertaining to distribution of the software
! 13: without specific, written prior permission.
! 14:
! 15: ALPHALPHA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
! 16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
! 17: ALPHALPHA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
! 18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
! 19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
! 20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
! 21: SOFTWARE.
! 22:
! 23: If you make any modifications, bugfixes or other changes to this software
! 24: we'd appreciate it if you could send a copy to us so we can keep things
! 25: up-to-date. Many thanks.
! 26: Kee Hinckley
! 27: Alfalfa Software, Inc.
! 28: 267 Allston St., #3
! 29: Cambridge, MA 02139 USA
! 30: nazgul@alfalfa.com
! 31:
! 32: ******************************************************************/
! 33:
! 34: /* Edit History
! 35:
! 36: 01/18/91 3 hamilton #if not reparsed
! 37: 01/12/91 2 schulert conditionally use prototypes
! 38: 12/23/90 2 hamilton Fix fd == NULL to fd < 0
! 39: 11/03/90 1 hamilton Alphalpha->Alfalfa & OmegaMail->Poste
! 40: 08/13/90 1 schulert move from ua to omu
! 41: */
! 42:
! 43: #include <stdio.h>
! 44: #include <sys/types.h>
! 45: #ifdef SYSV
! 46: #include <sys/fcntl.h>
! 47: #define L_SET SEEK_SET
! 48: #define L_INCR SEEK_CUR
! 49: #endif
! 50: #include <sys/file.h>
! 51: #include <sys/stat.h>
! 52: #include "gencat.h"
! 53:
! 54: /*
! 55: * The spec says the syntax is "gencat catfile msgfile...".
! 56: * We extend it to:
! 57: * gencat [-lang C|C++|ANSIC] catfile msgfile [-h <header-file>]...
! 58: * Flags are order dependant, we'll take whatever lang was most recently chosen
! 59: * and use it to generate the next header file. The header files are generated
! 60: * at the point in the command line they are listed. Thus the sequence:
! 61: * gencat -lang C foo.cat foo.mcs -h foo.h -lang C++ bar.mcs -h bar.H
! 62: * will put constants from foo.mcs into foo.h and constants from bar.mcs into
! 63: * bar.h. Constants are not saved in the catalog file, so nothing will come
! 64: * from that, even if things have been defined before. The constants in foo.h
! 65: * will be in C syntax, in bar.H in C++ syntax.
! 66: */
! 67:
! 68: #if ANSI_C || defined(__cplusplus)
! 69: # define P_(x) x
! 70: #else
! 71: # define P_(x) /**/
! 72: #endif
! 73:
! 74: static void writeIfChanged P_((char *fname, int lang, int orConsts));
! 75:
! 76: #undef P_
! 77:
! 78: void usage() {
! 79: fprintf(stderr, "Use: gencat [-new] [-or] [-lang C|C++|ANSIC]\n");
! 80: fprintf(stderr, " catfile msgfile [-h <header-file>]...\n");
! 81: }
! 82:
! 83: void main(
! 84: #if ANSI_C || defined(__cplusplus)
! 85: int argc, char *argv[])
! 86: #else
! 87: argc, argv)
! 88: int argc;
! 89: char *argv[];
! 90: #endif
! 91: {
! 92: int ofd, ifd, i;
! 93: FILE *fptr;
! 94: char *catfile = NULL;
! 95: char *input = NULL;
! 96: int lang = MCLangC;
! 97: int new = False;
! 98: int orConsts = False;
! 99:
! 100: for (i = 1; i < argc; ++i) {
! 101: if (argv[i][0] == '-') {
! 102: if (strcmp(argv[i], "-lang") == 0) {
! 103: ++i;
! 104: if (strcmp(argv[i], "C") == 0) lang = MCLangC;
! 105: else if (strcmp(argv[i], "C++") == 0) lang = MCLangCPlusPlus;
! 106: else if (strcmp(argv[i], "ANSIC") == 0) lang = MCLangANSIC;
! 107: else {
! 108: fprintf(stderr, "gencat: Unrecognized language: %s\n", argv[i]);
! 109: exit(1);
! 110: }
! 111: } else if (strcmp(argv[i], "-h") == 0) {
! 112: if (!input) {
! 113: fprintf(stderr, "gencat: Can't write to a header before reading something.\n");
! 114: exit(1);
! 115: }
! 116: ++i;
! 117: writeIfChanged(argv[i], lang, orConsts);
! 118: } else if (strcmp(argv[i], "-new") == 0) {
! 119: if (catfile) {
! 120: fprintf(stderr, "gencat: You must specify -new before the catalog file name\n");
! 121: exit(1);
! 122: }
! 123: new = True;
! 124: } else if (strcmp(argv[i], "-or") == 0) {
! 125: orConsts = ~orConsts;
! 126: } else {
! 127: usage();
! 128: exit(1);
! 129: }
! 130: } else {
! 131: if (!catfile) {
! 132: catfile = argv[i];
! 133: if (new) {
! 134: if ((ofd = open(catfile, O_WRONLY|O_TRUNC|O_CREAT, 0666)) < 0) {
! 135: fprintf(stderr, "gencat: Unable to create a new %s.\n", catfile);
! 136: exit(1);
! 137: }
! 138: } else if ((ofd = open(catfile, O_RDONLY)) < 0) {
! 139: if ((ofd = open(catfile, O_WRONLY|O_CREAT, 0666)) < 0) {
! 140: fprintf(stderr, "gencat: Unable to create %s.\n", catfile);
! 141: exit(1);
! 142: }
! 143: } else {
! 144: MCReadCat(ofd);
! 145: close(ofd);
! 146: if ((ofd = open(catfile, O_WRONLY|O_TRUNC)) < 0) {
! 147: fprintf(stderr, "gencat: Unable to truncate %s.\n", catfile);
! 148: exit(1);
! 149: }
! 150: }
! 151: } else {
! 152: input = argv[i];
! 153: if ((ifd = open(input, O_RDONLY)) < 0) {
! 154: fprintf(stderr, "gencat: Unable to read %s\n", input);
! 155: exit(1);
! 156: }
! 157: MCParse(ifd);
! 158: close(ifd);
! 159: }
! 160: }
! 161: }
! 162: if (catfile) {
! 163: MCWriteCat(ofd);
! 164: exit(0);
! 165: } else {
! 166: usage();
! 167: exit(1);
! 168: }
! 169: }
! 170:
! 171: static void writeIfChanged(
! 172: #if ANSI_C || defined(__cplusplus)
! 173: char *fname, int lang, int orConsts)
! 174: #else
! 175: fname, lang, orConsts)
! 176: char *fname;
! 177: int lang;
! 178: int orConsts;
! 179: #endif
! 180: {
! 181: char tmpname[32];
! 182: char buf[BUFSIZ], tbuf[BUFSIZ], *cptr, *tptr;
! 183: int fd, tfd;
! 184: int diff = False;
! 185: int c, len, tlen;
! 186: struct stat sbuf;
! 187:
! 188: /* If it doesn't exist, just create it */
! 189: if (stat(fname, &sbuf)) {
! 190: if ((fd = open(fname, O_WRONLY|O_CREAT, 0666)) < 0) {
! 191: fprintf(stderr, "gencat: Unable to create header file %s.\n", fname);
! 192: exit(1);
! 193: }
! 194: MCWriteConst(fd, lang, orConsts);
! 195: close(fd);
! 196: return;
! 197: }
! 198:
! 199: /* If it does exist, create a temp file for now */
! 200: sprintf(tmpname, "/tmp/gencat.%d", (int) getpid());
! 201: if ((tfd = open(tmpname, O_RDWR|O_CREAT, 0666)) < 0) {
! 202: fprintf(stderr, "gencat: Unable to open temporary file: %s\n", tmpname);
! 203: exit(1);
! 204: }
! 205: unlink(tmpname);
! 206:
! 207: /* Write to the temp file and rewind */
! 208: MCWriteConst(tfd, lang, orConsts);
! 209:
! 210: /* Open the real header file */
! 211: if ((fd = open(fname, O_RDONLY)) < 0) {
! 212: fprintf(stderr, "gencat: Unable to read header file: %s\n", fname);
! 213: exit(1);
! 214: }
! 215:
! 216: /* Backup to the start of the temp file */
! 217: if (lseek(tfd, 0L, L_SET) < 0) {
! 218: fprintf(stderr, "gencat: Unable to seek in tempfile: %s\n", tmpname);
! 219: exit(1);
! 220: }
! 221:
! 222: /* Now compare them */
! 223: while ((tlen = read(tfd, tbuf, BUFSIZ)) > 0) {
! 224: if ((len = read(fd, buf, BUFSIZ)) != tlen) {
! 225: diff = True;
! 226: goto done;
! 227: }
! 228: for (cptr = buf, tptr = tbuf; cptr < buf+len; ++cptr, ++tptr) {
! 229: if (*tptr != *cptr) {
! 230: diff = True;
! 231: goto done;
! 232: }
! 233: }
! 234: }
! 235: done:
! 236: if (diff) {
! 237: if (lseek(tfd, 0L, L_SET) < 0) {
! 238: fprintf(stderr, "gencat: Unable to seek in tempfile: %s\n", tmpname);
! 239: exit(1);
! 240: }
! 241: close(fd);
! 242: if ((fd = open(fname, O_WRONLY|O_TRUNC)) < 0) {
! 243: fprintf(stderr, "gencat: Unable to truncate header file: %s\n", fname);
! 244: exit(1);
! 245: }
! 246: while ((len = read(tfd, buf, BUFSIZ)) > 0) {
! 247: if (write(fd, buf, len) != len) {
! 248: fprintf(stderr, "gencat: Error writing to header file: %s\n", fname);
! 249: }
! 250: }
! 251: }
! 252: close(fd);
! 253: close(tfd);
! 254: }