cannot use tokenizer for parse_args() as the search for commata must be away of parenthesis
This commit is contained in:
@ -4690,23 +4690,43 @@ void Variable::atom_vector(char *word, Tree **tree,
|
|||||||
max allowed # of args = MAXFUNCARG
|
max allowed # of args = MAXFUNCARG
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
int Variable::parse_args(const std::string &str, char **args)
|
int Variable::parse_args(char *str, char **args)
|
||||||
{
|
{
|
||||||
|
char *ptrnext;
|
||||||
int narg = 0;
|
int narg = 0;
|
||||||
args[0] = nullptr;
|
char *ptr = str;
|
||||||
|
|
||||||
Tokenizer values(str,",");
|
while (ptr && narg < MAXFUNCARG) {
|
||||||
|
ptrnext = find_next_comma(ptr);
|
||||||
while (values.has_next() && narg < MAXFUNCARG) {
|
if (ptrnext) *ptrnext = '\0';
|
||||||
args[narg] = utils::strdup(values.next());
|
args[narg] = utils::strdup(ptr);
|
||||||
narg++;
|
narg++;
|
||||||
|
ptr = ptrnext;
|
||||||
|
if (ptr) ptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (values.has_next())
|
if (ptr) error->all(FLERR,"Too many args in variable function");
|
||||||
error->all(FLERR,"Too many args in variable function");
|
|
||||||
return narg;
|
return narg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
find next comma in str
|
||||||
|
skip commas inside one or more nested parenthesis
|
||||||
|
only return ptr to comma at level 0, else nullptr if not found
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
char *Variable::find_next_comma(char *str)
|
||||||
|
{
|
||||||
|
int level = 0;
|
||||||
|
for (char *p = str; *p; ++p) {
|
||||||
|
if ('(' == *p) level++;
|
||||||
|
else if (')' == *p) level--;
|
||||||
|
else if (',' == *p && !level) return p;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
helper routine for printing variable name with error message
|
helper routine for printing variable name with error message
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|||||||
@ -126,7 +126,8 @@ class Variable : protected Pointers {
|
|||||||
Tree **, Tree **, int &, double *, int &);
|
Tree **, Tree **, int &, double *, int &);
|
||||||
int is_atom_vector(char *);
|
int is_atom_vector(char *);
|
||||||
void atom_vector(char *, Tree **, Tree **, int &);
|
void atom_vector(char *, Tree **, Tree **, int &);
|
||||||
int parse_args(const std::string &, char **);
|
int parse_args(char *, char **);
|
||||||
|
char *find_next_comma(char *);
|
||||||
void print_var_error(const std::string &, int, const std::string &,
|
void print_var_error(const std::string &, int, const std::string &,
|
||||||
int, int global=1);
|
int, int global=1);
|
||||||
void print_tree(Tree *, int);
|
void print_tree(Tree *, int);
|
||||||
|
|||||||
@ -334,8 +334,9 @@ TEST_F(VariableTest, Functions)
|
|||||||
file_vars();
|
file_vars();
|
||||||
|
|
||||||
BEGIN_HIDE_OUTPUT();
|
BEGIN_HIDE_OUTPUT();
|
||||||
|
command("variable seed index 643532");
|
||||||
command("variable one index 1");
|
command("variable one index 1");
|
||||||
command("variable two equal random(1,2,643532)");
|
command("variable two equal random(1,2,v_seed)");
|
||||||
command("variable three equal atan2(v_one,1)");
|
command("variable three equal atan2(v_one,1)");
|
||||||
command("variable four equal atan2()");
|
command("variable four equal atan2()");
|
||||||
command("variable five equal sqrt(v_one+v_one)");
|
command("variable five equal sqrt(v_one+v_one)");
|
||||||
@ -346,6 +347,7 @@ TEST_F(VariableTest, Functions)
|
|||||||
command("variable ten equal floor(1.85)+ceil(1.85)");
|
command("variable ten equal floor(1.85)+ceil(1.85)");
|
||||||
command("variable ten1 equal tan(v_eight/2.0)");
|
command("variable ten1 equal tan(v_eight/2.0)");
|
||||||
command("variable ten2 equal asin(-1.0)+acos(0.0)");
|
command("variable ten2 equal asin(-1.0)+acos(0.0)");
|
||||||
|
command("variable ten3 equal floor(100*random(0.2,0.8,v_seed)+1)");
|
||||||
END_HIDE_OUTPUT();
|
END_HIDE_OUTPUT();
|
||||||
|
|
||||||
ASSERT_GT(variable->compute_equal(variable->find("two")), 0.99);
|
ASSERT_GT(variable->compute_equal(variable->find("two")), 0.99);
|
||||||
@ -357,7 +359,8 @@ TEST_F(VariableTest, Functions)
|
|||||||
ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("nine")), 1);
|
ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("nine")), 1);
|
||||||
ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("ten")), 3);
|
ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("ten")), 3);
|
||||||
ASSERT_FLOAT_EQ(variable->compute_equal(variable->find("ten1")), 1);
|
ASSERT_FLOAT_EQ(variable->compute_equal(variable->find("ten1")), 1);
|
||||||
ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("ten2")), 0);
|
ASSERT_GT(variable->compute_equal(variable->find("ten3")), 19);
|
||||||
|
ASSERT_LT(variable->compute_equal(variable->find("ten3")), 81);
|
||||||
|
|
||||||
TEST_FAILURE(".*ERROR: Variable four: Invalid syntax in variable formula.*",
|
TEST_FAILURE(".*ERROR: Variable four: Invalid syntax in variable formula.*",
|
||||||
command("print \"${four}\""););
|
command("print \"${four}\""););
|
||||||
|
|||||||
Reference in New Issue
Block a user