diff options
Diffstat (limited to 'usr/src/lib/libast/common/misc/optjoin.c')
-rw-r--r-- | usr/src/lib/libast/common/misc/optjoin.c | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/usr/src/lib/libast/common/misc/optjoin.c b/usr/src/lib/libast/common/misc/optjoin.c new file mode 100644 index 0000000000..6aa0903810 --- /dev/null +++ b/usr/src/lib/libast/common/misc/optjoin.c @@ -0,0 +1,123 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1985-2007 AT&T Knowledge Ventures * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Knowledge Ventures * +* * +* A copy of the License is available at * +* http://www.opensource.org/licenses/cpl1.0.txt * +* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* David Korn <dgk@research.att.com> * +* Phong Vo <kpv@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped +/* + * Glenn Fowler + * AT&T Research + * + * multi-pass commmand line option parse assist + * + * int fun(char** argv, int last) + * + * each fun() argument parses as much of argv as + * possible starting at (opt_info.index,opt_info.offset) using + * optget() + * + * if last!=0 then fun is the last pass to view + * the current arg, otherwise fun sets opt_info.again=1 + * and another pass will get a crack at it + * + * 0 fun() return causes immediate optjoin() 0 return + * + * optjoin() returns non-zero if more args remain + * to be parsed at opt_info.index + */ + +#include <optlib.h> + +typedef int (*Optpass_f)(char**, int); + +int +optjoin(char** argv, ...) +{ + va_list ap; + register Optpass_f fun; + register Optpass_f rep; + Optpass_f err; + int more; + int user; + int last_index; + int last_offset; + int err_index; + int err_offset; + + if (!opt_info.state) + optget(NiL, NiL); + err = rep = 0; + for (;;) + { + va_start(ap, argv); + opt_info.state->join = 0; + while (fun = va_arg(ap, Optpass_f)) + { + last_index = opt_info.index; + last_offset = opt_info.offset; + opt_info.state->join++; + user = (*fun)(argv, 0); + more = argv[opt_info.index] != 0; + if (!opt_info.again) + { + if (!more) + { + opt_info.state->join = 0; + return 0; + } + if (!user) + { + if (*argv[opt_info.index] != '+') + { + opt_info.state->join = 0; + return 1; + } + opt_info.again = -1; + } + else + err = 0; + } + if (opt_info.again) + { + if (opt_info.again > 0 && (!err || err_index < opt_info.index || err_index == opt_info.index && err_offset < opt_info.offset)) + { + err = fun; + err_index = opt_info.index; + err_offset = opt_info.offset; + } + opt_info.again = 0; + opt_info.index = opt_info.state->pindex ? opt_info.state->pindex : 1; + opt_info.offset = opt_info.state->poffset; + } + if (!rep || opt_info.index != last_index || opt_info.offset != last_offset) + rep = fun; + else if (fun == rep) + { + if (!err) + { + opt_info.state->join = 0; + return 1; + } + (*err)(argv, 1); + opt_info.offset = 0; + } + } + va_end(ap); + } +} |