1/*********************************************************************** 2* * 3* This software is part of the ast package * 4* Copyright (c) 1985-2011 AT&T Intellectual Property * 5* and is licensed under the * 6* Common Public License, Version 1.0 * 7* by AT&T Intellectual Property * 8* * 9* A copy of the License is available at * 10* http://www.opensource.org/licenses/cpl1.0.txt * 11* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12* * 13* Information and Software Systems Research * 14* AT&T Research * 15* Florham Park NJ * 16* * 17* Glenn Fowler <gsf@research.att.com> * 18* David Korn <dgk@research.att.com> * 19* Phong Vo <kpv@research.att.com> * 20* * 21***********************************************************************/ 22#pragma prototyped 23/* 24 * Glenn Fowler 25 * AT&T Research 26 * 27 * multi-pass commmand line option parse assist 28 * 29 * int fun(char** argv, int last) 30 * 31 * each fun() argument parses as much of argv as 32 * possible starting at (opt_info.index,opt_info.offset) using 33 * optget() 34 * 35 * if last!=0 then fun is the last pass to view 36 * the current arg, otherwise fun sets opt_info.again=1 37 * and another pass will get a crack at it 38 * 39 * 0 fun() return causes immediate optjoin() 0 return 40 * 41 * optjoin() returns non-zero if more args remain 42 * to be parsed at opt_info.index 43 */ 44 45#include <optlib.h> 46 47typedef int (*Optpass_f)(char**, int); 48 49int 50optjoin(char** argv, ...) 51{ 52 va_list ap; 53 register Optpass_f fun; 54 register Optpass_f rep; 55 Optpass_f err; 56 Optstate_t* state; 57 int more; 58 int user; 59 int last_index; 60 int last_offset; 61 int err_index; 62 int err_offset; 63 64 state = optstate(&opt_info); 65 err = rep = 0; 66 for (;;) 67 { 68 va_start(ap, argv); 69 state->join = 0; 70 while (fun = va_arg(ap, Optpass_f)) 71 { 72 last_index = opt_info.index; 73 last_offset = opt_info.offset; 74 state->join++; 75 user = (*fun)(argv, 0); 76 more = argv[opt_info.index] != 0; 77 if (!opt_info.again) 78 { 79 if (!more) 80 { 81 state->join = 0; 82 return 0; 83 } 84 if (!user) 85 { 86 if (*argv[opt_info.index] != '+') 87 { 88 state->join = 0; 89 return 1; 90 } 91 opt_info.again = -1; 92 } 93 else 94 err = 0; 95 } 96 if (opt_info.again) 97 { 98 if (opt_info.again > 0 && (!err || err_index < opt_info.index || err_index == opt_info.index && err_offset < opt_info.offset)) 99 { 100 err = fun; 101 err_index = opt_info.index; 102 err_offset = opt_info.offset; 103 } 104 opt_info.again = 0; 105 opt_info.index = state->pindex ? state->pindex : 1; 106 opt_info.offset = state->poffset; 107 } 108 if (!rep || opt_info.index != last_index || opt_info.offset != last_offset) 109 rep = fun; 110 else if (fun == rep) 111 { 112 if (!err) 113 { 114 state->join = 0; 115 return 1; 116 } 117 (*err)(argv, 1); 118 opt_info.offset = 0; 119 } 120 } 121 va_end(ap); 122 } 123} 124