1N/A/***********************************************************************
1N/A* *
1N/A* This software is part of the ast package *
1N/A* Copyright (c) 1982-2011 AT&T Intellectual Property *
1N/A* and is licensed under the *
1N/A* Common Public License, Version 1.0 *
1N/A* by AT&T Intellectual Property *
1N/A* *
1N/A* A copy of the License is available at *
1N/A* http://www.opensource.org/licenses/cpl1.0.txt *
1N/A* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
1N/A* *
1N/A* Information and Software Systems Research *
1N/A* AT&T Research *
1N/A* Florham Park NJ *
1N/A* *
1N/A* David Korn <dgk@research.att.com> *
1N/A* *
1N/A***********************************************************************/
1N/A#pragma prototyped
1N/A/*
1N/A * break [n]
1N/A * continue [n]
1N/A * return [n]
1N/A * exit [n]
1N/A *
1N/A * David Korn
1N/A * AT&T Labs
1N/A * dgk@research.att.com
1N/A *
1N/A */
1N/A
1N/A#include "defs.h"
1N/A#include <ast.h>
1N/A#include <error.h>
1N/A#include "shnodes.h"
1N/A#include "builtins.h"
1N/A
1N/A/*
1N/A * return and exit
1N/A */
1N/A#if 0
1N/A /* for the dictionary generator */
1N/A int b_exit(int n, register char *argv[],void *extra){}
1N/A#endif
1N/Aint b_return(register int n, register char *argv[],void *extra)
1N/A{
1N/A register char *arg;
1N/A register Shell_t *shp = ((Shbltin_t*)extra)->shp;
1N/A struct checkpt *pp = (struct checkpt*)shp->jmplist;
1N/A const char *options = (**argv=='r'?sh_optreturn:sh_optexit);
1N/A while((n = optget(argv,options))) switch(n)
1N/A {
1N/A case ':':
1N/A if(!strmatch(argv[opt_info.index],"[+-]+([0-9])"))
1N/A errormsg(SH_DICT,2, "%s", opt_info.arg);
1N/A goto done;
1N/A case '?':
1N/A errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
1N/A return(2);
1N/A }
1N/Adone:
1N/A if(error_info.errors)
1N/A errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
1N/A pp->mode = (**argv=='e'?SH_JMPEXIT:SH_JMPFUN);
1N/A argv += opt_info.index;
1N/A n = (((arg= *argv)?(int)strtol(arg, (char**)0, 10)&SH_EXITMASK:shp->oldexit));
1N/A /* return outside of function, dotscript and profile is exit */
1N/A if(shp->fn_depth==0 && shp->dot_depth==0 && !sh_isstate(SH_PROFILE))
1N/A pp->mode = SH_JMPEXIT;
1N/A sh_exit(shp->savexit=n);
1N/A return(1);
1N/A}
1N/A
1N/A
1N/A/*
1N/A * break and continue
1N/A */
1N/A#if 0
1N/A /* for the dictionary generator */
1N/A int b_continue(int n, register char *argv[],void *extra){}
1N/A#endif
1N/Aint b_break(register int n, register char *argv[],void *extra)
1N/A{
1N/A char *arg;
1N/A register int cont= **argv=='c';
1N/A register Shell_t *shp = ((Shbltin_t*)extra)->shp;
1N/A while((n = optget(argv,cont?sh_optcont:sh_optbreak))) switch(n)
1N/A {
1N/A case ':':
1N/A errormsg(SH_DICT,2, "%s", opt_info.arg);
1N/A break;
1N/A case '?':
1N/A errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
1N/A return(2);
1N/A }
1N/A if(error_info.errors)
1N/A errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
1N/A argv += opt_info.index;
1N/A n=1;
1N/A if(arg= *argv)
1N/A {
1N/A n = strtol(arg,&arg,10);
1N/A if(n<=0 || *arg)
1N/A errormsg(SH_DICT,ERROR_exit(1),e_nolabels,*argv);
1N/A }
1N/A if(shp->st.loopcnt)
1N/A {
1N/A shp->st.execbrk = shp->st.breakcnt = n;
1N/A if(shp->st.breakcnt > shp->st.loopcnt)
1N/A shp->st.breakcnt = shp->st.loopcnt;
1N/A if(cont)
1N/A shp->st.breakcnt = -shp->st.breakcnt;
1N/A }
1N/A return(0);
1N/A}
1N/A