source: vendor/FreeBSD-usr.bin/current/gencat.c@ 2362

Last change on this file since 2362 was 1308, checked in by bird, 21 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 6.0 KB
Line 
1/***********************************************************
2Copyright 1990, by Alfalfa Software Incorporated, Cambridge, Massachusetts.
3
4 All Rights Reserved
5
6Permission to use, copy, modify, and distribute this software and its
7documentation for any purpose and without fee is hereby granted,
8provided that the above copyright notice appear in all copies and that
9both that copyright notice and this permission notice appear in
10supporting documentation, and that Alfalfa's name not be used in
11advertising or publicity pertaining to distribution of the software
12without specific, written prior permission.
13
14ALPHALPHA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16ALPHALPHA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20SOFTWARE.
21
22If you make any modifications, bugfixes or other changes to this software
23we'd appreciate it if you could send a copy to us so we can keep things
24up-to-date. Many thanks.
25 Kee Hinckley
26 Alfalfa Software, Inc.
27 267 Allston St., #3
28 Cambridge, MA 02139 USA
29 nazgul@alfalfa.com
30
31******************************************************************/
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: src/usr.bin/gencat/gencat.c,v 1.9 2002/05/29 14:23:10 tjr Exp $");
35
36#include <sys/file.h>
37#include <sys/stat.h>
38#include <err.h>
39#include <paths.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include <unistd.h>
44#include "gencat.h"
45
46/*
47 * The spec says the syntax is "gencat catfile msgfile...".
48 * We extend it to:
49 * gencat [-lang C|C++|ANSIC] catfile msgfile [-h <header-file>]...
50 * Flags are order dependent, we'll take whatever lang was most recently chosen
51 * and use it to generate the next header file. The header files are generated
52 * at the point in the command line they are listed. Thus the sequence:
53 * gencat -lang C foo.cat foo.mcs -h foo.h -lang C++ bar.mcs -h bar.H
54 * will put constants from foo.mcs into foo.h and constants from bar.mcs into
55 * bar.h. Constants are not saved in the catalog file, so nothing will come
56 * from that, even if things have been defined before. The constants in foo.h
57 * will be in C syntax, in bar.H in C++ syntax.
58 */
59
60static void writeIfChanged(char *, int, int);
61
62static void
63usage(void)
64{
65 fprintf(stderr, "usage: gencat [-new] [-or] [-lang C|C++|ANSIC]\n"
66 " catfile msgfile [-h <header-file>]...\n");
67 exit(1);
68}
69
70int
71main(int argc, char *argv[])
72{
73 int ofd, ifd, i;
74 char *catfile = NULL;
75 char *input = NULL;
76 int lang = MCLangC;
77 int new = FALSE;
78 int orConsts = FALSE;
79
80 for (i = 1; i < argc; ++i) {
81 if (argv[i][0] == '-') {
82 if (strcmp(argv[i], "-lang") == 0) {
83 ++i;
84 if (strcmp(argv[i], "C") == 0) lang = MCLangC;
85 else if (strcmp(argv[i], "C++") == 0) lang = MCLangCPlusPlus;
86 else if (strcmp(argv[i], "ANSIC") == 0) lang = MCLangANSIC;
87 else {
88 errx(1, "unrecognized language: %s", argv[i]);
89 }
90 } else if (strcmp(argv[i], "-h") == 0) {
91 if (!input)
92 errx(1, "can't write to a header before reading something");
93 ++i;
94 writeIfChanged(argv[i], lang, orConsts);
95 } else if (strcmp(argv[i], "-new") == 0) {
96 if (catfile)
97 errx(1, "you must specify -new before the catalog file name");
98 new = TRUE;
99 } else if (strcmp(argv[i], "-or") == 0) {
100 orConsts = ~orConsts;
101 } else {
102 usage();
103 }
104 } else {
105 if (!catfile) {
106 catfile = argv[i];
107 if (new) {
108 if ((ofd = open(catfile, O_WRONLY|O_TRUNC|O_CREAT, 0666)) < 0)
109 errx(1, "unable to create a new %s", catfile);
110 } else if ((ofd = open(catfile, O_RDONLY)) < 0) {
111 if ((ofd = open(catfile, O_WRONLY|O_CREAT, 0666)) < 0)
112 errx(1, "unable to create %s", catfile);
113 } else {
114 MCReadCat(ofd);
115 close(ofd);
116 if ((ofd = open(catfile, O_WRONLY|O_TRUNC)) < 0)
117 errx(1, "unable to truncate %s", catfile);
118 }
119 } else {
120 input = argv[i];
121 if ((ifd = open(input, O_RDONLY)) < 0)
122 errx(1, "unable to read %s", input);
123 MCParse(ifd);
124 close(ifd);
125 }
126 }
127 }
128 if (catfile) {
129 MCWriteCat(ofd);
130 exit(0);
131 } else {
132 usage();
133 }
134 return 0;
135}
136
137static void
138writeIfChanged(char *fname, int lang, int orConsts)
139{
140 char tmpname[] = _PATH_TMP"/gencat.XXXXXX";
141 char buf[BUFSIZ], tbuf[BUFSIZ], *cptr, *tptr;
142 int fd, tfd;
143 int diff = FALSE;
144 int len, tlen;
145 struct stat sbuf;
146
147 /* If it doesn't exist, just create it */
148 if (stat(fname, &sbuf)) {
149 if ((fd = open(fname, O_WRONLY|O_CREAT, 0666)) < 0)
150 errx(1, "unable to create header file %s", fname);
151 MCWriteConst(fd, lang, orConsts);
152 close(fd);
153 return;
154 }
155
156 /* If it does exist, create a temp file for now */
157 if ((tfd = mkstemp(tmpname)) < 0)
158 err(1, "mkstemp");
159 unlink(tmpname);
160
161 /* Write to the temp file and rewind */
162 MCWriteConst(tfd, lang, orConsts);
163
164 /* Open the real header file */
165 if ((fd = open(fname, O_RDONLY)) < 0)
166 errx(1, "unable to read header file: %s", fname);
167
168 /* Backup to the start of the temp file */
169 if (lseek(tfd, (off_t)0, L_SET) < 0)
170 errx(1, "unable to seek in tempfile: %s", tmpname);
171
172 /* Now compare them */
173 while ((tlen = read(tfd, tbuf, BUFSIZ)) > 0) {
174 if ((len = read(fd, buf, BUFSIZ)) != tlen) {
175 diff = TRUE;
176 goto done;
177 }
178 for (cptr = buf, tptr = tbuf; cptr < buf+len; ++cptr, ++tptr) {
179 if (*tptr != *cptr) {
180 diff = TRUE;
181 goto done;
182 }
183 }
184 }
185done:
186 if (diff) {
187 if (lseek(tfd, (off_t)0, L_SET) < 0)
188 errx(1, "unable to seek in tempfile: %s", tmpname);
189 close(fd);
190 if ((fd = open(fname, O_WRONLY|O_TRUNC)) < 0)
191 errx(1, "unable to truncate header file: %s", fname);
192 while ((len = read(tfd, buf, BUFSIZ)) > 0) {
193 if (write(fd, buf, (size_t)len) != len)
194 warnx("error writing to header file: %s", fname);
195 }
196 }
197 close(fd);
198 close(tfd);
199}
Note: See TracBrowser for help on using the repository browser.