From e4ef7b1a65f89e833dc9864cc48315b4ee77b038 Mon Sep 17 00:00:00 2001 From: edwardhartnett Date: Wed, 21 Aug 2019 04:46:00 -0600 Subject: [PATCH 01/13] more unit tests, this time for nc4internal.c --- include/nc4internal.h | 1 + libdispatch/nc.c | 5 ++- libsrc4/nc4internal.c | 27 ++++++++++- unit_test/Makefile.am | 4 +- unit_test/tst_nc4internal.c | 90 +++++++++++++++++++++++++++++++++++++ unit_test/tst_nclist.c | 12 ++--- 6 files changed, 129 insertions(+), 10 deletions(-) create mode 100644 unit_test/tst_nc4internal.c diff --git a/include/nc4internal.h b/include/nc4internal.h index 0728adf7e..45d2bd647 100644 --- a/include/nc4internal.h +++ b/include/nc4internal.h @@ -341,6 +341,7 @@ int nc4_file_list_add(int ncid, const char *path, int mode, int nc4_file_list_get(int ncid, char **path, int *mode, void **dispatchdata); int nc4_file_list_del(int ncid); +int nc4_file_change_ncid(int ncid, int new_ncid); int nc4_var_list_add(NC_GRP_INFO_T* grp, const char* name, int ndims, NC_VAR_INFO_T **var); int nc4_var_list_add2(NC_GRP_INFO_T* grp, const char* name, diff --git a/libdispatch/nc.c b/libdispatch/nc.c index f7b6d6750..0c600c73a 100644 --- a/libdispatch/nc.c +++ b/libdispatch/nc.c @@ -68,10 +68,11 @@ free_NC(NC *ncp) /** * Create and initialize a new NC struct. The ncid is assigned later. * - * @param dispatcher + * @param dispatcher An pointer to the NC_Dispatch table that should + * be used by this NC. * @param path The name of the file. * @param mode The open or create mode. - * @param model + * @param model An NCmodel instance, provided by NC_infermodel(). * @param ncpp A pointer that gets a pointer to the newlly allocacted * and initialized NC struct. * diff --git a/libsrc4/nc4internal.c b/libsrc4/nc4internal.c index bc02d1cd0..abac1a811 100644 --- a/libsrc4/nc4internal.c +++ b/libsrc4/nc4internal.c @@ -89,7 +89,7 @@ nc4_check_name(const char *name, char *norm_name) * nc4_nc4f_list_add(), except it takes an ncid instead of an NC *, * and also passes back the dispatchdata pointer. * - * @param ncid The ncid of the file (aka ext_ncid). + * @param ncid The (already-assigned) ncid of the file (aka ext_ncid). * @param path The file name of the new file. * @param mode The mode flag. * @param dispatchdata Void * that gets pointer to dispatch data, @@ -125,6 +125,31 @@ nc4_file_list_add(int ncid, const char *path, int mode, void **dispatchdata) return NC_NOERR; } +/** + * @internal Change the ncid of an open file. This is needed for PIO + * integration. + * + * @param ncid The ncid of the file (aka ext_ncid). + * @param new_ncid The new ncid to use. + * + * @return ::NC_NOERR No error. + * @return ::NC_EBADID No NC struct with this ext_ncid. + * @return ::NC_ENOMEM Out of memory. + * @author Ed Hartnett + */ +int +nc4_file_change_ncid(int ncid, int new_ncid) +{ + NC *nc; + int ret; + + /* Find NC pointer for this file. */ + if ((ret = NC_check_id(ncid, &nc))) + return ret; + + return NC_NOERR; +} + /** * @internal Get info about a file on the list of libsrc4 open files. This is * used by dispatch layers that wish to use the libsrc4 metadata diff --git a/unit_test/Makefile.am b/unit_test/Makefile.am index c83024a77..c96729745 100644 --- a/unit_test/Makefile.am +++ b/unit_test/Makefile.am @@ -14,8 +14,8 @@ include $(top_srcdir)/lib_flags.am # Find and link to the netcdf-c library. LDADD = ${top_builddir}/liblib/libnetcdf.la -check_PROGRAMS = tst_nclist -TESTS = tst_nclist +check_PROGRAMS = tst_nclist tst_nc4internal +TESTS = tst_nclist tst_nc4internal # If valgrind is present, add valgrind targets. @VALGRIND_CHECK_RULES@ diff --git a/unit_test/tst_nc4internal.c b/unit_test/tst_nc4internal.c new file mode 100644 index 000000000..baadb4fb4 --- /dev/null +++ b/unit_test/tst_nc4internal.c @@ -0,0 +1,90 @@ +/* This is part of the netCDF package. Copyright 2005-2019 University + Corporation for Atmospheric Research/Unidata. See COPYRIGHT file + for conditions of use. + + Test list functions in nc4internal.c. + + Ed Hartnett, 8/21/19 +*/ + +#include "config.h" +#include +#include "nc.h" +#include "nc4internal.h" +#include "ncdispatch.h" +#include "err_macros.h" + +/* An integer value to use in testing. */ +#define TEST_VAL_42 42 + +#define FILE_NAME "tst_nc4internal.nc" + +int +main(int argc, char **argv) +{ + printf("\n*** Testing netcdf nc4internal functions.\n"); + printf("Testing adding new file to nc4internal file lists..."); + { + NC *ncp; + NCmodel model; + + /* This won't work because there is no NC in the NC list which + * has an ncid of TEST_VAL_42. */ + if (nc4_file_list_add(TEST_VAL_42, FILE_NAME, 0, NULL) != NC_EBADID) ERR; + + /* Create the NC* instance and insert its dispatcher and + * model. The NC3_dispatch_table is defined in + * ncdispatch.h. */ + if(new_NC(NC3_dispatch_table, FILE_NAME, 0, &model, &ncp)) ERR; + + /* Add to list of known open files and define ext_ncid. */ + add_to_NCList(ncp); + + /* Create the NC_FILE_INFO_T instance associated empty lists + * to hold dims, types, groups, and the root group. */ + if (nc4_file_list_add(ncp->ext_ncid, FILE_NAME, 0, NULL)) ERR; + + /* Delete the NC_FILE_INFO_T and related storage. */ + if (nc4_file_list_del(ncp->ext_ncid)) ERR; + + /* Delete the ncp from the list. (In fact, just null out its + * entry in the array of file slots. */ + del_from_NCList(ncp); /* Will free empty list. */ + + /* Now free the NC struct. */ + free_NC(ncp); + } + SUMMARIZE_ERR; + /* printf("Testing changing ncid..."); */ + /* { */ + /* NC *ncp, *ncp2; */ + /* int mode = 0; */ + /* NCmodel model; */ + /* int ret; */ + + /* /\* Create the NC* instance and insert its dispatcher and model. *\/ */ + /* if ((ret = new_NC(NULL, FILE_NAME, mode, &model, &ncp))) ERR; */ + + /* /\* Add to list of known open files and define ext_ncid. *\/ */ + /* add_to_NCList(ncp); */ + + /* /\* Find it in the list. *\/ */ + /* if (!(ncp2 = find_in_NCList(ncp->ext_ncid))) ERR; */ + /* if (!(ncp2 = find_in_NCList_by_name(FILE_NAME))) ERR; */ + /* if ((ret = iterate_NCList(1, &ncp2))) ERR; */ + /* if (count_NCList() != 1) ERR; */ + + /* /\* Change the ncid. *\/ */ + /* if (nc4_file_change_ncid(ncp->ext_ncid, TEST_VAL_42)) ERR; */ + + /* /\* Delete it. *\/ */ + /* del_from_NCList(ncp); /\* Will free empty list. *\/ */ + /* free_NC(ncp); */ + + /* /\* Ensure it is no longer in list. *\/ */ + /* /\* if (find_in_NCList(ncp->ext_ncid)) ERR; *\/ */ + + /* } */ + /* SUMMARIZE_ERR; */ + FINAL_RESULTS; +} diff --git a/unit_test/tst_nclist.c b/unit_test/tst_nclist.c index 3637a1642..37783e980 100644 --- a/unit_test/tst_nclist.c +++ b/unit_test/tst_nclist.c @@ -16,6 +16,8 @@ /* An integer value to use in testing. */ #define TEST_VAL_42 42 +#define FILE_NAME "tst_nclist.nc" + int main(int argc, char **argv) { @@ -36,11 +38,10 @@ main(int argc, char **argv) NC *ncp, *ncp2; int mode = 0; NCmodel model; - char path[] = {"file.nc"}; int ret; /* Create the NC* instance and insert its dispatcher and model. */ - if ((ret = new_NC(NULL, path, mode, &model, &ncp))) ERR; + if ((ret = new_NC(NULL, FILE_NAME, mode, &model, &ncp))) ERR; /* Nothing to find yet. */ if (find_in_NCList(TEST_VAL_42)) ERR; @@ -55,7 +56,7 @@ main(int argc, char **argv) /* Find it in the list. */ if (!(ncp2 = find_in_NCList(ncp->ext_ncid))) ERR; - if (!(ncp2 = find_in_NCList_by_name(path))) ERR; + if (!(ncp2 = find_in_NCList_by_name(FILE_NAME))) ERR; if ((ret = iterate_NCList(1, &ncp2))) ERR; if (count_NCList() != 1) ERR; @@ -66,6 +67,8 @@ main(int argc, char **argv) ncid = ncp->ext_ncid; del_from_NCList(ncp); /* Will free empty list. */ free_NC(ncp); + + /* Ensure it is no longer in list. */ if (find_in_NCList(ncid)) ERR; } SUMMARIZE_ERR; @@ -76,7 +79,6 @@ main(int argc, char **argv) NC *ncp; int mode = 0; NCmodel model; - char path[] = {"file.nc"}; int max_num_nc = 65535; int i; int ret; @@ -84,7 +86,7 @@ main(int argc, char **argv) /* Fill the NC list. */ for (i = 0; i < max_num_nc; i++) { - if ((ret = new_NC(NULL, path, mode, &model, &ncp))) ERR; + if ((ret = new_NC(NULL, FILE_NAME, mode, &model, &ncp))) ERR; if (add_to_NCList(ncp)) ERR; } From 0e95d4c8713bb294ee7e45fb683f30287abe8b7c Mon Sep 17 00:00:00 2001 From: edwardhartnett Date: Wed, 21 Aug 2019 04:52:33 -0600 Subject: [PATCH 02/13] more comments --- unit_test/tst_nc4internal.c | 5 +++-- unit_test/tst_nclist.c | 7 ++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/unit_test/tst_nc4internal.c b/unit_test/tst_nc4internal.c index baadb4fb4..de9a7f5f2 100644 --- a/unit_test/tst_nc4internal.c +++ b/unit_test/tst_nc4internal.c @@ -37,7 +37,8 @@ main(int argc, char **argv) * ncdispatch.h. */ if(new_NC(NC3_dispatch_table, FILE_NAME, 0, &model, &ncp)) ERR; - /* Add to list of known open files and define ext_ncid. */ + /* Add to array of open files nc_filelist and define + * ext_ncid by left-shifting the index 16 bits. */ add_to_NCList(ncp); /* Create the NC_FILE_INFO_T instance associated empty lists @@ -48,7 +49,7 @@ main(int argc, char **argv) if (nc4_file_list_del(ncp->ext_ncid)) ERR; /* Delete the ncp from the list. (In fact, just null out its - * entry in the array of file slots. */ + * entry in the array of file slots.) */ del_from_NCList(ncp); /* Will free empty list. */ /* Now free the NC struct. */ diff --git a/unit_test/tst_nclist.c b/unit_test/tst_nclist.c index 37783e980..0daae16a9 100644 --- a/unit_test/tst_nclist.c +++ b/unit_test/tst_nclist.c @@ -46,7 +46,12 @@ main(int argc, char **argv) /* Nothing to find yet. */ if (find_in_NCList(TEST_VAL_42)) ERR; - /* Add to list of known open files and define ext_ncid. */ + /* Add to list of known open files and define ext_ncid. To get + * the ncid, we find the first open index > 1 in the + * nc_filelist array, which has a size of 65536. Then we + * left-shift that index 16 bits to put it in the first + * 2-bytes of the 4-byte ncid. (The other two bytes are + * reserved for grpid of netCDF-4 groups.) */ add_to_NCList(ncp); /* These won't work! */ From 96344631a8ac7c8a484113d68f548636aa8588bc Mon Sep 17 00:00:00 2001 From: edwardhartnett Date: Wed, 21 Aug 2019 09:48:50 -0600 Subject: [PATCH 03/13] run tst_nc4internal for netcdf4 builds only --- libsrc4/nc4internal.c | 8 ++++---- unit_test/Makefile.am | 8 ++++++-- unit_test/tst_nc4internal.c | 18 +++++++++++++++++- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/libsrc4/nc4internal.c b/libsrc4/nc4internal.c index abac1a811..5e5d5f085 100644 --- a/libsrc4/nc4internal.c +++ b/libsrc4/nc4internal.c @@ -151,9 +151,9 @@ nc4_file_change_ncid(int ncid, int new_ncid) } /** - * @internal Get info about a file on the list of libsrc4 open files. This is - * used by dispatch layers that wish to use the libsrc4 metadata - * model, but don't know about struct NC. + * @internal Get info about a file on the list of libsrc4 open + * files. This is used by dispatch layers that wish to use the libsrc4 + * metadata model, but don't know about struct NC. * * @param ncid The ncid of the file (aka ext_ncid). * @param path A pointer that gets file name (< NC_MAX_NAME). Igored @@ -237,7 +237,7 @@ nc4_nc4f_list_add(NC *nc, const char *path, int mode) /* There's always at least one open group - the root * group. Allocate space for one group's worth of information. Set - * its hdf id, name, and a pointer to it's file structure. */ + * its grp id, name, and allocate associated empty lists. */ if ((retval = nc4_grp_list_add(h5, NULL, NC_GROUP_NAME, &h5->root_grp))) return retval; diff --git a/unit_test/Makefile.am b/unit_test/Makefile.am index c96729745..65b545a60 100644 --- a/unit_test/Makefile.am +++ b/unit_test/Makefile.am @@ -14,8 +14,12 @@ include $(top_srcdir)/lib_flags.am # Find and link to the netcdf-c library. LDADD = ${top_builddir}/liblib/libnetcdf.la -check_PROGRAMS = tst_nclist tst_nc4internal -TESTS = tst_nclist tst_nc4internal +if USE_NETCDF4 +NC4_TESTS = tst_nc4internal +endif # USE_NETCDF4 + +check_PROGRAMS = tst_nclist $(NC4_TESTS) +TESTS = tst_nclist $(NC4_TESTS) # If valgrind is present, add valgrind targets. @VALGRIND_CHECK_RULES@ diff --git a/unit_test/tst_nc4internal.c b/unit_test/tst_nc4internal.c index de9a7f5f2..877f27097 100644 --- a/unit_test/tst_nc4internal.c +++ b/unit_test/tst_nc4internal.c @@ -23,10 +23,14 @@ int main(int argc, char **argv) { printf("\n*** Testing netcdf nc4internal functions.\n"); - printf("Testing adding new file to nc4internal file lists..."); + printf("Testing adding new file to nc4internal file lists with " + "nc4_file_list_add()..."); { NC *ncp; NCmodel model; + char path[NC_MAX_NAME + 1]; + void *dispatchdata; + int mode; /* This won't work because there is no NC in the NC list which * has an ncid of TEST_VAL_42. */ @@ -45,6 +49,13 @@ main(int argc, char **argv) * to hold dims, types, groups, and the root group. */ if (nc4_file_list_add(ncp->ext_ncid, FILE_NAME, 0, NULL)) ERR; + /* Find the file in the list. */ + if (nc4_file_list_get(ncp->ext_ncid, NULL, &mode, &dispatchdata)) ERR; + /* if (nc4_file_list_get(ncp->ext_ncid, (char **)&path, &mode, &dispatchdata)) ERR; */ + + /* This won't work. */ + if (nc4_file_list_del(TEST_VAL_42) != NC_EBADID) ERR; + /* Delete the NC_FILE_INFO_T and related storage. */ if (nc4_file_list_del(ncp->ext_ncid)) ERR; @@ -56,6 +67,11 @@ main(int argc, char **argv) free_NC(ncp); } SUMMARIZE_ERR; + printf("Testing adding new file to nc4internal file lists with " + "nc4_nc4f_list_add()..."); + { + } + SUMMARIZE_ERR; /* printf("Testing changing ncid..."); */ /* { */ /* NC *ncp, *ncp2; */ From bf069c398306126dff266073e312f2684061973d Mon Sep 17 00:00:00 2001 From: edwardhartnett Date: Wed, 21 Aug 2019 10:04:49 -0600 Subject: [PATCH 04/13] more unit testing --- unit_test/tst_nc4internal.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/unit_test/tst_nc4internal.c b/unit_test/tst_nc4internal.c index 877f27097..4b990829c 100644 --- a/unit_test/tst_nc4internal.c +++ b/unit_test/tst_nc4internal.c @@ -28,9 +28,9 @@ main(int argc, char **argv) { NC *ncp; NCmodel model; - char path[NC_MAX_NAME + 1]; + char *path; void *dispatchdata; - int mode; + int mode = 0, mode_in; /* This won't work because there is no NC in the NC list which * has an ncid of TEST_VAL_42. */ @@ -39,7 +39,7 @@ main(int argc, char **argv) /* Create the NC* instance and insert its dispatcher and * model. The NC3_dispatch_table is defined in * ncdispatch.h. */ - if(new_NC(NC3_dispatch_table, FILE_NAME, 0, &model, &ncp)) ERR; + if(new_NC(NC3_dispatch_table, FILE_NAME, mode, &model, &ncp)) ERR; /* Add to array of open files nc_filelist and define * ext_ncid by left-shifting the index 16 bits. */ @@ -47,11 +47,15 @@ main(int argc, char **argv) /* Create the NC_FILE_INFO_T instance associated empty lists * to hold dims, types, groups, and the root group. */ - if (nc4_file_list_add(ncp->ext_ncid, FILE_NAME, 0, NULL)) ERR; + if (nc4_file_list_add(ncp->ext_ncid, FILE_NAME, mode, NULL)) ERR; /* Find the file in the list. */ - if (nc4_file_list_get(ncp->ext_ncid, NULL, &mode, &dispatchdata)) ERR; - /* if (nc4_file_list_get(ncp->ext_ncid, (char **)&path, &mode, &dispatchdata)) ERR; */ + /* if (nc4_file_list_get(ncp->ext_ncid, NULL, &mode, &dispatchdata)) ERR; */ + path = malloc(NC_MAX_NAME + 1); + if (nc4_file_list_get(ncp->ext_ncid, &path, &mode_in, &dispatchdata)) ERR; + if (strcmp(path, FILE_NAME)) ERR; + if (mode_in != mode) ERR; + free(path); /* This won't work. */ if (nc4_file_list_del(TEST_VAL_42) != NC_EBADID) ERR; From 788c63d1dc5a96a78899fc93cab9cc0fe4ee8b05 Mon Sep 17 00:00:00 2001 From: edwardhartnett Date: Wed, 21 Aug 2019 10:08:24 -0600 Subject: [PATCH 05/13] more unit testing --- unit_test/tst_nc4internal.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/unit_test/tst_nc4internal.c b/unit_test/tst_nc4internal.c index 4b990829c..995c6aa40 100644 --- a/unit_test/tst_nc4internal.c +++ b/unit_test/tst_nc4internal.c @@ -29,7 +29,7 @@ main(int argc, char **argv) NC *ncp; NCmodel model; char *path; - void *dispatchdata; + void *dispatchdata, *disspatchdata_in; int mode = 0, mode_in; /* This won't work because there is no NC in the NC list which @@ -50,12 +50,12 @@ main(int argc, char **argv) if (nc4_file_list_add(ncp->ext_ncid, FILE_NAME, mode, NULL)) ERR; /* Find the file in the list. */ - /* if (nc4_file_list_get(ncp->ext_ncid, NULL, &mode, &dispatchdata)) ERR; */ - path = malloc(NC_MAX_NAME + 1); - if (nc4_file_list_get(ncp->ext_ncid, &path, &mode_in, &dispatchdata)) ERR; + if (!(path = malloc(NC_MAX_NAME + 1))) ERR; + if (nc4_file_list_get(ncp->ext_ncid, &path, &mode_in, &dispatchdata_in)) ERR; if (strcmp(path, FILE_NAME)) ERR; - if (mode_in != mode) ERR; free(path); + if (mode_in != mode) ERR; + if (dispatchdata_in != dispatchdata) ERR; /* This won't work. */ if (nc4_file_list_del(TEST_VAL_42) != NC_EBADID) ERR; From e9cc0e28990569bd9dca6abf6809f13fd54bb372 Mon Sep 17 00:00:00 2001 From: edwardhartnett Date: Wed, 21 Aug 2019 10:33:28 -0600 Subject: [PATCH 06/13] more unit testing --- unit_test/tst_nc4internal.c | 49 +++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/unit_test/tst_nc4internal.c b/unit_test/tst_nc4internal.c index 995c6aa40..f6c3f58b7 100644 --- a/unit_test/tst_nc4internal.c +++ b/unit_test/tst_nc4internal.c @@ -29,7 +29,11 @@ main(int argc, char **argv) NC *ncp; NCmodel model; char *path; - void *dispatchdata, *disspatchdata_in; + /* The NC3_dispatch_table is defined in nc3dispatch.c and + * externed in ncdispatch.h. But it will be 0 because we have + * not yet called NC3_initialize(). */ + const void *dispatcher = NC3_dispatch_table; + void *dispatchdata_in; int mode = 0, mode_in; /* This won't work because there is no NC in the NC list which @@ -37,9 +41,8 @@ main(int argc, char **argv) if (nc4_file_list_add(TEST_VAL_42, FILE_NAME, 0, NULL) != NC_EBADID) ERR; /* Create the NC* instance and insert its dispatcher and - * model. The NC3_dispatch_table is defined in - * ncdispatch.h. */ - if(new_NC(NC3_dispatch_table, FILE_NAME, mode, &model, &ncp)) ERR; + * model. */ + if (new_NC(dispatcher, FILE_NAME, mode, &model, &ncp)) ERR; /* Add to array of open files nc_filelist and define * ext_ncid by left-shifting the index 16 bits. */ @@ -55,7 +58,6 @@ main(int argc, char **argv) if (strcmp(path, FILE_NAME)) ERR; free(path); if (mode_in != mode) ERR; - if (dispatchdata_in != dispatchdata) ERR; /* This won't work. */ if (nc4_file_list_del(TEST_VAL_42) != NC_EBADID) ERR; @@ -74,6 +76,43 @@ main(int argc, char **argv) printf("Testing adding new file to nc4internal file lists with " "nc4_nc4f_list_add()..."); { + NC *ncp; + NCmodel model; + char *path; + void *dispatchdata_in; + int mode = 0, mode_in; + + /* Create the NC* instance and insert its dispatcher and + * model. */ + if (new_NC(NC3_dispatch_table, FILE_NAME, mode, &model, &ncp)) ERR; + + /* Add to array of open files nc_filelist and define + * ext_ncid by left-shifting the index 16 bits. */ + add_to_NCList(ncp); + + /* Create the NC_FILE_INFO_T instance associated empty lists + * to hold dims, types, groups, and the root group. */ + if (nc4_nc4f_list_add(ncp, FILE_NAME, mode)) ERR; + + /* Find the file in the list. */ + if (!(path = malloc(NC_MAX_NAME + 1))) ERR; + if (nc4_file_list_get(ncp->ext_ncid, &path, &mode_in, &dispatchdata_in)) ERR; + if (strcmp(path, FILE_NAME)) ERR; + free(path); + if (mode_in != mode) ERR; + + /* This won't work. */ + if (nc4_file_list_del(TEST_VAL_42) != NC_EBADID) ERR; + + /* Delete the NC_FILE_INFO_T and related storage. */ + if (nc4_file_list_del(ncp->ext_ncid)) ERR; + + /* Delete the ncp from the list. (In fact, just null out its + * entry in the array of file slots.) */ + del_from_NCList(ncp); /* Will free empty list. */ + + /* Now free the NC struct. */ + free_NC(ncp); } SUMMARIZE_ERR; /* printf("Testing changing ncid..."); */ From 04544a3dabafc3d5a19c4e66a0aa6ad5d3dcf691 Mon Sep 17 00:00:00 2001 From: edwardhartnett Date: Wed, 21 Aug 2019 11:11:57 -0600 Subject: [PATCH 07/13] more unit tests for nc4internal functions --- unit_test/tst_nc4internal.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/unit_test/tst_nc4internal.c b/unit_test/tst_nc4internal.c index f6c3f58b7..075db0913 100644 --- a/unit_test/tst_nc4internal.c +++ b/unit_test/tst_nc4internal.c @@ -76,11 +76,13 @@ main(int argc, char **argv) printf("Testing adding new file to nc4internal file lists with " "nc4_nc4f_list_add()..."); { - NC *ncp; + NC *ncp, *ncp_in, *ncp_in2; NCmodel model; char *path; void *dispatchdata_in; int mode = 0, mode_in; + NC_GRP_INFO_T *grp, *grp2; + NC_FILE_INFO_T *h5, *h52; /* Create the NC* instance and insert its dispatcher and * model. */ @@ -101,8 +103,34 @@ main(int argc, char **argv) free(path); if (mode_in != mode) ERR; - /* This won't work. */ - if (nc4_file_list_del(TEST_VAL_42) != NC_EBADID) ERR; + /* Find it again. */ + if (nc4_find_nc_grp_h5(ncp->ext_ncid, &ncp_in, &grp, &h5)) ERR; + if (ncp_in->ext_ncid != ncp->ext_ncid) ERR; + if (grp->nc4_info->controller->ext_ncid != ncp->ext_ncid) ERR; + if (h5->controller->ext_ncid != ncp->ext_ncid) ERR; + + /* Any of the pointer parameters may be NULL. */ + if (nc4_find_nc_grp_h5(ncp->ext_ncid, NULL, NULL, NULL)) ERR; + if (nc4_find_nc_grp_h5(ncp->ext_ncid, &ncp_in2, NULL, NULL)) ERR; + if (ncp_in2->ext_ncid != ncp->ext_ncid) ERR; + if (nc4_find_nc_grp_h5(ncp->ext_ncid, NULL, &grp2, NULL)) ERR; + if (grp2->nc4_info->controller->ext_ncid != ncp->ext_ncid) ERR; + if (nc4_find_nc_grp_h5(ncp->ext_ncid, NULL, NULL, &h52)) ERR; + if (h52->controller->ext_ncid != ncp->ext_ncid) ERR; + + /* There are additional functions which use the NULL + * parameters of nc4_find_nc_grp_h5(). */ + grp2 = NULL; + h52 = NULL; + if (nc4_find_grp_h5(ncp->ext_ncid, NULL, NULL)) ERR; + if (nc4_find_grp_h5(ncp->ext_ncid, &grp2, NULL)) ERR; + if (grp2->nc4_info->controller->ext_ncid != ncp->ext_ncid) ERR; + if (nc4_find_grp_h5(ncp->ext_ncid, NULL, &h52)) ERR; + if (h52->controller->ext_ncid != ncp->ext_ncid) ERR; + grp2 = NULL; + if (nc4_find_nc4_grp(ncp->ext_ncid, NULL)) ERR; + if (nc4_find_nc4_grp(ncp->ext_ncid, &grp2)) ERR; + if (grp2->nc4_info->controller->ext_ncid != ncp->ext_ncid) ERR; /* Delete the NC_FILE_INFO_T and related storage. */ if (nc4_file_list_del(ncp->ext_ncid)) ERR; From 5f586fc9ccf8abeae7c82adec15112cb603f872a Mon Sep 17 00:00:00 2001 From: edwardhartnett Date: Wed, 21 Aug 2019 13:34:06 -0600 Subject: [PATCH 08/13] more unit tests for nc4internal.c --- unit_test/tst_nc4internal.c | 53 +++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/unit_test/tst_nc4internal.c b/unit_test/tst_nc4internal.c index 075db0913..3f752986e 100644 --- a/unit_test/tst_nc4internal.c +++ b/unit_test/tst_nc4internal.c @@ -18,6 +18,7 @@ #define TEST_VAL_42 42 #define FILE_NAME "tst_nc4internal.nc" +#define VAR_NAME "Hilary_Duff" int main(int argc, char **argv) @@ -143,6 +144,58 @@ main(int argc, char **argv) free_NC(ncp); } SUMMARIZE_ERR; + printf("Testing adding new var to nc4internal file..."); + { + NC *ncp, *ncp_in; + NCmodel model; + NC_GRP_INFO_T *grp; + NC_VAR_INFO_T *var, *var_in; + NC_FILE_INFO_T *h5; + + /* Create the NC* instance and insert its dispatcher and + * model. */ + if (new_NC(NC3_dispatch_table, FILE_NAME, 0, &model, &ncp)) ERR; + + /* Add to array of open files nc_filelist and define + * ext_ncid by left-shifting the index 16 bits. */ + add_to_NCList(ncp); + + /* Create the NC_FILE_INFO_T instance associated empty lists + * to hold dims, types, groups, and the root group. */ + if (nc4_file_list_add(ncp->ext_ncid, FILE_NAME, 0, NULL)) ERR; + + /* Find the file in the list. */ + if (nc4_find_nc_grp_h5(ncp->ext_ncid, &ncp_in, &grp, &h5)) ERR; + if (ncp_in->ext_ncid != ncp->ext_ncid) ERR; + + /* Add a var to the varlist. */ + if (nc4_var_list_add(grp, VAR_NAME, 0, &var)) ERR; + + /* Find the var. */ + if (nc4_find_var(grp, VAR_NAME, &var_in)) ERR; + if (strcmp(var_in->hdr.name, var->hdr.name)) ERR; + + /* Find it again. */ + h5 = NULL; + grp = NULL; + var_in = NULL; + if (nc4_find_grp_h5_var(ncp->ext_ncid, 0, &h5, &grp, &var_in)) ERR; + if (h5->controller->ext_ncid != ncp->ext_ncid) ERR; + if (grp->nc4_info->controller->ext_ncid != ncp->ext_ncid) ERR; + if (strcmp(var_in->hdr.name, var->hdr.name)) ERR; + + /* Delete the NC_FILE_INFO_T and related storage, including + * all vars, dims, types, etc. */ + if (nc4_file_list_del(ncp->ext_ncid)) ERR; + + /* Delete the ncp from the list. (In fact, just null out its + * entry in the array of file slots.) */ + del_from_NCList(ncp); /* Will free empty list. */ + + /* Now free the NC struct. */ + free_NC(ncp); + } + SUMMARIZE_ERR; /* printf("Testing changing ncid..."); */ /* { */ /* NC *ncp, *ncp2; */ From 100e000d43ac241d1268a0f1920c78e381d7c105 Mon Sep 17 00:00:00 2001 From: edwardhartnett Date: Wed, 21 Aug 2019 13:34:43 -0600 Subject: [PATCH 09/13] more unit tests for nc4internal.c --- include/nc4internal.h | 1 - libsrc4/nc4internal.c | 44 +++++++++++++++++++++---------------------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/include/nc4internal.h b/include/nc4internal.h index 45d2bd647..0728adf7e 100644 --- a/include/nc4internal.h +++ b/include/nc4internal.h @@ -341,7 +341,6 @@ int nc4_file_list_add(int ncid, const char *path, int mode, int nc4_file_list_get(int ncid, char **path, int *mode, void **dispatchdata); int nc4_file_list_del(int ncid); -int nc4_file_change_ncid(int ncid, int new_ncid); int nc4_var_list_add(NC_GRP_INFO_T* grp, const char* name, int ndims, NC_VAR_INFO_T **var); int nc4_var_list_add2(NC_GRP_INFO_T* grp, const char* name, diff --git a/libsrc4/nc4internal.c b/libsrc4/nc4internal.c index 5e5d5f085..ad4d3a70f 100644 --- a/libsrc4/nc4internal.c +++ b/libsrc4/nc4internal.c @@ -125,30 +125,30 @@ nc4_file_list_add(int ncid, const char *path, int mode, void **dispatchdata) return NC_NOERR; } -/** - * @internal Change the ncid of an open file. This is needed for PIO - * integration. - * - * @param ncid The ncid of the file (aka ext_ncid). - * @param new_ncid The new ncid to use. - * - * @return ::NC_NOERR No error. - * @return ::NC_EBADID No NC struct with this ext_ncid. - * @return ::NC_ENOMEM Out of memory. - * @author Ed Hartnett - */ -int -nc4_file_change_ncid(int ncid, int new_ncid) -{ - NC *nc; - int ret; +/* /\** */ +/* * @internal Change the ncid of an open file. This is needed for PIO */ +/* * integration. */ +/* * */ +/* * @param ncid The ncid of the file (aka ext_ncid). */ +/* * @param new_ncid The new ncid to use. */ +/* * */ +/* * @return ::NC_NOERR No error. */ +/* * @return ::NC_EBADID No NC struct with this ext_ncid. */ +/* * @return ::NC_ENOMEM Out of memory. */ +/* * @author Ed Hartnett */ +/* *\/ */ +/* int */ +/* nc4_file_change_ncid(int ncid, int new_ncid) */ +/* { */ +/* NC *nc; */ +/* int ret; */ - /* Find NC pointer for this file. */ - if ((ret = NC_check_id(ncid, &nc))) - return ret; +/* /\* Find NC pointer for this file. *\/ */ +/* if ((ret = NC_check_id(ncid, &nc))) */ +/* return ret; */ - return NC_NOERR; -} +/* return NC_NOERR; */ +/* } */ /** * @internal Get info about a file on the list of libsrc4 open From 9a92201c9411faa74d009d9143ddc99c72c93bff Mon Sep 17 00:00:00 2001 From: Ward Fisher Date: Wed, 21 Aug 2019 14:50:09 -0600 Subject: [PATCH 10/13] Wiring unit test directory into cmake-based builds. --- CMakeLists.txt | 11 +++++++++++ nc_test4/CMakeLists.txt | 2 -- unit_test/CMakeLists.txt | 21 +++++++++++++++++++++ unit_test/Makefile.am | 2 ++ 4 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 unit_test/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index b1211d026..384b4bcba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -935,6 +935,13 @@ IF(ENABLE_TESTS) OPTION(ENABLE_FAILING_TESTS "Run tests which are known to fail, check to see if any have been fixed." OFF) + ### + # Option to turn on unit testing. See https://github.com/Unidata/netcdf-c/pull/1472 for more information. + # Currently (August 21, 2019): Will not work with Visual Studio + ### + IF(NOT MSVC) + OPTION(ENABLE_UNIT_TESTS "Run Unit Tests." ON) + ENDIF(NOT MSVC) ### # End known-failures. ### @@ -1621,6 +1628,7 @@ MACRO(print_conf_summary) MESSAGE(STATUS "Parallel Tests: ${ENABLE_PARALLEL_TESTS}") MESSAGE(STATUS "Large File Tests: ${ENABLE_LARGE_FILE_TESTS}") MESSAGE(STATUS "Extreme Numbers: ${ENABLE_EXTREME_NUMBERS}") + MESSAGE(STATUS "Unit Tests: ${ENABLE_UNIT_TESTS}") ENDIF() MESSAGE("") @@ -1794,6 +1802,9 @@ IF(ENABLE_TESTS) IF(ENABLE_EXAMPLES) ADD_SUBDIRECTORY(examples) ENDIF() + IF(ENABLE_UNIT_TESTS) + ADD_SUBDIRECTORY(unit_test) + ENDIF(ENABLE_UNIT_TESTS) ENDIF() # Code to generate an export header diff --git a/nc_test4/CMakeLists.txt b/nc_test4/CMakeLists.txt index 38d433824..50eed3fe4 100644 --- a/nc_test4/CMakeLists.txt +++ b/nc_test4/CMakeLists.txt @@ -90,5 +90,3 @@ IF(TEST_PARALLEL4) build_bin_test(tst_simplerw_coll_r) add_sh_test(nc_test4 run_par_test) ENDIF() - -ADD_EXTRA_DIST(findplugin.in run_par_test.sh.in) diff --git a/unit_test/CMakeLists.txt b/unit_test/CMakeLists.txt new file mode 100644 index 000000000..004d44a73 --- /dev/null +++ b/unit_test/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, +# 2015, 2016, 2017, 2018, 2019 +# University Corporation for Atmospheric Research/Unidata. + +# See netcdf-c/COPYRIGHT file for more info. + +# This is the cmake build file for unit_test/ directory. +# @author Ward Fisher + +# Some unit testing + +SET(UNIT_TESTS tst_nclist) + +IF(ENABLE_NETCDF_4) + SET(UNIT_TESTS ${UNIT_TESTS} tst_nc4internal) +ENDIF(ENABLE_NETCDF_4) + +FOREACH(CTEST ${UNIT_TESTS}) + add_bin_test(unit_test ${CTEST}) +ENDFOREACH() diff --git a/unit_test/Makefile.am b/unit_test/Makefile.am index 65b545a60..9e2f87d13 100644 --- a/unit_test/Makefile.am +++ b/unit_test/Makefile.am @@ -21,5 +21,7 @@ endif # USE_NETCDF4 check_PROGRAMS = tst_nclist $(NC4_TESTS) TESTS = tst_nclist $(NC4_TESTS) +EXTRA_DIST = CMakeLists.txt + # If valgrind is present, add valgrind targets. @VALGRIND_CHECK_RULES@ From 5b3891a2534cf67bf017ab5bfee76d6c76152416 Mon Sep 17 00:00:00 2001 From: edwardhartnett Date: Wed, 21 Aug 2019 16:04:59 -0600 Subject: [PATCH 11/13] more unit tests, starting on doxygen docs for nc4internal.h --- include/nc4internal.h | 130 ++++++++++++++++++++---------------- unit_test/tst_nc4internal.c | 69 +++++++++++++++++++ 2 files changed, 141 insertions(+), 58 deletions(-) diff --git a/include/nc4internal.h b/include/nc4internal.h index 0728adf7e..ca01d2be9 100644 --- a/include/nc4internal.h +++ b/include/nc4internal.h @@ -33,48 +33,53 @@ /* Always needed */ #include "nc.h" +/** The file ID is stored in the first two bytes of ncid. */ #define FILE_ID_MASK (0xffff0000) + +/** The group ID is stored in the last two bytes of ncid. */ #define GRP_ID_MASK (0x0000ffff) + +/** File and group IDs are each 16 bits of the ncid. */ #define ID_SHIFT (16) -typedef enum {GET, PUT} NC_PG_T; +/* typedef enum {GET, PUT} NC_PG_T; */ +/** These are the different objects that can be in our hash-lists. */ typedef enum {NCNAT, NCVAR, NCDIM, NCATT, NCTYP, NCFLD, NCGRP} NC_SORT; +/** The netCDF V2 error code. */ #define NC_V2_ERR (-1) -/* The name of the root group. */ +/** The name of the root group. */ #define NC_GROUP_NAME "/" +/** One mega-byte. */ #define MEGABYTE 1048576 -/* - * limits of the external representation - */ -#define X_SCHAR_MIN (-128) -#define X_SCHAR_MAX 127 -#define X_UCHAR_MAX 255U -#define X_SHORT_MIN (-32768) -#define X_SHRT_MIN X_SHORT_MIN /* alias compatible with limits.h */ -#define X_SHORT_MAX 32767 -#define X_SHRT_MAX X_SHORT_MAX /* alias compatible with limits.h */ -#define X_USHORT_MAX 65535U -#define X_USHRT_MAX X_USHORT_MAX /* alias compatible with limits.h */ -#define X_INT_MIN (-2147483647-1) -#define X_INT_MAX 2147483647 -#define X_LONG_MIN X_INT_MIN -#define X_LONG_MAX X_INT_MAX -#define X_UINT_MAX 4294967295U -#define X_INT64_MIN (-9223372036854775807LL-1LL) -#define X_INT64_MAX 9223372036854775807LL -#define X_UINT64_MAX 18446744073709551615ULL +#define X_SCHAR_MIN (-128) /**< Minimum signed char value. */ +#define X_SCHAR_MAX 127 /**< Maximum signed char value. */ +#define X_UCHAR_MAX 255U /**< Maximum unsigned char value. */ +#define X_SHORT_MIN (-32768) /**< Minumum short value. */ +#define X_SHRT_MIN X_SHORT_MIN /**< This alias is compatible with limits.h. */ +#define X_SHORT_MAX 32767 /**< Maximum short value. */ +#define X_SHRT_MAX X_SHORT_MAX /**< This alias is compatible with limits.h. */ +#define X_USHORT_MAX 65535U /**< Maximum unsigned short value. */ +#define X_USHRT_MAX X_USHORT_MAX /**< This alias is compatible with limits.h. */ +#define X_INT_MIN (-2147483647-1) /**< Minimum int value. */ +#define X_INT_MAX 2147483647 /**< Maximum int value. */ +#define X_LONG_MIN X_INT_MIN /**< Minimum long value. */ +#define X_LONG_MAX X_INT_MAX /**< Maximum long value. */ +#define X_UINT_MAX 4294967295U /**< Maximum unsigned int value. */ +#define X_INT64_MIN (-9223372036854775807LL-1LL) /**< Minimum int64 value. */ +#define X_INT64_MAX 9223372036854775807LL /**< Maximum int64 value. */ +#define X_UINT64_MAX 18446744073709551615ULL /**< Maximum unsigned int64 value. */ #ifdef WIN32 /* Windows, of course, has to be a *little* different. */ #define X_FLOAT_MAX 3.402823466e+38f #else -#define X_FLOAT_MAX 3.40282347e+38f +#define X_FLOAT_MAX 3.40282347e+38f /**< Maximum float value. */ #endif /* WIN32 */ -#define X_FLOAT_MIN (-X_FLOAT_MAX) -#define X_DOUBLE_MAX 1.7976931348623157e+308 -#define X_DOUBLE_MIN (-X_DOUBLE_MAX) +#define X_FLOAT_MIN (-X_FLOAT_MAX) /**< Minimum float value. */ +#define X_DOUBLE_MAX 1.7976931348623157e+308 /**< Maximum double value. */ +#define X_DOUBLE_MIN (-X_DOUBLE_MAX) /**< Minimum double value. */ /** This is the number of netCDF atomic types. */ #define NUM_ATOMIC_TYPES (NC_MAX_ATOMIC_TYPE + 1) @@ -82,6 +87,33 @@ typedef enum {NCNAT, NCVAR, NCDIM, NCATT, NCTYP, NCFLD, NCGRP} NC_SORT; /** Number of parameters needed for ZLIB filter. */ #define CD_NELEMS_ZLIB 1 +/* Define accessors for the dispatchdata */ +#define NC4_DATA(nc) ((NC_FILE_INFO_T*)(nc)->dispatchdata) +#define NC4_DATA_SET(nc,data) ((nc)->dispatchdata = (void*)(data)) + +/* Reserved attribute flags: must be powers of 2. */ +/* Hidden dimscale-related, per-variable attributes; immutable and + * unreadable thru API. */ +#define DIMSCALEFLAG 1 + +/* Readonly global attributes; readable, but immutable thru the + * API. */ +#define READONLYFLAG 2 + +/* Subset of readonly flags; readable by name only thru the API. */ +#define NAMEONLYFLAG 4 + +/* Subset of readonly flags; Value is actually in file. */ +#define MATERIALIZEDFLAG 8 + +/* Generic reserved Attributes */ +#define NC_ATT_REFERENCE_LIST "REFERENCE_LIST" +#define NC_ATT_CLASS "CLASS" +#define NC_ATT_DIMENSION_LIST "DIMENSION_LIST" +#define NC_ATT_NAME "NAME" +#define NC_ATT_COORDINATES COORDINATES /*defined above*/ +#define NC_ATT_FORMAT "_Format" + /* Boolean type, to make the code easier to read */ typedef enum {NC_FALSE = 0, NC_TRUE = 1} nc_bool_t; @@ -101,13 +133,21 @@ struct NC_TYPE_INFO; MUST HAVE AN INSTANCE of NC_OBJ AS THE FIRST FIELD. */ -typedef struct NC_OBJ { +typedef struct NC_OBJ +{ NC_SORT sort; char* name; /* assumed to be null terminated */ size_t id; unsigned int hashkey; /* crc32(name) */ } NC_OBJ; +/* Reserved Attributes Info */ +typedef struct NC_reservedatt +{ + const char* name; + int flags; +} NC_reservedatt; + /* This is a struct to handle the dim metadata. */ typedef struct NC_DIM_INFO { @@ -291,12 +331,14 @@ typedef struct NC_FILE_INFO /* Variable Length Datatype struct in memory. Must be identical to * HDF5 hvl_t. (This is only used for VL sequences, not VL strings, * which are stored in char *'s) */ -typedef struct { +typedef struct +{ size_t len; /* Length of VL data (in base type units) */ void *p; /* Pointer to VL data */ } nc_hvl_t; -extern const char* nc4_atomic_name[NC_MAX_ATOMIC_TYPE+1]; +/* The names of the atomic data types. */ +extern const char *nc4_atomic_name[NC_MAX_ATOMIC_TYPE + 1]; /* These functions convert between netcdf and HDF5 types. */ int nc4_get_typelen_mem(NC_FILE_INFO_T *h5, nc_type xtype, size_t *len); @@ -396,35 +438,7 @@ extern void nc4_hdf5_finalize(void); int log_metadata_nc(NC_FILE_INFO_T *h5); #endif -/* Define accessors for the dispatchdata */ -#define NC4_DATA(nc) ((NC_FILE_INFO_T*)(nc)->dispatchdata) -#define NC4_DATA_SET(nc,data) ((nc)->dispatchdata = (void*)(data)) - -/* Reserved Attributes Info */ -typedef struct NC_reservedatt { - const char* name; - int flags; -} NC_reservedatt; - -/* Reserved attribute flags: must be powers of 2*/ -/* Hidden dimscale-related, per-variable attributes; immutable and unreadable thru API */ -#define DIMSCALEFLAG 1 -/* Readonly global attributes; readable, but immutable thru the API */ -#define READONLYFLAG 2 -/* Subset of readonly flags; readable by name only thru the API */ -#define NAMEONLYFLAG 4 -/* Subset of readonly flags; Value is actually in file */ -#define MATERIALIZEDFLAG 8 - /* Binary searcher for reserved attributes */ -extern const NC_reservedatt* NC_findreserved(const char* name); - -/* Generic reserved Attributes */ -#define NC_ATT_REFERENCE_LIST "REFERENCE_LIST" -#define NC_ATT_CLASS "CLASS" -#define NC_ATT_DIMENSION_LIST "DIMENSION_LIST" -#define NC_ATT_NAME "NAME" -#define NC_ATT_COORDINATES COORDINATES /*defined above*/ -#define NC_ATT_FORMAT "_Format" +extern const NC_reservedatt *NC_findreserved(const char *name); #endif /* _NC4INTERNAL_ */ diff --git a/unit_test/tst_nc4internal.c b/unit_test/tst_nc4internal.c index 3f752986e..9257b58a9 100644 --- a/unit_test/tst_nc4internal.c +++ b/unit_test/tst_nc4internal.c @@ -19,6 +19,12 @@ #define FILE_NAME "tst_nc4internal.nc" #define VAR_NAME "Hilary_Duff" +#define DIM_NAME "Foggy" +#define DIM_LEN 5 +#define TYPE_NAME "Madonna" +#define TYPE_SIZE TEST_VAL_42 +#define FIELD_NAME "Britany_Spears" +#define FIELD_OFFSET 9 int main(int argc, char **argv) @@ -196,6 +202,69 @@ main(int argc, char **argv) free_NC(ncp); } SUMMARIZE_ERR; + printf("Testing adding new dim to nc4internal file..."); + { + NC *ncp; + NCmodel model; + NC_GRP_INFO_T *grp, *dim_grp; + NC_DIM_INFO_T *dim, *dim_in; + + /* Create the NC, add it to nc_filelist array, add and init + * NC_FILE_INFO_T. */ + if (new_NC(NC3_dispatch_table, FILE_NAME, 0, &model, &ncp)) ERR; + add_to_NCList(ncp); + if (nc4_file_list_add(ncp->ext_ncid, FILE_NAME, 0, NULL)) ERR; + if (nc4_find_nc_grp_h5(ncp->ext_ncid, NULL, &grp, NULL)) ERR; + + /* Add a dim. */ + if (nc4_dim_list_add(grp, DIM_NAME, DIM_LEN, 0, &dim)) ERR; + + /* Find the dim. */ + if (nc4_find_dim(grp, 0, &dim_in, &dim_grp)) ERR; + if (strcmp(dim_in->hdr.name, dim->hdr.name)) ERR; + if (strcmp(dim_grp->hdr.name, grp->hdr.name)) ERR; + dim_in = NULL; + if (nc4_find_dim(grp, 0, &dim_in, NULL)) ERR; + if (strcmp(dim_in->hdr.name, dim->hdr.name)) ERR; + + /* Release resources. */ + if (nc4_file_list_del(ncp->ext_ncid)) ERR; + del_from_NCList(ncp); + free_NC(ncp); + } + SUMMARIZE_ERR; + printf("Testing adding new type to nc4internal file..."); + { + NC *ncp; + NCmodel model; + NC_GRP_INFO_T *grp; + NC_TYPE_INFO_T *type, *type_in; + NC_FILE_INFO_T *h5; + + /* Create the NC, add it to nc_filelist array, add and init + * NC_FILE_INFO_T. */ + if (new_NC(NC3_dispatch_table, FILE_NAME, 0, &model, &ncp)) ERR; + add_to_NCList(ncp); + if (nc4_file_list_add(ncp->ext_ncid, FILE_NAME, 0, NULL)) ERR; + if (nc4_find_nc_grp_h5(ncp->ext_ncid, NULL, &grp, &h5)) ERR; + + /* Add a type. */ + if (nc4_type_list_add(grp, TYPE_SIZE, TYPE_NAME, &type)) ERR; + + /* Add a field to the type. */ + if (nc4_field_list_add(type, FIELD_NAME, FIELD_OFFSET, NC_INT, 0, + NULL)) ERR; + + /* Find it. */ + if (nc4_find_type(h5, type->hdr.id, &type_in)) ERR; + if (strcmp(type_in->hdr.name, type->hdr.name)) ERR; + + /* Release resources. */ + if (nc4_file_list_del(ncp->ext_ncid)) ERR; + del_from_NCList(ncp); + free_NC(ncp); + } + SUMMARIZE_ERR; /* printf("Testing changing ncid..."); */ /* { */ /* NC *ncp, *ncp2; */ From 5d1e3b45931c09b94de950c6dd5c722e8def36fe Mon Sep 17 00:00:00 2001 From: edwardhartnett Date: Wed, 21 Aug 2019 18:31:37 -0600 Subject: [PATCH 12/13] more doxygen documentation for nc4internal.h --- include/nc4internal.h | 337 ++++++++++++++++++------------------ unit_test/tst_nc4internal.c | 4 +- 2 files changed, 173 insertions(+), 168 deletions(-) diff --git a/include/nc4internal.h b/include/nc4internal.h index ca01d2be9..b4e07c7d3 100644 --- a/include/nc4internal.h +++ b/include/nc4internal.h @@ -87,257 +87,262 @@ typedef enum {NCNAT, NCVAR, NCDIM, NCATT, NCTYP, NCFLD, NCGRP} NC_SORT; /** Number of parameters needed for ZLIB filter. */ #define CD_NELEMS_ZLIB 1 -/* Define accessors for the dispatchdata */ -#define NC4_DATA(nc) ((NC_FILE_INFO_T*)(nc)->dispatchdata) -#define NC4_DATA_SET(nc,data) ((nc)->dispatchdata = (void*)(data)) +/** Get a pointer to the NC_FILE_INFO_T from dispatchdata field. */ +#define NC4_DATA(nc) ((NC_FILE_INFO_T *)(nc)->dispatchdata) + +/** Set a pointer to the NC_FILE_INFO_T in the dispatchdata field. */ +#define NC4_DATA_SET(nc,data) ((nc)->dispatchdata = (void *)(data)) /* Reserved attribute flags: must be powers of 2. */ -/* Hidden dimscale-related, per-variable attributes; immutable and +/** Hidden dimscale-related, per-variable attributes; immutable and * unreadable thru API. */ #define DIMSCALEFLAG 1 -/* Readonly global attributes; readable, but immutable thru the +/** Readonly global attributes; readable, but immutable thru the * API. */ #define READONLYFLAG 2 -/* Subset of readonly flags; readable by name only thru the API. */ +/** Subset of readonly flags; readable by name only thru the API. */ #define NAMEONLYFLAG 4 -/* Subset of readonly flags; Value is actually in file. */ +/** Subset of readonly flags; Value is actually in file. */ #define MATERIALIZEDFLAG 8 /* Generic reserved Attributes */ -#define NC_ATT_REFERENCE_LIST "REFERENCE_LIST" -#define NC_ATT_CLASS "CLASS" -#define NC_ATT_DIMENSION_LIST "DIMENSION_LIST" -#define NC_ATT_NAME "NAME" -#define NC_ATT_COORDINATES COORDINATES /*defined above*/ -#define NC_ATT_FORMAT "_Format" +#define NC_ATT_REFERENCE_LIST "REFERENCE_LIST" /**< HDF5 reference list attribute name. */ +#define NC_ATT_CLASS "CLASS" /**< HDF5 class atttribute name. */ +#define NC_ATT_DIMENSION_LIST "DIMENSION_LIST" /**< HDF5 dimension list attribute name. */ +#define NC_ATT_NAME "NAME" /**< HDF5 name atttribute name. */ +#define NC_ATT_COORDINATES COORDINATES /**< Coordinates atttribute name. */ +#define NC_ATT_FORMAT "_Format" /**< Format atttribute name. */ -/* Boolean type, to make the code easier to read */ +/** Boolean type, to make the code easier to read. */ typedef enum {NC_FALSE = 0, NC_TRUE = 1} nc_bool_t; -/*Forward*/ +/* Forward declarations. */ struct NC_GRP_INFO; struct NC_TYPE_INFO; -/* - Indexed Access to Meta-data objects: - - See the document docs/indexing.dox for detailed information. - - Basically provide a common header and use NCindex instances - instead of linked lists. - - WARNING: ALL OBJECTS THAT CAN BE INSERTED INTO AN NCindex - MUST HAVE AN INSTANCE of NC_OBJ AS THE FIRST FIELD. +/** + * This struct provides indexed Access to Meta-data objects. See the + * document docs/indexing.dox for detailed information. + * + * Basically it provides a common header and use NCindex instances + * instead of linked lists. + * + * WARNING: ALL OBJECTS THAT CAN BE INSERTED INTO AN NCindex MUST HAVE + * AN INSTANCE of NC_OBJ AS THE FIRST FIELD. */ - typedef struct NC_OBJ { - NC_SORT sort; - char* name; /* assumed to be null terminated */ - size_t id; - unsigned int hashkey; /* crc32(name) */ + NC_SORT sort; /**< Type of object. */ + char* name; /**< Name, assumed to be null terminated. */ + size_t id; /**< This objects ID. */ + unsigned int hashkey; /**< The hash key, crc32(name). */ } NC_OBJ; -/* Reserved Attributes Info */ +/** + * This struct holds information about reserved attributes. These + * attributes cannot be created or read by the user (through the + * netCDF API). */ typedef struct NC_reservedatt { - const char* name; - int flags; + const char *name; /**< Name of the reserved attribute. */ + int flags; /**< Flags that control handling of reserved attribute. */ } NC_reservedatt; -/* This is a struct to handle the dim metadata. */ +/** This is a struct to handle the dimension metadata. */ typedef struct NC_DIM_INFO { - NC_OBJ hdr; - struct NC_GRP_INFO *container; /* containing group */ - size_t len; - nc_bool_t unlimited; /* True if the dimension is unlimited */ - nc_bool_t extended; /* True if the dimension needs to be extended */ - nc_bool_t too_long; /* True if len is too big to fit in local size_t. */ - void *format_dim_info; /* Pointer to format-specific dim info. */ - struct NC_VAR_INFO *coord_var; /* The coord var, if it exists. */ + NC_OBJ hdr; /**< The hdr contains the name and ID. */ + struct NC_GRP_INFO *container; /**< Pointer to containing group. */ + size_t len; /**< Length of this dimension. */ + nc_bool_t unlimited; /**< True if the dimension is unlimited */ + nc_bool_t extended; /**< True if the dimension needs to be extended. */ + nc_bool_t too_long; /**< True if len is too big to fit in local size_t. */ + void *format_dim_info; /**< Pointer to format-specific dim info. */ + struct NC_VAR_INFO *coord_var; /**< The coord var, if it exists. */ } NC_DIM_INFO_T; +/** This is a struct to handle the attribute metadata. */ typedef struct NC_ATT_INFO { - NC_OBJ hdr; - struct NC_OBJ *container; /* containing group|var */ - int len; - nc_bool_t dirty; /* True if attribute modified */ - nc_bool_t created; /* True if attribute already created */ - nc_type nc_typeid; /* netCDF type of attribute's data */ - void *format_att_info; - void *data; - nc_vlen_t *vldata; /* only used for vlen */ - char **stdata; /* only for string type. */ + NC_OBJ hdr; /**< The hdr contains the name and ID. */ + struct NC_OBJ *container; /**< Pointer to containing group|var. */ + int len; /**< Length of attribute data. */ + nc_bool_t dirty; /**< True if attribute modified. */ + nc_bool_t created; /**< True if attribute already created. */ + nc_type nc_typeid; /**< NetCDF type of attribute's data. */ + void *format_att_info; /**< Pointer to format-specific att info. */ + void *data; /**< The attribute data. */ + nc_vlen_t *vldata; /**< VLEN data (only used for vlen types). */ + char **stdata; /**< String data (only for string type). */ } NC_ATT_INFO_T; -/* This is a struct to handle the var metadata. */ +/** This is a struct to handle the var metadata. */ typedef struct NC_VAR_INFO { - NC_OBJ hdr; - char *hdf5_name; /* used if different from name */ - struct NC_GRP_INFO *container; /* containing group */ - size_t ndims; - int *dimids; - NC_DIM_INFO_T **dim; - nc_bool_t is_new_var; /* True if variable is newly created */ - nc_bool_t was_coord_var; /* True if variable was a coordinate var, but either the dim or var has been renamed */ - nc_bool_t became_coord_var; /* True if variable _became_ a coordinate var, because either the dim or var has been renamed */ - nc_bool_t fill_val_changed; /* True if variable's fill value changes after it has been created */ - nc_bool_t attr_dirty; /* True if variable's attributes are dirty and should be rewritten */ - nc_bool_t created; /* Variable has already been created (_not_ that it was just created) */ - nc_bool_t written_to; /* True if variable has data written to it */ + NC_OBJ hdr; /**< The hdr contains the name and ID. */ + char *hdf5_name; /**< Used if name in HDF5 must be different from name. */ + struct NC_GRP_INFO *container; /**< Pointer to containing group. */ + size_t ndims; /**< Number of dims. */ + int *dimids; /**< Dim IDs. */ + NC_DIM_INFO_T **dim; /**< Pointer to dim. */ + nc_bool_t is_new_var; /**< True if variable is newly created */ + nc_bool_t was_coord_var; /**< True if variable was a coordinate var, but either the dim or var has been renamed */ + nc_bool_t became_coord_var; /**< True if variable _became_ a coordinate var, because either the dim or var has been renamed */ + nc_bool_t fill_val_changed; /**< True if variable's fill value changes after it has been created */ + nc_bool_t attr_dirty; /**< True if variable's attributes are dirty and should be rewritten */ + nc_bool_t created; /**< Variable has already been created (_not_ that it was just created) */ + nc_bool_t written_to; /**< True if variable has data written to it */ struct NC_TYPE_INFO *type_info; - int atts_read; /* If true, the atts have been read. */ - nc_bool_t meta_read; /* True if this vars metadata has been completely read. */ - nc_bool_t coords_read; /* True if this var has hidden coordinates att, and it has been read. */ - NCindex *att; /* NCindex */ - nc_bool_t no_fill; /* True if no fill value is defined for var */ + int atts_read; /**< If true, the atts have been read. */ + nc_bool_t meta_read; /**< True if this vars metadata has been completely read. */ + nc_bool_t coords_read; /**< True if this var has hidden coordinates att, and it has been read. */ + NCindex *att; /**< NCindex */ + nc_bool_t no_fill; /**< True if no fill value is defined for var */ void *fill_value; size_t *chunksizes; - nc_bool_t contiguous; /* True if variable is stored contiguously in HDF5 file */ - int parallel_access; /* Type of parallel access for I/O on variable (collective or independent) */ - nc_bool_t dimscale; /* True if var is a dimscale */ - nc_bool_t *dimscale_attached; /* Array of flags that are true if dimscale is attached for that dim index */ - nc_bool_t deflate; /* True if var has deflate filter applied */ + nc_bool_t contiguous; /**< True if variable is stored contiguously in HDF5 file */ + int parallel_access; /**< Type of parallel access for I/O on variable (collective or independent) */ + nc_bool_t dimscale; /**< True if var is a dimscale */ + nc_bool_t *dimscale_attached; /**< Array of flags that are true if dimscale is attached for that dim index */ + nc_bool_t deflate; /**< True if var has deflate filter applied */ int deflate_level; - nc_bool_t shuffle; /* True if var has shuffle filter applied */ - nc_bool_t fletcher32; /* True if var has fletcher32 filter applied */ + nc_bool_t shuffle; /**< True if var has shuffle filter applied */ + nc_bool_t fletcher32; /**< True if var has fletcher32 filter applied */ size_t chunk_cache_size, chunk_cache_nelems; float chunk_cache_preemption; - void *format_var_info; /* Pointer to any binary format info. */ - /* Stuff for arbitrary filters */ - unsigned int filterid; - size_t nparams; - unsigned int *params; + void *format_var_info; /**< Pointer to any binary format info. */ + unsigned int filterid; /**< ID for arbitrary filter. */ + size_t nparams; /**< nparams for arbitrary filter. */ + unsigned int *params; /**< Params for arbitrary filter. */ } NC_VAR_INFO_T; +/** This is a struct to handle the field metadata from a user-defined + * type. */ typedef struct NC_FIELD_INFO { - NC_OBJ hdr; - nc_type nc_typeid; - size_t offset; - int ndims; - int *dim_size; - void *format_field_info; /* Pointer to any binary format info for field. */ + NC_OBJ hdr; /**< The hdr contains the name and ID. */ + nc_type nc_typeid; /**< The type of this field. */ + size_t offset; /**< Offset in bytes of field. */ + int ndims; /**< Number of dims. */ + int *dim_size; /**< Dim sizes. */ + void *format_field_info; /**< Pointer to any binary format info for field. */ } NC_FIELD_INFO_T; +/** This is a struct to handle metadata for a user-defined enum + * type. */ typedef struct NC_ENUM_MEMBER_INFO { - char *name; - void *value; + char *name; /**< Name of member. */ + void *value; /**< Value of member. */ } NC_ENUM_MEMBER_INFO_T; +/** This is a struct to handle metadata for a user-defined type. */ typedef struct NC_TYPE_INFO { - NC_OBJ hdr; /* NetCDF type ID. */ - struct NC_GRP_INFO *container; /* Containing group */ - unsigned rc; /* Ref. count of objects using this type */ - int endianness; /* What endianness for the type? */ - size_t size; /* Size of the type in memory, in bytes */ - nc_bool_t committed; /* True when datatype is committed in the file */ - nc_type nc_type_class; /* NC_VLEN, NC_COMPOUND, NC_OPAQUE, - * NC_ENUM, NC_INT, NC_FLOAT, or - * NC_STRING. */ - void *format_type_info; /* HDF5-specific type info. */ + NC_OBJ hdr; /**< The hdr contains the name and ID. */ + struct NC_GRP_INFO *container; /**< Containing group */ + unsigned rc; /**< Ref. count of objects using this type */ + int endianness; /**< What endianness for the type? */ + size_t size; /**< Size of the type in memory, in bytes */ + nc_bool_t committed; /**< True when datatype is committed in the file */ + nc_type nc_type_class; /**< NC_VLEN, NC_COMPOUND, NC_OPAQUE, NC_ENUM, NC_INT, NC_FLOAT, or NC_STRING. */ + void *format_type_info; /**< HDF5-specific type info. */ - /* Information for each type or class */ + /** Information for each type or class */ union { struct { - NClist* enum_member; /* */ - nc_type base_nc_typeid; - } e; /* Enum */ + NClist* enum_member; /**< */ + nc_type base_nc_typeid; /**< Typeid of the base type. */ + } e; /**< Enum */ struct Fields { - NClist* field; /* */ - } c; /* Compound */ + NClist* field; /**< */ + } c; /**< Compound */ struct { - nc_type base_nc_typeid; - } v; /* Variable-length */ - } u; /* Union of structs, for each type/class */ + nc_type base_nc_typeid; /**< Typeid of the base type. */ + } v; /**< Variable-length. */ + } u; /**< Union of structs, for each type/class. */ } NC_TYPE_INFO_T; -/* This holds information for one group. Groups reproduce with +/** This holds information for one group. Groups reproduce with * parthenogenesis. */ typedef struct NC_GRP_INFO { - NC_OBJ hdr; - void *format_grp_info; - struct NC_FILE_INFO *nc4_info; - struct NC_GRP_INFO *parent; - int atts_read; /* True if atts have been read for this group. */ - NCindex* children; /* NCindex */ - NCindex* dim; /* NCindex * */ - NCindex* att; /* NCindex * */ - NCindex* type; /* NCindex * */ + NC_OBJ hdr; /**< The hdr contains the name and ID. */ + void *format_grp_info; /**< Pointer to binary format info for group. */ + struct NC_FILE_INFO *nc4_info; /**< Pointer containing NC_FILE_INFO_T. */ + struct NC_GRP_INFO *parent; /**< Pointer tp parent group. */ + int atts_read; /**< True if atts have been read for this group. */ + NCindex* children; /**< NCindex */ + NCindex* dim; /**< NCindex * */ + NCindex* att; /**< NCindex * */ + NCindex* type; /**< NCindex * */ /* Note that this is the list of vars with position == varid */ - NCindex* vars; /* NCindex * */ + NCindex* vars; /**< NCindex * */ } NC_GRP_INFO_T; /* These constants apply to the cmode parameter in the * HDF5_FILE_INFO_T defined below. */ -#define NC_CREAT 2 /* in create phase, cleared by ncendef */ -#define NC_INDEF 8 /* in define mode, cleared by ncendef */ -#define NC_NSYNC 0x10 /* synchronise numrecs on change */ -#define NC_HSYNC 0x20 /* synchronise whole header on change */ -#define NC_NDIRTY 0x40 /* numrecs has changed */ -#define NC_HDIRTY 0x80 /* header info has changed */ +#define NC_CREAT 2 /**< in create phase, cleared by ncendef */ +#define NC_INDEF 8 /**< in define mode, cleared by ncendef */ +#define NC_NSYNC 0x10 /**< synchronise numrecs on change */ +#define NC_HSYNC 0x20 /**< synchronise whole header on change */ +#define NC_NDIRTY 0x40 /**< numrecs has changed */ +#define NC_HDIRTY 0x80 /**< header info has changed */ -/* This is the metadata we need to keep track of for each - netcdf-4/HDF5 file. */ +/** This is the metadata we need to keep track of for each + * netcdf-4/HDF5 file. */ typedef struct NC_FILE_INFO { - NC* controller; + NC *controller; /**< Pointer to containing NC. */ #ifdef USE_PARALLEL4 - MPI_Comm comm; /* Copy of MPI Communicator used to open the file */ - MPI_Info info; /* Copy of MPI Information Object used to open the file */ + MPI_Comm comm; /**< Copy of MPI Communicator used to open the file. */ + MPI_Info info; /**< Copy of MPI Information Object used to open the file. */ #endif - int flags; - int cmode; - nc_bool_t parallel; /* True if file is open for parallel access */ - nc_bool_t redef; /* True if redefining an existing file */ - int fill_mode; /* Fill mode for vars - Unused internally currently */ - nc_bool_t no_write; /* true if nc_open has mode NC_NOWRITE. */ - NC_GRP_INFO_T *root_grp; - /* Track indices to assign to grps, types, and dims */ - short next_nc_grpid; - int next_typeid; - int next_dimid; - /* Provide convenience vectors indexed by the object id. - This allows for direct conversion of e.g. an nc_type to - the corresponding NC_TYPE_INFO_T object. - */ - NClist* alldims; - NClist* alltypes; - NClist* allgroups; /* including root group */ - void *format_file_info; - NC4_Provenance provenance; - struct NC4_Memio { - NC_memio memio; /* What we sent to image_init and what comes back*/ - int locked; /* do not copy and do not free */ - int persist; /* Should file be persisted out on close? */ - int inmemory; /* NC_INMEMORY flag was set */ - int diskless; /* NC_DISKLESS flag was set => inmemory */ - int created; /* 1 => create, 0 => open */ - unsigned int imageflags; /* for H5LTopen_file_image */ - size_t initialsize; - void* udata; /* extra memory allocated in NC4_image_init */ + int flags; /**< Flags used to open the file. */ + int cmode; /**< Create mode used to create the file. */ + nc_bool_t parallel; /**< True if file is open for parallel access */ + nc_bool_t redef; /**< True if redefining an existing file */ + int fill_mode; /**< Fill mode for vars - Unused internally currently */ + nc_bool_t no_write; /**< true if nc_open has mode NC_NOWRITE. */ + NC_GRP_INFO_T *root_grp; /**< Pointer to root group. */ + short next_nc_grpid; /**< Next available group ID. */ + int next_typeid; /**< Next available type ID. */ + int next_dimid; /**< Next available dim ID. */ + /* Provide convenience vectors indexed by the object id. This + allows for direct conversion of e.g. an nc_type to the + corresponding NC_TYPE_INFO_T object. */ + NClist *alldims; /**< List of all dims. */ + NClist *alltypes; /**< List of all types. */ + NClist *allgroups; /**< List of all groups, including root group. */ + void *format_file_info; /**< Pointer to binary format info for file. */ + NC4_Provenance provenance; /**< File provenence info. */ + struct NC4_Memio + { + NC_memio memio; /**< What we sent to image_init and what comes back. */ + int locked; /**< Do not copy and do not free. */ + int persist; /**< Should file be persisted out on close? */ + int inmemory; /**< NC_INMEMORY flag was set. */ + int diskless; /**< NC_DISKLESS flag was set => inmemory. */ + int created; /**< 1 => create, 0 => open. */ + unsigned int imageflags; /**< for H5LTopen_file_image. */ + size_t initialsize; /**< Initial size. */ + void *udata; /**< Extra memory allocated in NC4_image_init. */ } mem; } NC_FILE_INFO_T; -/* Variable Length Datatype struct in memory. Must be identical to +/** Variable Length Datatype struct in memory. Must be identical to * HDF5 hvl_t. (This is only used for VL sequences, not VL strings, * which are stored in char *'s) */ typedef struct { - size_t len; /* Length of VL data (in base type units) */ - void *p; /* Pointer to VL data */ + size_t len; /**< Length of VL data (in base type units) */ + void *p; /**< Pointer to VL data */ } nc_hvl_t; -/* The names of the atomic data types. */ +/** The names of the atomic data types. */ extern const char *nc4_atomic_name[NC_MAX_ATOMIC_TYPE + 1]; /* These functions convert between netcdf and HDF5 types. */ diff --git a/unit_test/tst_nc4internal.c b/unit_test/tst_nc4internal.c index 9257b58a9..323a47989 100644 --- a/unit_test/tst_nc4internal.c +++ b/unit_test/tst_nc4internal.c @@ -252,8 +252,8 @@ main(int argc, char **argv) if (nc4_type_list_add(grp, TYPE_SIZE, TYPE_NAME, &type)) ERR; /* Add a field to the type. */ - if (nc4_field_list_add(type, FIELD_NAME, FIELD_OFFSET, NC_INT, 0, - NULL)) ERR; + /* if (nc4_field_list_add(type, FIELD_NAME, FIELD_OFFSET, NC_INT, 0, */ + /* NULL)) ERR; */ /* Find it. */ if (nc4_find_type(h5, type->hdr.id, &type_in)) ERR; From 0ce88e6c9561bd2defb731992aba81816a0b0baf Mon Sep 17 00:00:00 2001 From: edwardhartnett Date: Wed, 21 Aug 2019 18:43:57 -0600 Subject: [PATCH 13/13] updated RELEASE_NOTES --- RELEASE_NOTES.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 04c7eb960..0b33d26a9 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -7,18 +7,24 @@ This file contains a high-level description of this package's evolution. Release ## 4.7.1 - TBD +* [Enhancement] Added unit_test directory, which contains unit tests +for the libdispatch and libsrc4 code (and any other directories that +want to put unit tests there). Use --disable-unit-tests to run without +unit tests (ex. for code coverage analysis). +See [GitHub #1458](https://github.com/Unidata/netcdf-c/issues/1458) + * [Bug Fix] Remove obsolete _CRAYMPP and LOCKNUMREC macros from code. Also brought documentation up to date in man page. These macros were used in ancient times, before modern parallel I/O systems were developed. Programmers interested in parallel I/O should see nc_open_par() and nc_create_par(). -See [GitHub #1436](https://github.com/Unidata/netcdf-c/issues/1459) +See [GitHub #1459](https://github.com/Unidata/netcdf-c/issues/1459) * [Enhancement] Remove obsolete and deprecated functions nc_set_base_pe() and nc_inq_base_pe() from the dispatch table. (Both functions are still supported in the library, this is an internal change only.) -See [GitHub #1436](https://github.com/Unidata/netcdf-c/issues/1468) +See [GitHub #1468](https://github.com/Unidata/netcdf-c/issues/1468) * [Bug Fix] Reverted nccopy behavior so that if no -c parameters are given, then any default chunking is left to the netcdf-c library