[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[FDclone-users:00805] Re: configure 時のエラーについて



 しらいです。

In Message-Id <20080629094256.AB91348067A@yuka.unixusers.net>
        Takashi SHIRAI <shirai@unixusers.net>writes:
>  しらいです。

>  尚、FDclone 側の対応は一応考え付く限りやっておきましたので、
> 後で patch を用意する予定です。

 お待たせしました。ようやく用意出来ました。サイズを少しでも
抑えるために [FDclone-users:00799] に対する patch になってい
ます。それでも結構大きいんですが。

 多分、BASHSTYLE を有効にすればどちらの configure も通ると
思います。
 有効にしない場合は、既に解説済の ${} 内の改行と test の ==
のせいで dovecot の方は通りませんが、件の箇所を手で修正すれ
ば大丈夫でしょう。
 configure の挙動は環境依存なので、全ての環境用に検証しきれ
てはいないと思いますが、失敗する script 部分がまだあるようで
したら報告お願いします。

---- Cut Here ----
diff -u old/parse.c ./parse.c
--- old/parse.c	2008-04-02 02:11:52.000000000 +0900
+++ ./parse.c	2008-06-29 19:59:05.000000000 +0900
@@ -709,7 +709,7 @@
 #if	defined (FD) && !defined (DEP_ORIGSHELL)
 	prompt = new = evalpath(cp, EA_NOUNIQDELIM);
 #else
-	prompt = new = evalvararg(cp, '\0', EA_BACKQ | EA_KEEPMETA, 0);
+	prompt = new = evalvararg(cp, EA_BACKQ | EA_KEEPMETA, 0);
 	free2(cp);
 #endif
 	unprint = 0;
diff -u old/pathname.c ./pathname.c
--- old/pathname.c	2008-06-29 19:45:32.000000000 +0900
+++ ./pathname.c	2008-06-29 22:43:45.000000000 +0900
@@ -116,11 +116,13 @@
 static char **NEAR removevar __P_((char **, CONST char *, int, int));
 static char *NEAR evalshellparam __P_((int, int, CONST char *, int, int *));
 #endif	/* !MINIMUMSHELL */
-static int NEAR replacevar __P_((CONST char *, char **,
-		int, int, int, int, int));
+static int NEAR replacevar __P_((CONST char *, char **, int, int, int, int));
 static char *NEAR insertarg __P_((char *, int, CONST char *, int, int));
 static int NEAR evalvar __P_((char **, int, CONST char **, int));
-static char *NEAR replacebackquote __P_((char *, int *, char *, int));
+static char *NEAR replacebackquote __P_((char *, int *, char *, int, int));
+#ifdef	BASHSTYLE
+static VOID replaceifs __P_((char *, int));
+#endif
 #ifndef	MINIMUMSHELL
 static int NEAR evalhome __P_((char **, int, CONST char **));
 #endif
@@ -2044,22 +2046,27 @@
 CONST char *s2;
 int quoted;
 {
-	int i, j, pc, quote;
+	int i, j, c;
 
 	if (!s2) return(0);
+	if (quoted & EA_INQUOTE) quoted |= EA_NOEVALQ;
 	for (i = j = 0; s2[i]; i++, j++) {
-		quote = quoted;
-		pc = parsechar(&(s2[i]), -1, '\0', EA_EOLMETA, &quote, NULL);
-		if (pc == PC_OPQUOTE || pc == PC_CLQUOTE || pc == PC_ESCAPE) {
-			if (s1) s1[j] = PMETA;
-			j++;
-		}
-		else if (pc == PC_WORD) {
-			if (s1) s1[j] = s2[i];
+		c = '\0';
+		if (s2[i] == '\'' && !(quoted & EA_NOEVALQ)) c = PMETA;
+		else if (s2[i] == '"' && !(quoted & EA_NOEVALDQ)) c = PMETA;
+#ifndef	FAKEMETA
+		else if (s2[i] == PMETA && !(quoted & EA_STRIPMETA))
+			c = PMETA;
+#endif
+		else if (iskanji1(s2, i)) c = s2[i++];
+#ifdef	CODEEUC
+		else if (isekana(s2, i)) c = s2[i++];
+#endif
+
+		if (c) {
+			if (s1) s1[j] = c;
 			j++;
-			i++;
 		}
-
 		if (s1) s1[j] = s2[i];
 	}
 
@@ -2228,7 +2235,7 @@
 #endif
 
 	if ((*bufp)[*ptrp] != '{') {
-		if ((*bufp)[*ptrp] != qed) (*ptrp)++;
+		if (!(qed & EA_INQUOTE) || (*bufp)[*ptrp] != '"') (*ptrp)++;
 		if (eolp) *eolp = *ptrp;
 		return(mode);
 	}
@@ -2299,14 +2306,11 @@
 int qed, nonl, nest;
 #endif
 {
-#ifndef	MINIMUMSHELL
-	int tmpq;
-#endif
 #ifdef	NESTINGQUOTE
 	int pq;
 #endif
 	CONST char *cp;
-	int pc, q, len;
+	int pc, q, len, f;
 
 #ifdef	NESTINGQUOTE
 	pq = '\0';
@@ -2314,6 +2318,8 @@
 	q = '\0';
 	len = strlen(next);
 	while (s[*ptrp]) {
+		f = qed;
+		if (q == '"') f |= EA_INQUOTE;
 #ifdef	NESTINGQUOTE
 		pc = parsechar(&(s[*ptrp]), -1, '$', EA_BACKQ, &q, &pq);
 #else
@@ -2323,8 +2329,7 @@
 		else if (pc == '$') {
 			if (!s[++(*ptrp)]) return(0);
 			cp = s;
-			if (skipvar(&cp, NULL, ptrp, (q) ? q : qed) < 0)
-				return(-1);
+			if (skipvar(&cp, NULL, ptrp, f) < 0) return(-1);
 			*ptrp += (cp - s);
 			continue;
 		}
@@ -2332,9 +2337,8 @@
 		else if (nonl && s[*ptrp] == '\n') return(-1);
 #ifndef	MINIMUMSHELL
 		else if (nest && s[*ptrp] == '(') {
-			tmpq = (q) ? q : qed;
 			(*ptrp)++;
-			if (skipvarvalue(s, ptrp, ")", tmpq, nonl, nest) < 0)
+			if (skipvarvalue(s, ptrp, ")", f, nonl, nest) < 0)
 				return(-1);
 			continue;
 		}
@@ -2362,7 +2366,7 @@
 
 	if (!s || !*s) return(NULL);
 	tmp = strndup2(pattern, plen);
-	new = evalarg(tmp, '\0', EA_BACKQ);
+	new = evalarg(tmp, EA_BACKQ);
 	free2(tmp);
 	re = regexp_init(new, -1);
 	free2(new);
@@ -2466,7 +2470,7 @@
 			}
 #endif
 			sp = ' ';
-			if (!quoted) {
+			if (!(quoted & EA_INQUOTE)) {
 				cp = catvar(&(arglist[1]), sp);
 				break;
 			}
@@ -2484,9 +2488,9 @@
 				cp = malloc2(j + 1);
 				j = addmeta(cp, arglist[1], quoted);
 				for (i = 2; arglist[i]; i++) {
-					cp[j++] = quoted;
+					cp[j++] = '"';
 					cp[j++] = sp;
-					cp[j++] = quoted;
+					cp[j++] = '"';
 					j += addmeta(&(cp[j]), arglist[i],
 						quoted);
 				}
@@ -2506,7 +2510,8 @@
 			sp = ' ';
 #ifdef	BASHSTYLE
 	/* bash uses IFS instead of a space as a separator */
-			if (quoted && (cp = getconstvar(ENVIFS)))
+			if ((quoted & EA_INQUOTE)
+			&& (cp = getconstvar(ENVIFS)))
 				sp = (*cp) ? *cp : '\0';
 #endif
 			cp = catvar(&(arglist[1]), sp);
@@ -2549,10 +2554,10 @@
 	return(cp);
 }
 
-static int NEAR replacevar(arg, cpp, s, len, vlen, mode, quoted)
+static int NEAR replacevar(arg, cpp, s, len, vlen, mode)
 CONST char *arg;
 char **cpp;
-int s, len, vlen, mode, quoted;
+int s, len, vlen, mode;
 {
 	char *val;
 	int i;
@@ -2565,7 +2570,7 @@
 	else if (mode == '=' && !isidentchar(*arg)) return(-1);
 
 	val = strndup2(&(arg[s]), vlen);
-	*cpp = evalarg(val, quoted,
+	*cpp = evalarg(val,
 		(mode == '=' || mode == '?')
 		? EA_STRIPQ | EA_BACKQ : EA_BACKQ);
 	free2(val);
@@ -2584,7 +2589,7 @@
 	/* bash does not evaluates a quoted string in substitution itself */
 		free2(*cpp);
 		val = strndup2(&(arg[s]), vlen);
-		*cpp = evalarg(val, quoted, EA_BACKQ);
+		*cpp = evalarg(val, EA_BACKQ);
 		free2(val);
 		if (!*cpp) return(-1);
 # ifdef	FD
@@ -2725,7 +2730,7 @@
 	}
 	else
 #endif	/* !MINIMUMSHELL */
-	if ((mode = replacevar(top, &cp, s, len, vlen, mode, quoted)) < 0) {
+	if ((mode = replacevar(top, &cp, s, len, vlen, mode)) < 0) {
 		free2(new);
 		return(mode);
 	}
@@ -2734,14 +2739,14 @@
 		new = cp;
 	}
 
-	if (!mode && (c != '@' || !quoted)) {
+	if (!mode && (c != '@' || !(quoted & EA_INQUOTE))) {
 		vlen = addmeta(NULL, cp, quoted);
 		*bufp = insertarg(*bufp, ptr, arg, *argp - arg + 1, vlen);
 		addmeta(&((*bufp)[ptr]), cp, quoted);
 	}
 	else if (!cp) vlen = 0;
-	else if (c == '@' && !*cp && quoted
-	&& ptr > 0 && (*bufp)[ptr - 1] == quoted && *(*argp + 1) == quoted) {
+	else if (c == '@' && !*cp && (quoted & EA_INQUOTE)
+	&& ptr > 0 && (*bufp)[ptr - 1] == '"' && *(*argp + 1) == '"') {
 		vlen = 0;
 		ptr--;
 		(*argp)++;
@@ -2951,21 +2956,21 @@
 # endif
 #endif	/* !NOUID */
 
-static char *NEAR replacebackquote(buf, ptrp, bbuf, rest)
+static char *NEAR replacebackquote(buf, ptrp, bbuf, rest, flags)
 char *buf;
 int *ptrp;
 char *bbuf;
-int rest;
+int rest, flags;
 {
 	char *tmp;
 	int len, size;
 
 	stripquote(bbuf, EA_BACKQ);
 	if (!(tmp = (*backquotefunc)(bbuf))) return(buf);
-	len = addmeta(NULL, tmp, '\0');
+	len = addmeta(NULL, tmp, flags);
 	size = *ptrp + len + rest + 1;
 	buf = realloc2(buf, size);
-	addmeta(&(buf[*ptrp]), tmp, '\0');
+	addmeta(&(buf[*ptrp]), tmp, flags);
 	*ptrp += len;
 	free2(tmp);
 
@@ -3029,6 +3034,25 @@
 	return(err);
 }
 
+#ifdef	BASHSTYLE
+static VOID replaceifs(s, len)
+char *s;
+int len;
+{
+	CONST char *ifs;
+	int i;
+
+	if (!(ifs = getconstvar(ENVIFS))) return;
+	for (i = 0; i < len; i++) {
+		if (strchr2(ifs, s[i]) && !strchr2(IFS_SET, s[i])) s[i] = ' ';
+		else if (iskanji1(s, i)) i++;
+# ifdef	CODEEUC
+		else if (isekana(s, i)) i++;
+# endif
+	}
+}
+#endif	/* BASHSTYLE */
+
 #ifndef	MINIMUMSHELL
 static int NEAR evalhome(bufp, ptr, argp)
 char **bufp;
@@ -3097,22 +3121,25 @@
 }
 #endif	/* !MINIMUMSHELL */
 
-char *evalarg(arg, qed, flags)
+char *evalarg(arg, flags)
 char *arg;
-int qed, flags;
+int flags;
 {
 #ifdef	DEP_DOSLFN
 	char path[MAXPATHLEN], alias[MAXPATHLEN];
 #endif
 #ifndef	MINIMUMSHELL
-	int prev;
+	int q2, prev;
 #endif
 #ifdef	NESTINGQUOTE
 	int pq;
 #endif
+#ifdef	BASHSTYLE
+	int top;
+#endif
 	CONST char *cp;
 	char *buf, *bbuf;
-	int i, j, pc, q, tmpq;
+	int i, j, pc, q, f;
 
 #ifdef	DEP_DOSLFN
 	if (*arg == '"' && (i = strlen(arg)) > 2 && arg[i - 1] == '"') {
@@ -3136,7 +3163,7 @@
 	if (!backquotefunc) flags &= ~EA_BACKQ;
 	bbuf = (flags & EA_BACKQ) ? malloc2(i) : NULL;
 #ifndef	MINIMUMSHELL
-	prev =
+	q2 = prev =
 #endif
 #ifdef	NESTINGQUOTE
 	pq =
@@ -3146,6 +3173,9 @@
 	cp = arg;
 
 	while (*cp) {
+#ifdef	BASHSTYLE
+		top = i;
+#endif
 #ifdef	NESTINGQUOTE
 		pc = parsechar(cp, -1, '$', flags, &q, &pq);
 #else
@@ -3155,7 +3185,12 @@
 			if (*cp == '`') {
 				bbuf[j] = '\0';
 				buf = replacebackquote(buf, &i,
-					bbuf, strlen(&(cp[1])));
+					bbuf, strlen(&(cp[1])), flags);
+#ifdef	BASHSTYLE
+	/* bash replaces the IFS character to a space */
+				if (flags & EA_EVALIFS)
+					replaceifs(&(buf[top]), i - top);
+#endif
 				j = 0;
 			}
 			else if (!(flags & EA_STRIPQ)) buf[i++] = *cp;
@@ -3170,10 +3205,16 @@
 				buf[i++] = *cp;
 			}
 		}
-		else if (pc == PC_BQUOTE) bbuf[j++] = *cp;
+		else if (pc == PC_BQUOTE) {
+			bbuf[j++] = *cp;
+#ifndef	MINIMUMSHELL
+			parsechar(cp, -1, '\0', flags, &q2, NULL);
+#endif
+		}
 		else if (pc == PC_SQUOTE || pc == PC_DQUOTE) buf[i++] = *cp;
 		else if (pc == '$') {
-			tmpq = (q) ? q : qed;
+			f = flags;
+			if (q == '"') f |= EA_INQUOTE;
 			if (!cp[1]) buf[i++] = *cp;
 #ifdef	FAKEMETA
 # ifdef	MINIMUMSHELL
@@ -3182,12 +3223,17 @@
 			else if (cp[1] == '$' || cp[1] == '~') cp++;
 # endif
 #endif	/* FAKEMETA */
-			else if ((i = evalvar(&buf, i, &cp, tmpq)) < 0) {
+			else if ((i = evalvar(&buf, i, &cp, f)) < 0) {
 				free2(bbuf);
 				free2(buf);
 				if (i < -1) *arg = '\0';
 				return(NULL);
 			}
+#ifdef	BASHSTYLE
+	/* bash replaces the IFS character to a space */
+			else if (flags & EA_EVALIFS)
+				replaceifs(&(buf[top]), i - top);
+#endif
 		}
 		else if (pc == PC_ESCAPE) {
 			cp++;
@@ -3202,7 +3248,12 @@
 			else pc = PC_NORMAL;
 
 			if (q == '`') {
-				bbuf[j++] = PMETA;
+				if (*cp == '$') /*EMPTY*/;
+#ifndef	MINIMUMSHELL
+				else if (q2 == '\'' && *cp == PMETA)
+					/*EMPTY*/;
+#endif
+				else bbuf[j++] = PMETA;
 				bbuf[j++] = *cp;
 			}
 			else {
@@ -3211,7 +3262,12 @@
 			}
 		}
 		else if (pc == PC_OPQUOTE) {
-			if (*cp == '`') j = 0;
+			if (*cp == '`') {
+				j = 0;
+#ifndef	MINIMUMSHELL
+				q2 = '\0';
+#endif
+			}
 			else if (!(flags & EA_STRIPQ)) buf[i++] = *cp;
 		}
 		else if (pc != PC_NORMAL) /*EMPTY*/;
@@ -3231,7 +3287,7 @@
 	/* bash does not allow unclosed quote */
 	if ((flags & EA_BACKQ) && q == '`') {
 		bbuf[j] = '\0';
-		buf = replacebackquote(buf, &i, bbuf, 0);
+		buf = replacebackquote(buf, &i, bbuf, 0, flags);
 	}
 #endif
 	free2(bbuf);
@@ -3377,7 +3433,8 @@
 	else i = strlen(path);
 	cp = strndup2(path, i);
 
-	if (!(tmp = evalarg(cp, '\'', EA_KEEPMETA))) {
+	tmp = evalarg(cp, EA_NOEVALQ | EA_NOEVALDQ | EA_KEEPMETA);
+	if (!tmp) {
 		*cp = '\0';
 		return(cp);
 	}
diff -u old/pathname.h ./pathname.h
--- old/pathname.h	2008-06-29 19:45:32.000000000 +0900
+++ ./pathname.h	2008-06-29 22:50:52.000000000 +0900
@@ -154,6 +154,8 @@
 #define	EA_EOLMETA		00400
 #define	EA_FINDMETA		01000
 #define	EA_FINDDELIM		02000
+#define	EA_EVALIFS		04000
+#define	EA_INQUOTE		010000
 
 #ifdef	NOUID_T
 typedef u_short			uid_t;
@@ -290,7 +292,7 @@
 #endif	/* !NOUID */
 extern CONST char *gethomedir __P_((VOID_A));
 extern CONST char *getrealpath __P_((CONST char *, char *, char *));
-extern char *evalarg __P_((char *, int, int));
+extern char *evalarg __P_((char *, int));
 extern int evalifs __P_((int, char ***, CONST char *));
 extern int evalglob __P_((int, char ***, int));
 extern int stripquote __P_((char *, int));
diff -u old/posixsh.c ./posixsh.c
--- old/posixsh.c	2008-06-29 19:45:32.000000000 +0900
+++ ./posixsh.c	2008-06-29 20:32:38.000000000 +0900
@@ -779,7 +779,10 @@
 	}
 	else {
 		n = 0L;
-		if (!(cp = evalvararg(new, '\'', EA_BACKQ, 0))) *ptrp = -1;
+		cp = evalvararg(new,
+			EA_STRIPMETA
+			| EA_NOEVALQ | EA_NOEVALDQ | EA_BACKQ, 0);
+		if (!cp) *ptrp = -1;
 		else {
 			for (i = 0; cp[i]; i++)
 				if (!strchr2(IFS_SET, cp[i])) break;
@@ -1314,6 +1317,11 @@
 
 		if (s[0] == '!' && s[1] == '=' && !s[2])
 			ret = (strcmp(a1, a2)) ? RET_SUCCESS : RET_FAIL;
+#ifdef	BASHSTYLE
+	/* bash's "test" allows "==" as same as "=" */
+		else if (s[0] == '=' && s[1] == '=' && !s[2])
+			ret = (!strcmp(a1, a2)) ? RET_SUCCESS : RET_FAIL;
+#endif
 		else if (s[0] == '=' && !s[1])
 			ret = (!strcmp(a1, a2)) ? RET_SUCCESS : RET_FAIL;
 		else if (s[0] == '-') {
diff -u old/system.c ./system.c
--- old/system.c	2008-06-29 19:45:32.000000000 +0900
+++ ./system.c	2008-06-29 20:30:35.000000000 +0900
@@ -656,7 +656,10 @@
 #ifndef	_NOUSEHASH
 static VOID NEAR disphash __P_((VOID_A));
 #endif
-static int NEAR substvar __P_((char **));
+#ifdef	BASHSTYLE
+static char *NEAR quotemeta __P_((char *));
+#endif
+static int NEAR substvar __P_((char **, int));
 static int NEAR evalargv __P_((command_t *, int *, int *));
 static char *NEAR evalexternal __P_((command_t *));
 static VOID NEAR printindent __P_((int, XFILE *));
@@ -1818,7 +1821,7 @@
 
 	if (trapped > 0) {
 		trapmode[sig] |= TR_CATCH;
-		if (havetty() && duptrapok > 0) exectrapcomm();
+		if (duptrapok > 0) exectrapcomm();
 	}
 	else if (trapped < 0 && *(signallist[i].mes)) {
 		Xfputs(signallist[i].mes, Xstderr);
@@ -2171,14 +2174,10 @@
 		return;
 	}
 	duperrno = errno;
-	if (havetty()) {
-		exectrapcomm();
-		if (mypid != orgpid) /*EMPTY*/;
-		else if (!noexit && (trapmode[0] & TR_STAT) == TR_TRAP) {
-			trapmode[0] = 0;
-			if (trapcomm[0] && *(trapcomm[0]))
-				_dosystem(trapcomm[0]);
-		}
+	exectrapcomm();
+	if (mypid == orgpid && !noexit && (trapmode[0] & TR_STAT) == TR_TRAP) {
+		trapmode[0] = 0;
+		if (trapcomm[0] && *(trapcomm[0])) _dosystem(trapcomm[0]);
 	}
 #ifndef	NOJOB
 	if (ttyio >= 0 && ttypgrp >= (p_id_t)0 && oldttypgrp >= (p_id_t)0)
@@ -3004,13 +3003,13 @@
 	return(realloc2(cp, i));
 }
 
-char *evalvararg(arg, quoted, flags, noexit)
+char *evalvararg(arg, flags, noexit)
 char *arg;
-int quoted, flags, noexit;
+int flags, noexit;
 {
 	char *tmp;
 
-	if ((tmp = evalarg(arg, quoted, flags))) return(tmp);
+	if ((tmp = evalarg(arg, flags))) return(tmp);
 #if	defined (BASHSTYLE) && defined (STRICTPOSIX)
 	if (!noexit) noexit = -1;
 #endif
@@ -3657,7 +3656,7 @@
 		}
 
 		if (!(hdp -> flags & HD_QUOTED) && ret == RET_SUCCESS) {
-			cp = evalvararg(buf, '\'',
+			cp = evalvararg(buf,
 				EA_STRIPMETA
 				| EA_NOEVALQ | EA_NOEVALDQ | EA_BACKQ, 1);
 			if (!cp) ret = RET_FAIL;
@@ -3861,8 +3860,7 @@
 	if (!(rp -> filename)) tmp = NULL;
 	else if (type & MD_HEREDOC) tmp = rp -> filename;
 	else {
-		tmp = evalvararg(rp -> filename, '\0',
-			EA_BACKQ | EA_STRIPQLATER, 0);
+		tmp = evalvararg(rp -> filename, EA_BACKQ | EA_STRIPQLATER, 0);
 		if (!tmp) {
 			errno = -1;
 			return(rp);
@@ -4009,7 +4007,7 @@
 #ifndef	BASHSTYLE
 	/* bash allows no variables as the EOF identifier */
 	free2(cp);
-	if (!(cp = evalvararg(eof, '\0', EA_STRIPQLATER, 0))) {
+	if (!(cp = evalvararg(eof, EA_STRIPQLATER, 0))) {
 		errno = -1;
 		return(NULL);
 	}
@@ -5707,6 +5705,9 @@
 
 		if (pc == PC_OPQUOTE || pc == PC_CLQUOTE || pc == PC_SQUOTE)
 			rp -> filename[j++] = s[i];
+#ifdef	BASHSTYLE
+		else if (pc == PC_BQUOTE) rp -> filename[j++] = s[i];
+#endif
 		else if (pc == PC_WORD) {
 			rp -> filename[j++] = s[i++];
 			rp -> filename[j++] = s[i];
@@ -5759,9 +5760,10 @@
 	/* bash treats any meta character in ${} as just a character */
 		else if ((trp -> cont & CN_SBST) == CN_VAR)
 			rp -> filename[j++] = s[i];
+#else
+		else if (pc == PC_BQUOTE) rp -> filename[j++] = s[i];
 #endif
-		else if (pc == PC_DQUOTE || pc == PC_BQUOTE)
-			rp -> filename[j++] = s[i];
+		else if (pc == PC_DQUOTE) rp -> filename[j++] = s[i];
 #ifndef	MINIMUMSHELL
 # ifdef	BASHBUG
 	/* bash cannot include 'case' statement within $() */
@@ -6718,6 +6720,39 @@
 }
 #endif	/* !FDSH && !_NOCOMPLETE */
 
+#ifdef	BASHSTYLE
+static char *NEAR quotemeta(s)
+char *s;
+{
+	char *cp, *buf;
+	ALLOC_T ptr, len;
+
+	cp = strchr(s, '=');
+	if (!cp || !strpbrk(++cp, METACHAR)) return(s);
+	len = strlen(s) + 2;
+	buf = malloc2(len + 1);
+	ptr = cp - s;
+	memcpy(buf, s, ptr);
+	buf[ptr++] = '\'';
+	while (*cp) {
+		if (*cp != '\'') buf[ptr++] = *(cp++);
+		else {
+			len += 3;
+			buf = realloc2(buf, len + 1);
+			buf[ptr++] = '\'';
+			buf[ptr++] = PMETA;
+			buf[ptr++] = *(cp++);
+			buf[ptr++] = '\'';
+		}
+	}
+	buf[ptr++] = '\'';
+	buf[ptr] = '\0';
+	free2(s);
+
+	return(buf);
+}
+#endif	/* BASHSTYLE */
+
 int getsubst(argc, argv, substp, lenp)
 int argc;
 char **argv, ***substp;
@@ -6728,8 +6763,9 @@
 	*substp = (char **)malloc2((argc + 1) * sizeof(char *));
 	*lenp = (int *)malloc2(argc * sizeof(int));
 
+	len = 1;
 	for (i = n = 0; i < argc; i++) {
-		len = (freeenviron || n >= i) ? identcheck(argv[i], '=') : -1;
+		len = (freeenviron || len > 0) ? identcheck(argv[i], '=') : 0;
 		if (len > 0) {
 			(*substp)[n] = argv[i];
 			(*lenp)[n] = len;
@@ -6745,23 +6781,27 @@
 	return(argc);
 }
 
-static int NEAR substvar(argv)
+static int NEAR substvar(argv, flags)
 char **argv;
+int flags;
 {
 	char *tmp, *arg;
 	int i;
 
 	for (i = 0; argv[i]; i++) {
 		if (trapok >= 0) trapok = 1;
-		tmp = evalarg(argv[i], '\0', EA_BACKQ);
+		tmp = evalarg(argv[i], flags);
 		if (trapok >= 0) trapok = 0;
-		if (!tmp && i && *(argv[i])) {
+		if (!tmp) {
 			arg = argv[i];
-			while (argv[i]) i++;
-			freevar(checkshellbuiltinargv(i, duplvar(argv, 2)));
+			if (i && *arg && (flags & EA_EVALIFS)) {
+				while (argv[i]) i++;
+				argv = duplvar(argv, 2);
+				freevar(checkshellbuiltinargv(i, argv));
+			}
 			execerror(NULL, arg, ER_BADSUBST, 0);
+			return(-1);
 		}
-		if (!tmp) return(-1);
 		free2(argv[i]);
 		argv[i] = tmp;
 	}
@@ -6782,12 +6822,13 @@
 		return(comm -> id);
 	}
 
-	if (contp && substvar(comm -> argv) < 0) return(-1);
+	if (contp && substvar(comm -> argv, EA_BACKQ | EA_EVALIFS) < 0)
+		return(-1);
 
 	if (trapok >= 0) trapok = 1;
 #ifdef	BASHSTYLE
 	/* bash does not use IFS as a command separator */
-	comm -> argc = evalifs(comm -> argc, &(comm -> argv), " \t");
+	comm -> argc = evalifs(comm -> argc, &(comm -> argv), IFS_SET);
 #else
 	comm -> argc = evalifs(comm -> argc, &(comm -> argv), getifs());
 #endif
@@ -7545,7 +7586,7 @@
 
 		argv = (char **)malloc2((comm -> argc + 1) * sizeof(char *));
 		for (i = 0; i < comm -> argc; i++) {
-			tmp = evalvararg(comm -> argv[i], '\0', EA_BACKQ, 0);
+			tmp = evalvararg(comm -> argv[i], EA_BACKQ, 0);
 			if (!tmp) {
 				while (--i >= 0) free2(argv[i]);
 				free2(argv);
@@ -7614,7 +7655,7 @@
 
 	var = statementbody(trp);
 	comm = var -> comm;
-	key = evalvararg(comm -> argv[0], '\0', EA_BACKQ | EA_STRIPQLATER, 0);
+	key = evalvararg(comm -> argv[0], EA_BACKQ | EA_STRIPQLATER, 0);
 	if (!key) return(RET_FAIL);
 #ifdef	FD
 	demacroarg(&key);
@@ -7635,7 +7676,7 @@
 		if (!(comm = var -> comm)) break;
 		ret = -1;
 		for (i = 0; i < comm -> argc; i++) {
-			tmp = evalvararg(comm -> argv[i], '\0', EA_BACKQ, 0);
+			tmp = evalvararg(comm -> argv[i], EA_BACKQ, 0);
 			if (!tmp) {
 				ret = RET_FAIL;
 				break;
@@ -8000,6 +8041,10 @@
 		i = countvar(var);
 		if (i > 1) qsort(var, i, sizeof(char *), cmppath);
 		for (i = 0; var[i]; i++) {
+#ifdef	BASHSTYLE
+	/* bash's "set" quotes the value which includes any meta chacters */
+			var[i] = quotemeta(var[i]);
+#endif
 			kanjifputs(var[i], Xstdout);
 			fputnl(Xstdout);
 		}
@@ -9782,7 +9827,7 @@
 	argv = duplvar((trp -> comm) -> argv, 2);
 	argc = getsubst((trp -> comm) -> argc, argv, &subst, &len);
 
-	if (substvar(argv) < 0) ret = -1;
+	if (substvar(argv, EA_BACKQ | EA_EVALIFS) < 0) ret = -1;
 	else {
 		argv = checkshellbuiltinargv(argc, argv);
 		ret = 0;
@@ -9815,9 +9860,6 @@
 	u_long esize;
 	int i, ret, id, type, argc, nsubst, keepvar, *len;
 
-#ifndef	MINIMUMSHELL
-	if (shfunclevel) setshlineno(trp -> lineno);
-#endif
 	isshellbuiltin = execerrno = 0;
 	comm = trp -> comm;
 	argc = comm -> argc;
@@ -9830,9 +9872,7 @@
 	comm -> argc = getsubst(comm -> argc, comm -> argv, &subst, &len);
 
 	id = evalargv(comm, &type, contp);
-	if (subst[0] && type == CT_NONE) ret_status = RET_SUCCESS;
-
-	if (id < 0 || (nsubst = substvar(subst)) < 0) {
+	if (id < 0 || (nsubst = substvar(subst, EA_BACKQ)) < 0) {
 		freevar(subst);
 		free2(len);
 		comm -> argc = argc;
@@ -9840,6 +9880,7 @@
 		comm -> argv = argv;
 		return(RET_FAIL);
 	}
+	if (nsubst > 0 && type == CT_NONE) ret_status = RET_SUCCESS;
 
 	keepvar = 0;
 #ifdef	BASHSTYLE
@@ -9894,7 +9935,7 @@
 # ifdef	FD
 	if ((ps = getconstvar(ENVPS4))) evalprompt(&ps, ps);
 # else
-	if ((ps = getconstvar(ENVPS4))) ps = evalvararg(ps, '\0', EA_BACKQ, 0);
+	if ((ps = getconstvar(ENVPS4))) ps = evalvararg(ps, EA_BACKQ, 0);
 # endif
 #endif	/* !MINIMUMSHELL */
 	while (nsubst--) {
@@ -9987,6 +10028,9 @@
 	p_id_t pid;
 	int bg, sub, stop;
 #endif
+#ifndef	MINIMUMSHELL
+	long dupshlineno;
+#endif
 	syntaxtree *next;
 	int cont, ret;
 
@@ -10048,8 +10092,12 @@
 	else if (next) ret = dosetshfunc((trp -> comm) -> argv[0], next);
 	else for (;;) {
 		cont = 0;
+#ifndef	MINIMUMSHELL
+		dupshlineno = shlineno;
+		setshlineno(trp -> lineno);
+#endif
 #if	MSDOS
-		if ((ret = exec_command(trp, &cont)) < 0) break;
+		ret = exec_command(trp, &cont);
 #else	/* !MSDOS */
 		if (sub) bg = 1;
 # ifndef	USEFAKEPIPE
@@ -10060,8 +10108,12 @@
 # endif
 		else bg = 0;
 
-		if ((ret = exec_command(trp, &cont, bg)) < 0) break;
+		ret = exec_command(trp, &cont, bg);
 #endif	/* !MSDOS */
+#ifndef	MINIMUMSHELL
+		setshlineno(dupshlineno);
+#endif
+		if (ret < 0) break;
 #ifdef	FD
 		if (cont) continue;
 #endif
@@ -10205,7 +10257,7 @@
 				doperror(NULL, NULL);
 			else {
 				if (!(errp -> filename)) tmp = strdup2("-");
-				else tmp = evalvararg(errp -> filename, '\0',
+				else tmp = evalvararg(errp -> filename,
 					EA_BACKQ | EA_STRIPQLATER, 0);
 				if (tmp && !*tmp && *(errp -> filename)) {
 					free2(tmp);
diff -u old/system.h ./system.h
--- old/system.h	2008-06-29 19:45:32.000000000 +0900
+++ ./system.h	2008-06-29 20:26:19.000000000 +0900
@@ -454,7 +454,7 @@
 extern int waitchild __P_((p_id_t, syntaxtree *));
 #endif
 extern VOID setshflag __P_((int, int));
-extern char *evalvararg __P_((char *, int, int, int));
+extern char *evalvararg __P_((char *, int, int));
 extern VOID freeheredoc __P_((heredoc_t *, int));
 extern VOID freerlist __P_((redirectlist *, int));
 extern VOID freecomm __P_((command_t *, int));
---- Cut Here ----

                                               しらい たかし