svn commit: r293007 - in user/ngie/more-tests2: . bin/sh contrib/binutils/bfd contrib/llvm/patches contrib/llvm/tools/clang/tools/driver lib/libc/stdio lib/libc/sys lib/libmd lib/libstand sbin/rebo...

Garrett Cooper ngie at FreeBSD.org
Thu Dec 31 21:51:40 UTC 2015


Author: ngie
Date: Thu Dec 31 21:51:38 2015
New Revision: 293007
URL: https://svnweb.freebsd.org/changeset/base/293007

Log:
  MFhead @ r293006

Added:
  user/ngie/more-tests2/sys/opencrypto/xform_aes_icm.c
     - copied unchanged from r293006, head/sys/opencrypto/xform_aes_icm.c
  user/ngie/more-tests2/sys/opencrypto/xform_aes_xts.c
     - copied unchanged from r293006, head/sys/opencrypto/xform_aes_xts.c
  user/ngie/more-tests2/sys/opencrypto/xform_auth.h
     - copied unchanged from r293006, head/sys/opencrypto/xform_auth.h
  user/ngie/more-tests2/sys/opencrypto/xform_blf.c
     - copied unchanged from r293006, head/sys/opencrypto/xform_blf.c
  user/ngie/more-tests2/sys/opencrypto/xform_cast5.c
     - copied unchanged from r293006, head/sys/opencrypto/xform_cast5.c
  user/ngie/more-tests2/sys/opencrypto/xform_cml.c
     - copied unchanged from r293006, head/sys/opencrypto/xform_cml.c
  user/ngie/more-tests2/sys/opencrypto/xform_comp.h
     - copied unchanged from r293006, head/sys/opencrypto/xform_comp.h
  user/ngie/more-tests2/sys/opencrypto/xform_deflate.c
     - copied unchanged from r293006, head/sys/opencrypto/xform_deflate.c
  user/ngie/more-tests2/sys/opencrypto/xform_des1.c
     - copied unchanged from r293006, head/sys/opencrypto/xform_des1.c
  user/ngie/more-tests2/sys/opencrypto/xform_des3.c
     - copied unchanged from r293006, head/sys/opencrypto/xform_des3.c
  user/ngie/more-tests2/sys/opencrypto/xform_enc.h
     - copied unchanged from r293006, head/sys/opencrypto/xform_enc.h
  user/ngie/more-tests2/sys/opencrypto/xform_gmac.c
     - copied unchanged from r293006, head/sys/opencrypto/xform_gmac.c
  user/ngie/more-tests2/sys/opencrypto/xform_md5.c
     - copied unchanged from r293006, head/sys/opencrypto/xform_md5.c
  user/ngie/more-tests2/sys/opencrypto/xform_null.c
     - copied unchanged from r293006, head/sys/opencrypto/xform_null.c
  user/ngie/more-tests2/sys/opencrypto/xform_rijndael.c
     - copied unchanged from r293006, head/sys/opencrypto/xform_rijndael.c
  user/ngie/more-tests2/sys/opencrypto/xform_rmd160.c
     - copied unchanged from r293006, head/sys/opencrypto/xform_rmd160.c
  user/ngie/more-tests2/sys/opencrypto/xform_sha1.c
     - copied unchanged from r293006, head/sys/opencrypto/xform_sha1.c
  user/ngie/more-tests2/sys/opencrypto/xform_sha2.c
     - copied unchanged from r293006, head/sys/opencrypto/xform_sha2.c
  user/ngie/more-tests2/sys/opencrypto/xform_skipjack.c
     - copied unchanged from r293006, head/sys/opencrypto/xform_skipjack.c
  user/ngie/more-tests2/sys/opencrypto/xform_userland.h
     - copied unchanged from r293006, head/sys/opencrypto/xform_userland.h
  user/ngie/more-tests2/tests/sys/kern/unix_passfd_test.c
     - copied unchanged from r293006, head/tests/sys/kern/unix_passfd_test.c
  user/ngie/more-tests2/usr.bin/clang/clang/CC.sh
     - copied unchanged from r293006, head/usr.bin/clang/clang/CC.sh
Deleted:
  user/ngie/more-tests2/contrib/llvm/patches/patch-02-add-CC-aliases.diff
  user/ngie/more-tests2/tools/regression/sockets/unix_passfd/
