Skip to content

Commit 0060b16

Browse files
Step 1 in splitting PR 3068
re: PR Unidata#3068 1. Update the ncjson and ncproplist code to lastest. 2. Fix some references to older API functions. 3. Update the netcdf_json and netcdf_proplist builds.
1 parent 82dd707 commit 0060b16

15 files changed

+633
-302
lines changed

RELEASE_NOTES.md

+6
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,14 @@ Release Notes {#RELEASE_NOTES}
55

66
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.
77

8+
## 4.9.4 - TBD
9+
10+
* Step 1 in splittig PR [Github #3068](https://github.com/Unidata/netcdf-c/pull/3068). Update ncjson.[ch] and ncproplist.[ch]. Also fix references to old API. Also fix include/netcdf_ncjson.h and include/netcdf_proplist.h builds.
11+
See [Github #????](https://github.com/Unidata/netcdf-c/pull/????) for more information.
12+
813
## 4.9.3 - TBD
914

15+
* Step in converting PR 3068 to a sequence of much smaller PRs. This one updates the ncjson and ncproplist code to the latest versions. See [Github #????](https://github.com/Unidata/netcdf-c/pull/????) for more information.
1016
* Extend the netcdf API to support programmatic changes to the plugin search path. See [Github #3034](https://github.com/Unidata/netcdf-c/pull/3034) for more information.
1117

1218
## Known Issue

include/Makefile.am

+12-7
Original file line numberDiff line numberDiff line change
@@ -48,21 +48,26 @@ BUILT_SOURCES = netcdf_json.h netcdf_proplist.h
4848
# marked with a macro (OPTSTATIC) that marks the entry point as
4949
# static inside netcdf_json.h. This is an ugly hack to avoid
5050
# having to reference libnetcdf in the nczarr code wrappers.
51-
# Note also that we incorporate the core of ncexternl.h into the netcdf_json.h file.
51+
# Note that the file is built in builddir in case the build
52+
# is out of source.
5253

5354
# Give the recipe for building netcdf_json.h
5455
netcdf_json.h: ${top_srcdir}/libdispatch/ncjson.c ${top_srcdir}/include/ncjson.h ${top_srcdir}/include/ncexternl.h
5556
rm -fr ${builddir}/netcdf_json.h
56-
cat ${srcdir}/ncjson.h | sed -e 's/NCJSON_H/NETCDF_JSON_H/' >> ${builddir}/netcdf_json.h
57-
echo '#ifdef NETCDF_JSON_H' >> ${builddir}/netcdf_json.h
58-
sed -e '/ncjson.h/d' < ${srcdir}/../libdispatch/ncjson.c >> ${builddir}/netcdf_json.h
57+
cat ${srcdir}/ncjson.h \
58+
| sed -e '/!NCJSON_H/d' \
59+
| sed -e 's/NCJSON_H/NETCDF_JSON_H/' \
60+
>> ${builddir}/netcdf_json.h
61+
cat ${srcdir}/../libdispatch/ncjson.c | sed -e '/ncjson.h/d' >> ${builddir}/netcdf_json.h
5962
echo '#endif /*NETCDF_JSON_H*/' >> ${builddir}/netcdf_json.h
6063

6164
# netcdf_proplist is analogous to netcdf_json but, of course, using libdispatch/ncproplist.c and include/ncproplist.h
6265
# Give the recipe for building netcdf_proplist.h. Basically same as for netcdf_json.h
6366
netcdf_proplist.h: ${top_srcdir}/libdispatch/ncproplist.c ${top_srcdir}/include/ncproplist.h ${top_srcdir}/include/ncexternl.h
6467
rm -fr ${builddir}/netcdf_proplist.h
65-
cat ${srcdir}/ncproplist.h | sed -e 's/NCPROPLIST_H/NETCDF_PROPLIST_H/' >> ${builddir}/netcdf_proplist.h
66-
echo '#ifdef NETCDF_PROPLIST_H' >> ${builddir}/netcdf_proplist.h
67-
sed -e '/ncproplist.h/d' < ${srcdir}/../libdispatch/ncproplist.c >> ${builddir}/netcdf_proplist.h
68+
cat ${srcdir}/ncproplist.h \
69+
| sed -e '/!NCPROPLIST_H/d' \
70+
| sed -e 's/NCPROPLIST_H/NETCDF_PROPLIST_H/' \
71+
>> ${builddir}/netcdf_proplist.h
72+
cat ${srcdir}/../libdispatch/ncproplist.c | sed -e '/ncproplist.h/d' >> ${builddir}/netcdf_proplist.h
6873
echo '#endif /*NETCDF_PROPLIST_H*/' >> ${builddir}/netcdf_proplist.h

include/ncconfigure.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ unsigned long long int strtoull(const char*, char**, int);
134134
#endif /*_WIN32*/
135135

136136
#ifndef nulldup
137-
#define nulldup(s) ((s)==NULL?NULL:strdup(s))
137+
#define nulldup(s) ((s)==NULL?s:strdup(s))
138138
#endif
139139

140140
#ifndef nulllen

include/ncjson.h

+67-27
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,26 @@
33
*/
44

55
#ifndef NCJSON_H
6-
#define NCJSON_H
6+
#define NCJSON_H 1
77

88
#ifndef OPTEXPORT
99
#ifdef NETCDF_JSON_H
1010
#define OPTEXPORT static
1111
#else /*!NETCDF_JSON_H*/
1212
#ifdef _WIN32
1313
#define OPTEXPORT __declspec(dllexport)
14-
#else
14+
#else /*!WIN32*/
1515
#define OPTEXPORT extern
16-
#endif
16+
#endif /*WIN32*/
1717
#endif /*NETCDF_JSON_H*/
1818
#endif /*OPTEXPORT*/
1919

2020
/**************************************************/
21+
22+
/* Return codes */
23+
#define NCJ_OK 0 /* must equal NC_NOERR in netcdf.h */
24+
#define NCJ_ERR (-1) /* must equal NC_ERROR in netcdf.h */
25+
2126
/* Json object sorts (note use of term sort rather than e.g. type or discriminant) */
2227
#define NCJ_UNDEF 0
2328
#define NCJ_STRING 1
@@ -30,6 +35,10 @@
3035

3136
#define NCJ_NSORTS 8
3237

38+
/* Dump/text/unparse flags */
39+
#define NCJFLAG_NONE 0
40+
#define NCJFLAG_INDENTED 1
41+
3342
/* Define a struct to store primitive values as unquoted
3443
strings. The sort will provide more info. Do not bother with
3544
a union since the amount of saved space is minimal.
@@ -39,25 +48,25 @@ typedef struct NCjson {
3948
int sort; /* of this object */
4049
char* string; /* sort != DICT|ARRAY */
4150
struct NCjlist {
42-
size_t len;
43-
struct NCjson** contents;
51+
size_t alloc;
52+
size_t len;
53+
struct NCjson** contents;
4454
} list; /* sort == DICT|ARRAY */
4555
} NCjson;
4656

4757
/* Structure to hold result of convertinf one json sort to value of another type;
4858
don't use union so we can know when to reclaim sval
4959
*/
5060
struct NCJconst {int bval; long long ival; double dval; char* sval;};
51-
#define NCJconst_empty {0,0,0.0,NULL}
5261

5362
/**************************************************/
5463
/* Extended API */
5564

56-
/* Return 0 if ok else -1 */
65+
/* Return NCJ_OK if ok else NCJ_ERR */
5766

5867
#if defined(__cplusplus)
5968
extern "C" {
60-
#endif
69+
#endif /*__cplusplus*/
6170

6271
/* Parse a string to NCjson*/
6372
OPTEXPORT int NCJparse(const char* text, unsigned flags, NCjson** jsonp);
@@ -80,24 +89,35 @@ OPTEXPORT int NCJnewstringn(int sort, size_t len, const char* value, NCjson** js
8089
/* Get dict key value by name */
8190
OPTEXPORT int NCJdictget(const NCjson* dict, const char* key, const NCjson** valuep);
8291

92+
/* Functional version of NCJdictget */
93+
OPTEXPORT NCjson* NCJdictlookup(const NCjson* dict, const char* key);
94+
8395
/* Convert one json sort to value of another type; don't use union so we can know when to reclaim sval */
8496
OPTEXPORT int NCJcvt(const NCjson* value, int outsort, struct NCJconst* output);
8597

86-
/* Insert an atomic value to an array or dict object. */
98+
/* Append an atomic value to an array or dict object. */
8799
OPTEXPORT int NCJaddstring(NCjson* json, int sort, const char* s);
88100

89101
/* Append value to an array or dict object. */
90102
OPTEXPORT int NCJappend(NCjson* object, NCjson* value);
91103

92-
/* Insert key-value pair into a dict object. key will be copied */
93-
OPTEXPORT int NCJinsert(NCjson* object, const char* key, NCjson* value);
104+
/* Append string value to an array or dict object. */
105+
OPTEXPORT int NCJappendstring(NCjson* object, int sort, const char* s);
94106

95-
/* Insert key-value pair as strings into a dict object.
96-
key and value will be copied */
107+
/* Append int value to an array or dict object. */
108+
OPTEXPORT int NCJappendint(NCjson* object, long long n);
109+
110+
/* Insert (string)key-(NCjson*)value pair into a dict object. key will be copied; jvalue will not */
111+
OPTEXPORT int NCJinsert(NCjson* object, const char* key, NCjson* jvalue);
112+
113+
/* Insert key-value pair into a dict object. key and value will be copied */
97114
OPTEXPORT int NCJinsertstring(NCjson* object, const char* key, const char* value);
98115

99-
/* Insert key-value pair where value is an int */
100-
OPTEXPORT int NCJinsertint(NCjson* object, const char* key, long long ivalue);
116+
/* Overwrite key-value pair in a dict object. Act like NCJinsert if key not found */
117+
OPTEXPORT int NCJoverwrite(NCjson* object, const char* key, NCjson* value);
118+
119+
/* Insert key-value pair into a dict object. key and value will be copied */
120+
OPTEXPORT int NCJinsertint(NCjson* object, const char* key, long long n);
101121

102122
/* Unparser to convert NCjson object to text in buffer */
103123
OPTEXPORT int NCJunparse(const NCjson* json, unsigned flags, char** textp);
@@ -106,37 +126,57 @@ OPTEXPORT int NCJunparse(const NCjson* json, unsigned flags, char** textp);
106126
OPTEXPORT int NCJclone(const NCjson* json, NCjson** clonep);
107127

108128
#ifndef NETCDF_JSON_H
129+
109130
/* dump NCjson* object to output file */
110131
OPTEXPORT void NCJdump(const NCjson* json, unsigned flags, FILE*);
132+
111133
/* convert NCjson* object to output string */
112-
OPTEXPORT const char* NCJtotext(const NCjson* json);
134+
OPTEXPORT const char* NCJtotext(const NCjson* json, unsigned flags);
135+
136+
/* Sort a dictionary by key */
137+
OPTEXPORT void NCJdictsort(NCjson* jdict);
138+
113139
#endif /*NETCDF_JSON_H*/
114140

115141
#if defined(__cplusplus)
116142
}
117-
#endif
143+
#endif /*__cplusplus*/
118144

119145
/* Getters */
120-
#define NCJsort(x) ((x)->sort)
121-
#define NCJstring(x) ((x)->string)
122-
#define NCJlength(x) ((x)==NULL ? 0 : (x)->list.len)
123-
#define NCJdictlength(x) ((x)==NULL ? 0 : (x)->list.len/2)
124-
#define NCJcontents(x) ((x)->list.contents)
146+
#define NCJsort(x) ((x)==NULL?NCJ_UNDEF:(x)->sort)
147+
#define NCJstring(x) ((x)==NULL?NULL:(x)->string)
148+
#define NCJarraylength(x) ((x)==NULL ? 0 : (x)->list.len)
149+
#define NCJdictlength(x) ((x)==NULL ? 0 : ((x)->list.len) / 2)
150+
#define NCJcontents(x) ((x)==NULL?NULL:(x)->list.contents)
125151
#define NCJith(x,i) ((x)->list.contents[i])
126-
#define NCJdictith(x,i) ((x)->list.contents[2*i])
152+
#define NCJdictkey(x,i) ((x)->list.contents[(i)*2])
153+
#define NCJdictvalue(x,i) ((x)->list.contents[((i)*2)+1])
127154

128155
/* Setters */
129156
#define NCJsetsort(x,s) (x)->sort=(s)
130157
#define NCJsetstring(x,y) (x)->string=(y)
131158
#define NCJsetcontents(x,c) (x)->list.contents=(c)
132-
#define NCJsetlength(x,l) (x)->list.len=(l)
159+
#define NCJsetarraylength(x,l) (x)->list.len=(l)
160+
#define NCJsetdictlength(x,l) (x)->list.len=((l)*2)
133161

134162
/* Misc */
135163
#define NCJisatomic(j) ((j)->sort != NCJ_ARRAY && (j)->sort != NCJ_DICT && (j)->sort != NCJ_NULL && (j)->sort != NCJ_UNDEF)
136164

137165
/**************************************************/
166+
/* Error detection helper */
167+
#undef NCJDEBUG
168+
#ifdef NCJDEBUG
169+
static int
170+
NCJBREAKPOINT(int err)
171+
{
172+
(void)NCJBREAKPOINT;
173+
return err;
174+
}
175+
#else
176+
#define NCJBREAKPOINT(err) (err)
177+
#endif /*NCJDEBUG*/
178+
#define NCJcheck(expr) do{if((expr) < 0) {stat = NCJBREAKPOINT(NCJ_ERR); goto done;}}while(0)
138179

139-
#endif /*NCJSON_H*/
140-
141-
180+
/**************************************************/
142181

182+
#endif /*!NCJSON_H*/ /* Leave the ! as a tag for sed */

include/ncproplist.h

+51-25
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,16 @@
2222
/**************************************************/
2323
/*
2424
This is used to store a property list mapping a small number of
25-
fixed-sized key strings to an arbitrary uintptr_t value. The
26-
uintptr_t type is used to ensure that the value can be a pointer or a
27-
small string upto sizeof(uintptr_t) - 1 (for trailing nul). The big
28-
problem is reclaiming the value if it a pointer. The fact that the
29-
number of keys is small makes it feasible to use linear search.
30-
This is currently only used for plugins, but may be extended to other uses.
25+
keys to objects. The uintptr_t type is used to ensure that the value can be a pointer or a
26+
small string upto sizeof(uintptr_t) - 1 (for trailing nul) or an integer constant.
27+
28+
There are two operations that may be defined for the property:
29+
1. reclaiming the value when proplist is free'd and property value points to allocated data of arbitrary complexity.
30+
2. coping the value (for cloning) if it points to allocated data of arbitrary complexity.
31+
32+
The fact that the number of keys is small makes it feasible to use
33+
linear search. This is currently only used for plugins, but may be
34+
extended to other uses.
3135
*/
3236

3337
/*! Proplist-related structs.
@@ -38,31 +42,48 @@ This is currently only used for plugins, but may be extended to other uses.
3842
1. It is critical that |uintptr_t| == |void*|
3943
*/
4044

41-
#define NCPROPSMAXKEY 31 /* characters assert (NCPROPSMAXKEY+1)/8 == 0*/
45+
#define NCPROPSMAXKEY 31 /* characters; assert (NCPROPSMAXKEY+1)/8 == 0*/
4246

43-
/* Returns 0 => error; 1 => success */
44-
typedef int (*NCPreclaimfcn)(uintptr_t userdata, const char* key, void* value, uintptr_t size);
47+
/* Opaque forward */
48+
struct NCPpair;
4549

46-
/* The property list proper is a sequence of these objects */
47-
typedef struct NCProperty {
50+
/* This function performs all of the following operations on a complex type */
51+
typedef enum NCPtypeop {NCP_RECLAIM=1,NCP_COPY=2} NCPtypeop;
52+
53+
/* There are three possible types for a property value */
54+
typedef enum NCPtype {
55+
NCP_CONST=0, /* Value is a simple uintptr_t constant */
56+
NCP_BYTES=2, /* Value points to a counted sequence of bytes; If a string,
57+
then it includes the nul term character */
58+
NCP_COMPLEX=3 /* Value points to an arbitraryily complex structure */
59+
} NCPtype;
60+
61+
/* (Returns < 0 => error) (>= 0 => success) */
62+
typedef int (*NCPtypefcn)(NCPtypeop op, struct NCPpair* input, struct NCPpair* output);
63+
64+
/* Expose this prefix of NCProperty; used in clone and lookup */
65+
/* Hold just the key+value pair */
66+
typedef struct NCPpair {
4867
char key[NCPROPSMAXKEY+1]; /* copy of the key string; +1 for trailing nul */
49-
uintptr_t flags;
50-
# define NCPF_SIMPLE (1<<0) /* non-reclaimable */
51-
# define NCPF_BYTES (1<<1) /* reclaimable bytes */
52-
# define NCPF_COMPLEX (1<<2) /* extended case */
68+
NCPtype sort;
5369
uintptr_t value;
5470
uintptr_t size; /* size = |value| as ptr to memory, if string, then include trailing nul */
55-
uintptr_t userdata; /* extra data for following functions */
56-
NCPreclaimfcn reclaim;
57-
} NCProperty;
71+
} NCPpair;
72+
73+
/* The property list proper is a sequence of these objects */
74+
typedef struct NCPproperty {
75+
NCPpair pair; /* Allowed by C language standard */
76+
uintptr_t userdata; /* extra data for the type function */
77+
NCPtypefcn typefcn; /* Process type operations */
78+
} NCPproperty;
5879

5980
/*
6081
The property list object.
6182
*/
6283
typedef struct NCproplist {
6384
size_t alloc; /* allocated space to hold properties */
6485
size_t count; /* # of defined properties */
65-
NCProperty* properties;
86+
NCPproperty* properties;
6687
} NCproplist;
6788

6889
/**************************************************/
@@ -72,19 +93,24 @@ typedef struct NCproplist {
7293
extern "C" {
7394
#endif
7495

96+
/* All int valued functions return < 0 if error; >= 0 otherwise */
97+
98+
7599
/* Create, free, etc. */
76100
OPTEXPORT NCproplist* ncproplistnew(void);
77101
OPTEXPORT int ncproplistfree(NCproplist*);
78102

79-
/* Locate a proplist entry */
80-
OPTEXPORT int ncproplistadd(NCproplist* plist,const char* key, uintptr_t value); /* use when reclaim not needed */
81-
82103
/* Insert properties */
83104
OPTEXPORT int ncproplistadd(NCproplist* plist,const char* key, uintptr_t value); /* use when reclaim not needed */
84105
OPTEXPORT int ncproplistaddstring(NCproplist* plist, const char* key, const char* str); /* use when value is simple string (char*) */
85-
OPTEXPORT int ncproplistaddbytes(NCproplist* plist, const char* key, void* value, uintptr_t size); /* use when value is simple ptr and reclaim is simple free function */
86-
OPTEXPORT int ncproplistaddx(NCproplist* plist, const char* key, void* value, uintptr_t size, uintptr_t userdata, NCPreclaimfcn); /* fully extended case */
87106

107+
/* Insert an instance of type NCP_BYTES */
108+
OPTEXPORT int ncproplistaddbytes(NCproplist* plist, const char* key, void* value, uintptr_t size);
109+
110+
/* Add instance of a complex type */
111+
OPTEXPORT int ncproplistaddx(NCproplist* plist, const char* key, void* value, uintptr_t size, uintptr_t userdata, NCPtypefcn typefcn);
112+
113+
/* clone; keys are copies and values are copied using the NCPtypefcn */
88114
OPTEXPORT int ncproplistclone(const NCproplist* src, NCproplist* clone);
89115

90116
/*
@@ -105,4 +131,4 @@ OPTEXPORT int ncproplistith(const NCproplist*, size_t i, char* const * keyp, uin
105131
}
106132
#endif
107133

108-
#endif /*NCPROPLIST_H*/
134+
#endif /*!NCPROPLIST_H*/ /* WARNING: Do not remove the !; used in building netcdf_proplist.h */

0 commit comments

Comments
 (0)