2013-12-19 15:29:19 +00:00
|
|
|
/*
|
2020-01-28 14:32:34 +00:00
|
|
|
* (C) Copyright 2005- ECMWF.
|
2013-12-19 15:29:19 +00:00
|
|
|
*
|
|
|
|
* This software is licensed under the terms of the Apache Licence Version 2.0
|
|
|
|
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
|
|
|
|
*
|
|
|
|
* In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
|
|
|
|
* virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "grib_api_internal.h"
|
|
|
|
|
2022-10-20 13:38:17 +00:00
|
|
|
#define NUMBER(x) (sizeof(x) / sizeof(x[0]))
|
2021-12-14 19:49:25 +00:00
|
|
|
|
2017-04-05 15:47:19 +00:00
|
|
|
int assertion_caught = 0;
|
2022-11-19 17:49:39 +00:00
|
|
|
int logging_caught = 0;
|
2017-04-05 15:47:19 +00:00
|
|
|
|
2020-01-29 12:05:02 +00:00
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
IBM_FLOAT,
|
|
|
|
IEEE_FLOAT
|
|
|
|
} FloatRep;
|
2013-12-19 15:29:19 +00:00
|
|
|
|
2017-09-01 16:36:16 +00:00
|
|
|
static void compare_doubles(const double d1, const double d2, const double epsilon)
|
2013-12-19 15:29:19 +00:00
|
|
|
{
|
2022-07-29 12:21:04 +00:00
|
|
|
Assert(fabs(d1 - d2) < epsilon);
|
2013-12-19 15:29:19 +00:00
|
|
|
}
|
|
|
|
|
2017-09-01 16:36:16 +00:00
|
|
|
static void check_float_representation(const double val, const double expected, const FloatRep rep)
|
2013-12-19 15:29:19 +00:00
|
|
|
{
|
2020-01-29 12:05:02 +00:00
|
|
|
double out = 0;
|
|
|
|
const double tolerance = 1e-9;
|
|
|
|
if (rep == IBM_FLOAT)
|
2022-07-29 12:21:04 +00:00
|
|
|
Assert(grib_nearest_smaller_ibm_float(val, &out) == GRIB_SUCCESS);
|
2020-01-29 12:05:02 +00:00
|
|
|
else
|
2022-07-29 12:21:04 +00:00
|
|
|
Assert(grib_nearest_smaller_ieee_float(val, &out) == GRIB_SUCCESS);
|
2020-01-29 12:05:02 +00:00
|
|
|
|
|
|
|
/*printf("%s: d1=%10.20f, out=%10.20f\n", (rep==IBM_FLOAT)?"ibm":"ieee", val, out);*/
|
2013-03-25 14:23:07 +00:00
|
|
|
|
2020-01-29 12:05:02 +00:00
|
|
|
compare_doubles(out, expected, tolerance);
|
2013-12-19 15:29:19 +00:00
|
|
|
}
|
2013-03-25 14:23:07 +00:00
|
|
|
|
2020-02-27 13:47:07 +00:00
|
|
|
static void test_get_git_sha1()
|
|
|
|
{
|
2023-08-05 11:37:42 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
|
|
|
|
2020-02-27 13:47:07 +00:00
|
|
|
const char* sha1 = grib_get_git_sha1();
|
2020-03-25 13:13:19 +00:00
|
|
|
Assert(sha1 != NULL);
|
2020-02-27 13:47:07 +00:00
|
|
|
}
|
|
|
|
|
2021-12-14 19:49:25 +00:00
|
|
|
static void test_get_build_date()
|
|
|
|
{
|
2023-08-05 11:37:42 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
|
|
|
|
2021-12-14 19:49:25 +00:00
|
|
|
const char* bdate = codes_get_build_date();
|
|
|
|
Assert(bdate != NULL);
|
2021-12-14 20:02:02 +00:00
|
|
|
/* Should be of the format YYYY.MM.DD or empty (not implemented) */
|
|
|
|
Assert( strlen(bdate) == 0 || isdigit(bdate[0]) );
|
2021-12-14 19:49:25 +00:00
|
|
|
}
|
|
|
|
|
2017-09-01 16:36:16 +00:00
|
|
|
static void test_grib_nearest_smaller_ibmfloat()
|
2013-12-19 15:29:19 +00:00
|
|
|
{
|
2023-08-05 11:37:42 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
|
|
|
|
2013-12-19 15:29:19 +00:00
|
|
|
check_float_representation(-1.0, -1.0, IBM_FLOAT);
|
2020-01-29 12:05:02 +00:00
|
|
|
check_float_representation(0.0, 0.0, IBM_FLOAT);
|
|
|
|
check_float_representation(1.0, 1.0, IBM_FLOAT);
|
|
|
|
check_float_representation(1.1, 1.0999994277954, IBM_FLOAT);
|
2013-12-19 15:29:19 +00:00
|
|
|
check_float_representation(10.6, 10.599999427795, IBM_FLOAT);
|
|
|
|
check_float_representation(7.85, 7.8499994277954, IBM_FLOAT);
|
|
|
|
}
|
|
|
|
|
2017-09-01 16:36:16 +00:00
|
|
|
static void test_grib_nearest_smaller_ieeefloat()
|
2013-12-19 15:29:19 +00:00
|
|
|
{
|
2023-08-05 11:37:42 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
|
|
|
|
2013-12-19 15:29:19 +00:00
|
|
|
check_float_representation(-1.0, -1.0, IEEE_FLOAT);
|
2020-01-29 12:05:02 +00:00
|
|
|
check_float_representation(0.0, 0.0, IEEE_FLOAT);
|
|
|
|
check_float_representation(1.0, 1.0, IEEE_FLOAT);
|
|
|
|
check_float_representation(1.1, 1.0999999046325, IEEE_FLOAT);
|
2013-12-19 15:29:19 +00:00
|
|
|
check_float_representation(10.6, 10.599999427795, IEEE_FLOAT);
|
|
|
|
check_float_representation(7.85, 7.8499999046325, IEEE_FLOAT);
|
|
|
|
}
|
2013-03-25 14:23:07 +00:00
|
|
|
|
2017-09-01 16:36:16 +00:00
|
|
|
static void test_gaussian_latitudes(int order)
|
2013-03-25 14:23:07 +00:00
|
|
|
{
|
2023-08-05 11:37:42 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
|
|
|
|
2020-01-29 12:05:02 +00:00
|
|
|
int ret = 0;
|
2014-07-21 12:22:20 +00:00
|
|
|
const int num = 2 * order;
|
2014-07-31 15:23:05 +00:00
|
|
|
double lat1 = 0, lat2 = 0;
|
2020-01-29 12:05:02 +00:00
|
|
|
double* lats = (double*)malloc(sizeof(double) * num);
|
2023-08-05 11:37:42 +00:00
|
|
|
|
2014-07-21 12:22:20 +00:00
|
|
|
ret = grib_get_gaussian_latitudes(order, lats);
|
2016-02-11 18:39:35 +00:00
|
|
|
Assert(ret == GRIB_SUCCESS);
|
2014-07-21 12:22:20 +00:00
|
|
|
|
|
|
|
lat1 = lats[0];
|
2020-01-29 12:05:02 +00:00
|
|
|
lat2 = lats[num - 1];
|
2014-07-21 12:22:20 +00:00
|
|
|
/* Check first and last latitudes are the same with opposite sign */
|
|
|
|
compare_doubles(lat1, -lat2, 1.0e-6);
|
|
|
|
|
|
|
|
free(lats);
|
|
|
|
}
|
|
|
|
|
2017-09-01 16:36:16 +00:00
|
|
|
static void test_gaussian_latitude_640()
|
2014-07-21 12:22:20 +00:00
|
|
|
{
|
2023-08-05 11:37:42 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
|
|
|
|
|
|
|
/* Test latitudes for one specific Gaussian number */
|
2020-01-29 12:05:02 +00:00
|
|
|
const int order = 640;
|
|
|
|
const int num = 2 * order;
|
|
|
|
int ret = 0;
|
2017-09-01 16:36:16 +00:00
|
|
|
const double tolerance = 1e-6;
|
2020-01-29 12:05:02 +00:00
|
|
|
double* lats = (double*)malloc(sizeof(double) * num);
|
|
|
|
ret = grib_get_gaussian_latitudes(order, lats);
|
2017-09-01 16:36:16 +00:00
|
|
|
Assert(ret == GRIB_SUCCESS);
|
2013-03-25 14:23:07 +00:00
|
|
|
|
2017-09-01 16:36:16 +00:00
|
|
|
compare_doubles(lats[0], 89.892396, tolerance);
|
|
|
|
compare_doubles(lats[1], 89.753005, tolerance);
|
|
|
|
compare_doubles(lats[2], 89.612790, tolerance);
|
|
|
|
compare_doubles(lats[3], 89.472390, tolerance);
|
|
|
|
compare_doubles(lats[4], 89.331918, tolerance);
|
|
|
|
compare_doubles(lats[5], 89.191413, tolerance);
|
|
|
|
compare_doubles(lats[6], 89.050889, tolerance);
|
|
|
|
compare_doubles(lats[7], 88.910352, tolerance);
|
|
|
|
compare_doubles(lats[8], 88.769808, tolerance);
|
|
|
|
compare_doubles(lats[9], 88.629259, tolerance);
|
|
|
|
compare_doubles(lats[10], 88.488706, tolerance);
|
|
|
|
compare_doubles(lats[11], 88.348150, tolerance);
|
|
|
|
compare_doubles(lats[12], 88.207592, tolerance);
|
|
|
|
compare_doubles(lats[13], 88.067032, tolerance);
|
|
|
|
compare_doubles(lats[14], 87.926471, tolerance);
|
|
|
|
compare_doubles(lats[15], 87.785908, tolerance);
|
2023-03-07 21:57:22 +00:00
|
|
|
|
2017-09-01 16:36:16 +00:00
|
|
|
compare_doubles(lats[1262], -87.504781, tolerance);
|
|
|
|
compare_doubles(lats[1263], -87.645345, tolerance);
|
|
|
|
compare_doubles(lats[1264], -87.785908, tolerance);
|
|
|
|
compare_doubles(lats[1265], -87.926471, tolerance);
|
|
|
|
compare_doubles(lats[1266], -88.067032, tolerance);
|
|
|
|
compare_doubles(lats[1267], -88.207592, tolerance);
|
|
|
|
compare_doubles(lats[1268], -88.348150, tolerance);
|
|
|
|
compare_doubles(lats[1269], -88.488706, tolerance);
|
|
|
|
compare_doubles(lats[1270], -88.629259, tolerance);
|
|
|
|
compare_doubles(lats[1271], -88.769808, tolerance);
|
|
|
|
compare_doubles(lats[1272], -88.910352, tolerance);
|
|
|
|
compare_doubles(lats[1273], -89.050889, tolerance);
|
|
|
|
compare_doubles(lats[1274], -89.191413, tolerance);
|
|
|
|
compare_doubles(lats[1275], -89.331918, tolerance);
|
|
|
|
compare_doubles(lats[1276], -89.472390, tolerance);
|
|
|
|
compare_doubles(lats[1277], -89.612790, tolerance);
|
|
|
|
compare_doubles(lats[1278], -89.753005, tolerance);
|
|
|
|
compare_doubles(lats[1279], -89.892396, tolerance);
|
2013-03-25 14:23:07 +00:00
|
|
|
|
2017-09-01 16:36:16 +00:00
|
|
|
free(lats);
|
2013-03-25 14:23:07 +00:00
|
|
|
}
|
|
|
|
|
2017-09-01 16:36:16 +00:00
|
|
|
static void test_string_splitting()
|
2016-10-07 14:12:27 +00:00
|
|
|
{
|
2023-08-05 11:37:42 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
|
|
|
|
2020-01-29 12:05:02 +00:00
|
|
|
int i = 0;
|
2016-10-07 14:12:27 +00:00
|
|
|
char input[80] = "Born|To|Be|Wild";
|
2020-01-29 12:05:02 +00:00
|
|
|
char** list = 0;
|
2020-02-27 13:47:07 +00:00
|
|
|
|
2020-01-29 12:05:02 +00:00
|
|
|
list = string_split(input, "|");
|
2022-07-29 12:21:04 +00:00
|
|
|
if (!list) { Assert(!"List is NULL"); return; }
|
2020-01-29 12:05:02 +00:00
|
|
|
for (i = 0; list[i] != NULL; ++i) {} /* count how many tokens */
|
2022-07-29 12:21:04 +00:00
|
|
|
Assert(i == 4);
|
2023-02-17 15:44:46 +00:00
|
|
|
if (!list[0] || !STR_EQUAL(list[0], "Born")) Assert(0);
|
|
|
|
if (!list[1] || !STR_EQUAL(list[1], "To")) Assert(0);
|
|
|
|
if (!list[2] || !STR_EQUAL(list[2], "Be")) Assert(0);
|
|
|
|
if (!list[3] || !STR_EQUAL(list[3], "Wild")) Assert(0);
|
2020-03-26 11:11:00 +00:00
|
|
|
Assert(list[4] == NULL);
|
|
|
|
for (i = 0; list[i] != NULL; ++i) free(list[i]);
|
2020-01-23 11:08:28 +00:00
|
|
|
free(list);
|
2016-10-07 14:12:27 +00:00
|
|
|
|
2016-11-21 18:37:25 +00:00
|
|
|
strcpy(input, "12345|a gap|");
|
2016-11-22 11:06:00 +00:00
|
|
|
list = string_split(input, "|");
|
2022-07-29 12:21:04 +00:00
|
|
|
if (!list) { Assert(0); return; }
|
2020-01-29 12:05:02 +00:00
|
|
|
for (i = 0; list[i] != NULL; ++i) {} /* count how many tokens */
|
2022-07-29 12:21:04 +00:00
|
|
|
Assert(i == 2);
|
2023-02-17 15:44:46 +00:00
|
|
|
if (!list[0] || !STR_EQUAL(list[0], "12345")) Assert(0);
|
|
|
|
if (!list[1] || !STR_EQUAL(list[1], "a gap")) Assert(0);
|
2022-07-29 12:21:04 +00:00
|
|
|
Assert(list[2] == NULL);
|
2020-03-26 11:11:00 +00:00
|
|
|
for (i = 0; list[i] != NULL; ++i) free(list[i]);
|
2020-01-23 11:08:28 +00:00
|
|
|
free(list);
|
2016-11-21 18:37:25 +00:00
|
|
|
|
2016-10-07 14:18:03 +00:00
|
|
|
strcpy(input, "Steppenwolf");
|
2016-11-22 11:06:00 +00:00
|
|
|
list = string_split(input, ",");
|
2022-07-29 12:21:04 +00:00
|
|
|
if (!list) { Assert(0); return; }
|
2020-01-29 12:05:02 +00:00
|
|
|
for (i = 0; list[i] != NULL; ++i) {} /* count how many tokens */
|
2022-07-29 12:21:04 +00:00
|
|
|
Assert(i == 1);
|
2023-02-17 15:44:46 +00:00
|
|
|
if (!list[0] || !STR_EQUAL(list[0], "Steppenwolf")) Assert(0);
|
2022-07-29 12:21:04 +00:00
|
|
|
Assert(list[1] == NULL);
|
2020-03-26 11:11:00 +00:00
|
|
|
for (i = 0; list[i] != NULL; ++i) free(list[i]);
|
2020-01-23 11:08:28 +00:00
|
|
|
free(list);
|
2016-10-07 14:18:03 +00:00
|
|
|
|
|
|
|
/* Note: currently cannot cope with */
|
|
|
|
/* input being NULL */
|
|
|
|
/* input being empty */
|
|
|
|
/* input having several adjacent delimiters e.g. 'A||B|||C' */
|
2016-10-07 14:12:27 +00:00
|
|
|
}
|
|
|
|
|
2017-04-05 15:47:19 +00:00
|
|
|
static void my_assertion_proc(const char* message)
|
|
|
|
{
|
2020-01-23 11:08:28 +00:00
|
|
|
printf("It's OK. I caught the assertion: %s\n", message);
|
2017-04-05 15:47:19 +00:00
|
|
|
assertion_caught = 1;
|
|
|
|
}
|
|
|
|
|
2017-09-01 16:36:16 +00:00
|
|
|
static void test_assertion_catching()
|
2017-04-05 15:47:19 +00:00
|
|
|
{
|
2023-08-05 11:37:42 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
|
|
|
|
2020-01-29 12:05:02 +00:00
|
|
|
char empty[] = "";
|
|
|
|
char** list = 0;
|
|
|
|
int i = 0;
|
2022-07-29 12:21:04 +00:00
|
|
|
Assert(assertion_caught == 0);
|
2017-04-05 15:47:19 +00:00
|
|
|
codes_set_codes_assertion_failed_proc(&my_assertion_proc);
|
2022-12-26 14:37:01 +00:00
|
|
|
|
2017-04-05 15:47:19 +00:00
|
|
|
/* Do something illegal */
|
2020-01-23 11:08:28 +00:00
|
|
|
list = string_split(empty, " ");
|
2017-04-05 15:47:19 +00:00
|
|
|
|
2022-07-29 12:21:04 +00:00
|
|
|
Assert(assertion_caught == 1);
|
2017-04-05 15:47:19 +00:00
|
|
|
|
|
|
|
/* Restore everything */
|
|
|
|
codes_set_codes_assertion_failed_proc(NULL);
|
|
|
|
assertion_caught = 0;
|
2020-01-23 11:08:28 +00:00
|
|
|
|
2020-01-29 12:05:02 +00:00
|
|
|
for (i = 0; list[i] != NULL; ++i)
|
|
|
|
free(list[i]);
|
2020-01-23 11:08:28 +00:00
|
|
|
free(list);
|
2017-04-05 15:47:19 +00:00
|
|
|
}
|
|
|
|
|
2022-11-19 17:49:39 +00:00
|
|
|
static void my_logging_proc(const grib_context* c, int level, const char* mesg)
|
|
|
|
{
|
|
|
|
logging_caught = 1;
|
|
|
|
}
|
|
|
|
static void test_logging_proc()
|
|
|
|
{
|
|
|
|
grib_context* context = grib_context_get_default();
|
|
|
|
Assert(logging_caught == 0);
|
|
|
|
|
|
|
|
/* Override default behaviour */
|
|
|
|
grib_context_set_logging_proc(context, my_logging_proc);
|
2023-08-04 21:17:04 +00:00
|
|
|
grib_context_log(context, GRIB_LOG_ERROR, "test_logging_proc: This error will be handled by me");
|
2022-11-19 17:49:39 +00:00
|
|
|
Assert(logging_caught == 1);
|
|
|
|
|
|
|
|
/* Restore the logging proc */
|
|
|
|
logging_caught = 0;
|
|
|
|
grib_context_set_logging_proc(context, NULL);
|
2023-08-04 21:17:04 +00:00
|
|
|
grib_context_log(context, GRIB_LOG_ERROR, "test_logging_proc: This error will come out as normal");
|
2022-11-19 17:49:39 +00:00
|
|
|
Assert(logging_caught == 0);
|
|
|
|
}
|
|
|
|
|
2019-12-01 16:13:38 +00:00
|
|
|
static void test_concept_condition_strings()
|
|
|
|
{
|
2023-08-05 11:37:42 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
|
|
|
|
2020-01-29 12:05:02 +00:00
|
|
|
int err = 0;
|
2019-12-02 12:36:53 +00:00
|
|
|
char result[1024] = {0,};
|
2022-02-24 15:16:55 +00:00
|
|
|
grib_context* context = NULL;
|
|
|
|
grib_handle* h = grib_handle_new_from_samples(context, "GRIB2");
|
2019-12-01 16:13:38 +00:00
|
|
|
|
2019-12-02 12:36:53 +00:00
|
|
|
err = get_concept_condition_string(h, "typeOfLevel", NULL, result);
|
2020-03-25 13:13:19 +00:00
|
|
|
Assert(!err);
|
|
|
|
Assert(strcmp(result, "typeOfFirstFixedSurface=1,typeOfSecondFixedSurface=255") == 0);
|
2019-12-01 16:13:38 +00:00
|
|
|
|
2019-12-02 12:36:53 +00:00
|
|
|
err = get_concept_condition_string(h, "paramId", NULL, result);
|
2020-03-25 13:13:19 +00:00
|
|
|
Assert(!err);
|
|
|
|
Assert(strcmp(result, "discipline=0,parameterCategory=0,parameterNumber=0") == 0);
|
2019-12-01 16:13:38 +00:00
|
|
|
|
2019-12-02 12:36:53 +00:00
|
|
|
err = get_concept_condition_string(h, "gridType", NULL, result);
|
2020-03-25 13:13:19 +00:00
|
|
|
Assert(!err);
|
|
|
|
Assert(strcmp(result, "gridDefinitionTemplateNumber=0,PLPresent=0") == 0);
|
2019-12-02 14:55:29 +00:00
|
|
|
|
|
|
|
err = get_concept_condition_string(h, "stepType", NULL, result);
|
2020-03-25 13:13:19 +00:00
|
|
|
Assert(!err);
|
|
|
|
Assert(strcmp(result, "selectStepTemplateInstant=1,stepTypeInternal=instant") == 0);
|
2019-12-02 14:55:29 +00:00
|
|
|
|
2020-01-23 11:08:28 +00:00
|
|
|
grib_handle_delete(h);
|
2019-12-01 16:13:38 +00:00
|
|
|
}
|
|
|
|
|
2023-08-04 21:17:04 +00:00
|
|
|
static void test_string_trimming()
|
2020-06-26 21:18:08 +00:00
|
|
|
{
|
2023-08-05 11:37:42 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
|
|
|
|
2020-06-26 21:18:08 +00:00
|
|
|
char a[] = " Standing ";
|
|
|
|
char b[] = " Weeping ";
|
|
|
|
char c[] = " Silhouette ";
|
|
|
|
char d[] = " The Forest Of October ";
|
|
|
|
char e[] = "\t\n Apostle In Triumph \r ";
|
|
|
|
char* pA = a;
|
|
|
|
char* pB = b;
|
|
|
|
char* pC = c;
|
|
|
|
char* pD = d;
|
|
|
|
char* pE = e;
|
|
|
|
|
2022-06-10 19:51:39 +00:00
|
|
|
string_lrtrim(&pA, 0, 1); /*right only*/
|
2022-07-29 12:21:04 +00:00
|
|
|
Assert( strcmp(pA, " Standing")==0 );
|
2020-06-26 21:18:08 +00:00
|
|
|
|
2022-06-10 19:51:39 +00:00
|
|
|
string_lrtrim(&pB, 1, 0); /*left only*/
|
2022-07-29 12:21:04 +00:00
|
|
|
Assert( strcmp(pB, "Weeping ")==0 );
|
2020-06-26 21:18:08 +00:00
|
|
|
|
2022-06-10 19:51:39 +00:00
|
|
|
string_lrtrim(&pC, 1, 1); /*both ends*/
|
2022-07-29 12:21:04 +00:00
|
|
|
Assert( strcmp(pC, "Silhouette")==0 );
|
2020-06-26 21:18:08 +00:00
|
|
|
|
2022-06-10 19:51:39 +00:00
|
|
|
string_lrtrim(&pD, 1, 1); /*make sure other spaces are not removed*/
|
2022-07-29 12:21:04 +00:00
|
|
|
Assert( strcmp(pD, "The Forest Of October")==0 );
|
2020-06-26 21:18:08 +00:00
|
|
|
|
2022-06-10 19:51:39 +00:00
|
|
|
string_lrtrim(&pE, 1, 1); /* Other chars */
|
2022-07-29 12:21:04 +00:00
|
|
|
Assert( strcmp(pE, "Apostle In Triumph")==0 );
|
2020-06-26 21:18:08 +00:00
|
|
|
}
|
|
|
|
|
2022-03-14 15:15:05 +00:00
|
|
|
static void test_string_ends_with()
|
|
|
|
{
|
2023-08-05 11:37:42 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
|
|
|
|
2022-07-29 12:21:04 +00:00
|
|
|
Assert( string_ends_with("GRIB2.tmpl", "tmpl") == 1 );
|
|
|
|
Assert( string_ends_with("GRIB2.tmpl", ".tmpl") == 1 );
|
|
|
|
Assert( string_ends_with("", "") == 1 );
|
|
|
|
Assert( string_ends_with(".", ".") == 1 );
|
|
|
|
Assert( string_ends_with("Bam", "") == 1 );
|
2022-03-14 15:15:05 +00:00
|
|
|
|
2022-07-29 12:21:04 +00:00
|
|
|
Assert( string_ends_with("GRIB2.tmpl", "tmp") == 0 );
|
|
|
|
Assert( string_ends_with("GRIB2.tmpl", "tmpl0") == 0 );
|
|
|
|
Assert( string_ends_with("GRIB2.tmpl", "1.tmpl") == 0 );
|
|
|
|
Assert( string_ends_with("GRIB2.tmpl", " ") == 0 );
|
2022-03-14 15:15:05 +00:00
|
|
|
}
|
|
|
|
|
2023-08-04 18:58:14 +00:00
|
|
|
static void test_string_to_long()
|
|
|
|
{
|
2023-08-05 11:37:42 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
|
|
|
|
2023-08-04 18:58:14 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2023-08-04 21:17:04 +00:00
|
|
|
static void test_string_replace_char()
|
|
|
|
{
|
2023-08-05 11:37:42 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
2023-08-04 21:17:04 +00:00
|
|
|
|
2023-08-05 11:37:42 +00:00
|
|
|
char input[32] = {0,};
|
2023-08-04 21:17:04 +00:00
|
|
|
strncpy(input, "Mask Of Zoro", sizeof(input));
|
|
|
|
string_replace_char(input, ' ', '-');
|
|
|
|
Assert(STR_EQUAL(input, "Mask-Of-Zoro"));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void test_string_remove_char()
|
|
|
|
{
|
2023-08-05 11:37:42 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
2023-08-04 21:17:04 +00:00
|
|
|
char input[64] = "a:b:c";
|
|
|
|
string_remove_char(input, ':');
|
|
|
|
Assert(STR_EQUAL(input, "abc"));
|
|
|
|
}
|
|
|
|
|
2022-02-24 15:16:55 +00:00
|
|
|
static void test_gribex_mode()
|
|
|
|
{
|
|
|
|
grib_context* c = grib_context_get_default();
|
2023-08-05 11:37:42 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
2022-02-24 15:16:55 +00:00
|
|
|
|
2022-07-29 12:21:04 +00:00
|
|
|
Assert( grib_get_gribex_mode(c) == 0 ); /* default is OFF */
|
2022-02-24 15:16:55 +00:00
|
|
|
grib_gribex_mode_on(c);
|
2022-07-29 12:21:04 +00:00
|
|
|
Assert( grib_get_gribex_mode(c) == 1 );
|
2022-02-24 15:16:55 +00:00
|
|
|
grib_gribex_mode_off(c);
|
2022-07-29 12:21:04 +00:00
|
|
|
Assert( grib_get_gribex_mode(c) == 0 );
|
2022-02-24 15:16:55 +00:00
|
|
|
}
|
|
|
|
|
2022-10-20 13:38:17 +00:00
|
|
|
static void test_grib_binary_search()
|
|
|
|
{
|
2023-08-05 11:37:42 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
|
|
|
|
2022-10-20 13:38:17 +00:00
|
|
|
double array_asc[] = {-0.1, 33.4, 56.1, 101.8};
|
|
|
|
double array_desc[] = {88, 78, 0, -88};
|
|
|
|
const size_t idx_asc_max = NUMBER(array_asc) - 1;
|
|
|
|
const size_t idx_desc_max = NUMBER(array_desc) - 1;
|
|
|
|
size_t idx_upper=0, idx_lower = 0;
|
|
|
|
|
|
|
|
grib_binary_search(array_asc, idx_asc_max, 56.0, &idx_upper, &idx_lower);
|
|
|
|
Assert(idx_lower == 1 && idx_upper == 2);
|
|
|
|
grib_binary_search(array_asc, idx_asc_max, 56.1, &idx_upper, &idx_lower);
|
|
|
|
Assert(idx_lower == 2 && idx_upper == 3);
|
|
|
|
grib_binary_search(array_asc, idx_asc_max, -0.1, &idx_upper, &idx_lower);
|
|
|
|
Assert(idx_lower == 0 && idx_upper == 1);
|
|
|
|
|
|
|
|
grib_binary_search(array_desc, idx_desc_max, 88, &idx_upper, &idx_lower);
|
|
|
|
Assert(idx_lower == 0 && idx_upper == 1);
|
|
|
|
grib_binary_search(array_desc, idx_desc_max, -88, &idx_upper, &idx_lower);
|
|
|
|
Assert(idx_lower == 2 && idx_upper == 3);
|
|
|
|
grib_binary_search(array_desc, idx_desc_max, 1, &idx_upper, &idx_lower);
|
|
|
|
Assert(idx_lower == 1 && idx_upper == 2);
|
|
|
|
}
|
|
|
|
|
2022-10-26 12:02:45 +00:00
|
|
|
static void test_parse_keyval_string()
|
|
|
|
{
|
2023-08-05 11:37:42 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
|
|
|
|
2022-10-26 12:02:45 +00:00
|
|
|
int err = 0;
|
|
|
|
int values_required = 1;
|
|
|
|
int count = 0;
|
2023-01-06 12:30:05 +00:00
|
|
|
grib_values values1[128] = {{0},};
|
|
|
|
grib_values values2[128] = {{0},};
|
|
|
|
grib_values values3[128] = {{0},};
|
2022-10-26 12:02:45 +00:00
|
|
|
const int max_count = 128;
|
|
|
|
char input1[] = "key1=value1,key2!=value2";
|
|
|
|
char input2[] = "x=14";
|
|
|
|
char input3[] = "mars.level=0.978";
|
|
|
|
|
|
|
|
count = max_count;
|
|
|
|
err = parse_keyval_string(NULL, input1,
|
2022-11-07 12:22:49 +00:00
|
|
|
values_required, GRIB_TYPE_UNDEFINED, values1, &count);
|
2022-10-26 12:02:45 +00:00
|
|
|
Assert( !err );
|
|
|
|
Assert( count == 2 );
|
2023-08-14 12:35:55 +00:00
|
|
|
grib_print_values("print values test: values1", values1);
|
|
|
|
|
2022-11-07 12:22:49 +00:00
|
|
|
Assert( strcmp(values1[0].name, "key1")==0 );
|
|
|
|
Assert( strcmp(values1[0].string_value, "value1")==0 );
|
|
|
|
Assert( values1[0].equal == 1 );
|
|
|
|
Assert( strcmp(values1[1].name, "key2")==0 );
|
|
|
|
Assert( strcmp(values1[1].string_value, "value2")==0 );
|
|
|
|
Assert( values1[1].equal == 0 );
|
2022-10-26 12:02:45 +00:00
|
|
|
/* Note how the input is modified by the tokenizer (thanks to strtok_r) */
|
|
|
|
Assert( strcmp(input1, "key1=value1")==0 );
|
2022-11-07 12:22:49 +00:00
|
|
|
free( (void*)values1[0].name );
|
|
|
|
free( (void*)values1[1].name );
|
|
|
|
free( (void*)values1[0].string_value );
|
|
|
|
free( (void*)values1[1].string_value );
|
2022-10-26 12:02:45 +00:00
|
|
|
|
|
|
|
count = max_count;
|
|
|
|
err = parse_keyval_string(NULL, input2,
|
2022-11-07 12:22:49 +00:00
|
|
|
values_required, GRIB_TYPE_LONG, values2, &count);
|
2022-10-26 12:02:45 +00:00
|
|
|
Assert( !err );
|
|
|
|
Assert( count == 1 );
|
2023-08-14 12:35:55 +00:00
|
|
|
grib_print_values("print values test: values2", values2);
|
2022-11-07 12:22:49 +00:00
|
|
|
Assert( strcmp(values2[0].name, "x")==0 );
|
|
|
|
Assert( values2[0].long_value == 14 );
|
|
|
|
Assert( values2[0].equal == 1 );
|
|
|
|
free( (void*)values2[0].name );
|
2022-10-26 12:02:45 +00:00
|
|
|
|
|
|
|
count = max_count;
|
|
|
|
err = parse_keyval_string(NULL, input3,
|
2022-11-07 12:22:49 +00:00
|
|
|
values_required, GRIB_TYPE_DOUBLE, values3, &count);
|
2022-10-26 12:02:45 +00:00
|
|
|
Assert( !err );
|
|
|
|
Assert( count == 1 );
|
2023-08-14 12:35:55 +00:00
|
|
|
grib_print_values("print values test: values3", values3);
|
2022-11-07 12:22:49 +00:00
|
|
|
Assert( strcmp(values3[0].name, "mars.level")==0 );
|
|
|
|
free( (void*)values3[0].name );
|
2022-10-26 12:02:45 +00:00
|
|
|
}
|
|
|
|
|
2023-02-16 16:07:24 +00:00
|
|
|
static void test_dates()
|
|
|
|
{
|
2023-08-05 11:37:42 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
|
|
|
|
2023-02-16 16:07:24 +00:00
|
|
|
Assert( is_date_valid(1979,12, 1, 0,0,0) );
|
|
|
|
Assert( is_date_valid(1900, 1, 1, 0,0,0) );
|
|
|
|
Assert( is_date_valid(1964, 4, 6, 0,0,0) );
|
|
|
|
Assert( is_date_valid(2023, 3, 4, 0,0,0) );
|
|
|
|
Assert( is_date_valid(2023, 3, 4, 12,0,0) );
|
|
|
|
Assert( is_date_valid(2023, 3, 4, 0,10,0) );
|
|
|
|
Assert( is_date_valid(2023, 3, 4, 0,0,59) );
|
|
|
|
Assert( is_date_valid(0000, 3, 4, 0,0,0) );
|
|
|
|
Assert( is_date_valid(2020, 2, 29, 0,0,0) );//leap year
|
|
|
|
|
|
|
|
Assert( !is_date_valid( 10, -1, 1, 0,0,0) );// bad months
|
|
|
|
Assert( !is_date_valid(1900, 0, 1, 0,0,0) );
|
|
|
|
Assert( !is_date_valid(1900, 13, 1, 0,0,0) );
|
|
|
|
|
|
|
|
Assert( !is_date_valid(1900, 5, 0, 0,0,0) ); // bad days
|
|
|
|
Assert( !is_date_valid(2000, 5, 32, 0,0,0) );
|
|
|
|
Assert( !is_date_valid(2000, 5, -7, 0,0,0) );
|
|
|
|
|
|
|
|
Assert( !is_date_valid(2000, 5, 8, 99,0,0) );//bad hours
|
|
|
|
Assert( !is_date_valid(2000, 5, 9, -1,0,0) );
|
|
|
|
|
|
|
|
Assert( !is_date_valid(2000, 5, 8, 0, 61,0) );//bad mins
|
|
|
|
Assert( !is_date_valid(2000, 5, 9, 0,-1, 0) );
|
|
|
|
|
|
|
|
Assert( !is_date_valid(2000, 5, 8, 0, 1, -1) );//bad secs
|
|
|
|
Assert( !is_date_valid(2000, 5, 9, 0, 1, 60) );
|
|
|
|
|
|
|
|
Assert( !is_date_valid(2023, 2, 29, 0,0,0) );//Feb
|
2023-04-08 11:40:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void test_scale_factor_scaled_values()
|
|
|
|
{
|
2023-08-05 11:37:42 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
|
|
|
|
2023-04-08 11:40:30 +00:00
|
|
|
int err =0;
|
|
|
|
int64_t value, factor;
|
|
|
|
const int64_t scaled_value_max = 4294967295; // usually 4 octets
|
|
|
|
const int64_t scale_factor_max = 255; // usually 1 octet
|
|
|
|
|
|
|
|
err = compute_scaled_value_and_scale_factor(0, scaled_value_max, scale_factor_max, &value, &factor);
|
|
|
|
Assert(!err);
|
|
|
|
Assert(value == 0);
|
|
|
|
Assert(factor == 0);
|
|
|
|
|
|
|
|
err = compute_scaled_value_and_scale_factor(1, scaled_value_max, scale_factor_max, &value, &factor);
|
|
|
|
Assert(!err);
|
|
|
|
Assert(value == 1);
|
|
|
|
Assert(factor == 0);
|
|
|
|
|
|
|
|
err = compute_scaled_value_and_scale_factor(1.5, scaled_value_max, scale_factor_max, &value, &factor);
|
|
|
|
Assert(!err);
|
|
|
|
Assert(value == 15);
|
|
|
|
Assert(factor == 1);
|
|
|
|
|
|
|
|
err = compute_scaled_value_and_scale_factor(4.56, scaled_value_max, scale_factor_max, &value, &factor);
|
|
|
|
Assert(!err);
|
|
|
|
Assert(value == 456);
|
|
|
|
Assert(factor == 2);
|
|
|
|
|
|
|
|
err = compute_scaled_value_and_scale_factor(-0.003, scaled_value_max, scale_factor_max, &value, &factor);
|
|
|
|
Assert(!err);
|
|
|
|
Assert(value == -3);
|
|
|
|
Assert(factor == 3);
|
|
|
|
|
|
|
|
err = compute_scaled_value_and_scale_factor(145.889, scaled_value_max, scale_factor_max, &value, &factor);
|
|
|
|
Assert(!err);
|
|
|
|
Assert(value == 145889);
|
|
|
|
Assert(factor == 3);
|
2023-02-16 16:07:24 +00:00
|
|
|
|
2023-04-08 11:40:30 +00:00
|
|
|
err = compute_scaled_value_and_scale_factor(1111.00009, scaled_value_max, scale_factor_max, &value, &factor);
|
|
|
|
Assert(!err);
|
|
|
|
Assert(value == 111100009);
|
|
|
|
Assert(factor == 5);
|
2023-02-16 16:07:24 +00:00
|
|
|
}
|
2022-11-19 17:49:39 +00:00
|
|
|
|
2023-08-21 21:02:03 +00:00
|
|
|
void test_iarray()
|
|
|
|
{
|
2023-08-23 16:00:49 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
2023-08-21 21:02:03 +00:00
|
|
|
grib_context* c = grib_context_get_default();
|
|
|
|
grib_iarray* a = grib_iarray_new(c, 10, 10);
|
|
|
|
grib_iarray_push(a, 42);
|
2023-08-23 16:00:49 +00:00
|
|
|
grib_iarray_push(a, 10000);
|
|
|
|
grib_iarray_print("iarray", a);
|
|
|
|
|
|
|
|
grib_iarray* b = grib_iarray_new(c, 1, 1);
|
|
|
|
grib_iarray_push(b, 0);
|
|
|
|
grib_iarray_push(b, -1);
|
|
|
|
grib_iarray_push(b, +1);
|
|
|
|
|
|
|
|
grib_viarray* va = grib_viarray_new(c, 1, 1);
|
|
|
|
grib_viarray_push(c, va, a);
|
|
|
|
grib_viarray_push(c, va, b);
|
|
|
|
grib_viarray_print("viarray", va);
|
|
|
|
|
2023-08-21 21:02:03 +00:00
|
|
|
grib_iarray_delete(a);
|
2023-08-23 16:00:49 +00:00
|
|
|
grib_iarray_delete(b);
|
|
|
|
grib_viarray_delete(c, va);
|
2023-08-21 21:02:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void test_darray()
|
|
|
|
{
|
2023-08-23 16:00:49 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
2023-08-21 21:02:03 +00:00
|
|
|
grib_context* c = grib_context_get_default();
|
|
|
|
grib_darray* a = grib_darray_new(c, 10, 10);
|
|
|
|
grib_darray_push(c, a, 42.009);
|
|
|
|
grib_darray_push(c, a, -1.11);
|
|
|
|
grib_darray_push(c, a, 5099);
|
2023-08-23 16:00:49 +00:00
|
|
|
grib_darray_print("darray", a);
|
|
|
|
|
|
|
|
grib_darray* b = grib_darray_new(c, 5, 1);
|
|
|
|
grib_darray_push(c, b, 8);
|
|
|
|
grib_darray_push(c, b, 12);
|
|
|
|
|
|
|
|
grib_vdarray* va = grib_vdarray_new(c, 1, 1);
|
|
|
|
grib_vdarray_push(c, va, a);
|
|
|
|
grib_vdarray_push(c, va, b);
|
|
|
|
grib_vdarray_print("vdarray", va);
|
|
|
|
|
2023-08-21 21:02:03 +00:00
|
|
|
grib_darray_delete(c, a);
|
2023-08-23 16:00:49 +00:00
|
|
|
grib_darray_delete(c, b);
|
|
|
|
grib_vdarray_delete(c, va);
|
2023-08-21 21:02:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void test_sarray()
|
|
|
|
{
|
2023-08-23 16:00:49 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
2023-08-21 21:02:03 +00:00
|
|
|
grib_context* c = grib_context_get_default();
|
|
|
|
grib_sarray* a = grib_sarray_new(c, 10, 10);
|
|
|
|
grib_sarray_push(c, a, "ants");
|
|
|
|
grib_sarray_push(c, a, "bugs");
|
2023-08-23 16:00:49 +00:00
|
|
|
grib_sarray_print("sarray", a);
|
2023-08-21 21:02:03 +00:00
|
|
|
grib_sarray_delete(c, a);
|
|
|
|
}
|
|
|
|
|
2023-08-23 13:26:56 +00:00
|
|
|
void test_codes_get_product_name()
|
|
|
|
{
|
2023-08-23 16:00:49 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
2023-08-23 13:41:29 +00:00
|
|
|
Assert( STR_EQUAL("ANY", codes_get_product_name(PRODUCT_ANY)) );
|
|
|
|
Assert( STR_EQUAL("GRIB", codes_get_product_name(PRODUCT_GRIB)) );
|
|
|
|
Assert( STR_EQUAL("BUFR", codes_get_product_name(PRODUCT_BUFR)) );
|
|
|
|
Assert( STR_EQUAL("GTS", codes_get_product_name(PRODUCT_GTS)) );
|
2023-08-23 13:26:56 +00:00
|
|
|
Assert( STR_EQUAL("METAR", codes_get_product_name(PRODUCT_METAR)) );
|
|
|
|
}
|
|
|
|
|
2023-08-23 13:41:29 +00:00
|
|
|
void test_codes_get_type_name()
|
|
|
|
{
|
2023-08-23 16:00:49 +00:00
|
|
|
printf("Running %s ...\n", __func__);
|
2023-08-23 13:41:29 +00:00
|
|
|
Assert( STR_EQUAL("long", grib_get_type_name(GRIB_TYPE_LONG)) );
|
|
|
|
Assert( STR_EQUAL("string", grib_get_type_name(GRIB_TYPE_STRING)) );
|
|
|
|
Assert( STR_EQUAL("double", grib_get_type_name(GRIB_TYPE_DOUBLE)) );
|
|
|
|
Assert( STR_EQUAL("bytes", grib_get_type_name(GRIB_TYPE_BYTES)) );
|
|
|
|
Assert( STR_EQUAL("label", grib_get_type_name(GRIB_TYPE_LABEL)) );
|
|
|
|
Assert( STR_EQUAL("section", grib_get_type_name(GRIB_TYPE_SECTION)) );
|
|
|
|
}
|
|
|
|
|
2013-03-25 14:23:07 +00:00
|
|
|
int main(int argc, char** argv)
|
|
|
|
{
|
2022-10-26 12:02:45 +00:00
|
|
|
printf("Doing unit tests. ecCodes version = %ld\n", grib_get_api_version());
|
2022-10-20 13:38:17 +00:00
|
|
|
|
2023-08-21 21:02:03 +00:00
|
|
|
test_iarray();
|
|
|
|
test_darray();
|
|
|
|
test_sarray();
|
|
|
|
|
2023-08-23 13:26:56 +00:00
|
|
|
test_codes_get_product_name();
|
2023-08-23 13:41:29 +00:00
|
|
|
test_codes_get_type_name();
|
2023-08-23 13:26:56 +00:00
|
|
|
|
2023-04-08 11:40:30 +00:00
|
|
|
test_scale_factor_scaled_values();
|
2023-02-16 16:07:24 +00:00
|
|
|
test_dates();
|
2022-11-19 17:49:39 +00:00
|
|
|
test_logging_proc();
|
2022-10-20 13:38:17 +00:00
|
|
|
test_grib_binary_search();
|
2022-10-26 12:02:45 +00:00
|
|
|
test_parse_keyval_string();
|
2022-12-26 14:37:01 +00:00
|
|
|
|
2020-02-27 13:47:07 +00:00
|
|
|
test_get_git_sha1();
|
2021-12-14 19:49:25 +00:00
|
|
|
test_get_build_date();
|
2022-02-24 15:16:55 +00:00
|
|
|
test_gribex_mode();
|
2017-04-05 15:47:19 +00:00
|
|
|
|
2019-12-01 16:13:38 +00:00
|
|
|
test_concept_condition_strings();
|
|
|
|
|
2017-04-05 15:47:19 +00:00
|
|
|
test_assertion_catching();
|
2014-07-21 12:22:20 +00:00
|
|
|
|
|
|
|
test_gaussian_latitude_640();
|
|
|
|
|
|
|
|
test_gaussian_latitudes(32);
|
|
|
|
test_gaussian_latitudes(48);
|
|
|
|
test_gaussian_latitudes(80);
|
|
|
|
test_gaussian_latitudes(128);
|
|
|
|
test_gaussian_latitudes(160);
|
|
|
|
test_gaussian_latitudes(200);
|
|
|
|
test_gaussian_latitudes(256);
|
|
|
|
test_gaussian_latitudes(320);
|
|
|
|
test_gaussian_latitudes(400);
|
|
|
|
test_gaussian_latitudes(512);
|
|
|
|
test_gaussian_latitudes(640);
|
|
|
|
test_gaussian_latitudes(1024);
|
|
|
|
test_gaussian_latitudes(1280);
|
|
|
|
test_gaussian_latitudes(2000);
|
|
|
|
|
|
|
|
test_grib_nearest_smaller_ibmfloat();
|
|
|
|
test_grib_nearest_smaller_ieeefloat();
|
|
|
|
|
2016-10-07 14:12:27 +00:00
|
|
|
test_string_splitting();
|
2023-08-04 21:17:04 +00:00
|
|
|
test_string_ends_with();
|
|
|
|
test_string_to_long();
|
|
|
|
test_string_trimming();
|
|
|
|
test_string_replace_char();
|
|
|
|
test_string_remove_char();
|
2016-10-07 14:12:27 +00:00
|
|
|
|
2014-07-21 12:22:20 +00:00
|
|
|
return 0;
|
2013-03-25 14:23:07 +00:00
|
|
|
}
|