Modified:
  user/ngie/more-tests2/COPYRIGHT
  user/ngie/more-tests2/ObsoleteFiles.inc
  user/ngie/more-tests2/bin/sh/expand.c
  user/ngie/more-tests2/bin/sh/expand.h
  user/ngie/more-tests2/contrib/binutils/bfd/elf32-arm.c
  user/ngie/more-tests2/contrib/llvm/tools/clang/tools/driver/driver.cpp
  user/ngie/more-tests2/lib/libc/stdio/findfp.c
  user/ngie/more-tests2/lib/libc/sys/ptrace.2
  user/ngie/more-tests2/lib/libmd/mdXhl.c
  user/ngie/more-tests2/lib/libstand/Makefile
  user/ngie/more-tests2/sbin/reboot/reboot.c
  user/ngie/more-tests2/sys/arm/arm/locore-v6.S
  user/ngie/more-tests2/sys/arm64/arm64/identcpu.c
  user/ngie/more-tests2/sys/arm64/arm64/mp_machdep.c
  user/ngie/more-tests2/sys/arm64/include/armreg.h
  user/ngie/more-tests2/sys/arm64/include/cpu.h
  user/ngie/more-tests2/sys/boot/forth/loader.conf
  user/ngie/more-tests2/sys/boot/forth/menu-commands.4th
  user/ngie/more-tests2/sys/boot/forth/menu.rc
  user/ngie/more-tests2/sys/boot/forth/support.4th
  user/ngie/more-tests2/sys/boot/i386/loader/main.c
  user/ngie/more-tests2/sys/boot/uboot/common/main.c
  user/ngie/more-tests2/sys/boot/zfs/libzfs.h
  user/ngie/more-tests2/sys/boot/zfs/zfs.c
  user/ngie/more-tests2/sys/boot/zfs/zfsimpl.c
  user/ngie/more-tests2/sys/compat/linuxkpi/common/include/linux/cdev.h
  user/ngie/more-tests2/sys/compat/linuxkpi/common/include/linux/device.h
  user/ngie/more-tests2/sys/compat/linuxkpi/common/include/linux/file.h
  user/ngie/more-tests2/sys/compat/linuxkpi/common/include/linux/kobject.h
  user/ngie/more-tests2/sys/compat/linuxkpi/common/include/linux/miscdevice.h
  user/ngie/more-tests2/sys/compat/linuxkpi/common/src/linux_compat.c
  user/ngie/more-tests2/sys/compat/linuxkpi/common/src/linux_pci.c
  user/ngie/more-tests2/sys/conf/newvers.sh
  user/ngie/more-tests2/sys/crypto/sha1.h
  user/ngie/more-tests2/sys/dev/cxgb/ulp/tom/cxgb_l2t.c
  user/ngie/more-tests2/sys/dev/cxgbe/tom/t4_tom_l2t.c
  user/ngie/more-tests2/sys/dev/mlx5/mlx5_en/en.h
  user/ngie/more-tests2/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
  user/ngie/more-tests2/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
  user/ngie/more-tests2/sys/dev/usb/net/if_axe.c
  user/ngie/more-tests2/sys/dev/usb/usbdevs
  user/ngie/more-tests2/sys/fs/nullfs/null_vnops.c
  user/ngie/more-tests2/sys/kern/kern_fork.c
  user/ngie/more-tests2/sys/kern/kern_ktr.c
  user/ngie/more-tests2/sys/kern/kern_sig.c
  user/ngie/more-tests2/sys/kern/kern_thr.c
  user/ngie/more-tests2/sys/kern/kern_thread.c
  user/ngie/more-tests2/sys/kern/sys_process.c
  user/ngie/more-tests2/sys/net/bpf.c
  user/ngie/more-tests2/sys/net/flowtable.c
  user/ngie/more-tests2/sys/net/if.c
  user/ngie/more-tests2/sys/net/if_ethersubr.c
  user/ngie/more-tests2/sys/net/if_gif.c
  user/ngie/more-tests2/sys/net/if_gre.c
  user/ngie/more-tests2/sys/net/if_llatbl.c
  user/ngie/more-tests2/sys/net/if_llatbl.h
  user/ngie/more-tests2/sys/net/if_var.h
  user/ngie/more-tests2/sys/net/route.h
  user/ngie/more-tests2/sys/netinet/if_ether.c
  user/ngie/more-tests2/sys/netinet/if_ether.h
  user/ngie/more-tests2/sys/netinet/in.c
  user/ngie/more-tests2/sys/netinet/ip_output.c
  user/ngie/more-tests2/sys/netinet/toecore.c
  user/ngie/more-tests2/sys/netinet6/icmp6.c
  user/ngie/more-tests2/sys/netinet6/in6.c
  user/ngie/more-tests2/sys/netinet6/in6.h
  user/ngie/more-tests2/sys/netinet6/ip6_output.c
  user/ngie/more-tests2/sys/netinet6/nd6.c
  user/ngie/more-tests2/sys/netinet6/nd6.h
  user/ngie/more-tests2/sys/netinet6/nd6_nbr.c
  user/ngie/more-tests2/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c
  user/ngie/more-tests2/sys/opencrypto/skipjack.h
  user/ngie/more-tests2/sys/opencrypto/xform.c
  user/ngie/more-tests2/sys/opencrypto/xform.h
  user/ngie/more-tests2/sys/powerpc/booke/booke_machdep.c
  user/ngie/more-tests2/sys/powerpc/booke/locore.S
  user/ngie/more-tests2/sys/powerpc/booke/machdep_e500.c
  user/ngie/more-tests2/sys/powerpc/booke/pmap.c
  user/ngie/more-tests2/sys/powerpc/mpc85xx/mpc85xx.c
  user/ngie/more-tests2/sys/powerpc/mpc85xx/mpc85xx.h
  user/ngie/more-tests2/sys/powerpc/mpc85xx/platform_mpc85xx.c
  user/ngie/more-tests2/sys/sparc64/include/ktr.h
  user/ngie/more-tests2/sys/sparc64/sparc64/exception.S
  user/ngie/more-tests2/sys/sparc64/sparc64/mp_exception.S
  user/ngie/more-tests2/sys/sparc64/sparc64/pmap.c
  user/ngie/more-tests2/sys/sparc64/sparc64/swtch.S
  user/ngie/more-tests2/sys/sys/copyright.h
  user/ngie/more-tests2/sys/sys/param.h
  user/ngie/more-tests2/sys/sys/proc.h
  user/ngie/more-tests2/sys/sys/ptrace.h
  user/ngie/more-tests2/sys/x86/include/specialreg.h
  user/ngie/more-tests2/sys/x86/x86/identcpu.c
  user/ngie/more-tests2/sys/xen/xenbus/xenbusb.c
  user/ngie/more-tests2/tests/sys/kern/Makefile
  user/ngie/more-tests2/tests/sys/kern/ptrace_test.c
  user/ngie/more-tests2/usr.bin/clang/clang/Makefile
  user/ngie/more-tests2/usr.sbin/bhyve/bhyverun.c
  user/ngie/more-tests2/usr.sbin/bhyve/pci_emul.c
  user/ngie/more-tests2/usr.sbin/camdd/camdd.c
  user/ngie/more-tests2/usr.sbin/makefs/makefs.c
Directory Properties:
  user/ngie/more-tests2/   (props changed)
  user/ngie/more-tests2/contrib/binutils/   (props changed)
  user/ngie/more-tests2/contrib/llvm/   (props changed)
  user/ngie/more-tests2/contrib/llvm/tools/clang/   (props changed)
  user/ngie/more-tests2/lib/libc/   (props changed)
  user/ngie/more-tests2/sbin/   (props changed)
  user/ngie/more-tests2/sys/   (props changed)
  user/ngie/more-tests2/sys/boot/   (props changed)
  user/ngie/more-tests2/sys/conf/   (props changed)
  user/ngie/more-tests2/usr.sbin/bhyve/   (props changed)

