2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: dtdspmsg.c /main/4 1996/04/21 19:28:47 drk $ */
25 * COMPONENT_NAME: (CMDMSG) Message Catalogue Facilities
27 * FUNCTIONS: main, pars_args
31 * IBM CONFIDENTIAL -- (IBM Confidential Restricted when
32 * combined with the aggregated modules for this product)
33 * OBJECT CODE ONLY SOURCE MATERIALS
34 * (C) COPYRIGHT International Business Machines Corp. 1988, 1989, 1991
37 * US Government Users Restricted Rights - Use, duplication or
38 * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
43 /*static char rcsid[] = "RCSfile: dspmsg.c,v Revision: 1.4 (OSF) Date: 90/10/07 16:45:19 ";*/
46 * (c) Copyright 1993, 1994 Hewlett-Packard Company
47 * (c) Copyright 1993, 1994 International Business Machines Corp.
48 * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
49 * (c) Copyright 1993, 1994 Novell, Inc.
53 * EXTERNAL PROCEDURES CALLED: standard library functions
60 #include "msgfac_msg.h"
62 #define die(s) puts(s), exit(1)
63 #define isanumber(c) (c >= '0' && c <= '9') ? 1 : 0
64 #define isaoctal(c) (c >= '0' && c <= '7') ? 1 : 0
65 #define toanumber(c) (c - '0')
79 /*-- subroutine used to parse the input arguments ---*/
80 void parse_args(int argc, char *argv[], struct arguments *args);
82 nl_catd catderr; /* error message catalog descriptor */
89 * FUNCTION: Extract a message string from a catalog. Perform printf
90 * style substitutions and print it out.
92 * EXECUTION ENVIRONMENT:
95 * RETURNS: Exit with 0, except when: the format string
99 int main(int argc,char *argv[])
101 /* argc: Number of arguments */
102 /* argv: argument vector */
105 struct arguments args; /* place to store the parsed arguments*/
106 nl_catd catdmsg; /* catalog descriptor for message catalog */
107 char *message; /* place to store message */
108 char *p; /* pointer to current pos within message */
109 int idx, /* current argument to be printed */
110 reorder = NOT_SET; /* Reordering (TRUE, FALSE, NOT_SET) */
111 int n; /* # bytes in a character */
113 setlocale (LC_ALL,"");
114 catderr = catopen(MF_MSGFAC, 0);
116 die(catgets(catderr,MS_DSPMSG,M_DSPMSG, "Usage: dtdspmsg [-s setno] <catname> <msgno> ['default' arg ... ]"));
119 /*______________________________________________________________________
120 Parse the input arguments int the args structure.
121 ______________________________________________________________________*/
123 parse_args(argc,argv,&args);
125 /*______________________________________________________________________
126 get the message out of the catalog.
127 ______________________________________________________________________*/
129 catdmsg = catopen(args.catname, 0);
130 message = catgets(catdmsg,args.set,args.msg,args.def);
132 /*______________________________________________________________________
134 print out the message making the appropriate sub's for
135 the parameters. Reorder the parameters if necessary.
136 Do not use mixed reordering!!!
137 ______________________________________________________________________*/
139 for (p = message , idx = 0 ; *p ; p++ ) {
141 /* quoted escape characters */
142 if (*p == '\\' && message == args.def) {
173 while (isxdigit(*++pesc))
176 sscanf (p+1, "%2x", &hex);
177 else if (hexlen == 4)
178 sscanf (p+1, "%4x", &hex);
201 c = c * 8 + *pesc++ - '0';
202 while (isaoctal(*pesc) && pesc < p+3);
217 /* printf % style substitution */
218 else if (*p == '%') {
220 /* %% prints one % */
226 /* %n$ reorders the argument list and uses variable n next */
227 /* once this is used, all arguments must use it */
230 /* do not allow mixing of reorder types */
231 if (reorder == FALSE) {
232 die(catgets(catderr,MS_DSPMSG,M_REORDER,"\nNone or all arguments must use %n$ format"));
234 for (idx = 0 ; isanumber(*p) ; p++)
235 idx += idx * 10 + toanumber(*p);
238 die(catgets(catderr,MS_DSPMSG,M_INVRE,"\n% missing from %n$ format"));
243 /* do not allow mixing of reorder types */
244 if (reorder == TRUE) {
245 die(catgets(catderr,MS_DSPMSG,M_REORDER,"\nNone or all arguments must use %n$ format"));
249 /* report invalid printf argument number */
250 if (idx < 0 || idx >= args.argmax) {
251 die(catgets(catderr,MS_DSPMSG,M_REINDEX,"\nInvalid argument index"));
253 /* report unsupported % type */
256 else if (*p == 'l' && p[1] == 'd')
261 fwrite(args.args[idx],strlen(args.args[idx]),1,stdout);
265 /* just print the next character */
267 n = mblen(p, MB_CUR_MAX);
284 * FUNCTION: Sets up the args-> data structure for main().
286 * EXECUTION ENVIRONMENT:
292 void parse_args(int argc, char *argv[], struct arguments *args)
294 /* argc: The number or arguments */
295 /* argv: The input argument vector */
296 /* args: The output argument structure */
305 argc--; /* Skip the program name */
306 if (!strcmp(*argv,"-s")) { /* check for a set number */
307 if (argc < 4) /* check for sufficient arguements */
308 die(catgets(catderr,MS_DSPMSG,M_DSPMSG, "Usage: dtdspmsg [-s setno] <catname> <msgno> ['default' arg ... ]"));
310 argc--; /* skip past the '-s' */
311 sscanf(*argv,"%d",&args->set); /* get the real set number */
313 argc--; /* skip past the set number */
315 args->catname = *argv++; /* get the cat name */
317 if (!strcmp(*argv,"-s")) { /* check for a set number */
318 if (argc < 3) /* check for sufficient arguements */
319 die(catgets(catderr,MS_DSPMSG,M_DSPMSG, "Usage: dtdspmsg [-s setno] <catname> <msgno> ['default' arg ... ]"));
322 argc--; /* skip past the '-s' */
323 sscanf(*argv,"%d",&args->set); /* get the real set number */
325 argc--; /* skip past the set number */
327 sscanf(*argv++,"%d",&args->msg); /* scan the message number */
329 if (argc) { /* check for the arg count
330 for a default string */