implement ksh93 feature ${ foo;}
This commit is contained in:
		
							
								
								
									
										49
									
								
								eval.c
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								eval.c
									
									
									
									
									
								
							| @@ -23,7 +23,7 @@ | ||||
|  | ||||
| #include "sh.h" | ||||
|  | ||||
| __RCSID("$MirOS: src/bin/mksh/eval.c,v 1.122 2012/07/30 17:28:21 tg Exp $"); | ||||
| __RCSID("$MirOS: src/bin/mksh/eval.c,v 1.123 2012/07/30 21:37:11 tg Exp $"); | ||||
|  | ||||
| /* | ||||
|  * string expansion | ||||
| @@ -58,7 +58,7 @@ typedef struct Expand { | ||||
| #define IFS_NWS		2	/* have seen IFS non-white-space */ | ||||
|  | ||||
| static int varsub(Expand *, const char *, const char *, int *, int *); | ||||
| static int comsub(Expand *, const char *); | ||||
| static int comsub(Expand *, const char *, int); | ||||
| static char *trimsub(char *, char *, int); | ||||
| static void glob(char *, XPtrV *, int); | ||||
| static void globit(XString *, char **, char *, XPtrV *, int); | ||||
| @@ -278,17 +278,27 @@ expand(const char *cp,	/* input word */ | ||||
| 				quote = st->quotew; | ||||
| 				continue; | ||||
| 			case COMSUB: | ||||
| 			case FUNSUB: | ||||
| 				tilde_ok = 0; | ||||
| 				if (f & DONTRUNCOMMAND) { | ||||
| 					word = IFS_WORD; | ||||
| 					*dp++ = '$'; *dp++ = '('; | ||||
| 					*dp++ = '$'; | ||||
| 					if (c == FUNSUB) { | ||||
| 						*dp++ = '{'; | ||||
| 						*dp++ = ' '; | ||||
| 					} else | ||||
| 						*dp++ = '('; | ||||
| 					while (*sp != '\0') { | ||||
| 						Xcheck(ds, dp); | ||||
| 						*dp++ = *sp++; | ||||
| 					} | ||||
| 					*dp++ = ')'; | ||||
| 					if (c == FUNSUB) { | ||||
| 						*dp++ = ';'; | ||||
| 						*dp++ = '}'; | ||||
| 					} else | ||||
| 						*dp++ = ')'; | ||||
| 				} else { | ||||
| 					type = comsub(&x, sp); | ||||
| 					type = comsub(&x, sp, c); | ||||
| 					if (type == XCOM && (f&DOBLANK)) | ||||
| 						doblank++; | ||||
| 					sp = strnul(sp) + 1; | ||||
| @@ -611,8 +621,8 @@ expand(const char *cp,	/* input word */ | ||||
| 					case '#': | ||||
| 					case '%': | ||||
| 						/* ! DOBLANK,DOBRACE,DOTILDE */ | ||||
| 						f = DOPAT | (f&DONTRUNCOMMAND) | | ||||
| 						    DOTEMP; | ||||
| 						f = (f & DONTRUNCOMMAND) | | ||||
| 						    DOPAT | DOTEMP; | ||||
| 						st->quotew = quote = 0; | ||||
| 						/* | ||||
| 						 * Prepend open pattern (so | | ||||
| @@ -1272,7 +1282,7 @@ varsub(Expand *xp, const char *sp, const char *word, | ||||
|  * Run the command in $(...) and read its output. | ||||
|  */ | ||||
| static int | ||||
| comsub(Expand *xp, const char *cp) | ||||
| comsub(Expand *xp, const char *cp, int fn) | ||||
| { | ||||
| 	Source *s, *sold; | ||||
| 	struct op *t; | ||||
| @@ -1286,10 +1296,15 @@ comsub(Expand *xp, const char *cp) | ||||
| 	afree(s, ATEMP); | ||||
| 	source = sold; | ||||
|  | ||||
| 	UTFMODE = old_utfmode; | ||||
|  | ||||
| 	if (t == NULL) | ||||
| 		return (XBASE); | ||||
|  | ||||
| 	if (t != NULL && t->type == TCOM && | ||||
| 	/* no waitlast() unless specifically enabled later */ | ||||
| 	xp->split = false; | ||||
|  | ||||
| 	if (t->type == TCOM && | ||||
| 	    *t->args == NULL && *t->vars == NULL && t->ioact != NULL) { | ||||
| 		/* $(<file) */ | ||||
| 		struct ioword *io = *t->ioact; | ||||
| @@ -1302,10 +1317,9 @@ comsub(Expand *xp, const char *cp) | ||||
| 			SHF_MAPHI|SHF_CLEXEC); | ||||
| 		if (shf == NULL) | ||||
| 			errorf("%s: %s %s", name, "can't open", "$() input"); | ||||
| 		/* no waitlast() */ | ||||
| 		xp->split = false; | ||||
| 	} else { | ||||
| 		int ofd1, pv[2]; | ||||
|  | ||||
| 		openpipe(pv); | ||||
| 		shf = shf_fdopen(pv[0], SHF_RD, NULL); | ||||
| 		ofd1 = savefd(1); | ||||
| @@ -1313,14 +1327,16 @@ comsub(Expand *xp, const char *cp) | ||||
| 			ksh_dup2(pv[1], 1, false); | ||||
| 			close(pv[1]); | ||||
| 		} | ||||
| 		execute(t, XFORK|XXCOM|XPIPEO, NULL); | ||||
| 		execute(t, XXCOM | XPIPEO | | ||||
| 		    (fn == FUNSUB ? XERROK : XFORK), NULL); | ||||
| 		restfd(1, ofd1); | ||||
| 		startlast(); | ||||
| 		/* waitlast() */ | ||||
| 		xp->split = true; | ||||
| 		if (fn != FUNSUB) { | ||||
| 			startlast(); | ||||
| 			/* waitlast() */ | ||||
| 			xp->split = true; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	UTFMODE = old_utfmode; | ||||
| 	xp->u.shf = shf; | ||||
| 	return (XCOM); | ||||
| } | ||||
| @@ -1328,7 +1344,6 @@ comsub(Expand *xp, const char *cp) | ||||
| /* | ||||
|  * perform #pattern and %pattern substitution in ${} | ||||
|  */ | ||||
|  | ||||
| static char * | ||||
| trimsub(char *str, char *pat, int how) | ||||
| { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user