netcdf-c/ncgen/jdata.c

172 lines
3.9 KiB
C
Raw Normal View History

/*********************************************************************
2018-12-07 06:40:43 +08:00
* Copyright 2018, UCAR/Unidata
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
*********************************************************************/
2010-06-03 21:24:43 +08:00
#include "includes.h"
#ifdef ENABLE_JAVA
#include <math.h>
#ifndef isnan
extern int isnan(double);
#endif
2010-06-03 21:24:43 +08:00
static int j_uid = 0;
2010-06-03 21:24:43 +08:00
static int
j_charconstant(Generator* generator, Symbol* sym, Bytebuffer* codebuf, ...)
{
/* Escapes and quoting will be handled in genc_write */
/* Just transfer charbuf to codebuf */
Bytebuffer* charbuf;
va_list ap;
Fix more memory leaks in netcdf-c library This is a follow up to PR https://github.com/Unidata/netcdf-c/pull/1173 Sorry that it is so big, but leak suppression can be complex. This PR fixes all remaining memory leaks -- as determined by -fsanitize=address, and with the exceptions noted below. Unfortunately. there remains a significant leak that I cannot solve. It involves vlens, and it is unclear if the leak is occurring in the netcdf-c library or the HDF5 library. I have added a check_PROGRAM to the ncdump directory to show the problem. The program is called tst_vlen_demo.c To exercise it, build the netcdf library with -fsanitize=address enabled. Then go into ncdump and do a "make clean check". This should build tst_vlen_demo without actually executing it. Then do the command "./tst_vlen_demo" to see the output of the memory checker. Note the the lost malloc is deep in the HDF5 library (in H5Tvlen.c). I am temporarily working around this error in the following way. 1. I modified several test scripts to not execute known vlen tests that fail as described above. 2. Added an environment variable called NC_VLEN_NOTEST. If set, then those specific tests are suppressed. This should mean that the --disable-utilities option to ./configure should not need to be set to get a memory leak clean build. This should allow for detection of any new leaks. Note: I used an environment variable rather than a ./configure option to control the vlen tests. This is because it is temporary (I hope) and because it is a bit tricky for shell scripts to access ./configure options. Finally, as before, this only been tested with netcdf-4 and hdf5 support.
2018-11-16 01:00:38 +08:00
va_start(ap,codebuf);
charbuf = va_arg(ap, Bytebuffer*);
va_end(ap);
bbNull(charbuf);
bbCatbuf(codebuf,charbuf);
return 1;
}
2010-06-03 21:24:43 +08:00
static int
j_constant(Generator* generator, Symbol* sym, NCConstant* con, Bytebuffer* buf,...)
2010-06-03 21:24:43 +08:00
{
Bytebuffer* codetmp = bbNew();
char* special = NULL;
switch (con->nctype) {
case NC_CHAR:
if(con->value.charv == '\'')
bbprintf(codetmp,"'\\''");
else
bbprintf(codetmp,"'%c'",con->value.charv);
break;
case NC_BYTE:
bbprintf(codetmp,"%hhd",con->value.int8v);
break;
case NC_SHORT:
bbprintf(codetmp,"%hd",con->value.int16v);
break;
case NC_INT:
bbprintf(codetmp,"%d",con->value.int32v);
break;
case NC_FLOAT:
/* Special case for nan */
if(isnan(con->value.floatv))
bbprintf(codetmp,"Float.NaN");
else
bbprintf(codetmp,"%f",con->value.floatv);
break;
case NC_DOUBLE:
/* Special case for nan */
if(isnan(con->value.doublev))
bbprintf(codetmp,"Double.NaN");
else
bbprintf(codetmp,"%lf",con->value.doublev);
break;
case NC_UBYTE:
bbprintf(codetmp,"%hhu",con->value.uint8v);
break;
case NC_USHORT:
bbprintf(codetmp,"%hu",con->value.uint16v);
break;
case NC_UINT:
bbprintf(codetmp,"%uU",con->value.uint32v);
break;
case NC_INT64:
bbprintf(codetmp,"%lldLL",con->value.int64v);
break;
case NC_UINT64:
bbprintf(codetmp,"%lluLLU",con->value.uint64v);
break;
case NC_STRING: { /* handle separately */
char* escaped = escapify(con->value.stringv.stringv,
'"',con->value.stringv.len);
special = poolalloc(1+2+strlen(escaped));
strcpy(special,"\"");
strcat(special,escaped);
strcat(special,"\"");
} break;
default: PANIC1("ncstype: bad type code: %d",con->nctype);
}
if(special == NULL)
bbCatbuf(buf,codetmp);
else
bbCat(buf,special);
bbFree(codetmp);
return 1;
2010-06-03 21:24:43 +08:00
}
static int
j_listbegin(Generator* generator, Symbol* sym, void* liststate, ListClass lc, size_t size, Bytebuffer* codebuf, int* uidp, ...)
2010-06-03 21:24:43 +08:00
{
if(uidp) *uidp = ++j_uid;
switch (lc) {
case LISTATTR:
case LISTDATA:
break;
case LISTFIELDARRAY:
case LISTVLEN:
case LISTCOMPOUND:
2010-06-03 21:24:43 +08:00
break;
}
return 1;
2010-06-03 21:24:43 +08:00
}
static int
j_list(Generator* generator, Symbol* sym, void* liststate, ListClass lc, int uid, size_t count, Bytebuffer* codebuf, ...)
2010-06-03 21:24:43 +08:00
{
switch (lc) {
case LISTATTR:
if(count > 0) bbCat(codebuf,", ");
break;
case LISTDATA:
bbCat(codebuf," ");
break;
case LISTVLEN:
case LISTCOMPOUND:
case LISTFIELDARRAY:
break;
2010-06-03 21:24:43 +08:00
}
return 1;
}
2010-06-03 21:24:43 +08:00
static int
j_listend(Generator* generator, Symbol* sym, void* liststate, ListClass lc, int uid, size_t count, Bytebuffer* buf, ...)
{
return 1;
}
2010-06-03 21:24:43 +08:00
static int
j_vlendecl(Generator* generator, Symbol* tsym, Bytebuffer* codebuf, int uid, size_t count, ...)
{
return 1;
2010-06-03 21:24:43 +08:00
}
static int
j_vlenstring(Generator* generator, Symbol* sym, Bytebuffer* vlenmem, int* uidp, size_t* countp,...)
2010-06-03 21:24:43 +08:00
{
if(uidp) *uidp = ++j_uid;
if(countp) *countp = 0;
return 1;
}
2010-06-03 21:24:43 +08:00
/* Define the single static bin data generator */
static Generator j_generator_singleton = {
NULL,
j_charconstant,
j_constant,
j_listbegin,
j_list,
j_listend,
j_vlendecl,
j_vlenstring
};
Generator* j_generator = &j_generator_singleton;
2010-06-03 21:24:43 +08:00
#endif /*ENABLE_JAVA*/