diff options
author | Cameron Katri <me@cameronkatri.com> | 2021-05-09 14:20:58 -0400 |
---|---|---|
committer | Cameron Katri <me@cameronkatri.com> | 2021-05-09 14:20:58 -0400 |
commit | 5fd83771641d15c418f747bd343ba6738d3875f7 (patch) | |
tree | 5abf0f78f680d9837dbd93d4d4c3933bb7509599 /adv_cmds/gencat/gencat.c | |
download | apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.tar.gz apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.tar.zst apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.zip |
Import macOS userland
adv_cmds-176
basic_cmds-55
bootstrap_cmds-116.100.1
developer_cmds-66
diskdev_cmds-667.40.1
doc_cmds-53.60.1
file_cmds-321.40.3
mail_cmds-35
misc_cmds-34
network_cmds-606.40.1
patch_cmds-17
remote_cmds-63
shell_cmds-216.60.1
system_cmds-880.60.2
text_cmds-106
Diffstat (limited to 'adv_cmds/gencat/gencat.c')
-rw-r--r-- | adv_cmds/gencat/gencat.c | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/adv_cmds/gencat/gencat.c b/adv_cmds/gencat/gencat.c new file mode 100644 index 0000000..e0d00e3 --- /dev/null +++ b/adv_cmds/gencat/gencat.c @@ -0,0 +1,199 @@ +/*********************************************************** +Copyright 1990, by Alfalfa Software Incorporated, Cambridge, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that Alfalfa's name not be used in +advertising or publicity pertaining to distribution of the software +without specific, written prior permission. + +ALPHALPHA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +ALPHALPHA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +If you make any modifications, bugfixes or other changes to this software +we'd appreciate it if you could send a copy to us so we can keep things +up-to-date. Many thanks. + Kee Hinckley + Alfalfa Software, Inc. + 267 Allston St., #3 + Cambridge, MA 02139 USA + nazgul@alfalfa.com + +******************************************************************/ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD: src/usr.bin/gencat/gencat.c,v 1.9 2002/05/29 14:23:10 tjr Exp $"); + +#include <sys/file.h> +#include <sys/stat.h> +#include <err.h> +#include <paths.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include "gencat.h" + +/* + * The spec says the syntax is "gencat catfile msgfile...". + * We extend it to: + * gencat [-lang C|C++|ANSIC] catfile msgfile [-h <header-file>]... + * Flags are order dependent, we'll take whatever lang was most recently chosen + * and use it to generate the next header file. The header files are generated + * at the point in the command line they are listed. Thus the sequence: + * gencat -lang C foo.cat foo.mcs -h foo.h -lang C++ bar.mcs -h bar.H + * will put constants from foo.mcs into foo.h and constants from bar.mcs into + * bar.h. Constants are not saved in the catalog file, so nothing will come + * from that, even if things have been defined before. The constants in foo.h + * will be in C syntax, in bar.H in C++ syntax. + */ + +static void writeIfChanged(char *, int, int); + +static void +usage(void) +{ + fprintf(stderr, "usage: gencat [-new] [-or] [-lang C|C++|ANSIC]\n" + " catfile msgfile [-h <header-file>]...\n"); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + int ofd = -1, ifd, i; + char *catfile = NULL; + char *input = NULL; + int lang = MCLangC; + int new = FALSE; + int orConsts = FALSE; + + for (i = 1; i < argc; ++i) { + if (argv[i][0] == '-') { + if (strcmp(argv[i], "-lang") == 0) { + ++i; + if (strcmp(argv[i], "C") == 0) lang = MCLangC; + else if (strcmp(argv[i], "C++") == 0) lang = MCLangCPlusPlus; + else if (strcmp(argv[i], "ANSIC") == 0) lang = MCLangANSIC; + else { + errx(1, "unrecognized language: %s", argv[i]); + } + } else if (strcmp(argv[i], "-h") == 0) { + if (!input) + errx(1, "can't write to a header before reading something"); + ++i; + writeIfChanged(argv[i], lang, orConsts); + } else if (strcmp(argv[i], "-new") == 0) { + if (catfile) + errx(1, "you must specify -new before the catalog file name"); + new = TRUE; + } else if (strcmp(argv[i], "-or") == 0) { + orConsts = ~orConsts; + } else { + usage(); + } + } else { + if (!catfile) { + catfile = argv[i]; + if (new) { + if ((ofd = open(catfile, O_WRONLY|O_TRUNC|O_CREAT, 0666)) < 0) + errx(1, "unable to create a new %s", catfile); + } else if ((ofd = open(catfile, O_RDONLY)) < 0) { + if ((ofd = open(catfile, O_WRONLY|O_CREAT, 0666)) < 0) + errx(1, "unable to create %s", catfile); + } else { + MCReadCat(ofd); + close(ofd); + if ((ofd = open(catfile, O_WRONLY|O_TRUNC)) < 0) + errx(1, "unable to truncate %s", catfile); + } + } else { + input = argv[i]; + if ((ifd = open(input, O_RDONLY)) < 0) + errx(1, "unable to read %s", input); + MCParse(ifd); + close(ifd); + } + } + } + if (catfile) { + MCWriteCat(ofd); + exit(0); + } else { + usage(); + } + return 0; +} + +static void +writeIfChanged(char *fname, int lang, int orConsts) +{ + char tmpname[] = _PATH_TMP"/gencat.XXXXXX"; + char buf[BUFSIZ], tbuf[BUFSIZ], *cptr, *tptr; + int fd, tfd; + int diff = FALSE; + int len, tlen; + struct stat sbuf; + + /* If it doesn't exist, just create it */ + if (stat(fname, &sbuf)) { + if ((fd = open(fname, O_WRONLY|O_CREAT, 0666)) < 0) + errx(1, "unable to create header file %s", fname); + MCWriteConst(fd, lang, orConsts); + close(fd); + return; + } + + /* If it does exist, create a temp file for now */ + if ((tfd = mkstemp(tmpname)) < 0) + err(1, "mkstemp"); + unlink(tmpname); + + /* Write to the temp file and rewind */ + MCWriteConst(tfd, lang, orConsts); + + /* Open the real header file */ + if ((fd = open(fname, O_RDONLY)) < 0) + errx(1, "unable to read header file: %s", fname); + + /* Backup to the start of the temp file */ + if (lseek(tfd, (off_t)0, L_SET) < 0) + errx(1, "unable to seek in tempfile: %s", tmpname); + + /* Now compare them */ + while ((tlen = read(tfd, tbuf, BUFSIZ)) > 0) { + if ((len = read(fd, buf, BUFSIZ)) != tlen) { + diff = TRUE; + goto done; + } + for (cptr = buf, tptr = tbuf; cptr < buf+len; ++cptr, ++tptr) { + if (*tptr != *cptr) { + diff = TRUE; + goto done; + } + } + } +done: + if (diff) { + if (lseek(tfd, (off_t)0, L_SET) < 0) + errx(1, "unable to seek in tempfile: %s", tmpname); + close(fd); + if ((fd = open(fname, O_WRONLY|O_TRUNC)) < 0) + errx(1, "unable to truncate header file: %s", fname); + while ((len = read(tfd, buf, BUFSIZ)) > 0) { + if (write(fd, buf, (size_t)len) != len) + warnx("error writing to header file: %s", fname); + } + } + close(fd); + close(tfd); +} |