Skip to content

Instantly share code, notes, and snippets.

@piguet-b
Last active August 29, 2015 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save piguet-b/271f856cdd8d45bd6105 to your computer and use it in GitHub Desktop.
Save piguet-b/271f856cdd8d45bd6105 to your computer and use it in GitHub Desktop.
Example of a definition and use of a lenient version of ut_compare
/**
* Demonstration of the strict behaviour of ut_compare(), (for some values
* of unit, ut_compare(unit, (ut_parse(ut_format(unit))) != 0), and
* of a more lenient version.
*
* compile with :
* gcc -O pb_compare.c -ludunits2 -o pb_compare
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <udunits2/udunits2.h>
static ut_system *unitSystem;
int
my_ut_compare_pragmatic (const ut_unit * unit1, const ut_unit * unit2)
{
int CodRet;
ut_unit *ratio_ut_unit;
double ratio_double;
char buf[120];
char *endptr;
CodRet = ut_compare (unit1, unit2);
if (CodRet == 0)
return CodRet;
/* "This function returns a non-zero value if conversion is possible;
* otherwise, 0 is returned" */
CodRet = ut_are_convertible (unit1, unit2);
/* if conversion impossible, exit */
if (CodRet == 0)
return -5;
/* let's see if conversion ratio is close to 1 */
ratio_ut_unit = ut_divide (unit1, unit2);
if (ratio_ut_unit == NULL)
return -6;
/* Don't know how to get the value from an ut_unit variable.
* So, let's format it and parse the resulting string */
CodRet = ut_format (ratio_ut_unit, buf, sizeof (buf), UT_ASCII);
ut_free (ratio_ut_unit);
ratio_ut_unit = NULL;
if ((CodRet < 0) || (CodRet >= (int) sizeof (buf)))
{
return -7;
}
/* the end must be " 1" (meaning dimensionless) */
if ((strlen (buf) > 2) && (!strcmp (buf + strlen (buf) - 2, " 1")))
{
buf[strlen (buf) - 2] = 0;
ratio_double = strtod (buf, &endptr);
if ((*endptr == 0) && (fabs (1.0 - ratio_double) < 1.0e-8))
{
/* Approximately equal --> OK ! */
return 0;
}
}
return -8;
}
void
test_back_forth (const char *unit_str)
{
ut_unit *unit_1, *unit_2;
char buf[120];
int len, cmp_cod;
unit_1 = ut_parse (unitSystem, unit_str, UT_ASCII);
if (unit_1 == NULL)
{
fprintf (stderr, "Error %d parsing : %s\n", ut_get_status (), unit_str);
return;
}
len = ut_format (unit_1, buf, sizeof (buf), UT_ASCII);
if ((len < 0) || (len >= (int) sizeof (buf)))
{
fprintf (stderr, "Error %d writing unit\n", ut_get_status ());
ut_free (unit_1);
return;
}
fprintf (stdout, "%s formatted as : %s\n", unit_str, buf);
unit_2 = ut_parse (unitSystem, buf, UT_ASCII);
if (unit_2 == NULL)
{
fprintf (stderr, "Error %d parsing : %s\n", ut_get_status (), buf);
ut_free (unit_1);
return;
}
cmp_cod = ut_compare (unit_1, unit_2);
fprintf (stdout, " ut_compare(%s, %s) = %d\n", unit_str, buf, cmp_cod);
cmp_cod = my_ut_compare_pragmatic (unit_1, unit_2);
fprintf (stdout, " my_ut_compare(%s, %s) = %d\n", unit_str, buf,
cmp_cod);
ut_free (unit_1);
ut_free (unit_2);
}
int
main (int argc, char *argv[])
{
const char *unit_tab[] = { "degree",
"kt",
"ft/min",
"mm/h",
"l/min"
};
unsigned long nb_unit = sizeof (unit_str) / sizeof (*unit_str);
unsigned long i;
unitSystem = ut_read_xml (NULL);
if (unitSystem == NULL)
return 1;
for (i = 0; i < nb_unit; i++)
test_back_forth (unit_tab[i]);
ut_free_system (unitSystem);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment