Skip to content

Commit cdf507a

Browse files
authored
Merge pull request #2183 from DennisHeimbigner/modeflags.dmh
Make sure mode flags are properly defined in netcdf.h
2 parents 988e771 + b5879b1 commit cdf507a

8 files changed

Lines changed: 89 additions & 75 deletions

File tree

RELEASE_NOTES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This file contains a high-level description of this package's evolution. Release
77

88
## 4.8.2 - TBD
99

10+
* [Bug Fix] Make sure that netcdf.h accurately defines the flags in the open/create mode flags. See [Github #2183](https://github.com/Unidata/netcdf-c/pull/2183).
1011
* [Enhancement] Improve support for msys2+mingw platform. See [Github #2171](https://github.com/Unidata/netcdf-c/pull/2171).
1112
* [Bug Fix] Clean up the various inter-test dependencies in ncdump for CMake. See [Github #2168](https://github.com/Unidata/netcdf-c/pull/2168).
1213
* [Enhancement] Added options to suppress the new behavior from [Github #2135](https://github.com/Unidata/netcdf-c/pull/2135). The options for `cmake` and `configure` are, respectively `-DENABLE_LIBXML2` and `--(enable/disable)-libxml2`. Both of these options defaul to 'on/enabled'. When disabled, the bundled `ezxml` XML interpreter is used regardless of whether `libxml2` is present on the system.

include/nc3internal.h

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -224,15 +224,18 @@ NC_lookupvar(NC3_INFO* ncp, int varid, NC_var **varp);
224224
struct NC3_INFO {
225225
/* contains the previous NC during redef. */
226226
NC3_INFO *old;
227-
/* flags */
228-
#define NC_CREAT 2 /* in create phase, cleared by ncendef */
229-
#define NC_INDEF 8 /* in define mode, cleared by ncendef */
230-
#define NC_NSYNC 0x10 /* synchronise numrecs on change */
231-
#define NC_HSYNC 0x20 /* synchronise whole header on change */
232-
#define NC_NDIRTY 0x40 /* numrecs has changed */
233-
#define NC_HDIRTY 0x80 /* header info has changed */
234-
/* NC_NOFILL in netcdf.h, historical interface */
235-
int flags;
227+
int flags; /* mode flags */
228+
int state; /* state transitions flags */
229+
# define NC_CREAT 0x1 /* in create phase, cleared by ncendef */
230+
# define NC_INDEF 0x2 /* in define mode, cleared by ncendef */
231+
# define NC_NSYNC 0x4 /* synchronise numrecs on change */
232+
# define NC_HSYNC 0x8 /* synchronise whole header on change */
233+
# define NC_NDIRTY 0x10 /* numrecs has changed */
234+
# define NC_HDIRTY 0x20 /* header info has changed */
235+
/* NC_NOFILL defined in netcdf.h, historical interface */
236+
#if 0
237+
# define NC_NOFILL 0x100 /**< Argument to nc_set_fill() to turn off filling of data. */
238+
#endif
236239
struct ncio* nciop;
237240
size_t chunk; /* largest extent this layer will request from ncio->get() */
238241
size_t xsz; /* external size of this header, == var[0].begin */
@@ -258,31 +261,31 @@ struct NC3_INFO {
258261
fClr((ncp)->flags, NC_WRITE)
259262

260263
#define NC_IsNew(ncp) \
261-
fIsSet((ncp)->flags, NC_CREAT)
264+
fIsSet((ncp)->state, NC_CREAT)
262265

263266
#define NC_indef(ncp) \
264-
(NC_IsNew(ncp) || fIsSet((ncp)->flags, NC_INDEF))
267+
(NC_IsNew(ncp) || fIsSet((ncp)->state, NC_INDEF))
265268

266269
#define set_NC_ndirty(ncp) \
267-
fSet((ncp)->flags, NC_NDIRTY)
270+
fSet((ncp)->state, NC_NDIRTY)
268271

269272
#define NC_ndirty(ncp) \
270-
fIsSet((ncp)->flags, NC_NDIRTY)
273+
fIsSet((ncp)->state, NC_NDIRTY)
271274

272275
#define set_NC_hdirty(ncp) \
273-
fSet((ncp)->flags, NC_HDIRTY)
276+
fSet((ncp)->state, NC_HDIRTY)
274277

275278
#define NC_hdirty(ncp) \
276-
fIsSet((ncp)->flags, NC_HDIRTY)
279+
fIsSet((ncp)->state, NC_HDIRTY)
277280

278281
#define NC_dofill(ncp) \
279-
(!fIsSet((ncp)->flags, NC_NOFILL))
282+
(!fIsSet((ncp)->state, NC_NOFILL))
280283

281284
#define NC_doHsync(ncp) \
282-
fIsSet((ncp)->flags, NC_HSYNC)
285+
fIsSet((ncp)->state, NC_HSYNC)
283286

284287
#define NC_doNsync(ncp) \
285-
fIsSet((ncp)->flags, NC_NSYNC)
288+
fIsSet((ncp)->state, NC_NSYNC)
286289

287290
# define NC_get_numrecs(nc3i) \
288291
((nc3i)->numrecs)

include/nc4internal.h

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -276,29 +276,23 @@ typedef struct NC_GRP_INFO
276276
NCindex* vars; /**< NCindex<NC_VAR_INFO_T> * */
277277
} NC_GRP_INFO_T;
278278

279-
/* These constants apply to the cmode parameter in the
279+
/* These constants apply to the flags field in the
280280
* HDF5_FILE_INFO_T defined below. */
281-
/* Make sure they do not conflict with defined flags in netcdf.h */
282-
#define NC_CREAT 0x10002 /**< in create phase, cleared by ncendef */
283-
#define NC_INDEF 0x10008 /**< in define mode, cleared by ncendef */
284-
#define NC_NSYNC 0x10010 /**< synchronise numrecs on change */
285-
#define NC_HSYNC 0x10020 /**< synchronise whole header on change */
286-
#define NC_NDIRTY 0x10040 /**< numrecs has changed */
287-
#define NC_HDIRTY 0x10080 /**< header info has changed */
281+
#define NC_INDEF 0x01 /**< in define mode, cleared by ncendef */
288282

289283
/** This is the metadata we need to keep track of for each
290284
* netcdf-4/HDF5 file. */
291285

292-
typedef struct NC_FILE_INFO
286+
typedef struct NC_FILE_INFO
293287
{
294288
NC_OBJ hdr;
295289
NC *controller; /**< Pointer to containing NC. */
296290
#ifdef USE_PARALLEL4
297291
MPI_Comm comm; /**< Copy of MPI Communicator used to open the file. */
298292
MPI_Info info; /**< Copy of MPI Information Object used to open the file. */
299293
#endif
300-
int flags; /**< Flags used to open the file. */
301-
int cmode; /**< Create mode used to create the file. */
294+
int cmode; /**< Create/Open mode for the file. */
295+
int flags; /**< State transition flags . */
302296
nc_bool_t parallel; /**< True if file is open for parallel access */
303297
nc_bool_t redef; /**< True if redefining an existing file */
304298
nc_bool_t no_attr_create_order; /**< True if the creation order tracking of attributes is disabled (netcdf-4 only) */

include/netcdf.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,14 @@ extern "C" {
115115
#define NC_NOFILL 0x100 /**< Argument to nc_set_fill() to turn off filling of data. */
116116

117117
/* Define the ioflags bits for nc_create and nc_open.
118-
currently unused:
118+
Currently unused in lower 16 bits:
119119
0x0002
120-
and the whole upper 16 bits
121-
Note: nc4internal also defines flags in this space even tho it should not.
122-
so check there around #define NC_CREAT.
120+
All upper 16 bits are unused except
121+
0x20000
123122
*/
124123

124+
/* Lower 16 bits */
125+
125126
#define NC_NOWRITE 0x0000 /**< Set read-only access for nc_open(). */
126127
#define NC_WRITE 0x0001 /**< Set read-write access for nc_open(). */
127128

@@ -161,7 +162,8 @@ Use this in mode flags for both nc_create() and nc_open(). */
161162
#define NC_PERSIST 0x4000 /**< Save diskless contents to disk. Mode flag for nc_open() or nc_create() */
162163
#define NC_INMEMORY 0x8000 /**< Read from memory. Mode flag for nc_open() or nc_create() */
163164

164-
#define NC_NOATTCREORD 0x20000 /**< Disable the netcdf-4 (hdf5) attribute creation order tracking */
165+
/* Upper 16 bits */
166+
#define NC_NOATTCREORD 0x20000 /**< Disable the netcdf-4 (hdf5) attribute creation order tracking */
165167

166168
#define NC_MAX_MAGIC_NUMBER_LEN 8 /**< Max len of user-defined format magic number. */
167169

libsrc/nc3internal.c

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ write_numrecs(NC3_INFO *ncp)
413413
(void) ncio_rel(ncp->nciop, NC_NUMRECS_OFFSET, RGN_MODIFIED);
414414

415415
if(status == NC_NOERR)
416-
fClr(ncp->flags, NC_NDIRTY);
416+
fClr(ncp->state, NC_NDIRTY);
417417

418418
return status;
419419
}
@@ -435,7 +435,7 @@ read_NC(NC3_INFO *ncp)
435435
status = nc_get_NC(ncp);
436436

437437
if(status == NC_NOERR)
438-
fClr(ncp->flags, NC_NDIRTY | NC_HDIRTY);
438+
fClr(ncp->state, NC_NDIRTY | NC_HDIRTY);
439439

440440
return status;
441441
}
@@ -454,7 +454,7 @@ write_NC(NC3_INFO *ncp)
454454
status = ncx_put_NC(ncp, NULL, 0, 0);
455455

456456
if(status == NC_NOERR)
457-
fClr(ncp->flags, NC_NDIRTY | NC_HDIRTY);
457+
fClr(ncp->state, NC_NDIRTY | NC_HDIRTY);
458458

459459
return status;
460460
}
@@ -864,7 +864,7 @@ NC_endef(NC3_INFO *ncp,
864864
{
865865
/* a plain redef, not a create */
866866
assert(!NC_IsNew(ncp));
867-
assert(fIsSet(ncp->flags, NC_INDEF));
867+
assert(fIsSet(ncp->state, NC_INDEF));
868868
assert(ncp->begin_rec >= ncp->old->begin_rec);
869869
assert(ncp->begin_var >= ncp->old->begin_var);
870870

@@ -937,7 +937,7 @@ NC_endef(NC3_INFO *ncp,
937937
ncp->old = NULL;
938938
}
939939

940-
fClr(ncp->flags, NC_CREAT | NC_INDEF);
940+
fClr(ncp->state, NC_CREAT | NC_INDEF);
941941

942942
return ncio_sync(ncp->nciop);
943943
}
@@ -1071,7 +1071,7 @@ NC3_create(const char *path, int ioflags, size_t initialsz, int basepe,
10711071
goto unwind_alloc;
10721072
}
10731073

1074-
fSet(nc3->flags, NC_CREAT);
1074+
fSet(nc3->state, NC_CREAT);
10751075

10761076
if(fIsSet(nc3->nciop->ioflags, NC_SHARE))
10771077
{
@@ -1082,7 +1082,7 @@ NC3_create(const char *path, int ioflags, size_t initialsz, int basepe,
10821082
* automatically. Some sort of IPC (external to this package)
10831083
* would be used to trigger a call to nc_sync().
10841084
*/
1085-
fSet(nc3->flags, NC_NSYNC);
1085+
fSet(nc3->state, NC_NSYNC);
10861086
}
10871087

10881088
status = ncx_put_NC(nc3, &xp, sizeof_off_t, nc3->xsz);
@@ -1173,29 +1173,12 @@ NC3_open(const char *path, int ioflags, int basepe, size_t *chunksizehintp,
11731173
goto unwind_alloc;
11741174
}
11751175

1176-
#ifdef ENABLE_BYTERANGE
1177-
{
1178-
NCURI* uri = NULL;
1179-
ncuriparse(path,&uri);
1180-
if(uri) {
1181-
/* If the model specified the use of byte-ranges, then signal by
1182-
a temporary hack using one of the flags in the ioflags. */
1183-
if(NC_testmode(uri,"bytes")) {
1184-
# ifdef ENABLE_S3_SDK
1185-
if(NC_iss3(uri)) ioflags |= NC_S3SDK; else
1186-
# endif
1187-
ioflags |= NC_HTTP;
1188-
}
1189-
ncurifree(uri);
1190-
}
1191-
}
1192-
#endif /*ENABLE_BYTERANGE*/
11931176
status = ncio_open(path, ioflags, 0, 0, &nc3->chunk, parameters,
11941177
&nc3->nciop, NULL);
11951178
if(status)
11961179
goto unwind_alloc;
11971180

1198-
assert(nc3->flags == 0);
1181+
assert(nc3->state == 0);
11991182

12001183
if(fIsSet(nc3->nciop->ioflags, NC_SHARE))
12011184
{
@@ -1206,7 +1189,7 @@ NC3_open(const char *path, int ioflags, int basepe, size_t *chunksizehintp,
12061189
* automatically. Some sort of IPC (external to this package)
12071190
* would be used to trigger a call to nc_sync().
12081191
*/
1209-
fSet(nc3->flags, NC_NSYNC);
1192+
fSet(nc3->state, NC_NSYNC);
12101193
}
12111194

12121195
status = nc_get_NC(nc3);
@@ -1279,10 +1262,10 @@ NC3_abort(int ncid)
12791262
{
12801263
/* a plain redef, not a create */
12811264
assert(!NC_IsNew(nc3));
1282-
assert(fIsSet(nc3->flags, NC_INDEF));
1265+
assert(fIsSet(nc3->state, NC_INDEF));
12831266
free_NC3INFO(nc3->old);
12841267
nc3->old = NULL;
1285-
fClr(nc3->flags, NC_INDEF);
1268+
fClr(nc3->state, NC_INDEF);
12861269
}
12871270
else if(!NC_readonly(nc3))
12881271
{
@@ -1397,7 +1380,7 @@ NC3_redef(int ncid)
13971380
if(nc3->old == NULL)
13981381
return NC_ENOMEM;
13991382

1400-
fSet(nc3->flags, NC_INDEF);
1383+
fSet(nc3->state, NC_INDEF);
14011384

14021385
return NC_NOERR;
14031386
}
@@ -1509,15 +1492,15 @@ NC3_set_fill(int ncid,
15091492
if(NC_readonly(nc3))
15101493
return NC_EPERM;
15111494

1512-
oldmode = fIsSet(nc3->flags, NC_NOFILL) ? NC_NOFILL : NC_FILL;
1495+
oldmode = fIsSet(nc3->state, NC_NOFILL) ? NC_NOFILL : NC_FILL;
15131496

15141497
if(fillmode == NC_NOFILL)
15151498
{
1516-
fSet(nc3->flags, NC_NOFILL);
1499+
fSet(nc3->state, NC_NOFILL);
15171500
}
15181501
else if(fillmode == NC_FILL)
15191502
{
1520-
if(fIsSet(nc3->flags, NC_NOFILL))
1503+
if(fIsSet(nc3->state, NC_NOFILL))
15211504
{
15221505
/*
15231506
* We are changing back to fill mode
@@ -1527,7 +1510,7 @@ NC3_set_fill(int ncid,
15271510
if(status != NC_NOERR)
15281511
return status;
15291512
}
1530-
fClr(nc3->flags, NC_NOFILL);
1513+
fClr(nc3->state, NC_NOFILL);
15311514
}
15321515
else
15331516
{

libsrc/ncio.c

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include "netcdf.h"
1313
#include "ncio.h"
1414
#include "fbits.h"
15+
#include "ncuri.h"
16+
#include "ncrc.h"
1517

1618
/* With the advent of diskless io, we need to provide
1719
for multiple ncio packages at the same time,
@@ -46,6 +48,9 @@ extern int ffio_open(const char*,int,off_t,size_t,size_t*,void*,ncio**,void** co
4648
extern int memio_create(const char*,int,size_t,off_t,size_t,size_t*,void*,ncio**,void** const);
4749
extern int memio_open(const char*,int,off_t,size_t,size_t*,void*,ncio**,void** const);
4850

51+
/* Forward */
52+
static int urlmodetest(const char* path);
53+
4954
int
5055
ncio_create(const char *path, int ioflags, size_t initialsz,
5156
off_t igeto, size_t igetsz, size_t *sizehintp,
@@ -78,6 +83,8 @@ ncio_open(const char *path, int ioflags,
7883
void* parameters,
7984
ncio** iopp, void** const mempp)
8085
{
86+
int modetest = urlmodetest(path);
87+
8188
/* Diskless open has the following constraints:
8289
1. file must be classic version 1 or 2 or 5
8390
*/
@@ -93,12 +100,11 @@ ncio_open(const char *path, int ioflags,
93100
}
94101
# endif /*USE_MMAP*/
95102
# ifdef ENABLE_BYTERANGE
96-
/* The NC_HTTP flag is a big hack until we can reorganize the ncio interface */
97-
if(fIsSet(ioflags,NC_HTTP)) {
103+
if(modetest == NC_HTTP) {
98104
return httpio_open(path,ioflags,igeto,igetsz,sizehintp,parameters,iopp,mempp);
99105
}
100106
# ifdef ENABLE_S3_SDK
101-
if(fIsSet(ioflags,NC_S3SDK)) {
107+
if(modetest == NC_S3SDK) {
102108
return s3io_open(path,ioflags,igeto,igetsz,sizehintp,parameters,iopp,mempp);
103109
}
104110
# endif
@@ -162,3 +168,29 @@ ncio_close(ncio* const nciop, int doUnlink)
162168
int status = nciop->close(nciop,doUnlink);
163169
return status;
164170
}
171+
172+
/* URL utilities */
173+
174+
/*
175+
Check mode flags and return:
176+
NC_HTTP => byterange
177+
NC_S3SDK => s3
178+
0 => Not URL
179+
*/
180+
static int
181+
urlmodetest(const char* path)
182+
{
183+
int kind = 0;
184+
NCURI* uri = NULL;
185+
186+
ncuriparse(path,&uri);
187+
if(uri == NULL) return 0; /* Not URL */
188+
if(NC_testmode(uri, "bytes"))
189+
kind = NC_HTTP;
190+
else if(NC_testmode(uri, "s3"))
191+
kind = NC_S3SDK;
192+
else
193+
kind = 0;
194+
ncurifree(uri);
195+
return kind;
196+
}

libsrc/ncio.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,9 @@
1111
#include <sys/types.h> /* off_t */
1212
#include "netcdf.h"
1313

14-
/* Define internal use only flags to signal use of byte ranges and S3.
15-
This is temporary until we can re-organize the ncio open/create API.
16-
*/
17-
#define NC_HTTP 0x80000000
18-
#define NC_S3SDK 0x40000000
14+
/* Define internal use only flags to signal use of byte ranges and S3. */
15+
#define NC_HTTP 1
16+
#define NC_S3SDK 2
1917

2018
typedef struct ncio ncio; /* forward reference */
2119

libsrc/s3io.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "fbits.h"
3737
#include "rnd.h"
3838
#include "ncs3sdk.h"
39+
#include "ncuri.h"
3940

4041
#define DEFAULTPAGESIZE 16384
4142

0 commit comments

Comments
 (0)