Fix for bug 989: parse command line properly. Good code to tweak
around with while waiting for other things to compile. :-) Since there were some unit tests for the argv interface, took the liberty of updating it for two new functions that were necessary: ompi_argv_delete() and ompi_argv_insert(). This commit was SVN r2907.
Этот коммит содержится в:
родитель
3f8c5372c6
Коммит
7f2b73a4e5
@ -252,3 +252,100 @@ char **ompi_argv_copy(char **argv)
|
|||||||
|
|
||||||
return dupv;
|
return dupv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ompi_argv_delete(char **argv, int start, int num_to_delete)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int count;
|
||||||
|
int suffix_count;
|
||||||
|
|
||||||
|
/* Check for the bozo cases */
|
||||||
|
|
||||||
|
count = ompi_argv_count(argv);
|
||||||
|
if (NULL == argv || start > count || 0 == num_to_delete) {
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
} else if (start < 0 || num_to_delete < 0) {
|
||||||
|
return OMPI_ERR_BAD_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ok, we have some tokens to delete. Calculate the new length of
|
||||||
|
the argv array. */
|
||||||
|
|
||||||
|
suffix_count = count - (start + num_to_delete);
|
||||||
|
if (suffix_count < 0) {
|
||||||
|
suffix_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free all items that are being deleted */
|
||||||
|
|
||||||
|
for (i = start; i < count && i < start + num_to_delete; ++i) {
|
||||||
|
free(argv[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the suffix over the deleted items */
|
||||||
|
|
||||||
|
for (i = start; i < start + suffix_count; ++i) {
|
||||||
|
argv[i] = argv[i + num_to_delete];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the trailing NULL */
|
||||||
|
|
||||||
|
argv[i] = NULL;
|
||||||
|
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ompi_argv_insert(char ***target, int start, char **source)
|
||||||
|
{
|
||||||
|
int i, source_count, target_count;
|
||||||
|
int suffix_count;
|
||||||
|
|
||||||
|
/* Check for the bozo cases */
|
||||||
|
|
||||||
|
if (NULL == target || NULL == *target || start < 0) {
|
||||||
|
return OMPI_ERR_BAD_PARAM;
|
||||||
|
} else if (NULL == source) {
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Easy case: appending to the end */
|
||||||
|
|
||||||
|
target_count = ompi_argv_count(*target);
|
||||||
|
source_count = ompi_argv_count(source);
|
||||||
|
if (start > target_count) {
|
||||||
|
for (i = 0; i < source_count; ++i) {
|
||||||
|
ompi_argv_append(&target_count, target, source[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Harder: insertting into the middle */
|
||||||
|
|
||||||
|
else {
|
||||||
|
|
||||||
|
/* Alloc out new space */
|
||||||
|
|
||||||
|
*target = realloc(*target,
|
||||||
|
sizeof(char *) * (target_count + source_count + 1));
|
||||||
|
|
||||||
|
/* Move suffix items down to the end */
|
||||||
|
|
||||||
|
suffix_count = target_count - start;
|
||||||
|
for (i = suffix_count - 1; i >= 0; --i) {
|
||||||
|
(*target)[start + source_count + i] =
|
||||||
|
(*target)[start + i];
|
||||||
|
}
|
||||||
|
(*target)[start + suffix_count + source_count] = NULL;
|
||||||
|
|
||||||
|
/* Strdup in the source argv */
|
||||||
|
|
||||||
|
for (i = start; i < start + source_count; ++i) {
|
||||||
|
(*target)[i] = strdup(source[i - start]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All done */
|
||||||
|
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
@ -133,6 +133,55 @@ extern "C" {
|
|||||||
* as the input argv, and strcmp(argv_in[i], argv_out[i]) will be 0.
|
* as the input argv, and strcmp(argv_in[i], argv_out[i]) will be 0.
|
||||||
*/
|
*/
|
||||||
char **ompi_argv_copy(char **argv);
|
char **ompi_argv_copy(char **argv);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete one or more tokens from the middle of an argv.
|
||||||
|
*
|
||||||
|
* @param argv The argv to delete from
|
||||||
|
* @param start The index of the first token to delete
|
||||||
|
* @param num_to_delete How many tokens to delete
|
||||||
|
*
|
||||||
|
* @retval OMPI_SUCCESS Always
|
||||||
|
*
|
||||||
|
* Delete some tokens from within an existing argv. The start
|
||||||
|
* parameter specifies the first token to delete, and will delete
|
||||||
|
* (num_to_delete-1) tokens following it.
|
||||||
|
*
|
||||||
|
* If start is beyond the end of the argv array, this function is
|
||||||
|
* a no-op.
|
||||||
|
*
|
||||||
|
* If num_to_delete runs beyond the end of the argv array, this
|
||||||
|
* function will delete all tokens starting with start to the end
|
||||||
|
* of the array.
|
||||||
|
*
|
||||||
|
* All deleted items in the argv array will have their contents
|
||||||
|
* free()ed (it is assumed that the argv "owns" the memory that
|
||||||
|
* the pointer points to).
|
||||||
|
*/
|
||||||
|
int ompi_argv_delete(char **argv, int start, int num_to_delete);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert one argv array into the middle of another
|
||||||
|
*
|
||||||
|
* @param target The argv to insert tokens into
|
||||||
|
* @param start Index where the first token will be placed in target
|
||||||
|
* @param source The argv to copy tokens from
|
||||||
|
*
|
||||||
|
* @retval OMPI_SUCCESS upon success
|
||||||
|
* @retval OMPI_BAD_PARAM if any parameters are non-sensical
|
||||||
|
*
|
||||||
|
* This function takes one arg and inserts it in the middle of
|
||||||
|
* another. The first token in source will be insertted at index
|
||||||
|
* start in the target argv; all other tokens will follow it.
|
||||||
|
* Similar to ompi_argv_append(), the target may be realloc()'ed
|
||||||
|
* to accomodate the new storage requirements.
|
||||||
|
*
|
||||||
|
* The source array is left unaffected -- its contents are copied
|
||||||
|
* by value over to the target array (i.e., the strings that
|
||||||
|
* source points to are strdup'ed into the new locations in
|
||||||
|
* target).
|
||||||
|
*/
|
||||||
|
int ompi_argv_insert(char ***target, int start, char **source);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -88,12 +88,12 @@ static char special_empty_token[] = {
|
|||||||
* Private functions
|
* Private functions
|
||||||
*/
|
*/
|
||||||
static void free_parse_results(ompi_cmd_line_t *cmd);
|
static void free_parse_results(ompi_cmd_line_t *cmd);
|
||||||
static int split_shorts(ompi_cmd_line_t *cmd, bool ignore_unknown);
|
static int split_shorts(ompi_cmd_line_t *cmd,
|
||||||
|
char *token, char **args,
|
||||||
|
int *output_argc, char ***output_argv,
|
||||||
|
int *num_args_used, bool ignore_unknown);
|
||||||
static cmd_line_option_t *find_option(ompi_cmd_line_t *cmd,
|
static cmd_line_option_t *find_option(ompi_cmd_line_t *cmd,
|
||||||
const char *option_name);
|
const char *option_name);
|
||||||
static void suck_params(ompi_cmd_line_t *cmd, cmd_line_option_t *option,
|
|
||||||
int *argc, char ***argv,
|
|
||||||
char *token, int *i);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -170,6 +170,9 @@ int ompi_cmd_line_parse(ompi_cmd_line_t *cmd, bool ignore_unknown,
|
|||||||
cmd_line_param_t *param;
|
cmd_line_param_t *param;
|
||||||
bool is_unknown;
|
bool is_unknown;
|
||||||
bool is_option;
|
bool is_option;
|
||||||
|
char **shortsv;
|
||||||
|
int shortsc;
|
||||||
|
int num_args_used;
|
||||||
|
|
||||||
/* Bozo check */
|
/* Bozo check */
|
||||||
|
|
||||||
@ -190,13 +193,6 @@ int ompi_cmd_line_parse(ompi_cmd_line_t *cmd, bool ignore_unknown,
|
|||||||
cmd->lcl_argc = argc;
|
cmd->lcl_argc = argc;
|
||||||
cmd->lcl_argv = ompi_argv_copy(argv);
|
cmd->lcl_argv = ompi_argv_copy(argv);
|
||||||
|
|
||||||
/* Split groups of multiple short names into individual tokens */
|
|
||||||
|
|
||||||
if (OMPI_SUCCESS != (ret = split_shorts(cmd, ignore_unknown))) {
|
|
||||||
ompi_mutex_unlock(&cmd->lcl_mutex);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now traverse the easy-to-parse sequence of tokens. Note that
|
/* Now traverse the easy-to-parse sequence of tokens. Note that
|
||||||
incrementing i must happen elsehwere; it can't be the third
|
incrementing i must happen elsehwere; it can't be the third
|
||||||
clause in the "if" statement. */
|
clause in the "if" statement. */
|
||||||
@ -236,13 +232,45 @@ int ompi_cmd_line_parse(ompi_cmd_line_t *cmd, bool ignore_unknown,
|
|||||||
option = find_option(cmd, cmd->lcl_argv[i] + 2);
|
option = find_option(cmd, cmd->lcl_argv[i] + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nope, this must be a short name (and, as a result of
|
/* It could be a short name. Is it? */
|
||||||
split_shorts(), above, we know that there's only one short
|
|
||||||
name in this token) */
|
|
||||||
|
|
||||||
else {
|
else {
|
||||||
is_option = true;
|
|
||||||
option = find_option(cmd, cmd->lcl_argv[i] + 1);
|
option = find_option(cmd, cmd->lcl_argv[i] + 1);
|
||||||
|
|
||||||
|
/* If we didn't find it, try to split it into shorts. If
|
||||||
|
we find the short option, replace lcl_argv[i] and
|
||||||
|
insert the rest into lcl_argv starting after position
|
||||||
|
i. If we don't find the short option, don't do
|
||||||
|
anything to lcl_argv so that it can fall through to the
|
||||||
|
error condition, below. */
|
||||||
|
|
||||||
|
if (NULL == option) {
|
||||||
|
shortsv = NULL;
|
||||||
|
shortsc = 0;
|
||||||
|
ret = split_shorts(cmd, cmd->lcl_argv[i] + 1,
|
||||||
|
&(cmd->lcl_argv[i + 1]),
|
||||||
|
&shortsc, &shortsv,
|
||||||
|
&num_args_used, ignore_unknown);
|
||||||
|
if (OMPI_SUCCESS == ret) {
|
||||||
|
option = find_option(cmd, shortsv[0] + 1);
|
||||||
|
|
||||||
|
if (NULL != option) {
|
||||||
|
ompi_argv_delete(cmd->lcl_argv, i,
|
||||||
|
1 + num_args_used);
|
||||||
|
ompi_argv_insert(&cmd->lcl_argv, i, shortsv);
|
||||||
|
cmd->lcl_argc = ompi_argv_count(cmd->lcl_argv);
|
||||||
|
} else {
|
||||||
|
is_unknown = true;
|
||||||
|
}
|
||||||
|
ompi_argv_free(shortsv);
|
||||||
|
} else {
|
||||||
|
is_unknown = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL != option) {
|
||||||
|
is_option = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we figured out above that this is an option, handle it */
|
/* If we figured out above that this is an option, handle it */
|
||||||
@ -716,160 +744,62 @@ static void free_parse_results(ompi_cmd_line_t *cmd)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look for collections of short names and split them into individual
|
* Traverse a token and split it into individual letter options (the
|
||||||
* short options. Ensure to differentiate them from "single dash"
|
* token has already been certified to not be a long name and not be a
|
||||||
* names.
|
* short name). Ensure to differentiate the resulting options from
|
||||||
|
* "single dash" names.
|
||||||
*/
|
*/
|
||||||
static int split_shorts(ompi_cmd_line_t *cmd, bool ignore_unknown)
|
static int split_shorts(ompi_cmd_line_t *cmd, char *token, char **args,
|
||||||
|
int *output_argc, char ***output_argv,
|
||||||
|
int *num_args_used, bool ignore_unknown)
|
||||||
{
|
{
|
||||||
int i, j, k, len;
|
int i, j, len;
|
||||||
int argc;
|
|
||||||
char **argv;
|
|
||||||
char *token;
|
|
||||||
bool changed;
|
|
||||||
char new_token[3];
|
|
||||||
cmd_line_option_t *option;
|
cmd_line_option_t *option;
|
||||||
|
char fake_token[3];
|
||||||
|
int num_args;
|
||||||
|
|
||||||
/* Traverse all the tokens looking for "-multiple_letters". Note
|
/* Setup that we didn't use any of the args */
|
||||||
that incrementing i must happen elsehwere; it can't be the
|
|
||||||
third clause in the "if" statement. */
|
|
||||||
|
|
||||||
argc = 0;
|
num_args = ompi_argv_count(args);
|
||||||
argv = NULL;
|
*num_args_used = 0;
|
||||||
changed = false;
|
|
||||||
if (cmd->lcl_argc > 0) {
|
|
||||||
ompi_argv_append(&argc, &argv, cmd->lcl_argv[0]);
|
|
||||||
}
|
|
||||||
for (i = 1; i < cmd->lcl_argc; ) {
|
|
||||||
token = cmd->lcl_argv[i];
|
|
||||||
len = strlen(token);
|
|
||||||
|
|
||||||
/* If we hit the special "--" token, copy the rest into the
|
/* Traverse the token */
|
||||||
new argv */
|
|
||||||
|
|
||||||
if (0 == strcmp(token, "--")) {
|
len = strlen(token);
|
||||||
while (i < cmd->lcl_argc) {
|
fake_token[0] = '-';
|
||||||
ompi_argv_append(&argc, &argv, cmd->lcl_argv[i]);
|
fake_token[2] = '\0';
|
||||||
++i;
|
for (i = 0; i < len; ++i) {
|
||||||
}
|
fake_token[1] = token[i];
|
||||||
}
|
option = find_option(cmd, fake_token + 1);
|
||||||
|
|
||||||
/* If it's a long name, find its option and copy that many
|
/* If we don't find the option, either return an error or pass
|
||||||
parmeters into the new argv */
|
it through unmodified to the new argv */
|
||||||
|
|
||||||
else if (0 == strncmp(token, "--", 2)) {
|
if (NULL == option) {
|
||||||
option = find_option(cmd, token + 2);
|
|
||||||
|
|
||||||
/* If we don't find the option, either return an error or
|
|
||||||
pass it through unmodified to the new argv */
|
|
||||||
|
|
||||||
if (NULL == option) {
|
|
||||||
++i;
|
|
||||||
if (!ignore_unknown) {
|
|
||||||
ompi_output(0, "Unrecognized option: '%s'", token);
|
|
||||||
return OMPI_ERR_BAD_PARAM;
|
|
||||||
} else {
|
|
||||||
ompi_argv_append(&argc, &argv, new_token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we do find the option, copy it and all of its
|
|
||||||
parameters to the output args. If we run out of
|
|
||||||
paramters (i.e., no more tokens in the original argv),
|
|
||||||
that error will be handled at a higher level) */
|
|
||||||
|
|
||||||
else {
|
|
||||||
suck_params(cmd, option, &argc, &argv, token, &i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If it's a bunch of short names, handle them */
|
|
||||||
|
|
||||||
else if ('-' == token[0] && len >= 2 && '-' != token[1]) {
|
|
||||||
changed = true;
|
|
||||||
|
|
||||||
/* See if this is a "single-dash" name. If we find it,
|
|
||||||
treat it just like finding a --long name above: copy it
|
|
||||||
and all of its parameters to the output args. If we
|
|
||||||
run out of paramters (i.e., no more tokens in the
|
|
||||||
original argv), that error will be handled at a higher
|
|
||||||
level) */
|
|
||||||
|
|
||||||
option = find_option(cmd, token + 1);
|
|
||||||
if (NULL != option) {
|
|
||||||
suck_params(cmd, option, &argc, &argv, token, &i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Nope, it must be one or more short names */
|
|
||||||
|
|
||||||
else {
|
|
||||||
++i;
|
|
||||||
for (j = 1; j < len; ++j) {
|
|
||||||
new_token[0] = '-';
|
|
||||||
new_token[1] = token[j];
|
|
||||||
new_token[2] = '\0';
|
|
||||||
|
|
||||||
option = find_option(cmd, new_token + 1);
|
|
||||||
|
|
||||||
/* If we don't find the option, either return an
|
|
||||||
error or pass it through unmodified to the new
|
|
||||||
argv */
|
|
||||||
|
|
||||||
if (NULL == option) {
|
|
||||||
if (!ignore_unknown) {
|
|
||||||
ompi_output(0, "Unrecognized option: '-%c'",
|
|
||||||
token[j]);
|
|
||||||
return OMPI_ERR_BAD_PARAM;
|
|
||||||
} else {
|
|
||||||
ompi_argv_append(&argc, &argv, new_token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we do find the option, copy it and all of
|
|
||||||
its parameters to the output args. If we run
|
|
||||||
out of paramters (i.e., no more tokens in the
|
|
||||||
original argv), that error will be handled at a
|
|
||||||
higher level) */
|
|
||||||
|
|
||||||
else {
|
|
||||||
ompi_argv_append(&argc, &argv, new_token);
|
|
||||||
for (k = 0; k < option->clo_num_params; ++k) {
|
|
||||||
if (i < cmd->lcl_argc) {
|
|
||||||
ompi_argv_append(&argc, &argv,
|
|
||||||
cmd->lcl_argv[i]);
|
|
||||||
++i;
|
|
||||||
} else {
|
|
||||||
ompi_argv_append(&argc, &argv,
|
|
||||||
special_empty_token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* It's unrecognized */
|
|
||||||
|
|
||||||
else {
|
|
||||||
if (!ignore_unknown) {
|
if (!ignore_unknown) {
|
||||||
ompi_output(0, "Unrecognized option: '%s'", token);
|
|
||||||
return OMPI_ERR_BAD_PARAM;
|
return OMPI_ERR_BAD_PARAM;
|
||||||
} else {
|
} else {
|
||||||
ompi_argv_append(&argc, &argv, token);
|
ompi_argv_append(output_argc, output_argv, fake_token);
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* If we changed anything, then replace the argc/argv on cmd */
|
/* If we do find the option, copy it and all of its parameters
|
||||||
|
to the output args. If we run out of paramters (i.e., no
|
||||||
|
more tokens in the original argv), that error will be
|
||||||
|
handled at a higher level) */
|
||||||
|
|
||||||
if (changed) {
|
else {
|
||||||
ompi_argv_free(cmd->lcl_argv);
|
ompi_argv_append(output_argc, output_argv, fake_token);
|
||||||
cmd->lcl_argc = argc;
|
for (j = 0; j < option->clo_num_params; ++j) {
|
||||||
cmd->lcl_argv = argv;
|
if (*num_args_used < num_args) {
|
||||||
} else {
|
ompi_argv_append(output_argc, output_argv,
|
||||||
if (NULL != argv) {
|
args[*num_args_used]);
|
||||||
ompi_argv_free(argv);
|
++(*num_args_used);
|
||||||
|
} else {
|
||||||
|
ompi_argv_append(output_argc, output_argv,
|
||||||
|
special_empty_token);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -907,22 +837,3 @@ static cmd_line_option_t *find_option(ompi_cmd_line_t *cmd,
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void suck_params(ompi_cmd_line_t *cmd, cmd_line_option_t *option,
|
|
||||||
int *argc, char ***argv,
|
|
||||||
char *token, int *i)
|
|
||||||
{
|
|
||||||
int k;
|
|
||||||
|
|
||||||
ompi_argv_append(argc, argv, token);
|
|
||||||
++(*i);
|
|
||||||
|
|
||||||
for (k = 0; k < option->clo_num_params; ++k, ++(*i)) {
|
|
||||||
if ((*i) < cmd->lcl_argc) {
|
|
||||||
ompi_argv_append(argc, argv, cmd->lcl_argv[*i]);
|
|
||||||
} else {
|
|
||||||
ompi_argv_append(argc, argv, special_empty_token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
# -*- makefile -*-
|
|
||||||
#
|
#
|
||||||
# $HEADER$
|
# $HEADER$
|
||||||
#
|
#
|
||||||
|
|
||||||
include $(top_srcdir)/config/Makefile.options
|
include $(top_srcdir)/config/Makefile.options
|
||||||
AM_CPPFLAGS = -I$(top_srcdir)/test/support -DOMPI_ENABLE_DEBUG_OVERRIDE=1
|
AM_CPPFLAGS = -I$(top_srcdir)/test/support -DOMPI_ENABLE_DEBUG_OVERRIDE=1 -g
|
||||||
|
|
||||||
noinst_PROGRAMS = \
|
noinst_PROGRAMS = \
|
||||||
ompi_numtostr \
|
ompi_numtostr \
|
||||||
|
@ -19,6 +19,8 @@ static bool test5(void);
|
|||||||
static bool test6(void);
|
static bool test6(void);
|
||||||
static bool test7(void);
|
static bool test7(void);
|
||||||
static bool test8(void);
|
static bool test8(void);
|
||||||
|
static bool test9(void);
|
||||||
|
static bool test10(void);
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
@ -50,6 +52,17 @@ int main(int argc, char* argv[])
|
|||||||
if( test8() ) test_success();
|
if( test8() ) test_success();
|
||||||
else test_failure("test8 argv test failed");
|
else test_failure("test8 argv test failed");
|
||||||
|
|
||||||
|
if (test9()) {
|
||||||
|
test_success();
|
||||||
|
} else {
|
||||||
|
test_failure("test9 argv test failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (test10()) {
|
||||||
|
test_success();
|
||||||
|
} else {
|
||||||
|
test_failure("test10 argv test failed");
|
||||||
|
}
|
||||||
|
|
||||||
/* All done */
|
/* All done */
|
||||||
test_finalize();
|
test_finalize();
|
||||||
@ -92,6 +105,7 @@ static bool test1(void)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ompi_argv_free(argv);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -135,6 +149,11 @@ static bool test2(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ompi_argv_free(argv);
|
||||||
|
for (i = 0; b[i] != NULL; ++i) {
|
||||||
|
free(b[i]);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,9 +185,12 @@ static bool test3(void)
|
|||||||
/* Do the same thing but guarantee that the copied array was from
|
/* Do the same thing but guarantee that the copied array was from
|
||||||
the heap and was freed before we call ompi_argv_free(). */
|
the heap and was freed before we call ompi_argv_free(). */
|
||||||
|
|
||||||
|
argc = 0;
|
||||||
|
argv = NULL;
|
||||||
for (i = 0; a[i] != NULL; ++i) {
|
for (i = 0; a[i] != NULL; ++i) {
|
||||||
b[i] = strdup(a[i]);
|
b[i] = strdup(a[i]);
|
||||||
}
|
}
|
||||||
|
b[i] = NULL;
|
||||||
for (i = 0; b[i] != NULL; ++i) {
|
for (i = 0; b[i] != NULL; ++i) {
|
||||||
if (ompi_argv_append(&argc, &argv, b[i]) != OMPI_SUCCESS) {
|
if (ompi_argv_append(&argc, &argv, b[i]) != OMPI_SUCCESS) {
|
||||||
return false;
|
return false;
|
||||||
@ -324,3 +346,284 @@ static bool test8(void)
|
|||||||
ompi_argv_free(b);
|
ompi_argv_free(b);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool test9(void)
|
||||||
|
{
|
||||||
|
char **a = NULL;
|
||||||
|
int argc;
|
||||||
|
|
||||||
|
/* bozo cases */
|
||||||
|
|
||||||
|
if (OMPI_SUCCESS != ompi_argv_delete(NULL, 0, 0)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
a = NULL;
|
||||||
|
argc = 0;
|
||||||
|
ompi_argv_append(&argc, &a, "foo");
|
||||||
|
if (OMPI_SUCCESS != ompi_argv_delete(a, 7, 1) ||
|
||||||
|
1 != ompi_argv_count(a)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ompi_argv_free(a);
|
||||||
|
|
||||||
|
a = NULL;
|
||||||
|
argc = 0;
|
||||||
|
ompi_argv_append(&argc, &a, "foo");
|
||||||
|
if (OMPI_SUCCESS != ompi_argv_delete(a, 0, 0) ||
|
||||||
|
1 != ompi_argv_count(a)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ompi_argv_free(a);
|
||||||
|
|
||||||
|
/* now some real tests */
|
||||||
|
/* delete 1 off the top */
|
||||||
|
|
||||||
|
a = NULL;
|
||||||
|
argc = 0;
|
||||||
|
ompi_argv_append(&argc, &a, "a");
|
||||||
|
ompi_argv_append(&argc, &a, "b");
|
||||||
|
ompi_argv_append(&argc, &a, "c");
|
||||||
|
ompi_argv_append(&argc, &a, "d");
|
||||||
|
ompi_argv_append(&argc, &a, "e");
|
||||||
|
ompi_argv_append(&argc, &a, "f");
|
||||||
|
if (OMPI_SUCCESS != ompi_argv_delete(a, 0, 1) ||
|
||||||
|
5 != ompi_argv_count(a) ||
|
||||||
|
0 != strcmp(a[0], "b") ||
|
||||||
|
0 != strcmp(a[1], "c") ||
|
||||||
|
0 != strcmp(a[2], "d") ||
|
||||||
|
0 != strcmp(a[3], "e") ||
|
||||||
|
0 != strcmp(a[4], "f")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ompi_argv_free(a);
|
||||||
|
|
||||||
|
/* delete 2 off the top */
|
||||||
|
|
||||||
|
a = NULL;
|
||||||
|
argc = 0;
|
||||||
|
ompi_argv_append(&argc, &a, "a");
|
||||||
|
ompi_argv_append(&argc, &a, "b");
|
||||||
|
ompi_argv_append(&argc, &a, "c");
|
||||||
|
ompi_argv_append(&argc, &a, "d");
|
||||||
|
ompi_argv_append(&argc, &a, "e");
|
||||||
|
ompi_argv_append(&argc, &a, "f");
|
||||||
|
if (OMPI_SUCCESS != ompi_argv_delete(a, 0, 2) ||
|
||||||
|
4 != ompi_argv_count(a) ||
|
||||||
|
0 != strcmp(a[0], "c") ||
|
||||||
|
0 != strcmp(a[1], "d") ||
|
||||||
|
0 != strcmp(a[2], "e") ||
|
||||||
|
0 != strcmp(a[3], "f")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ompi_argv_free(a);
|
||||||
|
|
||||||
|
/* delete 1 in the middle */
|
||||||
|
|
||||||
|
a = NULL;
|
||||||
|
argc = 0;
|
||||||
|
ompi_argv_append(&argc, &a, "a");
|
||||||
|
ompi_argv_append(&argc, &a, "b");
|
||||||
|
ompi_argv_append(&argc, &a, "c");
|
||||||
|
ompi_argv_append(&argc, &a, "d");
|
||||||
|
ompi_argv_append(&argc, &a, "e");
|
||||||
|
ompi_argv_append(&argc, &a, "f");
|
||||||
|
if (OMPI_SUCCESS != ompi_argv_delete(a, 1, 1) ||
|
||||||
|
5 != ompi_argv_count(a) ||
|
||||||
|
0 != strcmp(a[0], "a") ||
|
||||||
|
0 != strcmp(a[1], "c") ||
|
||||||
|
0 != strcmp(a[2], "d") ||
|
||||||
|
0 != strcmp(a[3], "e") ||
|
||||||
|
0 != strcmp(a[4], "f")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ompi_argv_free(a);
|
||||||
|
|
||||||
|
/* delete 2 in the middle */
|
||||||
|
|
||||||
|
a = NULL;
|
||||||
|
argc = 0;
|
||||||
|
ompi_argv_append(&argc, &a, "a");
|
||||||
|
ompi_argv_append(&argc, &a, "b");
|
||||||
|
ompi_argv_append(&argc, &a, "c");
|
||||||
|
ompi_argv_append(&argc, &a, "d");
|
||||||
|
ompi_argv_append(&argc, &a, "e");
|
||||||
|
ompi_argv_append(&argc, &a, "f");
|
||||||
|
if (OMPI_SUCCESS != ompi_argv_delete(a, 1, 2) ||
|
||||||
|
4 != ompi_argv_count(a) ||
|
||||||
|
0 != strcmp(a[0], "a") ||
|
||||||
|
0 != strcmp(a[1], "d") ||
|
||||||
|
0 != strcmp(a[2], "e") ||
|
||||||
|
0 != strcmp(a[3], "f")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ompi_argv_free(a);
|
||||||
|
|
||||||
|
/* delete everything from the top */
|
||||||
|
|
||||||
|
a = NULL;
|
||||||
|
argc = 0;
|
||||||
|
ompi_argv_append(&argc, &a, "a");
|
||||||
|
ompi_argv_append(&argc, &a, "b");
|
||||||
|
if (OMPI_SUCCESS != ompi_argv_delete(a, 0, 99) ||
|
||||||
|
0 != ompi_argv_count(a)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ompi_argv_free(a);
|
||||||
|
|
||||||
|
/* delete everything from the middle */
|
||||||
|
|
||||||
|
a = NULL;
|
||||||
|
argc = 0;
|
||||||
|
ompi_argv_append(&argc, &a, "a");
|
||||||
|
ompi_argv_append(&argc, &a, "b");
|
||||||
|
if (OMPI_SUCCESS != ompi_argv_delete(a, 1, 99) ||
|
||||||
|
1 != ompi_argv_count(a) ||
|
||||||
|
0 != strcmp(a[0], "a")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ompi_argv_free(a);
|
||||||
|
|
||||||
|
/* All done */
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool test10(void)
|
||||||
|
{
|
||||||
|
char **orig;
|
||||||
|
char **insert;
|
||||||
|
int o, i;
|
||||||
|
|
||||||
|
/* bozo cases */
|
||||||
|
|
||||||
|
orig = NULL;
|
||||||
|
o = 0;
|
||||||
|
insert = NULL;
|
||||||
|
i = 0;
|
||||||
|
ompi_argv_append(&i, &insert, "insert a");
|
||||||
|
if (OMPI_SUCCESS == ompi_argv_insert(NULL, 0, insert)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ompi_argv_append(&o, &orig, "orig a");
|
||||||
|
if (OMPI_SUCCESS != ompi_argv_insert(&orig, 0, NULL)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (OMPI_SUCCESS == ompi_argv_insert(&orig, -1, insert)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ompi_argv_free(orig);
|
||||||
|
ompi_argv_free(insert);
|
||||||
|
|
||||||
|
/* append to the end */
|
||||||
|
|
||||||
|
orig = NULL;
|
||||||
|
o = 0;
|
||||||
|
insert = NULL;
|
||||||
|
i = 0;
|
||||||
|
ompi_argv_append(&i, &insert, "insert a");
|
||||||
|
ompi_argv_append(&i, &insert, "insert b");
|
||||||
|
ompi_argv_append(&i, &insert, "insert c");
|
||||||
|
ompi_argv_append(&o, &orig, "orig a");
|
||||||
|
ompi_argv_append(&o, &orig, "orig b");
|
||||||
|
ompi_argv_append(&o, &orig, "orig c");
|
||||||
|
if (OMPI_SUCCESS != ompi_argv_insert(&orig, 99, insert) ||
|
||||||
|
6 != ompi_argv_count(orig) ||
|
||||||
|
0 != strcmp(orig[0], "orig a") ||
|
||||||
|
0 != strcmp(orig[1], "orig b") ||
|
||||||
|
0 != strcmp(orig[2], "orig c") ||
|
||||||
|
0 != strcmp(orig[3], "insert a") ||
|
||||||
|
0 != strcmp(orig[4], "insert b") ||
|
||||||
|
0 != strcmp(orig[5], "insert c")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ompi_argv_free(orig);
|
||||||
|
ompi_argv_free(insert);
|
||||||
|
|
||||||
|
/* insert at the beginning */
|
||||||
|
|
||||||
|
orig = NULL;
|
||||||
|
o = 0;
|
||||||
|
insert = NULL;
|
||||||
|
i = 0;
|
||||||
|
ompi_argv_append(&i, &insert, "insert a");
|
||||||
|
ompi_argv_append(&i, &insert, "insert b");
|
||||||
|
ompi_argv_append(&i, &insert, "insert c");
|
||||||
|
ompi_argv_append(&o, &orig, "orig a");
|
||||||
|
ompi_argv_append(&o, &orig, "orig b");
|
||||||
|
ompi_argv_append(&o, &orig, "orig c");
|
||||||
|
if (OMPI_SUCCESS != ompi_argv_insert(&orig, 0, insert) ||
|
||||||
|
6 != ompi_argv_count(orig) ||
|
||||||
|
0 != strcmp(orig[3], "orig a") ||
|
||||||
|
0 != strcmp(orig[4], "orig b") ||
|
||||||
|
0 != strcmp(orig[5], "orig c") ||
|
||||||
|
0 != strcmp(orig[0], "insert a") ||
|
||||||
|
0 != strcmp(orig[1], "insert b") ||
|
||||||
|
0 != strcmp(orig[2], "insert c")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ompi_argv_free(orig);
|
||||||
|
ompi_argv_free(insert);
|
||||||
|
|
||||||
|
/* insert in the middle */
|
||||||
|
|
||||||
|
orig = NULL;
|
||||||
|
o = 0;
|
||||||
|
insert = NULL;
|
||||||
|
i = 0;
|
||||||
|
ompi_argv_append(&i, &insert, "insert a");
|
||||||
|
ompi_argv_append(&i, &insert, "insert b");
|
||||||
|
ompi_argv_append(&i, &insert, "insert c");
|
||||||
|
ompi_argv_append(&o, &orig, "orig a");
|
||||||
|
ompi_argv_append(&o, &orig, "orig b");
|
||||||
|
ompi_argv_append(&o, &orig, "orig c");
|
||||||
|
if (OMPI_SUCCESS != ompi_argv_insert(&orig, 1, insert) ||
|
||||||
|
6 != ompi_argv_count(orig) ||
|
||||||
|
0 != strcmp(orig[0], "orig a") ||
|
||||||
|
0 != strcmp(orig[4], "orig b") ||
|
||||||
|
0 != strcmp(orig[5], "orig c") ||
|
||||||
|
0 != strcmp(orig[1], "insert a") ||
|
||||||
|
0 != strcmp(orig[2], "insert b") ||
|
||||||
|
0 != strcmp(orig[3], "insert c")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ompi_argv_free(orig);
|
||||||
|
ompi_argv_free(insert);
|
||||||
|
|
||||||
|
/* insert in the middle */
|
||||||
|
|
||||||
|
orig = NULL;
|
||||||
|
o = 0;
|
||||||
|
insert = NULL;
|
||||||
|
i = 0;
|
||||||
|
ompi_argv_append(&i, &insert, "insert a");
|
||||||
|
ompi_argv_append(&i, &insert, "insert b");
|
||||||
|
ompi_argv_append(&i, &insert, "insert c");
|
||||||
|
ompi_argv_append(&o, &orig, "orig a");
|
||||||
|
ompi_argv_append(&o, &orig, "orig b");
|
||||||
|
ompi_argv_append(&o, &orig, "orig c");
|
||||||
|
ompi_argv_append(&o, &orig, "orig d");
|
||||||
|
ompi_argv_append(&o, &orig, "orig e");
|
||||||
|
ompi_argv_append(&o, &orig, "orig f");
|
||||||
|
if (OMPI_SUCCESS != ompi_argv_insert(&orig, 1, insert) ||
|
||||||
|
9 != ompi_argv_count(orig) ||
|
||||||
|
0 != strcmp(orig[0], "orig a") ||
|
||||||
|
0 != strcmp(orig[4], "orig b") ||
|
||||||
|
0 != strcmp(orig[5], "orig c") ||
|
||||||
|
0 != strcmp(orig[6], "orig d") ||
|
||||||
|
0 != strcmp(orig[7], "orig e") ||
|
||||||
|
0 != strcmp(orig[8], "orig f") ||
|
||||||
|
0 != strcmp(orig[1], "insert a") ||
|
||||||
|
0 != strcmp(orig[2], "insert b") ||
|
||||||
|
0 != strcmp(orig[3], "insert c")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ompi_argv_free(orig);
|
||||||
|
ompi_argv_free(insert);
|
||||||
|
|
||||||
|
/* All done */
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Загрузка…
Ссылка в новой задаче
Block a user