svn commit: r289159 - head/bin/sh

Jilles Tjoelker jilles at FreeBSD.org
Sun Oct 11 21:33:02 UTC 2015


Author: jilles
Date: Sun Oct 11 21:33:00 2015
New Revision: 289159
URL: https://svnweb.freebsd.org/changeset/base/289159

Log:
  sh: Make struct arglist an array instead of a linked list.
  
  This simplifies the code (e.g. allowing use of qsort(3) instead of a
  hand-rolled mergesort) and should have better cache properties.
  
  The waste of unused args arrays after resizes is approximately the same as
  the savings from getting rid of the next pointers.
  
  At the same time, remove a piece of global state and move some duplicated
  code into a function.

Modified:
  head/bin/sh/eval.c
  head/bin/sh/eval.h
  head/bin/sh/expand.c
  head/bin/sh/expand.h
  head/bin/sh/var.c
  head/bin/sh/var.h

Modified: head/bin/sh/eval.c
==============================================================================
--- head/bin/sh/eval.c	Sun Oct 11 21:29:24 2015	(r289158)
+++ head/bin/sh/eval.c	Sun Oct 11 21:33:00 2015	(r289159)
@@ -82,7 +82,7 @@ static int builtin_flags;	/* evalcommand
 
 
 char *commandname;
-struct strlist *cmdenviron;
+struct arglist *cmdenviron;
 int exitstatus;			/* exit status of last command */
 int oexitstatus;		/* saved exit status */
 
@@ -352,20 +352,19 @@ evalfor(union node *n, int flags)
 {
 	struct arglist arglist;
 	union node *argp;
-	struct strlist *sp;
+	int i;
 	int status;
 
-	arglist.lastp = &arglist.list;
+	emptyarglist(&arglist);
 	for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
 		oexitstatus = exitstatus;
 		expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
 	}
-	*arglist.lastp = NULL;
 
 	loopnest++;
 	status = 0;
-	for (sp = arglist.list ; sp ; sp = sp->next) {
-		setvar(n->nfor.var, sp->text, 0);
+	for (i = 0; i < arglist.count; i++) {
+		setvar(n->nfor.var, arglist.args[i], 0);
 		evaltree(n->nfor.body, flags);
 		status = exitstatus;
 		if (evalskip) {
@@ -396,12 +395,12 @@ evalcase(union node *n)
 	union node *patp;
 	struct arglist arglist;
 
-	arglist.lastp = &arglist.list;
+	emptyarglist(&arglist);
 	oexitstatus = exitstatus;
 	expandarg(n->ncase.expr, &arglist, EXP_TILDE);
 	for (cp = n->ncase.cases ; cp ; cp = cp->nclist.next) {
 		for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
-			if (casematch(patp, arglist.list->text)) {
+			if (casematch(patp, arglist.args[0])) {
 				while (cp->nclist.next &&
 				    cp->type == NCLISTFALLTHRU &&
 				    cp->nclist.body == NULL)
@@ -508,7 +507,7 @@ exphere(union node *redir, struct arglis
 	else {
 		handler = &jmploc;
 		expandarg(redir->nhere.doc, fn, 0);
-		redir->nhere.expdoc = fn->list->text;
+		redir->nhere.expdoc = fn->args[0];
 		INTOFF;
 	}
 	handler = savehandler;
@@ -532,7 +531,7 @@ expredir(union node *n)
 
 	for (redir = n ; redir ; redir = redir->nfile.next) {
 		struct arglist fn;
-		fn.lastp = &fn.list;
+		emptyarglist(&fn);
 		switch (redir->type) {
 		case NFROM:
 		case NTO:
@@ -540,13 +539,13 @@ expredir(union node *n)
 		case NAPPEND:
 		case NCLOBBER:
 			expandarg(redir->nfile.fname, &fn, EXP_TILDE);
-			redir->nfile.expfname = fn.list->text;
+			redir->nfile.expfname = fn.args[0];
 			break;
 		case NFROMFD:
 		case NTOFD:
 			if (redir->ndup.vname) {
 				expandarg(redir->ndup.vname, &fn, EXP_TILDE);
-				fixredir(redir, fn.list->text, 1);
+				fixredir(redir, fn.args[0], 1);
 			}
 			break;
 		case NXHERE:
@@ -753,28 +752,30 @@ isdeclarationcmd(struct narg *arg)
 static void
 xtracecommand(struct arglist *varlist, struct arglist *arglist)
 {
-	struct strlist *sp;
 	char sep = 0;
-	const char *p, *ps4;
+	const char *text, *p, *ps4;
+	int i;
 
 	ps4 = expandstr(ps4val());
 	out2str(ps4 != NULL ? ps4 : ps4val());
-	for (sp = varlist->list ; sp ; sp = sp->next) {
+	for (i = 0; i < varlist->count; i++) {
+		text = varlist->args[i];
 		if (sep != 0)
 			out2c(' ');
-		p = strchr(sp->text, '=');
+		p = strchr(text, '=');
 		if (p != NULL) {
 			p++;
-			outbin(sp->text, p - sp->text, out2);
+			outbin(text, p - text, out2);
 			out2qstr(p);
 		} else
-			out2qstr(sp->text);
+			out2qstr(text);
 		sep = ' ';
 	}
-	for (sp = arglist->list ; sp ; sp = sp->next) {
+	for (i = 0; i < arglist->count; i++) {
+		text = arglist->args[i];
 		if (sep != 0)
 			out2c(' ');
-		out2qstr(sp->text);
+		out2qstr(text);
 		sep = ' ';
 	}
 	out2c('\n');
@@ -822,7 +823,6 @@ evalcommand(union node *cmd, int flags, 
 	int argc;
 	char **envp;
 	int varflag;
-	struct strlist *sp;
 	int mode;
 	int pip[2];
 	struct cmdentry cmdentry;
@@ -838,11 +838,12 @@ evalcommand(union node *cmd, int flags, 
 	int realstatus;
 	int do_clearcmdentry;
 	const char *path = pathval();
+	int i;
 
 	/* First expand the arguments. */
 	TRACE(("evalcommand(%p, %d) called\n", (void *)cmd, flags));
-	arglist.lastp = &arglist.list;
-	varlist.lastp = &varlist.list;
+	emptyarglist(&arglist);
+	emptyarglist(&varlist);
 	varflag = 1;
 	jp = NULL;
 	do_clearcmdentry = 0;
@@ -857,25 +858,17 @@ evalcommand(union node *cmd, int flags, 
 			varflag = isdeclarationcmd(&argp->narg) ? 2 : 0;
 		expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
 	}
-	*arglist.lastp = NULL;
-	*varlist.lastp = NULL;
 	expredir(cmd->ncmd.redirect);
-	argc = 0;
-	for (sp = arglist.list ; sp ; sp = sp->next)
-		argc++;
+	argc = arglist.count;
 	/* Add one slot at the beginning for tryexec(). */
 	argv = stalloc(sizeof (char *) * (argc + 2));
 	argv++;
 
-	for (sp = arglist.list ; sp ; sp = sp->next) {
-		TRACE(("evalcommand arg: %s\n", sp->text));
-		*argv++ = sp->text;
-	}
-	*argv = NULL;
+	memcpy(argv, arglist.args, sizeof(*argv) * argc);
+	argv[argc] = NULL;
 	lastarg = NULL;
 	if (iflag && funcnest == 0 && argc > 0)
-		lastarg = argv[-1];
-	argv -= argc;
+		lastarg = argv[argc - 1];
 
 	/* Print the command if xflag is set. */
 	if (xflag)
@@ -895,9 +888,9 @@ evalcommand(union node *cmd, int flags, 
 		 * Modify the command lookup path, if a PATH= assignment
 		 * is present
 		 */
-		for (sp = varlist.list ; sp ; sp = sp->next)
-			if (strncmp(sp->text, PATH, sizeof(PATH) - 1) == 0) {
-				path = sp->text + sizeof(PATH) - 1;
+		for (i = 0; i < varlist.count; i++)
+			if (strncmp(varlist.args[i], PATH, sizeof(PATH) - 1) == 0) {
+				path = varlist.args[i] + sizeof(PATH) - 1;
 				/*
 				 * On `PATH=... command`, we need to make
 				 * sure that the command isn't using the
@@ -999,7 +992,7 @@ evalcommand(union node *cmd, int flags, 
 		}
 		if (cmdentry.cmdtype == CMDNORMAL &&
 		    cmd->ncmd.redirect == NULL &&
-		    varlist.list == NULL &&
+		    varlist.count == 0 &&
 		    (mode == FORK_FG || mode == FORK_NOJOB) &&
 		    !disvforkset() && !iflag && !mflag) {
 			vforkexecshell(jp, argv, environment(), path,
@@ -1053,8 +1046,8 @@ evalcommand(union node *cmd, int flags, 
 		funcnest++;
 		redirect(cmd->ncmd.redirect, REDIR_PUSH);
 		INTON;
-		for (sp = varlist.list ; sp ; sp = sp->next)
-			mklocal(sp->text);
+		for (i = 0; i < varlist.count; i++)
+			mklocal(varlist.args[i]);
 		exitstatus = oexitstatus;
 		evaltree(getfuncnode(cmdentry.u.func),
 		    flags & (EV_TESTED | EV_EXIT));
@@ -1087,7 +1080,7 @@ evalcommand(union node *cmd, int flags, 
 		}
 		savecmdname = commandname;
 		savetopfile = getcurrentfile();
-		cmdenviron = varlist.list;
+		cmdenviron = &varlist;
 		e = -1;
 		savehandler = handler;
 		if (setjmp(jmploc.loc)) {
@@ -1152,8 +1145,8 @@ cmddone:
 		trputs("normal command:  ");  trargs(argv);
 #endif
 		redirect(cmd->ncmd.redirect, 0);
-		for (sp = varlist.list ; sp ; sp = sp->next)
-			setvareq(sp->text, VEXPORT|VSTACK);
+		for (i = 0; i < varlist.count; i++)
+			setvareq(varlist.args[i], VEXPORT|VSTACK);
 		envp = environment();
 		shellexec(argv, envp, path, cmdentry.u.index);
 		/*NOTREACHED*/
@@ -1336,6 +1329,8 @@ truecmd(int argc __unused, char **argv _
 int
 execcmd(int argc, char **argv)
 {
+	int i;
+
 	/*
 	 * Because we have historically not supported any options,
 	 * only treat "--" specially.
@@ -1343,13 +1338,11 @@ execcmd(int argc, char **argv)
 	if (argc > 1 && strcmp(argv[1], "--") == 0)
 		argc--, argv++;
 	if (argc > 1) {
-		struct strlist *sp;
-
 		iflag = 0;		/* exit on error */
 		mflag = 0;
 		optschanged();
-		for (sp = cmdenviron; sp ; sp = sp->next)
-			setvareq(sp->text, VEXPORT|VSTACK);
+		for (i = 0; i < cmdenviron->count; i++)
+			setvareq(cmdenviron->args[i], VEXPORT|VSTACK);
 		shellexec(argv + 1, environment(), pathval(), 0);
 
 	}

Modified: head/bin/sh/eval.h
==============================================================================
--- head/bin/sh/eval.h	Sun Oct 11 21:29:24 2015	(r289158)
+++ head/bin/sh/eval.h	Sun Oct 11 21:33:00 2015	(r289159)
@@ -36,7 +36,7 @@
 extern char *commandname;	/* currently executing command */
 extern int exitstatus;		/* exit status of last command */
 extern int oexitstatus;		/* saved exit status */
-extern struct strlist *cmdenviron;  /* environment for builtin command */
+extern struct arglist *cmdenviron;  /* environment for builtin command */
 
 
 struct backcmd {		/* result of evalbackcmd */

Modified: head/bin/sh/expand.c
==============================================================================
--- head/bin/sh/expand.c	Sun Oct 11 21:29:24 2015	(r289158)
+++ head/bin/sh/expand.c	Sun Oct 11 21:33:00 2015	(r289159)
@@ -96,7 +96,6 @@ static char *expdest;			/* output of cur
 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 struct arglist exparg;		/* holds expanded arg list */
 
 static char *argstr(char *, int);
 static char *exptilde(char *, int);
@@ -110,15 +109,43 @@ static void varvalue(const char *, int, 
 static void recordregion(int, int, int);
 static void removerecordregions(int);
 static void ifsbreakup(char *, struct arglist *);
-static void expandmeta(struct strlist *);
-static void expmeta(char *, char *);
-static void addfname(char *);
-static struct strlist *expsort(struct strlist *);
-static struct strlist *msort(struct strlist *, int);
+static void expandmeta(struct arglist *, 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 void appendarglist(struct arglist *, char *);
 static int collate_range_cmp(wchar_t, wchar_t);
 
+void
+emptyarglist(struct arglist *list)
+{
+
+	list->args = list->smallarg;
+	list->count = 0;
+	list->capacity = sizeof(list->smallarg) / sizeof(list->smallarg[0]);
+}
+
+static void
+appendarglist(struct arglist *list, char *str)
+{
+	char **newargs;
+	int newcapacity;
+
+	if (list->count >= list->capacity) {
+		newcapacity = list->capacity * 2;
+		if (newcapacity < 16)
+			newcapacity = 16;
+		if (newcapacity > INT_MAX / (int)sizeof(newargs[0]))
+			error("Too many entries in arglist");
+		newargs = stalloc(newcapacity * sizeof(newargs[0]));
+		memcpy(newargs, list->args, list->count * sizeof(newargs[0]));
+		list->args = newargs;
+		list->capacity = newcapacity;
+	}
+	list->args[list->count++] = str;
+}
+
 static int
 collate_range_cmp(wchar_t c1, wchar_t c2)
 {
@@ -157,7 +184,7 @@ stputs_quotes(const char *data, const ch
 void
 expandarg(union node *arg, struct arglist *arglist, int flag)
 {
-	struct strlist *sp;
+	struct arglist exparg;
 	char *p;
 
 	argbackq = arg->narg.backquote;
@@ -171,18 +198,12 @@ expandarg(union node *arg, struct arglis
 	}
 	STPUTC('\0', expdest);
 	p = grabstackstr(expdest);
-	exparg.lastp = &exparg.list;
+	emptyarglist(&exparg);
 	if (flag & EXP_FULL) {
 		ifsbreakup(p, &exparg);
-		*exparg.lastp = NULL;
-		exparg.lastp = &exparg.list;
-		expandmeta(exparg.list);
-	} else {
-		sp = (struct strlist *)stalloc(sizeof (struct strlist));
-		sp->text = p;
-		*exparg.lastp = sp;
-		exparg.lastp = &sp->next;
-	}
+		expandmeta(&exparg, arglist);
+	} else
+		appendarglist(arglist, p);
 	while (ifsfirst.next != NULL) {
 		struct ifsregion *ifsp;
 		INTOFF;
@@ -191,11 +212,6 @@ expandarg(union node *arg, struct arglis
 		ifsfirst.next = ifsp;
 		INTON;
 	}
-	*exparg.lastp = NULL;
-	if (exparg.list) {
-		*arglist->lastp = exparg.list;
-		arglist->lastp = exparg.lastp;
-	}
 }
 
 
@@ -984,7 +1000,6 @@ static void
 ifsbreakup(char *string, struct arglist *arglist)
 {
 	struct ifsregion *ifsp;
-	struct strlist *sp;
 	char *start;
 	char *p;
 	char *q;
@@ -996,10 +1011,7 @@ ifsbreakup(char *string, struct arglist 
 
 	if (ifslastp == NULL) {
 		/* Return entire argument, IFS doesn't apply to any of it */
-		sp = (struct strlist *)stalloc(sizeof *sp);
-		sp->text = start;
-		*arglist->lastp = sp;
-		arglist->lastp = &sp->next;
+		appendarglist(arglist, start);
 		return;
 	}
 
@@ -1038,10 +1050,7 @@ ifsbreakup(char *string, struct arglist 
 
 			/* Save this argument... */
 			*q = '\0';
-			sp = (struct strlist *)stalloc(sizeof *sp);
-			sp->text = start;
-			*arglist->lastp = sp;
-			arglist->lastp = &sp->next;
+			appendarglist(arglist, start);
 			p++;
 
 			if (ifsspc != NULL) {
@@ -1071,12 +1080,8 @@ ifsbreakup(char *string, struct arglist 
 	 * Some recent clarification of the Posix spec say that it
 	 * should only generate one....
 	 */
-	if (had_param_ch || *start != 0) {
-		sp = (struct strlist *)stalloc(sizeof *sp);
-		sp->text = start;
-		*arglist->lastp = sp;
-		arglist->lastp = &sp->next;
-	}
+	if (had_param_ch || *start != 0)
+		appendarglist(arglist, start);
 }
 
 
@@ -1086,45 +1091,42 @@ static char expdir[PATH_MAX];
 /*
  * Perform pathname generation and remove control characters.
  * At this point, the only control characters should be CTLESC and CTLQUOTEMARK.
- * The results are stored in the list exparg.
+ * The results are stored in the list dstlist.
  */
 static void
-expandmeta(struct strlist *str)
+expandmeta(struct arglist *srclist, struct arglist *dstlist)
 {
 	char *p;
-	struct strlist **savelastp;
-	struct strlist *sp;
+	int firstmatch;
+	int i;
 	char c;
 
-	while (str) {
-		savelastp = exparg.lastp;
+	for (i = 0; i < srclist->count; i++) {
+		firstmatch = dstlist->count;
 		if (!fflag) {
-			p = str->text;
+			p = srclist->args[i];
 			for (; (c = *p) != '\0'; p++) {
 				/* fast check for meta chars */
 				if (c == '*' || c == '?' || c == '[') {
 					INTOFF;
-					expmeta(expdir, str->text);
+					expmeta(expdir, srclist->args[i],
+					    dstlist);
 					INTON;
 					break;
 				}
 			}
 		}
-		if (exparg.lastp == savelastp) {
+		if (dstlist->count == firstmatch) {
 			/*
 			 * no matches
 			 */
-			*exparg.lastp = str;
-			rmescapes(str->text);
-			exparg.lastp = &str->next;
+			rmescapes(srclist->args[i]);
+			appendarglist(dstlist, srclist->args[i]);
 		} else {
-			*exparg.lastp = NULL;
-			*savelastp = sp = expsort(*savelastp);
-			while (sp->next != NULL)
-				sp = sp->next;
-			exparg.lastp = &sp->next;
+			qsort(&dstlist->args[firstmatch],
+			    dstlist->count - firstmatch,
+			    sizeof(dstlist->args[0]), expsortcmp);
 		}
-		str = str->next;
 	}
 }
 
@@ -1134,7 +1136,7 @@ expandmeta(struct strlist *str)
  */
 
 static void
-expmeta(char *enddir, char *name)
+expmeta(char *enddir, char *name, struct arglist *arglist)
 {
 	const char *p;
 	const char *q;
@@ -1199,7 +1201,7 @@ expmeta(char *enddir, char *name)
 				return;
 		}
 		if (metaflag == 0 || lstat(expdir, &statb) >= 0)
-			addfname(expdir);
+			appendarglist(arglist, stsavestr(expdir));
 		return;
 	}
 	endname = name + (p - name);
@@ -1251,7 +1253,7 @@ expmeta(char *enddir, char *name)
 				continue;
 			memcpy(enddir, dp->d_name, namlen + 1);
 			if (atend)
-				addfname(expdir);
+				appendarglist(arglist, stsavestr(expdir));
 			else {
 				if (dp->d_type != DT_UNKNOWN &&
 				    dp->d_type != DT_DIR &&
@@ -1261,7 +1263,7 @@ expmeta(char *enddir, char *name)
 					continue;
 				enddir[namlen] = '/';
 				enddir[namlen + 1] = '\0';
-				expmeta(enddir + namlen + 1, endname);
+				expmeta(enddir + namlen + 1, endname, arglist);
 			}
 		}
 	}
@@ -1271,81 +1273,13 @@ expmeta(char *enddir, char *name)
 }
 
 
-/*
- * Add a file name to the list.
- */
-
-static void
-addfname(char *name)
-{
-	char *p;
-	struct strlist *sp;
-
-	p = stsavestr(name);
-	sp = (struct strlist *)stalloc(sizeof *sp);
-	sp->text = p;
-	*exparg.lastp = sp;
-	exparg.lastp = &sp->next;
-}
-
-
-/*
- * Sort the results of file name expansion.  It calculates the number of
- * strings to sort and then calls msort (short for merge sort) to do the
- * work.
- */
-
-static struct strlist *
-expsort(struct strlist *str)
+static int
+expsortcmp(const void *p1, const void *p2)
 {
-	int len;
-	struct strlist *sp;
+	const char *s1 = *(const char * const *)p1;
+	const char *s2 = *(const char * const *)p2;
 
-	len = 0;
-	for (sp = str ; sp ; sp = sp->next)
-		len++;
-	return msort(str, len);
-}
-
-
-static struct strlist *
-msort(struct strlist *list, int len)
-{
-	struct strlist *p, *q = NULL;
-	struct strlist **lpp;
-	int half;
-	int n;
-
-	if (len <= 1)
-		return list;
-	half = len >> 1;
-	p = list;
-	for (n = half ; --n >= 0 ; ) {
-		q = p;
-		p = p->next;
-	}
-	q->next = NULL;			/* terminate first half of list */
-	q = msort(list, half);		/* sort first half of list */
-	p = msort(p, len - half);		/* sort second half */
-	lpp = &list;
-	for (;;) {
-		if (strcmp(p->text, q->text) < 0) {
-			*lpp = p;
-			lpp = &p->next;
-			if ((p = *lpp) == NULL) {
-				*lpp = q;
-				break;
-			}
-		} else {
-			*lpp = q;
-			lpp = &q->next;
-			if ((q = *lpp) == NULL) {
-				*lpp = p;
-				break;
-			}
-		}
-	}
-	return list;
+	return (strcmp(s1, s2));
 }
 
 
@@ -1666,11 +1600,11 @@ freebsd_wordexpcmd(int argc __unused, ch
 {
 	struct arglist arglist;
 	union node *args, *n;
-	struct strlist *sp;
-	size_t count, len;
+	size_t len;
 	int ch;
 	int protected = 0;
 	int fd = -1;
+	int i;
 
 	while ((ch = nextopt("f:p")) != '\0') {
 		switch (ch) {
@@ -1699,14 +1633,13 @@ freebsd_wordexpcmd(int argc __unused, ch
 			}
 		}
 	outcslow(' ', out1);
-	arglist.lastp = &arglist.list;
+	emptyarglist(&arglist);
 	for (n = args; n != NULL; n = n->narg.next)
 		expandarg(n, &arglist, EXP_FULL | EXP_TILDE);
-	*arglist.lastp = NULL;
-	for (sp = arglist.list, count = len = 0; sp; sp = sp->next)
-		count++, len += strlen(sp->text);
-	out1fmt("%016zx %016zx", count, len);
-	for (sp = arglist.list; sp; sp = sp->next)
-		outbin(sp->text, strlen(sp->text) + 1, out1);
+	for (i = 0, len = 0; i < arglist.count; i++)
+		len += strlen(arglist.args[i]);
+	out1fmt("%016x %016zx", arglist.count, len);
+	for (i = 0; i < arglist.count; i++)
+		outbin(arglist.args[i], strlen(arglist.args[i]) + 1, out1);
 	return (0);
 }

Modified: head/bin/sh/expand.h
==============================================================================
--- head/bin/sh/expand.h	Sun Oct 11 21:29:24 2015	(r289158)
+++ head/bin/sh/expand.h	Sun Oct 11 21:33:00 2015	(r289159)
@@ -33,15 +33,11 @@
  * $FreeBSD$
  */
 
-struct strlist {
-	struct strlist *next;
-	char *text;
-};
-
-
 struct arglist {
-	struct strlist *list;
-	struct strlist **lastp;
+	char **args;
+	int count;
+	int capacity;
+	char *smallarg[1];
 };
 
 /*
@@ -55,6 +51,7 @@ struct arglist {
 #define EXP_LIT_QUOTED	0x40	/* for EXP_SPLIT_LIT, start off quoted */
 
 
+void emptyarglist(struct arglist *);
 union node;
 void expandarg(union node *, struct arglist *, int);
 void rmescapes(char *);

Modified: head/bin/sh/var.c
==============================================================================
--- head/bin/sh/var.c	Sun Oct 11 21:29:24 2015	(r289158)
+++ head/bin/sh/var.c	Sun Oct 11 21:33:00 2015	(r289159)
@@ -403,14 +403,13 @@ setvareq_const(const char *s, int flags)
  */
 
 void
-listsetvar(struct strlist *list, int flags)
+listsetvar(struct arglist *list, int flags)
 {
-	struct strlist *lp;
+	int i;
 
 	INTOFF;
-	for (lp = list ; lp ; lp = lp->next) {
-		setvareq(savestr(lp->text), flags);
-	}
+	for (i = 0; i < list->count; i++)
+		setvareq(savestr(list->args[i]), flags);
 	INTON;
 }
 
@@ -442,14 +441,14 @@ lookupvar(const char *name)
 char *
 bltinlookup(const char *name, int doall)
 {
-	struct strlist *sp;
 	struct var *v;
 	char *result;
+	int i;
 
 	result = NULL;
-	for (sp = cmdenviron ; sp ; sp = sp->next) {
-		if (varequal(sp->text, name))
-			result = strchr(sp->text, '=') + 1;
+	if (cmdenviron) for (i = 0; i < cmdenviron->count; i++) {
+		if (varequal(cmdenviron->args[i], name))
+			result = strchr(cmdenviron->args[i], '=') + 1;
 	}
 	if (result != NULL)
 		return result;
@@ -468,13 +467,12 @@ bltinlookup(const char *name, int doall)
 void
 bltinsetlocale(void)
 {
-	struct strlist *lp;
 	int act = 0;
 	char *loc, *locdef;
 	int i;
 
-	for (lp = cmdenviron ; lp ; lp = lp->next) {
-		if (localevar(lp->text)) {
+	if (cmdenviron) for (i = 0; i < cmdenviron->count; i++) {
+		if (localevar(cmdenviron->args[i])) {
 			act = 1;
 			break;
 		}
@@ -507,11 +505,11 @@ bltinsetlocale(void)
 void
 bltinunsetlocale(void)
 {
-	struct strlist *lp;
+	int i;
 
 	INTOFF;
-	for (lp = cmdenviron ; lp ; lp = lp->next) {
-		if (localevar(lp->text)) {
+	if (cmdenviron) for (i = 0; i < cmdenviron->count; i++) {
+		if (localevar(cmdenviron->args[i])) {
 			setlocale(LC_ALL, "");
 			updatecharset();
 			return;

Modified: head/bin/sh/var.h
==============================================================================
--- head/bin/sh/var.h	Sun Oct 11 21:29:24 2015	(r289158)
+++ head/bin/sh/var.h	Sun Oct 11 21:33:00 2015	(r289159)
@@ -114,8 +114,8 @@ extern int initial_localeisutf8;
 void initvar(void);
 void setvar(const char *, const char *, int);
 void setvareq(char *, int);
-struct strlist;
-void listsetvar(struct strlist *, int);
+struct arglist;
+void listsetvar(struct arglist *, int);
 char *lookupvar(const char *);
 char *bltinlookup(const char *, int);
 void bltinsetlocale(void);


More information about the svn-src-all mailing list