xref: /onnv-gate/usr/src/lib/libast/common/comp/getoptl.c (revision 12068:08a39a083754)
14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*12068SRoger.Faulkner@Oracle.COM *          Copyright (c) 1985-2010 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
78462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
84887Schin *                                                                      *
94887Schin *                A copy of the License is available at                 *
104887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
114887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
124887Schin *                                                                      *
134887Schin *              Information and Software Systems Research               *
144887Schin *                            AT&T Research                             *
154887Schin *                           Florham Park NJ                            *
164887Schin *                                                                      *
174887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
184887Schin *                  David Korn <dgk@research.att.com>                   *
194887Schin *                   Phong Vo <kpv@research.att.com>                    *
204887Schin *                                                                      *
214887Schin ***********************************************************************/
224887Schin #pragma prototyped
234887Schin 
244887Schin #include <ast.h>
258462SApril.Chin@Sun.COM #include <ast_getopt.h>
264887Schin 
274887Schin #undef	_BLD_ast	/* enable ast imports since we're user static */
284887Schin 
294887Schin #include <error.h>
304887Schin #include <option.h>
314887Schin #include <getopt.h>
324887Schin #include <ctype.h>
334887Schin 
344887Schin static const char*		lastoptstring;
354887Schin static const struct option*	lastlongopts;
364887Schin static char*			usage;
374887Schin static Sfio_t*			up;
384887Schin 
394887Schin static int			lastoptind;
404887Schin 
414887Schin static int
golly(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longindex,int flags)424887Schin golly(int argc, char* const* argv, const char* optstring, const struct option* longopts, int* longindex, int flags)
434887Schin {
444887Schin 	register char*			s;
454887Schin 	register const struct option*	o;
464887Schin 	register int			c;
474887Schin 	char*				t;
484887Schin 
494887Schin 	if (!up || optstring != lastoptstring || longopts != lastlongopts)
504887Schin 	{
514887Schin 		if (!up && !(up = sfstropen()))
524887Schin 			return -1;
534887Schin 		sfprintf(up, "[-1p%d]", flags);
544887Schin 		t = strdup(optstring);
554887Schin 		for (o = longopts; o->name; o++)
564887Schin 		{
574887Schin 			if (o->flag || o->val <= 0 || o->val > UCHAR_MAX || !isalnum(o->val))
584887Schin 				sfprintf(up, "\n[%d:%s]", UCHAR_MAX + 1 + (o - longopts), o->name);
594887Schin 			else
604887Schin 			{
614887Schin 				sfprintf(up, "\n[%c:%s]", o->val, o->name);
624887Schin 				if (s = strchr(t, o->val))
634887Schin 				{
644887Schin 					*s++ = ' ';
654887Schin 					if (*s == ':')
664887Schin 					{
674887Schin 						*s++ = ' ';
684887Schin 						if (*s == ':')
694887Schin 							*s = ' ';
704887Schin 					}
714887Schin 				}
724887Schin 			}
734887Schin 			if (o->has_arg)
744887Schin 			{
754887Schin 				sfputc(up, ':');
764887Schin 				if (o->has_arg == optional_argument)
774887Schin 					sfputc(up, '?');
784887Schin 				sfprintf(up, "[string]");
794887Schin 			}
804887Schin 		}
814887Schin 		s = t;
824887Schin 		while (c = *s++)
834887Schin 			if (c != ' ')
844887Schin 			{
854887Schin 				sfprintf(up, "\n[%c]", c);
864887Schin 				if (*s == ':')
874887Schin 				{
884887Schin 					sfputc(up, *s);
894887Schin 					if (*++s == ':')
904887Schin 					{
914887Schin 						sfputc(up, '?');
924887Schin 						s++;
934887Schin 					}
944887Schin 					sfputc(up, '[');
954887Schin 					sfputc(up, ']');
964887Schin 				}
974887Schin 			}
984887Schin 		sfputc(up, '\n');
994887Schin 		if (!(usage = sfstruse(up)))
1004887Schin 			return -1;
1014887Schin 		lastoptstring = optstring;
1024887Schin 		lastlongopts = longopts;
1034887Schin 	}
1044887Schin 	opt_info.index = (optind > 1 || optind == lastoptind) ? optind : 0;
1054887Schin 	if (opt_info.index >= argc || !(c = optget((char**)argv, usage)))
1064887Schin 	{
1074887Schin 		sfstrclose(up);
1084887Schin 		up = 0;
1094887Schin 		c = -1;
1104887Schin 	}
1114887Schin 	else
1124887Schin 	{
1134887Schin 		if (c == ':' || c == '?')
1144887Schin 		{
1154887Schin 			if (opterr && (!optstring || *optstring != ':'))
1164887Schin 			{
1174887Schin 				if (!error_info.id)
1184887Schin 					error_info.id = argv[0];
1194887Schin 				errormsg(NiL, c == '?' ? (ERROR_USAGE|4) : 2, "%s", opt_info.arg);
1204887Schin 			}
1214887Schin 			optopt = opt_info.option[1];
1224887Schin 			c = '?';
1234887Schin 		}
1244887Schin 		optarg = opt_info.arg;
1254887Schin 		if (c < 0)
1264887Schin 		{
1274887Schin 			o = longopts - c - UCHAR_MAX - 1;
1284887Schin 			if (o->flag)
1294887Schin 			{
1304887Schin 				*o->flag = o->val;
1314887Schin 				c = 0;
1324887Schin 			}
1334887Schin 			else
1344887Schin 				c = o->val;
1354887Schin 		}
1364887Schin 	}
1374887Schin 	lastoptind = optind = opt_info.index;
1384887Schin 	return c;
1394887Schin }
1404887Schin 
1414887Schin extern int
getopt_long(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longindex)1424887Schin getopt_long(int argc, char* const* argv, const char* optstring, const struct option* longopts, int* longindex)
1434887Schin {
1444887Schin 	return golly(argc, argv, optstring, longopts, longindex, 2);
1454887Schin }
1464887Schin 
1474887Schin extern int
getopt_long_only(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longindex)1484887Schin getopt_long_only(int argc, char* const* argv, const char* optstring, const struct option* longopts, int* longindex)
1494887Schin {
1504887Schin 	return golly(argc, argv, optstring, longopts, longindex, 1);
1514887Schin }
152