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 * Glenn Fowler
254887Schin * AT&T Research
264887Schin *
274887Schin * multi-pass commmand line option parse assist
284887Schin *
294887Schin * int fun(char** argv, int last)
304887Schin *
314887Schin * each fun() argument parses as much of argv as
324887Schin * possible starting at (opt_info.index,opt_info.offset) using
334887Schin * optget()
344887Schin *
354887Schin * if last!=0 then fun is the last pass to view
364887Schin * the current arg, otherwise fun sets opt_info.again=1
374887Schin * and another pass will get a crack at it
384887Schin *
394887Schin * 0 fun() return causes immediate optjoin() 0 return
404887Schin *
414887Schin * optjoin() returns non-zero if more args remain
424887Schin * to be parsed at opt_info.index
434887Schin */
444887Schin
454887Schin #include <optlib.h>
464887Schin
474887Schin typedef int (*Optpass_f)(char**, int);
484887Schin
494887Schin int
optjoin(char ** argv,...)504887Schin optjoin(char** argv, ...)
514887Schin {
524887Schin va_list ap;
534887Schin register Optpass_f fun;
544887Schin register Optpass_f rep;
554887Schin Optpass_f err;
564887Schin int more;
574887Schin int user;
584887Schin int last_index;
594887Schin int last_offset;
604887Schin int err_index;
614887Schin int err_offset;
624887Schin
634887Schin if (!opt_info.state)
644887Schin optget(NiL, NiL);
654887Schin err = rep = 0;
664887Schin for (;;)
674887Schin {
684887Schin va_start(ap, argv);
694887Schin opt_info.state->join = 0;
704887Schin while (fun = va_arg(ap, Optpass_f))
714887Schin {
724887Schin last_index = opt_info.index;
734887Schin last_offset = opt_info.offset;
744887Schin opt_info.state->join++;
754887Schin user = (*fun)(argv, 0);
764887Schin more = argv[opt_info.index] != 0;
774887Schin if (!opt_info.again)
784887Schin {
794887Schin if (!more)
804887Schin {
814887Schin opt_info.state->join = 0;
824887Schin return 0;
834887Schin }
844887Schin if (!user)
854887Schin {
864887Schin if (*argv[opt_info.index] != '+')
874887Schin {
884887Schin opt_info.state->join = 0;
894887Schin return 1;
904887Schin }
914887Schin opt_info.again = -1;
924887Schin }
934887Schin else
944887Schin err = 0;
954887Schin }
964887Schin if (opt_info.again)
974887Schin {
984887Schin if (opt_info.again > 0 && (!err || err_index < opt_info.index || err_index == opt_info.index && err_offset < opt_info.offset))
994887Schin {
1004887Schin err = fun;
1014887Schin err_index = opt_info.index;
1024887Schin err_offset = opt_info.offset;
1034887Schin }
1044887Schin opt_info.again = 0;
1054887Schin opt_info.index = opt_info.state->pindex ? opt_info.state->pindex : 1;
1064887Schin opt_info.offset = opt_info.state->poffset;
1074887Schin }
1084887Schin if (!rep || opt_info.index != last_index || opt_info.offset != last_offset)
1094887Schin rep = fun;
1104887Schin else if (fun == rep)
1114887Schin {
1124887Schin if (!err)
1134887Schin {
1144887Schin opt_info.state->join = 0;
1154887Schin return 1;
1164887Schin }
1174887Schin (*err)(argv, 1);
1184887Schin opt_info.offset = 0;
1194887Schin }
1204887Schin }
1214887Schin va_end(ap);
1224887Schin }
1234887Schin }
124