Module Name: src
Committed By: rillig
Date: Sun Aug 30 19:56:02 UTC 2020
Modified Files:
src/usr.bin/make: compat.c for.c job.c main.c nonints.h str.c var.c
Log Message:
make(1): replace brk_string with Str_Words
The API is much simpler, and there is less detail that is exposed by
default and fewer punctuation to type on the caller's side. To see that
there is some memory to be freed, one would have to look into the
struct. Having part of the return value as the actual return value and
the rest in output parameters was unnecessarily asymmetrical.
To generate a diff of this commit:
cvs rdiff -u -r1.137 -r1.138 src/usr.bin/make/compat.c
cvs rdiff -u -r1.66 -r1.67 src/usr.bin/make/for.c
cvs rdiff -u -r1.226 -r1.227 src/usr.bin/make/job.c
cvs rdiff -u -r1.330 -r1.331 src/usr.bin/make/main.c
cvs rdiff -u -r1.101 -r1.102 src/usr.bin/make/nonints.h
cvs rdiff -u -r1.63 -r1.64 src/usr.bin/make/str.c
cvs rdiff -u -r1.478 -r1.479 src/usr.bin/make/var.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.bin/make/compat.c
diff -u src/usr.bin/make/compat.c:1.137 src/usr.bin/make/compat.c:1.138
--- src/usr.bin/make/compat.c:1.137 Sun Aug 30 14:11:42 2020
+++ src/usr.bin/make/compat.c Sun Aug 30 19:56:02 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: compat.c,v 1.137 2020/08/30 14:11:42 rillig Exp $ */
+/* $NetBSD: compat.c,v 1.138 2020/08/30 19:56:02 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: compat.c,v 1.137 2020/08/30 14:11:42 rillig Exp $";
+static char rcsid[] = "$NetBSD: compat.c,v 1.138 2020/08/30 19:56:02 rillig Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)compat.c 8.2 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: compat.c,v 1.137 2020/08/30 14:11:42 rillig Exp $");
+__RCSID("$NetBSD: compat.c,v 1.138 2020/08/30 19:56:02 rillig Exp $");
#endif
#endif /* not lint */
#endif
@@ -336,17 +336,18 @@ again:
else
shargv[shargc++] = "-c";
shargv[shargc++] = cmd;
- shargv[shargc++] = NULL;
+ shargv[shargc] = NULL;
av = shargv;
bp = NULL;
mav = NULL;
} else {
- size_t argc;
/*
* No meta-characters, so no need to exec a shell. Break the command
* into words to form an argument vector we can execute.
*/
- mav = brk_string(cmd, TRUE, &argc, &bp);
+ Words words = Str_Words(cmd, TRUE);
+ mav = words.words;
+ bp = words.freeIt;
if (mav == NULL) {
useShell = 1;
goto again;
Index: src/usr.bin/make/for.c
diff -u src/usr.bin/make/for.c:1.66 src/usr.bin/make/for.c:1.67
--- src/usr.bin/make/for.c:1.66 Sat Aug 29 10:32:00 2020
+++ src/usr.bin/make/for.c Sun Aug 30 19:56:02 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: for.c,v 1.66 2020/08/29 10:32:00 rillig Exp $ */
+/* $NetBSD: for.c,v 1.67 2020/08/30 19:56:02 rillig Exp $ */
/*
* Copyright (c) 1992, The Regents of the University of California.
@@ -30,14 +30,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: for.c,v 1.66 2020/08/29 10:32:00 rillig Exp $";
+static char rcsid[] = "$NetBSD: for.c,v 1.67 2020/08/30 19:56:02 rillig Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)for.c 8.1 (Berkeley) 6/6/93";
#else
-__RCSID("$NetBSD: for.c,v 1.66 2020/08/29 10:32:00 rillig Exp $");
+__RCSID("$NetBSD: for.c,v 1.67 2020/08/30 19:56:02 rillig Exp $");
#endif
#endif /* not lint */
#endif
@@ -133,8 +133,7 @@ For_Eval(char *line)
size_t len;
int escapes;
unsigned char ch;
- char **words, *word_buf;
- size_t nwords;
+ Words words;
/* Skip the '.' and any following whitespace */
for (ptr++; *ptr && isspace((unsigned char)*ptr); ptr++)
@@ -203,15 +202,15 @@ For_Eval(char *line)
/*
* Split into words allowing for quoted strings.
*/
- words = brk_string(sub, FALSE, &nwords, &word_buf);
+ words = Str_Words(sub, FALSE);
free(sub);
- if (words != NULL) {
+ {
size_t n;
- for (n = 0; n < nwords; n++) {
- ptr = words[n];
+ for (n = 0; n < words.len; n++) {
+ ptr = words.words[n];
if (!*ptr)
continue;
escapes = 0;
@@ -234,11 +233,11 @@ For_Eval(char *line)
* We have to dup words[n] to maintain the semantics of
* strlist.
*/
- strlist_add_str(&new_for->items, bmake_strdup(words[n]), escapes);
+ strlist_add_str(&new_for->items, bmake_strdup(words.words[n]),
+ escapes);
}
- free(words);
- free(word_buf);
+ Words_Free(words);
if ((len = strlist_num(&new_for->items)) > 0 &&
len % (n = strlist_num(&new_for->vars))) {
Index: src/usr.bin/make/job.c
diff -u src/usr.bin/make/job.c:1.226 src/usr.bin/make/job.c:1.227
--- src/usr.bin/make/job.c:1.226 Sun Aug 30 13:53:02 2020
+++ src/usr.bin/make/job.c Sun Aug 30 19:56:02 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: job.c,v 1.226 2020/08/30 13:53:02 rillig Exp $ */
+/* $NetBSD: job.c,v 1.227 2020/08/30 19:56:02 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: job.c,v 1.226 2020/08/30 13:53:02 rillig Exp $";
+static char rcsid[] = "$NetBSD: job.c,v 1.227 2020/08/30 19:56:02 rillig Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: job.c,v 1.226 2020/08/30 13:53:02 rillig Exp $");
+__RCSID("$NetBSD: job.c,v 1.227 2020/08/30 19:56:02 rillig Exp $");
#endif
#endif /* not lint */
#endif
@@ -2414,6 +2414,7 @@ JobMatchShell(const char *name)
Boolean
Job_ParseShell(char *line)
{
+ Words wordsList;
char **words;
char **argv;
size_t argc;
@@ -2433,7 +2434,10 @@ Job_ParseShell(char *line)
/*
* Parse the specification by keyword
*/
- words = brk_string(line, TRUE, &argc, &path);
+ wordsList = Str_Words(line, TRUE);
+ words = wordsList.words;
+ argc = wordsList.len;
+ path = wordsList.freeIt;
if (words == NULL) {
Error("Unterminated quoted string [%s]", line);
return FALSE;
Index: src/usr.bin/make/main.c
diff -u src/usr.bin/make/main.c:1.330 src/usr.bin/make/main.c:1.331
--- src/usr.bin/make/main.c:1.330 Sun Aug 30 11:15:05 2020
+++ src/usr.bin/make/main.c Sun Aug 30 19:56:02 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.330 2020/08/30 11:15:05 rillig Exp $ */
+/* $NetBSD: main.c,v 1.331 2020/08/30 19:56:02 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,7 +69,7 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: main.c,v 1.330 2020/08/30 11:15:05 rillig Exp $";
+static char rcsid[] = "$NetBSD: main.c,v 1.331 2020/08/30 19:56:02 rillig Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
@@ -81,7 +81,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 19
#if 0
static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: main.c,v 1.330 2020/08/30 11:15:05 rillig Exp $");
+__RCSID("$NetBSD: main.c,v 1.331 2020/08/30 19:56:02 rillig Exp $");
#endif
#endif /* not lint */
#endif
@@ -690,9 +690,7 @@ noarg:
void
Main_ParseArgLine(const char *line)
{
- char **argv; /* Manufactured argument vector */
- size_t argc; /* Number of arguments in argv */
- char *args; /* Space used by the args */
+ Words words;
char *p1;
const char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &p1);
char *buf;
@@ -707,17 +705,16 @@ Main_ParseArgLine(const char *line)
buf = str_concat3(argv0, " ", line);
free(p1);
- argv = brk_string(buf, TRUE, &argc, &args);
- if (argv == NULL) {
+ words = Str_Words(buf, TRUE);
+ if (words.words == NULL) {
Error("Unterminated quoted string [%s]", buf);
free(buf);
return;
}
free(buf);
- MainParseArgs((int)argc, argv);
+ MainParseArgs((int)words.len, words.words);
- free(args);
- free(argv);
+ Words_Free(words);
}
Boolean
Index: src/usr.bin/make/nonints.h
diff -u src/usr.bin/make/nonints.h:1.101 src/usr.bin/make/nonints.h:1.102
--- src/usr.bin/make/nonints.h:1.101 Sat Aug 29 12:01:46 2020
+++ src/usr.bin/make/nonints.h Sun Aug 30 19:56:02 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: nonints.h,v 1.101 2020/08/29 12:01:46 rillig Exp $ */
+/* $NetBSD: nonints.h,v 1.102 2020/08/30 19:56:02 rillig Exp $ */
/*-
* Copyright (c) 1988, 1989, 1990, 1993
@@ -133,10 +133,22 @@ void Parse_SetInput(const char *, int, i
Lst Parse_MainName(void);
/* str.c */
+typedef struct {
+ char **words;
+ size_t len;
+ void *freeIt;
+} Words;
+
+Words Str_Words(const char *, Boolean);
+static inline void MAKE_ATTR_UNUSED
+Words_Free(Words w) {
+ free(w.words);
+ free(w.freeIt);
+}
+
char *str_concat2(const char *, const char *);
char *str_concat3(const char *, const char *, const char *);
char *str_concat4(const char *, const char *, const char *, const char *);
-char **brk_string(const char *, Boolean, size_t *, char **);
char *Str_FindSubstring(const char *, const char *);
Boolean Str_Match(const char *, const char *);
Index: src/usr.bin/make/str.c
diff -u src/usr.bin/make/str.c:1.63 src/usr.bin/make/str.c:1.64
--- src/usr.bin/make/str.c:1.63 Sat Aug 29 07:52:55 2020
+++ src/usr.bin/make/str.c Sun Aug 30 19:56:02 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: str.c,v 1.63 2020/08/29 07:52:55 rillig Exp $ */
+/* $NetBSD: str.c,v 1.64 2020/08/30 19:56:02 rillig Exp $ */
/*-
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: str.c,v 1.63 2020/08/29 07:52:55 rillig Exp $";
+static char rcsid[] = "$NetBSD: str.c,v 1.64 2020/08/30 19:56:02 rillig Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)str.c 5.8 (Berkeley) 6/1/90";
#else
-__RCSID("$NetBSD: str.c,v 1.63 2020/08/29 07:52:55 rillig Exp $");
+__RCSID("$NetBSD: str.c,v 1.64 2020/08/30 19:56:02 rillig Exp $");
#endif
#endif /* not lint */
#endif
@@ -125,25 +125,19 @@ str_concat4(const char *s1, const char *
return result;
}
-/*-
- * brk_string --
- * Fracture a string into an array of words (as delineated by tabs or
- * spaces) taking quotation marks into account. Leading tabs/spaces
- * are ignored.
- *
- * If expand is TRUE, quotes are removed and escape sequences
- * such as \r, \t, etc... are expanded. In this case, the return value
- * is NULL on parse errors.
- *
- * returns --
- * Pointer to the array of pointers to the words.
- * Memory containing the actual words in *out_words_buf.
- * Both of these must be free'd by the caller.
- * Number of words in *out_words_len.
+/* Fracture a string into an array of words (as delineated by tabs or spaces)
+ * taking quotation marks into account. Leading tabs/spaces are ignored.
+ *
+ * If expand is TRUE, quotes are removed and escape sequences such as \r, \t,
+ * etc... are expanded. In this case, the return value is NULL on parse
+ * errors.
+ *
+ * Returns the fractured words, which must be freed later using Words_Free.
+ * If expand was TRUE and there was a parse error, words is NULL, and in that
+ * case, nothing needs to be freed.
*/
-char **
-brk_string(const char *str, Boolean expand,
- size_t *out_words_len, char **out_words_buf)
+Words
+Str_Words(const char *str, Boolean expand)
{
size_t str_len;
char *words_buf;
@@ -233,8 +227,7 @@ brk_string(const char *str, Boolean expa
if (expand && inquote) {
free(words);
free(words_buf);
- *out_words_buf = NULL;
- return NULL;
+ return (Words){ NULL, 0, NULL };
}
goto done;
}
@@ -282,9 +275,7 @@ brk_string(const char *str, Boolean expa
}
done:
words[words_len] = NULL;
- *out_words_len = (int)words_len;
- *out_words_buf = words_buf;
- return words;
+ return (Words){ words, words_len, words_buf };
}
/*
Index: src/usr.bin/make/var.c
diff -u src/usr.bin/make/var.c:1.478 src/usr.bin/make/var.c:1.479
--- src/usr.bin/make/var.c:1.478 Sat Aug 29 13:38:48 2020
+++ src/usr.bin/make/var.c Sun Aug 30 19:56:02 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: var.c,v 1.478 2020/08/29 13:38:48 rillig Exp $ */
+/* $NetBSD: var.c,v 1.479 2020/08/30 19:56:02 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: var.c,v 1.478 2020/08/29 13:38:48 rillig Exp $";
+static char rcsid[] = "$NetBSD: var.c,v 1.479 2020/08/30 19:56:02 rillig Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: var.c,v 1.478 2020/08/29 13:38:48 rillig Exp $");
+__RCSID("$NetBSD: var.c,v 1.479 2020/08/30 19:56:02 rillig Exp $");
#endif
#endif /* not lint */
#endif
@@ -600,16 +600,12 @@ Var_ExportVars(void)
val = Var_Subst("${" MAKE_EXPORTED ":O:u}", VAR_GLOBAL, VARE_WANTRES);
if (*val) {
- char **av;
- char *as;
- size_t ac;
+ Words words = Str_Words(val, FALSE);
size_t i;
- av = brk_string(val, FALSE, &ac, &as);
- for (i = 0; i < ac; i++)
- Var_Export1(av[i], 0);
- free(as);
- free(av);
+ for (i = 0; i < words.len; i++)
+ Var_Export1(words.words[i], 0);
+ Words_Free(words);
}
free(val);
}
@@ -645,13 +641,11 @@ Var_Export(const char *str, Boolean isEx
val = Var_Subst(str, VAR_GLOBAL, VARE_WANTRES);
if (val[0] != '\0') {
- char *as;
- size_t ac;
- char **av = brk_string(val, FALSE, &ac, &as);
+ Words words = Str_Words(val, FALSE);
size_t i;
- for (i = 0; i < ac; i++) {
- const char *name = av[i];
+ for (i = 0; i < words.len; i++) {
+ const char *name = words.words[i];
if (Var_Export1(name, flags)) {
if (var_exportedVars != VAR_EXPORTED_ALL)
var_exportedVars = VAR_EXPORTED_YES;
@@ -660,8 +654,7 @@ Var_Export(const char *str, Boolean isEx
}
}
}
- free(as);
- free(av);
+ Words_Free(words);
}
free(val);
}
@@ -723,20 +716,18 @@ Var_UnExport(const char *str)
{
Var *v;
- char **av;
- char *as;
- size_t ac;
size_t i;
- av = brk_string(varnames, FALSE, &ac, &as);
- for (i = 0; i < ac; i++) {
- v = VarFind(av[i], VAR_GLOBAL, 0);
+ Words words = Str_Words(varnames, FALSE);
+ for (i = 0; i < words.len; i++) {
+ const char *varname = words.words[i];
+ v = VarFind(varname, VAR_GLOBAL, 0);
if (v == NULL) {
- VAR_DEBUG("Not unexporting \"%s\" (not found)\n", av[i]);
+ VAR_DEBUG("Not unexporting \"%s\" (not found)\n", varname);
continue;
}
- VAR_DEBUG("Unexporting \"%s\"\n", av[i]);
+ VAR_DEBUG("Unexporting \"%s\"\n", varname);
if (!unexport_env && (v->flags & VAR_EXPORTED) &&
!(v->flags & VAR_REEXPORT))
unsetenv(v->name);
@@ -756,8 +747,7 @@ Var_UnExport(const char *str)
free(expr);
}
}
- free(as);
- free(av);
+ Words_Free(words);
if (varnames != str) {
Var_Delete(MAKE_EXPORTED, VAR_GLOBAL);
free(varnames_freeIt);
@@ -1483,9 +1473,7 @@ static char *
VarSelectWords(char sep, Boolean oneBigWord, const char *str, int first,
int last)
{
- char **av; /* word list */
- char *as; /* word list memory */
- size_t ac;
+ Words words;
int start, end, step;
int i;
@@ -1493,14 +1481,14 @@ VarSelectWords(char sep, Boolean oneBigW
SepBuf_Init(&buf, sep);
if (oneBigWord) {
- /* fake what brk_string() would do if there were only one word */
- ac = 1;
- av = bmake_malloc((ac + 1) * sizeof(char *));
- as = bmake_strdup(str);
- av[0] = as;
- av[1] = NULL;
+ /* fake what Str_Words() would do if there were only one word */
+ words.len = 1;
+ words.words = bmake_malloc((words.len + 1) * sizeof(char *));
+ words.freeIt = bmake_strdup(str);
+ words.words[0] = words.freeIt;
+ words.words[1] = NULL;
} else {
- av = brk_string(str, FALSE, &ac, &as);
+ words = Str_Words(str, FALSE);
}
/*
@@ -1509,30 +1497,29 @@ VarSelectWords(char sep, Boolean oneBigW
* (-1 gets converted to ac, -2 gets converted to (ac - 1), etc.).
*/
if (first < 0)
- first += (int)ac + 1;
+ first += (int)words.len + 1;
if (last < 0)
- last += (int)ac + 1;
+ last += (int)words.len + 1;
/*
* We avoid scanning more of the list than we need to.
*/
if (first > last) {
- start = MIN((int)ac, first) - 1;
+ start = MIN((int)words.len, first) - 1;
end = MAX(0, last - 1);
step = -1;
} else {
start = MAX(0, first - 1);
- end = MIN((int)ac, last);
+ end = MIN((int)words.len, last);
step = 1;
}
for (i = start; (step < 0) == (i >= end); i += step) {
- SepBuf_AddStr(&buf, av[i]);
+ SepBuf_AddStr(&buf, words.words[i]);
SepBuf_Sep(&buf);
}
- free(as);
- free(av);
+ Words_Free(words);
return SepBuf_Destroy(&buf, FALSE);
}
@@ -1571,9 +1558,7 @@ ModifyWords(GNode *ctx, char sep, Boolea
ModifyWordsCallback modifyWord, void *modifyWord_args)
{
SepBuf result;
- char **av; /* word list */
- char *as; /* word list memory */
- size_t ac;
+ Words words;
size_t i;
if (oneBigWord) {
@@ -1584,39 +1569,37 @@ ModifyWords(GNode *ctx, char sep, Boolea
SepBuf_Init(&result, sep);
- av = brk_string(str, FALSE, &ac, &as);
+ words = Str_Words(str, FALSE);
- VAR_DEBUG("ModifyWords: split \"%s\" into %zu words\n", str, ac);
+ VAR_DEBUG("ModifyWords: split \"%s\" into %zu words\n", str, words.len);
- for (i = 0; i < ac; i++) {
- modifyWord(av[i], &result, modifyWord_args);
+ for (i = 0; i < words.len; i++) {
+ modifyWord(words.words[i], &result, modifyWord_args);
if (result.buf.count > 0)
SepBuf_Sep(&result);
}
- free(as);
- free(av);
+ Words_Free(words);
return SepBuf_Destroy(&result, FALSE);
}
static char *
-WordList_JoinFree(char **av, size_t ac, char *as)
+Words_JoinFree(Words words)
{
Buffer buf;
size_t i;
Buf_Init(&buf, 0);
- for (i = 0; i < ac; i++) {
+ for (i = 0; i < words.len; i++) {
if (i != 0)
Buf_AddByte(&buf, ' '); /* XXX: st->sep, for consistency */
- Buf_AddStr(&buf, av[i]);
+ Buf_AddStr(&buf, words.words[i]);
}
- free(av);
- free(as);
+ Words_Free(words);
return Buf_Destroy(&buf, FALSE);
}
@@ -1625,9 +1608,9 @@ WordList_JoinFree(char **av, size_t ac,
static char *
VarUniq(const char *str)
{
- char *as; /* Word list memory */
- size_t ac;
- char **av = brk_string(str, FALSE, &ac, &as);
+ Words words = Str_Words(str, FALSE);
+ size_t ac = words.len;
+ char **av = words.words;
if (ac > 1) {
size_t i, j;
@@ -1637,7 +1620,7 @@ VarUniq(const char *str)
ac = j + 1;
}
- return WordList_JoinFree(av, ac, as);
+ return Words_JoinFree(words);
}
@@ -2238,10 +2221,9 @@ ApplyModifier_Range(const char **pp, App
}
if (n == 0) {
- char *as;
- char **av = brk_string(st->val, FALSE, &n, &as);
- free(as);
- free(av);
+ Words words = Str_Words(st->val, FALSE);
+ n = words.len;
+ Words_Free(words);
}
Buf_Init(&buf, 0);
@@ -2629,15 +2611,11 @@ ApplyModifier_Words(const char **pp, App
} else {
Buffer buf;
- /* XXX: brk_string() is a rather expensive
- * way of counting words. */
- char *as;
- size_t ac;
- char **av = brk_string(st->val, FALSE, &ac, &as);
- free(as);
- free(av);
-
- Buf_Init(&buf, 4); /* 3 digits + '\0' */
+ Words words = Str_Words(st->val, FALSE);
+ size_t ac = words.len;
+ Words_Free(words);
+
+ Buf_Init(&buf, 4); /* 3 digits + '\0' is usually enough */
Buf_AddInt(&buf, (int)ac);
st->newVal = Buf_Destroy(&buf, FALSE);
}
@@ -2722,13 +2700,11 @@ ApplyModifier_Order(const char **pp, App
{
const char *mod = (*pp)++; /* skip past the 'O' in any case */
- char *as; /* word list memory */
- size_t ac;
- char **av = brk_string(st->val, FALSE, &ac, &as);
+ Words words = Str_Words(st->val, FALSE);
if (mod[1] == st->endc || mod[1] == ':') {
/* :O sorts ascending */
- qsort(av, ac, sizeof(char *), str_cmp_asc);
+ qsort(words.words, words.len, sizeof(char *), str_cmp_asc);
} else if ((mod[1] == 'r' || mod[1] == 'x') &&
(mod[2] == st->endc || mod[2] == ':')) {
@@ -2736,7 +2712,7 @@ ApplyModifier_Order(const char **pp, App
if (mod[1] == 'r') {
/* :Or sorts descending */
- qsort(av, ac, sizeof(char *), str_cmp_desc);
+ qsort(words.words, words.len, sizeof(char *), str_cmp_desc);
} else {
/* :Ox shuffles
@@ -2747,20 +2723,19 @@ ApplyModifier_Order(const char **pp, App
* 0 with probability 1).
*/
size_t i;
- for (i = ac - 1; i > 0; i--) {
+ for (i = words.len - 1; i > 0; i--) {
size_t rndidx = (size_t)random() % (i + 1);
- char *t = av[i];
- av[i] = av[rndidx];
- av[rndidx] = t;
+ char *t = words.words[i];
+ words.words[i] = words.words[rndidx];
+ words.words[rndidx] = t;
}
}
} else {
- free(as);
- free(av);
+ Words_Free(words);
return AMR_BAD;
}
- st->newVal = WordList_JoinFree(av, ac, as);
+ st->newVal = Words_JoinFree(words);
return AMR_OK;
}