svn commit: r293016 - in projects/clang380-import: . bin/sh contrib/binutils/bfd lib/libmd lib/libstand share/man/man4 sys/arm64/arm64 sys/arm64/include sys/boot/forth sys/boot/i386/loader sys/boot...
Dimitry Andric
dim at FreeBSD.org
Thu Dec 31 22:55:04 UTC 2015
Author: dim
Date: Thu Dec 31 22:55:02 2015
New Revision: 293016
URL: https://svnweb.freebsd.org/changeset/base/293016
Log:
Merge ^/head r292951 through r293015.
Added:
projects/clang380-import/share/man/man4/rtwn.4
- copied unchanged from r293015, head/share/man/man4/rtwn.4
projects/clang380-import/share/man/man4/rtwnfw.4
- copied unchanged from r293015, head/share/man/man4/rtwnfw.4
projects/clang380-import/sys/contrib/dev/rtwn/
- copied from r293015, head/sys/contrib/dev/rtwn/
projects/clang380-import/sys/dev/rtwn/
- copied from r293015, head/sys/dev/rtwn/
projects/clang380-import/sys/modules/rtwnfw/
- copied from r293015, head/sys/modules/rtwnfw/
projects/clang380-import/sys/opencrypto/xform_aes_icm.c
- copied unchanged from r293015, head/sys/opencrypto/xform_aes_icm.c
projects/clang380-import/sys/opencrypto/xform_aes_xts.c
- copied unchanged from r293015, head/sys/opencrypto/xform_aes_xts.c
projects/clang380-import/sys/opencrypto/xform_auth.h
- copied unchanged from r293015, head/sys/opencrypto/xform_auth.h
projects/clang380-import/sys/opencrypto/xform_blf.c
- copied unchanged from r293015, head/sys/opencrypto/xform_blf.c
projects/clang380-import/sys/opencrypto/xform_cast5.c
- copied unchanged from r293015, head/sys/opencrypto/xform_cast5.c
projects/clang380-import/sys/opencrypto/xform_cml.c
- copied unchanged from r293015, head/sys/opencrypto/xform_cml.c
projects/clang380-import/sys/opencrypto/xform_comp.h
- copied unchanged from r293015, head/sys/opencrypto/xform_comp.h
projects/clang380-import/sys/opencrypto/xform_deflate.c
- copied unchanged from r293015, head/sys/opencrypto/xform_deflate.c
projects/clang380-import/sys/opencrypto/xform_des1.c
- copied unchanged from r293015, head/sys/opencrypto/xform_des1.c
projects/clang380-import/sys/opencrypto/xform_des3.c
- copied unchanged from r293015, head/sys/opencrypto/xform_des3.c
projects/clang380-import/sys/opencrypto/xform_enc.h
- copied unchanged from r293015, head/sys/opencrypto/xform_enc.h
projects/clang380-import/sys/opencrypto/xform_gmac.c
- copied unchanged from r293015, head/sys/opencrypto/xform_gmac.c
projects/clang380-import/sys/opencrypto/xform_md5.c
- copied unchanged from r293015, head/sys/opencrypto/xform_md5.c
projects/clang380-import/sys/opencrypto/xform_null.c
- copied unchanged from r293015, head/sys/opencrypto/xform_null.c
projects/clang380-import/sys/opencrypto/xform_rijndael.c
- copied unchanged from r293015, head/sys/opencrypto/xform_rijndael.c
projects/clang380-import/sys/opencrypto/xform_rmd160.c
- copied unchanged from r293015, head/sys/opencrypto/xform_rmd160.c
projects/clang380-import/sys/opencrypto/xform_sha1.c
- copied unchanged from r293015, head/sys/opencrypto/xform_sha1.c
projects/clang380-import/sys/opencrypto/xform_sha2.c
- copied unchanged from r293015, head/sys/opencrypto/xform_sha2.c
projects/clang380-import/sys/opencrypto/xform_skipjack.c
- copied unchanged from r293015, head/sys/opencrypto/xform_skipjack.c
projects/clang380-import/sys/opencrypto/xform_userland.h
- copied unchanged from r293015, head/sys/opencrypto/xform_userland.h
Modified:
projects/clang380-import/COPYRIGHT
projects/clang380-import/bin/sh/expand.c
projects/clang380-import/bin/sh/expand.h
projects/clang380-import/contrib/binutils/bfd/elf32-arm.c
projects/clang380-import/lib/libmd/mdXhl.c
projects/clang380-import/lib/libstand/Makefile
projects/clang380-import/share/man/man4/Makefile
projects/clang380-import/sys/arm64/arm64/identcpu.c
projects/clang380-import/sys/arm64/arm64/mp_machdep.c
projects/clang380-import/sys/arm64/include/armreg.h
projects/clang380-import/sys/arm64/include/cpu.h
projects/clang380-import/sys/boot/forth/loader.conf
projects/clang380-import/sys/boot/forth/menu-commands.4th
projects/clang380-import/sys/boot/forth/menu.rc
projects/clang380-import/sys/boot/forth/support.4th
projects/clang380-import/sys/boot/i386/loader/main.c
projects/clang380-import/sys/boot/zfs/libzfs.h
projects/clang380-import/sys/boot/zfs/zfs.c
projects/clang380-import/sys/boot/zfs/zfsimpl.c
projects/clang380-import/sys/compat/linuxkpi/common/include/linux/cdev.h
projects/clang380-import/sys/compat/linuxkpi/common/include/linux/device.h
projects/clang380-import/sys/compat/linuxkpi/common/include/linux/file.h
projects/clang380-import/sys/compat/linuxkpi/common/include/linux/kobject.h
projects/clang380-import/sys/compat/linuxkpi/common/include/linux/miscdevice.h
projects/clang380-import/sys/compat/linuxkpi/common/src/linux_compat.c
projects/clang380-import/sys/compat/linuxkpi/common/src/linux_pci.c
projects/clang380-import/sys/conf/newvers.sh
projects/clang380-import/sys/crypto/sha1.h
projects/clang380-import/sys/dev/cxgb/ulp/tom/cxgb_l2t.c
projects/clang380-import/sys/dev/cxgbe/tom/t4_tom_l2t.c
projects/clang380-import/sys/dev/usb/net/if_axe.c
projects/clang380-import/sys/dev/usb/usbdevs
projects/clang380-import/sys/fs/nullfs/null_vnops.c
projects/clang380-import/sys/modules/Makefile
projects/clang380-import/sys/net/bpf.c
projects/clang380-import/sys/net/flowtable.c
projects/clang380-import/sys/net/if.c
projects/clang380-import/sys/net/if_ethersubr.c
projects/clang380-import/sys/net/if_gif.c
projects/clang380-import/sys/net/if_gre.c
projects/clang380-import/sys/net/if_llatbl.c
projects/clang380-import/sys/net/if_llatbl.h
projects/clang380-import/sys/net/if_var.h
projects/clang380-import/sys/net/route.h
projects/clang380-import/sys/netinet/if_ether.c
projects/clang380-import/sys/netinet/if_ether.h
projects/clang380-import/sys/netinet/in.c
projects/clang380-import/sys/netinet/ip_output.c
projects/clang380-import/sys/netinet/toecore.c
projects/clang380-import/sys/netinet6/icmp6.c
projects/clang380-import/sys/netinet6/in6.c
projects/clang380-import/sys/netinet6/in6.h
projects/clang380-import/sys/netinet6/ip6_output.c
projects/clang380-import/sys/netinet6/nd6.c
projects/clang380-import/sys/netinet6/nd6.h
projects/clang380-import/sys/netinet6/nd6_nbr.c
projects/clang380-import/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c
projects/clang380-import/sys/opencrypto/skipjack.h
projects/clang380-import/sys/opencrypto/xform.c
projects/clang380-import/sys/opencrypto/xform.h
projects/clang380-import/sys/sparc64/include/ktr.h
projects/clang380-import/sys/sys/copyright.h
projects/clang380-import/sys/sys/param.h
projects/clang380-import/sys/xen/xenbus/xenbusb.c
projects/clang380-import/tests/sys/kern/unix_passfd_test.c
projects/clang380-import/usr.sbin/bhyve/bhyverun.c
projects/clang380-import/usr.sbin/bhyve/pci_emul.c
projects/clang380-import/usr.sbin/camdd/camdd.c
Directory Properties:
projects/clang380-import/ (props changed)
projects/clang380-import/contrib/binutils/ (props changed)
projects/clang380-import/contrib/pf/ (props changed)
projects/clang380-import/share/ (props changed)
projects/clang380-import/share/man/man4/ (props changed)
projects/clang380-import/sys/ (props changed)
projects/clang380-import/sys/boot/ (props changed)
projects/clang380-import/sys/conf/ (props changed)
projects/clang380-import/usr.sbin/bhyve/ (props changed)
Modified: projects/clang380-import/COPYRIGHT
==============================================================================
--- projects/clang380-import/COPYRIGHT Thu Dec 31 22:52:11 2015 (r293015)
+++ projects/clang380-import/COPYRIGHT Thu Dec 31 22:55:02 2015 (r293016)
@@ -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: projects/clang380-import/bin/sh/expand.c
==============================================================================
--- projects/clang380-import/bin/sh/expand.c Thu Dec 31 22:52:11 2015 (r293015)
+++ projects/clang380-import/bin/sh/expand.c Thu Dec 31 22:55:02 2015 (r293016)
@@ -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,42 +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_trim(char *, int, int, int, 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);
+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
@@ -169,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
@@ -184,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));
}
@@ -221,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;
@@ -253,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 '=':
@@ -286,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 == '=')
@@ -298,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);
}
}
}
@@ -345,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++;
@@ -353,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;
@@ -407,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;
@@ -425,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;
}
@@ -434,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) {
@@ -476,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);
@@ -498,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),
@@ -521,18 +531,17 @@ recordleft(const char *str, const char *
*startp++ = *loc++;
}
-static int
-subevalvar_trim(char *p, int strloc, int subtype, int startloc, 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, EXP_CASE | EXP_TILDE);
+ argstr(p, EXP_CASE | EXP_TILDE, NULL);
STACKSTRNUL(expdest);
argbackq = saveargbackq;
startp = stackblock() + startloc;
@@ -543,72 +552,56 @@ subevalvar_trim(char *p, int strloc, int
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);
}
@@ -620,7 +613,7 @@ subevalvar_misc(char *p, const char *var
struct nodelist *saveargbackq = argbackq;
int amount;
- argstr(p, EXP_TILDE);
+ argstr(p, EXP_TILDE, NULL);
STACKSTRNUL(expdest);
argbackq = saveargbackq;
startp = stackblock() + startloc;
@@ -653,7 +646,7 @@ subevalvar_misc(char *p, const char *var
*/
static char *
-evalvar(char *p, int flag)
+evalvar(char *p, int flag, struct worddest *dst)
{
int subtype;
int varflags;
@@ -666,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;
@@ -710,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;
@@ -734,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:
@@ -777,14 +768,10 @@ again: /* jump here after setting a vari
*/
STPUTC('\0', expdest);
patloc = expdest - stackblock();
- if (subevalvar_trim(p, patloc, subtype,
- startloc, 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:
@@ -793,16 +780,10 @@ again: /* jump here after setting a vari
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:
@@ -814,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 (;;) {
@@ -884,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 '$':
@@ -919,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 */
@@ -941,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:
@@ -959,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;
- }
- ifsspc = NULL;
- } else {
- if (!strchr(ifs, *p)) {
- had_param_ch = 1;
- p++;
- continue;
- }
- ifsspc = strchr(" \t\n", *p);
-
- /* Ignore IFS whitespace at start */
- if (q == start && ifsspc != NULL) {
- p++;
- start = p;
- continue;
- }
- had_param_ch = 0;
- }
-
- /* Save this argument... */
- *q = '\0';
- appendarglist(arglist, start);
- p++;
-
- if (ifsspc != NULL) {
- /* Ignore further trailing IFS whitespace */
- for (; p < string + ifsp->endoff; p++) {
- q = p;
- if (*p == CTLESC)
- p++;
- if (strchr(ifs, *p) == NULL) {
- p = q;
- break;
- }
- if (strchr(" \t\n", *p) == NULL) {
- p++;
- break;
- }
- }
- }
- start = p;
- }
- }
-
- /*
- * Save anything left as an argument.
- * Traditionally we have treated 'IFS=':'; set -- x$IFS' as
- * generating 2 arguments, the second of which is empty.
- * Some recent clarification of the Posix spec say that it
- * should only generate one....
- */
- if (had_param_ch || *start != 0)
- appendarglist(arglist, start);
-}
-
-
static char expdir[PATH_MAX];
#define expdir_end (expdir + sizeof(expdir))
/*
* Perform pathname generation and remove control characters.
- * At this point, the only control characters should be CTLESC and CTLQUOTEMARK.
+ * At this point, the only control characters should be CTLESC.
* The results are stored in the list dstlist.
*/
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list