Modified: user/ngie/more-tests2/COPYRIGHT
==============================================================================
--- user/ngie/more-tests2/COPYRIGHT	Thu Dec 31 21:01:06 2015	(r293006)
+++ user/ngie/more-tests2/COPYRIGHT	Thu Dec 31 21:51:38 2015	(r293007)
@@ -4,7 +4,7 @@
 The compilation of software known as FreeBSD is distributed under the
 following terms:
 
-Copyright (c) 1992-2015 The FreeBSD Project. All rights reserved.
+Copyright (c) 1992-2016 The FreeBSD Project. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions

Modified: user/ngie/more-tests2/ObsoleteFiles.inc
==============================================================================
--- user/ngie/more-tests2/ObsoleteFiles.inc	Thu Dec 31 21:01:06 2015	(r293006)
+++ user/ngie/more-tests2/ObsoleteFiles.inc	Thu Dec 31 21:51:38 2015	(r293007)
@@ -105,6 +105,8 @@ OLD_FILES+=usr/lib/clang/3.7.0/include/x
 OLD_FILES+=usr/lib/clang/3.7.0/include/xtestintrin.h
 OLD_DIRS+=usr/lib/clang/3.7.0/include
 OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.asan-i386.a
+OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.asan-preinit-i386.a
+OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.asan-preinit-x86_64.a
 OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.asan-x86_64.a
 OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.asan_cxx-i386.a
 OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.asan_cxx-x86_64.a

Modified: user/ngie/more-tests2/bin/sh/expand.c
==============================================================================
--- user/ngie/more-tests2/bin/sh/expand.c	Thu Dec 31 21:01:06 2015	(r293006)
+++ user/ngie/more-tests2/bin/sh/expand.c	Thu Dec 31 21:51:38 2015	(r293007)
@@ -3,6 +3,8 @@
  *	The Regents of the University of California.  All rights reserved.
  * Copyright (c) 1997-2005
  *	Herbert Xu <herbert at gondor.apana.org.au>.  All rights reserved.
+ * Copyright (c) 2010-2015
+ *	Jilles Tjoelker <jilles at stack.nl>.  All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * Kenneth Almquist.
@@ -79,41 +81,32 @@ __FBSDID("$FreeBSD$");
 #include "show.h"
 #include "builtins.h"
 
-/*
- * Structure specifying which parts of the string should be searched
- * for IFS characters.
- */
+enum wordstate { WORD_IDLE, WORD_WS_DELIMITED, WORD_QUOTEMARK };
 
-struct ifsregion {
-	struct ifsregion *next;	/* next region in list */
-	int begoff;		/* offset of start of region */
-	int endoff;		/* offset of end of region */
-	int inquotes;		/* search for nul bytes only */
+struct worddest {
+	struct arglist *list;
+	enum wordstate state;
 };
 
-
 static char *expdest;			/* output of current string */
 static struct nodelist *argbackq;	/* list of back quote expressions */
-static struct ifsregion ifsfirst;	/* first struct in list of ifs regions */
-static struct ifsregion *ifslastp;	/* last struct in list */
 
-static char *argstr(char *, int);
+static char *argstr(char *, int, struct worddest *);
 static char *exptilde(char *, int);
-static char *expari(char *);
-static void expbackq(union node *, int, int);
-static int subevalvar(char *, char *, int, int, int, int, int);
-static char *evalvar(char *, int);
+static char *expari(char *, int, struct worddest *);
+static void expbackq(union node *, int, int, struct worddest *);
+static void subevalvar_trim(char *, int, int, int);
+static int subevalvar_misc(char *, const char *, int, int, int);
+static char *evalvar(char *, int, struct worddest *);
 static int varisset(const char *, int);
-static void strtodest(const char *, int, int, int);
-static void varvalue(const char *, int, int, int);
-static void recordregion(int, int, int);
-static void removerecordregions(int);
-static void ifsbreakup(char *, struct arglist *);
-static void expandmeta(struct arglist *, struct arglist *);
+static void strtodest(const char *, int, int, int, struct worddest *);
+static void reprocess(int, int, int, int, struct worddest *);
+static void varvalue(const char *, int, int, int, struct worddest *);
+static void expandmeta(char *, struct arglist *);
 static void expmeta(char *, char *, struct arglist *);
 static int expsortcmp(const void *, const void *);
-static int patmatch(const char *, const char *, int);
-static char *cvtnum(int, char *);
+static int patmatch(const char *, const char *);
+static void cvtnum(int, char *);
 static int collate_range_cmp(wchar_t, wchar_t);
 
 void
@@ -168,6 +161,53 @@ stputs_quotes(const char *data, const ch
 }
 #define STPUTS_QUOTES(data, syntax, p) p = stputs_quotes((data), syntax, p)
 
+static char *
+nextword(char c, int flag, char *p, struct worddest *dst)
+{
+	int is_ws;
+
+	is_ws = c == '\t' || c == '\n' || c == ' ';
+	if (p != stackblock() || (is_ws ? dst->state == WORD_QUOTEMARK :
+	    dst->state != WORD_WS_DELIMITED) || c == '\0') {
+		STPUTC('\0', p);
+		if (flag & EXP_GLOB)
+			expandmeta(grabstackstr(p), dst->list);
+		else
+			appendarglist(dst->list, grabstackstr(p));
+		dst->state = is_ws ? WORD_WS_DELIMITED : WORD_IDLE;
+	} else if (!is_ws && dst->state == WORD_WS_DELIMITED)
+		dst->state = WORD_IDLE;
+	/* Reserve space while the stack string is empty. */
+	appendarglist(dst->list, NULL);
+	dst->list->count--;
+	STARTSTACKSTR(p);
+	return p;
+}
+#define NEXTWORD(c, flag, p, dstlist) p = nextword(c, flag, p, dstlist)
+
+static char *
+stputs_split(const char *data, const char *syntax, int flag, char *p,
+    struct worddest *dst)
+{
+	const char *ifs;
+	char c;
+
+	ifs = ifsset() ? ifsval() : " \t\n";
+	while (*data) {
+		CHECKSTRSPACE(2, p);
+		c = *data++;
+		if (strchr(ifs, c) != NULL) {
+			NEXTWORD(c, flag, p, dst);
+			continue;
+		}
+		if (flag & EXP_GLOB && syntax[(int)c] == CCTL)
+			USTPUTC(CTLESC, p);
+		USTPUTC(c, p);
+	}
+	return (p);
+}
+#define STPUTS_SPLIT(data, syntax, flag, p, dst) p = stputs_split((data), syntax, flag, p, dst)
+
 /*
  * Perform expansions on an argument, placing the resulting list of arguments
  * in arglist.  Parameter expansion, command substitution and arithmetic
@@ -183,34 +223,31 @@ stputs_quotes(const char *data, const ch
 void
 expandarg(union node *arg, struct arglist *arglist, int flag)
 {
-	struct arglist exparg;
-	char *p;
+	struct worddest exparg;
 
+	if (fflag)
+		flag &= ~EXP_GLOB;
 	argbackq = arg->narg.backquote;
+	exparg.list = arglist;
+	exparg.state = WORD_IDLE;
 	STARTSTACKSTR(expdest);
-	ifsfirst.next = NULL;
-	ifslastp = NULL;
-	argstr(arg->narg.text, flag);
+	argstr(arg->narg.text, flag, &exparg);
 	if (arglist == NULL) {
 		STACKSTRNUL(expdest);
 		return;			/* here document expanded */
 	}
