xref: /titanic_50/usr/src/lib/libshell/common/bltins/cflow.c (revision 4f680cc668fa6cf678c531083400ade9a9c7934c)
1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1982-2008 AT&T Intellectual Property          *
5 *                      and is licensed under the                       *
6 *                  Common Public License, Version 1.0                  *
7 *                    by AT&T Intellectual Property                     *
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  * break [n]
23  * continue [n]
24  * return [n]
25  * exit [n]
26  *
27  *   David Korn
28  *   AT&T Labs
29  *   dgk@research.att.com
30  *
31  */
32 
33 #include	"defs.h"
34 #include	<ast.h>
35 #include	<error.h>
36 #include	<ctype.h>
37 #include	"shnodes.h"
38 #include	"builtins.h"
39 
40 /*
41  * return and exit
42  */
43 #if 0
44     /* for the dictionary generator */
45     int	b_exit(int n, register char *argv[],void *extra){}
46 #endif
47 int	b_return(register int n, register char *argv[],void *extra)
48 {
49 	register char *arg;
50 	register Shell_t *shp = ((Shbltin_t*)extra)->shp;
51 	struct checkpt *pp = (struct checkpt*)shp->jmplist;
52 	const char *options = (**argv=='r'?sh_optreturn:sh_optexit);
53 	while((n = optget(argv,options))) switch(n)
54 	{
55 	    case ':':
56 		if(!strmatch(argv[opt_info.index],"[+-]+([0-9])"))
57 			errormsg(SH_DICT,2, "%s", opt_info.arg);
58 		goto done;
59 	    case '?':
60 		errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
61 		return(2);
62 	}
63 done:
64 	if(error_info.errors)
65 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
66 	pp->mode = (**argv=='e'?SH_JMPEXIT:SH_JMPFUN);
67 	argv += opt_info.index;
68 	n = (((arg= *argv)?(int)strtol(arg, (char**)0, 10):shp->oldexit)&SH_EXITMASK);
69 	/* return outside of function, dotscript and profile is exit */
70 	if(shp->fn_depth==0 && shp->dot_depth==0 && !sh_isstate(SH_PROFILE))
71 		pp->mode = SH_JMPEXIT;
72 	sh_exit(shp->savexit=n);
73 	return(1);
74 }
75 
76 
77 /*
78  * break and continue
79  */
80 #if 0
81     /* for the dictionary generator */
82     int	b_continue(int n, register char *argv[],void *extra){}
83 #endif
84 int	b_break(register int n, register char *argv[],void *extra)
85 {
86 	char *arg;
87 	register int cont= **argv=='c';
88 	register Shell_t *shp = ((Shbltin_t*)extra)->shp;
89 	while((n = optget(argv,cont?sh_optcont:sh_optbreak))) switch(n)
90 	{
91 	    case ':':
92 		errormsg(SH_DICT,2, "%s", opt_info.arg);
93 		break;
94 	    case '?':
95 		errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
96 		return(2);
97 	}
98 	if(error_info.errors)
99 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
100 	argv += opt_info.index;
101 	n=1;
102 	if(arg= *argv)
103 	{
104 		n = strtol(arg,&arg,10);
105 		if(n<=0 || *arg)
106 			errormsg(SH_DICT,ERROR_exit(1),e_nolabels,*argv);
107 	}
108 	if(shp->st.loopcnt)
109 	{
110 		shp->st.execbrk = shp->st.breakcnt = n;
111 		if(shp->st.breakcnt > shp->st.loopcnt)
112 			shp->st.breakcnt = shp->st.loopcnt;
113 		if(cont)
114 			shp->st.breakcnt = -shp->st.breakcnt;
115 	}
116 	return(0);
117 }
118 
119