From 8b0e1134b49b9dd6e7463f4d41cac21ae07b3afc Mon Sep 17 00:00:00 2001 From: Dennis Heimbigner Date: Tue, 5 Jul 2022 22:03:52 -0600 Subject: [PATCH 1/3] Ensure that netcdf_json.h does not interfere with ncjson. re: Issue https://github.com/Unidata/netcdf-c/issues/2419 There are effectively two json subsystems in netcdf-c. 1. ncjson.[ch] in libnetcdf 2. netcdf_json.h for use by plugins so they can be built without need for libnetcdf. The netcdf_json.h file is constructed from the concatenation of ncjson.h plus ncjson.c. It turned out that in doing this, I was leaving some symbols externally visible so that if, for some reason, a plugin was built and needed libnetcdf, then symbol conflicts arose. The solution is to prefix the declarations in ncjson.[ch] with a macro (OPTSTATIC) that can be resolved to either nothing or to "static". Then in netcdf_json.h, it resolves to "static" and prevents the symbol conflicts. Note that netcdf_json.h is constructed once in netcdf-c/include/Makefile.am with the rule named "makepluginjson". This means that it is included in the distribution. However, this also means that if ncjson.[ch] is changed, then it is necessary to invoke makepluginjson explicitly to rebuild netcdf_json.h --- RELEASE_NOTES.md | 2 +- include/CMakeLists.txt | 6 +- include/Makefile.am | 10 ++- include/ncjson.h | 49 ++++++++---- include/netcdf_json.h | 170 +++++++++++++++++++++++++++-------------- libdispatch/dhttp.c | 2 + libdispatch/drc.c | 3 + libdispatch/ncjson.c | 93 ++++++++++++++-------- nc_test4/tst_vars3.c | 8 +- ncdump/tst_vlen_data.c | 8 +- ncgen3/run_tests.sh | 1 + 11 files changed, 239 insertions(+), 113 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index a28e135e29..d03ca6b376 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -5,9 +5,9 @@ Release Notes {#RELEASE_NOTES} This file contains a high-level description of this package's evolution. Releases are in reverse chronological order (most recent first). Note that, as of netcdf 4.2, the `netcdf-c++` and `netcdf-fortran` libraries have been separated into their own libraries. - ## 4.9.1 - T.B.D. +* [Bug Fi] Fix the json submodule symbol conflicts between libnetcdf and the plugin specific netcdf_json.h. See [Github #????](https://github.com/Unidata/netcdf-c/pull/????). * [Enhancement] Add `--disable-quantize` option to `configure`. * [Enhancement] Provide a simple API to allow user access to the internal .rc file table: supports get/set/overwrite of entries of the form "key=value". See [Github #2408](https://github.com/Unidata/netcdf-c/pull/2408). * [Bug Fix] Use env variable USERPROFILE instead of HOME for windows and mingw. See [Github #2405](https://github.com/Unidata/netcdf-c/pull/2405). diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 08017c7f8f..2e507c028a 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -41,9 +41,9 @@ IF(ENABLE_PNETCDF OR ENABLE_PARALLEL4) COMPONENT headers) ENDIF() -#INSTALL(FILES ${netCDF_BINARY_DIR}/include/netcdf_json.h -# DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} -# COMPONENT headers) +INSTALL(FILES ${netCDF_BINARY_DIR}/include/netcdf_json.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + COMPONENT headers) FILE(GLOB CUR_EXTRA_DIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.h) SET(CUR_EXTRA_DIST ${CUR_EXTRA_DIST} Makefile.am CMakeLists.txt) diff --git a/include/Makefile.am b/include/Makefile.am index 0a4a58e050..3b7e13839e 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -32,7 +32,15 @@ endif EXTRA_DIST = CMakeLists.txt XGetopt.h netcdf_meta.h.in netcdf_dispatch.h.in +# netcdf_json.h is constructed as a header-only file for use by +# nczarr code wrappers in the plugin directory. It is +# constructed by joining libdispatch/ncjson.c with +# include/ncjson.h. Additionally all the entry points are +# marked with a macro (OPTSTATIC) that marks the entry point as +# static inside netcdf_json.h. This is an ugly hack to avoid +# having to reference libnetcdf in the nczarr code wrappers. + # Give the recipe for rebuilding netcdf_json.h -makencjson:: +makepluginjson:: sed -e 's/NCJSON_H/NETCDF_JSON_H/' -e '/ncjson.h/d' <${srcdir}/ncjson.h > netcdf_json.h sed -e '/ncjson.h/d' < ${srcdir}/../libdispatch/ncjson.c >> netcdf_json.h diff --git a/include/ncjson.h b/include/ncjson.h index c065bc2ed1..c4974cfb58 100644 --- a/include/ncjson.h +++ b/include/ncjson.h @@ -2,9 +2,20 @@ See the COPYRIGHT file for more information. */ + #ifndef NCJSON_H #define NCJSON_H 1 +/* +WARNING: +If you modify this file, +then you need to got to +the include/ directory +and do the command: + make makepluginjson +*/ + +/* Inside libnetcdf and for plugins, export the json symbols */ #ifndef DLLEXPORT #ifdef _WIN32 #define DLLEXPORT __declspec(dllexport) @@ -13,6 +24,13 @@ #endif #endif +/* Override for plugins */ +#ifdef NETCDF_JSON_H +#define OPTEXPORT static +#else +#define OPTEXPORT DLLEXPORT +#endif /*NETCDF_JSON_H*/ + /**************************************************/ /* Json object sorts (note use of term sort rather than e.g. type or discriminant) */ #define NCJ_UNDEF 0 @@ -57,48 +75,47 @@ extern "C" { #endif /* Parse a string to NCjson*/ -DLLEXPORT int NCJparse(const char* text, unsigned flags, NCjson** jsonp); +OPTEXPORT int NCJparse(const char* text, unsigned flags, NCjson** jsonp); /* Parse a counted string to NCjson*/ -DLLEXPORT int NCJparsen(size_t len, const char* text, unsigned flags, NCjson** jsonp); +OPTEXPORT int NCJparsen(size_t len, const char* text, unsigned flags, NCjson** jsonp); /* Reclaim a JSON tree */ -DLLEXPORT extern void NCJreclaim(NCjson* json); +OPTEXPORT void NCJreclaim(NCjson* json); /* Create a new JSON node of a given sort */ -DLLEXPORT extern int NCJnew(int sort, NCjson** objectp); +OPTEXPORT int NCJnew(int sort, NCjson** objectp); /* Create new json object with given string content */ -DLLEXPORT extern int NCJnewstring(int sort, const char* value, NCjson** jsonp); +OPTEXPORT int NCJnewstring(int sort, const char* value, NCjson** jsonp); /* Create new json object with given counted string content */ -DLLEXPORT extern int NCJnewstringn(int sort, size_t len, const char* value, NCjson** jsonp); +OPTEXPORT int NCJnewstringn(int sort, size_t len, const char* value, NCjson** jsonp); /* Get dict key value by name */ -DLLEXPORT extern int NCJdictget(const NCjson* dict, const char* key, NCjson** valuep); +OPTEXPORT int NCJdictget(const NCjson* dict, const char* key, NCjson** valuep); /* Convert one json sort to value of another type; don't use union so we can know when to reclaim sval */ -DLLEXPORT extern int NCJcvt(const NCjson* value, int outsort, struct NCJconst* output); - -#ifndef NETCDF_JSON_H +OPTEXPORT int NCJcvt(const NCjson* value, int outsort, struct NCJconst* output); /* Insert an atomic value to an array or dict object. */ -DLLEXPORT int NCJaddstring(NCjson* json, int sort, const char* s); +OPTEXPORT int NCJaddstring(NCjson* json, int sort, const char* s); /* Append value to an array or dict object. */ -DLLEXPORT extern int NCJappend(NCjson* object, NCjson* value); +OPTEXPORT int NCJappend(NCjson* object, NCjson* value); /* Insert key-value pair into a dict object. key will be copied */ -DLLEXPORT extern int NCJinsert(NCjson* object, char* key, NCjson* value); +OPTEXPORT int NCJinsert(NCjson* object, char* key, NCjson* value); /* Unparser to convert NCjson object to text in buffer */ -DLLEXPORT extern int NCJunparse(const NCjson* json, unsigned flags, char** textp); +OPTEXPORT int NCJunparse(const NCjson* json, unsigned flags, char** textp); /* Deep clone a json object */ -DLLEXPORT extern int NCJclone(const NCjson* json, NCjson** clonep); +OPTEXPORT int NCJclone(const NCjson* json, NCjson** clonep); +#ifndef NETCDF_JSON_H /* dump NCjson* object to output file */ -DLLEXPORT extern void NCJdump(const NCjson* json, unsigned flags, FILE*); +OPTEXPORT void NCJdump(const NCjson* json, unsigned flags, FILE*); #endif #if defined(__cplusplus) diff --git a/include/netcdf_json.h b/include/netcdf_json.h index 9c6860c925..d53944a8a5 100644 --- a/include/netcdf_json.h +++ b/include/netcdf_json.h @@ -5,6 +5,7 @@ #ifndef NETCDF_JSON_H #define NETCDF_JSON_H 1 +/* Inside libnetcdf and for plugins, export the json symbols */ #ifndef DLLEXPORT #ifdef _WIN32 #define DLLEXPORT __declspec(dllexport) @@ -13,6 +14,13 @@ #endif #endif +/* Override for plugins */ +#ifdef NETCDF_JSON_H +#define OPTEXPORT static +#else +#define OPTEXPORT DLLEXPORT +#endif /*NETCDF_JSON_H*/ + /**************************************************/ /* Json object sorts (note use of term sort rather than e.g. type or discriminant) */ #define NCJ_UNDEF 0 @@ -56,46 +64,48 @@ struct NCJconst {int bval; long long ival; double dval; char* sval;}; extern "C" { #endif -/* Parse a JSON string */ -DLLEXPORT int NCJparse(const char* text, unsigned flags, NCjson** jsonp); +/* Parse a string to NCjson*/ +OPTEXPORT int NCJparse(const char* text, unsigned flags, NCjson** jsonp); + +/* Parse a counted string to NCjson*/ +OPTEXPORT int NCJparsen(size_t len, const char* text, unsigned flags, NCjson** jsonp); /* Reclaim a JSON tree */ -DLLEXPORT extern void NCJreclaim(NCjson* json); +OPTEXPORT void NCJreclaim(NCjson* json); /* Create a new JSON node of a given sort */ -DLLEXPORT extern int NCJnew(int sort, NCjson** objectp); +OPTEXPORT int NCJnew(int sort, NCjson** objectp); /* Create new json object with given string content */ -DLLEXPORT extern int NCJnewstring(int sort, const char* value, NCjson** jsonp); +OPTEXPORT int NCJnewstring(int sort, const char* value, NCjson** jsonp); /* Create new json object with given counted string content */ -DLLEXPORT extern int NCJnewstringn(int sort, size_t len, const char* value, NCjson** jsonp); +OPTEXPORT int NCJnewstringn(int sort, size_t len, const char* value, NCjson** jsonp); /* Get dict key value by name */ -DLLEXPORT extern int NCJdictget(const NCjson* dict, const char* key, NCjson** valuep); +OPTEXPORT int NCJdictget(const NCjson* dict, const char* key, NCjson** valuep); /* Convert one json sort to value of another type; don't use union so we can know when to reclaim sval */ -DLLEXPORT extern int NCJcvt(const NCjson* value, int outsort, struct NCJconst* output); - -#ifndef NETCDF_JSON_H +OPTEXPORT int NCJcvt(const NCjson* value, int outsort, struct NCJconst* output); /* Insert an atomic value to an array or dict object. */ -DLLEXPORT int NCJaddstring(NCjson* json, int sort, const char* s); +OPTEXPORT int NCJaddstring(NCjson* json, int sort, const char* s); /* Append value to an array or dict object. */ -DLLEXPORT extern int NCJappend(NCjson* object, NCjson* value); +OPTEXPORT int NCJappend(NCjson* object, NCjson* value); /* Insert key-value pair into a dict object. key will be copied */ -DLLEXPORT extern int NCJinsert(NCjson* object, char* key, NCjson* value); +OPTEXPORT int NCJinsert(NCjson* object, char* key, NCjson* value); /* Unparser to convert NCjson object to text in buffer */ -DLLEXPORT extern int NCJunparse(const NCjson* json, unsigned flags, char** textp); +OPTEXPORT int NCJunparse(const NCjson* json, unsigned flags, char** textp); /* Deep clone a json object */ -DLLEXPORT extern int NCJclone(const NCjson* json, NCjson** clonep); +OPTEXPORT int NCJclone(const NCjson* json, NCjson** clonep); +#ifndef NETCDF_JSON_H /* dump NCjson* object to output file */ -DLLEXPORT extern void NCJdump(const NCjson* json, unsigned flags, FILE*); +OPTEXPORT void NCJdump(const NCjson* json, unsigned flags, FILE*); #endif #if defined(__cplusplus) @@ -130,8 +140,6 @@ DLLEXPORT extern void NCJdump(const NCjson* json, unsigned flags, FILE*); TODO: make utf8 safe */ -#define NCJSON_INTERNAL - #include #include #include @@ -185,7 +193,7 @@ typedef struct NCJbuf { /**************************************************/ -#ifdef _WIN32 +#if defined(_WIN32) && !defined(__MINGW32__) #define strdup _strdup #define strcasecmp _stricmp #else @@ -217,39 +225,58 @@ static int NCJyytext(NCJparser*, char* start, size_t pdlen); static void NCJreclaimArray(struct NCjlist*); static void NCJreclaimDict(struct NCjlist*); static int NCJunescape(NCJparser* parser); +static int unescape1(int c); static int listappend(struct NCjlist* list, NCjson* element); -#ifndef NETCDF_JSON_H static int NCJcloneArray(const NCjson* array, NCjson** clonep); static int NCJcloneDict(const NCjson* dict, NCjson** clonep); static int NCJunparseR(const NCjson* json, NCJbuf* buf, unsigned flags); static int bytesappendquoted(NCJbuf* buf, const char* s); static int bytesappend(NCJbuf* buf, const char* s); static int bytesappendc(NCJbuf* bufp, const char c); -#endif + +/* Hide these for plugins */ +#ifdef NETCDF_JSON_H +#define OPTSTATIC static +static int NCJparsen(size_t len, const char* text, unsigned flags, NCjson** jsonp); +static int NCJnew(int sort, NCjson** objectp); +static int NCJnewstring(int sort, const char* value, NCjson** jsonp); +static int NCJnewstringn(int sort, size_t len, const char* value, NCjson** jsonp); +static int NCJclone(const NCjson* json, NCjson** clonep); +static int NCJaddstring(NCjson* json, int sort, const char* s); +static int NCJinsert(NCjson* object, char* key, NCjson* jvalue); +static int NCJappend(NCjson* object, NCjson* value); +static int NCJunparse(const NCjson* json, unsigned flags, char** textp); +#else /*!NETCDF_JSON_H*/ +#define OPTSTATIC +#endif /*NETCDF_JSON_H*/ /**************************************************/ -int +OPTSTATIC int NCJparse(const char* text, unsigned flags, NCjson** jsonp) +{ + return NCJparsen(strlen(text),text,flags,jsonp); +} + +OPTSTATIC int +NCJparsen(size_t len, const char* text, unsigned flags, NCjson** jsonp) { int stat = NCJ_OK; - size_t len; NCJparser* parser = NULL; NCjson* json = NULL; /* Need at least 1 character of input */ - if(text == NULL || text[0] == '\0') + if(len == 0 || text == NULL) {stat = NCJTHROW(NCJ_ERR); goto done;} if(jsonp == NULL) goto done; parser = calloc(1,sizeof(NCJparser)); if(parser == NULL) {stat = NCJTHROW(NCJ_ERR); goto done;} - len = strlen(text); parser->text = (char*)malloc(len+1+1); if(parser->text == NULL) {stat = NCJTHROW(NCJ_ERR); goto done;} - strcpy(parser->text,text); + memcpy(parser->text,text,len); parser->text[len] = '\0'; parser->text[len+1] = '\0'; parser->pos = &parser->text[0]; @@ -457,16 +484,21 @@ NCJlex(NCJparser* parser) c = *parser->pos; if(c == '\0') { token = NCJ_EOF; - } else if(c <= ' ' || c == '\177') { + } else if(c <= ' ' || c == '\177') {/* ignore whitespace */ parser->pos++; - continue; /* ignore whitespace */ + continue; + } else if(c == NCJ_ESCAPE) { + parser->pos++; + c = *parser->pos; + *parser->pos = unescape1(c); + continue; } else if(strchr(JSON_WORD, c) != NULL) { start = parser->pos; for(;;) { c = *parser->pos++; if(c == '\0' || strchr(JSON_WORD,c) == NULL) break; /* end of word */ } - /* Pushback c if not whitespace */ + /* Pushback c */ parser->pos--; count = ((parser->pos) - start); if(NCJyytext(parser,start,count)) goto done; @@ -579,7 +611,7 @@ NCJyytext(NCJparser* parser, char* start, size_t pdlen) /**************************************************/ -void +OPTSTATIC void NCJreclaim(NCjson* json) { if(json == NULL) return; @@ -621,7 +653,7 @@ NCJreclaimDict(struct NCjlist* dict) /**************************************************/ /* Build Functions */ -int +OPTSTATIC int NCJnew(int sort, NCjson** objectp) { int stat = NCJ_OK; @@ -651,13 +683,13 @@ NCJnew(int sort, NCjson** objectp) return NCJTHROW(stat); } -int +OPTSTATIC int NCJnewstring(int sort, const char* value, NCjson** jsonp) { return NCJTHROW(NCJnewstringn(sort,strlen(value),value,jsonp)); } -int +OPTSTATIC int NCJnewstringn(int sort, size_t len, const char* value, NCjson** jsonp) { int stat = NCJ_OK; @@ -679,7 +711,7 @@ NCJnewstringn(int sort, size_t len, const char* value, NCjson** jsonp) return NCJTHROW(stat); } -int +OPTSTATIC int NCJdictget(const NCjson* dict, const char* key, NCjson** valuep) { int i,stat = NCJ_OK; @@ -727,6 +759,21 @@ NCJunescape(NCJparser* parser) return NCJTHROW(NCJ_OK); } +/* Unescape a single character */ +static int +unescape1(int c) +{ + switch (c) { + case 'b': c = '\b'; break; + case 'f': c = '\f'; break; + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + default: c = c; break;/* technically not Json conformant */ + } + return c; +} + #ifdef NCJDEBUG static char* tokenname(int token) @@ -755,7 +802,7 @@ tokenname(int token) #endif /* Convert a JSON value to an equivalent value of a specified sort */ -int +OPTSTATIC int NCJcvt(const NCjson* jvalue, int outsort, struct NCJconst* output) { int stat = NCJ_OK; @@ -864,9 +911,7 @@ listappend(struct NCjlist* list, NCjson* json) /**************************************************/ -#ifndef NETCDF_JSON_H - -int +OPTSTATIC int NCJclone(const NCjson* json, NCjson** clonep) { int stat = NCJ_OK; @@ -934,7 +979,7 @@ NCJcloneDict(const NCjson* dict, NCjson** clonep) return NCJTHROW(stat); } -int +OPTSTATIC int NCJaddstring(NCjson* json, int sort, const char* s) { int stat = NCJ_OK; @@ -952,7 +997,7 @@ NCJaddstring(NCjson* json, int sort, const char* s) } /* Insert key-value pair into a dict object. key will be strdup'd */ -int +OPTSTATIC int NCJinsert(NCjson* object, char* key, NCjson* jvalue) { int stat = NCJ_OK; @@ -967,7 +1012,7 @@ NCJinsert(NCjson* object, char* key, NCjson* jvalue) } /* Append value to an array or dict object. */ -int +OPTSTATIC int NCJappend(NCjson* object, NCjson* value) { if(object == NULL || value == NULL) @@ -986,7 +1031,7 @@ NCJappend(NCjson* object, NCjson* value) /**************************************************/ /* Unparser to convert NCjson object to text in buffer */ -int +OPTSTATIC int NCJunparse(const NCjson* json, unsigned flags, char** textp) { int stat = NCJ_OK; @@ -1019,7 +1064,7 @@ NCJunparseR(const NCjson* json, NCJbuf* buf, unsigned flags) if(json->list.len > 0 && json->list.contents != NULL) { int shortlist = 0; for(i=0;!shortlist && i < json->list.len;i+=2) { - if(i > 0) bytesappendc(buf,NCJ_COMMA); + if(i > 0) {bytesappendc(buf,NCJ_COMMA);bytesappendc(buf,' ');}; NCJunparseR(json->list.contents[i],buf,flags); /* key */ bytesappendc(buf,NCJ_COLON); bytesappendc(buf,' '); @@ -1068,7 +1113,7 @@ escape(const char* text, NCJbuf* buf) case '\n': replace = 'n'; break; case '\r': replace = 'r'; break; case '\t': replace = 't'; break; - case NCJ_QUOTE: replace = '\''; break; + case NCJ_QUOTE: replace = '\"'; break; case NCJ_ESCAPE: replace = '\\'; break; default: break; } @@ -1090,17 +1135,6 @@ bytesappendquoted(NCJbuf* buf, const char* s) return NCJTHROW(NCJ_OK); } -void -NCJdump(const NCjson* json, unsigned flags, FILE* out) -{ - char* text = NULL; - (void)NCJunparse(json,0,&text); - if(out == NULL) out = stderr; - fprintf(out,"%s\n",text); - fflush(out); - nullfree(text); -} - static int bytesappend(NCJbuf* buf, const char* s) { @@ -1140,4 +1174,28 @@ bytesappendc(NCJbuf* bufp, const char c) s[1] = '\0'; return bytesappend(bufp,s); } -#endif /*!NETCDF_JSON_H*/ + +OPTSTATIC void +NCJdump(const NCjson* json, unsigned flags, FILE* out) +{ + char* text = NULL; + (void)NCJunparse(json,0,&text); + if(out == NULL) out = stderr; + fprintf(out,"%s\n",text); + fflush(out); + nullfree(text); +} + +/* Hack to avoid static unused warning */ +void +netcdf_supresswarnings(void) +{ + void* ignore; + ignore = (void*)NCJdump; + ignore = (void*)NCJinsert; + ignore = (void*)NCJaddstring; + ignore = (void*)NCJcvt; + ignore = (void*)NCJdictget; + ignore = (void*)NCJparse; + ignore = ignore; +} diff --git a/libdispatch/dhttp.c b/libdispatch/dhttp.c index 729885163c..071252e47f 100644 --- a/libdispatch/dhttp.c +++ b/libdispatch/dhttp.c @@ -492,7 +492,9 @@ setupconn(NC_HTTP_STATE* state, const char* objecturl) ncuriparse(objecturl,&uri); if(uri == NULL) goto fail; hostport = NC_combinehostport(uri); + ncurifree(uri); uri = NULL; value = NC_rclookup("HTTP.SSL.CAINFO",hostport,NULL); + nullfree(hostport); hostport = NULL; if(value == NULL) value = NC_rclookup("HTTP.SSL.CAINFO",NULL,NULL); if(value != NULL) { diff --git a/libdispatch/drc.c b/libdispatch/drc.c index 7798052ef7..160dff23de 100644 --- a/libdispatch/drc.c +++ b/libdispatch/drc.c @@ -189,6 +189,7 @@ NC_rcclear(NCRCinfo* info) nullfree(info->rchome); rcfreeentries(info->entries); freeprofilelist(info->s3profiles); + } static void @@ -1143,6 +1144,8 @@ aws_load_credentials(NCglobalstate* gstate) nclistpush(profiles,noprof); noprof = NULL; } + if(gstate->rcinfo->s3profiles) + freeprofilelist(gstate->rcinfo->s3profiles); gstate->rcinfo->s3profiles = profiles; profiles = NULL; #ifdef AWSDEBUG diff --git a/libdispatch/ncjson.c b/libdispatch/ncjson.c index c0f85dd3f4..b716fbdec0 100644 --- a/libdispatch/ncjson.c +++ b/libdispatch/ncjson.c @@ -6,7 +6,14 @@ TODO: make utf8 safe */ -#define NCJSON_INTERNAL +/* +WARNING: +If you modify this file, +then you need to got to +the include/ directory +and do the command: + make makenetcdfjson +*/ #include #include @@ -97,24 +104,38 @@ static int NCJunescape(NCJparser* parser); static int unescape1(int c); static int listappend(struct NCjlist* list, NCjson* element); -#ifndef NETCDF_JSON_H static int NCJcloneArray(const NCjson* array, NCjson** clonep); static int NCJcloneDict(const NCjson* dict, NCjson** clonep); static int NCJunparseR(const NCjson* json, NCJbuf* buf, unsigned flags); static int bytesappendquoted(NCJbuf* buf, const char* s); static int bytesappend(NCJbuf* buf, const char* s); static int bytesappendc(NCJbuf* bufp, const char c); -#endif + +/* Hide these for plugins */ +#ifdef NETCDF_JSON_H +#define OPTSTATIC static +static int NCJparsen(size_t len, const char* text, unsigned flags, NCjson** jsonp); +static int NCJnew(int sort, NCjson** objectp); +static int NCJnewstring(int sort, const char* value, NCjson** jsonp); +static int NCJnewstringn(int sort, size_t len, const char* value, NCjson** jsonp); +static int NCJclone(const NCjson* json, NCjson** clonep); +static int NCJaddstring(NCjson* json, int sort, const char* s); +static int NCJinsert(NCjson* object, char* key, NCjson* jvalue); +static int NCJappend(NCjson* object, NCjson* value); +static int NCJunparse(const NCjson* json, unsigned flags, char** textp); +#else /*!NETCDF_JSON_H*/ +#define OPTSTATIC +#endif /*NETCDF_JSON_H*/ /**************************************************/ -int +OPTSTATIC int NCJparse(const char* text, unsigned flags, NCjson** jsonp) { return NCJparsen(strlen(text),text,flags,jsonp); } -int +OPTSTATIC int NCJparsen(size_t len, const char* text, unsigned flags, NCjson** jsonp) { int stat = NCJ_OK; @@ -466,7 +487,7 @@ NCJyytext(NCJparser* parser, char* start, size_t pdlen) /**************************************************/ -void +OPTSTATIC void NCJreclaim(NCjson* json) { if(json == NULL) return; @@ -508,7 +529,7 @@ NCJreclaimDict(struct NCjlist* dict) /**************************************************/ /* Build Functions */ -int +OPTSTATIC int NCJnew(int sort, NCjson** objectp) { int stat = NCJ_OK; @@ -538,13 +559,13 @@ NCJnew(int sort, NCjson** objectp) return NCJTHROW(stat); } -int +OPTSTATIC int NCJnewstring(int sort, const char* value, NCjson** jsonp) { return NCJTHROW(NCJnewstringn(sort,strlen(value),value,jsonp)); } -int +OPTSTATIC int NCJnewstringn(int sort, size_t len, const char* value, NCjson** jsonp) { int stat = NCJ_OK; @@ -566,7 +587,7 @@ NCJnewstringn(int sort, size_t len, const char* value, NCjson** jsonp) return NCJTHROW(stat); } -int +OPTSTATIC int NCJdictget(const NCjson* dict, const char* key, NCjson** valuep) { int i,stat = NCJ_OK; @@ -657,7 +678,7 @@ tokenname(int token) #endif /* Convert a JSON value to an equivalent value of a specified sort */ -int +OPTSTATIC int NCJcvt(const NCjson* jvalue, int outsort, struct NCJconst* output) { int stat = NCJ_OK; @@ -766,9 +787,7 @@ listappend(struct NCjlist* list, NCjson* json) /**************************************************/ -#ifndef NETCDF_JSON_H - -int +OPTSTATIC int NCJclone(const NCjson* json, NCjson** clonep) { int stat = NCJ_OK; @@ -836,7 +855,7 @@ NCJcloneDict(const NCjson* dict, NCjson** clonep) return NCJTHROW(stat); } -int +OPTSTATIC int NCJaddstring(NCjson* json, int sort, const char* s) { int stat = NCJ_OK; @@ -854,7 +873,7 @@ NCJaddstring(NCjson* json, int sort, const char* s) } /* Insert key-value pair into a dict object. key will be strdup'd */ -int +OPTSTATIC int NCJinsert(NCjson* object, char* key, NCjson* jvalue) { int stat = NCJ_OK; @@ -869,7 +888,7 @@ NCJinsert(NCjson* object, char* key, NCjson* jvalue) } /* Append value to an array or dict object. */ -int +OPTSTATIC int NCJappend(NCjson* object, NCjson* value) { if(object == NULL || value == NULL) @@ -888,7 +907,7 @@ NCJappend(NCjson* object, NCjson* value) /**************************************************/ /* Unparser to convert NCjson object to text in buffer */ -int +OPTSTATIC int NCJunparse(const NCjson* json, unsigned flags, char** textp) { int stat = NCJ_OK; @@ -992,17 +1011,6 @@ bytesappendquoted(NCJbuf* buf, const char* s) return NCJTHROW(NCJ_OK); } -void -NCJdump(const NCjson* json, unsigned flags, FILE* out) -{ - char* text = NULL; - (void)NCJunparse(json,0,&text); - if(out == NULL) out = stderr; - fprintf(out,"%s\n",text); - fflush(out); - nullfree(text); -} - static int bytesappend(NCJbuf* buf, const char* s) { @@ -1042,4 +1050,29 @@ bytesappendc(NCJbuf* bufp, const char c) s[1] = '\0'; return bytesappend(bufp,s); } -#endif /*!NETCDF_JSON_H*/ + +OPTSTATIC void +NCJdump(const NCjson* json, unsigned flags, FILE* out) +{ + char* text = NULL; + (void)NCJunparse(json,0,&text); + if(out == NULL) out = stderr; + fprintf(out,"%s\n",text); + fflush(out); + nullfree(text); +} + +/* Hack to avoid static unused warning */ +static void +netcdf_supresswarnings(void) +{ + void* ignore; + ignore = (void*)netcdf_supresswarnings; + ignore = (void*)NCJdump; + ignore = (void*)NCJinsert; + ignore = (void*)NCJaddstring; + ignore = (void*)NCJcvt; + ignore = (void*)NCJdictget; + ignore = (void*)NCJparse; + ignore = ignore; +} diff --git a/nc_test4/tst_vars3.c b/nc_test4/tst_vars3.c index 1758789662..9c4af0751d 100644 --- a/nc_test4/tst_vars3.c +++ b/nc_test4/tst_vars3.c @@ -418,7 +418,7 @@ main(int argc, char **argv) if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; -#ifdef HAVE_SZ +#ifdef HAVE_H5Z_SZIP printf("**** testing simple szip filter setup..."); { int ncid; @@ -748,9 +748,9 @@ main(int argc, char **argv) params[1] = NC_SZIP_EC_BPP_IN; /* pixels_per_block */ if (nc_def_var_chunking(ncid, varid, NC_CHUNKED, NULL)) ERR; { int stat; - if ((stat = nc_def_var_filter(ncid, varid, H5_FILTER_SZIP, NUM_PARAMS_IN, - params)) != NC_ENOFILTER) - ERR; + stat = nc_def_var_filter(ncid, varid, H5_FILTER_SZIP, NUM_PARAMS_IN, params); + if(stat != NC_ENOFILTER) + ERR; } if (nc_def_var_szip(ncid, varid, NC_SZIP_NN, NC_SZIP_EC_BPP_IN) != NC_ENOFILTER) ERR; diff --git a/ncdump/tst_vlen_data.c b/ncdump/tst_vlen_data.c index 9b1850e8f7..ad5d18388e 100644 --- a/ncdump/tst_vlen_data.c +++ b/ncdump/tst_vlen_data.c @@ -28,6 +28,10 @@ The leak may be in HDF5. #define ATT5_LEN 1 #define NROWS 5 +/* Use reclaim_data */ +#undef RECLAIM + + int main(int argc, char **argv) { @@ -64,7 +68,7 @@ main(int argc, char **argv) if (nc_def_var(ncid, VAR5_NAME, typeid, VAR5_RANK, var_dims, &varid)) ERR; /* Create and write a variable attribute of the vlen type */ -#if 0 +#ifdef RECLAIM /* In order to use ncaux_reclaim_data, all the interior nodes must have been alloc'd */ missing_val.p = (float*)malloc(sizeof(missing_value)); memcpy((void*)missing_val.p,&missing_value,sizeof(missing_value)); @@ -74,7 +78,7 @@ main(int argc, char **argv) missing_val.len = 1; if (nc_put_att(ncid, varid, ATT5_NAME, typeid, ATT5_LEN, (void *) &missing_val)) ERR; if (nc_enddef(ncid)) ERR; -#if 0 +#ifdef RECLAIM /* reclaim */ if(ncaux_reclaim_data(ncid,typeid,&missing_val,1)) ERR; #endif diff --git a/ncgen3/run_tests.sh b/ncgen3/run_tests.sh index fcba7489e5..8e300092cf 100755 --- a/ncgen3/run_tests.sh +++ b/ncgen3/run_tests.sh @@ -3,6 +3,7 @@ # $Id: run_tests.sh,v 1.9 2009/09/24 18:19:11 dmh Exp $ echo "*** Testing ncgen3." + set -e if test "x$srcdir" = x ;then srcdir=`pwd`; fi From f50007e21d636198fbb78519d06715473da5708b Mon Sep 17 00:00:00 2001 From: Dennis Heimbigner Date: Tue, 5 Jul 2022 22:06:28 -0600 Subject: [PATCH 2/3] Update RELEASENOTES.md --- RELEASE_NOTES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index d03ca6b376..361c1ee932 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -7,7 +7,7 @@ This file contains a high-level description of this package's evolution. Release ## 4.9.1 - T.B.D. -* [Bug Fi] Fix the json submodule symbol conflicts between libnetcdf and the plugin specific netcdf_json.h. See [Github #????](https://github.com/Unidata/netcdf-c/pull/????). +* [Bug Fi] Fix the json submodule symbol conflicts between libnetcdf and the plugin specific netcdf_json.h. See [Github #2448](https://github.com/Unidata/netcdf-c/pull/2448). * [Enhancement] Add `--disable-quantize` option to `configure`. * [Enhancement] Provide a simple API to allow user access to the internal .rc file table: supports get/set/overwrite of entries of the form "key=value". See [Github #2408](https://github.com/Unidata/netcdf-c/pull/2408). * [Bug Fix] Use env variable USERPROFILE instead of HOME for windows and mingw. See [Github #2405](https://github.com/Unidata/netcdf-c/pull/2405). From 31b24d767a5736a9b974d653ec40b887c490cf93 Mon Sep 17 00:00:00 2001 From: Dennis Heimbigner Date: Wed, 6 Jul 2022 15:01:23 -0600 Subject: [PATCH 3/3] Fix bad cmake install location --- include/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 2e507c028a..224bd2bb38 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -41,7 +41,7 @@ IF(ENABLE_PNETCDF OR ENABLE_PARALLEL4) COMPONENT headers) ENDIF() -INSTALL(FILES ${netCDF_BINARY_DIR}/include/netcdf_json.h +INSTALL(FILES ${netCDF_SOURCE_DIR}/include/netcdf_json.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT headers)