-	STPUTC('\0', expdest);
-	p = grabstackstr(expdest);
-	emptyarglist(&exparg);
-	if (flag & EXP_FULL) {
-		ifsbreakup(p, &exparg);
-		expandmeta(&exparg, arglist);
-	} else
-		appendarglist(arglist, p);
-	while (ifsfirst.next != NULL) {
-		struct ifsregion *ifsp;
-		INTOFF;
-		ifsp = ifsfirst.next->next;
-		ckfree(ifsfirst.next);
-		ifsfirst.next = ifsp;
-		INTON;
+	if ((flag & EXP_SPLIT) == 0 || expdest != stackblock() ||
+	    exparg.state == WORD_QUOTEMARK) {
+		STPUTC('\0', expdest);
+		if (flag & EXP_SPLIT) {
+			if (flag & EXP_GLOB)
+				expandmeta(grabstackstr(expdest), exparg.list);
+			else
+				appendarglist(exparg.list, grabstackstr(expdest));
+		}
 	}
+	if ((flag & EXP_SPLIT) == 0)
+		appendarglist(arglist, grabstackstr(expdest));
 }
 
 
@@ -220,15 +257,16 @@ expandarg(union node *arg, struct arglis
  * expansion, and tilde expansion if requested via EXP_TILDE/EXP_VARTILDE.
  * Processing ends at a CTLENDVAR or CTLENDARI character as well as '\0'.
  * This is used to expand word in ${var+word} etc.
- * If EXP_FULL or EXP_CASE are set, keep and/or generate CTLESC
+ * If EXP_GLOB or EXP_CASE are set, keep and/or generate CTLESC
  * characters to allow for further processing.
- * If EXP_FULL is set, also preserve CTLQUOTEMARK characters.
+ *
+ * If EXP_SPLIT is set, dst receives any complete words produced.
  */
 static char *
-argstr(char *p, int flag)
+argstr(char *p, int flag, struct worddest *dst)
 {
 	char c;
-	int quotes = flag & (EXP_FULL | EXP_CASE);	/* do CTLESC */
+	int quotes = flag & (EXP_GLOB | EXP_CASE);	/* do CTLESC */
 	int firsteq = 1;
 	int split_lit;
 	int lit_quoted;
@@ -252,32 +290,33 @@ argstr(char *p, int flag)
 			if (p[0] == CTLVAR && (p[1] & VSQUOTE) != 0 &&
 			    p[2] == '@' && p[3] == '=')
 				break;
-			if ((flag & EXP_FULL) != 0)
-				USTPUTC(c, expdest);
+			if ((flag & EXP_SPLIT) != 0 && expdest == stackblock())
+				dst->state = WORD_QUOTEMARK;
 			break;
 		case CTLQUOTEEND:
 			lit_quoted = 0;
 			break;
 		case CTLESC:
-			if (quotes)
-				USTPUTC(c, expdest);
 			c = *p++;
+			if (split_lit && !lit_quoted &&
+			    strchr(ifsset() ? ifsval() : " \t\n", c) != NULL) {
+				NEXTWORD(c, flag, expdest, dst);
+				break;
+			}
+			if (quotes)
+				USTPUTC(CTLESC, expdest);
 			USTPUTC(c, expdest);
-			if (split_lit && !lit_quoted)
-				recordregion(expdest - stackblock() -
-				    (quotes ? 2 : 1),
-				    expdest - stackblock(), 0);
 			break;
 		case CTLVAR:
-			p = evalvar(p, flag);
+			p = evalvar(p, flag, dst);
 			break;
 		case CTLBACKQ:
 		case CTLBACKQ|CTLQUOTE:
-			expbackq(argbackq->n, c & CTLQUOTE, flag);
+			expbackq(argbackq->n, c & CTLQUOTE, flag, dst);
 			argbackq = argbackq->next;
 			break;
 		case CTLARI:
-			p = expari(p);
+			p = expari(p, flag, dst);
 			break;
 		case ':':
 		case '=':
@@ -285,10 +324,12 @@ argstr(char *p, int flag)
 			 * sort of a hack - expand tildes in variable
 			 * assignments (after the first '=' and after ':'s).
 			 */
+			if (split_lit && !lit_quoted &&
+			    strchr(ifsset() ? ifsval() : " \t\n", c) != NULL) {
+				NEXTWORD(c, flag, expdest, dst);
+				break;
+			}
 			USTPUTC(c, expdest);
-			if (split_lit && !lit_quoted)
-				recordregion(expdest - stackblock() - 1,
-				    expdest - stackblock(), 0);
 			if (flag & EXP_VARTILDE && *p == '~' &&
 			    (c != '=' || firsteq)) {
 				if (c == '=')
@@ -297,10 +338,12 @@ argstr(char *p, int flag)
 			}
 			break;
 		default:
+			if (split_lit && !lit_quoted &&
+			    strchr(ifsset() ? ifsval() : " \t\n", c) != NULL) {
+				NEXTWORD(c, flag, expdest, dst);
+				break;
+			}
 			USTPUTC(c, expdest);
-			if (split_lit && !lit_quoted)
-				recordregion(expdest - stackblock() - 1,
-				    expdest - stackblock(), 0);
 		}
 	}
 }
