1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

r10514: Add str_list_make_shell() and str_list_join_shell()

This commit is contained in:
Jelmer Vernooij 2005-09-26 17:42:12 +00:00 committed by Gerald (Jerry) Carter
parent a5b88bcd42
commit 8b86a5da73
5 changed files with 166 additions and 2 deletions

View File

@ -2,6 +2,7 @@
Unix SMB/CIFS implementation.
Copyright (C) Andrew Tridgell 2005
Copyright (C) Jelmer Vernooij 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -70,6 +71,63 @@ const char **str_list_make(TALLOC_CTX *mem_ctx, const char *string, const char *
return ret;
}
/* build a null terminated list of strings from an argv-like input string
Entries are seperated by spaces and can be enclosed by quotes.
Does NOT support escaping
*/
const char **str_list_make_shell(TALLOC_CTX *mem_ctx, const char *string)
{
int num_elements = 0;
const char **ret = NULL;
ret = talloc_array(mem_ctx, const char *, 1);
if (ret == NULL) {
return NULL;
}
while (string && *string) {
size_t len = strcspn(string, " ");
char *element;
const char **ret2;
if (len == 0) {
string += strspn(string, " ");
continue;
}
if (*string == '\"') {
string++;
len = strcspn(string, "\"");
element = talloc_strndup(ret, string, len);
string += len + 1;
} else {
element = talloc_strndup(ret, string, len);
string += len;
}
if (element == NULL) {
talloc_free(ret);
return NULL;
}
ret2 = talloc_realloc(mem_ctx, ret, const char *, num_elements+2);
if (ret2 == NULL) {
talloc_free(ret);
return NULL;
}
ret = ret2;
ret[num_elements] = element;
num_elements++;
}
ret[num_elements] = NULL;
return ret;
}
/* join a list back to one string */
char *str_list_join(TALLOC_CTX *mem_ctx, const char **list, char seperator)
{
@ -88,6 +146,30 @@ char *str_list_join(TALLOC_CTX *mem_ctx, const char **list, char seperator)
return ret;
}
/* join a list back to one (shell-like) string; entries
* seperated by spaces, using quotes where necessary */
char *str_list_join_shell(TALLOC_CTX *mem_ctx, const char **list)
{
char *ret = NULL;
int i;
if (list[0] == NULL)
return talloc_strdup(mem_ctx, "");
if (strchr(list[0], ' ') || strlen(list[0]) == 0)
ret = talloc_asprintf(mem_ctx, "\"%s\"", list[0]);
else
ret = talloc_strdup(mem_ctx, list[0]);
for (i = 1; list[i]; i++) {
if (strchr(list[i], ' ') || strlen(list[i]) == 0)
ret = talloc_asprintf_append(ret, " \"%s\"", list[i]);
else
ret = talloc_asprintf_append(ret, " %s", list[i]);
}
return ret;
}
/*
return the number of elements in a string list

View File

@ -34,7 +34,7 @@ hostenv.StaticLibrary('torture_auth', [ 'auth/ntlmssp.c', 'auth/pac.c' ])
hostenv.StaticLibrary('torture_local',
['local/iconv.c', 'lib/talloc/testsuite.c', 'local/messaging.c',
'local/binding_string.c', 'local/idtree.c', 'local/socket.c',
'local/irpc.c', 'local/resolve.c'])
'local/irpc.c', 'local/resolve.c', 'local/util_strlist.c'])
hostenv.StaticLibrary('torture_nbench', [ 'nbench/nbio.c', 'nbench/nbench.c' ])

View File

@ -148,7 +148,8 @@ ADD_OBJ_FILES = \
torture/local/idtree.o \
torture/local/socket.o \
torture/local/irpc.o \
torture/local/resolve.o
torture/local/resolve.o \
torture/local/util_strlist.o
REQUIRED_SUBSYSTEMS = \
LIBSMB \
MESSAGING

View File

@ -0,0 +1,80 @@
/*
Unix SMB/CIFS implementation.
util_strlist testing
Copyright (C) Jelmer Vernooij 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
static const char *test_lists_shell_strings[] = {
"",
"foo",
"foo bar",
"foo bar \"bla \"",
"foo \"\" bla",
"bla \"\"\"\" blie",
};
static BOOL test_lists_shell(TALLOC_CTX *mem_ctx)
{
int i;
for (i = 0; test_lists_shell_strings[i]; i++) {
const char **ret1, **ret2, *tmp;
BOOL match = True;
ret1 = str_list_make_shell(mem_ctx, test_lists_shell_strings[i]);
tmp = str_list_join_shell(mem_ctx, ret1);
ret2 = str_list_make_shell(mem_ctx, tmp);
if ((ret1 == NULL || ret2 == NULL) && ret2 != ret1) {
match = False;
} else {
int j;
for (j = 0; ret1[j] && ret2[j]; j++) {
if (strcmp(ret1[j], ret2[j]) != 0) {
match = False;
break;
}
}
if (ret1[j] || ret2[j])
match = False;
}
if (!match) {
printf("str_list_{make,join}_shell: Error double parsing, first run:\n%s\nSecond run: \n%s\n",
test_lists_shell_strings[i],
tmp);
return False;
}
}
return True;
}
BOOL torture_local_util_strlist(void)
{
BOOL ret = True;
TALLOC_CTX *mem_ctx = talloc_init("test_util_strlist");
ret &= test_lists_shell(mem_ctx);
talloc_free(mem_ctx);
return ret;
}

View File

@ -2321,6 +2321,7 @@ static struct {
{"LOCAL-MESSAGING", torture_local_messaging, 0},
{"LOCAL-IRPC", torture_local_irpc, 0},
{"LOCAL-BINDING", torture_local_binding_string, 0},
{"LOCAL-STRLIST", torture_local_util_strlist, 0},
{"LOCAL-IDTREE", torture_local_idtree, 0},
{"LOCAL-SOCKET", torture_local_socket, 0},
{"LOCAL-PAC", torture_pac, 0},