summaryrefslogtreecommitdiff
path: root/src/cmd/ksh93/bltins/getopts.c
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2012-06-24 22:28:35 +0000
committerIgor Pashev <pashev.igor@gmail.com>2012-06-24 22:28:35 +0000
commit3950ffe2a485479f6561c27364d3d7df5a21d124 (patch)
tree468c6e14449d1b1e279222ec32f676b0311917d2 /src/cmd/ksh93/bltins/getopts.c
downloadksh-upstream.tar.gz
Imported Upstream version 93u+upstream
Diffstat (limited to 'src/cmd/ksh93/bltins/getopts.c')
-rw-r--r--src/cmd/ksh93/bltins/getopts.c199
1 files changed, 199 insertions, 0 deletions
diff --git a/src/cmd/ksh93/bltins/getopts.c b/src/cmd/ksh93/bltins/getopts.c
new file mode 100644
index 0000000..8b92b73
--- /dev/null
+++ b/src/cmd/ksh93/bltins/getopts.c
@@ -0,0 +1,199 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1982-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* David Korn <dgk@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * getopts optstring name [arg...]
+ *
+ * David Korn
+ * AT&T Labs
+ * research!dgk
+ *
+ */
+
+#include "defs.h"
+#include "variables.h"
+#include <error.h>
+#include <nval.h>
+#include "builtins.h"
+
+static int infof(Opt_t* op, Sfio_t* sp, const char* s, Optdisc_t* dp)
+{
+ Shell_t *shp = *(Shell_t**)(dp+1);
+ Stk_t *stkp = shp->stk;
+ if(nv_search(s,shp->fun_tree,0))
+ {
+ int savtop = stktell(stkp);
+ char *savptr = stkfreeze(stkp,0);
+ sfputc(stkp,'$');
+ sfputc(stkp,'(');
+ sfputr(stkp,s,')');
+ sfputr(sp,sh_mactry(shp,stkfreeze(stkp,1)),-1);
+ stkset(stkp,savptr,savtop);
+ }
+ return(1);
+}
+
+int b_getopts(int argc,char *argv[],Shbltin_t *context)
+{
+ register char *options=error_info.context->id;
+ register Namval_t *np;
+ register int flag, mode;
+ register Shell_t *shp = context->shp;
+ char value[2], key[2];
+ int jmpval,extended;
+ volatile int r= -1;
+ struct checkpt buff, *pp;
+ struct {
+ Optdisc_t hdr;
+ Shell_t *sh;
+ } disc;
+ memset(&disc, 0, sizeof(disc));
+ disc.hdr.version = OPT_VERSION;
+ disc.hdr.infof = infof;
+ disc.sh = shp;
+ value[1] = 0;
+ key[1] = 0;
+ while((flag = optget(argv,sh_optgetopts))) switch(flag)
+ {
+ case 'a':
+ options = opt_info.arg;
+ break;
+ case ':':
+ errormsg(SH_DICT,2, "%s", opt_info.arg);
+ break;
+ case '?':
+ errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
+ break;
+ }
+ argv += opt_info.index;
+ argc -= opt_info.index;
+ if(error_info.errors || argc<2)
+ errormsg(SH_DICT,ERROR_usage(2), "%s", optusage((char*)0));
+ error_info.context->flags |= ERROR_SILENT;
+ error_info.id = options;
+ options = argv[0];
+ np = nv_open(argv[1],shp->var_tree,NV_NOASSIGN|NV_VARNAME);
+ if(argc>2)
+ {
+ argv +=1;
+ argc -=1;
+ }
+ else
+ {
+ argv = shp->st.dolv;
+ argc = shp->st.dolc;
+ }
+ opt_info.index = shp->st.optindex;
+ opt_info.offset = shp->st.optchar;
+ if(mode= (*options==':'))
+ options++;
+ extended = *options=='\n' && *(options+1)=='[' || *options=='[' && *(options+1)=='-';
+ sh_pushcontext(shp,&buff,1);
+ jmpval = sigsetjmp(buff.buff,0);
+ if(jmpval)
+ {
+ sh_popcontext(shp,&buff);
+ shp->st.opterror = 1;
+ if(r==0)
+ return(2);
+ pp = (struct checkpt*)shp->jmplist;
+ pp->mode = SH_JMPERREXIT;
+ sh_exit(2);
+ }
+ opt_info.disc = &disc.hdr;
+ switch(opt_info.index>=0 && opt_info.index<=argc?(opt_info.num= LONG_MIN,flag=optget(argv,options)):0)
+ {
+ case '?':
+ if(mode==0)
+ errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
+ opt_info.option[1] = '?';
+ /* FALL THRU */
+ case ':':
+ key[0] = opt_info.option[1];
+ if(strmatch(opt_info.arg,"*unknown*"))
+ flag = '?';
+ if(mode)
+ opt_info.arg = key;
+ else
+ {
+ errormsg(SH_DICT,2, "%s", opt_info.arg);
+ opt_info.arg = 0;
+ flag = '?';
+ }
+ *(options = value) = flag;
+ shp->st.opterror = 1;
+ if (opt_info.offset != 0 && !argv[opt_info.index][opt_info.offset])
+ {
+ opt_info.offset = 0;
+ opt_info.index++;
+ }
+ break;
+ case 0:
+ if(shp->st.opterror)
+ {
+ char *com[2];
+ com[0] = "-?";
+ com[1] = 0;
+ flag = opt_info.index;
+ opt_info.index = 0;
+ optget(com,options);
+ opt_info.index = flag;
+ if(!mode && strchr(options,' '))
+ errormsg(SH_DICT,ERROR_usage(2), "%s", optusage((char*)0));
+ }
+ opt_info.arg = 0;
+ options = value;
+ *options = '?';
+ r=1;
+ opt_info.offset = 0;
+ break;
+ default:
+ options = opt_info.option + (*opt_info.option!='+');
+ }
+ if(r<0)
+ r = 0;
+ error_info.context->flags &= ~ERROR_SILENT;
+ shp->st.optindex = opt_info.index;
+ shp->st.optchar = opt_info.offset;
+ nv_putval(np, options, 0);
+ nv_close(np);
+ np = nv_open(nv_name(OPTARGNOD),shp->var_tree,NV_NOSCOPE);
+ if(opt_info.num == LONG_MIN)
+ nv_putval(np, opt_info.arg, NV_RDONLY);
+ 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] != '+')
+ {
+ key[0] = (char)opt_info.num;
+ key[1] = 0;
+ nv_putval(np, key, NV_RDONLY);
+ }
+ else if(extended)
+ {
+ Sfdouble_t d;
+ d = opt_info.number;
+ nv_putval(np, (char*)&d, NV_LDOUBLE|NV_RDONLY);
+ }
+ else
+ nv_putval(np, opt_info.arg, NV_RDONLY);
+ nv_close(np);
+ sh_popcontext(shp,&buff);
+ opt_info.disc = 0;
+ return(r);
+}
+