From 2ba7a01bfff451b043e2ec00811c0aad78921545 Mon Sep 17 00:00:00 2001 From: jhendersonHDF Date: Sun, 1 May 2022 15:54:41 -0500 Subject: Fix some const cast and stack/static object size warnings (#1700) * Fix various warnings * Move HDfree_const to H5private.h for wider use * Print output from all ranks in parallel tests on allocation failure * Move const pointer freeing macro to h5test.h for now --- src/H5Dchunk.c | 12 +++---- src/H5Dmpio.c | 6 ++-- src/H5Dpkg.h | 2 +- src/H5Shyper.c | 9 +++-- src/H5Smpio.c | 93 ++++++++++++++++++++++++++++++++------------------- src/H5Sprivate.h | 2 +- src/H5Tconv.c | 4 +-- src/H5Tpkg.h | 2 +- src/H5Tref.c | 9 +++++ src/H5Tvlen.c | 16 ++++----- test/h5test.h | 9 +++++ test/vds_env.c | 51 +++++++++++++++++++++------- test/vfd.c | 16 ++++----- testpar/t_2Gio.c | 20 +++++++++-- testpar/t_cache.c | 34 +++++++++++++++---- testpar/t_mdset.c | 6 ++++ testpar/t_mpi.c | 34 ++++++++++++------- testpar/t_pflush1.c | 15 +++++++-- testpar/t_pflush2.c | 18 ++++++++-- testpar/t_shapesame.c | 17 ++++++++-- testpar/testphdf5.c | 17 ++++++++-- 21 files changed, 282 insertions(+), 110 deletions(-) diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 1d4b215..2075498 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -8089,13 +8089,13 @@ H5D__chunk_iter_cb(const H5D_chunk_rec_t *chunk_rec, void *udata) *------------------------------------------------------------------------- */ herr_t -H5D__chunk_iter(const H5D_t *dset, H5D_chunk_iter_op_t op, void *op_data) +H5D__chunk_iter(H5D_t *dset, H5D_chunk_iter_op_t op, void *op_data) { - const H5O_layout_t *layout = NULL; /* Dataset layout */ - const H5D_rdcc_t * rdcc = NULL; /* Raw data chunk cache */ - H5D_rdcc_ent_t * ent; /* Cache entry index */ - H5D_chk_idx_info_t idx_info; /* Chunked index info */ - herr_t ret_value = SUCCEED; /* Return value */ + const H5D_rdcc_t * rdcc = NULL; /* Raw data chunk cache */ + H5O_layout_t * layout = NULL; /* Dataset layout */ + H5D_rdcc_ent_t * ent; /* Cache entry index */ + H5D_chk_idx_info_t idx_info; /* Chunked index info */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE_TAG(dset->oloc.addr) diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c index a7908fe..0620459 100644 --- a/src/H5Dmpio.c +++ b/src/H5Dmpio.c @@ -302,7 +302,7 @@ static herr_t H5D__link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_ty static herr_t H5D__link_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, H5D_chunk_map_t *fm, int mpi_rank, int mpi_size); static herr_t H5D__inter_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, - const H5S_t *file_space, const H5S_t *mem_space); + H5S_t *file_space, H5S_t *mem_space); static herr_t H5D__final_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, MPI_Datatype mpi_file_type, MPI_Datatype mpi_buf_type); static herr_t H5D__sort_chunk(H5D_io_info_t *io_info, const H5D_chunk_map_t *fm, @@ -2372,8 +2372,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5D__inter_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, const H5S_t *file_space, - const H5S_t *mem_space) +H5D__inter_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, H5S_t *file_space, + H5S_t *mem_space) { int mpi_buf_count; /* # of MPI types */ hbool_t mbt_is_derived = FALSE; diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 724f3ce..3df9dde 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -566,7 +566,7 @@ H5_DLL herr_t H5D__get_chunk_info(const H5D_t *dset, const H5S_t *space, hsize_ unsigned *filter_mask, haddr_t *offset, hsize_t *size); H5_DLL herr_t H5D__get_chunk_info_by_coord(const H5D_t *dset, const hsize_t *coord, unsigned *filter_mask, haddr_t *addr, hsize_t *size); -H5_DLL herr_t H5D__chunk_iter(const H5D_t *dset, H5D_chunk_iter_op_t cb, void *op_data); +H5_DLL herr_t H5D__chunk_iter(H5D_t *dset, H5D_chunk_iter_op_t cb, void *op_data); H5_DLL haddr_t H5D__get_offset(const H5D_t *dset); H5_DLL herr_t H5D__vlen_get_buf_size(H5D_t *dset, hid_t type_id, hid_t space_id, hsize_t *size); H5_DLL herr_t H5D__vlen_get_buf_size_gen(H5VL_object_t *vol_obj, hid_t type_id, hid_t space_id, diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 7b87d7b..86aaef2 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -160,7 +160,7 @@ static herr_t H5S__hyper_iter_get_seq_list_opt(H5S_sel_iter_t *iter, size_t max static herr_t H5S__hyper_iter_get_seq_list_single(H5S_sel_iter_t *iter, size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem, hsize_t *off, size_t *len); static herr_t H5S__hyper_proj_int_build_proj(H5S_hyper_project_intersect_ud_t *udata); -static herr_t H5S__hyper_proj_int_iterate(const H5S_hyper_span_info_t *ss_span_info, +static herr_t H5S__hyper_proj_int_iterate(H5S_hyper_span_info_t * ss_span_info, const H5S_hyper_span_info_t *sis_span_info, hsize_t count, unsigned depth, H5S_hyper_project_intersect_ud_t *udata); static void H5S__hyper_get_clip_diminfo(hsize_t start, hsize_t stride, hsize_t *count, hsize_t *block, @@ -11332,9 +11332,8 @@ sis_span_info unsigned depth; IN: Depth of iteration (in terms of rank) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S__hyper_proj_int_iterate(const H5S_hyper_span_info_t *ss_span_info, - const H5S_hyper_span_info_t *sis_span_info, hsize_t count, unsigned depth, - H5S_hyper_project_intersect_ud_t *udata) +H5S__hyper_proj_int_iterate(H5S_hyper_span_info_t *ss_span_info, const H5S_hyper_span_info_t *sis_span_info, + hsize_t count, unsigned depth, H5S_hyper_project_intersect_ud_t *udata) { const H5S_hyper_span_t *ss_span; /* Current span in source space */ const H5S_hyper_span_t *sis_span; /* Current span in source intersect space */ @@ -11597,7 +11596,7 @@ H5S__hyper_project_intersection(H5S_t *src_space, H5S_t *dst_space, H5S_t *src_i H5S_t *proj_space, hbool_t share_selection) { H5S_hyper_project_intersect_ud_t udata; /* User data for subroutines */ - const H5S_hyper_span_info_t * ss_span_info; + H5S_hyper_span_info_t * ss_span_info; const H5S_hyper_span_info_t * ds_span_info; H5S_hyper_span_info_t * ss_span_info_buf = NULL; H5S_hyper_span_info_t * ds_span_info_buf = NULL; diff --git a/src/H5Smpio.c b/src/H5Smpio.c index 0c14129..a9108a5 100644 --- a/src/H5Smpio.c +++ b/src/H5Smpio.c @@ -73,10 +73,10 @@ static herr_t H5S__mpio_create_point_datatype(size_t elmt_size, hsize_t num_poin static herr_t H5S__mpio_point_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type, int *count, hbool_t *is_derived_type, hbool_t do_permute, hsize_t **permute_map, hbool_t *is_permuted); -static herr_t H5S__mpio_permute_type(const H5S_t *space, size_t elmt_size, hsize_t **permute_map, +static herr_t H5S__mpio_permute_type(H5S_t *space, size_t elmt_size, hsize_t **permute_map, MPI_Datatype *new_type, int *count, hbool_t *is_derived_type); -static herr_t H5S__mpio_reg_hyper_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type, - int *count, hbool_t *is_derived_type); +static herr_t H5S__mpio_reg_hyper_type(H5S_t *space, size_t elmt_size, MPI_Datatype *new_type, int *count, + hbool_t *is_derived_type); static herr_t H5S__mpio_span_hyper_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type, int *count, hbool_t *is_derived_type); static herr_t H5S__release_datatype(H5S_mpio_mpitype_list_t *type_list); @@ -95,6 +95,9 @@ static herr_t H5S__obtain_datatype(H5S_hyper_span_info_t *spans, const hsize_t * /* Declare a free list to manage the H5S_mpio_mpitype_node_t struct */ H5FL_DEFINE_STATIC(H5S_mpio_mpitype_node_t); +/* Declare a free list to manage dataspace selection iterators */ +H5FL_EXTERN(H5S_sel_iter_t); + /*------------------------------------------------------------------------- * Function: H5S__mpio_all_type * @@ -501,17 +504,19 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5S__mpio_permute_type(const H5S_t *space, size_t elmt_size, hsize_t **permute, MPI_Datatype *new_type, - int *count, hbool_t *is_derived_type) +H5S__mpio_permute_type(H5S_t *space, size_t elmt_size, hsize_t **permute, MPI_Datatype *new_type, int *count, + hbool_t *is_derived_type) { - MPI_Aint * disp = NULL; /* Datatype displacement for each point*/ - H5S_sel_iter_t sel_iter; /* Selection iteration info */ - hbool_t sel_iter_init = FALSE; /* Selection iteration info has been initialized */ - hssize_t snum_points; /* Signed number of elements in selection */ - hsize_t num_points; /* Number of points in the selection */ - size_t max_elem; /* Maximum number of elements allowed in sequences */ - hsize_t u; /* Local index variable */ - herr_t ret_value = SUCCEED; /* Return value */ + MPI_Aint * disp = NULL; /* Datatype displacement for each point*/ + H5S_sel_iter_t *sel_iter = NULL; /* Selection iteration info */ + hbool_t sel_iter_init = FALSE; /* Selection iteration info has been initialized */ + hssize_t snum_points; /* Signed number of elements in selection */ + hsize_t num_points; /* Number of points in the selection */ + hsize_t * off = NULL; + size_t * len = NULL; + size_t max_elem; /* Maximum number of elements allowed in sequences */ + hsize_t u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -527,8 +532,18 @@ H5S__mpio_permute_type(const H5S_t *space, size_t elmt_size, hsize_t **permute, if (NULL == (disp = (MPI_Aint *)H5MM_malloc(sizeof(MPI_Aint) * num_points))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of displacements") + /* Allocate arrays to hold sequence offsets and lengths */ + if (NULL == (off = H5MM_malloc(H5D_IO_VECTOR_SIZE * sizeof(*off)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate sequence offsets array") + if (NULL == (len = H5MM_malloc(H5D_IO_VECTOR_SIZE * sizeof(*len)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate sequence lengths array") + + /* Allocate a selection iterator for iterating over the dataspace */ + if (NULL == (sel_iter = H5FL_MALLOC(H5S_sel_iter_t))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "couldn't allocate dataspace selection iterator") + /* Initialize selection iterator */ - if (H5S_select_iter_init(&sel_iter, space, elmt_size, 0) < 0) + if (H5S_select_iter_init(sel_iter, space, elmt_size, 0) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") sel_iter_init = TRUE; /* Selection iteration info has been initialized */ @@ -538,14 +553,12 @@ H5S__mpio_permute_type(const H5S_t *space, size_t elmt_size, hsize_t **permute, /* Loop, while elements left in selection */ u = 0; while (max_elem > 0) { - hsize_t off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets */ - size_t len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths */ - size_t nelem; /* Number of elements used in sequences */ - size_t nseq; /* Number of sequences generated */ - size_t curr_seq; /* Current sequence being worked on */ + size_t nelem; /* Number of elements used in sequences */ + size_t nseq; /* Number of sequences generated */ + size_t curr_seq; /* Current sequence being worked on */ /* Get the sequences of bytes */ - if (H5S_SELECT_ITER_GET_SEQ_LIST(&sel_iter, (size_t)H5D_IO_VECTOR_SIZE, max_elem, &nseq, &nelem, off, + if (H5S_SELECT_ITER_GET_SEQ_LIST(sel_iter, (size_t)H5D_IO_VECTOR_SIZE, max_elem, &nseq, &nelem, off, len) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") @@ -602,9 +615,14 @@ H5S__mpio_permute_type(const H5S_t *space, size_t elmt_size, hsize_t **permute, done: /* Release selection iterator */ - if (sel_iter_init) - if (H5S_SELECT_ITER_RELEASE(&sel_iter) < 0) + if (sel_iter) { + if (sel_iter_init && H5S_SELECT_ITER_RELEASE(sel_iter) < 0) HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator") + sel_iter = H5FL_FREE(H5S_sel_iter_t, sel_iter); + } + + H5MM_free(len); + H5MM_free(off); /* Free memory */ if (disp) @@ -634,11 +652,11 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5S__mpio_reg_hyper_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type, int *count, +H5S__mpio_reg_hyper_type(H5S_t *space, size_t elmt_size, MPI_Datatype *new_type, int *count, hbool_t *is_derived_type) { - H5S_sel_iter_t sel_iter; /* Selection iteration info */ - hbool_t sel_iter_init = FALSE; /* Selection iteration info has been initialized */ + H5S_sel_iter_t *sel_iter = NULL; /* Selection iteration info */ + hbool_t sel_iter_init = FALSE; /* Selection iteration info has been initialized */ struct dim { /* less hassle than malloc/free & ilk */ hssize_t start; @@ -668,32 +686,37 @@ H5S__mpio_reg_hyper_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new HDassert(sizeof(MPI_Aint) >= sizeof(elmt_size)); bigio_count = H5_mpi_get_bigio_count(); + + /* Allocate a selection iterator for iterating over the dataspace */ + if (NULL == (sel_iter = H5FL_MALLOC(H5S_sel_iter_t))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "couldn't allocate dataspace selection iterator") + /* Initialize selection iterator */ - if (H5S_select_iter_init(&sel_iter, space, elmt_size, 0) < 0) + if (H5S_select_iter_init(sel_iter, space, elmt_size, 0) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") sel_iter_init = TRUE; /* Selection iteration info has been initialized */ /* Abbreviate args */ - diminfo = sel_iter.u.hyp.diminfo; + diminfo = sel_iter->u.hyp.diminfo; HDassert(diminfo); /* Make a local copy of the dimension info so we can operate with them */ /* Check if this is a "flattened" regular hyperslab selection */ - if (sel_iter.u.hyp.iter_rank != 0 && sel_iter.u.hyp.iter_rank < space->extent.rank) { + if (sel_iter->u.hyp.iter_rank != 0 && sel_iter->u.hyp.iter_rank < space->extent.rank) { /* Flattened selection */ - rank = sel_iter.u.hyp.iter_rank; + rank = sel_iter->u.hyp.iter_rank; #ifdef H5S_DEBUG if (H5DEBUG(S)) HDfprintf(H5DEBUG(S), "%s: Flattened selection\n", __func__); #endif for (u = 0; u < rank; ++u) { H5_CHECK_OVERFLOW(diminfo[u].start, hsize_t, hssize_t) - d[u].start = (hssize_t)diminfo[u].start + sel_iter.u.hyp.sel_off[u]; + d[u].start = (hssize_t)diminfo[u].start + sel_iter->u.hyp.sel_off[u]; d[u].strid = diminfo[u].stride; d[u].block = diminfo[u].block; d[u].count = diminfo[u].count; - d[u].xtent = sel_iter.u.hyp.size[u]; + d[u].xtent = sel_iter->u.hyp.size[u]; #ifdef H5S_DEBUG if (H5DEBUG(S)) { @@ -951,9 +974,11 @@ H5S__mpio_reg_hyper_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new done: /* Release selection iterator */ - if (sel_iter_init) - if (H5S_SELECT_ITER_RELEASE(&sel_iter) < 0) + if (sel_iter) { + if (sel_iter_init && H5S_SELECT_ITER_RELEASE(sel_iter) < 0) HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator") + sel_iter = H5FL_FREE(H5S_sel_iter_t, sel_iter); + } #ifdef H5S_DEBUG if (H5DEBUG(S)) @@ -1364,7 +1389,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5S_mpio_space_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type, int *count, +H5S_mpio_space_type(H5S_t *space, size_t elmt_size, MPI_Datatype *new_type, int *count, hbool_t *is_derived_type, hbool_t do_permute, hsize_t **permute_map, hbool_t *is_permuted) { herr_t ret_value = SUCCEED; /* Return value */ diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 4c997b1..2c31ba9 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -299,7 +299,7 @@ H5_DLL herr_t H5S_select_iter_release(H5S_sel_iter_t *sel_iter); H5_DLL herr_t H5S_sel_iter_close(H5S_sel_iter_t *sel_iter); #ifdef H5_HAVE_PARALLEL -H5_DLL herr_t H5S_mpio_space_type(const H5S_t *space, size_t elmt_size, +H5_DLL herr_t H5S_mpio_space_type(H5S_t *space, size_t elmt_size, /* out: */ MPI_Datatype *new_type, int *count, hbool_t *is_derived_type, hbool_t do_permute, hsize_t **permute_map, hbool_t *is_permuted); #endif /* H5_HAVE_PARALLEL */ diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 26ecff5..da98182 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -3406,8 +3406,8 @@ H5T__conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, si /* For nested VL case, free leftover heap objects from the deeper level if the * length of new data elements is shorter than the old data elements.*/ if (nested && seq_len < bg_seq_len) { - const uint8_t *tmp; - size_t u; + uint8_t *tmp; + size_t u; /* Sanity check */ HDassert(write_to_file); diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index 72afbeb..520b44d 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -287,7 +287,7 @@ typedef herr_t (*H5T_vlen_setnull_func_t)(H5VL_object_t *file, void *_vl, void * typedef herr_t (*H5T_vlen_read_func_t)(H5VL_object_t *file, void *_vl, void *buf, size_t len); typedef herr_t (*H5T_vlen_write_func_t)(H5VL_object_t *file, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *buf, void *_bg, size_t seq_len, size_t base_size); -typedef herr_t (*H5T_vlen_delete_func_t)(H5VL_object_t *file, const void *_vl); +typedef herr_t (*H5T_vlen_delete_func_t)(H5VL_object_t *file, void *_vl); /* VL datatype callbacks */ typedef struct H5T_vlen_class_t { diff --git a/src/H5Tref.c b/src/H5Tref.c index b6b26ce..e8cab02 100644 --- a/src/H5Tref.c +++ b/src/H5Tref.c @@ -753,6 +753,14 @@ done: * *------------------------------------------------------------------------- */ +/* + * It is the correct thing to do to have the reference buffer + * be const-qualified here, but the VOL "blob specific" routine + * needs a non-const pointer since an operation might modify + * the "blob". Disable this warning here (at least temporarily) + * for this reason. + */ +H5_GCC_CLANG_DIAG_OFF("cast-qual") static herr_t H5T__ref_disk_isnull(const H5VL_object_t *src_file, const void *src_buf, hbool_t *isnull) { @@ -792,6 +800,7 @@ H5T__ref_disk_isnull(const H5VL_object_t *src_file, const void *src_buf, hbool_t done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5T__ref_disk_isnull() */ +H5_GCC_CLANG_DIAG_ON("cast-qual") /*------------------------------------------------------------------------- * Function: H5T__ref_disk_setnull diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index 39d33d4..4823940 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -76,7 +76,7 @@ static herr_t H5T__vlen_disk_setnull(H5VL_object_t *file, void *_vl, void *_bg); static herr_t H5T__vlen_disk_read(H5VL_object_t *file, void *_vl, void *_buf, size_t len); static herr_t H5T__vlen_disk_write(H5VL_object_t *file, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *_buf, void *_bg, size_t seq_len, size_t base_size); -static herr_t H5T__vlen_disk_delete(H5VL_object_t *file, const void *_vl); +static herr_t H5T__vlen_disk_delete(H5VL_object_t *file, void *_vl); /*********************/ /* Public Variables */ @@ -917,9 +917,9 @@ static herr_t H5T__vlen_disk_write(H5VL_object_t *file, const H5T_vlen_alloc_info_t H5_ATTR_UNUSED *vl_alloc_info, void *_vl, void *buf, void *_bg, size_t seq_len, size_t base_size) { - uint8_t * vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ - const uint8_t *bg = (const uint8_t *)_bg; /* Pointer to the old data hvl_t */ - herr_t ret_value = SUCCEED; /* Return value */ + uint8_t *vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ + uint8_t *bg = (uint8_t *)_bg; /* Pointer to the old data hvl_t */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -957,10 +957,10 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5T__vlen_disk_delete(H5VL_object_t *file, const void *_vl) +H5T__vlen_disk_delete(H5VL_object_t *file, void *_vl) { - const uint8_t *vl = (const uint8_t *)_vl; /* Pointer to the user's hvl_t information */ - herr_t ret_value = SUCCEED; /* Return value */ + uint8_t *vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -981,7 +981,7 @@ H5T__vlen_disk_delete(H5VL_object_t *file, const void *_vl) /* Set up VOL callback arguments */ vol_cb_args.op_type = H5VL_BLOB_DELETE; - if (H5VL_blob_specific(file, (void *)vl, &vol_cb_args) < 0) /* Casting away 'const' OK -QAK */ + if (H5VL_blob_specific(file, vl, &vol_cb_args) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to delete blob") } /* end if */ } /* end if */ diff --git a/test/h5test.h b/test/h5test.h index 7b82b68..5c3e9a3 100644 --- a/test/h5test.h +++ b/test/h5test.h @@ -193,6 +193,15 @@ H5TEST_DLLVAR MPI_Info h5_io_info_g; /* MPI INFO object for IO */ extern "C" { #endif +/* + * Ugly hack to cast away const for freeing const-qualified pointers. + * Should only be used sparingly, where the alternative (like keeping + * an equivalent non-const pointer around) is far messier. + */ +#ifndef h5_free_const +#define h5_free_const(mem) HDfree((void *)(uintptr_t)mem) +#endif + /* Generally useful testing routines */ H5TEST_DLL void h5_clean_files(const char *base_name[], hid_t fapl); H5TEST_DLL int h5_cleanup(const char *base_name[], hid_t fapl); diff --git a/test/vds_env.c b/test/vds_env.c index e01f2e0..97aa245 100644 --- a/test/vds_env.c +++ b/test/vds_env.c @@ -44,13 +44,13 @@ const char *FILENAME[] = {"vds_env_virt_0", "vds_env_virt_3", "vds_env_src_2", " static int test_vds_prefix_second(unsigned config, hid_t fapl) { - char srcfilename[FILENAME_BUF_SIZE]; - char srcfilename_map[FILENAME_BUF_SIZE]; - char vfilename[FILENAME_BUF_SIZE]; - char vfilename2[FILENAME_BUF_SIZE]; - char srcfilenamepct[FILENAME_BUF_SIZE]; - char srcfilenamepct_map[FILENAME_BUF_SIZE]; const char *srcfilenamepct_map_orig = "vds%%%%_src"; + char * srcfilename = NULL; + char * srcfilename_map = NULL; + char * vfilename = NULL; + char * vfilename2 = NULL; + char * srcfilenamepct = NULL; + char * srcfilenamepct_map = NULL; hid_t srcfile[4] = {-1, -1, -1, -1}; /* Files with source dsets */ hid_t vfile = -1; /* File with virtual dset */ hid_t dcpl = -1; /* Dataset creation property list */ @@ -69,12 +69,25 @@ test_vds_prefix_second(unsigned config, hid_t fapl) TESTING("basic virtual dataset I/O via H5Pset_vds_prefix(): all selection with ENV prefix") - h5_fixname(FILENAME[0], fapl, vfilename, sizeof vfilename); - h5_fixname(FILENAME[1], fapl, vfilename2, sizeof vfilename2); - h5_fixname(FILENAME[2], fapl, srcfilename, sizeof srcfilename); - h5_fixname_printf(FILENAME[2], fapl, srcfilename_map, sizeof srcfilename_map); - h5_fixname(FILENAME[3], fapl, srcfilenamepct, sizeof srcfilenamepct); - h5_fixname_printf(srcfilenamepct_map_orig, fapl, srcfilenamepct_map, sizeof srcfilenamepct_map); + if (NULL == (srcfilename = HDmalloc(FILENAME_BUF_SIZE))) + TEST_ERROR + if (NULL == (srcfilename_map = HDmalloc(FILENAME_BUF_SIZE))) + TEST_ERROR + if (NULL == (vfilename = HDmalloc(FILENAME_BUF_SIZE))) + TEST_ERROR + if (NULL == (vfilename2 = HDmalloc(FILENAME_BUF_SIZE))) + TEST_ERROR + if (NULL == (srcfilenamepct = HDmalloc(FILENAME_BUF_SIZE))) + TEST_ERROR + if (NULL == (srcfilenamepct_map = HDmalloc(FILENAME_BUF_SIZE))) + TEST_ERROR + + h5_fixname(FILENAME[0], fapl, vfilename, FILENAME_BUF_SIZE); + h5_fixname(FILENAME[1], fapl, vfilename2, FILENAME_BUF_SIZE); + h5_fixname(FILENAME[2], fapl, srcfilename, FILENAME_BUF_SIZE); + h5_fixname_printf(FILENAME[2], fapl, srcfilename_map, FILENAME_BUF_SIZE); + h5_fixname(FILENAME[3], fapl, srcfilenamepct, FILENAME_BUF_SIZE); + h5_fixname_printf(srcfilenamepct_map_orig, fapl, srcfilenamepct_map, FILENAME_BUF_SIZE); /* create tmp directory and get current working directory path */ if (HDmkdir(TMPDIR, (mode_t)0755) < 0 && errno != EEXIST) @@ -260,10 +273,24 @@ test_vds_prefix_second(unsigned config, hid_t fapl) TEST_ERROR dcpl = -1; + HDfree(srcfilenamepct_map); + HDfree(srcfilenamepct); + HDfree(vfilename2); + HDfree(vfilename); + HDfree(srcfilename_map); + HDfree(srcfilename); + PASSED(); return 0; error: + HDfree(srcfilenamepct_map); + HDfree(srcfilenamepct); + HDfree(vfilename2); + HDfree(vfilename); + HDfree(srcfilename_map); + HDfree(srcfilename); + H5E_BEGIN_TRY { for (i = 0; i < (int)(sizeof(srcdset) / sizeof(srcdset[0])); i++) diff --git a/test/vfd.c b/test/vfd.c index b1b176a..b3bbf43 100644 --- a/test/vfd.c +++ b/test/vfd.c @@ -4112,7 +4112,7 @@ test_vector_io__setup_v(uint32_t count, H5FD_mem_t types[], haddr_t addrs[], siz if (write_bufs[i]) { - HDfree((void *)write_bufs[i]); + h5_free_const(write_bufs[i]); write_bufs[i] = NULL; } @@ -4256,7 +4256,7 @@ test_vector_io__setup_fixed_size_v(uint32_t count, H5FD_mem_t types[], haddr_t a if (write_bufs[i]) { - HDfree((void *)write_bufs[i]); + h5_free_const(write_bufs[i]); write_bufs[i] = NULL; } @@ -4922,13 +4922,13 @@ test_vector_io(const char *vfd_name) for (i = 0; i < count; i++) { - HDfree((void *)write_bufs_0[i]); + h5_free_const(write_bufs_0[i]); write_bufs_0[i] = NULL; - HDfree((void *)write_bufs_1[i]); + h5_free_const(write_bufs_1[i]); write_bufs_1[i] = NULL; - HDfree((void *)write_bufs_2[i]); + h5_free_const(write_bufs_2[i]); write_bufs_2[i] = NULL; HDfree(read_bufs_0[i]); @@ -4940,13 +4940,13 @@ test_vector_io(const char *vfd_name) HDfree(read_bufs_2[i]); read_bufs_2[i] = NULL; - HDfree((void *)f_write_bufs_0[i]); + h5_free_const(f_write_bufs_0[i]); f_write_bufs_0[i] = NULL; - HDfree((void *)f_write_bufs_1[i]); + h5_free_const(f_write_bufs_1[i]); f_write_bufs_1[i] = NULL; - HDfree((void *)f_write_bufs_2[i]); + h5_free_const(f_write_bufs_2[i]); f_write_bufs_2[i] = NULL; HDfree(f_read_bufs_0[i]); diff --git a/testpar/t_2Gio.c b/testpar/t_2Gio.c index 79241c6..554d4ec 100644 --- a/testpar/t_2Gio.c +++ b/testpar/t_2Gio.c @@ -78,7 +78,7 @@ void * old_client_data; /* previous error handler arg.*/ #define NFILENAME 3 #define PARATESTFILE filenames[0] const char *FILENAME[NFILENAME] = {"ParaTest", "Hugefile", NULL}; -char filenames[NFILENAME][PATH_MAX]; +char * filenames[NFILENAME]; hid_t fapl; /* file access property list */ MPI_Comm test_comm = MPI_COMM_WORLD; @@ -224,7 +224,7 @@ parse_options(int argc, char **argv) n = sizeof(FILENAME) / sizeof(FILENAME[0]) - 1; /* exclude the NULL */ for (i = 0; i < n; i++) - if (h5_fixname(FILENAME[i], fapl, filenames[i], sizeof(filenames[i])) == NULL) { + if (h5_fixname(FILENAME[i], fapl, filenames[i], PATH_MAX) == NULL) { HDprintf("h5_fixname failed\n"); nerrors++; return (1); @@ -4585,6 +4585,8 @@ main(int argc, char **argv) MPI_Comm_size(test_comm, &mpi_size); MPI_Comm_rank(test_comm, &mpi_rank); + HDmemset(filenames, 0, sizeof(filenames)); + dim0 = BIG_X_FACTOR; dim1 = BIG_Y_FACTOR; dim2 = BIG_Z_FACTOR; @@ -4601,6 +4603,15 @@ main(int argc, char **argv) HDprintf("Failed to turn off atexit processing. Continue.\n"); }; H5open(); + + HDmemset(filenames, 0, sizeof(filenames)); + for (int i = 0; i < NFILENAME; i++) { + if (NULL == (filenames[i] = HDmalloc(PATH_MAX))) { + HDprintf("couldn't allocate filename array\n"); + MPI_Abort(MPI_COMM_WORLD, -1); + } + } + /* Set the internal transition size to allow use of derived datatypes * without having to actually read or write large datasets (>2GB). */ @@ -4665,6 +4676,11 @@ main(int argc, char **argv) if (mpi_rank == 0) HDremove(FILENAME[0]); + for (int i = 0; i < NFILENAME; i++) { + HDfree(filenames[i]); + filenames[i] = NULL; + } + H5close(); if (test_comm != MPI_COMM_WORLD) { MPI_Comm_free(&test_comm); diff --git a/testpar/t_cache.c b/testpar/t_cache.c index d889b3b..5d1cfdc 100644 --- a/testpar/t_cache.c +++ b/testpar/t_cache.c @@ -41,7 +41,7 @@ const char *FILENAME[NFILENAME] = {"CacheTestDummy", NULL}; #ifndef PATH_MAX #define PATH_MAX 512 #endif /* !PATH_MAX */ -char filenames[NFILENAME][PATH_MAX]; +char * filenames[NFILENAME]; hid_t fapl; /* file access property list */ haddr_t max_addr = 0; /* used to store the end of * the address space used by @@ -192,7 +192,7 @@ struct datum { #define NUM_DATA_ENTRIES 100000 -struct datum data[NUM_DATA_ENTRIES]; +struct datum *data = NULL; /* Many tests use the size of data array as the size of test loops. * On some machines, this results in unacceptably long test runs. @@ -231,7 +231,7 @@ int virt_num_data_entries = NUM_DATA_ENTRIES; * *****************************************************************************/ -int data_index[NUM_DATA_ENTRIES]; +int *data_index = NULL; /***************************************************************************** * The following two #defines are used to control code that is in turn used @@ -2264,13 +2264,13 @@ datum_deserialize(const void H5_ATTR_NDEBUG_UNUSED *image_ptr, H5_ATTR_UNUSED si static herr_t datum_image_len(const void *thing, size_t *image_len) { - int idx; - struct datum *entry_ptr; + int idx; + const struct datum *entry_ptr; HDassert(thing); HDassert(image_len); - entry_ptr = (struct datum *)thing; + entry_ptr = (const struct datum *)thing; idx = addr_to_datum_index(entry_ptr->base_addr); @@ -6938,6 +6938,23 @@ main(int argc, char **argv) goto finish; } + if (NULL == (data = HDmalloc(NUM_DATA_ENTRIES * sizeof(*data)))) { + HDprintf(" Couldn't allocate data array. Exiting.\n"); + MPI_Abort(MPI_COMM_WORLD, -1); + } + if (NULL == (data_index = HDmalloc(NUM_DATA_ENTRIES * sizeof(*data_index)))) { + HDprintf(" Couldn't allocate data index array. Exiting.\n"); + MPI_Abort(MPI_COMM_WORLD, -1); + } + + HDmemset(filenames, 0, sizeof(filenames)); + for (int i = 0; i < NFILENAME; i++) { + if (NULL == (filenames[i] = HDmalloc(PATH_MAX))) { + HDprintf("couldn't allocate filename array\n"); + MPI_Abort(MPI_COMM_WORLD, -1); + } + } + set_up_file_communicator(); setup_derived_types(); @@ -7053,6 +7070,11 @@ main(int argc, char **argv) #endif finish: + if (data_index) + HDfree(data_index); + if (data) + HDfree(data); + /* make sure all processes are finished before final report, cleanup * and exit. */ diff --git a/testpar/t_mdset.c b/testpar/t_mdset.c index 97d5966..339ca33 100644 --- a/testpar/t_mdset.c +++ b/testpar/t_mdset.c @@ -1977,6 +1977,7 @@ rr_obj_hdr_flush_confusion_writer(MPI_Comm comm) /* Tell the reader to check the file up to steps. */ steps++; Reader_check(mrc, steps, steps_done); + VRFY((MPI_SUCCESS == mrc), "Reader_check failed"); /* * Step 2: write attributes to each dataset @@ -2031,6 +2032,7 @@ rr_obj_hdr_flush_confusion_writer(MPI_Comm comm) /* Tell the reader to check the file up to steps. */ steps++; Reader_check(mrc, steps, steps_done); + VRFY((MPI_SUCCESS == mrc), "Reader_check failed"); /* * Step 3: write large attributes to each dataset @@ -2078,6 +2080,7 @@ rr_obj_hdr_flush_confusion_writer(MPI_Comm comm) /* Tell the reader to check the file up to steps. */ steps++; Reader_check(mrc, steps, steps_done); + VRFY((MPI_SUCCESS == mrc), "Reader_check failed"); /* * Step 4: write different large attributes to each dataset @@ -2111,6 +2114,7 @@ rr_obj_hdr_flush_confusion_writer(MPI_Comm comm) /* Tell the reader to check the file up to steps. */ steps++; Reader_check(mrc, steps, steps_done); + VRFY((MPI_SUCCESS == mrc), "Reader_check failed"); /* Step 5: Close all objects and the file */ @@ -2165,10 +2169,12 @@ rr_obj_hdr_flush_confusion_writer(MPI_Comm comm) /* Tell the reader to check the file up to steps. */ steps++; Reader_check(mrc, steps, steps_done); + VRFY((MPI_SUCCESS == mrc), "Reader_check failed"); /* All done. Inform reader to end. */ steps = 0; Reader_check(mrc, steps, steps_done); + VRFY((MPI_SUCCESS == mrc), "Reader_check failed"); if (verbose) HDfprintf(stdout, "%0d:%s: Done.\n", mpi_rank, fcn_name); diff --git a/testpar/t_mpi.c b/testpar/t_mpi.c index 39d7722..47cb6af 100644 --- a/testpar/t_mpi.c +++ b/testpar/t_mpi.c @@ -41,18 +41,18 @@ static int errors_sum(int nerrs); static int test_mpio_overlap_writes(char *filename) { - int mpi_size, mpi_rank; - MPI_Comm comm; - MPI_Info info = MPI_INFO_NULL; - int color, mrc; - MPI_File fh; - int i; - int vrfyerrs, nerrs; - unsigned char buf[4093]; /* use some prime number for size */ - int bufsize = sizeof(buf); - MPI_Offset stride; - MPI_Offset mpi_off; - MPI_Status mpi_stat; + int mpi_size, mpi_rank; + MPI_Comm comm; + MPI_Info info = MPI_INFO_NULL; + int color, mrc; + MPI_File fh; + int i; + int vrfyerrs, nerrs; + unsigned char *buf = NULL; + int bufsize; + MPI_Offset stride; + MPI_Offset mpi_off; + MPI_Status mpi_stat; if (VERBOSE_MED) HDprintf("MPIO independent overlapping writes test on file %s\n", filename); @@ -70,6 +70,13 @@ test_mpio_overlap_writes(char *filename) return 0; } + bufsize = 4093; /* use some prime number for size */ + if (NULL == (buf = HDmalloc((size_t)bufsize))) { + if (MAINPROCESS) + HDprintf("couldn't allocate buffer\n"); + return 1; + } + /* splits processes 0 to n-2 into one comm. and the last one into another */ color = ((mpi_rank < (mpi_size - 1)) ? 0 : 1); mrc = MPI_Comm_split(MPI_COMM_WORLD, color, mpi_rank, &comm); @@ -159,6 +166,9 @@ test_mpio_overlap_writes(char *filename) */ mrc = MPI_Barrier(MPI_COMM_WORLD); VRFY((mrc == MPI_SUCCESS), "Sync before leaving test"); + + HDfree(buf); + return (nerrs); } diff --git a/testpar/t_pflush1.c b/testpar/t_pflush1.c index 0500a2d..7e90cd2 100644 --- a/testpar/t_pflush1.c +++ b/testpar/t_pflush1.c @@ -25,7 +25,7 @@ const char *FILENAME[] = {"flush", "noflush", NULL}; -static int data_g[100][100]; +static int *data_g = NULL; #define N_GROUPS 100 @@ -77,7 +77,7 @@ create_test_file(char *name, size_t name_length, hid_t fapl_id) /* Write some data */ for (i = 0; i < dims[0]; i++) for (j = 0; j < dims[1]; j++) - data_g[i][j] = (int)(i + (i * j) + j); + data_g[(i * 100) + j] = (int)(i + (i * j) + j); if (H5Dwrite(did, H5T_NATIVE_INT, sid, sid, dxpl_id, data_g) < 0) goto error; @@ -146,6 +146,9 @@ main(int argc, char *argv[]) HDexit(EXIT_FAILURE); } + if (NULL == (data_g = HDmalloc(100 * 100 * sizeof(*data_g)))) + goto error; + if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) goto error; if (H5Pset_fapl_mpio(fapl_id, comm, info) < 0) @@ -192,6 +195,11 @@ main(int argc, char *argv[]) HDfflush(stdout); HDfflush(stderr); + if (data_g) { + HDfree(data_g); + data_g = NULL; + } + /* Always exit with a failure code! * * In accordance with the standard, not having all processes @@ -209,5 +217,8 @@ error: HDprintf("THERE WAS A REAL ERROR IN t_pflush1.\n"); HDfflush(stdout); + if (data_g) + HDfree(data_g); + HD_exit(EXIT_FAILURE); } /* end main() */ diff --git a/testpar/t_pflush2.c b/testpar/t_pflush2.c index 8cf40d0..af2e57d 100644 --- a/testpar/t_pflush2.c +++ b/testpar/t_pflush2.c @@ -26,7 +26,7 @@ const char *FILENAME[] = {"flush", "noflush", NULL}; -static int data_g[100][100]; +static int *data_g = NULL; #define N_GROUPS 100 @@ -77,9 +77,10 @@ check_test_file(char *name, size_t name_length, hid_t fapl_id) for (i = 0; i < dims[0]; i++) { for (j = 0; j < dims[1]; j++) { val = (int)(i + (i * j) + j); - if (data_g[i][j] != val) { + if (data_g[(i * 100) + j] != val) { H5_FAILED(); - HDprintf(" data_g[%lu][%lu] = %d\n", (unsigned long)i, (unsigned long)j, data_g[i][j]); + HDprintf(" data_g[%lu][%lu] = %d\n", (unsigned long)i, (unsigned long)j, + data_g[(i * 100) + j]); HDprintf(" should be %d\n", val); } } @@ -170,6 +171,9 @@ main(int argc, char *argv[]) HDexit(EXIT_SUCCESS); } + if (NULL == (data_g = HDmalloc(100 * 100 * sizeof(*data_g)))) + goto error; + if ((fapl_id1 = H5Pcreate(H5P_FILE_ACCESS)) < 0) goto error; if (H5Pset_fapl_mpio(fapl_id1, comm, info) < 0) @@ -213,10 +217,18 @@ main(int argc, char *argv[]) h5_clean_files(&FILENAME[0], fapl_id1); h5_clean_files(&FILENAME[1], fapl_id2); + if (data_g) { + HDfree(data_g); + data_g = NULL; + } + MPI_Finalize(); HDexit(EXIT_SUCCESS); error: + if (data_g) + HDfree(data_g); + HDexit(EXIT_FAILURE); } /* end main() */ diff --git a/testpar/t_shapesame.c b/testpar/t_shapesame.c index 0a18781..d265761 100644 --- a/testpar/t_shapesame.c +++ b/testpar/t_shapesame.c @@ -3956,7 +3956,7 @@ void * old_client_data; /* previous error handler arg.*/ #define NFILENAME 2 #define PARATESTFILE filenames[0] const char *FILENAME[NFILENAME] = {"ShapeSameTest", NULL}; -char filenames[NFILENAME][PATH_MAX]; +char * filenames[NFILENAME]; hid_t fapl; /* file access property list */ #ifdef USE_PAUSE @@ -4144,7 +4144,7 @@ parse_options(int argc, char **argv) n = sizeof(FILENAME) / sizeof(FILENAME[0]) - 1; /* exclude the NULL */ for (i = 0; i < n; i++) - if (h5_fixname(FILENAME[i], fapl, filenames[i], sizeof(filenames[i])) == NULL) { + if (h5_fixname(FILENAME[i], fapl, filenames[i], PATH_MAX) == NULL) { HDprintf("h5_fixname failed\n"); nerrors++; return (1); @@ -4302,6 +4302,14 @@ main(int argc, char **argv) H5open(); h5_show_hostname(); + HDmemset(filenames, 0, sizeof(filenames)); + for (int i = 0; i < NFILENAME; i++) { + if (NULL == (filenames[i] = HDmalloc(PATH_MAX))) { + HDprintf("couldn't allocate filename array\n"); + MPI_Abort(MPI_COMM_WORLD, -1); + } + } + /* Initialize testing framework */ TestInit(argv[0], usage, parse_options); @@ -4366,6 +4374,11 @@ main(int argc, char **argv) HDprintf("===================================\n"); } + for (int i = 0; i < NFILENAME; i++) { + HDfree(filenames[i]); + filenames[i] = NULL; + } + /* close HDF5 library */ H5close(); diff --git a/testpar/testphdf5.c b/testpar/testphdf5.c index 1ead1b8..d7b5305 100644 --- a/testpar/testphdf5.c +++ b/testpar/testphdf5.c @@ -43,7 +43,7 @@ int dxfer_coll_type = DXFER_COLLECTIVE_IO; #define NFILENAME 2 #define PARATESTFILE filenames[0] const char *FILENAME[NFILENAME] = {"ParaTest", NULL}; -char filenames[NFILENAME][PATH_MAX]; +char * filenames[NFILENAME]; hid_t fapl; /* file access property list */ #ifdef USE_PAUSE @@ -231,7 +231,7 @@ parse_options(int argc, char **argv) n = sizeof(FILENAME) / sizeof(FILENAME[0]) - 1; /* exclude the NULL */ for (i = 0; i < n; i++) - if (h5_fixname(FILENAME[i], fapl, filenames[i], sizeof(filenames[i])) == NULL) { + if (h5_fixname(FILENAME[i], fapl, filenames[i], PATH_MAX) == NULL) { HDprintf("h5_fixname failed\n"); nerrors++; return (1); @@ -336,6 +336,14 @@ main(int argc, char **argv) H5open(); h5_show_hostname(); + HDmemset(filenames, 0, sizeof(filenames)); + for (int i = 0; i < NFILENAME; i++) { + if (NULL == (filenames[i] = HDmalloc(PATH_MAX))) { + HDprintf("couldn't allocate filename array\n"); + MPI_Abort(MPI_COMM_WORLD, -1); + } + } + /* Initialize testing framework */ TestInit(argv[0], usage, parse_options); @@ -544,6 +552,11 @@ main(int argc, char **argv) HDprintf("===================================\n"); } + for (int i = 0; i < NFILENAME; i++) { + HDfree(filenames[i]); + filenames[i] = NULL; + } + /* close HDF5 library */ H5close(); -- cgit v0.12