msggen.c revision 3f54fd611f536639ec30dd53c48e5ec1897cc7d9
57221209d11b05aa0373cc3892d5df89ba96ebf9Christian Maeder/***********************************************************************
53bd0c89aa4743dc41a6394db5a90717c1ca4517Liam O'Reilly* This software is part of the ast package *
53bd0c89aa4743dc41a6394db5a90717c1ca4517Liam O'Reilly* Copyright (c) 2000-2011 AT&T Intellectual Property *
53bd0c89aa4743dc41a6394db5a90717c1ca4517Liam O'Reilly* and is licensed under the *
98890889ffb2e8f6f722b00e265a211f13b5a861Corneliu-Claudiu Prodescu* Eclipse Public License, Version 1.0 *
53bd0c89aa4743dc41a6394db5a90717c1ca4517Liam O'Reilly* by AT&T Intellectual Property *
53bd0c89aa4743dc41a6394db5a90717c1ca4517Liam O'Reilly* A copy of the License is available at *
53bd0c89aa4743dc41a6394db5a90717c1ca4517Liam O'Reilly* http://www.eclipse.org/org/documents/epl-v10.html *
53bd0c89aa4743dc41a6394db5a90717c1ca4517Liam O'Reilly* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
53bd0c89aa4743dc41a6394db5a90717c1ca4517Liam O'Reilly* Information and Software Systems Research *
53bd0c89aa4743dc41a6394db5a90717c1ca4517Liam O'Reilly* AT&T Research *
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly* Florham Park NJ *
57221209d11b05aa0373cc3892d5df89ba96ebf9Christian Maeder* Glenn Fowler <gsf@research.att.com> *
66bc8d6e69cde43f1ccbeb76104cf7b8038acd6cChristian Maeder***********************************************************************/
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly * Glenn Fowler
56899f6457976a2ee20f6a23f088cb5655b15715Liam O'Reilly * AT&T Research
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reillystatic const char usage[] =
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly"[-?\n@(#)$Id: msggen (AT&T Research) 2002-03-11 $\n]"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder"[+NAME?msggen - generate a machine independent formatted message catalog]"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder"[+DESCRIPTION?\bmsggen\b merges the message text source files \amsgfile\a"
7830e8fa7442fb7452af7ecdba102bc297ae367eChristian Maeder" into a machine independent formatted message catalog \acatfile\a."
f21c7417bdd1c0282025cba0f5cb0ff5bc5c98eeLiam O'Reilly" The file \acatfile\a will be created if it does not already exist."
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" If \acatfile\a does exist, its messages will be included in the new"
d5833d2ee7bafcbf2fdd2bdfd9a728c769b100c7Christian Maeder" \acatfile\a. If set and message numbers collide, the new message"
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly" text defined in \amsgfile\a will replace the old message text"
c0833539c8cf577dd3f2497792fbdd818442744cChristian Maeder" currently contained in \acatfile\a. Non-ASCII characters must be"
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly" UTF-8 encoded. \biconv\b(1) can be used to convert to/from UTF-8.]"
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly"[f:format?List the \bprintf\b(3) format signature for each message in"
7830e8fa7442fb7452af7ecdba102bc297ae367eChristian Maeder" \acatfile\a. A format signature is one line containing one character"
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly" per format specification:]{"
fa373bc327620e08861294716b4454be8d25669fChristian Maeder" [D?long double]"
53bd0c89aa4743dc41a6394db5a90717c1ca4517Liam O'Reilly" [j?long long]"
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly" [t?ptrdiff_t]"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" [???unknown]"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder"[l:list?List \acatfile\a in UTF-8 \amsgfile\a form.]"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder"[s:set?Convert the \acatfile\a operand to a message set number and"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" print the number on the standard output.]"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder"[+EXTENDED DESCRIPTION?Message text source files are in \bgencat\b(1)"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" format, defined as follows. Note that the fields of a message text"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" source line are separated by a single blank character. Any other"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" blank characters are considered as being part of the subsequent"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" field. The \bNL_*\b constants are defined in one or both of"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" \b<limits.h>\b and \b<nl_types.h>\b.]{"
4314e26a12954cb1c9be4dea10aa8103edac5bbbChristian Maeder" [+$ \acomment\a?A line beginning with \b$\b followed by a"
d5833d2ee7bafcbf2fdd2bdfd9a728c769b100c7Christian Maeder" blank character is treated as a comment.]"
d5833d2ee7bafcbf2fdd2bdfd9a728c769b100c7Christian Maeder" [+$delset \an\a \acomment\a?This line deletes message set"
9aeda2b3ae8ce0b018955521e4ca835a8ba8a27bLiam O'Reilly" \an\a from an existing message catalog. \an\a"
9aeda2b3ae8ce0b018955521e4ca835a8ba8a27bLiam O'Reilly" denotes the set number [1, \bNL_SETMAX\b]]. Any"
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly" text following the set number is treated as a"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" [+$quote \ac\a?This line specifies an optional quote"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" character \ac\a, which can be used to surround"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" \amessage-text\a so that trailing spaces or"
d5833d2ee7bafcbf2fdd2bdfd9a728c769b100c7Christian Maeder" empty messages are visible in a message source"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" line. By default, or if an empty \b$quote\b"
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly" directive is supplied, no quoting of \amessage-text\a"
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly" will be recognized.]"
fa373bc327620e08861294716b4454be8d25669fChristian Maeder" [+$set \an\a \acomment\a?This line specifies the set"
fa373bc327620e08861294716b4454be8d25669fChristian Maeder" identifier of the following messages until the next"
fa373bc327620e08861294716b4454be8d25669fChristian Maeder" \b$set\b or end-of-file appears. \an\a denotes the set"
fa373bc327620e08861294716b4454be8d25669fChristian Maeder" identifier, which is defined as a number in the range"
fa373bc327620e08861294716b4454be8d25669fChristian Maeder" [1, \bNL_SETMAX\b]]. Set numbers need not be"
fa373bc327620e08861294716b4454be8d25669fChristian Maeder" contiguous. Any text following the set identifier is"
fa373bc327620e08861294716b4454be8d25669fChristian Maeder" treated as a comment. If no \b$set\b directive is"
fa373bc327620e08861294716b4454be8d25669fChristian Maeder" specified in a message text source file, all messages"
fa373bc327620e08861294716b4454be8d25669fChristian Maeder" will be located in message set \b1\b.]"
fa373bc327620e08861294716b4454be8d25669fChristian Maeder" [+$translation \aidentification\a \aYYYY-MM-DD\a[,...]]?Append"
fa373bc327620e08861294716b4454be8d25669fChristian Maeder" translation info to the message catalog header. Only"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" the newest date for a given \aidentification\a"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" is retained in the catalog. Multiple translation lines"
d5833d2ee7bafcbf2fdd2bdfd9a728c769b100c7Christian Maeder" are combined into a single \b,\b separated list.]"
7857a35e3af533dfbd0f0e18638ebd211e6358a0Christian Maeder" [+\am\a \amessage-text\a?\am\a denotes the message identifier,"
7857a35e3af533dfbd0f0e18638ebd211e6358a0Christian Maeder" which is defined as a number in the range"
7857a35e3af533dfbd0f0e18638ebd211e6358a0Christian Maeder" [1, \bNL_MSGMAX\b]]. The message-text is stored in the"
9aeda2b3ae8ce0b018955521e4ca835a8ba8a27bLiam O'Reilly" message catalogue with the set identifier specified by"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" the last \b$set\b directive, and with message"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" identifier \am\a. If the \amessage-text\a is empty,"
7857a35e3af533dfbd0f0e18638ebd211e6358a0Christian Maeder" and a blank character field separator is present, an"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" empty string is stored in the message catalogue. If a"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" message source line has a message number, but neither"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" a field separator nor \amessage-text\a, the existing"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" message with that number (if any) is deleted from the"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" catalogue. Message identifiers need not be contiguous."
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder" There are no \amessage-text\a length restrictions.]"
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder"\ncatfile [ msgfile ]\n"
eb48217dfa67ddb87b8fbd846de293d0636bd578Christian Maeder"[+SEE ALSO?\bgencat\b(1), \biconv\b(1), \bmsgcc\b(1), \btranslate\b(1),"
eb48217dfa67ddb87b8fbd846de293d0636bd578Christian Maeder" \bfmtfmt\b(3)]"
7830e8fa7442fb7452af7ecdba102bc297ae367eChristian Maedertypedef struct Xl_s
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder * append s to the translation list
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder register char* t;
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder for (; isspace(*s); s++);
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder for (d = e = 0, t = s; *t; t++)
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder if (*t == ',')
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder error(ERROR_SYSTEM|3, "out of space [translation]");
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly if (!(px = newof(0, Xl_t, 1, strlen(s))) || !(px->date = strdup(d)))
7d96b1ef2b8597330aedee6713615ec15508edcfLiam O'Reilly error(ERROR_SYSTEM|3, "out of space [translation]");
f21c7417bdd1c0282025cba0f5cb0ff5bc5c98eeLiam O'Reilly } while (s = e);
f19dc06364e8d6ea36f7c170e1f7a0677de63184Liam O'Reilly * sfprintf() with ccmaps(from,to)
580f1724640a78be687e79d0ec95dd2665e77e91Liam O'Reillyccsfprintf(int from, int to, Sfio_t* sp, const char* format, ...)
f19dc06364e8d6ea36f7c170e1f7a0677de63184Liam O'Reilly register char* s;
f19dc06364e8d6ea36f7c170e1f7a0677de63184Liam O'Reilly register char* t;
f19dc06364e8d6ea36f7c170e1f7a0677de63184Liam O'Reilly register int c;
f19dc06364e8d6ea36f7c170e1f7a0677de63184Liam O'Reilly register int q;
f19dc06364e8d6ea36f7c170e1f7a0677de63184Liam O'Reilly register int i;
fa373bc327620e08861294716b4454be8d25669fChristian Maeder if (error_info.errors || !(catfile = *argv++))
fa373bc327620e08861294716b4454be8d25669fChristian Maeder * set and list only need catfile
fa373bc327620e08861294716b4454be8d25669fChristian Maeder sfprintf(sfstdout, "%d\n", mcindex(catfile, NiL, NiL, NiL));
fa373bc327620e08861294716b4454be8d25669fChristian Maeder error(ERROR_SYSTEM|3, "%s: cannot read catalog", catfile);
fa373bc327620e08861294716b4454be8d25669fChristian Maeder error(ERROR_SYSTEM|3, "%s: catalog content error", catfile);
7830e8fa7442fb7452af7ecdba102bc297ae367eChristian Maeder for (num = 1; num <= mc->set[set].num; num++)
7830e8fa7442fb7452af7ecdba102bc297ae367eChristian Maeder sfprintf(sfstdout, "%d \"%s\"\n", num, fmtfmt(s));
7830e8fa7442fb7452af7ecdba102bc297ae367eChristian Maeder ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "$translation ");
7830e8fa7442fb7452af7ecdba102bc297ae367eChristian Maeder ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "\n");
7830e8fa7442fb7452af7ecdba102bc297ae367eChristian Maeder ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "$quote \"\n");
66bc8d6e69cde43f1ccbeb76104cf7b8038acd6cChristian Maeder ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "$set %d\n", set);
66bc8d6e69cde43f1ccbeb76104cf7b8038acd6cChristian Maeder for (num = 1; num <= mc->set[set].num; num++)
66bc8d6e69cde43f1ccbeb76104cf7b8038acd6cChristian Maeder ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "%d \"", num);
ace03c3051e5c5144e43ae78cae73f6a29dde6d5Christian Maeder while (c = *s++)
ace03c3051e5c5144e43ae78cae73f6a29dde6d5Christian Maeder /*INDENT...*/
a00461fcf7432205a79a0f12dbe6c1ebc58bc000Christian Maeder /*...UNDENT*/
bcd914850de931848b86d7728192a149f9c0108bChristian Maeder ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "\"\n");
a00461fcf7432205a79a0f12dbe6c1ebc58bc000Christian Maeder error(3, "exactly one message file must be specified");
bcd914850de931848b86d7728192a149f9c0108bChristian Maeder * open the files and handles
bcd914850de931848b86d7728192a149f9c0108bChristian Maeder error(ERROR_SYSTEM|3, "out of space [string stream]");
eb48217dfa67ddb87b8fbd846de293d0636bd578Christian Maeder error(ERROR_SYSTEM|3, "%s: cannot read message file", msgfile);
eb48217dfa67ddb87b8fbd846de293d0636bd578Christian Maeder error(ERROR_SYSTEM|3, "%s: catalog content error", catfile);
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly * read the message file
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly if (*s == '$')
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly if (!*++s || isspace(*s))
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly for (t = s; *s && !isspace(*s); s++);
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly q = *s ? *s : 0;
dd7da1b5fedc05b92ba023ebd803e6f4a662503bChristian Maeder error(2, "(%d,%d): cannot delete message", set, num);
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly else if (isspace(*s++))
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly if (*s++ != q)
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly error(2, "(%d,%d): %c quote expected", set, num, q);
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly while (c = *s++)
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder if (c == '\\')
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly else if (c == q)
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly error(2, "(%d,%d): characters after quote not expected", set, num);
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder error(2, "(%d,%d): cannot add message", set, num);
648fe1220044aac847acbdfbc4155af5556063ebChristian Maeder * fix up the translation record
05cc55892e6c93bdd7b9c3f100ab1bb65fe6a21eLiam O'Reilly if (px->date && (!bp || strcoll(bp->date, px->date) < 0))
remove(s);