1N/A/***********************************************************************
1N/A* *
1N/A* This software is part of the ast package *
1N/A* Copyright (c) 1985-2011 AT&T Intellectual Property *
1N/A* and is licensed under the *
1N/A* Common Public License, Version 1.0 *
1N/A* by AT&T Intellectual Property *
1N/A* *
1N/A* A copy of the License is available at *
1N/A* http://www.opensource.org/licenses/cpl1.0.txt *
1N/A* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
1N/A* *
1N/A* Information and Software Systems Research *
1N/A* AT&T Research *
1N/A* Florham Park NJ *
1N/A* *
1N/A* Glenn Fowler <gsf@research.att.com> *
1N/A* David Korn <dgk@research.att.com> *
1N/A* Phong Vo <kpv@research.att.com> *
1N/A* *
1N/A***********************************************************************/
1N/A#pragma prototyped
1N/A/*
1N/A * Glenn Fowler
1N/A * AT&T Research
1N/A *
1N/A * multi-pass commmand line option parse assist
1N/A *
1N/A * int fun(char** argv, int last)
1N/A *
1N/A * each fun() argument parses as much of argv as
1N/A * possible starting at (opt_info.index,opt_info.offset) using
1N/A * optget()
1N/A *
1N/A * if last!=0 then fun is the last pass to view
1N/A * the current arg, otherwise fun sets opt_info.again=1
1N/A * and another pass will get a crack at it
1N/A *
1N/A * 0 fun() return causes immediate optjoin() 0 return
1N/A *
1N/A * optjoin() returns non-zero if more args remain
1N/A * to be parsed at opt_info.index
1N/A */
1N/A
1N/A#include <optlib.h>
1N/A
1N/Atypedef int (*Optpass_f)(char**, int);
1N/A
1N/Aint
1N/Aoptjoin(char** argv, ...)
1N/A{
1N/A va_list ap;
1N/A register Optpass_f fun;
1N/A register Optpass_f rep;
1N/A Optpass_f err;
1N/A Optstate_t* state;
1N/A int more;
1N/A int user;
1N/A int last_index;
1N/A int last_offset;
1N/A int err_index;
1N/A int err_offset;
1N/A
1N/A state = optstate(&opt_info);
1N/A err = rep = 0;
1N/A for (;;)
1N/A {
1N/A va_start(ap, argv);
1N/A state->join = 0;
1N/A while (fun = va_arg(ap, Optpass_f))
1N/A {
1N/A last_index = opt_info.index;
1N/A last_offset = opt_info.offset;
1N/A state->join++;
1N/A user = (*fun)(argv, 0);
1N/A more = argv[opt_info.index] != 0;
1N/A if (!opt_info.again)
1N/A {
1N/A if (!more)
1N/A {
1N/A state->join = 0;
1N/A return 0;
1N/A }
1N/A if (!user)
1N/A {
1N/A if (*argv[opt_info.index] != '+')
1N/A {
1N/A state->join = 0;
1N/A return 1;
1N/A }
1N/A opt_info.again = -1;
1N/A }
1N/A else
1N/A err = 0;
1N/A }
1N/A if (opt_info.again)
1N/A {
1N/A if (opt_info.again > 0 && (!err || err_index < opt_info.index || err_index == opt_info.index && err_offset < opt_info.offset))
1N/A {
1N/A err = fun;
1N/A err_index = opt_info.index;
1N/A err_offset = opt_info.offset;
1N/A }
1N/A opt_info.again = 0;
1N/A opt_info.index = state->pindex ? state->pindex : 1;
1N/A opt_info.offset = state->poffset;
1N/A }
1N/A if (!rep || opt_info.index != last_index || opt_info.offset != last_offset)
1N/A rep = fun;
1N/A else if (fun == rep)
1N/A {
1N/A if (!err)
1N/A {
1N/A state->join = 0;
1N/A return 1;
1N/A }
1N/A (*err)(argv, 1);
1N/A opt_info.offset = 0;
1N/A }
1N/A }
1N/A va_end(ap);
1N/A }
1N/A}