@@ -344,7 +387,7 @@ exptilde(char *p, int flag)
 			*p = c;
 			if (home == NULL || *home == '\0')
 				return (startp);
-			strtodest(home, flag, VSNORMAL, 1);
+			strtodest(home, flag, VSNORMAL, 1, NULL);
 			return (p);
 		}
 		p++;
@@ -352,51 +395,11 @@ exptilde(char *p, int flag)
 }
 
 
-static void
-removerecordregions(int endoff)
-{
-	if (ifslastp == NULL)
-		return;
-
-	if (ifsfirst.endoff > endoff) {
-		while (ifsfirst.next != NULL) {
-			struct ifsregion *ifsp;
-			INTOFF;
-			ifsp = ifsfirst.next->next;
-			ckfree(ifsfirst.next);
-			ifsfirst.next = ifsp;
-			INTON;
-		}
-		if (ifsfirst.begoff > endoff)
-			ifslastp = NULL;
-		else {
-			ifslastp = &ifsfirst;
-			ifsfirst.endoff = endoff;
-		}
-		return;
-	}
-
-	ifslastp = &ifsfirst;
-	while (ifslastp->next && ifslastp->next->begoff < endoff)
-		ifslastp=ifslastp->next;
-	while (ifslastp->next != NULL) {
-		struct ifsregion *ifsp;
-		INTOFF;
-		ifsp = ifslastp->next->next;
-		ckfree(ifslastp->next);
-		ifslastp->next = ifsp;
-		INTON;
-	}
-	if (ifslastp->endoff > endoff)
-		ifslastp->endoff = endoff;
-}
-
 /*
  * Expand arithmetic expression.
- * Note that flag is not required as digits never require CTLESC characters.
  */
 static char *
-expari(char *p)
+expari(char *p, int flag, struct worddest *dst)
 {
 	char *q, *start;
 	arith_t result;
@@ -406,8 +409,7 @@ expari(char *p)
 
 	quoted = *p++ == '"';
 	begoff = expdest - stackblock();
-	p = argstr(p, 0);
-	removerecordregions(begoff);
+	p = argstr(p, 0, NULL);
 	STPUTC('\0', expdest);
 	start = stackblock() + begoff;
 
@@ -424,7 +426,7 @@ expari(char *p)
 	adj = strlen(expdest);
 	STADJUST(adj, expdest);
 	if (!quoted)
-		recordregion(begoff, expdest - stackblock(), 0);
+		reprocess(expdest - adj - stackblock(), flag, VSNORMAL, 0, dst);
 	return p;
 }
 
@@ -433,35 +435,34 @@ expari(char *p)
  * Perform command substitution.
  */
 static void
