Commit 100a03ff authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

Refactor cdoConvertUnits().

parent 0a02c98c
......@@ -44,132 +44,10 @@
#include "pstream.h"
#include "util.h"
#include "pmlist.h"
#include "convert_units.h"
int stringToParam(const char *paramstr);
#if defined(HAVE_UDUNITS2)
static void udunitsInitialize(void);
static int udunitsInit = 0;
#if defined(HAVE_LIBPTHREAD)
# include <pthread.h>
static pthread_once_t udunitsInitThread = PTHREAD_ONCE_INIT;
static pthread_mutex_t udunitsMutex;
# define UDUNITS_LOCK() pthread_mutex_lock(&udunitsMutex)
# define UDUNITS_UNLOCK() pthread_mutex_unlock(&udunitsMutex)
# define UDUNITS_INIT() pthread_once(&udunitsInitThread, udunitsInitialize)
#else
# define UDUNITS_LOCK()
# define UDUNITS_UNLOCK()
# define UDUNITS_INIT() if ( !udunitsInit ) udunitsInitialize();
#endif
static ut_system *ut_read = NULL;
static
void udunitsInitialize(void)
{
#if defined(HAVE_LIBPTHREAD)
/* initialize global API mutex lock */
pthread_mutex_init(&udunitsMutex, NULL);
#endif
udunitsInit = 1;
}
static
void *get_converter(char *src_unit_str, char *tgt_unit_str, int *rstatus)
{
ut_unit *src_unit, *tgt_unit;
cv_converter *ut_units_converter = NULL;
int status;
*rstatus = -1;
if ( ut_read == NULL )
{
ut_set_error_message_handler(ut_ignore);
errno = 0;
ut_read = ut_read_xml(NULL);
status = ut_get_status();
if ( status == UT_PARSE )
{
if ( cdoVerbose ) cdoWarning("Udunits: Couldn't parse unit database!");
}
if ( status == UT_OPEN_ENV || status == UT_OPEN_DEFAULT || status == UT_OS )
{
if ( cdoVerbose ) cdoWarning("Udunits: %s", strerror(errno));
}
errno = 0;
if ( status != UT_SUCCESS )
{
if ( cdoVerbose ) cdoWarning("Udunits: Error reading units system!");
return NULL;
}
}
ut_trim(src_unit_str, UT_ASCII);
src_unit = ut_parse(ut_read, src_unit_str, UT_ASCII);
if ( ut_get_status() != UT_SUCCESS )
{
if ( cdoVerbose ) cdoWarning("Udunits: Error parsing units: [%s]", src_unit_str);
return NULL;
}
ut_trim(tgt_unit_str, UT_ASCII);
tgt_unit = ut_parse(ut_read, tgt_unit_str, UT_ASCII);
if ( ut_get_status() != UT_SUCCESS )
{
if ( cdoVerbose ) cdoWarning("Udunits: Error parsing units: [%s]", tgt_unit_str);
return NULL;
}
status = ut_compare(src_unit, tgt_unit);
if ( status == 0 ) *rstatus = -2;
if ( *rstatus == -1 )
{
status = ut_are_convertible(src_unit, tgt_unit);
if ( status == 0 ) *rstatus = -3;
}
if ( *rstatus == -1 )
{
ut_units_converter = ut_get_converter(src_unit, tgt_unit);
if ( ut_units_converter == NULL || ut_get_status() != UT_SUCCESS )
{
if ( cdoVerbose ) cdoWarning("Udunits: Error getting converter from [%s] to [%s]", src_unit_str, tgt_unit_str);
}
else
*rstatus = 0;
}
ut_free(src_unit);
if ( ut_get_status() != UT_SUCCESS )
{
if ( cdoVerbose ) cdoWarning("Udunits: Error freeing units [%s]", src_unit_str);
return NULL;
}
ut_free(tgt_unit);
if ( ut_get_status() != UT_SUCCESS )
{
if ( cdoVerbose ) cdoWarning("Udunits: Error freeing units [%s]", tgt_unit_str);
return NULL;
}
return (void *) ut_units_converter;
}
#endif
typedef struct
{
bool convert;
......@@ -208,57 +86,6 @@ void defineVarAttText(int vlistID2, int varID, const char *attname, const char *
cdiDefAttTxt(vlistID2, varID, attname, len, atttext);
}
static
void convertVarUnits(var_t *vars, int varID, char *name)
{
if ( vars[varID].convert == false ) vars[varID].changeunits = false;
if ( vars[varID].changeunits )
{
char *units = vars[varID].units;
char *units_old = vars[varID].units_old;
#if defined(HAVE_UDUNITS2)
int status;
UDUNITS_INIT();
UDUNITS_LOCK();
vars[varID].ut_converter = get_converter(units_old, units, &status);
UDUNITS_UNLOCK();
if ( vars[varID].ut_converter == NULL )
{
if ( status == -2 )
{
if ( cdoVerbose )
cdoPrint("%s - not converted from [%s] to [%s], units are equal!", name, units_old, units);
}
else if ( status == -3 )
{
cdoWarning("%s - converting units from [%s] to [%s] failed, not convertible!", name, units_old, units);
}
else
cdoWarning("%s - converting units from [%s] to [%s] failed!", name, units_old, units);
vars[varID].changeunits = false;
}
else
{
// if ( cdoVerbose )
{
char buf[64];
cv_get_expression((const cv_converter*)vars[varID].ut_converter, buf, 64, name);
cdoPrint("%s - convert units from [%s] to [%s] (expression: %s).", name, units_old, units, buf);
}
}
#else
static bool lwarn_udunits = true;
if ( lwarn_udunits )
{
cdoWarning("%s - converting units from [%s] to [%s] failed, UDUNITS2 support not compiled in!", name,units_old, units);
vars[varID].changeunits = false;
lwarn_udunits = false;
}
#endif
}
}
static
void defineVarUnits(var_t *vars, int vlistID2, int varID, const char *units)
{
......@@ -614,7 +441,12 @@ void *CMOR_lite(void *argument)
}
for ( int varID = 0; varID < nvars; ++varID )
convertVarUnits(vars, varID, vars[varID].name);
{
var_t *var = &vars[varID];
if ( var->convert == false ) var->changeunits = false;
if ( var->changeunits )
cdoConvertUnits(&var->ut_converter, &var->changeunits, (char*)&var->units, (char*)&var->units_old, var->name);
}
int taxisID1 = vlistInqTaxis(vlistID1);
int taxisID2 = taxisDuplicate(taxisID1);
......@@ -711,18 +543,10 @@ void *CMOR_lite(void *argument)
streamClose(streamID1);
#if defined(HAVE_UDUNITS2)
UDUNITS_LOCK();
for ( int varID = 0; varID < nvars; varID++ )
if ( vars[varID].ut_converter ) cv_free((cv_converter*)vars[varID].ut_converter);
if ( ut_read )
{
ut_free_system(ut_read);
ut_read = NULL;
}
if ( vars[varID].ut_converter ) cdoConvertFree(vars[varID].ut_converter);
UDUNITS_UNLOCK();
cdoConvertDestroy();
#endif
if ( array ) Free(array);
......
......@@ -27,6 +27,8 @@ libcdo_la_SOURCES = \
color.h \
commandline.c \
const.h \
convert_units.c \
convert_units.h \
counter.h \
datetime.c \
datetime.h \
......
......@@ -109,14 +109,15 @@ am_libcdo_la_OBJECTS = libcdo_la-cdo_pthread.lo libcdo_la-cdo_vlist.lo \
libcdo_la-after_vertint.lo libcdo_la-after_namelist.lo \
libcdo_la-afterburnerlib.lo libcdo_la-constants.lo \
libcdo_la-color.lo libcdo_la-commandline.lo \
libcdo_la-datetime.lo libcdo_la-ecacore.lo \
libcdo_la-ecautil.lo libcdo_la-exception.lo libcdo_la-expr.lo \
libcdo_la-expr_fun.lo libcdo_la-expr_lex.lo \
libcdo_la-expr_yacc.lo libcdo_la-features.lo \
libcdo_la-field.lo libcdo_la-field2.lo libcdo_la-fieldc.lo \
libcdo_la-fieldmem.lo libcdo_la-fieldmer.lo \
libcdo_la-fieldzon.lo libcdo_la-gradsdeslib.lo \
libcdo_la-grid.lo libcdo_la-grid_area.lo libcdo_la-grid_gme.lo \
libcdo_la-convert_units.lo libcdo_la-datetime.lo \
libcdo_la-ecacore.lo libcdo_la-ecautil.lo \
libcdo_la-exception.lo libcdo_la-expr.lo libcdo_la-expr_fun.lo \
libcdo_la-expr_lex.lo libcdo_la-expr_yacc.lo \
libcdo_la-features.lo libcdo_la-field.lo libcdo_la-field2.lo \
libcdo_la-fieldc.lo libcdo_la-fieldmem.lo \
libcdo_la-fieldmer.lo libcdo_la-fieldzon.lo \
libcdo_la-gradsdeslib.lo libcdo_la-grid.lo \
libcdo_la-grid_area.lo libcdo_la-grid_gme.lo \
libcdo_la-grid_lcc.lo libcdo_la-grid_rot.lo \
libcdo_la-gridreference.lo libcdo_la-griddes.lo \
libcdo_la-griddes_h5.lo libcdo_la-griddes_nc.lo \
......@@ -505,32 +506,33 @@ libcdo_la_SOURCES = cdo_int.h compare.h cdo_pthread.c cdo_vlist.c \
after_vertint.c after_vertint.h after_namelist.c \
afterburnerlib.c afterburner.h vct_l191.h calendar.h \
constants.h constants.c color.c color.h commandline.c const.h \
counter.h datetime.c datetime.h dmemory.h ecacore.c ecacore.h \
ecautil.c ecautil.h error.h etopo.h temp.h mask.h exception.c \
expr.c expr.h expr_fun.c expr_fun.h expr_lex.c expr_yacc.c \
expr_yacc.h features.c field.c field.h field2.c fieldc.c \
fieldmem.c fieldmer.c fieldzon.c functs.h gradsdeslib.c \
gradsdeslib.h grid.c grid.h grid_area.c grid_gme.c grid_lcc.c \
grid_rot.c gridreference.c griddes.c griddes.h griddes_h5.c \
griddes_nc.c hetaeta.c hetaeta.h institution.c interpol.c \
interpol.h job.c juldate.c grid_search.c grid_search.h \
listarray.c listarray.h list.c list.h merge_sort2.c \
merge_sort2.h modules.c modules.h namelist.c namelist.h nml.c \
nml.h normal.c nth_element.c nth_element.h operator_help.h \
par_io.c par_io.h parse_cmor_table.c percentiles_hist.c \
percentiles_hist.h percentiles.c percentiles.h pipe.c pipe.h \
pml.c pml.h pmlist.c pmlist.h pragma_omp_atomic_update.h \
printinfo.h process.c process.h pstream.c pstream.h \
pstream_write.h pstream_int.h pthread_debug.c pthread_debug.h \
readline.c realtime.c remap.h remaplib.c remapsort.c \
remap_scrip_io.c remap_search_reg2d.c remap_search_latbins.c \
remap_store_link.c remap_store_link.h remap_store_link_cnsrv.c \
remap_store_link_cnsrv.h remap_conserv.c remap_conserv_scrip.c \
remap_distwgt.c remap_bicubic_scrip.c remap_bilinear_scrip.c \
stdnametable.c stdnametable.h specspace.c specspace.h \
statistic.c statistic.h table.c text.c text.h timebase.h \
timer.c userlog.c uthash.h util.c util.h zaxis.c json/jsmn.h \
json/jsmn.c kdtreelib/kdtree.h kdtreelib/kdtree_cartesian.c \
convert_units.c convert_units.h counter.h datetime.c \
datetime.h dmemory.h ecacore.c ecacore.h ecautil.c ecautil.h \
error.h etopo.h temp.h mask.h exception.c expr.c expr.h \
expr_fun.c expr_fun.h expr_lex.c expr_yacc.c expr_yacc.h \
features.c field.c field.h field2.c fieldc.c fieldmem.c \
fieldmer.c fieldzon.c functs.h gradsdeslib.c gradsdeslib.h \
grid.c grid.h grid_area.c grid_gme.c grid_lcc.c grid_rot.c \
gridreference.c griddes.c griddes.h griddes_h5.c griddes_nc.c \
hetaeta.c hetaeta.h institution.c interpol.c interpol.h job.c \
juldate.c grid_search.c grid_search.h listarray.c listarray.h \
list.c list.h merge_sort2.c merge_sort2.h modules.c modules.h \
namelist.c namelist.h nml.c nml.h normal.c nth_element.c \
nth_element.h operator_help.h par_io.c par_io.h \
parse_cmor_table.c percentiles_hist.c percentiles_hist.h \
percentiles.c percentiles.h pipe.c pipe.h pml.c pml.h pmlist.c \
pmlist.h pragma_omp_atomic_update.h printinfo.h process.c \
process.h pstream.c pstream.h pstream_write.h pstream_int.h \
pthread_debug.c pthread_debug.h readline.c realtime.c remap.h \
remaplib.c remapsort.c remap_scrip_io.c remap_search_reg2d.c \
remap_search_latbins.c remap_store_link.c remap_store_link.h \
remap_store_link_cnsrv.c remap_store_link_cnsrv.h \
remap_conserv.c remap_conserv_scrip.c remap_distwgt.c \
remap_bicubic_scrip.c remap_bilinear_scrip.c stdnametable.c \
stdnametable.h specspace.c specspace.h statistic.c statistic.h \
table.c text.c text.h timebase.h timer.c userlog.c uthash.h \
util.c util.h zaxis.c json/jsmn.h json/jsmn.c \
kdtreelib/kdtree.h kdtreelib/kdtree_cartesian.c \
kdtreelib/kdtree_common.c kdtreelib/kdtree_spherical.c \
kdtreelib/qsort.c kdtreelib/pmergesort.c kdtreelib/pqueue.c \
kdtreelib/pqueue.h clipping/clipping.c clipping/clipping.h \
......@@ -1004,6 +1006,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdo_la-color.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdo_la-commandline.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdo_la-constants.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdo_la-convert_units.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdo_la-datetime.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdo_la-ecacore.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdo_la-ecautil.Plo@am__quote@
......@@ -1212,6 +1215,13 @@ libcdo_la-commandline.lo: commandline.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-commandline.lo `test -f 'commandline.c' || echo '$(srcdir)/'`commandline.c
libcdo_la-convert_units.lo: convert_units.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-convert_units.lo -MD -MP -MF $(DEPDIR)/libcdo_la-convert_units.Tpo -c -o libcdo_la-convert_units.lo `test -f 'convert_units.c' || echo '$(srcdir)/'`convert_units.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-convert_units.Tpo $(DEPDIR)/libcdo_la-convert_units.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='convert_units.c' object='libcdo_la-convert_units.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-convert_units.lo `test -f 'convert_units.c' || echo '$(srcdir)/'`convert_units.c
libcdo_la-datetime.lo: datetime.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-datetime.lo -MD -MP -MF $(DEPDIR)/libcdo_la-datetime.Tpo -c -o libcdo_la-datetime.lo `test -f 'datetime.c' || echo '$(srcdir)/'`datetime.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-datetime.Tpo $(DEPDIR)/libcdo_la-datetime.Plo
......
......@@ -21,157 +21,18 @@
Setpartab setpartab Set parameter table
*/
#if defined(HAVE_CONFIG_H)
# include "config.h"
#endif
#if defined(HAVE_LIBUDUNITS2) && (defined(HAVE_UDUNITS2_H) || defined(HAVE_UDUNITS2_UDUNITS2_H))
#define HAVE_UDUNITS2
#endif
#if defined(HAVE_UDUNITS2)
#if defined(HAVE_UDUNITS2_UDUNITS2_H)
# include <udunits2/udunits2.h>
#else
# include <udunits2.h>
#endif
#endif
#include <errno.h>
#include <cdi.h>
#include "cdo.h"
#include "cdo_int.h"
#include "pstream.h"
#include "util.h"
#include "nml.h"
#include "convert_units.h"
int stringToParam(const char *paramstr);
typedef enum {CODE_NUMBER, PARAMETER_ID, VARIABLE_NAME, STANDARD_NAME} pt_mode_t;
#if defined(HAVE_UDUNITS2)
static void udunitsInitialize(void);
static int udunitsInit = 0;
#if defined(HAVE_LIBPTHREAD)
# include <pthread.h>
static pthread_once_t udunitsInitThread = PTHREAD_ONCE_INIT;
static pthread_mutex_t udunitsMutex;
# define UDUNITS_LOCK() pthread_mutex_lock(&udunitsMutex)
# define UDUNITS_UNLOCK() pthread_mutex_unlock(&udunitsMutex)
# define UDUNITS_INIT() pthread_once(&udunitsInitThread, udunitsInitialize)
#else
# define UDUNITS_LOCK()
# define UDUNITS_UNLOCK()
# define UDUNITS_INIT() if ( !udunitsInit ) udunitsInitialize();
#endif
static ut_system *ut_read = NULL;
static
void udunitsInitialize(void)
{
#if defined(HAVE_LIBPTHREAD)
/* initialize global API mutex lock */
pthread_mutex_init(&udunitsMutex, NULL);
#endif
udunitsInit = 1;
}
static
void *get_converter(char *src_unit_str, char *tgt_unit_str, int *rstatus)
{
ut_unit *src_unit, *tgt_unit;
cv_converter *ut_units_converter = NULL;
int status;
*rstatus = -1;
if ( ut_read == NULL )
{
ut_set_error_message_handler(ut_ignore);
errno = 0;
ut_read = ut_read_xml(NULL);
status = ut_get_status();
if ( status == UT_PARSE )
{
if ( cdoVerbose ) cdoWarning("Udunits: Couldn't parse unit database!");
}
if ( status == UT_OPEN_ENV || status == UT_OPEN_DEFAULT || status == UT_OS )
{
if ( cdoVerbose ) cdoWarning("Udunits: %s", strerror(errno));
}
errno = 0;
if ( status != UT_SUCCESS )
{
if ( cdoVerbose ) cdoWarning("Udunits: Error reading units system!");
return NULL;
}
}
ut_trim(src_unit_str, UT_ASCII);
src_unit = ut_parse(ut_read, src_unit_str, UT_ASCII);
if ( ut_get_status() != UT_SUCCESS )
{
if ( cdoVerbose ) cdoWarning("Udunits: Error parsing units: [%s]", src_unit_str);
return NULL;
}
ut_trim(tgt_unit_str, UT_ASCII);
tgt_unit = ut_parse(ut_read, tgt_unit_str, UT_ASCII);
if ( ut_get_status() != UT_SUCCESS )
{
if ( cdoVerbose ) cdoWarning("Udunits: Error parsing units: [%s]", tgt_unit_str);
return NULL;
}
status = ut_compare(src_unit, tgt_unit);
if ( status == 0 ) *rstatus = -2;
if ( *rstatus == -1 )
{
status = ut_are_convertible(src_unit, tgt_unit);
if ( status == 0 ) *rstatus = -3;
}
if ( *rstatus == -1 )
{
ut_units_converter = ut_get_converter(src_unit, tgt_unit);
if ( ut_units_converter == NULL || ut_get_status() != UT_SUCCESS )
{
if ( cdoVerbose ) cdoWarning("Udunits: Error getting converter from [%s] to [%s]", src_unit_str, tgt_unit_str);
}
else
*rstatus = 0;
}
ut_free(src_unit);
if ( ut_get_status() != UT_SUCCESS )
{
if ( cdoVerbose ) cdoWarning("Udunits: Error freeing units [%s]", src_unit_str);
return NULL;
}
ut_free(tgt_unit);
if ( ut_get_status() != UT_SUCCESS )
{
if ( cdoVerbose ) cdoWarning("Udunits: Error freeing units [%s]", tgt_unit_str);
return NULL;
}
return (void *) ut_units_converter;
}
#endif
typedef struct
{
bool convert;
......@@ -210,57 +71,6 @@ void defineVarAttText(int vlistID2, int varID, const char *attname, const char *
cdiDefAttTxt(vlistID2, varID, attname, len, atttext);
}
static
void convertVarUnits(var_t *vars, int varID, char *name)
{
if ( vars[varID].convert == false ) vars[varID].changeunits = false;
if ( vars[varID].changeunits )
{
char *units = vars[varID].units;
char *units_old = vars[varID].units_old;
#if defined(HAVE_UDUNITS2)
int status;
UDUNITS_INIT();
UDUNITS_LOCK();
vars[varID].ut_converter = get_converter(units_old, units, &status);
UDUNITS_UNLOCK();
if ( vars[varID].ut_converter == NULL )
{
if ( status == -2 )
{
if ( cdoVerbose )
cdoPrint("%s - not converted from [%s] to [%s], units are equal!", name, units_old, units);
}
else if ( status == -3 )
{
cdoWarning("%s - converting units from [%s] to [%s] failed, not convertible!", name, units_old, units);
}
else
cdoWarning("%s - converting units from [%s] to [%s] failed!", name, units_old, units);
vars[varID].changeunits = false;
}
else
{
// if ( cdoVerbose )
{
char buf[64];
cv_get_expression((const cv_converter*)vars[varID].ut_converter, buf, 64, name);
cdoPrint("%s - convert units from [%s] to [%s] (expression: %s).", name, units_old, units, buf);
}
}
#else
static bool lwarn_udunits = true;
if ( lwarn_udunits )
{
cdoWarning("%s - converting units from [%s] to [%s] failed, UDUNITS2 support not compiled in!", name,units_old, units);
vars[varID].changeunits = false;
lwarn_udunits = false;
}
#endif
}
}
static
void defineVarUnits(var_t *vars, int vlistID2, int varID, char *units)
{
......@@ -745,7 +555,12 @@ void *Setpartab(void *argument)
}
for ( int varID = 0; varID < nvars; ++varID )
convertVarUnits(vars, varID, vars[varID].name);
{
var_t *var = &vars[varID];
if ( var->convert == false ) var->changeunits = false;
if ( var->changeunits )
cdoConvertUnits(&var->ut_converter, &var->changeunits, (char*)&var->units, (char*)&var->units_old, var->name);
}
}
int taxisID1 = vlistInqTaxis(vlistID1);
......@@ -843,18 +658,10 @@ void *Setpartab(void *argument)
streamClose(streamID1);
#if defined(HAVE_UDUNITS2)
UDUNITS_LOCK();
for ( int varID = 0; varID < nvars; varID++ )
if ( vars[varID].ut_converter ) cv_free((cv_converter*)vars[varID].ut_converter);
if ( ut_read )
{
ut_free_system(ut_read);
ut_read = NULL;
}
if ( vars[varID].ut_converter ) cdoConvertFree(vars[varID].ut_converter);
UDUNITS_UNLOCK();
cdoConvertDestroy();
#endif
if ( array ) Free(array);
......
#include <errno.h>
#include "convert_units.h"
#if defined(HAVE_UDUNITS2)
static void udunitsInitialize(void);
static int udunitsInit = 0;
#if defined(HAVE_LIBPTHREAD)
# include <pthread.h>
static pthread_once_t udunitsInitThread = PTHREAD_ONCE_INIT;
static pthread_mutex_t udunitsMutex;
# define UDUNITS_LOCK() pthread_mutex_lock(&udunitsMutex)
# define UDUNITS_UNLOCK() pthread_mutex_unlock(&udunitsMutex)
# define UDUNITS_INIT() pthread_once(&udunitsInitThread, udunitsInitialize)
#else
# define UDUNITS_LOCK()
# define UDUNITS_UNLOCK()
# define UDUNITS_INIT() if ( !udunitsInit ) udunitsInitialize();
#endif
static ut_system *ut_read = NULL;
static
void udunitsInitialize(void)
{
#if defined(HAVE_LIBPTHREAD)
/* initialize global API mutex lock */
pthread_mutex_init(&udunitsMutex, NULL);
#endif
udunitsInit = 1;
}
static
void *get_converter(char *src_unit_str, char *tgt_unit_str, int *rstatus)
{
ut_unit *src_unit, *tgt_unit;
cv_converter *ut_units_converter = NULL;
int status;
*rstatus = -1;