diff -r c8092e909886 -r c41975a290ce absyntax_utils/function_param_iterator.cc --- a/absyntax_utils/function_param_iterator.cc Thu Jun 14 12:00:19 2012 +0100 +++ b/absyntax_utils/function_param_iterator.cc Thu Jun 14 17:50:37 2012 +0100 @@ -47,14 +47,13 @@ */ - -#include "absyntax_utils.hh" /* required for extract_integer() */ -// #include "function_param_iterator.hh" /* no longer required, aready included by absyntax_utils.hh */ -// #include "spec_init_separator.hh" /* no longer required, aready included by absyntax_utils.hh */ +#include "function_param_iterator.hh" /* no longer required, aready included by absyntax_utils.hh */ +#include "spec_init_separator.hh" /* no longer required, aready included by absyntax_utils.hh */ #include /* required for strtol() */ #include #include - +#include // required for std::numeric_limits< XXX >::max() +#include // required for errno //#define DEBUG #ifdef DEBUG @@ -70,6 +69,61 @@ + + +/* NOTE: The following function is not really needed, as we could get the value that constant_folding_c determined for this + * integer. Remember that currently constant_folding_c runs before this class is ever used/called! + * However, I (Mario) do not currently feel it would be a good idea to restrict the use of this + * abstract syntax utility to only after the constant_folding_c has had a chance to fill in the constant value + * of this symbol. + * For this reason only, I have opted to let this abstract syntax utility have its own private copy of the + * extract_integer() function. + * Another aspect that makes this OK is that this function will only be used to extract the integer value of the + * index for the first extensible paramater (examples follow shortly). Since this is an extension to IEC 61131-3 + * that we created to allow us to handle extensible functions with very little hard coding, it is OK if we + * impose extra/different limits on how an integer may be legally be formated in this case. This will also + * only show up in code that describes the interface to the standard function of IEC 61131-3, which the user + * will not ever get to see. We write that IEC 61131-3 code ourselves! + * + * Example of source code we will be parsing and analysing: + * + * FUNCTION ADD : REAL VAR_INPUT IN 1 .. : REAL; END_VAR RETURN; END_FUNCTION + * ^^^ + * + * FUNCTION MUX : REAL VAR_INPUT K : USINT; IN 0 .. : REAL; END_VAR RETURN; END_FUNCTION + * ^^^ + * + * Basically, currently this will only be either a '0' or a '1' !! + */ + +/* NOTE: it must ignore underscores! */ +static int extract_first_index_value(symbol_c *sym) { + std::string str = ""; + integer_c *integer; + long int ret; + + if ((integer = dynamic_cast(sym)) == NULL) ERROR; + for(unsigned int i = 0; i < strlen(integer->value); i++) + if (integer->value[i] != '_') str += integer->value[i]; + + errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly! + ret = strtol(str.c_str(), NULL, 10); + if (errno != 0) ERROR; + if (ret < 0) ERROR; // the following code assumes that the first index will never be negative! + if (ret > std::numeric_limits< int >::max()) ERROR; // output of this function is only an int!! + + return ret; +} + + + + + + + + + + /* compare the name of two __extensible__ function parameters. * The usual use case is to have one of the parameters as used * in the function declaration, and another as used in a formal function call. @@ -130,7 +184,7 @@ if (extensible_parameter != NULL) { sym = extensible_parameter->var_name; current_param_is_extensible = true; - _first_extensible_param_index = extract_int64_value(extensible_parameter->first_index); + _first_extensible_param_index = extract_first_index_value(extensible_parameter->first_index); } identifier_c *variable_name = dynamic_cast(sym); if (variable_name == NULL) ERROR; @@ -167,7 +221,7 @@ if (extensible_parameter != NULL) { var_name = extensible_parameter->var_name; current_param_is_extensible = true; - _first_extensible_param_index = extract_int64_value(extensible_parameter->first_index); + _first_extensible_param_index = extract_first_index_value(extensible_parameter->first_index); } identifier_c *variable_name = dynamic_cast(var_name); if (variable_name == NULL) ERROR; @@ -265,7 +319,7 @@ if (extensible_parameter != NULL) { sym = extensible_parameter->var_name; current_param_is_extensible = true; - _first_extensible_param_index = extract_int64_value(extensible_parameter->first_index); + _first_extensible_param_index = extract_first_index_value(extensible_parameter->first_index); current_extensible_param_index = _first_extensible_param_index; } identifier = dynamic_cast(sym);