da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* Copyright (c) 2000-2009 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Glenn Fowler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Research
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[-?\n@(#)$Id: msggen (AT&T Research) 2002-03-11 $\n]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+NAME?msggen - generate a machine independent formatted message catalog]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+DESCRIPTION?\bmsggen\b merges the message text source files \amsgfile\a"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" into a machine independent formatted message catalog \acatfile\a."
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" The file \acatfile\a will be created if it does not already exist."
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" If \acatfile\a does exist, its messages will be included in the new"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" \acatfile\a. If set and message numbers collide, the new message"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" text defined in \amsgfile\a will replace the old message text"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" currently contained in \acatfile\a. Non-ASCII characters must be"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" UTF-8 encoded. \biconv\b(1) can be used to convert to/from UTF-8.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[f:format?List the \bprintf\b(3) format signature for each message in"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" \acatfile\a. A format signature is one line containing one character"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" per format specification:]{"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" [c?char]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" [d?double]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" [D?long double]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" [f?float]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" [h?short]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" [j?long long]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" [l?long]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" [p?void*]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" [s?string]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" [t?ptrdiff_t]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" [z?size_t]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" [???unknown]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[l:list?List \acatfile\a in UTF-8 \amsgfile\a form.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[s:set?Convert the \acatfile\a operand to a message set number and"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" print the number on the standard output.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+EXTENDED DESCRIPTION?Message text source files are in \bgencat\b(1)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" format, defined as follows. Note that the fields of a message text"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" source line are separated by a single blank character. Any other"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" blank characters are considered as being part of the subsequent"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" field. The \bNL_*\b constants are defined in one or both of"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" \b<limits.h>\b and \b<nl_types.h>\b.]{"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" [+$ \acomment\a?A line beginning with \b$\b followed by a"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" blank character is treated as a comment.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" [+$delset \an\a \acomment\a?This line deletes message set"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" \an\a from an existing message catalog. \an\a"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" denotes the set number [1, \bNL_SETMAX\b]]. Any"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" text following the set number is treated as a"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" comment.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" [+$quote \ac\a?This line specifies an optional quote"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" character \ac\a, which can be used to surround"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" \amessage-text\a so that trailing spaces or"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" empty messages are visible in a message source"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" line. By default, or if an empty \b$quote\b"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" directive is supplied, no quoting of \amessage-text\a"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" will be recognized.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" [+$set \an\a \acomment\a?This line specifies the set"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" identifier of the following messages until the next"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" \b$set\b or end-of-file appears. \an\a denotes the set"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" identifier, which is defined as a number in the range"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" [1, \bNL_SETMAX\b]]. Set numbers need not be"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" contiguous. Any text following the set identifier is"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" treated as a comment. If no \b$set\b directive is"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" specified in a message text source file, all messages"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" will be located in message set \b1\b.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" [+$translation \aidentification\a \aYYYY-MM-DD\a[,...]]?Append"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" translation info to the message catalog header. Only"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" the newest date for a given \aidentification\a"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" is retained in the catalog. Multiple translation lines"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" are combined into a single \b,\b separated list.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" [+\am\a \amessage-text\a?\am\a denotes the message identifier,"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" which is defined as a number in the range"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" [1, \bNL_MSGMAX\b]]. The message-text is stored in the"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" message catalogue with the set identifier specified by"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" the last \b$set\b directive, and with message"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" identifier \am\a. If the \amessage-text\a is empty,"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" and a blank character field separator is present, an"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" empty string is stored in the message catalogue. If a"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" message source line has a message number, but neither"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" a field separator nor \amessage-text\a, the existing"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" message with that number (if any) is deleted from the"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" catalogue. Message identifiers need not be contiguous."
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" There are no \amessage-text\a length restrictions.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"\ncatfile [ msgfile ]\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+SEE ALSO?\bgencat\b(1), \biconv\b(1), \bmsgcc\b(1), \btranslate\b(1),"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" \bfmtfmt\b(3)]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * append s to the translation list
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; isspace(*s); s++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (d = e = 0, t = s; *t; t++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*t == ',')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (isspace(*t))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(px = newof(0, Xl_t, 1, strlen(s))) || !(px->date = strdup(d)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (s = e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * sfprintf() with ccmaps(from,to)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinccsfprintf(int from, int to, Sfio_t* sp, const char* format, ...)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set and list only need catfile
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstdout, "%d\n", mcindex(catfile, NiL, NiL, NiL));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_SYSTEM|3, "%s: cannot read catalog", catfile);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_SYSTEM|3, "%s: catalog content error", catfile);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "$translation ");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "$quote \"\n");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "$set %d\n", set);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "%d \"", num);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (c = *s++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*INDENT...*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*...UNDENT*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(3, "exactly one message file must be specified");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * open the files and handles
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_SYSTEM|3, "%s: cannot read message file", msgfile);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_SYSTEM|3, "%s: catalog content error", catfile);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * read the message file
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s == '$')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*++s || isspace(*s))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (t = s; *s && !isspace(*s); s++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (isspace(*s))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = *s ? *s : 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (isspace(*s))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e != s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e != s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (isspace(*s++))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s++ != q)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = t = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (c = *s++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == '\\')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == q)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "(%d,%d): characters after quote not expected", set, num);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * fix up the translation record
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (px->date && (!bp || strcoll(bp->date, px->date) < 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * dump the catalog to a local temporary
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * rename if no errors
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(s = pathtemp(NiL, 0, "", error_info.id, NiL)) || !(sp = sfopen(NiL, s, "w")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_SYSTEM|3, "%s: cannot write catalog file", catfile);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_SYSTEM|3, "%s: temporary catalog file write error", s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_SYSTEM|3, "%s: cannot rename from temporary catalog file %s", catfile, s);