Utility function: string_to_long plus tests

This commit is contained in:
Shahram Najm 2023-08-04 18:58:14 +00:00 committed by shahramn
parent dbb439c658
commit b2217d46b0
10 changed files with 49 additions and 15 deletions

View File

@ -1456,7 +1456,7 @@ void string_rtrim(char* s);
void string_lrtrim(char** x, int do_left, int do_right);
const char* extract_filename(const char* filepath);
char** string_split(char* inputString, const char* delimiter);
int string_to_long(const char* input, long* output);
int string_to_long(const char* input, long* output, int strict);
int string_ends_with(const char* str1, const char* str2);
int string_count_char(const char* str, char c);
const char* codes_get_product_name(ProductKind product);

View File

@ -642,7 +642,7 @@ static int pack_string(grib_accessor* a, const char* buffer, size_t* len)
{
long lValue = 0;
Assert(buffer);
if (is_number(buffer) && string_to_long(buffer, &lValue) == GRIB_SUCCESS) {
if (is_number(buffer) && string_to_long(buffer, &lValue, 1) == GRIB_SUCCESS) {
// ECC-1654: If value is a pure number, just pack as long
size_t l = 1;
return grib_pack_long(a, &lValue, &l);

View File

@ -382,7 +382,7 @@ static int grib_concept_apply(grib_accessor* a, const char* name)
grib_context_log(h->context, GRIB_LOG_ERROR, "concept: input handle edition=%ld, centre=%s", editionNumber, centre_s);
}
if (strcmp(act->name, "paramId") == 0) {
if (string_to_long(name, &dummy) == GRIB_SUCCESS) {
if (string_to_long(name, &dummy, 1) == GRIB_SUCCESS) {
// The paramId value is an integer. Show them the param DB
grib_context_log(h->context, GRIB_LOG_ERROR,
"Please check the Parameter Database 'https://codes.ecmwf.int/grib/param-db/?id=%s'", name);

View File

@ -257,7 +257,7 @@ static int pack_string(grib_accessor* a, const char* val, size_t* len)
// return pack_missing(a);
//}
if (string_to_long(val, &v) != GRIB_SUCCESS) {
if (string_to_long(val, &v, 1) != GRIB_SUCCESS) {
grib_context_log(a->context, GRIB_LOG_ERROR,
"Trying to pack \"%s\" as long. String cannot be converted to an integer", val);
return GRIB_WRONG_TYPE;

View File

@ -144,7 +144,7 @@ static int evaluate_long(grib_expression* g, grib_handle* h, long* lres)
char* env = getenv(p);
if (env) {
long lval = 0;
if (string_to_long(env, &lval) == GRIB_SUCCESS) {
if (string_to_long(env, &lval, 1) == GRIB_SUCCESS) {
*lres = lval;
return GRIB_SUCCESS;
}

View File

@ -473,7 +473,8 @@ int grib_recompose_print(grib_handle* h, grib_accessor* observer, const char* un
break;
case '!':
pp = (char*)uname;
if (string_to_long(uname + i + 1, &numcols) == GRIB_SUCCESS) {
// Turn off strict as the input string will have a final ']' suffix
if (string_to_long(uname + i + 1, &numcols, /*strict=*/0) == GRIB_SUCCESS) {
maxcols = (int)numcols;
}
else {

View File

@ -124,8 +124,10 @@ char** string_split(char* inputString, const char* delimiter)
return result;
}
/* Return GRIB_SUCCESS if can convert input to an integer, GRIB_INVALID_ARGUMENT otherwise */
int string_to_long(const char* input, long* output)
// Return GRIB_SUCCESS if we can convert 'input' to an integer, GRIB_INVALID_ARGUMENT otherwise.
// If 'strict' is 1 then disallow characters at the end which are not valid digits.
// E.g., in strict mode, "4i" will be rejected. Otherwise it will convert it to 4
int string_to_long(const char* input, long* output, int strict)
{
const int base = 10;
char* endptr;
@ -138,11 +140,15 @@ int string_to_long(const char* input, long* output)
val = strtol(input, &endptr, base);
if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) ||
(errno != 0 && val == 0)) {
/*perror("strtol");*/
// perror("strtol");
return GRIB_INVALID_ARGUMENT;
}
if (endptr == input) {
/*fprintf(stderr, "No digits were found. EXIT_FAILURE\n");*/
// fprintf(stderr, "No digits were found\n");
return GRIB_INVALID_ARGUMENT;
}
if (strict && *endptr != 0) {
// fprintf(stderr, "Left over characters at the end; not a pure number\n");
return GRIB_INVALID_ARGUMENT;
}
*output = val;

View File

@ -68,7 +68,7 @@ int main(int argc, char** argv)
return 1;
}
str_code = list[0];
if (string_to_long(str_code, &lValue) != GRIB_SUCCESS) {
if (string_to_long(str_code, &lValue, 1) != GRIB_SUCCESS) {
fprintf(stderr, "Error on line %zu: descriptor code '%s' (column 1) is not numeric.\n",
line_number, str_code);
return 1;
@ -103,17 +103,18 @@ int main(int argc, char** argv)
str_scale = list[5];
str_ref = list[6];
str_width = list[7];
if (string_to_long(str_scale, &lValue) != GRIB_SUCCESS) {
if (string_to_long(str_scale, &lValue, 1) != GRIB_SUCCESS) {
fprintf(stderr, "Error on line %zu: descriptor scale '%s' (column 6) is not numeric.\n",
line_number, str_scale);
return 1;
}
if (string_to_long(str_ref, &lValue) != GRIB_SUCCESS) {
if (string_to_long(str_ref, &lValue, 1) != GRIB_SUCCESS) {
fprintf(stderr, "Error on line %zu: descriptor reference '%s' (column 7) is not numeric.\n",
line_number, str_ref);
return 1;
}
if (string_to_long(str_width, &lValue) != GRIB_SUCCESS) {
// The final width column can have spaces etc at the end. So turn off strict mode
if (string_to_long(str_width, &lValue, /*strict=*/0) != GRIB_SUCCESS) {
fprintf(stderr, "Error on line %zu: descriptor width '%s' (column 8) is not numeric.\n",
line_number, str_width);
return 1;

View File

@ -319,6 +319,31 @@ static void test_string_ends_with()
Assert( string_ends_with("GRIB2.tmpl", " ") == 0 );
}
static void test_string_to_long()
{
printf("Testing: test_string_to_long...\n");
long lVal = 0;
Assert( string_to_long("0", &lVal, 1) == GRIB_SUCCESS);
Assert( lVal == 0 );
Assert( string_to_long("42", &lVal, 1) == GRIB_SUCCESS);
Assert( lVal == 42 );
Assert( string_to_long("-1", &lVal, 1) == GRIB_SUCCESS);
Assert( lVal == -1 );
Assert( string_to_long("+999", &lVal, 1) == GRIB_SUCCESS);
Assert( lVal == 999 );
Assert( string_to_long("15MB", &lVal, 0) == GRIB_SUCCESS);
Assert( lVal == 15 );
// illegal cases
Assert( string_to_long("4000000000000000000000", &lVal, 1) == GRIB_INVALID_ARGUMENT);
Assert( string_to_long("XY", &lVal, 1) == GRIB_INVALID_ARGUMENT);
Assert( string_to_long("A6", &lVal, 1) == GRIB_INVALID_ARGUMENT);
Assert( string_to_long("5K", &lVal, 1) == GRIB_INVALID_ARGUMENT);
}
static void test_gribex_mode()
{
grib_context* c = grib_context_get_default();
@ -497,6 +522,7 @@ int main(int argc, char** argv)
test_trimming();
test_string_ends_with();
test_string_to_long();
test_get_git_sha1();
test_get_build_date();

View File

@ -64,7 +64,7 @@ int main(int argc, char** argv)
sMaxNumMessages = getenv(ENV_VAR);
if (sMaxNumMessages) {
long lmax = 0;
if (string_to_long(sMaxNumMessages, &lmax) == GRIB_SUCCESS) {
if (string_to_long(sMaxNumMessages, &lmax, 1) == GRIB_SUCCESS) {
MAX_NUM_MESSAGES = lmax;
}
}