1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2008 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 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 int more; 57 int user; 58 int last_index; 59 int last_offset; 60 int err_index; 61 int err_offset; 62 63 if (!opt_info.state) 64 optget(NiL, NiL); 65 err = rep = 0; 66 for (;;) 67 { 68 va_start(ap, argv); 69 opt_info.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 opt_info.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 opt_info.state->join = 0; 82 return 0; 83 } 84 if (!user) 85 { 86 if (*argv[opt_info.index] != '+') 87 { 88 opt_info.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 = opt_info.state->pindex ? opt_info.state->pindex : 1; 106 opt_info.offset = opt_info.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 opt_info.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