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
61 #include "msgfac_msg.h"
63 #define die(s) puts(s), exit(1)
64 #define isanumber(c) (c >= '0' && c <= '9') ? 1 : 0
65 #define isaoctal(c) (c >= '0' && c <= '7') ? 1 : 0
66 #define toanumber(c) (c - '0')
80 /*-- subroutine used to parse the input arguments ---*/
81 void parse_args(int argc, char *argv[], struct arguments *args);
83 nl_catd catderr; /* error message catalog descriptor */
90 * FUNCTION: Extract a message string from a catalog. Perform printf
91 * style substitutions and print it out.
93 * EXECUTION ENVIRONMENT:
96 * RETURNS: Exit with 0, except when: the format string
100 int main(int argc,char *argv[])
102 /* argc: Number of arguments */
103 /* argv: argument vector */
106 struct arguments args; /* place to store the parsed arguments*/
107 nl_catd catdmsg; /* catalog descriptor for message catalog */
108 char *message; /* place to store message */
109 char *p; /* pointer to current pos within message */
110 int idx, /* current argument to be printed */
111 reorder = NOT_SET; /* Reordering (TRUE, FALSE, NOT_SET) */
112 int n; /* # bytes in a character */
114 setlocale (LC_ALL,"");
115 catderr = catopen(MF_MSGFAC, 0);
117 die(catgets(catderr,MS_DSPMSG,M_DSPMSG, "Usage: dtdspmsg [-s setno] <catname> <msgno> ['default' arg ... ]"));
120 /*______________________________________________________________________
121 Parse the input arguments int the args structure.
122 ______________________________________________________________________*/
124 parse_args(argc,argv,&args);
126 /*______________________________________________________________________
127 get the message out of the catalog.
128 ______________________________________________________________________*/
130 catdmsg = catopen(args.catname, 0);
131 message = catgets(catdmsg,args.set,args.msg,args.def);
133 /*______________________________________________________________________
135 print out the message making the appropriate sub's for
136 the parameters. Reorder the parameters if necessary.
137 Do not use mixed reordering!!!
138 ______________________________________________________________________*/
140 for (p = message , idx = 0 ; *p ; p++ ) {
142 /* quoted escape characters */
143 if (*p == '\\' && message == args.def) {
172 unsigned int hex, hexlen = 0;
174 while (isxdigit(*++pesc))
177 sscanf (p+1, "%2x", &hex);
178 else if (hexlen == 4)
179 sscanf (p+1, "%4x", &hex);
202 c = c * 8 + *pesc++ - '0';
203 while (isaoctal(*pesc) && pesc < p+3);
218 /* printf % style substitution */
219 else if (*p == '%') {
221 /* %% prints one % */
227 /* %n$ reorders the argument list and uses variable n next */
228 /* once this is used, all arguments must use it */
231 /* do not allow mixing of reorder types */
232 if (reorder == FALSE) {
233 die(catgets(catderr,MS_DSPMSG,M_REORDER,"\nNone or all arguments must use %n$ format"));
235 for (idx = 0 ; isanumber(*p) ; p++)
236 idx += idx * 10 + toanumber(*p);
239 die(catgets(catderr,MS_DSPMSG,M_INVRE,"\n% missing from %n$ format"));
244 /* do not allow mixing of reorder types */
245 if (reorder == TRUE) {
246 die(catgets(catderr,MS_DSPMSG,M_REORDER,"\nNone or all arguments must use %n$ format"));
250 /* report invalid printf argument number */
251 if (idx < 0 || idx >= args.argmax) {
252 die(catgets(catderr,MS_DSPMSG,M_REINDEX,"\nInvalid argument index"));
254 /* report unsupported % type */
257 else if (*p == 'l' && p[1] == 'd')
262 fwrite(args.args[idx],strlen(args.args[idx]),1,stdout);
266 /* just print the next character */
268 n = mblen(p, MB_CUR_MAX);
285 * FUNCTION: Sets up the args-> data structure for main().
287 * EXECUTION ENVIRONMENT:
293 void parse_args(int argc, char *argv[], struct arguments *args)
295 /* argc: The number or arguments */
296 /* argv: The input argument vector */
297 /* args: The output argument structure */
306 argc--; /* Skip the program name */
307 if (!strcmp(*argv,"-s")) { /* check for a set number */
308 if (argc < 4) /* check for sufficient arguements */
309 die(catgets(catderr,MS_DSPMSG,M_DSPMSG, "Usage: dtdspmsg [-s setno] <catname> <msgno> ['default' arg ... ]"));
311 argc--; /* skip past the '-s' */
312 sscanf(*argv,"%d",&args->set); /* get the real set number */
314 argc--; /* skip past the set number */
316 args->catname = *argv++; /* get the cat name */
318 if (!strcmp(*argv,"-s")) { /* check for a set number */
319 if (argc < 3) /* check for sufficient arguements */
320 die(catgets(catderr,MS_DSPMSG,M_DSPMSG, "Usage: dtdspmsg [-s setno] <catname> <msgno> ['default' arg ... ]"));
323 argc--; /* skip past the '-s' */
324 sscanf(*argv,"%d",&args->set); /* get the real set number */
326 argc--; /* skip past the set number */
328 sscanf(*argv++,"%d",&args->msg); /* scan the message number */
330 if (argc) { /* check for the arg count
331 for a default string */