da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1982-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * getopts optstring name [arg...]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * research!dgk
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "defs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "variables.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <error.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <nval.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "builtins.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int infof(Opt_t* op, Sfio_t* sp, const char* s, Optdisc_t* dp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = *(Shell_t**)(dp+1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp = shp->stk;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_search(s,sh.fun_tree,0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int savtop = stktell(stkp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *savptr = stkfreeze(stkp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,'$');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,'(');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputr(stkp,s,')');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputr(sp,sh_mactry(shp,stkfreeze(stkp,1)),-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkset(stkp,savptr,savtop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint b_getopts(int argc,char *argv[],void *extra)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *options=error_info.context->id;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int flag, mode, r=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Shell_t *shp = ((Shbltin_t*)extra)->shp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char value[2], key[2];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int jmpval,extended;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct checkpt buff, *pp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Optdisc_t hdr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *sh;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin } disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(&disc, 0, sizeof(disc));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin disc.hdr.version = OPT_VERSION;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin disc.hdr.infof = infof;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin disc.sh = shp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value[1] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin key[1] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((flag = optget(argv,sh_optgetopts))) switch(flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'a':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin options = opt_info.arg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,2, "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '?':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv += opt_info.index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argc -= opt_info.index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(error_info.errors || argc<2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_usage(2), "%s", optusage((char*)0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.context->flags |= ERROR_SILENT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.id = options;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin options = argv[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = nv_open(argv[1],shp->var_tree,NV_NOASSIGN|NV_VARNAME);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argc>2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv +=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argc -=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv = shp->st.dolv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argc = shp->st.dolc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.index = shp->st.optindex;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.offset = shp->st.optchar;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode= (*options==':'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin options++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin extended = *options=='\n' && *(options+1)=='[' || *options=='[' && *(options+1)=='-';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pushcontext(&buff,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jmpval = sigsetjmp(buff.buff,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_popcontext(&buff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = (struct checkpt*)shp->jmplist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->mode = SH_JMPERREXIT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exit(2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin opt_info.disc = &disc.hdr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(opt_info.index>=0 && opt_info.index<=argc?(opt_info.num= LONG_MIN,flag=optget(argv,options)):0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '?':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.option[1] = '?';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin key[0] = opt_info.option[1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strmatch(opt_info.arg,"*unknown*"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag = '?';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.arg = key;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,2, "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.arg = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag = '?';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *(options = value) = flag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->st.opterror = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (opt_info.offset != 0 && !argv[opt_info.index][opt_info.offset])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.offset = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.index++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(shp->st.opterror)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *com[2];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin com[0] = "-?";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin com[1] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag = opt_info.index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.index = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin optget(com,options);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.index = flag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!mode && strchr(options,' '))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_usage(2), "%s", optusage((char*)0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.arg = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin options = value;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *options = '?';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.offset = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin options = opt_info.option + (*opt_info.option!='+');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.context->flags &= ~ERROR_SILENT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->st.optindex = opt_info.index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->st.optchar = opt_info.offset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(np, options, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_close(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = nv_open(nv_name(OPTARGNOD),shp->var_tree,NV_NOSCOPE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(opt_info.num == LONG_MIN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(np, opt_info.arg, NV_RDONLY);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if (opt_info.arg && opt_info.num > 0 && isalpha((char)opt_info.num) && !isdigit(opt_info.arg[0]) && opt_info.arg[0] != '-' && opt_info.arg[0] != '+')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin key[0] = (char)opt_info.num;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin key[1] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(np, key, NV_RDONLY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(extended)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfdouble_t d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = opt_info.number;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(np, (char*)&d, NV_LDOUBLE|NV_RDONLY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putval(np, opt_info.arg, NV_RDONLY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_close(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_popcontext(&buff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.disc = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin