[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[UDUNITS #BUK-910616]: ut_get_name() returning NULL?
- Subject: [UDUNITS #BUK-910616]: ut_get_name() returning NULL?
- Date: Mon, 06 Jul 2015 10:45:17 -0600
David,
> Moving the "<symbol>lb</symbol>" out of the "aliases" section functioned
> as expected and the three output lines all changed to:
> ut_get_unit_by_name( "pound" ) returned "lb"
If that's all it takes (promoting the standard name and symbol from the
"aliases" section) then all that's needed is for that to be done for all the
unit entries. Shouldn't take more than a day.
I wish I had a day.
> In the process I uncovered a bug. I accidentally copied the
> "<symbol>lb</symbol>" out of the aliases instead of moving it (i.e., it
> was defined both in and out of the aliases). This resulted in a
> segmentation fault... :-(
Interesting! I'll have to see if I can replicate that. It's been added to the
list of issues on the GitHub site.
> I am still a little confused by UDUNITS definition of a unit-system
> since it seems that the definition that base units are SI is totally
> irrelevant when actually using the unit-system.
Not quite. A unit system defines the base units -- the units from which all
other units are defined and to which all other units will be converted for
comparison and conversion purposes.
> Even more than that,
> however, I don't see a way to even know if a value with units parsed by
> the system is in SI units or not. Whether ut_get_name() returned NULL or
> a name was a clue, but not a very good one.
If the function ut_read_xml() is given a NULL argument, then the resulting unit
system will be the SI.
> Can I propose an extension to the library that might help? I would be
> willing to assist with its implementation as my time permits.
>
> What I would propose is adding the concept of a "named system".
> Examples, and probably predefined, would be "SI", "MKS", "cgs", "
> avoirdupois", "imperial system", "US", etc. Maybe allowing aliases for
> these would be good too. This would be completely general however so a
> user could define their own favorite units system. Any given unit could
> be part of any number of named units systems and of course the named
> unit system could have any number of units.
This is possible now by specifying the pathname of the unit database to open to
the function ut_read_xml(). For example "ut_read_xml("imperial.xml"). Doing so
would require that the "imperial.xml" database exists, however.
The unfortunate result of doing this, however, is that units in different unit
systems are not comparable and values in units in different unit systems are
not convertible.
> Extensions to the API could be something like:
> 1) ut_status ut_add_named_system( ut_system* system, const char
> *system_name );
> 2) ut_status ut_map_name_to_named_system( ut_system* system, const
> char *new_name, const char *system_name );
> 3) ut_status ut_add_unit_to_named_system( const ut_unit* unit,
> const char *system_name );
> 4) ut_status ut_remove_unit_from_named_system( const ut_unit*
> unit, const char *system_name );
> 5) int ut_is_in_named_system( const ut_unit *unit, const
> char* system_name );
> 6) ut_unit* ut_unit_in_named_system_convertible_with_unit( const
> char* system_name, const ut_unit* unit );
>
> With these code like:
>
> if( !ut_is_in_named_system( usersUnits, "SI" ) ) {
> ut_unit *siEquiv =
> ut_unit_in_named_system_convertible_with_unit( "SI", usersUnits );
> printf( "The value provided by the user is in %s but will
> be converted to %s\n",
> ut_get_name( usersUnits ), ut_get_name( siEquiv ) );
> }
>
> or
> chart *userPreferedUnitSystem = "US";
>
> if( !ut_is_in_named_system( unitsForSensorValue,
> userPreferedUnitSystem ) ) {
> ut_unit *preferedEquiv =
> ut_unit_in_named_system_convertible_with_unit( userPreferedUnitSystem,
> unitsForSensorValue );
> cv_converter *converter = ut_get_converter(
> unitsForSensorValue, preferedEquiv );
> double equivValue = cv_convert_double( converter,
> valueFromSensor );
> printf( "The current sensor value is %g %s\n", equivValue,
> ut_get_symbol( preferedEquiv ) );
> } else {
> printf( "The current sensor value is %g %s\n",
> valueFromSensor, ut_get_symbol( unitsForSensorValue ) );
> }
>
> or
> // Maybe an application would have a user initialization file
> these could be set from....
> ut_add_named_system( system, const "outback" );
> ut_status ut_add_unit_to_named_system( ut_get_unit_by_name(
> "jigger" ), "outback" );
> ut_status ut_add_unit_to_named_system( ut_get_unit_by_name(
> "furlong" ), "outback" );
> ut_status ut_add_unit_to_named_system( ut_get_unit_by_name(
> "hand" ), "outback" );
> ut_status ut_add_unit_to_named_system( ut_get_unit_by_name(
> "stone" ), "outback" );
>
> ut_unit *volumeUnits = ut_get_unit_by_name( system, "liter" );
> ut_unit *australianVolumeUnits =
> ut_unit_in_named_system_convertible_with_unit( "outback", volumeUnits );
> printf( "In the outback unit system milk is bought in %s\n",
> ut_get_name( australianVolumeUnits ) );
>
> There could be extensions to specify units as base units within a named
> system, etc., if this would improve the interface. This would require
> extending the XML. Maybe with an attribute or new tag defined for a unit
> or potentially simpler would be a new top level tag "named-unit-system"
> that would contain a name, an aliases section, and a list of the units
> it contains.
>
> What do you think?
I think this is a possible solution to the wrong problem. User's usually want
something like this so that, when a program prints a value with a unit, the
unit is something that the user wants (e.g., mass in pounds rather than
kilograms). A better solution to this problem would be to make programs
configurable in terms of the units the user wants to see for output values.
Regards,
Steve Emmerson
Ticket Details
===================
Ticket ID: BUK-910616
Department: Support UDUNITS
Priority: High
Status: Closed