Merge branch 'tb/ban-strtok'
Mark strtok() and strtok_r() to be banned. * tb/ban-strtok: banned.h: mark `strtok()` and `strtok_r()` as banned t/helper/test-json-writer.c: avoid using `strtok()` t/helper/test-oidmap.c: avoid using `strtok()` t/helper/test-hashmap.c: avoid using `strtok()` string-list: introduce `string_list_setlen()` string-list: multi-delimiter `string_list_split_in_place()`
This commit is contained in:
commit
d699e27bd4
4
banned.h
4
banned.h
@ -18,6 +18,10 @@
|
|||||||
#define strncpy(x,y,n) BANNED(strncpy)
|
#define strncpy(x,y,n) BANNED(strncpy)
|
||||||
#undef strncat
|
#undef strncat
|
||||||
#define strncat(x,y,n) BANNED(strncat)
|
#define strncat(x,y,n) BANNED(strncat)
|
||||||
|
#undef strtok
|
||||||
|
#define strtok(x,y) BANNED(strtok)
|
||||||
|
#undef strtok_r
|
||||||
|
#define strtok_r(x,y,z) BANNED(strtok_r)
|
||||||
|
|
||||||
#undef sprintf
|
#undef sprintf
|
||||||
#undef vsprintf
|
#undef vsprintf
|
||||||
|
@ -1685,11 +1685,11 @@ static int get_schedule_cmd(const char **cmd, int *is_available)
|
|||||||
if (is_available)
|
if (is_available)
|
||||||
*is_available = 0;
|
*is_available = 0;
|
||||||
|
|
||||||
string_list_split_in_place(&list, testing, ',', -1);
|
string_list_split_in_place(&list, testing, ",", -1);
|
||||||
for_each_string_list_item(item, &list) {
|
for_each_string_list_item(item, &list) {
|
||||||
struct string_list pair = STRING_LIST_INIT_NODUP;
|
struct string_list pair = STRING_LIST_INIT_NODUP;
|
||||||
|
|
||||||
if (string_list_split_in_place(&pair, item->string, ':', 2) != 2)
|
if (string_list_split_in_place(&pair, item->string, ":", 2) != 2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!strcmp(*cmd, pair.items[0].string)) {
|
if (!strcmp(*cmd, pair.items[0].string)) {
|
||||||
|
2
diff.c
2
diff.c
@ -139,7 +139,7 @@ static int parse_dirstat_params(struct diff_options *options, const char *params
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (*params_copy)
|
if (*params_copy)
|
||||||
string_list_split_in_place(¶ms, params_copy, ',', -1);
|
string_list_split_in_place(¶ms, params_copy, ",", -1);
|
||||||
for (i = 0; i < params.nr; i++) {
|
for (i = 0; i < params.nr; i++) {
|
||||||
const char *p = params.items[i].string;
|
const char *p = params.items[i].string;
|
||||||
if (!strcmp(p, "changes")) {
|
if (!strcmp(p, "changes")) {
|
||||||
|
2
notes.c
2
notes.c
@ -964,7 +964,7 @@ void string_list_add_refs_from_colon_sep(struct string_list *list,
|
|||||||
char *globs_copy = xstrdup(globs);
|
char *globs_copy = xstrdup(globs);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
string_list_split_in_place(&split, globs_copy, ':', -1);
|
string_list_split_in_place(&split, globs_copy, ":", -1);
|
||||||
string_list_remove_empty_items(&split, 0);
|
string_list_remove_empty_items(&split, 0);
|
||||||
|
|
||||||
for (i = 0; i < split.nr; i++)
|
for (i = 0; i < split.nr; i++)
|
||||||
|
@ -651,7 +651,7 @@ static struct snapshot *create_snapshot(struct packed_ref_store *refs)
|
|||||||
snapshot->buf,
|
snapshot->buf,
|
||||||
snapshot->eof - snapshot->buf);
|
snapshot->eof - snapshot->buf);
|
||||||
|
|
||||||
string_list_split_in_place(&traits, p, ' ', -1);
|
string_list_split_in_place(&traits, p, " ", -1);
|
||||||
|
|
||||||
if (unsorted_string_list_has_string(&traits, "fully-peeled"))
|
if (unsorted_string_list_has_string(&traits, "fully-peeled"))
|
||||||
snapshot->peeled = PEELED_FULLY;
|
snapshot->peeled = PEELED_FULLY;
|
||||||
|
@ -203,6 +203,15 @@ void string_list_clear_func(struct string_list *list, string_list_clear_func_t c
|
|||||||
list->nr = list->alloc = 0;
|
list->nr = list->alloc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void string_list_setlen(struct string_list *list, size_t nr)
|
||||||
|
{
|
||||||
|
if (list->strdup_strings)
|
||||||
|
BUG("cannot setlen a string_list which owns its entries");
|
||||||
|
if (nr > list->nr)
|
||||||
|
BUG("cannot grow a string_list with setlen");
|
||||||
|
list->nr = nr;
|
||||||
|
}
|
||||||
|
|
||||||
struct string_list_item *string_list_append_nodup(struct string_list *list,
|
struct string_list_item *string_list_append_nodup(struct string_list *list,
|
||||||
char *string)
|
char *string)
|
||||||
{
|
{
|
||||||
@ -301,7 +310,7 @@ int string_list_split(struct string_list *list, const char *string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int string_list_split_in_place(struct string_list *list, char *string,
|
int string_list_split_in_place(struct string_list *list, char *string,
|
||||||
int delim, int maxsplit)
|
const char *delim, int maxsplit)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
char *p = string, *end;
|
char *p = string, *end;
|
||||||
@ -315,7 +324,7 @@ int string_list_split_in_place(struct string_list *list, char *string,
|
|||||||
string_list_append(list, p);
|
string_list_append(list, p);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
end = strchr(p, delim);
|
end = strpbrk(p, delim);
|
||||||
if (end) {
|
if (end) {
|
||||||
*end = '\0';
|
*end = '\0';
|
||||||
string_list_append(list, p);
|
string_list_append(list, p);
|
||||||
|
@ -134,6 +134,16 @@ typedef void (*string_list_clear_func_t)(void *p, const char *str);
|
|||||||
/** Call a custom clear function on each util pointer */
|
/** Call a custom clear function on each util pointer */
|
||||||
void string_list_clear_func(struct string_list *list, string_list_clear_func_t clearfunc);
|
void string_list_clear_func(struct string_list *list, string_list_clear_func_t clearfunc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the length of a string_list to `nr`, provided that (a) `list`
|
||||||
|
* does not own its own storage, and (b) that `nr` is no larger than
|
||||||
|
* `list->nr`.
|
||||||
|
*
|
||||||
|
* Useful when "shrinking" `list` to write over existing entries that
|
||||||
|
* are no longer used without reallocating.
|
||||||
|
*/
|
||||||
|
void string_list_setlen(struct string_list *list, size_t nr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply `func` to each item. If `func` returns nonzero, the
|
* Apply `func` to each item. If `func` returns nonzero, the
|
||||||
* iteration aborts and the return value is propagated.
|
* iteration aborts and the return value is propagated.
|
||||||
@ -270,5 +280,5 @@ int string_list_split(struct string_list *list, const char *string,
|
|||||||
* list->strdup_strings must *not* be set.
|
* list->strdup_strings must *not* be set.
|
||||||
*/
|
*/
|
||||||
int string_list_split_in_place(struct string_list *list, char *string,
|
int string_list_split_in_place(struct string_list *list, char *string,
|
||||||
int delim, int maxsplit);
|
const char *delim, int maxsplit);
|
||||||
#endif /* STRING_LIST_H */
|
#endif /* STRING_LIST_H */
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "git-compat-util.h"
|
#include "git-compat-util.h"
|
||||||
#include "hashmap.h"
|
#include "hashmap.h"
|
||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
|
#include "string-list.h"
|
||||||
|
|
||||||
struct test_entry
|
struct test_entry
|
||||||
{
|
{
|
||||||
@ -150,6 +151,7 @@ static void perf_hashmap(unsigned int method, unsigned int rounds)
|
|||||||
*/
|
*/
|
||||||
int cmd__hashmap(int argc, const char **argv)
|
int cmd__hashmap(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
|
struct string_list parts = STRING_LIST_INIT_NODUP;
|
||||||
struct strbuf line = STRBUF_INIT;
|
struct strbuf line = STRBUF_INIT;
|
||||||
int icase;
|
int icase;
|
||||||
struct hashmap map = HASHMAP_INIT(test_entry_cmp, &icase);
|
struct hashmap map = HASHMAP_INIT(test_entry_cmp, &icase);
|
||||||
@ -159,21 +161,26 @@ int cmd__hashmap(int argc, const char **argv)
|
|||||||
|
|
||||||
/* process commands from stdin */
|
/* process commands from stdin */
|
||||||
while (strbuf_getline(&line, stdin) != EOF) {
|
while (strbuf_getline(&line, stdin) != EOF) {
|
||||||
char *cmd, *p1 = NULL, *p2 = NULL;
|
char *cmd, *p1, *p2;
|
||||||
unsigned int hash = 0;
|
unsigned int hash = 0;
|
||||||
struct test_entry *entry;
|
struct test_entry *entry;
|
||||||
|
|
||||||
/* break line into command and up to two parameters */
|
/* break line into command and up to two parameters */
|
||||||
cmd = strtok(line.buf, DELIM);
|
string_list_setlen(&parts, 0);
|
||||||
|
string_list_split_in_place(&parts, line.buf, DELIM, 2);
|
||||||
|
string_list_remove_empty_items(&parts, 0);
|
||||||
|
|
||||||
/* ignore empty lines */
|
/* ignore empty lines */
|
||||||
if (!cmd || *cmd == '#')
|
if (!parts.nr)
|
||||||
|
continue;
|
||||||
|
if (!*parts.items[0].string || *parts.items[0].string == '#')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
p1 = strtok(NULL, DELIM);
|
cmd = parts.items[0].string;
|
||||||
if (p1) {
|
p1 = parts.nr >= 1 ? parts.items[1].string : NULL;
|
||||||
|
p2 = parts.nr >= 2 ? parts.items[2].string : NULL;
|
||||||
|
if (p1)
|
||||||
hash = icase ? strihash(p1) : strhash(p1);
|
hash = icase ? strihash(p1) : strhash(p1);
|
||||||
p2 = strtok(NULL, DELIM);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp("add", cmd) && p1 && p2) {
|
if (!strcmp("add", cmd) && p1 && p2) {
|
||||||
|
|
||||||
@ -260,6 +267,7 @@ int cmd__hashmap(int argc, const char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string_list_clear(&parts, 0);
|
||||||
strbuf_release(&line);
|
strbuf_release(&line);
|
||||||
hashmap_clear_and_free(&map, struct test_entry, ent);
|
hashmap_clear_and_free(&map, struct test_entry, ent);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "test-tool.h"
|
#include "test-tool.h"
|
||||||
#include "json-writer.h"
|
#include "json-writer.h"
|
||||||
|
#include "string-list.h"
|
||||||
|
|
||||||
static const char *expect_obj1 = "{\"a\":\"abc\",\"b\":42,\"c\":true}";
|
static const char *expect_obj1 = "{\"a\":\"abc\",\"b\":42,\"c\":true}";
|
||||||
static const char *expect_obj2 = "{\"a\":-1,\"b\":2147483647,\"c\":0}";
|
static const char *expect_obj2 = "{\"a\":-1,\"b\":2147483647,\"c\":0}";
|
||||||
@ -394,35 +395,41 @@ static int unit_tests(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_s(int line_nr, char **s_in)
|
struct line {
|
||||||
|
struct string_list *parts;
|
||||||
|
size_t consumed_nr;
|
||||||
|
int nr;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void get_s(struct line *line, char **s_in)
|
||||||
{
|
{
|
||||||
*s_in = strtok(NULL, " ");
|
if (line->consumed_nr > line->parts->nr)
|
||||||
if (!*s_in)
|
die("line[%d]: expected: <s>", line->nr);
|
||||||
die("line[%d]: expected: <s>", line_nr);
|
*s_in = line->parts->items[line->consumed_nr++].string;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_i(int line_nr, intmax_t *s_in)
|
static void get_i(struct line *line, intmax_t *s_in)
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
|
||||||
get_s(line_nr, &s);
|
get_s(line, &s);
|
||||||
|
|
||||||
*s_in = strtol(s, &endptr, 10);
|
*s_in = strtol(s, &endptr, 10);
|
||||||
if (*endptr || errno == ERANGE)
|
if (*endptr || errno == ERANGE)
|
||||||
die("line[%d]: invalid integer value", line_nr);
|
die("line[%d]: invalid integer value", line->nr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_d(int line_nr, double *s_in)
|
static void get_d(struct line *line, double *s_in)
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
|
||||||
get_s(line_nr, &s);
|
get_s(line, &s);
|
||||||
|
|
||||||
*s_in = strtod(s, &endptr);
|
*s_in = strtod(s, &endptr);
|
||||||
if (*endptr || errno == ERANGE)
|
if (*endptr || errno == ERANGE)
|
||||||
die("line[%d]: invalid float value", line_nr);
|
die("line[%d]: invalid float value", line->nr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pretty;
|
static int pretty;
|
||||||
@ -453,6 +460,7 @@ static char *get_trimmed_line(char *buf, int buf_size)
|
|||||||
|
|
||||||
static int scripted(void)
|
static int scripted(void)
|
||||||
{
|
{
|
||||||
|
struct string_list parts = STRING_LIST_INIT_NODUP;
|
||||||
struct json_writer jw = JSON_WRITER_INIT;
|
struct json_writer jw = JSON_WRITER_INIT;
|
||||||
char buf[MAX_LINE_LENGTH];
|
char buf[MAX_LINE_LENGTH];
|
||||||
char *line;
|
char *line;
|
||||||
@ -470,66 +478,77 @@ static int scripted(void)
|
|||||||
die("expected first line to be 'object' or 'array'");
|
die("expected first line to be 'object' or 'array'");
|
||||||
|
|
||||||
while ((line = get_trimmed_line(buf, MAX_LINE_LENGTH)) != NULL) {
|
while ((line = get_trimmed_line(buf, MAX_LINE_LENGTH)) != NULL) {
|
||||||
|
struct line state = { 0 };
|
||||||
char *verb;
|
char *verb;
|
||||||
char *key;
|
char *key;
|
||||||
char *s_value;
|
char *s_value;
|
||||||
intmax_t i_value;
|
intmax_t i_value;
|
||||||
double d_value;
|
double d_value;
|
||||||
|
|
||||||
line_nr++;
|
state.parts = &parts;
|
||||||
|
state.nr = ++line_nr;
|
||||||
|
|
||||||
verb = strtok(line, " ");
|
/* break line into command and zero or more tokens */
|
||||||
|
string_list_setlen(&parts, 0);
|
||||||
|
string_list_split_in_place(&parts, line, " ", -1);
|
||||||
|
string_list_remove_empty_items(&parts, 0);
|
||||||
|
|
||||||
|
/* ignore empty lines */
|
||||||
|
if (!parts.nr || !*parts.items[0].string)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
verb = parts.items[state.consumed_nr++].string;
|
||||||
|
|
||||||
if (!strcmp(verb, "end")) {
|
if (!strcmp(verb, "end")) {
|
||||||
jw_end(&jw);
|
jw_end(&jw);
|
||||||
}
|
}
|
||||||
else if (!strcmp(verb, "object-string")) {
|
else if (!strcmp(verb, "object-string")) {
|
||||||
get_s(line_nr, &key);
|
get_s(&state, &key);
|
||||||
get_s(line_nr, &s_value);
|
get_s(&state, &s_value);
|
||||||
jw_object_string(&jw, key, s_value);
|
jw_object_string(&jw, key, s_value);
|
||||||
}
|
}
|
||||||
else if (!strcmp(verb, "object-int")) {
|
else if (!strcmp(verb, "object-int")) {
|
||||||
get_s(line_nr, &key);
|
get_s(&state, &key);
|
||||||
get_i(line_nr, &i_value);
|
get_i(&state, &i_value);
|
||||||
jw_object_intmax(&jw, key, i_value);
|
jw_object_intmax(&jw, key, i_value);
|
||||||
}
|
}
|
||||||
else if (!strcmp(verb, "object-double")) {
|
else if (!strcmp(verb, "object-double")) {
|
||||||
get_s(line_nr, &key);
|
get_s(&state, &key);
|
||||||
get_i(line_nr, &i_value);
|
get_i(&state, &i_value);
|
||||||
get_d(line_nr, &d_value);
|
get_d(&state, &d_value);
|
||||||
jw_object_double(&jw, key, i_value, d_value);
|
jw_object_double(&jw, key, i_value, d_value);
|
||||||
}
|
}
|
||||||
else if (!strcmp(verb, "object-true")) {
|
else if (!strcmp(verb, "object-true")) {
|
||||||
get_s(line_nr, &key);
|
get_s(&state, &key);
|
||||||
jw_object_true(&jw, key);
|
jw_object_true(&jw, key);
|
||||||
}
|
}
|
||||||
else if (!strcmp(verb, "object-false")) {
|
else if (!strcmp(verb, "object-false")) {
|
||||||
get_s(line_nr, &key);
|
get_s(&state, &key);
|
||||||
jw_object_false(&jw, key);
|
jw_object_false(&jw, key);
|
||||||
}
|
}
|
||||||
else if (!strcmp(verb, "object-null")) {
|
else if (!strcmp(verb, "object-null")) {
|
||||||
get_s(line_nr, &key);
|
get_s(&state, &key);
|
||||||
jw_object_null(&jw, key);
|
jw_object_null(&jw, key);
|
||||||
}
|
}
|
||||||
else if (!strcmp(verb, "object-object")) {
|
else if (!strcmp(verb, "object-object")) {
|
||||||
get_s(line_nr, &key);
|
get_s(&state, &key);
|
||||||
jw_object_inline_begin_object(&jw, key);
|
jw_object_inline_begin_object(&jw, key);
|
||||||
}
|
}
|
||||||
else if (!strcmp(verb, "object-array")) {
|
else if (!strcmp(verb, "object-array")) {
|
||||||
get_s(line_nr, &key);
|
get_s(&state, &key);
|
||||||
jw_object_inline_begin_array(&jw, key);
|
jw_object_inline_begin_array(&jw, key);
|
||||||
}
|
}
|
||||||
else if (!strcmp(verb, "array-string")) {
|
else if (!strcmp(verb, "array-string")) {
|
||||||
get_s(line_nr, &s_value);
|
get_s(&state, &s_value);
|
||||||
jw_array_string(&jw, s_value);
|
jw_array_string(&jw, s_value);
|
||||||
}
|
}
|
||||||
else if (!strcmp(verb, "array-int")) {
|
else if (!strcmp(verb, "array-int")) {
|
||||||
get_i(line_nr, &i_value);
|
get_i(&state, &i_value);
|
||||||
jw_array_intmax(&jw, i_value);
|
jw_array_intmax(&jw, i_value);
|
||||||
}
|
}
|
||||||
else if (!strcmp(verb, "array-double")) {
|
else if (!strcmp(verb, "array-double")) {
|
||||||
get_i(line_nr, &i_value);
|
get_i(&state, &i_value);
|
||||||
get_d(line_nr, &d_value);
|
get_d(&state, &d_value);
|
||||||
jw_array_double(&jw, i_value, d_value);
|
jw_array_double(&jw, i_value, d_value);
|
||||||
}
|
}
|
||||||
else if (!strcmp(verb, "array-true"))
|
else if (!strcmp(verb, "array-true"))
|
||||||
@ -552,6 +571,7 @@ static int scripted(void)
|
|||||||
printf("%s\n", jw.json.buf);
|
printf("%s\n", jw.json.buf);
|
||||||
|
|
||||||
jw_release(&jw);
|
jw_release(&jw);
|
||||||
|
string_list_clear(&parts, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "oidmap.h"
|
#include "oidmap.h"
|
||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
|
#include "string-list.h"
|
||||||
|
|
||||||
/* key is an oid and value is a name (could be a refname for example) */
|
/* key is an oid and value is a name (could be a refname for example) */
|
||||||
struct test_entry {
|
struct test_entry {
|
||||||
@ -25,6 +26,7 @@ struct test_entry {
|
|||||||
*/
|
*/
|
||||||
int cmd__oidmap(int argc UNUSED, const char **argv UNUSED)
|
int cmd__oidmap(int argc UNUSED, const char **argv UNUSED)
|
||||||
{
|
{
|
||||||
|
struct string_list parts = STRING_LIST_INIT_NODUP;
|
||||||
struct strbuf line = STRBUF_INIT;
|
struct strbuf line = STRBUF_INIT;
|
||||||
struct oidmap map = OIDMAP_INIT;
|
struct oidmap map = OIDMAP_INIT;
|
||||||
|
|
||||||
@ -35,19 +37,24 @@ int cmd__oidmap(int argc UNUSED, const char **argv UNUSED)
|
|||||||
|
|
||||||
/* process commands from stdin */
|
/* process commands from stdin */
|
||||||
while (strbuf_getline(&line, stdin) != EOF) {
|
while (strbuf_getline(&line, stdin) != EOF) {
|
||||||
char *cmd, *p1 = NULL, *p2 = NULL;
|
char *cmd, *p1, *p2;
|
||||||
struct test_entry *entry;
|
struct test_entry *entry;
|
||||||
struct object_id oid;
|
struct object_id oid;
|
||||||
|
|
||||||
/* break line into command and up to two parameters */
|
/* break line into command and up to two parameters */
|
||||||
cmd = strtok(line.buf, DELIM);
|
string_list_setlen(&parts, 0);
|
||||||
|
string_list_split_in_place(&parts, line.buf, DELIM, 2);
|
||||||
|
string_list_remove_empty_items(&parts, 0);
|
||||||
|
|
||||||
/* ignore empty lines */
|
/* ignore empty lines */
|
||||||
if (!cmd || *cmd == '#')
|
if (!parts.nr)
|
||||||
|
continue;
|
||||||
|
if (!*parts.items[0].string || *parts.items[0].string == '#')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
p1 = strtok(NULL, DELIM);
|
cmd = parts.items[0].string;
|
||||||
if (p1)
|
p1 = parts.nr >= 1 ? parts.items[1].string : NULL;
|
||||||
p2 = strtok(NULL, DELIM);
|
p2 = parts.nr >= 2 ? parts.items[2].string : NULL;
|
||||||
|
|
||||||
if (!strcmp("put", cmd) && p1 && p2) {
|
if (!strcmp("put", cmd) && p1 && p2) {
|
||||||
|
|
||||||
@ -108,6 +115,7 @@ int cmd__oidmap(int argc UNUSED, const char **argv UNUSED)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string_list_clear(&parts, 0);
|
||||||
strbuf_release(&line);
|
strbuf_release(&line);
|
||||||
oidmap_free(&map, 1);
|
oidmap_free(&map, 1);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -62,7 +62,7 @@ int cmd__string_list(int argc, const char **argv)
|
|||||||
struct string_list list = STRING_LIST_INIT_NODUP;
|
struct string_list list = STRING_LIST_INIT_NODUP;
|
||||||
int i;
|
int i;
|
||||||
char *s = xstrdup(argv[2]);
|
char *s = xstrdup(argv[2]);
|
||||||
int delim = *argv[3];
|
const char *delim = argv[3];
|
||||||
int maxsplit = atoi(argv[4]);
|
int maxsplit = atoi(argv[4]);
|
||||||
|
|
||||||
i = string_list_split_in_place(&list, s, delim, maxsplit);
|
i = string_list_split_in_place(&list, s, delim, maxsplit);
|
||||||
@ -111,7 +111,7 @@ int cmd__string_list(int argc, const char **argv)
|
|||||||
*/
|
*/
|
||||||
if (sb.len && sb.buf[sb.len - 1] == '\n')
|
if (sb.len && sb.buf[sb.len - 1] == '\n')
|
||||||
strbuf_setlen(&sb, sb.len - 1);
|
strbuf_setlen(&sb, sb.len - 1);
|
||||||
string_list_split_in_place(&list, sb.buf, '\n', -1);
|
string_list_split_in_place(&list, sb.buf, "\n", -1);
|
||||||
|
|
||||||
string_list_sort(&list);
|
string_list_sort(&list);
|
||||||
|
|
||||||
|
@ -18,6 +18,14 @@ test_split () {
|
|||||||
"
|
"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_split_in_place() {
|
||||||
|
cat >expected &&
|
||||||
|
test_expect_success "split (in place) $1 at $2, max $3" "
|
||||||
|
test-tool string-list split_in_place '$1' '$2' '$3' >actual &&
|
||||||
|
test_cmp expected actual
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
test_split "foo:bar:baz" ":" "-1" <<EOF
|
test_split "foo:bar:baz" ":" "-1" <<EOF
|
||||||
3
|
3
|
||||||
[0]: "foo"
|
[0]: "foo"
|
||||||
@ -61,6 +69,49 @@ test_split ":" ":" "-1" <<EOF
|
|||||||
[1]: ""
|
[1]: ""
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
test_split_in_place "foo:;:bar:;:baz:;:" ":;" "-1" <<EOF
|
||||||
|
10
|
||||||
|
[0]: "foo"
|
||||||
|
[1]: ""
|
||||||
|
[2]: ""
|
||||||
|
[3]: "bar"
|
||||||
|
[4]: ""
|
||||||
|
[5]: ""
|
||||||
|
[6]: "baz"
|
||||||
|
[7]: ""
|
||||||
|
[8]: ""
|
||||||
|
[9]: ""
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_split_in_place "foo:;:bar:;:baz" ":;" "0" <<EOF
|
||||||
|
1
|
||||||
|
[0]: "foo:;:bar:;:baz"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_split_in_place "foo:;:bar:;:baz" ":;" "1" <<EOF
|
||||||
|
2
|
||||||
|
[0]: "foo"
|
||||||
|
[1]: ";:bar:;:baz"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_split_in_place "foo:;:bar:;:baz" ":;" "2" <<EOF
|
||||||
|
3
|
||||||
|
[0]: "foo"
|
||||||
|
[1]: ""
|
||||||
|
[2]: ":bar:;:baz"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_split_in_place "foo:;:bar:;:" ":;" "-1" <<EOF
|
||||||
|
7
|
||||||
|
[0]: "foo"
|
||||||
|
[1]: ""
|
||||||
|
[2]: ""
|
||||||
|
[3]: "bar"
|
||||||
|
[4]: ""
|
||||||
|
[5]: ""
|
||||||
|
[6]: ""
|
||||||
|
EOF
|
||||||
|
|
||||||
test_expect_success "test filter_string_list" '
|
test_expect_success "test filter_string_list" '
|
||||||
test "x-" = "x$(test-tool string-list filter - y)" &&
|
test "x-" = "x$(test-tool string-list filter - y)" &&
|
||||||
test "x-" = "x$(test-tool string-list filter no y)" &&
|
test "x-" = "x$(test-tool string-list filter no y)" &&
|
||||||
|
Loading…
Reference in New Issue
Block a user