1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1982-2007 AT&T Knowledge Ventures * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Knowledge Ventures * 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 * David Korn <dgk@research.att.com> * 18 * * 19 ***********************************************************************/ 20 #pragma prototyped 21 /* 22 * getopts optstring name [arg...] 23 * 24 * David Korn 25 * AT&T Labs 26 * research!dgk 27 * 28 */ 29 30 #include "defs.h" 31 #include "variables.h" 32 #include <error.h> 33 #include <nval.h> 34 #include "builtins.h" 35 36 static int infof(Opt_t* op, Sfio_t* sp, const char* s, Optdisc_t* dp) 37 { 38 if(nv_search(s,sh.fun_tree,0)) 39 { 40 int savtop = staktell(); 41 char *savptr = stakfreeze(0); 42 stakputc('$'); 43 stakputc('('); 44 stakputs(s); 45 stakputc(')'); 46 sfputr(sp,sh_mactry(stakfreeze(1)),-1); 47 stakset(savptr,savtop); 48 } 49 return(1); 50 } 51 52 int b_getopts(int argc,char *argv[],void *extra) 53 { 54 register char *options=error_info.context->id; 55 register Namval_t *np; 56 register int flag, mode, r=0; 57 register Shell_t *shp = (Shell_t*)extra; 58 char value[2], key[2]; 59 int jmpval; 60 struct checkpt buff, *pp; 61 Optdisc_t disc; 62 memset(&disc, 0, sizeof(disc)); 63 disc.version = OPT_VERSION; 64 disc.infof = infof; 65 value[1] = 0; 66 key[1] = 0; 67 while((flag = optget(argv,sh_optgetopts))) switch(flag) 68 { 69 case 'a': 70 options = opt_info.arg; 71 break; 72 case ':': 73 errormsg(SH_DICT,2, "%s", opt_info.arg); 74 break; 75 case '?': 76 errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg); 77 break; 78 } 79 argv += opt_info.index; 80 argc -= opt_info.index; 81 if(error_info.errors || argc<2) 82 errormsg(SH_DICT,ERROR_usage(2), "%s", optusage((char*)0)); 83 error_info.context->flags |= ERROR_SILENT; 84 error_info.id = options; 85 options = argv[0]; 86 np = nv_open(argv[1],shp->var_tree,NV_NOASSIGN|NV_VARNAME); 87 if(argc>2) 88 { 89 argv +=1; 90 argc -=1; 91 } 92 else 93 { 94 argv = shp->st.dolv; 95 argc = shp->st.dolc; 96 } 97 opt_info.index = shp->st.optindex; 98 opt_info.offset = shp->st.optchar; 99 if(mode= (*options==':')) 100 options++; 101 sh_pushcontext(&buff,1); 102 jmpval = sigsetjmp(buff.buff,0); 103 if(jmpval) 104 { 105 sh_popcontext(&buff); 106 pp = (struct checkpt*)shp->jmplist; 107 pp->mode = SH_JMPERREXIT; 108 sh_exit(2); 109 } 110 opt_info.disc = &disc; 111 switch(opt_info.index>=0 && opt_info.index<=argc?(opt_info.num= LONG_MIN,flag=optget(argv,options)):0) 112 { 113 case '?': 114 if(mode==0) 115 errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg); 116 opt_info.option[1] = '?'; 117 /* FALL THRU */ 118 case ':': 119 key[0] = opt_info.option[1]; 120 if(strmatch(opt_info.arg,"*unknown*")) 121 flag = '?'; 122 if(mode) 123 opt_info.arg = key; 124 else 125 { 126 errormsg(SH_DICT,2, "%s", opt_info.arg); 127 opt_info.arg = 0; 128 flag = '?'; 129 } 130 *(options = value) = flag; 131 shp->st.opterror = 1; 132 if (opt_info.offset != 0 && !argv[opt_info.index][opt_info.offset]) 133 { 134 opt_info.offset = 0; 135 opt_info.index++; 136 } 137 break; 138 case 0: 139 if(shp->st.opterror) 140 { 141 char *com[2]; 142 com[0] = "-?"; 143 com[1] = 0; 144 flag = opt_info.index; 145 opt_info.index = 0; 146 optget(com,options); 147 opt_info.index = flag; 148 if(!mode && strchr(options,' ')) 149 errormsg(SH_DICT,ERROR_usage(2), "%s", optusage((char*)0)); 150 } 151 opt_info.arg = 0; 152 options = value; 153 *options = '?'; 154 r=1; 155 opt_info.offset = 0; 156 break; 157 default: 158 options = opt_info.option + (*opt_info.option!='+'); 159 } 160 error_info.context->flags &= ~ERROR_SILENT; 161 shp->st.optindex = opt_info.index; 162 shp->st.optchar = opt_info.offset; 163 nv_putval(np, options, 0); 164 nv_close(np); 165 np = nv_open(nv_name(OPTARGNOD),shp->var_tree,NV_NOSCOPE); 166 if(opt_info.num == LONG_MIN) 167 nv_putval(np, opt_info.arg, NV_RDONLY); 168 else if (opt_info.num > 0 && opt_info.arg && opt_info.arg[0] == (char)opt_info.num) 169 { 170 key[0] = (char)opt_info.num; 171 key[1] = 0; 172 nv_putval(np, key, NV_RDONLY); 173 } 174 else 175 { 176 Sfdouble_t d; 177 d = opt_info.number; 178 nv_putval(np, (char*)&d, NV_LDOUBLE|NV_RDONLY); 179 } 180 nv_close(np); 181 sh_popcontext(&buff); 182 opt_info.disc = 0; 183 return(r); 184 } 185 186