14887Schin /*********************************************************************** 24887Schin * * 34887Schin * This software is part of the ast package * 4*8462SApril.Chin@Sun.COM * Copyright (c) 1985-2008 AT&T Intellectual Property * 54887Schin * and is licensed under the * 64887Schin * Common Public License, Version 1.0 * 7*8462SApril.Chin@Sun.COM * by AT&T Intellectual Property * 84887Schin * * 94887Schin * A copy of the License is available at * 104887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 124887Schin * * 134887Schin * Information and Software Systems Research * 144887Schin * AT&T Research * 154887Schin * Florham Park NJ * 164887Schin * * 174887Schin * Glenn Fowler <gsf@research.att.com> * 184887Schin * David Korn <dgk@research.att.com> * 194887Schin * Phong Vo <kpv@research.att.com> * 204887Schin * * 214887Schin ***********************************************************************/ 224887Schin #pragma prototyped 234887Schin /* 244887Schin * Glenn Fowler 254887Schin * AT&T Research 264887Schin * 274887Schin * multi-pass commmand line option parse assist 284887Schin * 294887Schin * int fun(char** argv, int last) 304887Schin * 314887Schin * each fun() argument parses as much of argv as 324887Schin * possible starting at (opt_info.index,opt_info.offset) using 334887Schin * optget() 344887Schin * 354887Schin * if last!=0 then fun is the last pass to view 364887Schin * the current arg, otherwise fun sets opt_info.again=1 374887Schin * and another pass will get a crack at it 384887Schin * 394887Schin * 0 fun() return causes immediate optjoin() 0 return 404887Schin * 414887Schin * optjoin() returns non-zero if more args remain 424887Schin * to be parsed at opt_info.index 434887Schin */ 444887Schin 454887Schin #include <optlib.h> 464887Schin 474887Schin typedef int (*Optpass_f)(char**, int); 484887Schin 494887Schin int 504887Schin optjoin(char** argv, ...) 514887Schin { 524887Schin va_list ap; 534887Schin register Optpass_f fun; 544887Schin register Optpass_f rep; 554887Schin Optpass_f err; 564887Schin int more; 574887Schin int user; 584887Schin int last_index; 594887Schin int last_offset; 604887Schin int err_index; 614887Schin int err_offset; 624887Schin 634887Schin if (!opt_info.state) 644887Schin optget(NiL, NiL); 654887Schin err = rep = 0; 664887Schin for (;;) 674887Schin { 684887Schin va_start(ap, argv); 694887Schin opt_info.state->join = 0; 704887Schin while (fun = va_arg(ap, Optpass_f)) 714887Schin { 724887Schin last_index = opt_info.index; 734887Schin last_offset = opt_info.offset; 744887Schin opt_info.state->join++; 754887Schin user = (*fun)(argv, 0); 764887Schin more = argv[opt_info.index] != 0; 774887Schin if (!opt_info.again) 784887Schin { 794887Schin if (!more) 804887Schin { 814887Schin opt_info.state->join = 0; 824887Schin return 0; 834887Schin } 844887Schin if (!user) 854887Schin { 864887Schin if (*argv[opt_info.index] != '+') 874887Schin { 884887Schin opt_info.state->join = 0; 894887Schin return 1; 904887Schin } 914887Schin opt_info.again = -1; 924887Schin } 934887Schin else 944887Schin err = 0; 954887Schin } 964887Schin if (opt_info.again) 974887Schin { 984887Schin if (opt_info.again > 0 && (!err || err_index < opt_info.index || err_index == opt_info.index && err_offset < opt_info.offset)) 994887Schin { 1004887Schin err = fun; 1014887Schin err_index = opt_info.index; 1024887Schin err_offset = opt_info.offset; 1034887Schin } 1044887Schin opt_info.again = 0; 1054887Schin opt_info.index = opt_info.state->pindex ? opt_info.state->pindex : 1; 1064887Schin opt_info.offset = opt_info.state->poffset; 1074887Schin } 1084887Schin if (!rep || opt_info.index != last_index || opt_info.offset != last_offset) 1094887Schin rep = fun; 1104887Schin else if (fun == rep) 1114887Schin { 1124887Schin if (!err) 1134887Schin { 1144887Schin opt_info.state->join = 0; 1154887Schin return 1; 1164887Schin } 1174887Schin (*err)(argv, 1); 1184887Schin opt_info.offset = 0; 1194887Schin } 1204887Schin } 1214887Schin va_end(ap); 1224887Schin } 1234887Schin } 124