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 * Eclipse Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.eclipse.org/org/documents/epl-v10.html * 11 * (with md5 checksum b35adb5213ca9657e911e9befb180842) * 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 47 typedef int (*Optpass_f)(char**, int); 48 49 int 50 optjoin(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 r; 58 int more; 59 int user; 60 int last_index; 61 int last_offset; 62 int err_index; 63 int err_offset; 64 65 state = optstate(&opt_info); 66 err = rep = 0; 67 r = -1; 68 while (r < 0) 69 { 70 va_start(ap, argv); 71 state->join = 0; 72 while (fun = va_arg(ap, Optpass_f)) 73 { 74 last_index = opt_info.index; 75 last_offset = opt_info.offset; 76 state->join++; 77 user = (*fun)(argv, 0); 78 more = argv[opt_info.index] != 0; 79 if (!opt_info.again) 80 { 81 if (!more) 82 { 83 state->join = 0; 84 r = 0; 85 break; 86 } 87 if (!user) 88 { 89 if (*argv[opt_info.index] != '+') 90 { 91 state->join = 0; 92 r = 1; 93 break; 94 } 95 opt_info.again = -1; 96 } 97 else 98 err = 0; 99 } 100 if (opt_info.again) 101 { 102 if (opt_info.again > 0 && (!err || err_index < opt_info.index || err_index == opt_info.index && err_offset < opt_info.offset)) 103 { 104 err = fun; 105 err_index = opt_info.index; 106 err_offset = opt_info.offset; 107 } 108 opt_info.again = 0; 109 opt_info.index = state->pindex ? state->pindex : 1; 110 opt_info.offset = state->poffset; 111 } 112 if (!rep || opt_info.index != last_index || opt_info.offset != last_offset) 113 rep = fun; 114 else if (fun == rep) 115 { 116 if (!err) 117 { 118 state->join = 0; 119 r = 1; 120 break; 121 } 122 (*err)(argv, 1); 123 opt_info.offset = 0; 124 } 125 } 126 va_end(ap); 127 } 128 return r; 129 } 130