169b1fd3fSRichard Lowe /*
269b1fd3fSRichard Lowe * CDDL HEADER START
369b1fd3fSRichard Lowe *
469b1fd3fSRichard Lowe * The contents of this file are subject to the terms of the
569b1fd3fSRichard Lowe * Common Development and Distribution License (the "License").
669b1fd3fSRichard Lowe * You may not use this file except in compliance with the License.
769b1fd3fSRichard Lowe *
869b1fd3fSRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
969b1fd3fSRichard Lowe * or http://www.opensolaris.org/os/licensing.
1069b1fd3fSRichard Lowe * See the License for the specific language governing permissions
1169b1fd3fSRichard Lowe * and limitations under the License.
1269b1fd3fSRichard Lowe *
1369b1fd3fSRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each
1469b1fd3fSRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1569b1fd3fSRichard Lowe * If applicable, add the following below this CDDL HEADER, with the
1669b1fd3fSRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
1769b1fd3fSRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
1869b1fd3fSRichard Lowe *
1969b1fd3fSRichard Lowe * CDDL HEADER END
2069b1fd3fSRichard Lowe */
2169b1fd3fSRichard Lowe /*
2269b1fd3fSRichard Lowe * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
2369b1fd3fSRichard Lowe *
2469b1fd3fSRichard Lowe * sgsmsg generates several message files from an input template file. Messages
25*4b9db4f6SChris Fraire * are constructed for use with gettext(3C) - the default - or catgets(3C). The
2669b1fd3fSRichard Lowe * files generate are:
2769b1fd3fSRichard Lowe *
2869b1fd3fSRichard Lowe * msg.h a header file containing definitions for each message. The -h
2969b1fd3fSRichard Lowe * option triggers the creation of these definitions and specifies
3069b1fd3fSRichard Lowe * the name to use.
3169b1fd3fSRichard Lowe *
3269b1fd3fSRichard Lowe * msg.c a data array of message strings. The msg.h definitions are
3369b1fd3fSRichard Lowe * offsets into this array. The -d option triggers the creation of
3469b1fd3fSRichard Lowe * these definitions and specifies the name to use.
3569b1fd3fSRichard Lowe *
36*4b9db4f6SChris Fraire * messages a message file suitable for catgets(3C) or gettext(3C) use. The
3769b1fd3fSRichard Lowe * -m option triggers this output and specifies the filename to be
3869b1fd3fSRichard Lowe * used.
3969b1fd3fSRichard Lowe *
4069b1fd3fSRichard Lowe * The template file is processed based on the first character of each line:
4169b1fd3fSRichard Lowe *
4269b1fd3fSRichard Lowe * # or $ entries are copied (as is) to the message file (messages).
4369b1fd3fSRichard Lowe *
4469b1fd3fSRichard Lowe * @ token(s) entries are translated. Two translations are possible dependent
4569b1fd3fSRichard Lowe * on whether one or more tokens are supplied:
4669b1fd3fSRichard Lowe *
4769b1fd3fSRichard Lowe * A single token is interpreted as one of two reserved message
4869b1fd3fSRichard Lowe * output indicators, or a message identifier. The reserved output
4969b1fd3fSRichard Lowe * indicator _START_ enables output to the message file - Note that
5069b1fd3fSRichard Lowe * the occurance of any other @ token will also enable message
5169b1fd3fSRichard Lowe * output. The reserved output indicator _END_ disables output to
5269b1fd3fSRichard Lowe * the message file. The use of these two indicators provides for
5369b1fd3fSRichard Lowe * only those message strings that require translation to be output
5469b1fd3fSRichard Lowe * to the message file.
5569b1fd3fSRichard Lowe *
5669b1fd3fSRichard Lowe * Besides the reserved output indicators, a single token is taken
5769b1fd3fSRichard Lowe * to be a message identifier which will be subsituted for a
5869b1fd3fSRichard Lowe * `setid' for catgets(3c) output, or a `domain' name for
59*4b9db4f6SChris Fraire * gettext(3C) output. This value is determine by substituting the
6069b1fd3fSRichard Lowe * token for the associated definition found in the message
6169b1fd3fSRichard Lowe * identifier file (specified with the -i option).
6269b1fd3fSRichard Lowe *
6369b1fd3fSRichard Lowe * Multiple tokens are taken to be a message definition followed by
6469b1fd3fSRichard Lowe * the associated message string. The message string is copied to
6569b1fd3fSRichard Lowe * the data array being built in msg.c. The index into this array
6669b1fd3fSRichard Lowe * becomes the `message' identifier created in the msg.h file.
6769b1fd3fSRichard Lowe */
6869b1fd3fSRichard Lowe
6969b1fd3fSRichard Lowe #include <fcntl.h>
7069b1fd3fSRichard Lowe #include <stdlib.h>
7169b1fd3fSRichard Lowe #include <stdio.h>
7269b1fd3fSRichard Lowe #include <unistd.h>
7369b1fd3fSRichard Lowe #include <limits.h>
7469b1fd3fSRichard Lowe #include <string.h>
7569b1fd3fSRichard Lowe #include <ctype.h>
7669b1fd3fSRichard Lowe #include <errno.h>
7769b1fd3fSRichard Lowe #include <sys/param.h>
7869b1fd3fSRichard Lowe
7969b1fd3fSRichard Lowe #include <sgs.h>
8069b1fd3fSRichard Lowe #include <_string_table.h>
8169b1fd3fSRichard Lowe
8269b1fd3fSRichard Lowe /*
8369b1fd3fSRichard Lowe * Define any error message strings.
8469b1fd3fSRichard Lowe */
8569b1fd3fSRichard Lowe static const char
8669b1fd3fSRichard Lowe * Errmsg_malt = "sgsmsg: file %s: line %d: malformed input "
8769b1fd3fSRichard Lowe "at line\n",
8869b1fd3fSRichard Lowe * Errmsg_nmem = "sgsmsg: memory allocation failed: %s\n",
8969b1fd3fSRichard Lowe * Errmsg_opne = "sgsmsg: file %s: open failed: %s\n",
9069b1fd3fSRichard Lowe * Errmsg_wrte = "sgsmsg: file %s: write failed: %s\n",
9169b1fd3fSRichard Lowe * Errmsg_read = "sgsmsg: file %s: read failed %s\n",
9269b1fd3fSRichard Lowe * Errmsg_stnw = "sgsmsg: st_new(): failed: %s\n",
9369b1fd3fSRichard Lowe * Errmsg_stin = "sgsmsg: Str_tbl insert failed: %s\n",
9469b1fd3fSRichard Lowe * Errmsg_mnfn = "sgsmsg: message not found in Str_tbl: %s\n",
9569b1fd3fSRichard Lowe * Errmsg_use = "usage: sgsmsg [-clv] [-d mesgdata] [-h mesgdefs] "
9669b1fd3fSRichard Lowe "[-m messages] [-n name] [-i mesgident] file ...\n";
9769b1fd3fSRichard Lowe
9869b1fd3fSRichard Lowe /*
9969b1fd3fSRichard Lowe * Define all output filenames and associated descriptors.
10069b1fd3fSRichard Lowe */
10169b1fd3fSRichard Lowe static FILE *fddefs, *fddata, *fdmsgs, *fdmids, *fddesc;
10269b1fd3fSRichard Lowe static char *fldefs, *fldata, *flmsgs, *flmids, *fldesc;
10369b1fd3fSRichard Lowe static FILE *fdlint;
10469b1fd3fSRichard Lowe static char fllint[MAXPATHLEN];
10569b1fd3fSRichard Lowe
10669b1fd3fSRichard Lowe static uint_t vflag; /* verbose flag */
10769b1fd3fSRichard Lowe static Str_tbl *stp; /* string table */
10869b1fd3fSRichard Lowe
10969b1fd3fSRichard Lowe /*
11069b1fd3fSRichard Lowe * Define any default strings.
11169b1fd3fSRichard Lowe */
11269b1fd3fSRichard Lowe static const char
11369b1fd3fSRichard Lowe *nmlint = "/tmp/sgsmsg.lint",
11469b1fd3fSRichard Lowe *interface = "sgs_msg",
11569b1fd3fSRichard Lowe *start = "_START_",
11669b1fd3fSRichard Lowe *end = "_END_";
11769b1fd3fSRichard Lowe
11869b1fd3fSRichard Lowe /*
11969b1fd3fSRichard Lowe * Define any default flags and data items.
12069b1fd3fSRichard Lowe */
12169b1fd3fSRichard Lowe static int cflag = 0, lflag = 0, prtmsgs = 0, line, ptr = 1, msgid = 0;
12269b1fd3fSRichard Lowe static char *mesgid = 0, *setid = 0, *domain = 0;
12369b1fd3fSRichard Lowe
12469b1fd3fSRichard Lowe typedef struct msg_string {
12569b1fd3fSRichard Lowe char *ms_defn;
12669b1fd3fSRichard Lowe char *ms_message;
12769b1fd3fSRichard Lowe struct msg_string *ms_next;
12869b1fd3fSRichard Lowe } msg_string;
12969b1fd3fSRichard Lowe
13069b1fd3fSRichard Lowe static msg_string *msg_head;
13169b1fd3fSRichard Lowe static msg_string *msg_tail;
13269b1fd3fSRichard Lowe
13369b1fd3fSRichard Lowe /*
13469b1fd3fSRichard Lowe * message_append() is responsible for both inserting strings into
13569b1fd3fSRichard Lowe * the master Str_tbl as well as maintaining a list of the
13669b1fd3fSRichard Lowe * DEFINITIONS associated with each string.
13769b1fd3fSRichard Lowe *
13869b1fd3fSRichard Lowe * The list of strings is traversed at the end once the full
13969b1fd3fSRichard Lowe * Str_tbl has been constructed - and string offsets can be
14069b1fd3fSRichard Lowe * assigned.
14169b1fd3fSRichard Lowe */
14269b1fd3fSRichard Lowe static void
message_append(const char * defn,const char * message)14369b1fd3fSRichard Lowe message_append(const char *defn, const char *message)
14469b1fd3fSRichard Lowe {
14569b1fd3fSRichard Lowe msg_string *msg;
14669b1fd3fSRichard Lowe if ((msg = calloc(sizeof (msg_string), 1)) == 0) {
14769b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_nmem, strerror(errno));
14869b1fd3fSRichard Lowe exit(1);
14969b1fd3fSRichard Lowe }
15069b1fd3fSRichard Lowe
15169b1fd3fSRichard Lowe /*
15269b1fd3fSRichard Lowe * Initialize the string table.
15369b1fd3fSRichard Lowe */
15469b1fd3fSRichard Lowe if ((stp == 0) && ((stp = st_new(FLG_STNEW_COMPRESS)) == NULL)) {
15569b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_stnw, strerror(errno));
15669b1fd3fSRichard Lowe exit(1);
15769b1fd3fSRichard Lowe }
15869b1fd3fSRichard Lowe
15969b1fd3fSRichard Lowe
16069b1fd3fSRichard Lowe if ((msg->ms_defn = strdup(defn)) == 0) {
16169b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_nmem, strerror(errno));
16269b1fd3fSRichard Lowe exit(1);
16369b1fd3fSRichard Lowe }
16469b1fd3fSRichard Lowe if ((msg->ms_message = strdup(message)) == 0) {
16569b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_nmem, strerror(errno));
16669b1fd3fSRichard Lowe exit(1);
16769b1fd3fSRichard Lowe }
16869b1fd3fSRichard Lowe
16969b1fd3fSRichard Lowe if (st_insert(stp, msg->ms_message) == -1) {
17069b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_stin,
17169b1fd3fSRichard Lowe message);
17269b1fd3fSRichard Lowe exit(1);
17369b1fd3fSRichard Lowe }
17469b1fd3fSRichard Lowe
17569b1fd3fSRichard Lowe if (msg_head == 0) {
17669b1fd3fSRichard Lowe msg_head = msg_tail = msg;
17769b1fd3fSRichard Lowe return;
17869b1fd3fSRichard Lowe }
17969b1fd3fSRichard Lowe msg_tail->ms_next = msg;
18069b1fd3fSRichard Lowe msg_tail = msg;
18169b1fd3fSRichard Lowe }
18269b1fd3fSRichard Lowe
18369b1fd3fSRichard Lowe /*
18469b1fd3fSRichard Lowe * Initialize a setid value. Given a setid definition determine its numeric
18569b1fd3fSRichard Lowe * value from the specified message identifier file (specified with the -i
18669b1fd3fSRichard Lowe * option). Return a pointer to the numeric string.
18769b1fd3fSRichard Lowe */
18869b1fd3fSRichard Lowe static int
getmesgid(char * id)18969b1fd3fSRichard Lowe getmesgid(char *id)
19069b1fd3fSRichard Lowe {
19169b1fd3fSRichard Lowe char *buffer, *token, *_mesgid = 0, *_setid = 0, *_domain = 0;
19269b1fd3fSRichard Lowe
19369b1fd3fSRichard Lowe /*
19469b1fd3fSRichard Lowe * If we're being asked to interpret a message id but the user didn't
19569b1fd3fSRichard Lowe * provide the required message identifier file (-i option) we're in
19669b1fd3fSRichard Lowe * trouble.
19769b1fd3fSRichard Lowe */
19869b1fd3fSRichard Lowe if (flmids == 0) {
19969b1fd3fSRichard Lowe (void) fprintf(stderr, "sgsmsg: file %s: line %d: mesgid %s: "
20069b1fd3fSRichard Lowe "unable to process mesgid\n\t"
20169b1fd3fSRichard Lowe "no message identifier file specified "
20269b1fd3fSRichard Lowe "(see -i option)\n", fldesc, line, id);
20369b1fd3fSRichard Lowe return (1);
20469b1fd3fSRichard Lowe }
20569b1fd3fSRichard Lowe
20669b1fd3fSRichard Lowe if ((buffer = malloc(LINE_MAX)) == 0) {
20769b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_nmem, strerror(errno));
20869b1fd3fSRichard Lowe return (1);
20969b1fd3fSRichard Lowe }
21069b1fd3fSRichard Lowe
21169b1fd3fSRichard Lowe /*
21269b1fd3fSRichard Lowe * Read the message identifier file and locate the required mesgid.
21369b1fd3fSRichard Lowe */
21469b1fd3fSRichard Lowe rewind(fdmids);
21569b1fd3fSRichard Lowe while (fgets(buffer, LINE_MAX, fdmids) != NULL) {
21669b1fd3fSRichard Lowe if ((token = strstr(buffer, id)) == NULL)
21769b1fd3fSRichard Lowe continue;
21869b1fd3fSRichard Lowe
21969b1fd3fSRichard Lowe /*
22069b1fd3fSRichard Lowe * Establish individual strings for the mesgid, setid and domain
22169b1fd3fSRichard Lowe * values.
22269b1fd3fSRichard Lowe */
22369b1fd3fSRichard Lowe _mesgid = token;
22469b1fd3fSRichard Lowe while (!(isspace(*token)))
22569b1fd3fSRichard Lowe token++;
22669b1fd3fSRichard Lowe *token++ = 0;
22769b1fd3fSRichard Lowe
22869b1fd3fSRichard Lowe while (isspace(*token))
22969b1fd3fSRichard Lowe token++;
23069b1fd3fSRichard Lowe _setid = token;
23169b1fd3fSRichard Lowe while (!(isspace(*token)))
23269b1fd3fSRichard Lowe token++;
23369b1fd3fSRichard Lowe *token++ = 0;
23469b1fd3fSRichard Lowe
23569b1fd3fSRichard Lowe while (isspace(*token))
23669b1fd3fSRichard Lowe token++;
23769b1fd3fSRichard Lowe _domain = token;
23869b1fd3fSRichard Lowe while (!(isspace(*token)))
23969b1fd3fSRichard Lowe token++;
24069b1fd3fSRichard Lowe *token = 0;
24169b1fd3fSRichard Lowe break;
24269b1fd3fSRichard Lowe }
24369b1fd3fSRichard Lowe
24469b1fd3fSRichard Lowe /*
24569b1fd3fSRichard Lowe * Did we find a match?
24669b1fd3fSRichard Lowe */
24769b1fd3fSRichard Lowe if ((_mesgid == 0) || (_setid == 0) || (_domain == 0)) {
24869b1fd3fSRichard Lowe (void) fprintf(stderr, "sgsmsg: file %s: line %d: mesgid %s: "
24969b1fd3fSRichard Lowe "unable to process mesgid\n\t"
25069b1fd3fSRichard Lowe "identifier does not exist in file %s\n",
25169b1fd3fSRichard Lowe fldesc, line, id, flmids);
25269b1fd3fSRichard Lowe return (1);
25369b1fd3fSRichard Lowe }
25469b1fd3fSRichard Lowe
25569b1fd3fSRichard Lowe /*
25669b1fd3fSRichard Lowe * Have we been here before?
25769b1fd3fSRichard Lowe */
25869b1fd3fSRichard Lowe if (mesgid) {
25969b1fd3fSRichard Lowe if (cflag == 1) {
26069b1fd3fSRichard Lowe /*
26169b1fd3fSRichard Lowe * If we're being asked to process more than one mesgid
26269b1fd3fSRichard Lowe * warn the user that only one mesgid can be used for
26369b1fd3fSRichard Lowe * the catgets(3c) call.
26469b1fd3fSRichard Lowe */
26569b1fd3fSRichard Lowe (void) fprintf(stderr, "sgsmsg: file %s: line %d: "
26669b1fd3fSRichard Lowe "setid %s: warning: multiple mesgids "
26769b1fd3fSRichard Lowe "encountered\n\t"
26869b1fd3fSRichard Lowe "last setting used in messaging code\n",
26969b1fd3fSRichard Lowe fldesc, line, id);
27069b1fd3fSRichard Lowe }
27169b1fd3fSRichard Lowe }
27269b1fd3fSRichard Lowe
27369b1fd3fSRichard Lowe mesgid = _mesgid;
27469b1fd3fSRichard Lowe setid = _setid;
27569b1fd3fSRichard Lowe domain = _domain;
27669b1fd3fSRichard Lowe
27769b1fd3fSRichard Lowe /*
27869b1fd3fSRichard Lowe * Generate the message file output (insure output flag is enabled).
27969b1fd3fSRichard Lowe */
28069b1fd3fSRichard Lowe if (prtmsgs != -1)
28169b1fd3fSRichard Lowe prtmsgs = 1;
28269b1fd3fSRichard Lowe if (fdmsgs && (prtmsgs == 1)) {
28369b1fd3fSRichard Lowe if (cflag == 1) {
28469b1fd3fSRichard Lowe if (fprintf(fdmsgs, "$quote \"\n$set %s\n",
28569b1fd3fSRichard Lowe setid) < 0) {
28669b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, flmsgs,
28769b1fd3fSRichard Lowe strerror(errno));
28869b1fd3fSRichard Lowe return (1);
28969b1fd3fSRichard Lowe }
29069b1fd3fSRichard Lowe } else {
29169b1fd3fSRichard Lowe if (fprintf(fdmsgs, "domain\t\"%s\"\n", domain) < 0) {
29269b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, flmsgs,
29369b1fd3fSRichard Lowe strerror(errno));
29469b1fd3fSRichard Lowe return (1);
29569b1fd3fSRichard Lowe }
29669b1fd3fSRichard Lowe }
29769b1fd3fSRichard Lowe }
29869b1fd3fSRichard Lowe
29969b1fd3fSRichard Lowe /*
30069b1fd3fSRichard Lowe * For catgets(3c) output generate a setid definition in the message
30169b1fd3fSRichard Lowe * definition file.
30269b1fd3fSRichard Lowe */
30369b1fd3fSRichard Lowe if (fddefs && (cflag == 1) &&
30469b1fd3fSRichard Lowe (fprintf(fddefs, "#define\t%s\t%s\n\n", mesgid, setid) < 0)) {
30569b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
30669b1fd3fSRichard Lowe return (1);
30769b1fd3fSRichard Lowe }
30869b1fd3fSRichard Lowe
30969b1fd3fSRichard Lowe return (0);
31069b1fd3fSRichard Lowe }
31169b1fd3fSRichard Lowe
31269b1fd3fSRichard Lowe /*
31369b1fd3fSRichard Lowe * Dump contents of String Table to standard out
31469b1fd3fSRichard Lowe */
31569b1fd3fSRichard Lowe static void
dump_stringtab(Str_tbl * stp)31669b1fd3fSRichard Lowe dump_stringtab(Str_tbl *stp)
31769b1fd3fSRichard Lowe {
31869b1fd3fSRichard Lowe uint_t cnt;
31969b1fd3fSRichard Lowe
32069b1fd3fSRichard Lowe if ((stp->st_flags & FLG_STTAB_COMPRESS) == 0) {
32169b1fd3fSRichard Lowe (void) printf("string table full size: %ld: uncompressed\n",
32269b1fd3fSRichard Lowe stp->st_fullstrsize);
32369b1fd3fSRichard Lowe return;
32469b1fd3fSRichard Lowe }
32569b1fd3fSRichard Lowe
32669b1fd3fSRichard Lowe (void) printf("string table full size: %ld compressed down to: %ld\n\n",
32769b1fd3fSRichard Lowe stp->st_fullstrsize, stp->st_strsize);
32869b1fd3fSRichard Lowe (void) printf("string table compression information [%d buckets]:\n",
32969b1fd3fSRichard Lowe stp->st_hbckcnt);
33069b1fd3fSRichard Lowe
33169b1fd3fSRichard Lowe for (cnt = 0; cnt < stp->st_hbckcnt; cnt++) {
33269b1fd3fSRichard Lowe Str_hash *sthash = stp->st_hashbcks[cnt];
33369b1fd3fSRichard Lowe
33469b1fd3fSRichard Lowe if (sthash == 0)
33569b1fd3fSRichard Lowe continue;
33669b1fd3fSRichard Lowe
33769b1fd3fSRichard Lowe (void) printf(" bucket: [%d]\n", cnt);
33869b1fd3fSRichard Lowe
33969b1fd3fSRichard Lowe while (sthash) {
34069b1fd3fSRichard Lowe size_t stroff = sthash->hi_mstr->sm_strlen -
34169b1fd3fSRichard Lowe sthash->hi_strlen;
34269b1fd3fSRichard Lowe
34369b1fd3fSRichard Lowe if (stroff == 0) {
34469b1fd3fSRichard Lowe (void) printf(" [%ld]: '%s' <master>\n",
34569b1fd3fSRichard Lowe sthash->hi_refcnt, sthash->hi_mstr->sm_str);
34669b1fd3fSRichard Lowe } else {
34769b1fd3fSRichard Lowe (void) printf(" [%ld]: '%s' <suffix of: "
34869b1fd3fSRichard Lowe "'%s'>\n", sthash->hi_refcnt,
34969b1fd3fSRichard Lowe &sthash->hi_mstr->sm_str[stroff],
35069b1fd3fSRichard Lowe sthash->hi_mstr->sm_str);
35169b1fd3fSRichard Lowe }
35269b1fd3fSRichard Lowe sthash = sthash->hi_next;
35369b1fd3fSRichard Lowe }
35469b1fd3fSRichard Lowe }
35569b1fd3fSRichard Lowe }
35669b1fd3fSRichard Lowe
35769b1fd3fSRichard Lowe /*
35869b1fd3fSRichard Lowe * Initialize the message definition header file stream.
35969b1fd3fSRichard Lowe */
36069b1fd3fSRichard Lowe static int
init_defs(void)36169b1fd3fSRichard Lowe init_defs(void)
36269b1fd3fSRichard Lowe {
36369b1fd3fSRichard Lowe static char guard[FILENAME_MAX + 6];
36469b1fd3fSRichard Lowe char *optr;
36569b1fd3fSRichard Lowe const char *iptr, *_ptr;
36669b1fd3fSRichard Lowe
36769b1fd3fSRichard Lowe /*
36869b1fd3fSRichard Lowe * Establish a header guard name using the files basename.
36969b1fd3fSRichard Lowe */
37069b1fd3fSRichard Lowe for (iptr = 0, _ptr = fldefs; _ptr && (*_ptr != '\0'); _ptr++) {
37169b1fd3fSRichard Lowe if (*_ptr == '/')
37269b1fd3fSRichard Lowe iptr = _ptr + 1;
37369b1fd3fSRichard Lowe }
37469b1fd3fSRichard Lowe if (iptr == 0)
37569b1fd3fSRichard Lowe iptr = fldefs;
37669b1fd3fSRichard Lowe
37769b1fd3fSRichard Lowe optr = guard;
37869b1fd3fSRichard Lowe for (*optr++ = '_'; iptr && (*iptr != '\0'); iptr++, optr++) {
37969b1fd3fSRichard Lowe if (*iptr == '.') {
38069b1fd3fSRichard Lowe *optr++ = '_';
38169b1fd3fSRichard Lowe *optr++ = 'D';
38269b1fd3fSRichard Lowe *optr++ = 'O';
38369b1fd3fSRichard Lowe *optr++ = 'T';
38469b1fd3fSRichard Lowe *optr = '_';
38569b1fd3fSRichard Lowe } else
38669b1fd3fSRichard Lowe *optr = toupper(*iptr);
38769b1fd3fSRichard Lowe }
38869b1fd3fSRichard Lowe
38969b1fd3fSRichard Lowe if (fprintf(fddefs, "#ifndef\t%s\n#define\t%s\n\n", guard, guard) < 0) {
39069b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
39169b1fd3fSRichard Lowe return (1);
39269b1fd3fSRichard Lowe }
39369b1fd3fSRichard Lowe
39469b1fd3fSRichard Lowe if (fprintf(fddefs, "#include <sgsmsg.h>\t/* Msg typedef */\n\n") < 0) {
39569b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
39669b1fd3fSRichard Lowe return (1);
39769b1fd3fSRichard Lowe }
39869b1fd3fSRichard Lowe
39969b1fd3fSRichard Lowe if (fprintf(fddefs, "#ifndef\t__lint\n\n") < 0) {
40069b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
40169b1fd3fSRichard Lowe return (1);
40269b1fd3fSRichard Lowe }
40369b1fd3fSRichard Lowe
40469b1fd3fSRichard Lowe /*
40569b1fd3fSRichard Lowe * The MSG_SGS_ARRAY_NAME macro supplies a generic way to
40669b1fd3fSRichard Lowe * reference the string table regardless of its name.
40769b1fd3fSRichard Lowe */
40869b1fd3fSRichard Lowe if (fprintf(fddefs, "#define\tMSG_SGS_LOCAL_ARRAY\t__%s\n\n",
40969b1fd3fSRichard Lowe interface) < 0) {
41069b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
41169b1fd3fSRichard Lowe return (1);
41269b1fd3fSRichard Lowe }
41369b1fd3fSRichard Lowe
41469b1fd3fSRichard Lowe /*
41569b1fd3fSRichard Lowe * If the associated data array is global define a prototype.
41669b1fd3fSRichard Lowe * Define a macro to access the array elements.
41769b1fd3fSRichard Lowe */
41869b1fd3fSRichard Lowe if (lflag == 0) {
41969b1fd3fSRichard Lowe if (fprintf(fddefs, "extern\tconst char\t__%s[];\n\n",
42069b1fd3fSRichard Lowe interface) < 0) {
42169b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldefs,
42269b1fd3fSRichard Lowe strerror(errno));
42369b1fd3fSRichard Lowe return (1);
42469b1fd3fSRichard Lowe }
42569b1fd3fSRichard Lowe }
42669b1fd3fSRichard Lowe if (fprintf(fddefs,
42769b1fd3fSRichard Lowe "#define\tMSG_ORIG_STRTAB(_x, _s)\t&_s[_x]\n\n") < 0) {
42869b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
42969b1fd3fSRichard Lowe return (1);
43069b1fd3fSRichard Lowe }
43169b1fd3fSRichard Lowe if (fprintf(fddefs,
43269b1fd3fSRichard Lowe "#define\tMSG_ORIG(x)\tMSG_ORIG_STRTAB(x, __%s)\n\n",
43369b1fd3fSRichard Lowe interface) < 0) {
43469b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
43569b1fd3fSRichard Lowe return (1);
43669b1fd3fSRichard Lowe }
43769b1fd3fSRichard Lowe
43869b1fd3fSRichard Lowe /*
43969b1fd3fSRichard Lowe * Generate a prototype to access the associated data array.
44069b1fd3fSRichard Lowe */
44169b1fd3fSRichard Lowe if (fprintf(fddefs, "extern\tconst char *\t_%s(Msg);\n\n",
44269b1fd3fSRichard Lowe interface) < 0) {
44369b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
44469b1fd3fSRichard Lowe return (1);
44569b1fd3fSRichard Lowe }
44669b1fd3fSRichard Lowe if (fprintf(fddefs, "#define\tMSG_INTL(x)\t_%s(x)\n\n",
44769b1fd3fSRichard Lowe interface) < 0) {
44869b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
44969b1fd3fSRichard Lowe return (1);
45069b1fd3fSRichard Lowe }
45169b1fd3fSRichard Lowe
45269b1fd3fSRichard Lowe return (0);
45369b1fd3fSRichard Lowe }
45469b1fd3fSRichard Lowe
45569b1fd3fSRichard Lowe
45669b1fd3fSRichard Lowe /*
45769b1fd3fSRichard Lowe * Finish the message definition header file.
45869b1fd3fSRichard Lowe */
45969b1fd3fSRichard Lowe static int
fini_defs(void)46069b1fd3fSRichard Lowe fini_defs(void)
46169b1fd3fSRichard Lowe {
46269b1fd3fSRichard Lowe if (fprintf(fddefs, "\n#else\t/* __lint */\n\n") < 0) {
46369b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
46469b1fd3fSRichard Lowe return (1);
46569b1fd3fSRichard Lowe }
46669b1fd3fSRichard Lowe
46769b1fd3fSRichard Lowe if (fprintf(fddefs, "extern\tconst char *\t_%s(Msg);\n\n",
46869b1fd3fSRichard Lowe interface) < 0) {
46969b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
47069b1fd3fSRichard Lowe return (1);
47169b1fd3fSRichard Lowe }
47269b1fd3fSRichard Lowe
47369b1fd3fSRichard Lowe if (fprintf(fddefs, "#ifndef MSG_SGS_LOCAL_ARRAY\n"
47469b1fd3fSRichard Lowe "#define\tMSG_SGS_LOCAL_ARRAY\t\"\"\n#endif\n\n") < 0) {
47569b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
47669b1fd3fSRichard Lowe return (1);
47769b1fd3fSRichard Lowe }
47869b1fd3fSRichard Lowe
47969b1fd3fSRichard Lowe if (lflag == 0) {
48069b1fd3fSRichard Lowe if (fprintf(fddefs, "extern\tconst char\t__%s[];\n\n",
48169b1fd3fSRichard Lowe interface) < 0) {
48269b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldefs,
48369b1fd3fSRichard Lowe strerror(errno));
48469b1fd3fSRichard Lowe return (1);
48569b1fd3fSRichard Lowe }
48669b1fd3fSRichard Lowe }
48769b1fd3fSRichard Lowe
48869b1fd3fSRichard Lowe if (fprintf(fddefs,
48969b1fd3fSRichard Lowe "#define MSG_ORIG_STRTAB(_x, _s)\t_x\n"
49069b1fd3fSRichard Lowe "#define MSG_ORIG(x)\tx\n#define MSG_INTL(x)\tx\n") < 0) {
49169b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
49269b1fd3fSRichard Lowe return (1);
49369b1fd3fSRichard Lowe }
49469b1fd3fSRichard Lowe
49569b1fd3fSRichard Lowe /*
49669b1fd3fSRichard Lowe * Provide a way to get the array and function declarations above
49769b1fd3fSRichard Lowe * without also getting the actual messages. This is useful in
49869b1fd3fSRichard Lowe * our lintsup.c files that include more than one message header.
49969b1fd3fSRichard Lowe * lintsup doesn't need the actual messages, and this prevents
50069b1fd3fSRichard Lowe * macro name collisions.
50169b1fd3fSRichard Lowe */
50269b1fd3fSRichard Lowe if (fprintf(fddefs, "\n#ifndef LINTSUP_SUPPRESS_STRINGS\n") < 0) {
50369b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
50469b1fd3fSRichard Lowe return (1);
50569b1fd3fSRichard Lowe }
50669b1fd3fSRichard Lowe
50769b1fd3fSRichard Lowe /*
50869b1fd3fSRichard Lowe * Copy the temporary lint defs file into the new header.
50969b1fd3fSRichard Lowe */
51069b1fd3fSRichard Lowe if (fdlint) {
51169b1fd3fSRichard Lowe long size;
51269b1fd3fSRichard Lowe char *buf;
51369b1fd3fSRichard Lowe
51469b1fd3fSRichard Lowe size = ftell(fdlint);
51569b1fd3fSRichard Lowe (void) rewind(fdlint);
51669b1fd3fSRichard Lowe
51769b1fd3fSRichard Lowe if ((buf = malloc(size)) == 0) {
51869b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_nmem, strerror(errno));
51969b1fd3fSRichard Lowe return (1);
52069b1fd3fSRichard Lowe }
52169b1fd3fSRichard Lowe if (fread(buf, size, 1, fdlint) == 0) {
52269b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_read, fllint,
52369b1fd3fSRichard Lowe strerror(errno));
52469b1fd3fSRichard Lowe return (1);
52569b1fd3fSRichard Lowe }
52669b1fd3fSRichard Lowe if (fwrite(buf, size, 1, fddefs) == 0) {
52769b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldefs,
52869b1fd3fSRichard Lowe strerror(errno));
52969b1fd3fSRichard Lowe return (1);
53069b1fd3fSRichard Lowe }
53169b1fd3fSRichard Lowe (void) free(buf);
53269b1fd3fSRichard Lowe }
53369b1fd3fSRichard Lowe
53469b1fd3fSRichard Lowe if (fprintf(fddefs, "\n#endif\t/* LINTSUP_SUPPRESS_STRINGS */\n") < 0) {
53569b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
53669b1fd3fSRichard Lowe return (1);
53769b1fd3fSRichard Lowe }
53869b1fd3fSRichard Lowe
53969b1fd3fSRichard Lowe if (fprintf(fddefs, "\n#endif\t/* __lint */\n") < 0) {
54069b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
54169b1fd3fSRichard Lowe return (1);
54269b1fd3fSRichard Lowe }
54369b1fd3fSRichard Lowe
54469b1fd3fSRichard Lowe if (fprintf(fddefs, "\n#endif\n") < 0) {
54569b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
54669b1fd3fSRichard Lowe return (1);
54769b1fd3fSRichard Lowe }
54869b1fd3fSRichard Lowe
54969b1fd3fSRichard Lowe return (0);
55069b1fd3fSRichard Lowe }
55169b1fd3fSRichard Lowe
55269b1fd3fSRichard Lowe /*
55369b1fd3fSRichard Lowe * The entire messaging file has been scanned - and all strings have been
55469b1fd3fSRichard Lowe * inserted into the string_table. We can now walk the message queue
55569b1fd3fSRichard Lowe * and create the '#define <DEFN>' for each string - with the strings
55669b1fd3fSRichard Lowe * assigned offset into the string_table.
55769b1fd3fSRichard Lowe */
55869b1fd3fSRichard Lowe static int
output_defs(void)55969b1fd3fSRichard Lowe output_defs(void)
56069b1fd3fSRichard Lowe {
56169b1fd3fSRichard Lowe msg_string *msg;
56269b1fd3fSRichard Lowe size_t stbufsize;
56369b1fd3fSRichard Lowe char *stbuf;
56469b1fd3fSRichard Lowe
56569b1fd3fSRichard Lowe stbufsize = st_getstrtab_sz(stp);
56669b1fd3fSRichard Lowe if ((stbuf = malloc(stbufsize)) == 0) {
56769b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_nmem, strerror(errno));
56869b1fd3fSRichard Lowe exit(1);
56969b1fd3fSRichard Lowe }
57069b1fd3fSRichard Lowe (void) st_setstrbuf(stp, stbuf, stbufsize);
57169b1fd3fSRichard Lowe for (msg = msg_head; msg; msg = msg->ms_next) {
57269b1fd3fSRichard Lowe size_t stoff;
57369b1fd3fSRichard Lowe if ((st_setstring(stp, msg->ms_message, &stoff)) == -1) {
57469b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_mnfn, msg->ms_message);
57569b1fd3fSRichard Lowe return (1);
57669b1fd3fSRichard Lowe }
57769b1fd3fSRichard Lowe if (fprintf(fddefs, "\n#define\t%s\t%ld\n",
57869b1fd3fSRichard Lowe msg->ms_defn, stoff) < 0) {
57969b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte,
58069b1fd3fSRichard Lowe fldefs, strerror(errno));
58169b1fd3fSRichard Lowe return (1);
58269b1fd3fSRichard Lowe }
58369b1fd3fSRichard Lowe if (fddefs && fprintf(fddefs, "#define\t%s_SIZE\t%d\n",
58469b1fd3fSRichard Lowe msg->ms_defn, strlen(msg->ms_message)) < 0) {
58569b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte,
58669b1fd3fSRichard Lowe fldefs, strerror(errno));
58769b1fd3fSRichard Lowe return (1);
58869b1fd3fSRichard Lowe }
58969b1fd3fSRichard Lowe }
59069b1fd3fSRichard Lowe return (0);
59169b1fd3fSRichard Lowe }
59269b1fd3fSRichard Lowe
59369b1fd3fSRichard Lowe
59469b1fd3fSRichard Lowe /*
59569b1fd3fSRichard Lowe * Finish off the data structure definition.
59669b1fd3fSRichard Lowe */
59769b1fd3fSRichard Lowe static int
output_data(void)59869b1fd3fSRichard Lowe output_data(void)
59969b1fd3fSRichard Lowe {
60069b1fd3fSRichard Lowe size_t stbufsize;
60169b1fd3fSRichard Lowe size_t ndx;
60269b1fd3fSRichard Lowe size_t column = 1;
60369b1fd3fSRichard Lowe const char *stbuf;
60469b1fd3fSRichard Lowe const char *fmtstr;
60569b1fd3fSRichard Lowe
60669b1fd3fSRichard Lowe stbufsize = st_getstrtab_sz(stp);
60769b1fd3fSRichard Lowe stbuf = st_getstrbuf(stp);
60869b1fd3fSRichard Lowe
60969b1fd3fSRichard Lowe assert(stbuf);
61069b1fd3fSRichard Lowe
61169b1fd3fSRichard Lowe /*
61269b1fd3fSRichard Lowe * Determine from the local flag whether the data declaration should
61369b1fd3fSRichard Lowe * be static.
61469b1fd3fSRichard Lowe */
61569b1fd3fSRichard Lowe if (lflag)
61669b1fd3fSRichard Lowe fmtstr = (const char *)"static const";
61769b1fd3fSRichard Lowe else
61869b1fd3fSRichard Lowe fmtstr = (const char *)"const";
61969b1fd3fSRichard Lowe
62069b1fd3fSRichard Lowe if (fprintf(fddata, "\n%s char __%s[%ld] __attribute__((unused)) = { ",
62169b1fd3fSRichard Lowe fmtstr, interface, stbufsize) < 0) {
62269b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldata, strerror(errno));
62369b1fd3fSRichard Lowe return (1);
62469b1fd3fSRichard Lowe }
62569b1fd3fSRichard Lowe
62669b1fd3fSRichard Lowe for (ndx = 0; ndx < (stbufsize - 1); ndx++) {
62769b1fd3fSRichard Lowe if (column == 1) {
62869b1fd3fSRichard Lowe if (fddata && fprintf(fddata,
62969b1fd3fSRichard Lowe "\n/* %4ld */ 0x%.2x,", ndx,
63069b1fd3fSRichard Lowe (unsigned char)stbuf[ndx]) < 0) {
63169b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte,
63269b1fd3fSRichard Lowe fldata, strerror(errno));
63369b1fd3fSRichard Lowe return (1);
63469b1fd3fSRichard Lowe }
63569b1fd3fSRichard Lowe } else {
63669b1fd3fSRichard Lowe if (fddata && fprintf(fddata, " 0x%.2x,",
63769b1fd3fSRichard Lowe (unsigned char)stbuf[ndx]) < 0) {
63869b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte,
63969b1fd3fSRichard Lowe fldata, strerror(errno));
64069b1fd3fSRichard Lowe return (1);
64169b1fd3fSRichard Lowe }
64269b1fd3fSRichard Lowe }
64369b1fd3fSRichard Lowe
64469b1fd3fSRichard Lowe if (column++ == 10)
64569b1fd3fSRichard Lowe column = 1;
64669b1fd3fSRichard Lowe }
64769b1fd3fSRichard Lowe
64869b1fd3fSRichard Lowe if (column == 1)
64969b1fd3fSRichard Lowe fmtstr = "\n\t0x%.2x };\n";
65069b1fd3fSRichard Lowe else
65169b1fd3fSRichard Lowe fmtstr = " 0x%.2x };\n";
65269b1fd3fSRichard Lowe
65369b1fd3fSRichard Lowe if (fprintf(fddata, fmtstr, (unsigned char)stbuf[stbufsize - 1]) < 0) {
65469b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, fldata, strerror(errno));
65569b1fd3fSRichard Lowe return (1);
65669b1fd3fSRichard Lowe }
65769b1fd3fSRichard Lowe
65869b1fd3fSRichard Lowe return (0);
65969b1fd3fSRichard Lowe }
66069b1fd3fSRichard Lowe
66169b1fd3fSRichard Lowe static int
file()66269b1fd3fSRichard Lowe file()
66369b1fd3fSRichard Lowe {
66469b1fd3fSRichard Lowe char buffer[LINE_MAX], * token;
66569b1fd3fSRichard Lowe uint_t bufsize;
66669b1fd3fSRichard Lowe char *token_buffer;
66769b1fd3fSRichard Lowe int escape = 0;
66869b1fd3fSRichard Lowe int len = 0;
66969b1fd3fSRichard Lowe
67069b1fd3fSRichard Lowe if ((token_buffer = malloc(LINE_MAX)) == 0) {
67169b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_nmem, strerror(errno));
67269b1fd3fSRichard Lowe return (1);
67369b1fd3fSRichard Lowe }
67469b1fd3fSRichard Lowe bufsize = LINE_MAX;
67569b1fd3fSRichard Lowe
67669b1fd3fSRichard Lowe line = 1;
67769b1fd3fSRichard Lowe
67869b1fd3fSRichard Lowe while ((token = fgets(buffer, LINE_MAX, fddesc)) != NULL) {
67969b1fd3fSRichard Lowe char defn[PATH_MAX], * _defn, * str;
68069b1fd3fSRichard Lowe
68169b1fd3fSRichard Lowe switch (*token) {
68269b1fd3fSRichard Lowe case '#':
68369b1fd3fSRichard Lowe case '$':
68469b1fd3fSRichard Lowe if (escape) {
68569b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_malt, fldesc,
68669b1fd3fSRichard Lowe line);
68769b1fd3fSRichard Lowe return (1);
68869b1fd3fSRichard Lowe }
68969b1fd3fSRichard Lowe
69069b1fd3fSRichard Lowe /*
69169b1fd3fSRichard Lowe * If a msgid has been output a msgstr must follow
69269b1fd3fSRichard Lowe * before we digest the new token. A msgid is only set
69369b1fd3fSRichard Lowe * if fdmsgs is in use.
69469b1fd3fSRichard Lowe */
69569b1fd3fSRichard Lowe if (msgid) {
69669b1fd3fSRichard Lowe msgid = 0;
69769b1fd3fSRichard Lowe if (fprintf(fdmsgs, "msgstr\t\"\"\n") < 0) {
69869b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte,
69969b1fd3fSRichard Lowe flmsgs, strerror(errno));
70069b1fd3fSRichard Lowe return (1);
70169b1fd3fSRichard Lowe }
70269b1fd3fSRichard Lowe }
70369b1fd3fSRichard Lowe
70469b1fd3fSRichard Lowe /*
70569b1fd3fSRichard Lowe * Pass lines directly through to the output message
70669b1fd3fSRichard Lowe * file.
70769b1fd3fSRichard Lowe */
70869b1fd3fSRichard Lowe if (fdmsgs && (prtmsgs == 1)) {
70969b1fd3fSRichard Lowe char comment;
71069b1fd3fSRichard Lowe
71169b1fd3fSRichard Lowe if (cflag == 0)
71269b1fd3fSRichard Lowe comment = '#';
71369b1fd3fSRichard Lowe else
71469b1fd3fSRichard Lowe comment = '$';
71569b1fd3fSRichard Lowe
71669b1fd3fSRichard Lowe if (fprintf(fdmsgs, "%c%s", comment,
71769b1fd3fSRichard Lowe ++token) < 0) {
71869b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte,
71969b1fd3fSRichard Lowe flmsgs, strerror(errno));
72069b1fd3fSRichard Lowe return (1);
72169b1fd3fSRichard Lowe }
72269b1fd3fSRichard Lowe }
72369b1fd3fSRichard Lowe break;
72469b1fd3fSRichard Lowe
72569b1fd3fSRichard Lowe case '@':
72669b1fd3fSRichard Lowe if (escape) {
72769b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_malt, fldesc,
72869b1fd3fSRichard Lowe line);
72969b1fd3fSRichard Lowe return (1);
73069b1fd3fSRichard Lowe }
73169b1fd3fSRichard Lowe
73269b1fd3fSRichard Lowe /*
73369b1fd3fSRichard Lowe * If a msgid has been output a msgstr must follow
73469b1fd3fSRichard Lowe * before we digest the new token.
73569b1fd3fSRichard Lowe */
73669b1fd3fSRichard Lowe if (msgid) {
73769b1fd3fSRichard Lowe msgid = 0;
73869b1fd3fSRichard Lowe if (fprintf(fdmsgs, "msgstr\t\"\"\n") < 0) {
73969b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte,
74069b1fd3fSRichard Lowe flmsgs, strerror(errno));
74169b1fd3fSRichard Lowe return (1);
74269b1fd3fSRichard Lowe }
74369b1fd3fSRichard Lowe }
74469b1fd3fSRichard Lowe
74569b1fd3fSRichard Lowe /*
74669b1fd3fSRichard Lowe * Determine whether we have one or more tokens.
74769b1fd3fSRichard Lowe */
74869b1fd3fSRichard Lowe token++;
74969b1fd3fSRichard Lowe while (isspace(*token)) /* rid any whitespace */
75069b1fd3fSRichard Lowe token++;
75169b1fd3fSRichard Lowe _defn = token; /* definition start */
75269b1fd3fSRichard Lowe while (!(isspace(*token)))
75369b1fd3fSRichard Lowe token++;
75469b1fd3fSRichard Lowe *token++ = 0;
75569b1fd3fSRichard Lowe
75669b1fd3fSRichard Lowe while (isspace(*token)) /* rid any whitespace */
75769b1fd3fSRichard Lowe token++;
75869b1fd3fSRichard Lowe
75969b1fd3fSRichard Lowe /*
76069b1fd3fSRichard Lowe * Determine whether the single token is one of the
76169b1fd3fSRichard Lowe * reserved message output delimiters otherwise
76269b1fd3fSRichard Lowe * translate it as a message identifier.
76369b1fd3fSRichard Lowe */
76469b1fd3fSRichard Lowe if (*token == 0) {
76569b1fd3fSRichard Lowe if (strcmp(_defn, start) == 0)
76669b1fd3fSRichard Lowe prtmsgs = 1;
76769b1fd3fSRichard Lowe else if (strcmp(_defn, end) == 0)
76869b1fd3fSRichard Lowe prtmsgs = -1;
76969b1fd3fSRichard Lowe else if (getmesgid(_defn) == 1)
77069b1fd3fSRichard Lowe return (1);
77169b1fd3fSRichard Lowe break;
77269b1fd3fSRichard Lowe }
77369b1fd3fSRichard Lowe
77469b1fd3fSRichard Lowe /*
77569b1fd3fSRichard Lowe * Multiple tokens are translated by taking the first
77669b1fd3fSRichard Lowe * token as the message definition, and the rest of the
77769b1fd3fSRichard Lowe * line as the message itself. A message line ending
77869b1fd3fSRichard Lowe * with an escape ('\') is expected to be continued on
77969b1fd3fSRichard Lowe * the next line.
78069b1fd3fSRichard Lowe */
78169b1fd3fSRichard Lowe if (prtmsgs != -1)
78269b1fd3fSRichard Lowe prtmsgs = 1;
78369b1fd3fSRichard Lowe if (fdmsgs && (prtmsgs == 1)) {
78469b1fd3fSRichard Lowe /*
78569b1fd3fSRichard Lowe * For catgets(3c) make sure a message
78669b1fd3fSRichard Lowe * identifier has been established (this is
787*4b9db4f6SChris Fraire * normally a domain for gettext(3C), but for
78869b1fd3fSRichard Lowe * sgsmsg use this could be argued as being
78969b1fd3fSRichard Lowe * redundent). Also make sure that the message
79069b1fd3fSRichard Lowe * definitions haven't exceeeded the maximum
79169b1fd3fSRichard Lowe * value allowed by gencat(1) before generating
79269b1fd3fSRichard Lowe * any message file entries.
79369b1fd3fSRichard Lowe */
79469b1fd3fSRichard Lowe if (cflag == 1) {
79569b1fd3fSRichard Lowe if (setid == 0) {
79669b1fd3fSRichard Lowe (void) fprintf(stderr, "file "
79769b1fd3fSRichard Lowe "%s: no message identifier "
79869b1fd3fSRichard Lowe "has been established\n",
79969b1fd3fSRichard Lowe fldesc);
80069b1fd3fSRichard Lowe return (1);
80169b1fd3fSRichard Lowe }
80269b1fd3fSRichard Lowe if (ptr > NL_MSGMAX) {
80369b1fd3fSRichard Lowe (void) fprintf(stderr, "file "
80469b1fd3fSRichard Lowe "%s: message definition "
80569b1fd3fSRichard Lowe "(%d) exceeds allowable "
80669b1fd3fSRichard Lowe "limit (NL_MSGMAX)\n",
80769b1fd3fSRichard Lowe fldesc, ptr);
80869b1fd3fSRichard Lowe return (1);
80969b1fd3fSRichard Lowe }
81069b1fd3fSRichard Lowe }
81169b1fd3fSRichard Lowe
81269b1fd3fSRichard Lowe /*
81369b1fd3fSRichard Lowe * For catgets(3c) write the definition and the
81469b1fd3fSRichard Lowe * message string to the message file. For
815*4b9db4f6SChris Fraire * gettext(3C) write the message string as a
81669b1fd3fSRichard Lowe * mesgid - indicate a mesgid has been output
81769b1fd3fSRichard Lowe * so that a msgstr can follow.
81869b1fd3fSRichard Lowe */
81969b1fd3fSRichard Lowe if (cflag == 1) {
82069b1fd3fSRichard Lowe if (fprintf(fdmsgs, "%d\t%s", ptr,
82169b1fd3fSRichard Lowe token) < 0) {
82269b1fd3fSRichard Lowe (void) fprintf(stderr,
82369b1fd3fSRichard Lowe Errmsg_wrte, flmsgs,
82469b1fd3fSRichard Lowe strerror(errno));
82569b1fd3fSRichard Lowe return (1);
82669b1fd3fSRichard Lowe }
82769b1fd3fSRichard Lowe } else {
82869b1fd3fSRichard Lowe if (fprintf(fdmsgs, "msgid\t\"") < 0) {
82969b1fd3fSRichard Lowe (void) fprintf(stderr,
83069b1fd3fSRichard Lowe Errmsg_wrte, flmsgs,
83169b1fd3fSRichard Lowe strerror(errno));
83269b1fd3fSRichard Lowe return (1);
83369b1fd3fSRichard Lowe }
83469b1fd3fSRichard Lowe msgid = 1;
83569b1fd3fSRichard Lowe }
83669b1fd3fSRichard Lowe }
83769b1fd3fSRichard Lowe
83869b1fd3fSRichard Lowe /*
83969b1fd3fSRichard Lowe * The message itself is a quoted string as this makes
84069b1fd3fSRichard Lowe * embedding spaces at the start (or the end) of the
84169b1fd3fSRichard Lowe * string very easy.
84269b1fd3fSRichard Lowe */
84369b1fd3fSRichard Lowe if (*token != '"') {
84469b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_malt, fldesc,
84569b1fd3fSRichard Lowe line);
84669b1fd3fSRichard Lowe return (1);
84769b1fd3fSRichard Lowe }
84869b1fd3fSRichard Lowe
84969b1fd3fSRichard Lowe (void) strcpy(defn, _defn);
85069b1fd3fSRichard Lowe
85169b1fd3fSRichard Lowe /*
85269b1fd3fSRichard Lowe * Write the tag to the lint definitions.
85369b1fd3fSRichard Lowe */
85469b1fd3fSRichard Lowe if (fdlint) {
85569b1fd3fSRichard Lowe if (fprintf(fdlint, "\n#define\t%s\t",
85669b1fd3fSRichard Lowe _defn) < 0) {
85769b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte,
85869b1fd3fSRichard Lowe fllint, strerror(errno));
85969b1fd3fSRichard Lowe return (1);
86069b1fd3fSRichard Lowe }
86169b1fd3fSRichard Lowe }
86269b1fd3fSRichard Lowe
86369b1fd3fSRichard Lowe len = 0;
86469b1fd3fSRichard Lowe
86569b1fd3fSRichard Lowe /*
86669b1fd3fSRichard Lowe * Write each character of the message string to the
86769b1fd3fSRichard Lowe * data array. Translate any escaped characters - use
86869b1fd3fSRichard Lowe * the same specially recognized characters as defined
86969b1fd3fSRichard Lowe * by gencat(1).
87069b1fd3fSRichard Lowe */
87169b1fd3fSRichard Lowe message:
87269b1fd3fSRichard Lowe if (*token == '"') {
87369b1fd3fSRichard Lowe if (fdlint &&
87469b1fd3fSRichard Lowe (fprintf(fdlint, "%c", *token) < 0)) {
87569b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte,
87669b1fd3fSRichard Lowe fllint, strerror(errno));
87769b1fd3fSRichard Lowe return (1);
87869b1fd3fSRichard Lowe }
87969b1fd3fSRichard Lowe token++;
88069b1fd3fSRichard Lowe }
88169b1fd3fSRichard Lowe while (*token) {
88269b1fd3fSRichard Lowe char _token;
88369b1fd3fSRichard Lowe
88469b1fd3fSRichard Lowe if ((*token == '\\') && (escape == 0)) {
88569b1fd3fSRichard Lowe escape = 1;
88669b1fd3fSRichard Lowe if (fdlint && (*(token + 1) != '\n') &&
88769b1fd3fSRichard Lowe fprintf(fdlint, "%c", *token) < 0) {
88869b1fd3fSRichard Lowe (void) fprintf(stderr,
88969b1fd3fSRichard Lowe Errmsg_wrte, fllint,
89069b1fd3fSRichard Lowe strerror(errno));
89169b1fd3fSRichard Lowe return (1);
89269b1fd3fSRichard Lowe }
89369b1fd3fSRichard Lowe token++;
89469b1fd3fSRichard Lowe continue;
89569b1fd3fSRichard Lowe }
89669b1fd3fSRichard Lowe if (escape) {
89769b1fd3fSRichard Lowe if (*token == 'n')
89869b1fd3fSRichard Lowe _token = '\n';
89969b1fd3fSRichard Lowe else if (*token == 't')
90069b1fd3fSRichard Lowe _token = '\t';
90169b1fd3fSRichard Lowe else if (*token == 'v')
90269b1fd3fSRichard Lowe _token = '\v';
90369b1fd3fSRichard Lowe else if (*token == 'b')
90469b1fd3fSRichard Lowe _token = '\b';
90569b1fd3fSRichard Lowe else if (*token == 'f')
90669b1fd3fSRichard Lowe _token = '\f';
90769b1fd3fSRichard Lowe else if (*token == '\\')
90869b1fd3fSRichard Lowe _token = '\\';
90969b1fd3fSRichard Lowe else if (*token == '"')
91069b1fd3fSRichard Lowe _token = '"';
91169b1fd3fSRichard Lowe else if (*token == '\n')
91269b1fd3fSRichard Lowe break;
91369b1fd3fSRichard Lowe else
91469b1fd3fSRichard Lowe _token = *token;
91569b1fd3fSRichard Lowe
91669b1fd3fSRichard Lowe if (fdmsgs && (prtmsgs == 1) &&
91769b1fd3fSRichard Lowe (fprintf(fdmsgs, "\\") < 0)) {
91869b1fd3fSRichard Lowe (void) fprintf(stderr,
91969b1fd3fSRichard Lowe Errmsg_wrte, flmsgs,
92069b1fd3fSRichard Lowe strerror(errno));
92169b1fd3fSRichard Lowe return (1);
92269b1fd3fSRichard Lowe }
92369b1fd3fSRichard Lowe } else {
92469b1fd3fSRichard Lowe /*
92569b1fd3fSRichard Lowe * If this is the trailing quote then
92669b1fd3fSRichard Lowe * thats the last of the message string.
92769b1fd3fSRichard Lowe * Eat up any remaining white space and
92869b1fd3fSRichard Lowe * unless an escape character is found
92969b1fd3fSRichard Lowe * terminate the data string with a 0.
93069b1fd3fSRichard Lowe */
93169b1fd3fSRichard Lowe /* BEGIN CSTYLED */
93269b1fd3fSRichard Lowe if (*token == '"') {
93369b1fd3fSRichard Lowe if (fdlint && (fprintf(fdlint,
93469b1fd3fSRichard Lowe "%c", *token) < 0)) {
93569b1fd3fSRichard Lowe (void) fprintf(stderr,
93669b1fd3fSRichard Lowe Errmsg_wrte, fllint,
93769b1fd3fSRichard Lowe strerror(errno));
93869b1fd3fSRichard Lowe return (1);
93969b1fd3fSRichard Lowe }
94069b1fd3fSRichard Lowe
94169b1fd3fSRichard Lowe if (fdmsgs && (prtmsgs == 1) &&
94269b1fd3fSRichard Lowe (fprintf(fdmsgs, "%c",
94369b1fd3fSRichard Lowe *token) < 0)) {
94469b1fd3fSRichard Lowe (void) fprintf(stderr,
94569b1fd3fSRichard Lowe Errmsg_wrte, flmsgs,
94669b1fd3fSRichard Lowe strerror(errno));
94769b1fd3fSRichard Lowe return (1);
94869b1fd3fSRichard Lowe }
94969b1fd3fSRichard Lowe
95069b1fd3fSRichard Lowe while (*++token) {
95169b1fd3fSRichard Lowe if (*token == '\n')
95269b1fd3fSRichard Lowe break;
95369b1fd3fSRichard Lowe }
95469b1fd3fSRichard Lowe _token = '\0';
95569b1fd3fSRichard Lowe } else
95669b1fd3fSRichard Lowe _token = *token;
95769b1fd3fSRichard Lowe /* END CSTYLED */
95869b1fd3fSRichard Lowe }
95969b1fd3fSRichard Lowe
96069b1fd3fSRichard Lowe if (fdmsgs && (prtmsgs == 1) &&
96169b1fd3fSRichard Lowe (fprintf(fdmsgs, "%c", *token) < 0)) {
96269b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte,
96369b1fd3fSRichard Lowe flmsgs, strerror(errno));
96469b1fd3fSRichard Lowe return (1);
96569b1fd3fSRichard Lowe }
96669b1fd3fSRichard Lowe
96769b1fd3fSRichard Lowe if (fdlint && fprintf(fdlint,
96869b1fd3fSRichard Lowe "%c", *token) < 0) {
96969b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte,
97069b1fd3fSRichard Lowe fllint, strerror(errno));
97169b1fd3fSRichard Lowe return (1);
97269b1fd3fSRichard Lowe }
97369b1fd3fSRichard Lowe
97469b1fd3fSRichard Lowe if (len >= bufsize) {
97569b1fd3fSRichard Lowe bufsize += LINE_MAX;
97669b1fd3fSRichard Lowe if ((token_buffer = realloc(
97769b1fd3fSRichard Lowe token_buffer, bufsize)) == 0) {
97869b1fd3fSRichard Lowe (void) fprintf(stderr,
97969b1fd3fSRichard Lowe Errmsg_nmem,
98069b1fd3fSRichard Lowe strerror(errno));
98169b1fd3fSRichard Lowe return (1);
98269b1fd3fSRichard Lowe }
98369b1fd3fSRichard Lowe }
98469b1fd3fSRichard Lowe token_buffer[len] = _token;
98569b1fd3fSRichard Lowe ptr++, token++, len++;
98669b1fd3fSRichard Lowe escape = 0;
98769b1fd3fSRichard Lowe
98869b1fd3fSRichard Lowe if (_token == '\0')
98969b1fd3fSRichard Lowe break;
99069b1fd3fSRichard Lowe }
99169b1fd3fSRichard Lowe
99269b1fd3fSRichard Lowe /*
99369b1fd3fSRichard Lowe * After the complete message string has been processed
99469b1fd3fSRichard Lowe * (including its continuation beyond one line), create
99569b1fd3fSRichard Lowe * a string size definition.
99669b1fd3fSRichard Lowe */
99769b1fd3fSRichard Lowe if (escape == 0) {
99869b1fd3fSRichard Lowe const char *form = "#define\t%s_SIZE\t%d\n";
99969b1fd3fSRichard Lowe
100069b1fd3fSRichard Lowe token_buffer[len] = '\0';
100169b1fd3fSRichard Lowe
100269b1fd3fSRichard Lowe message_append(defn, token_buffer);
100369b1fd3fSRichard Lowe
100469b1fd3fSRichard Lowe if (fdlint && fprintf(fdlint, form, defn,
100569b1fd3fSRichard Lowe (len - 1)) < 0) {
100669b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte,
100769b1fd3fSRichard Lowe fllint, strerror(errno));
100869b1fd3fSRichard Lowe return (1);
100969b1fd3fSRichard Lowe }
101069b1fd3fSRichard Lowe }
101169b1fd3fSRichard Lowe break;
101269b1fd3fSRichard Lowe
101369b1fd3fSRichard Lowe default:
101469b1fd3fSRichard Lowe /*
101569b1fd3fSRichard Lowe * Empty lines are passed through to the message file.
101669b1fd3fSRichard Lowe */
101769b1fd3fSRichard Lowe while (isspace(*token))
101869b1fd3fSRichard Lowe token++;
101969b1fd3fSRichard Lowe
102069b1fd3fSRichard Lowe if (*token == 0) {
102169b1fd3fSRichard Lowe if (msgid || (fdmsgs && (prtmsgs == 1))) {
102269b1fd3fSRichard Lowe /*
102369b1fd3fSRichard Lowe * If a msgid has been output a msgstr
102469b1fd3fSRichard Lowe * must follow before we digest the new
102569b1fd3fSRichard Lowe * token.
102669b1fd3fSRichard Lowe */
102769b1fd3fSRichard Lowe if (msgid) {
102869b1fd3fSRichard Lowe msgid = 0;
102969b1fd3fSRichard Lowe str = "msgstr\t\"\"\n\n";
103069b1fd3fSRichard Lowe } else
103169b1fd3fSRichard Lowe str = "\n";
103269b1fd3fSRichard Lowe
103369b1fd3fSRichard Lowe if (fprintf(fdmsgs, str) < 0) {
103469b1fd3fSRichard Lowe (void) fprintf(stderr,
103569b1fd3fSRichard Lowe Errmsg_wrte, flmsgs,
103669b1fd3fSRichard Lowe strerror(errno));
103769b1fd3fSRichard Lowe return (1);
103869b1fd3fSRichard Lowe }
103969b1fd3fSRichard Lowe }
104069b1fd3fSRichard Lowe break;
104169b1fd3fSRichard Lowe }
104269b1fd3fSRichard Lowe
104369b1fd3fSRichard Lowe /*
104469b1fd3fSRichard Lowe * If an escape is in effect then any tokens are taken
104569b1fd3fSRichard Lowe * to be message continuations.
104669b1fd3fSRichard Lowe */
104769b1fd3fSRichard Lowe if (escape) {
104869b1fd3fSRichard Lowe escape = 0;
104969b1fd3fSRichard Lowe goto message;
105069b1fd3fSRichard Lowe }
105169b1fd3fSRichard Lowe
105269b1fd3fSRichard Lowe (void) fprintf(stderr, "file %s: line %d: invalid "
105369b1fd3fSRichard Lowe "input does not start with #, $ or @\n", fldesc,
105469b1fd3fSRichard Lowe line);
105569b1fd3fSRichard Lowe return (1);
105669b1fd3fSRichard Lowe }
105769b1fd3fSRichard Lowe line++;
105869b1fd3fSRichard Lowe }
105969b1fd3fSRichard Lowe
106069b1fd3fSRichard Lowe free(token_buffer);
106169b1fd3fSRichard Lowe
106269b1fd3fSRichard Lowe return (0);
106369b1fd3fSRichard Lowe }
106469b1fd3fSRichard Lowe
106569b1fd3fSRichard Lowe int
main(int argc,char ** argv)106669b1fd3fSRichard Lowe main(int argc, char ** argv)
106769b1fd3fSRichard Lowe {
106869b1fd3fSRichard Lowe opterr = 0;
106969b1fd3fSRichard Lowe while ((line = getopt(argc, argv, "cd:h:lm:n:i:v")) != EOF) {
107069b1fd3fSRichard Lowe switch (line) {
107169b1fd3fSRichard Lowe case 'c': /* catgets instead of gettext */
107269b1fd3fSRichard Lowe cflag = 1;
107369b1fd3fSRichard Lowe break;
107469b1fd3fSRichard Lowe case 'd': /* new message data filename */
107569b1fd3fSRichard Lowe fldata = optarg; /* (msg.c is default) */
107669b1fd3fSRichard Lowe break;
107769b1fd3fSRichard Lowe case 'h': /* new message defs filename */
107869b1fd3fSRichard Lowe fldefs = optarg; /* (msg.h is default) */
107969b1fd3fSRichard Lowe break;
108069b1fd3fSRichard Lowe case 'i': /* input message ids from */
108169b1fd3fSRichard Lowe flmids = optarg; /* from this file */
108269b1fd3fSRichard Lowe break;
108369b1fd3fSRichard Lowe case 'l': /* define message data arrays */
108469b1fd3fSRichard Lowe lflag = 1; /* to be local (static) */
108569b1fd3fSRichard Lowe break;
108669b1fd3fSRichard Lowe case 'm': /* generate message database */
108769b1fd3fSRichard Lowe flmsgs = optarg; /* to this file */
108869b1fd3fSRichard Lowe break;
108969b1fd3fSRichard Lowe case 'n': /* new data array and func */
109069b1fd3fSRichard Lowe interface = optarg; /* name (msg is default) */
109169b1fd3fSRichard Lowe break;
109269b1fd3fSRichard Lowe case 'v':
109369b1fd3fSRichard Lowe vflag = 1; /* set verbose flag */
109469b1fd3fSRichard Lowe break;
109569b1fd3fSRichard Lowe case '?':
109669b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_use, argv[0]);
109769b1fd3fSRichard Lowe exit(1);
109869b1fd3fSRichard Lowe default:
109969b1fd3fSRichard Lowe break;
110069b1fd3fSRichard Lowe }
110169b1fd3fSRichard Lowe }
110269b1fd3fSRichard Lowe
110369b1fd3fSRichard Lowe /*
110469b1fd3fSRichard Lowe * Validate the we have been given at least one input file.
110569b1fd3fSRichard Lowe */
110669b1fd3fSRichard Lowe if ((argc - optind) < 1) {
110769b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_use);
110869b1fd3fSRichard Lowe exit(1);
110969b1fd3fSRichard Lowe }
111069b1fd3fSRichard Lowe
111169b1fd3fSRichard Lowe /*
111269b1fd3fSRichard Lowe * Open all the required output files.
111369b1fd3fSRichard Lowe */
111469b1fd3fSRichard Lowe if (fldefs) {
111569b1fd3fSRichard Lowe if ((fddefs = fopen(fldefs, "w+")) == NULL) {
111669b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_opne, fldefs,
111769b1fd3fSRichard Lowe strerror(errno));
111869b1fd3fSRichard Lowe return (1);
111969b1fd3fSRichard Lowe }
112069b1fd3fSRichard Lowe }
112169b1fd3fSRichard Lowe if (fldata) {
112269b1fd3fSRichard Lowe if (fldefs && (strcmp(fldefs, fldata) == 0))
112369b1fd3fSRichard Lowe fddata = fddefs;
112469b1fd3fSRichard Lowe else if ((fddata = fopen(fldata, "w+")) == NULL) {
112569b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_opne, fldata,
112669b1fd3fSRichard Lowe strerror(errno));
112769b1fd3fSRichard Lowe return (1);
112869b1fd3fSRichard Lowe }
112969b1fd3fSRichard Lowe }
113069b1fd3fSRichard Lowe if (fddefs && fddata) {
113169b1fd3fSRichard Lowe (void) sprintf(fllint, "%s.%d.XXXXXX", nmlint, (int)getpid());
113269b1fd3fSRichard Lowe if ((mkstemp(fllint) == -1) ||
113369b1fd3fSRichard Lowe ((fdlint = fopen(fllint, "w+")) == NULL)) {
113469b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_opne, fllint,
113569b1fd3fSRichard Lowe strerror(errno));
113669b1fd3fSRichard Lowe return (1);
113769b1fd3fSRichard Lowe }
113869b1fd3fSRichard Lowe }
113969b1fd3fSRichard Lowe if (flmsgs) {
114069b1fd3fSRichard Lowe if ((fdmsgs = fopen(flmsgs, "w+")) == NULL) {
114169b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_opne, flmsgs,
114269b1fd3fSRichard Lowe strerror(errno));
114369b1fd3fSRichard Lowe return (1);
114469b1fd3fSRichard Lowe }
114569b1fd3fSRichard Lowe }
114669b1fd3fSRichard Lowe if (flmids) {
114769b1fd3fSRichard Lowe if ((fdmids = fopen(flmids, "r")) == NULL) {
114869b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_opne, flmids,
114969b1fd3fSRichard Lowe strerror(errno));
115069b1fd3fSRichard Lowe return (1);
115169b1fd3fSRichard Lowe }
115269b1fd3fSRichard Lowe }
115369b1fd3fSRichard Lowe
115469b1fd3fSRichard Lowe
115569b1fd3fSRichard Lowe /*
115669b1fd3fSRichard Lowe * Initialize the message definition and message data streams.
115769b1fd3fSRichard Lowe */
115869b1fd3fSRichard Lowe if (fddefs) {
115969b1fd3fSRichard Lowe if (init_defs())
116069b1fd3fSRichard Lowe return (1);
116169b1fd3fSRichard Lowe }
116269b1fd3fSRichard Lowe
116369b1fd3fSRichard Lowe /*
116469b1fd3fSRichard Lowe * Read the input message file, and for each line process accordingly.
116569b1fd3fSRichard Lowe */
116669b1fd3fSRichard Lowe for (; optind < argc; optind++) {
116769b1fd3fSRichard Lowe int err;
116869b1fd3fSRichard Lowe
116969b1fd3fSRichard Lowe fldesc = argv[optind];
117069b1fd3fSRichard Lowe
117169b1fd3fSRichard Lowe if ((fddesc = fopen(fldesc, "r")) == NULL) {
117269b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_opne, fldesc,
117369b1fd3fSRichard Lowe strerror(errno));
117469b1fd3fSRichard Lowe return (1);
117569b1fd3fSRichard Lowe }
117669b1fd3fSRichard Lowe err = file();
117769b1fd3fSRichard Lowe (void) fclose(fddesc);
117869b1fd3fSRichard Lowe
117969b1fd3fSRichard Lowe if (err != 0)
118069b1fd3fSRichard Lowe return (1);
118169b1fd3fSRichard Lowe }
118269b1fd3fSRichard Lowe
118369b1fd3fSRichard Lowe /*
118469b1fd3fSRichard Lowe * If a msgid has been output a msgstr must follow before we end the
118569b1fd3fSRichard Lowe * file.
118669b1fd3fSRichard Lowe */
118769b1fd3fSRichard Lowe if (msgid) {
118869b1fd3fSRichard Lowe msgid = 0;
118969b1fd3fSRichard Lowe if (fprintf(fdmsgs, "msgstr\t\"\"\n") < 0) {
119069b1fd3fSRichard Lowe (void) fprintf(stderr, Errmsg_wrte, flmsgs,
119169b1fd3fSRichard Lowe strerror(errno));
119269b1fd3fSRichard Lowe return (1);
119369b1fd3fSRichard Lowe }
119469b1fd3fSRichard Lowe }
119569b1fd3fSRichard Lowe
119669b1fd3fSRichard Lowe if (fdmids)
119769b1fd3fSRichard Lowe (void) fclose(fdmids);
119869b1fd3fSRichard Lowe if (fdmsgs)
119969b1fd3fSRichard Lowe (void) fclose(fdmsgs);
120069b1fd3fSRichard Lowe
120169b1fd3fSRichard Lowe if (fddefs) {
120269b1fd3fSRichard Lowe if (output_defs())
120369b1fd3fSRichard Lowe return (1);
120469b1fd3fSRichard Lowe }
120569b1fd3fSRichard Lowe
120669b1fd3fSRichard Lowe /*
120769b1fd3fSRichard Lowe * Finish off any generated data and header file.
120869b1fd3fSRichard Lowe */
120969b1fd3fSRichard Lowe if (fldata) {
121069b1fd3fSRichard Lowe if (output_data())
121169b1fd3fSRichard Lowe return (1);
121269b1fd3fSRichard Lowe }
121369b1fd3fSRichard Lowe if (fddefs) {
121469b1fd3fSRichard Lowe if (fini_defs())
121569b1fd3fSRichard Lowe return (1);
121669b1fd3fSRichard Lowe }
121769b1fd3fSRichard Lowe
121869b1fd3fSRichard Lowe if (vflag)
121969b1fd3fSRichard Lowe dump_stringtab(stp);
122069b1fd3fSRichard Lowe
122169b1fd3fSRichard Lowe /*
122269b1fd3fSRichard Lowe * Close up everything and go home.
122369b1fd3fSRichard Lowe */
122469b1fd3fSRichard Lowe if (fddata)
122569b1fd3fSRichard Lowe (void) fclose(fddata);
122669b1fd3fSRichard Lowe if (fddefs && (fddefs != fddata))
122769b1fd3fSRichard Lowe (void) fclose(fddefs);
122869b1fd3fSRichard Lowe if (fddefs && fddata) {
122969b1fd3fSRichard Lowe (void) fclose(fdlint);
123069b1fd3fSRichard Lowe (void) unlink(fllint);
123169b1fd3fSRichard Lowe }
123269b1fd3fSRichard Lowe
123369b1fd3fSRichard Lowe if (stp)
123469b1fd3fSRichard Lowe st_destroy(stp);
123569b1fd3fSRichard Lowe
123669b1fd3fSRichard Lowe return (0);
123769b1fd3fSRichard Lowe }
1238