Date: Thu, 31 Dec 2015 21:51:38 +0000 (UTC) From: Garrett Cooper <ngie@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: 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... Message-ID: <201512312151.tBVLpc7I063589@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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@gondor.apana.org.au>. All rights reserved. + * Copyright (c) 2010-2015 + * Jilles Tjoelker <jilles@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 ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201512312151.tBVLpc7I063589>