-expbackq(union node *cmd, int quoted, int flag)
+expbackq(union node *cmd, int quoted, int flag, struct worddest *dst)
 {
 	struct backcmd in;
 	int i;
 	char buf[128];
 	char *p;
 	char *dest = expdest;
-	struct ifsregion saveifs, *savelastp;
 	struct nodelist *saveargbackq;
 	char lastc;
-	int startloc = dest - stackblock();
 	char const *syntax = quoted? DQSYNTAX : BASESYNTAX;
-	int quotes = flag & (EXP_FULL | EXP_CASE);
+	int quotes = flag & (EXP_GLOB | EXP_CASE);
 	size_t nnl;
+	const char *ifs;
 
 	INTOFF;
-	saveifs = ifsfirst;
-	savelastp = ifslastp;
 	saveargbackq = argbackq;
 	p = grabstackstr(dest);
 	evalbackcmd(cmd, &in);
 	ungrabstackstr(p, dest);
-	ifsfirst = saveifs;
-	ifslastp = savelastp;
 	argbackq = saveargbackq;
 
 	p = in.buf;
 	lastc = '\0';
 	nnl = 0;
+	if (!quoted && flag & EXP_SPLIT)
+		ifs = ifsset() ? ifsval() : " \t\n";
+	else
+		ifs = "";
 	/* Don't copy trailing newlines */
 	for (;;) {
 		if (--in.nleft < 0) {
@@ -475,15 +476,27 @@ expbackq(union node *cmd, int quoted, in
 			in.nleft = i - 1;
 		}
 		lastc = *p++;
-		if (lastc != '\0') {
-			if (lastc == '\n') {
-				nnl++;
-			} else {
-				CHECKSTRSPACE(nnl + 2, dest);
-				while (nnl > 0) {
-					nnl--;
-					USTPUTC('\n', dest);
+		if (lastc == '\0')
+			continue;
+		if (lastc == '\n') {
+			nnl++;
+		} else {
+			if (nnl > 0) {
+				if (strchr(ifs, '\n') != NULL) {
+					NEXTWORD('\n', flag, dest, dst);
+					nnl = 0;
+				} else {
+					CHECKSTRSPACE(nnl + 2, dest);
+					while (nnl > 0) {
+						nnl--;
+						USTPUTC('\n', dest);
+					}
 				}
+			}
+			if (strchr(ifs, lastc) != NULL)
+				NEXTWORD(lastc, flag, dest, dst);
+			else {
+				CHECKSTRSPACE(2, dest);
 				if (quotes && syntax[(int)lastc] == CCTL)
 					USTPUTC(CTLESC, dest);
 				USTPUTC(lastc, dest);
@@ -497,8 +510,6 @@ expbackq(union node *cmd, int quoted, in
 		ckfree(in.buf);
 	if (in.jp)
 		exitstatus = waitforjob(in.jp, (int *)NULL);
-	if (quoted == 0)
-		recordregion(startloc, dest - stackblock(), 0);
 	TRACE(("expbackq: size=%td: \"%.*s\"\n",
 		((dest - stackblock()) - startloc),
 		(int)((dest - stackblock()) - startloc),
@@ -520,113 +531,112 @@ recordleft(const char *str, const char *
 		*startp++ = *loc++;
 }
 
-static int
-subevalvar(char *p, char *str, int strloc, int subtype, int startloc,
-  int varflags, int quotes)
+static void
+subevalvar_trim(char *p, int strloc, int subtype, int startloc)
 {
 	char *startp;
 	char *loc = NULL;
-	char *q;
+	char *str;
 	int c = 0;
 	struct nodelist *saveargbackq = argbackq;
 	int amount;
 
-	argstr(p, (subtype == VSTRIMLEFT || subtype == VSTRIMLEFTMAX ||
-	    subtype == VSTRIMRIGHT || subtype == VSTRIMRIGHTMAX ?
-	    EXP_CASE : 0) | EXP_TILDE);
+	argstr(p, EXP_CASE | EXP_TILDE, NULL);
 	STACKSTRNUL(expdest);
 	argbackq = saveargbackq;
 	startp = stackblock() + startloc;
-	if (str == NULL)
-	    str = stackblock() + strloc;
+	str = stackblock() + strloc;
 
 	switch (subtype) {
-	case VSASSIGN:
-		setvar(str, startp, 0);
-		amount = startp - expdest;
-		STADJUST(amount, expdest);
-		varflags &= ~VSNUL;
-		return 1;
-
-	case VSQUESTION:
-		if (*p != CTLENDVAR) {
-			outfmt(out2, "%s\n", startp);
-			error((char *)NULL);
-		}
-		error("%.*s: parameter %snot set", (int)(p - str - 1),
-		      str, (varflags & VSNUL) ? "null or " : "");
-		return 0;
-
 	case VSTRIMLEFT:
 		for (loc = startp; loc < str; loc++) {
 			c = *loc;
 			*loc = '\0';
-			if (patmatch(str, startp, quotes)) {
+			if (patmatch(str, startp)) {
 				*loc = c;
 				recordleft(str, loc, startp);
-				return 1;
+				return;
 			}
 			*loc = c;
-			if (quotes && *loc == CTLESC)
-				loc++;
 		}
-		return 0;
+		break;
 
 	case VSTRIMLEFTMAX:
 		for (loc = str - 1; loc >= startp;) {
 			c = *loc;
 			*loc = '\0';
-			if (patmatch(str, startp, quotes)) {
+			if (patmatch(str, startp)) {
 				*loc = c;
 				recordleft(str, loc, startp);
-				return 1;
+				return;
 			}
 			*loc = c;
 			loc--;
-			if (quotes && loc > startp && *(loc - 1) == CTLESC) {
-				for (q = startp; q < loc; q++)
-					if (*q == CTLESC)
-						q++;
-				if (q > loc)
-					loc--;
-			}
 		}
-		return 0;
+		break;
 
 	case VSTRIMRIGHT:
 		for (loc = str - 1; loc >= startp;) {
-			if (patmatch(str, loc, quotes)) {
+			if (patmatch(str, loc)) {
 				amount = loc - expdest;
 				STADJUST(amount, expdest);
-				return 1;
+				return;
 			}
 			loc--;
-			if (quotes && loc > startp && *(loc - 1) == CTLESC) {
-				for (q = startp; q < loc; q++)
-					if (*q == CTLESC)
-						q++;
-				if (q > loc)
-					loc--;
-			}
 		}
-		return 0;
+		break;
 
 	case VSTRIMRIGHTMAX:
 		for (loc = startp; loc < str - 1; loc++) {
-			if (patmatch(str, loc, quotes)) {
+			if (patmatch(str, loc)) {
 				amount = loc - expdest;
 				STADJUST(amount, expdest);
-				return 1;
+				return;
 			}
-			if (quotes && *loc == CTLESC)
-				loc++;
 		}
-		return 0;
+		break;
 
 
 	default:
 		abort();
 	}
+	amount = (expdest - stackblock() - strloc) + 1;
+	STADJUST(-amount, expdest);
+}
+
+
+static int
+subevalvar_misc(char *p, const char *var, int subtype, int startloc,
+  int varflags)
+{
+	char *startp;
+	struct nodelist *saveargbackq = argbackq;
+	int amount;
+
+	argstr(p, EXP_TILDE, NULL);
+	STACKSTRNUL(expdest);
+	argbackq = saveargbackq;
+	startp = stackblock() + startloc;
+
+	switch (subtype) {
+	case VSASSIGN:
+		setvar(var, startp, 0);
+		amount = startp - expdest;
+		STADJUST(amount, expdest);
+		return 1;
+
+	case VSQUESTION:
+		if (*p != CTLENDVAR) {
+			outfmt(out2, "%s\n", startp);
+			error((char *)NULL);
+		}
+		error("%.*s: parameter %snot set", (int)(p - var - 1),
+		      var, (varflags & VSNUL) ? "null or " : "");
+		return 0;
+
+	default:
+		abort();
+	}
 }
 
 
@@ -636,7 +646,7 @@ subevalvar(char *p, char *str, int strlo
  */
 
 static char *
-evalvar(char *p, int flag)
+evalvar(char *p, int flag, struct worddest *dst)
 {
 	int subtype;
 	int varflags;
@@ -649,9 +659,7 @@ evalvar(char *p, int flag)
 	int startloc;
 	int varlen;
 	int varlenb;
-	int easy;
-	int quotes = flag & (EXP_FULL | EXP_CASE);
-	int record = 0;
+	char buf[21];
 
 	varflags = (unsigned char)*p++;
 	subtype = varflags & VSTYPE;
@@ -693,10 +701,16 @@ again: /* jump here after setting a vari
 	if (set && subtype != VSPLUS) {
 		/* insert the value of the variable */
 		if (special) {
-			if (varflags & VSLINENO)
-				STPUTBIN(var, p - var - 1, expdest);
-			else
-				varvalue(var, varflags & VSQUOTE, subtype, flag);
+			if (varflags & VSLINENO) {
+				if (p - var > (ptrdiff_t)sizeof(buf))
+					abort();
+				memcpy(buf, var, p - var - 1);
+				buf[p - var - 1] = '\0';
+				strtodest(buf, flag, subtype,
+				    varflags & VSQUOTE, dst);
+			} else
+				varvalue(var, varflags & VSQUOTE, subtype, flag,
+				    dst);
 			if (subtype == VSLENGTH) {
 				varlenb = expdest - stackblock() - startloc;
 				varlen = varlenb;
@@ -717,35 +731,29 @@ again: /* jump here after setting a vari
 			}
 			else
 				strtodest(val, flag, subtype,
-				    varflags & VSQUOTE);
+				    varflags & VSQUOTE, dst);
 		}
 	}
 
 	if (subtype == VSPLUS)
 		set = ! set;
 
-	easy = ((varflags & VSQUOTE) == 0 ||
-		(*var == '@' && shellparam.nparam != 1));
-
-
 	switch (subtype) {
 	case VSLENGTH:
-		expdest = cvtnum(varlen, expdest);
-		record = 1;
+		cvtnum(varlen, buf);
+		strtodest(buf, flag, VSNORMAL, varflags & VSQUOTE, dst);
 		break;
 
 	case VSNORMAL:
-		record = easy;
 		break;
 
 	case VSPLUS:
 	case VSMINUS:
 		if (!set) {
-			argstr(p, flag | (flag & EXP_FULL ? EXP_SPLIT_LIT : 0) |
-			    (varflags & VSQUOTE ? EXP_LIT_QUOTED : 0));
+			argstr(p, flag | (flag & EXP_SPLIT ? EXP_SPLIT_LIT : 0) |
+			    (varflags & VSQUOTE ? EXP_LIT_QUOTED : 0), dst);
 			break;
 		}
-		record = easy;
 		break;
 
 	case VSTRIMLEFT:
@@ -760,32 +768,22 @@ again: /* jump here after setting a vari
 		 */
 		STPUTC('\0', expdest);
 		patloc = expdest - stackblock();
-		if (subevalvar(p, NULL, patloc, subtype,
-		    startloc, varflags, quotes) == 0) {
-			int amount = (expdest - stackblock() - patloc) + 1;
-			STADJUST(-amount, expdest);
-		}
-		/* Remove any recorded regions beyond start of variable */
-		removerecordregions(startloc);
-		record = 1;
+		subevalvar_trim(p, patloc, subtype, startloc);
+		reprocess(startloc, flag, VSNORMAL, varflags & VSQUOTE, dst);
+		if (flag & EXP_SPLIT && *var == '@' && varflags & VSQUOTE)
+			dst->state = WORD_QUOTEMARK;
 		break;
 
 	case VSASSIGN:
 	case VSQUESTION:
 		if (!set) {
-			if (subevalvar(p, var, 0, subtype, startloc, varflags,
-			    quotes)) {
+			if (subevalvar_misc(p, var, subtype, startloc,
+			    varflags)) {
 				varflags &= ~VSNUL;
-				/*
-				 * Remove any recorded regions beyond
-				 * start of variable
-				 */
-				removerecordregions(startloc);
 				goto again;
 			}
 			break;
 		}
-		record = easy;
 		break;
 
 	case VSERROR:
@@ -797,11 +795,6 @@ again: /* jump here after setting a vari
 		abort();
 	}
 
-	if (record)
-		recordregion(startloc, expdest - stackblock(),
-		    varflags & VSQUOTE || (ifsset() && ifsval()[0] == '\0' &&
-		    (*var == '@' || *var == '*')));
-
 	if (subtype != VSNORMAL) {	/* skip to end of alternative */
 		int nesting = 1;
 		for (;;) {
@@ -867,26 +860,80 @@ varisset(const char *name, int nulok)
 }
 
 static void
-strtodest(const char *p, int flag, int subtype, int quoted)
+strtodest(const char *p, int flag, int subtype, int quoted,
+    struct worddest *dst)
 {
-	if (flag & (EXP_FULL | EXP_CASE) && subtype != VSLENGTH)
+	if (subtype == VSLENGTH || subtype == VSTRIMLEFT ||
+	    subtype == VSTRIMLEFTMAX || subtype == VSTRIMRIGHT ||
+	    subtype == VSTRIMRIGHTMAX)
+		STPUTS(p, expdest);
+	else if (flag & EXP_SPLIT && !quoted && dst != NULL)
+		STPUTS_SPLIT(p, BASESYNTAX, flag, expdest, dst);
+	else if (flag & (EXP_GLOB | EXP_CASE))
 		STPUTS_QUOTES(p, quoted ? DQSYNTAX : BASESYNTAX, expdest);
 	else
 		STPUTS(p, expdest);
 }
 
+static void
+reprocess(int startloc, int flag, int subtype, int quoted,
+    struct worddest *dst)
+{
+	static char *buf = NULL;
+	static size_t buflen = 0;
+	char *startp;
+	size_t len, zpos, zlen;
+
+	startp = stackblock() + startloc;
+	len = expdest - startp;
+	if (len >= SIZE_MAX / 2)
+		abort();
+	INTOFF;
+	if (len >= buflen) {
+		ckfree(buf);
+		buf = NULL;
+	}
+	if (buflen < 128)
+		buflen = 128;
+	while (len >= buflen)
+		buflen <<= 1;
+	if (buf == NULL)
+		buf = ckmalloc(buflen);
+	INTON;
+	memcpy(buf, startp, len);
+	buf[len] = '\0';
+	STADJUST(-len, expdest);
+	for (zpos = 0;;) {
+		zlen = strlen(buf + zpos);
+		strtodest(buf + zpos, flag, subtype, quoted, dst);
+		zpos += zlen + 1;
+		if (zpos == len + 1)
+			break;
+		if (flag & EXP_SPLIT && (quoted || (zlen > 0 && zpos < len)))
+			NEXTWORD('\0', flag, expdest, dst);
+	}
+}
+
 /*
  * Add the value of a specialized variable to the stack string.
  */
 
 static void
-varvalue(const char *name, int quoted, int subtype, int flag)
+varvalue(const char *name, int quoted, int subtype, int flag,
+    struct worddest *dst)
 {
 	int num;
 	char *p;
 	int i;
+	int splitlater;
 	char sep[2];
 	char **ap;
+	char buf[(NSHORTOPTS > 10 ? NSHORTOPTS : 10) + 1];
+
+	if (subtype == VSLENGTH)
+		flag &= ~EXP_FULL;
+	splitlater = subtype == VSTRIMLEFT || subtype == VSTRIMLEFTMAX ||
+		subtype == VSTRIMRIGHT || subtype == VSTRIMRIGHTMAX;
 
 	switch (*name) {
 	case '$':
@@ -902,18 +949,28 @@ varvalue(const char *name, int quoted, i
 		num = backgndpidval();
 		break;
 	case '-':
+		p = buf;
 		for (i = 0 ; i < NSHORTOPTS ; i++) {
 			if (optlist[i].val)
-				STPUTC(optlist[i].letter, expdest);
+				*p++ = optlist[i].letter;
 		}
+		*p = '\0';
+		strtodest(buf, flag, subtype, quoted, dst);
 		return;
 	case '@':
-		if (flag & EXP_FULL && quoted) {
+		if (flag & EXP_SPLIT && quoted) {
 			for (ap = shellparam.p ; (p = *ap++) != NULL ; ) {
-				strtodest(p, flag, subtype, quoted);
-				if (*ap)
-					STPUTC('\0', expdest);
+				strtodest(p, flag, subtype, quoted, dst);
+				if (*ap) {
+					if (splitlater)
+						STPUTC('\0', expdest);
+					else
+						NEXTWORD('\0', flag, expdest,
+						    dst);
+				}
 			}
+			if (shellparam.nparam > 0)
+				dst->state = WORD_QUOTEMARK;
 			return;
 		}
 		/* FALLTHROUGH */
@@ -924,13 +981,17 @@ varvalue(const char *name, int quoted, i
 			sep[0] = ' ';
 		sep[1] = '\0';
 		for (ap = shellparam.p ; (p = *ap++) != NULL ; ) {
-			strtodest(p, flag, subtype, quoted);
+			strtodest(p, flag, subtype, quoted, dst);
 			if (!*ap)
 				break;
 			if (sep[0])
-				strtodest(sep, flag, subtype, quoted);
-			else if (flag & EXP_FULL && !quoted && **ap != '\0')
-				STPUTC('\0', expdest);
+				strtodest(sep, flag, subtype, quoted, dst);
+			else if (flag & EXP_SPLIT && !quoted && **ap != '\0') {
+				if (splitlater)
+					STPUTC('\0', expdest);
+				else
+					NEXTWORD('\0', flag, expdest, dst);
+			}
 		}
 		return;
 	default:
@@ -942,192 +1003,53 @@ varvalue(const char *name, int quoted, i
 				p = shellparam.p[num - 1];
 			else
 				return;
-			strtodest(p, flag, subtype, quoted);
+			strtodest(p, flag, subtype, quoted, dst);
 		}
 		return;
 	}
-	expdest = cvtnum(num, expdest);
-}
-
-
-
-/*
- * Record the fact that we have to scan this region of the
- * string for IFS characters.
- */
-
-static void
-recordregion(int start, int end, int inquotes)
-{
-	struct ifsregion *ifsp;
-
-	INTOFF;
-	if (ifslastp == NULL) {
-		ifsp = &ifsfirst;
-	} else {
-		if (ifslastp->endoff == start
-		    && ifslastp->inquotes == inquotes) {
-			/* extend previous area */
-			ifslastp->endoff = end;
-			INTON;
-			return;
-		}
-		ifsp = (struct ifsregion *)ckmalloc(sizeof (struct ifsregion));
-		ifslastp->next = ifsp;
-	}
-	ifslastp = ifsp;
-	ifslastp->next = NULL;
-	ifslastp->begoff = start;
-	ifslastp->endoff = end;
-	ifslastp->inquotes = inquotes;
-	INTON;
+	cvtnum(num, buf);
+	strtodest(buf, flag, subtype, quoted, dst);
 }
 
 
 
-/*
- * Break the argument string into pieces based upon IFS and add the
- * strings to the argument list.  The regions of the string to be
- * searched for IFS characters have been stored by recordregion.
- * CTLESC characters are preserved but have little effect in this pass
- * other than escaping CTL* characters.  In particular, they do not escape
- * IFS characters: that should be done with the ifsregion mechanism.
- * CTLQUOTEMARK characters are used to preserve empty quoted strings.
- * This pass treats them as a regular character, making the string non-empty.
- * Later, they are removed along with the other CTL* characters.
- */
-static void
-ifsbreakup(char *string, struct arglist *arglist)
-{
-	struct ifsregion *ifsp;
-	char *start;
-	char *p;
-	char *q;
-	const char *ifs;
-	const char *ifsspc;
-	int had_param_ch = 0;
-
-	start = string;
-
-	if (ifslastp == NULL) {
-		/* Return entire argument, IFS doesn't apply to any of it */
-		appendarglist(arglist, start);
-		return;
-	}
-
-	ifs = ifsset() ? ifsval() : " \t\n";
-
-	for (ifsp = &ifsfirst; ifsp != NULL; ifsp = ifsp->next) {
-		p = string + ifsp->begoff;
-		while (p < string + ifsp->endoff) {
-			q = p;
-			if (*p == CTLESC)
-				p++;
-			if (ifsp->inquotes) {
-				/* Only NULs (should be from "$@") end args */
-				had_param_ch = 1;
-				if (*p != 0) {
-					p++;
-					continue;
-				}

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-user mailing list