Commit 10044422 authored by Rusty Russell's avatar Rusty Russell

strsplit: remove nump argument

You can use talloc_array_length() to get the length of a tallocated array.
parent e70eae05
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
* all = grab_fd(NULL, 0, NULL); * all = grab_fd(NULL, 0, NULL);
* if (!all) * if (!all)
* return NULL; * return NULL;
* lines = strsplit(NULL, all, "\n", NULL); * lines = strsplit(NULL, all, "\n");
* talloc_free(all); * talloc_free(all);
* return lines; * return lines;
* } * }
...@@ -52,7 +52,7 @@ void *grab_fd(const void *ctx, int fd, size_t *size); ...@@ -52,7 +52,7 @@ void *grab_fd(const void *ctx, int fd, size_t *size);
* all = grab_file(NULL, filename, NULL); * all = grab_file(NULL, filename, NULL);
* if (!all) * if (!all)
* return NULL; * return NULL;
* lines = strsplit(NULL, all, "\n", NULL); * lines = strsplit(NULL, all, "\n");
* talloc_free(all); * talloc_free(all);
* return lines; * return lines;
* } * }
......
...@@ -18,7 +18,7 @@ main(int argc, char *argv[]) ...@@ -18,7 +18,7 @@ main(int argc, char *argv[])
struct stat st; struct stat st;
str = grab_file(NULL, "test/run-grab.c", NULL); str = grab_file(NULL, "test/run-grab.c", NULL);
split = strsplit(NULL, str, "\n", NULL); split = strsplit(NULL, str, "\n");
length = strlen(split[0]); length = strlen(split[0]);
ok1(!strcmp(split[0], "/* This is test for grab_file() function")); ok1(!strcmp(split[0], "/* This is test for grab_file() function"));
for (i = 1; split[i]; i++) for (i = 1; split[i]; i++)
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
* textfile = grab_file(NULL, argv[1], NULL); * textfile = grab_file(NULL, argv[1], NULL);
* if (!textfile) * if (!textfile)
* err(1, "Failed reading %s", argv[1]); * err(1, "Failed reading %s", argv[1]);
* lines = strsplit(textfile, textfile, "\n", NULL); * lines = strsplit(textfile, textfile, "\n");
* *
* // Join them back together with two linefeeds. * // Join them back together with two linefeeds.
* printf("%s", strjoin(textfile, lines, "\n\n")); * printf("%s", strjoin(textfile, lines, "\n\n"));
......
...@@ -11,8 +11,7 @@ ...@@ -11,8 +11,7 @@
#include <ccan/talloc/talloc.h> #include <ccan/talloc/talloc.h>
#include <ccan/str/str.h> #include <ccan/str/str.h>
char **strsplit(const void *ctx, const char *string, const char *delims, char **strsplit(const void *ctx, const char *string, const char *delims)
unsigned int *nump)
{ {
char **lines = NULL; char **lines = NULL;
unsigned int max = 64, num = 0; unsigned int max = 64, num = 0;
...@@ -30,9 +29,9 @@ char **strsplit(const void *ctx, const char *string, const char *delims, ...@@ -30,9 +29,9 @@ char **strsplit(const void *ctx, const char *string, const char *delims,
lines = talloc_realloc(ctx, lines, char *, max*=2 + 1); lines = talloc_realloc(ctx, lines, char *, max*=2 + 1);
} }
lines[num] = NULL; lines[num] = NULL;
if (nump)
*nump = num; /* Shrink, so talloc_get_size works */
return lines; return talloc_realloc(ctx, lines, char *, num+1);
} }
char *strjoin(const void *ctx, char *strings[], const char *delim) char *strjoin(const void *ctx, char *strings[], const char *delim)
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
* @ctx: the context to tallocate from (often NULL) * @ctx: the context to tallocate from (often NULL)
* @string: the string to split * @string: the string to split
* @delims: delimiters where lines should be split. * @delims: delimiters where lines should be split.
* @nump: optional pointer to place resulting number of lines
* *
* This function splits a single string into multiple strings. The * This function splits a single string into multiple strings. The
* original string is untouched: an array is allocated (using talloc) * original string is untouched: an array is allocated (using talloc)
...@@ -16,8 +15,9 @@ ...@@ -16,8 +15,9 @@
* in empty substrings. By definition, no delimiters will appear in * in empty substrings. By definition, no delimiters will appear in
* the substrings. * the substrings.
* *
* The final char * in the array will be NULL, so you can use this or * The final char * in the array will be NULL, talloc_array_length() of the
* @nump to find the array length. * returned value is 1 greater than the number of valid elements in
* the array.
* *
* Example: * Example:
* #include <ccan/talloc/talloc.h> * #include <ccan/talloc/talloc.h>
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
* unsigned int i, long_lines = 0; * unsigned int i, long_lines = 0;
* *
* // Can only fail on out-of-memory. * // Can only fail on out-of-memory.
* lines = strsplit(NULL, string, "\n", NULL); * lines = strsplit(NULL, string, "\n");
* for (i = 0; lines[i] != NULL; i++) * for (i = 0; lines[i] != NULL; i++)
* if (strlen(lines[i]) > 80) * if (strlen(lines[i]) > 80)
* long_lines++; * long_lines++;
...@@ -37,8 +37,7 @@ ...@@ -37,8 +37,7 @@
* return long_lines; * return long_lines;
* } * }
*/ */
char **strsplit(const void *ctx, const char *string, const char *delims, char **strsplit(const void *ctx, const char *string, const char *delims);
unsigned int *nump);
/** /**
* strjoin - Join an array of substrings into one long string * strjoin - Join an array of substrings into one long string
...@@ -56,7 +55,7 @@ char **strsplit(const void *ctx, const char *string, const char *delims, ...@@ -56,7 +55,7 @@ char **strsplit(const void *ctx, const char *string, const char *delims,
* { * {
* char **lines, *ret; * char **lines, *ret;
* *
* lines = strsplit(NULL, string, "\n", NULL); * lines = strsplit(NULL, string, "\n");
* ret = strjoin(NULL, lines, "-- EOL\n"); * ret = strjoin(NULL, lines, "-- EOL\n");
* talloc_free(lines); * talloc_free(lines);
* return ret; * return ret;
......
...@@ -4,34 +4,26 @@ ...@@ -4,34 +4,26 @@
#include <ccan/str_talloc/str_talloc.c> #include <ccan/str_talloc/str_talloc.c>
#include <ccan/tap/tap.h> #include <ccan/tap/tap.h>
/* FIXME: ccanize */
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
static char *substrings[] = { "far", "bar", "baz", "b", "ba", "z", "ar", NULL }; static char *substrings[] = { "far", "bar", "baz", "b", "ba", "z", "ar", NULL };
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
unsigned int n;
char **split, *str; char **split, *str;
void *ctx; void *ctx;
plan_tests(19); plan_tests(16);
split = strsplit(NULL, "hello world", " ", &n); split = strsplit(NULL, "hello world", " ");
ok1(n == 3); ok1(talloc_array_length(split) == 4);
ok1(!strcmp(split[0], "hello")); ok1(!strcmp(split[0], "hello"));
ok1(!strcmp(split[1], "")); ok1(!strcmp(split[1], ""));
ok1(!strcmp(split[2], "world")); ok1(!strcmp(split[2], "world"));
ok1(split[3] == NULL); ok1(split[3] == NULL);
talloc_free(split); talloc_free(split);
split = strsplit(NULL, "hello world", " ", NULL); split = strsplit(NULL, "hello world", "o ");
ok1(!strcmp(split[0], "hello")); ok1(talloc_array_length(split) == 6);
ok1(!strcmp(split[1], ""));
ok1(!strcmp(split[2], "world"));
ok1(split[3] == NULL);
talloc_free(split);
split = strsplit(NULL, "hello world", "o ", NULL);
ok1(!strcmp(split[0], "hell")); ok1(!strcmp(split[0], "hell"));
ok1(!strcmp(split[1], "")); ok1(!strcmp(split[1], ""));
ok1(!strcmp(split[2], "")); ok1(!strcmp(split[2], ""));
...@@ -40,7 +32,7 @@ int main(int argc, char *argv[]) ...@@ -40,7 +32,7 @@ int main(int argc, char *argv[])
ok1(split[5] == NULL); ok1(split[5] == NULL);
ctx = split; ctx = split;
split = strsplit(ctx, "hello world", "o ", NULL); split = strsplit(ctx, "hello world", "o ");
ok1(talloc_parent(split) == ctx); ok1(talloc_parent(split) == ctx);
talloc_free(ctx); talloc_free(ctx);
......
...@@ -872,11 +872,11 @@ static struct op *load_tracefile(char *filename[], ...@@ -872,11 +872,11 @@ static struct op *load_tracefile(char *filename[],
if (!contents) if (!contents)
err(1, "Reading %s", filename[file]); err(1, "Reading %s", filename[file]);
lines = strsplit(contents, contents, "\n", NULL); lines = strsplit(contents, contents, "\n");
if (!lines[0]) if (!lines[0])
errx(1, "%s is empty", filename[file]); errx(1, "%s is empty", filename[file]);
words = strsplit(lines, lines[0], " ", NULL); words = strsplit(lines, lines[0], " ");
if (!streq(words[1], "tdb_open")) if (!streq(words[1], "tdb_open"))
fail(filename[file], 1, "does not start with tdb_open"); fail(filename[file], 1, "does not start with tdb_open");
...@@ -887,7 +887,7 @@ static struct op *load_tracefile(char *filename[], ...@@ -887,7 +887,7 @@ static struct op *load_tracefile(char *filename[],
for (i = 1; lines[i]; i++) { for (i = 1; lines[i]; i++) {
const struct op_table *opt; const struct op_table *opt;
words = strsplit(lines, lines[i], " ", NULL); words = strsplit(lines, lines[i], " ");
if (!words[0] || !words[1]) if (!words[0] || !words[1])
fail(filename[file], i+1, fail(filename[file], i+1,
"Expected seqnum number and op"); "Expected seqnum number and op");
......
...@@ -238,7 +238,7 @@ static void init_tests(void) ...@@ -238,7 +238,7 @@ static void init_tests(void)
/* Resolve dependencies. */ /* Resolve dependencies. */
foreach_ptr(list, &compulsory_tests, &normal_tests) { foreach_ptr(list, &compulsory_tests, &normal_tests) {
list_for_each(list, c, list) { list_for_each(list, c, list) {
char **deps = strsplit(NULL, c->needs, " ", NULL); char **deps = strsplit(NULL, c->needs, " ");
unsigned int i; unsigned int i;
for (i = 0; deps[i]; i++) { for (i = 0; deps[i]; i++) {
...@@ -410,8 +410,8 @@ static void add_info_options(struct ccan_file *info, bool mark_fails) ...@@ -410,8 +410,8 @@ static void add_info_options(struct ccan_file *info, bool mark_fails)
continue; continue;
for (i = 0; i < d->num_lines; i++) { for (i = 0; i < d->num_lines; i++) {
char **words = collapse(strsplit(d, d->lines[i], " \t", char **words = collapse(strsplit(d, d->lines[i], " \t"),
NULL), NULL); NULL);
if (!words[0]) if (!words[0])
continue; continue;
......
...@@ -54,9 +54,10 @@ const char *get_ccan_file_contents(struct ccan_file *f) ...@@ -54,9 +54,10 @@ const char *get_ccan_file_contents(struct ccan_file *f)
char **get_ccan_file_lines(struct ccan_file *f) char **get_ccan_file_lines(struct ccan_file *f)
{ {
if (!f->lines) if (!f->lines)
f->lines = strsplit(f, get_ccan_file_contents(f), f->lines = strsplit(f, get_ccan_file_contents(f), "\n");
"\n", &f->num_lines);
/* FIXME: is f->num_lines necessary? */
f->num_lines = talloc_array_length(f->lines) - 1;
return f->lines; return f->lines;
} }
...@@ -64,7 +65,7 @@ struct list_head *get_ccan_file_docs(struct ccan_file *f) ...@@ -64,7 +65,7 @@ struct list_head *get_ccan_file_docs(struct ccan_file *f)
{ {
if (!f->doc_sections) { if (!f->doc_sections) {
get_ccan_file_lines(f); get_ccan_file_lines(f);
f->doc_sections = extract_doc_sections(f->lines, f->num_lines); f->doc_sections = extract_doc_sections(f->lines);
} }
return f->doc_sections; return f->doc_sections;
} }
......
...@@ -54,7 +54,7 @@ static unsigned int score_coverage(float covered, unsigned total) ...@@ -54,7 +54,7 @@ static unsigned int score_coverage(float covered, unsigned total)
static void analyze_coverage(struct manifest *m, bool full_gcov, static void analyze_coverage(struct manifest *m, bool full_gcov,
const char *output, struct score *score) const char *output, struct score *score)
{ {
char **lines = strsplit(score, output, "\n", NULL); char **lines = strsplit(score, output, "\n");
float covered_lines = 0.0; float covered_lines = 0.0;
unsigned int i, total_lines = 0; unsigned int i, total_lines = 0;
bool lines_matter = false; bool lines_matter = false;
......
...@@ -52,11 +52,11 @@ static bool blank_line(const char *line) ...@@ -52,11 +52,11 @@ static bool blank_line(const char *line)
static char *get_leaks(const char *output, char **errs) static char *get_leaks(const char *output, char **errs)
{ {
char *leaks = talloc_strdup(output, ""); char *leaks = talloc_strdup(output, "");
unsigned int i, num; unsigned int i;
char **lines = strsplit(output, output, "\n", &num); char **lines = strsplit(output, output, "\n");
*errs = talloc_strdup(output, ""); *errs = talloc_strdup(output, "");
for (i = 0; i < num; i++) { for (i = 0; i < talloc_array_length(lines) - 1; i++) {
if (strstr(lines[i], " lost ")) { if (strstr(lines[i], " lost ")) {
/* A leak... */ /* A leak... */
if (strstr(lines[i], " definitely lost ")) { if (strstr(lines[i], " definitely lost ")) {
......
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
static char ** __attribute__((format(printf, 3, 4))) static char ** __attribute__((format(printf, 2, 3)))
lines_from_cmd(const void *ctx, unsigned int *num, char *format, ...) lines_from_cmd(const void *ctx, char *format, ...)
{ {
va_list ap; va_list ap;
char *cmd, *buffer; char *cmd, *buffer;
...@@ -32,7 +32,7 @@ lines_from_cmd(const void *ctx, unsigned int *num, char *format, ...) ...@@ -32,7 +32,7 @@ lines_from_cmd(const void *ctx, unsigned int *num, char *format, ...)
err(1, "Reading from '%s'", cmd); err(1, "Reading from '%s'", cmd);
pclose(p); pclose(p);
return strsplit(ctx, buffer, "\n", num); return strsplit(ctx, buffer, "\n");
} }
/* Be careful about trying to compile over running programs (parallel make). /* Be careful about trying to compile over running programs (parallel make).
...@@ -80,9 +80,11 @@ static char **get_one_deps(const void *ctx, const char *dir, ...@@ -80,9 +80,11 @@ static char **get_one_deps(const void *ctx, const char *dir,
} }
cmd = talloc_asprintf(ctx, "%s depends", *infofile); cmd = talloc_asprintf(ctx, "%s depends", *infofile);
deps = lines_from_cmd(cmd, num, "%s", cmd); deps = lines_from_cmd(cmd, "%s", cmd);
if (!deps) if (!deps)
err(1, "Could not run '%s'", cmd); err(1, "Could not run '%s'", cmd);
/* FIXME: Do we need num arg? */
*num = talloc_array_length(deps) - 1;
return deps; return deps;
} }
...@@ -120,7 +122,7 @@ static char **get_one_safe_deps(const void *ctx, ...@@ -120,7 +122,7 @@ static char **get_one_safe_deps(const void *ctx,
char **infofile) char **infofile)
{ {
char **deps, **lines, *raw, *fname; char **deps, **lines, *raw, *fname;
unsigned int i, n = 0; unsigned int i, n;
fname = talloc_asprintf(ctx, "%s/_info", dir); fname = talloc_asprintf(ctx, "%s/_info", dir);
raw = grab_file(fname, fname, NULL); raw = grab_file(fname, fname, NULL);
...@@ -128,9 +130,9 @@ static char **get_one_safe_deps(const void *ctx, ...@@ -128,9 +130,9 @@ static char **get_one_safe_deps(const void *ctx,
errx(1, "Could not open %s", fname); errx(1, "Could not open %s", fname);
/* Replace \n by actual line breaks, and split it. */ /* Replace \n by actual line breaks, and split it. */
lines = strsplit(raw, replace(raw, raw, "\\n", "\n"), "\n", &n); lines = strsplit(raw, replace(raw, raw, "\\n", "\n"), "\n");
deps = talloc_array(ctx, char *, n+1); deps = talloc_array(ctx, char *, talloc_array_length(lines));
for (n = i = 0; lines[i]; i++) { for (n = i = 0; lines[i]; i++) {
char *str; char *str;
...@@ -222,9 +224,11 @@ char **get_libs(const void *ctx, const char *dir, ...@@ -222,9 +224,11 @@ char **get_libs(const void *ctx, const char *dir,
} }
cmd = talloc_asprintf(ctx, "%s libs", *infofile); cmd = talloc_asprintf(ctx, "%s libs", *infofile);
libs = lines_from_cmd(cmd, num, "%s", cmd); libs = lines_from_cmd(cmd, "%s", cmd);
if (!libs) if (!libs)
err(1, "Could not run '%s'", cmd); err(1, "Could not run '%s'", cmd);
/* FIXME: Do we need num arg? */
*num = talloc_array_length(libs) - 1;
return libs; return libs;
} }
......
...@@ -15,14 +15,14 @@ ...@@ -15,14 +15,14 @@
#include "doc_extract.h" #include "doc_extract.h"
#include "tools.h" #include "tools.h"
static char **grab_doc(char **lines, unsigned int num, unsigned int **linemap) static char **grab_doc(char **lines, unsigned int **linemap)
{ {
char **ret; char **ret;
unsigned int i; unsigned int i, num;
bool printing = false; bool printing = false;
ret = talloc_array(NULL, char *, num+1); ret = talloc_array(NULL, char *, talloc_array_length(lines));
*linemap = talloc_array(ret, unsigned int, num); *linemap = talloc_array(ret, unsigned int, talloc_array_length(lines));
num = 0; num = 0;
for (i = 0; lines[i]; i++) { for (i = 0; lines[i]; i++) {
...@@ -129,10 +129,10 @@ static void add_line(struct doc_section *curr, const char *line) ...@@ -129,10 +129,10 @@ static void add_line(struct doc_section *curr, const char *line)
curr->lines[curr->num_lines++] = talloc_strdup(curr->lines, line); curr->lines[curr->num_lines++] = talloc_strdup(curr->lines, line);
} }
struct list_head *extract_doc_sections(char **rawlines, unsigned int num) struct list_head *extract_doc_sections(char **rawlines)
{ {
unsigned int *linemap; unsigned int *linemap;
char **lines = grab_doc(rawlines, num, &linemap); char **lines = grab_doc(rawlines, &linemap);
const char *function = NULL; const char *function = NULL;
struct doc_section *curr = NULL; struct doc_section *curr = NULL;
unsigned int i; unsigned int i;
......
...@@ -27,16 +27,15 @@ int main(int argc, char *argv[]) ...@@ -27,16 +27,15 @@ int main(int argc, char *argv[])
type = argv[1]; type = argv[1];
for (i = 2; i < argc; i++) { for (i = 2; i < argc; i++) {
char *file, **lines; char *file, **lines;
unsigned int num;
struct list_head *list; struct list_head *list;
struct doc_section *d; struct doc_section *d;
file = grab_file(NULL, argv[i], NULL); file = grab_file(NULL, argv[i], NULL);
if (!file) if (!file)
err(1, "Reading file %s", argv[i]); err(1, "Reading file %s", argv[i]);
lines = strsplit(file, file, "\n", &num); lines = strsplit(file, file, "\n");
list = extract_doc_sections(lines, num); list = extract_doc_sections(lines);
if (list_empty(list)) if (list_empty(list))
errx(1, "No documentation in file %s", argv[i]); errx(1, "No documentation in file %s", argv[i]);
talloc_free(file); talloc_free(file);
......
...@@ -13,5 +13,5 @@ struct doc_section { ...@@ -13,5 +13,5 @@ struct doc_section {
char **lines; char **lines;
}; };
struct list_head *extract_doc_sections(char **rawlines, unsigned int num); struct list_head *extract_doc_sections(char **rawlines);
#endif /* _DOC_EXTRACT_CORE_H */ #endif /* _DOC_EXTRACT_CORE_H */
...@@ -445,7 +445,7 @@ static struct replace *read_replacement_file(const char *depdir) ...@@ -445,7 +445,7 @@ static struct replace *read_replacement_file(const char *depdir)
return NULL; return NULL;
} }
for (line = strsplit(file, file, "\n", NULL); *line; line++) for (line = strsplit(file, file, "\n"); *line; line++)
add_replace(&repl, *line); add_replace(&repl, *line);
return repl; return repl;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment