RNetCDF/0000755000176200001440000000000014600137202011432 5ustar liggesusersRNetCDF/NAMESPACE0000644000176200001440000000011214577713273012670 0ustar liggesusersuseDynLib(RNetCDF, .registration = TRUE) exportPattern("^[^\\.].*\\.nc$") RNetCDF/demo/0000755000176200001440000000000014577713273012403 5ustar liggesusersRNetCDF/demo/Rmpi_writeN_read1.R0000644000176200001440000000350014577713273016037 0ustar liggesusers### SHELL> mpiexec -np 2 Rscript --vanilla [...].R filename.nc library(Rmpi, quiet = TRUE) library(RNetCDF, quiet = TRUE) testfun <- function(x,y) { if (isTRUE(all.equal(x,y))) { cat("OK\n") return(TRUE) } else { cat("Failed\n") cat("x:\n") print(x) cat("y:\n") print(y) return(FALSE) } } ### MPI parameters comm <- 0 rank <- mpi.comm.rank(comm) size <- mpi.comm.size(comm) ### Define global dimensions and data nr <- 5 nc_loc <- 4 nc <- nc_loc * size data_global <- matrix(seq(1,nc*nr), nrow=nr, ncol=nc) data_local <- data_global[,rank*nc_loc+c(1:nc_loc)] ### Parallel write args <- commandArgs(TRUE) stopifnot(length(args) == 1) filename <- args[1] ncid <- create.nc(filename, format="netcdf4", mpi_comm=mpi.comm.c2f(comm), mpi_info=NULL) rdim <- dim.def.nc(ncid, "rows", nr) cdim <- dim.def.nc(ncid, "cols", nc) indid <- var.def.nc(ncid, "independent", "NC_INT", c(rdim, cdim)) var.par.nc(ncid, indid, "NC_INDEPENDENT") # Default mode, but make explicit here. colid <- var.def.nc(ncid, "collective", "NC_INT", c(rdim, cdim)) var.par.nc(ncid, colid, "NC_COLLECTIVE") var.put.nc(ncid, indid, data_local, start=c(1,rank*nc_loc+1), count=c(nr,nc_loc)) var.put.nc(ncid, colid, data_local, start=c(1,rank*nc_loc+1), count=c(nr,nc_loc)) close.nc(ncid) invisible(mpi.barrier(comm)) ### Serial read if (rank==0) { ncid2 <- open.nc(filename) data_ind <- var.get.nc(ncid2, "independent") data_col <- var.get.nc(ncid2, "collective") close.nc(ncid2) unlink(filename) } ### Check global data on rank 0 if (rank==0) { cat("Checking independent parallel write with Rmpi ... ") ind_ok <- testfun(data_global, data_ind) cat("Checking collective parallel write with Rmpi ... ") col_ok <- testfun(data_global, data_col) if (!ind_ok || !col_ok) { mpi.abort(comm) } } invisible(mpi.finalize()) RNetCDF/demo/00Index0000644000176200001440000000024614577713273013537 0ustar liggesusersRmpi_writeN_read1 RNetCDF Write NetCDF4 file with parallel processes using Rmpi pbdMPI_writeN_read1 RNetCDF Write NetCDF4 file with parallel processes using pbdMPI RNetCDF/demo/pbdMPI_writeN_read1.R0000644000176200001440000000344514577713273016253 0ustar liggesusers### SHELL> mpiexec -np 2 Rscript --vanilla [...].R filename.nc library(pbdMPI, quiet = TRUE) library(RNetCDF, quiet = TRUE) testfun <- function(x,y) { if (isTRUE(all.equal(x,y))) { cat("OK\n") return(TRUE) } else { cat("Failed\n") cat("x:\n") print(x) cat("y:\n") print(y) return(FALSE) } } ### MPI parameters init() rank <- comm.rank() size <- comm.size() ### Define global dimensions and data nr <- 5 nc_loc <- 4 nc <- nc_loc * size data_global <- matrix(seq(1,nc*nr), nrow=nr, ncol=nc) data_local <- data_global[,rank*nc_loc+c(1:nc_loc)] ### Parallel write args <- commandArgs(TRUE) stopifnot(length(args) == 1) filename <- args[1] info.create() ncid <- create.nc(filename, format="netcdf4", mpi_comm=comm.c2f(), mpi_info=info.c2f()) rdim <- dim.def.nc(ncid, "rows", nr) cdim <- dim.def.nc(ncid, "cols", nc) indid <- var.def.nc(ncid, "independent", "NC_INT", c(rdim, cdim)) var.par.nc(ncid, indid, "NC_INDEPENDENT") # Default mode, but make explicit here. colid <- var.def.nc(ncid, "collective", "NC_INT", c(rdim, cdim)) var.par.nc(ncid, colid, "NC_COLLECTIVE") var.put.nc(ncid, indid, data_local, start=c(1,rank*nc_loc+1), count=c(nr,nc_loc)) var.put.nc(ncid, colid, data_local, start=c(1,rank*nc_loc+1), count=c(nr,nc_loc)) close.nc(ncid) info.free() barrier() ### Serial read if (rank==0) { ncid2 <- open.nc(filename) data_ind <- var.get.nc(ncid2, "independent") data_col <- var.get.nc(ncid2, "collective") close.nc(ncid2) unlink(filename) } ### Check global data on rank 0 if (rank==0) { cat("Checking independent parallel write with pbdMPI ... ") ind_ok <- testfun(data_global, data_ind) cat("Checking collective parallel write with pbdMPI ... ") col_ok <- testfun(data_global, data_col) if (!ind_ok || !col_ok) { comm.abort() } } finalize() RNetCDF/LICENSE0000644000176200001440000002517214577720574012475 0ustar liggesusersThis file is intended to clarify ownership, copyrights and licenses. Where possible individual files also carry brief copyright notices. RNetCDF ======= All files except those indicated later are Copyright (C) 2004-2024 Pavel Michna and Milton Woods. They are licensed under the terms of the GNU General Public License: This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. See http://www.r-project.org/Licenses/GPL-2 for license details. NetCDF ====== The documentation of RNetCDF is based on the "NetCDF User's Guide for C", and installation of RNetCDF requires linking with the Unidata NetCDF library. These uses of NetCDF are allowed by the NetCDF copyright: Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, University Corporation for Atmospheric Research/Unidata. Portions of this software were developed by the Unidata Program at the University Corporation for Atmospheric Research. Access and use of this software shall impose the following obligations and understandings on the user. The user is granted the right, without any fee or cost, to use, copy, modify, alter, enhance and distribute this software, and any derivative works thereof, and its supporting documentation for any purpose whatsoever, provided that this entire notice appears in all copies of the software, derivative works and supporting documentation. Further, UCAR requests that the user credit UCAR/Unidata in any publications that result from the use of this software or in any product that includes this software, although this is not an obligation. The names UCAR and/or Unidata, however, may not be used in any advertising or publicity to endorse or promote any products or commercial entity unless specific written permission is obtained from UCAR/Unidata. The user also understands that UCAR/Unidata is not obligated to provide the user with any support, consulting, training or assistance of any kind with regard to the use, operation and performance of this software nor to provide the user with any updates, revisions, new versions or "bug fixes." THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE. UDUNITS2 ======== RNetCDF may be linked with the UDUNITS2 library. To simplify distribution of RNetCDF in binary form, data files required by UDUNITS2 are included with RNetCDF, subject to the following license: Copyright 2014 University Corporation for Atmospheric Research and contributors. All rights reserved. This software was developed by the Unidata Program Center of the University Corporation for Atmospheric Research (UCAR) . Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3) Neither the names of the development group, the copyright holders, nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. 4) This license shall terminate automatically and you may no longer exercise any of the rights granted to you by this license as of the date you commence an action, including a cross-claim or counterclaim, against the copyright holders or any contributor alleging that this software infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of this software with other software or hardware. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. NCSA HDF5 ========= Although the RNetCDF package does not use HDF5 directly, if statically linked to a build of netcdf with the netcdf4 feature enabled, it will link in code from HDF5. The license for such code is given below: Copyright Notice and License Terms for HDF5 (Hierarchical Data Format 5) Software Library and Utilities ----------------------------------------------------------------------------- HDF5 (Hierarchical Data Format 5) Software Library and Utilities Copyright 2006-2014 by The HDF Group. NCSA HDF5 (Hierarchical Data Format 5) Software Library and Utilities Copyright 1998-2006 by the Board of Trustees of the University of Illinois. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted for any purpose (including commercial purposes) provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation and/or materials provided with the distribution. 3. In addition, redistributions of modified forms of the source or binary code must carry prominent notices stating that the original code was changed and the date of the change. 4. All publications or advertising materials mentioning features or use of this software are asked, but not required, to acknowledge that it was developed by The HDF Group and by the National Center for Supercomputing Applications at the University of Illinois at Urbana-Champaign and credit the contributors. 5. Neither the name of The HDF Group, the name of the University, nor the name of any Contributor may be used to endorse or promote products derived from this software without specific prior written permission from The HDF Group, the University, or the Contributor, respectively. DISCLAIMER: THIS SOFTWARE IS PROVIDED BY THE HDF GROUP AND THE CONTRIBUTORS "AS IS" WITH NO WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED. In no event shall The HDF Group or the Contributors be liable for any damages suffered by the users arising out of the use of this software, even if advised of the possibility of such damage. ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- Contributors: National Center for Supercomputing Applications (NCSA) at the University of Illinois, Fortner Software, Unidata Program Center (netCDF), The Independent JPEG Group (JPEG), Jean-loup Gailly and Mark Adler (gzip), and Digital Equipment Corporation (DEC). ----------------------------------------------------------------------------- Portions of HDF5 were developed with support from the Lawrence Berkeley National Laboratory (LBNL) and the United States Department of Energy under Prime Contract No. DE-AC02-05CH11231. ----------------------------------------------------------------------------- Portions of HDF5 were developed with support from the University of California, Lawrence Livermore National Laboratory (UC LLNL). The following statement applies to those portions of the product and must be retained in any redistribution of source code, binaries, documentation, and/or accompanying materials: This work was partially produced at the University of California, Lawrence Livermore National Laboratory (UC LLNL) under contract no. W-7405-ENG-48 (Contract 48) between the U.S. Department of Energy (DOE) and The Regents of the University of California (University) for the operation of UC LLNL. DISCLAIMER: This work was prepared as an account of work sponsored by an agency of the United States Government. Neither the United States Government nor the University of California nor any of their employees, makes any warranty, express or implied, or assumes any liability or responsibility for the accuracy, completeness, or usefulness of any information, apparatus, product, or process disclosed, or represents that its use would not infringe privately- owned rights. Reference herein to any specific commercial products, process, or service by trade name, trademark, manufacturer, or otherwise, does not necessarily constitute or imply its endorsement, recommendation, or favoring by the United States Government or the University of California. The views and opinions of authors expressed herein do not necessarily state or reflect those of the United States Government or the University of California, and shall not be used for advertising or product endorsement purposes. ----------------------------------------------------------------------------- Pavel Michna RNetCDF/tools/0000755000176200001440000000000014577720574012621 5ustar liggesusersRNetCDF/tools/update-convert-c.sh0000755000176200001440000000033214577713273016334 0ustar liggesusers#!/bin/sh # Update src/convert.c from tools/convert.m4 set -e set -u # Set working directory to base directory of package: thisdir="$( dirname "$0" )" cd "$thisdir/.." # Run m4: m4 tools/convert.m4 > src/convert.c RNetCDF/tools/update-configure.sh0000755000176200001440000000040014577713273016411 0ustar liggesusers#!/bin/sh # Update configure script(s) set -e set -u # Set working directory to base directory of package: thisdir="$( dirname "$0" )" cd "$thisdir/.." # Update configure for Unix-like platforms: autoconf configure.ac > configure rm -rf autom4te.cache RNetCDF/tools/convert.m40000644000176200001440000020360114577720574014545 0ustar liggesusersdnl Insert warning into generated C code: /* NOTE: This code was generated from tools/convert.m4 */ /*=============================================================================*\ * * Name: convert.c * * Version: 2.9-2 * * Purpose: Type conversions for RNetCDF * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright (C) 2004-2024 Pavel Michna and Milton Woods. * *=============================================================================* * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *=============================================================================* */ /*=============================================================================*\ * Includes \*=============================================================================*/ #include #include #include #include #include #include #include #include #include #include "common.h" #include "convert.h" /*=============================================================================*\ * Local macros, constants and variables \*=============================================================================*/ /* Definition of missing value used by bit64 package */ #define NA_INTEGER64 LLONG_MIN /* Maximum length of R character string */ #define RNC_CHARSXP_MAXLEN 2147483647 /* Conversion from 64-bit integers to double may round upwards, so that the double cannot be converted back to the original type. The following limits can be safely converted both ways. */ static const double LLONG_MAX_DBL = \ ((double) LLONG_MAX) * (1.0 - DBL_EPSILON); static const double LLONG_MIN_DBL = \ ((double) LLONG_MIN) * (1.0 - DBL_EPSILON); static const double ULLONG_MAX_DBL = \ ((double) ULLONG_MAX) * (1.0 - DBL_EPSILON); static const double SIZE_MAX_DBL = \ ((double) SIZE_MAX) * (1.0 - DBL_EPSILON); /*=============================================================================*\ * Memory management. \*=============================================================================*/ size_t R_nc_length (int ndims, const size_t *count) { int ii; size_t length; if (ndims < 0) { /* Vector of length count[0] */ ndims = 1; } length = 1; for ( ii=0; ii 0) { rdim = PROTECT( allocVector (INTSXP, ndims)); intp = INTEGER (rdim); for ( ii=0, jj=ndims-1; ii 0) { /* Omit fastest-varying dimension from R character array */ rowlen = xdim[ndim-1]; cnt = R_nc_length (ndim-1, xdim); } else if (ndim == 0) { /* Scalar character */ rowlen = 1; cnt = 1; } else { /* Single string */ rowlen = xdim[0]; cnt = 1; } if ((size_t) xlength (rstr) < cnt) { error (RNC_EDATALEN); } carr = R_alloc (cnt*rowlen, sizeof (char)); /* Prefill the buffer with the defined value or null characters */ if (fill != NULL && fillsize == sizeof (char)) { fillval = *(char *) fill; } else { fillval = '\0'; } memset(carr, fillval, cnt*rowlen); for (ii=0, thiscstr=carr; iindim > 0) { io->rxp = PROTECT(R_nc_allocArray (STRSXP, (io->ndim)-1, io->xdim)); } else { /* Single character or string */ io->rxp = PROTECT(R_nc_allocArray (STRSXP, 0, io->xdim)); } if (!io->cbuf) { io->cbuf = R_alloc (R_nc_length (io->ndim, io->xdim), sizeof (char)); } UNPROTECT(1); return io->rxp; } static void R_nc_char_strsxp (R_nc_buf *io) { size_t ii, cnt, clen, rlen, thislen; char *thisstr, fillval; int hasfill; /* Find fill value */ if (io->fill != NULL && io->fillsize == sizeof (char)) { hasfill = 1; fillval = *(char *) io->fill; } else { hasfill = 0; } /* Find maximum length of strings returned to R, based on array dimensions of the C buffer */ if (io->ndim > 0) { /* Omit fastest-varying dimension from R character array */ clen = io->xdim[(io->ndim)-1]; } else if (io->ndim == 0) { /* Scalar character */ clen = 1; } else { /* Single string */ clen = io->xdim[0]; } rlen = (clen <= RNC_CHARSXP_MAXLEN) ? clen : RNC_CHARSXP_MAXLEN; cnt = xlength (io->rxp); /* If C buffer has row length > 0, convert rows of C buffer to separate R strings, otherwise return empty R strings as initialised by R_nc_allocArray */ if (clen > 0) { for (ii=0, thisstr=io->cbuf; iirxp, ii, PROTECT(mkCharLen (thisstr, thislen))); UNPROTECT(1); } } } static const char * R_nc_raw_char (SEXP rarr, int ndim, const size_t *xdim) { size_t cnt; cnt = R_nc_length (ndim, xdim); if ((size_t) xlength (rarr) < cnt) { error (RNC_EDATALEN); } return (const char *) RAW (rarr); } static SEXP R_nc_char_raw_init (R_nc_buf *io) { io->rxp = PROTECT(R_nc_allocArray (RAWSXP, io->ndim, io->xdim)); io->rbuf = RAW (io->rxp); if (!io->cbuf) { io->cbuf = io->rbuf; } UNPROTECT(1); return io->rxp; } static void R_nc_char_raw (R_nc_buf *io) { if (io->cbuf != io->rbuf) { memcpy(io->rbuf, io->cbuf, xlength(io->rxp) * sizeof(char)); } return; } static const char ** R_nc_strsxp_str (SEXP rstr, int ndim, const size_t *xdim, size_t fillsize, const void *fill) { size_t ii, cnt; const char **cstr, *fillval; SEXP thissxp; int hasfill; hasfill = (fill != NULL && fillsize == sizeof (size_t)); if (hasfill) { fillval = *(const char **) fill; } cnt = R_nc_length (ndim, xdim); if ((size_t) xlength (rstr) < cnt) { error (RNC_EDATALEN); } cstr = (const char **) R_alloc (cnt, sizeof(size_t)); for (ii=0; iirxp = PROTECT(R_nc_allocArray (STRSXP, io->ndim, io->xdim)); if (!io->cbuf) { io->cbuf = R_alloc (xlength (io->rxp), sizeof(size_t)); } UNPROTECT(1); return io->rxp; } static void R_nc_str_strsxp (R_nc_buf *io) { size_t ii, nchar, cnt; char **cstr; const char *fillval; int hasfill; hasfill = (io->fill != NULL && io->fillsize == sizeof (size_t)); if (hasfill) { fillval = *(const char **) io->fill; } cnt = xlength (io->rxp); cstr = (char **) io->cbuf; for (ii=0; iirxp, ii, NA_STRING); } else { /* Truncate excessively long strings while reading into R */ nchar = R_nc_strnlen (cstr[ii], '\0', RNC_CHARSXP_MAXLEN); SET_STRING_ELT (io->rxp, ii, PROTECT(mkCharLen (cstr[ii], nchar))); UNPROTECT(1); } } /* Free pointers to strings created by netcdf */ if (cnt > 0) { R_nc_check (nc_free_string (cnt, io->cbuf)); } } /*=============================================================================*\ * Numeric type conversions \*=============================================================================*/ dnl Test for missing values: dnl R_NC_ISNA(RTYPE,VALUE) define(`R_NC_ISNA',`ifelse(`$1',`int',`($2==NA_INTEGER)', `$1',`double',`(ISNA($2))', `$1',`long long',`($2==NA_INTEGER64)')') /* Convert numeric values from R to C format. Memory for the result is allocated if necessary (and freed by R). In special cases, the output is a pointer to the input data, so the output data should not be modified. An error is raised if any input values are outside the range of the output type. dnl R_NC_R2C_NUM(FUN, ITYPE, IFUN, OTYPE, MINVAL, MAXVAL) */ define(`R_NC_R2C_NUM', `dnl pushdef(`FUN',`$1')dnl pushdef(`ITYPE',`$2')dnl pushdef(`IFUN',`$3')dnl pushdef(`OTYPE',`$4')dnl pushdef(`MINVAL',`$5')dnl pushdef(`MAXVAL',`$6')dnl static const OTYPE* FUN (SEXP rv, int ndim, const size_t *xdim, size_t fillsize, const OTYPE *fill) { size_t ii, cnt, hasfill; const ITYPE *in; OTYPE fillval=0, *out; in = (ITYPE *) IFUN (rv); cnt = R_nc_length (ndim, xdim); if ((size_t) xlength (rv) < cnt) { error (RNC_EDATALEN); } hasfill = (fill != NULL); ifelse(ITYPE,OTYPE, `dnl Same types: if (hasfill) { out = (OTYPE *) R_alloc (cnt, sizeof(OTYPE)); } else { out = (OTYPE *) IFUN (rv); return out; } ', `dnl Different types: out = (OTYPE *) R_alloc (cnt, sizeof(OTYPE)); ')dnl if (hasfill) { if (fillsize != sizeof(OTYPE)) { error ("Size of fill value does not match output type"); } fillval = *fill; } if (hasfill) { R_NC_R2C_NUM_LOOP(1) } else { R_NC_R2C_NUM_LOOP(0) } return out; } popdef(`FUN',`ITYPE',`IFUN',`OTYPE',`MINVAL',`MAXVAL')dnl ') dnl R_NC_R2C_NUM_LOOP(WITH_FILL) - called by R_NC_R2C_NUM define(`R_NC_R2C_NUM_LOOP',`dnl dnl Allow any block of "if" statement to be first; dnl ELSE is blank on first use, then redefined to "} else". pushdef(`ELSE',`popdef(`ELSE')pushdef(`ELSE',`} else ')')dnl dnl Include range checks? pushdef(`WITH_RANGE',eval( ifelse(MINVAL,`',0,1) || ifelse(MAXVAL,`',0,1) ))dnl dnl Is input a floating point type? pushdef(`IN_FLOAT',eval( ifelse(ITYPE,`float',1,0) || ifelse(ITYPE,`double',1,0) ))dnl dnl Is output a floating point type? pushdef(`OUT_FLOAT',eval( ifelse(OTYPE,`float',1,0) || ifelse(OTYPE,`double',1,0) ))dnl for (ii=0; ii SIZEOF_SIZE_T R_NC_R2C_NUM(R_nc_r2c_int_size, int, INTEGER, size_t, 0, SIZE_MAX) #else R_NC_R2C_NUM(R_nc_r2c_int_size, int, INTEGER, size_t, 0,) #endif R_NC_R2C_NUM(R_nc_r2c_dbl_schar, double, REAL, signed char, SCHAR_MIN, SCHAR_MAX) R_NC_R2C_NUM(R_nc_r2c_dbl_uchar, double, REAL, unsigned char, 0, UCHAR_MAX) R_NC_R2C_NUM(R_nc_r2c_dbl_short, double, REAL, short, SHRT_MIN, SHRT_MAX) R_NC_R2C_NUM(R_nc_r2c_dbl_ushort, double, REAL, unsigned short, 0, USHRT_MAX) R_NC_R2C_NUM(R_nc_r2c_dbl_int, double, REAL, int, INT_MIN, INT_MAX) R_NC_R2C_NUM(R_nc_r2c_dbl_uint, double, REAL, unsigned int, 0, UINT_MAX) R_NC_R2C_NUM(R_nc_r2c_dbl_ll, double, REAL, long long, LLONG_MIN_DBL, LLONG_MAX_DBL) R_NC_R2C_NUM(R_nc_r2c_dbl_ull, double, REAL, unsigned long long, 0, ULLONG_MAX_DBL) R_NC_R2C_NUM(R_nc_r2c_dbl_float, double, REAL, float, -FLT_MAX, FLT_MAX) R_NC_R2C_NUM(R_nc_r2c_dbl_dbl, double, REAL, double,,) /* Only convert non-negative values to size_t */ R_NC_R2C_NUM(R_nc_r2c_dbl_size, double, REAL, size_t, 0, SIZE_MAX_DBL) /* bit64 is treated by R as signed long long, but we may need to store unsigned long long, with very large positive values wrapping to negative values in R. We allow wrapping in reverse for conversion of bit64 to unsigned long long. */ R_NC_R2C_NUM(R_nc_r2c_bit64_schar, long long, REAL, signed char, SCHAR_MIN, SCHAR_MAX) R_NC_R2C_NUM(R_nc_r2c_bit64_uchar, long long, REAL, unsigned char, 0, UCHAR_MAX) R_NC_R2C_NUM(R_nc_r2c_bit64_short, long long, REAL, short, SHRT_MIN, SHRT_MAX) R_NC_R2C_NUM(R_nc_r2c_bit64_ushort, long long, REAL, unsigned short, 0, USHRT_MAX) R_NC_R2C_NUM(R_nc_r2c_bit64_int, long long, REAL, int, INT_MIN, INT_MAX) R_NC_R2C_NUM(R_nc_r2c_bit64_uint, long long, REAL, unsigned int, 0, UINT_MAX) R_NC_R2C_NUM(R_nc_r2c_bit64_ll, long long, REAL, long long,,) R_NC_R2C_NUM(R_nc_r2c_bit64_ull, long long, REAL, unsigned long long,,) R_NC_R2C_NUM(R_nc_r2c_bit64_float, long long, REAL, float,,) R_NC_R2C_NUM(R_nc_r2c_bit64_dbl, long long, REAL, double,,) #if SIZEOF_LONG_LONG > SIZEOF_SIZE_T R_NC_R2C_NUM(R_nc_r2c_bit64_size, long long, REAL, size_t, 0, SIZE_MAX) #else R_NC_R2C_NUM(R_nc_r2c_bit64_size, long long, REAL, size_t,,) #endif /* Convert numeric values from R to C format with packing. Memory for the result is allocated and freed by R. An error is raised if any packed values are outside the range of the output type. dnl R_NC_R2C_NUM_PACK(FUN, ITYPE, IFUN, OTYPE, MINVAL, MAXVAL) */ define(`R_NC_R2C_NUM_PACK', `dnl pushdef(`FUN',`$1')dnl pushdef(`ITYPE',`$2')dnl pushdef(`IFUN',`$3')dnl pushdef(`OTYPE',`$4')dnl pushdef(`MINVAL',`$5')dnl pushdef(`MAXVAL',`$6')dnl static const OTYPE* FUN (SEXP rv, int ndim, const size_t *xdim, size_t fillsize, const OTYPE *fill, const double *scale, const double *add) { size_t ii, cnt, hasfill; double factor=1.0, offset=0.0, dpack; const ITYPE *in; OTYPE fillval=0, *out; in = (ITYPE *) IFUN (rv); cnt = R_nc_length (ndim, xdim); if ((size_t) xlength (rv) < cnt) { error (RNC_EDATALEN); } out = (OTYPE *) R_alloc (cnt, sizeof(OTYPE)); if (scale) { factor = *scale; } if (add) { offset = *add; } hasfill = (fill != NULL); if (hasfill) { if (fillsize != sizeof(OTYPE)) { error ("Size of fill value does not match output type"); } fillval = *fill; } if (hasfill) { R_NC_R2C_NUM_PACK_LOOP(1) } else { R_NC_R2C_NUM_PACK_LOOP(0) } return out; } popdef(`FUN',`ITYPE',`IFUN',`OTYPE',`MINVAL',`MAXVAL')dnl ') dnl R_NC_R2C_NUM_PACK_LOOP(WITH_FILL) - called by R_NC_R2C_NUM_PACK define(`R_NC_R2C_NUM_PACK_LOOP',`dnl dnl Allow any block of "if" statement to be first; dnl ELSE is blank on first use, then redefined to "} else". pushdef(`ELSE',`popdef(`ELSE')pushdef(`ELSE',`} else ')')dnl dnl Include range checks? pushdef(`WITH_RANGE',eval( ifelse(MINVAL,`',0,1) || ifelse(MAXVAL,`',0,1) ))dnl dnl Are non-finite input values within range? pushdef(`OUT_FLOAT',eval( ifelse(OTYPE,`float',1,0) || ifelse(OTYPE,`double',1,0) ))dnl for (ii=0; iicbuf is NULL, a separate C buffer is allocated for data before conversion, which will be freed automatically on return to R. The SEXP is returned and should be PROTECTed by the caller. */ dnl R_NC_C2R_NUM_INIT(FUN, SEXPTYPE, OFUN) define(`R_NC_C2R_NUM_INIT',`dnl pushdef(`FUN',`$1')dnl pushdef(`SEXPTYPE',`$2')dnl pushdef(`OFUN',`$3')dnl static SEXP FUN (R_nc_buf *io) { size_t xsize; io->rxp = PROTECT(R_nc_allocArray (SEXPTYPE, io->ndim, io->xdim)); io->rbuf = OFUN (io->rxp); if (!io->cbuf) { R_nc_check (nc_inq_type(io->ncid, io->xtype, NULL, &xsize)); io->cbuf = R_alloc (R_nc_length (io->ndim, io->xdim), xsize); } UNPROTECT(1); return io->rxp; } popdef(`FUN',`SEXPTYPE',`OFUN')dnl ')dnl R_NC_C2R_NUM_INIT(R_nc_c2r_int_init, INTSXP, INTEGER) R_NC_C2R_NUM_INIT(R_nc_c2r_dbl_init, REALSXP, REAL) R_NC_C2R_NUM_INIT(R_nc_c2r_bit64_init, REALSXP, REAL) /* Convert numeric values from C to R format. Parameters and buffers for the conversion are passed via the R_nc_buf struct. Non-overlapping buffers must be used for input and output. Fill values and values outside the valid range are set to missing, but NA or NaN values in floating point data are transferred to the output (because all comparisons with NA or NaN are false). */ dnl R_NC_C2R_NUM(FUN, ITYPE, OTYPE, MISSVAL) define(`R_NC_C2R_NUM',`dnl pushdef(`FUN',`$1')dnl pushdef(`ITYPE',`$2')dnl pushdef(`OTYPE',`$3')dnl pushdef(`MISSVAL',`$4')dnl static void FUN (R_nc_buf *io) { size_t ii, cnt; ITYPE fillval=0, minval=0, maxval=0, *in; OTYPE *out; int hasfill, hasmin, hasmax; cnt = xlength (io->rxp); in = (ITYPE *) io->cbuf; out = (OTYPE *) io->rbuf; if ((io->fill || io->min || io->max ) && io->fillsize != sizeof(ITYPE)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((ITYPE *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((ITYPE *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((ITYPE *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { R_NC_C2R_NUM_LOOP(1,1,1) } else { R_NC_C2R_NUM_LOOP(1,1,0) } } else { if (hasmax) { R_NC_C2R_NUM_LOOP(1,0,1) } else { R_NC_C2R_NUM_LOOP(1,0,0) } } } else { if (hasmin) { if (hasmax) { R_NC_C2R_NUM_LOOP(0,1,1) } else { R_NC_C2R_NUM_LOOP(0,1,0) } } else { if (hasmax) { R_NC_C2R_NUM_LOOP(0,0,1) } else { R_NC_C2R_NUM_LOOP(0,0,0) } } } } popdef(`FUN',`ITYPE',`OTYPE',`MISSVAL')dnl ')dnl dnl R_NC_C2R_NUM_LOOP(WITH_FILL,WITH_MIN,WITH_MAX) - called by R_NC_C2R_NUM define(`R_NC_C2R_NUM_LOOP',`dnl for (ii=0; iirxp); in = (ITYPE *) io->cbuf; out = (double *) io->rbuf; if (io->scale) { factor = *(io->scale); } if (io->add) { offset = *(io->add); } if ((io->fill || io->min || io->max) && io->fillsize != sizeof(ITYPE)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((ITYPE *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((ITYPE *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((ITYPE *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { R_NC_C2R_NUM_UNPACK_LOOP(1,1,1) } else { R_NC_C2R_NUM_UNPACK_LOOP(1,1,0) } } else { if (hasmax) { R_NC_C2R_NUM_UNPACK_LOOP(1,0,1) } else { R_NC_C2R_NUM_UNPACK_LOOP(1,0,0) } } } else { if (hasmin) { if (hasmax) { R_NC_C2R_NUM_UNPACK_LOOP(0,1,1) } else { R_NC_C2R_NUM_UNPACK_LOOP(0,1,0) } } else { if (hasmax) { R_NC_C2R_NUM_UNPACK_LOOP(0,0,1) } else { R_NC_C2R_NUM_UNPACK_LOOP(0,0,0) } } } } popdef(`FUN',`ITYPE')dnl ')dnl dnl R_NC_C2R_NUM_UNPACK_LOOP(WITH_FILL,WITH_MIN,WITH_MAX) - called by R_NC_C2R_NUM_UNPACK define(`R_NC_C2R_NUM_UNPACK_LOOP',`dnl for (ii=0; ii NC_MAX_ATOMIC_TYPE) { R_nc_check (nc_inq_user_type (ncid, basetype, NULL, &basesize, NULL, NULL, &baseclass)); } else { R_nc_check (nc_inq_type (ncid, basetype, NULL, &basesize)); baseclass = NC_NAT; } /* Check if fill value is properly defined */ hasfill = (fill != NULL && fillsize == size); basefill = NULL; basefillsize = 0; if (hasfill) { vfill = (nc_vlen_t *) fill; if (vfill[0].len > 0) { basefill = vfill[0].p; basefillsize = basesize; } } /* Convert list items to vlen elements */ vbuf = (nc_vlen_t *) R_alloc (cnt, sizeof(nc_vlen_t)); for (ii=0; ii 0) { len = strlen (CHAR (STRING_ELT (item, 0))); } else { len = 0; } } else if (baseclass == NC_OPAQUE && TYPEOF (item) == RAWSXP) { len = xlength(item) / basesize; } else { len = xlength(item); } vbuf[ii].len = len; if (len > 0) { vbuf[ii].p = (void *) R_nc_r2c (item, ncid, basetype, -1, &len, basefillsize, basefill, scale, add); } else { vbuf[ii].p = NULL; } UNPROTECT(1); } return vbuf; } /* Allocate memory for reading a slice of a netcdf vlen variable and converting the results to an R variable. On input, the R_nc_buf structure contains dimensions of the buffer (ndim, *xdim). On output, the R_nc_buf structure contains an allocated R list (with dim attribute), and the C buffer is an array of pointers which are allocated by netcdf when reading from the variable (and which must be freed later by netcdf). */ static SEXP R_nc_vlen_vecsxp_init (R_nc_buf *io) { io->rxp = PROTECT(R_nc_allocArray (VECSXP, io->ndim, io->xdim)); if (!io->cbuf) { io->cbuf = R_alloc (xlength (io->rxp), sizeof(nc_vlen_t)); } UNPROTECT(1); return io->rxp; } /* Convert netcdf vlen array from C to R format. Parameters and buffers for the conversion are passed via the R_nc_buf struct. On input, the C data is stored in io->cbuf. On output, the R data is copied to io->rxp, and memory used by netcdf is freed. */ static void R_nc_vlen_vecsxp (R_nc_buf *io) { size_t ii, cnt, size, basesize, basefillsize; nc_type basetype; nc_vlen_t *vbuf, *vfill; R_nc_buf tmpio; SEXP tmprxp; int baseclass, hasfill; const void *basefill; vbuf = io->cbuf; cnt = xlength (io->rxp); R_nc_check (nc_inq_user_type (io->ncid, io->xtype, NULL, &size, &basetype, NULL, NULL)); if (basetype > NC_MAX_ATOMIC_TYPE) { R_nc_check (nc_inq_user_type (io->ncid, basetype, NULL, &basesize, NULL, NULL, &baseclass)); } else { R_nc_check (nc_inq_type (io->ncid, basetype, NULL, &basesize)); baseclass = NC_NAT; } /* Check if fill value is properly defined */ hasfill = (io->fill != NULL && io->fillsize == size); basefill = NULL; basefillsize = 0; if (hasfill) { vfill = (nc_vlen_t *) io->fill; if (vfill[0].len > 0) { basefill = vfill[0].p; basefillsize = basesize; } } /* Convert vlen elements to list items */ for (ii=0; iincid, basetype, -1, &(vbuf[ii].len), io->rawchar, io->fitnum, basefillsize, basefill, io->min, io->max, io->scale, io->add)); R_nc_c2r (&tmpio); SET_VECTOR_ELT (io->rxp, ii, tmprxp); if (vbuf[ii].len > 0) { /* nc_free_vlen fails if length is 0; no need to free anyway */ nc_free_vlen(&(vbuf[ii])); } UNPROTECT(1); } } /* -- Opaque class -- */ /* Convert raw array from R to netcdf opaque type. Memory for the result is allocated if necessary (and freed by R). In special cases, the output may point to the input data, so the output data should not be modified. */ static const char * R_nc_raw_opaque (SEXP rv, int ncid, nc_type xtype, int ndim, const size_t *xdim) { size_t cnt, size; R_nc_check (nc_inq_user_type (ncid, xtype, NULL, &size, NULL, NULL, NULL)); cnt = R_nc_length (ndim, xdim); if ((size_t) xlength (rv) < (cnt * size)) { error (RNC_EDATALEN); } return (const char *) RAW (rv); } static SEXP R_nc_opaque_raw_init (R_nc_buf *io) { int ndim; size_t *xdim, size; /* Fastest varying dimension of R array contains bytes of opaque data */ R_nc_check (nc_inq_user_type (io->ncid, io->xtype, NULL, &size, NULL, NULL, NULL)); ndim = io->ndim; if (ndim < 0) { /* Special case for an R vector without dimension attribute, but dimensions are needed to select opaque elements of a vector */ ndim = 1; } xdim = (size_t *) R_alloc (ndim + 1, sizeof(size_t)); if (ndim != 0) { /* Scalar has no dimensions to copy */ memcpy (xdim, io->xdim, ndim * sizeof(size_t)); } xdim[ndim] = size; io->rxp = PROTECT(R_nc_allocArray (RAWSXP, ndim + 1, xdim)); io->rbuf = RAW (io->rxp); if (!io->cbuf) { io->cbuf = io->rbuf; } UNPROTECT(1); return io->rxp; } static void R_nc_opaque_raw (R_nc_buf *io) { if (io->cbuf != io->rbuf) { memcpy(io->rbuf, io->cbuf, xlength(io->rxp) * sizeof(char)); } return; } /* -- Enum class -- */ /* Convert factor array from R to netcdf enum type. Memory for the result is allocated if necessary (and freed by R). */ static void * R_nc_factor_enum (SEXP rv, int ncid, nc_type xtype, int ndim, const size_t *xdim, size_t fillsize, const void *fill) { SEXP levels; size_t size, imem, nmem, ilev, nlev, *ilev2mem, ifac, nfac, cnt; char *memnames, *memname, *memvals, *memval, *out; const char **levnames; int hasfill, ismatch, *in, inval; /* Extract indices and level names of R factor */ in = INTEGER (rv); levels = getAttrib (rv, R_LevelsSymbol); if (!isString (levels)) { error ("Expected character vector for levels of factor array"); } nlev = xlength (levels); levnames = (const char **) R_alloc (nlev, sizeof(size_t)); for (ilev=0; ilevrxp = PROTECT(R_nc_allocArray (INTSXP, io->ndim, io->xdim)); io->rbuf = INTEGER (io->rxp); if (!io->cbuf) { R_nc_check (nc_inq_type (io->ncid, io->xtype, NULL, &size)); io->cbuf = R_alloc (xlength (io->rxp), size); } UNPROTECT(1); return io->rxp; } /* Convert specified number of bytes to an R symbol, as required to store and retrieve values from a hashed environment. The work array must have minimum size 2*size+2 bytes. */ static SEXP R_nc_char_symbol (char *in, size_t size, char *work) { size_t ii; work[0]='X'; for (ii=0; iicbuf to R factor array in io->rbuf. Memory for the result must be pre-allocated by R_nc_enum_factor_init. */ static void R_nc_enum_factor (R_nc_buf *io) { SEXP levels, env, cmd, symbol, index; size_t size, nmem, ifac, nfac; char *memname, *memval, *work, *inval; int ncid, imem, imemmax, *out, any_undef; nc_type xtype; /* Get size and number of enum members */ ncid = io->ncid; xtype = io->xtype; R_nc_check (nc_inq_enum(ncid, xtype, NULL, NULL, &size, &nmem)); /* Set attributes for R factor */ levels = PROTECT(R_nc_allocArray (STRSXP, -1, &nmem)); setAttrib(io->rxp, R_LevelsSymbol, levels); setAttrib(io->rxp, R_ClassSymbol, mkString("factor")); /* Create a hashed environment for value-index pairs. Members inherit PROTECTion from the env. */ cmd = PROTECT(lang1 (install ("new.env"))); env = PROTECT(eval (cmd, R_BaseEnv)); /* Read values and names of netcdf enum members. Store names as R factor levels. Store values and their R indices (1-based) in hashed environment. */ memname = R_alloc (nmem, NC_MAX_NAME+1); memval = R_alloc (1, size); work = R_alloc (2*size+2, 1); imemmax = nmem; // netcdf member index is int for (imem=0; imemfill != NULL && io->fillsize == size) { symbol = PROTECT (R_nc_char_symbol (io->fill, size, work)); index = PROTECT (ScalarInteger( NA_INTEGER)); defineVar (symbol, index, env); UNPROTECT(2); } /* Convert netcdf enum values to R indices. Use hashed environment prepared above for efficient lookups. */ nfac = xlength (io->rxp); out = io->rbuf; any_undef = 0; for (ifac=0, inval=io->cbuf; ifac 0) { /* Use the first element of this field in fill as the fill value, because fill values are generally required to be scalar; this allows us to convert arrays with a single R_nc_r2c call. */ fillfld = (const char *) fill + offset; fillfldlen = fldsize; } else { fillfld = NULL; fillfldlen = 0; } buffld = R_nc_r2c (PROTECT(VECTOR_ELT (rv, ilist)), ncid, typefld, ndimfld+1, dimsizefld, fillfldlen, fillfld, NULL, NULL); UNPROTECT(1); /* Copy elements from the field array into the compound array */ for (ielem=0; ielemncid) == NC_NOERR) { /* Dataset must be writable because it is now in define mode */ error ("Please read compound type from a read-only dataset"); } /* Get number of fields in compound type */ R_nc_check (nc_inq_compound(io->ncid, io->xtype, NULL, &size, &nfld)); /* Allocate memory for output list */ io->rxp = PROTECT(R_nc_allocArray (VECSXP, -1, &nfld)); /* Allocate memory for compound array */ if (!io->cbuf) { cnt = R_nc_length (io->ndim, io->xdim); io->cbuf = R_alloc (cnt, size); } UNPROTECT(1); return io->rxp; } /* Convert netcdf compound values in io->cbuf to R list of arrays in io->rxp. Data structures are prepared by a prior call to R_nc_compound_vecsxp_init. */ static void R_nc_compound_vecsxp (R_nc_buf *io) { int ncid, ifld, ifldmax, idim, ndim, idimfld, ndimfld, *dimlenfld, ndimslice; int hasfill; nc_type xtype, typefld; size_t size, nfld, cnt, offset, fldsize, *dimslice, fldcnt, fldlen, ielem; size_t fillfldlen; SEXP namelist, rxpfld; char namefld[NC_MAX_NAME+1], *buffld, *bufcmp; R_nc_buf iofld; void *highwater; const char *fillfld; /* Get size and number of fields in compound type */ ncid = io->ncid; xtype = io->xtype; R_nc_check (nc_inq_compound(ncid, xtype, NULL, &size, &nfld)); cnt = R_nc_length (io->ndim, io->xdim); /* Check if fill value is properly defined */ hasfill = (io->fill != NULL && io->fillsize == size); /* Set names attribute of R list */ namelist = PROTECT(R_nc_allocArray (STRSXP, -1, &nfld)); setAttrib(io->rxp, R_NamesSymbol, namelist); /* Convert each field in turn */ bufcmp = io->cbuf; ifldmax = nfld; for (ifld=0; ifldndim; if (ndim < 0) { /* Special case to drop dimensions of a vector, but dimensions are needed for a compound vector. */ ndim = 1; } ndim = io->ndim < 0 ? 1 : io->ndim ; ndimslice = ndim + ndimfld; dimslice = (size_t *) R_alloc (ndimslice, sizeof(size_t)); for (idim=0; idimxdim[idim]; } for (idimfld=0; idimfld 0) { fillfld = (const char *) io->fill + offset; fillfldlen = fldsize; } else { fillfld = NULL; fillfldlen = 0; } buffld = NULL; rxpfld = PROTECT(R_nc_c2r_init (&iofld, (void **) &buffld, ncid, typefld, ndimslice, dimslice, io->rawchar, io->fitnum, fillfldlen, fillfld, NULL, NULL, NULL, NULL)); /* Copy elements from the compound array into the field array */ for (ielem=0; ielemrxp, ifld, rxpfld); /* Allow memory from R_alloc since vmaxget to be reclaimed */ UNPROTECT(1); vmaxset (highwater); } UNPROTECT(1); } /*=============================================================================*\ * Generic type conversions \*=============================================================================*/ const void * R_nc_r2c (SEXP rv, int ncid, nc_type xtype, int ndim, const size_t *xdim, size_t fillsize, const void *fill, const double *scale, const double *add) { int pack, class; pack = (scale || add); if (xtype > NC_MAX_ATOMIC_TYPE) { R_nc_check (nc_inq_user_type (ncid, xtype, NULL, NULL, NULL, NULL, &class)); } switch (TYPEOF(rv)) { case INTSXP: if (pack) { switch (xtype) { case NC_BYTE: return R_nc_r2c_pack_int_schar (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UBYTE: return R_nc_r2c_pack_int_uchar (rv, ndim, xdim, fillsize, fill, scale, add); case NC_SHORT: return R_nc_r2c_pack_int_short (rv, ndim, xdim, fillsize, fill, scale, add); case NC_USHORT: return R_nc_r2c_pack_int_ushort (rv, ndim, xdim, fillsize, fill, scale, add); case NC_INT: return R_nc_r2c_pack_int_int (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UINT: return R_nc_r2c_pack_int_uint (rv, ndim, xdim, fillsize, fill, scale, add); case NC_INT64: return R_nc_r2c_pack_int_ll (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UINT64: return R_nc_r2c_pack_int_ull (rv, ndim, xdim, fillsize, fill, scale, add); case NC_FLOAT: return R_nc_r2c_pack_int_float (rv, ndim, xdim, fillsize, fill, scale, add); case NC_DOUBLE: return R_nc_r2c_pack_int_dbl (rv, ndim, xdim, fillsize, fill, scale, add); } } else { switch (xtype) { case NC_BYTE: return R_nc_r2c_int_schar (rv, ndim, xdim, fillsize, fill); case NC_UBYTE: return R_nc_r2c_int_uchar (rv, ndim, xdim, fillsize, fill); case NC_SHORT: return R_nc_r2c_int_short (rv, ndim, xdim, fillsize, fill); case NC_USHORT: return R_nc_r2c_int_ushort (rv, ndim, xdim, fillsize, fill); case NC_INT: return R_nc_r2c_int_int (rv, ndim, xdim, fillsize, fill); case NC_UINT: return R_nc_r2c_int_uint (rv, ndim, xdim, fillsize, fill); case NC_INT64: return R_nc_r2c_int_ll (rv, ndim, xdim, fillsize, fill); case NC_UINT64: return R_nc_r2c_int_ull (rv, ndim, xdim, fillsize, fill); case NC_FLOAT: return R_nc_r2c_int_float (rv, ndim, xdim, fillsize, fill); case NC_DOUBLE: return R_nc_r2c_int_dbl (rv, ndim, xdim, fillsize, fill); } } if (xtype > NC_MAX_ATOMIC_TYPE && class == NC_ENUM && R_nc_inherits (rv, "factor")) { return R_nc_factor_enum (rv, ncid, xtype, ndim, xdim, fillsize, fill); } break; case REALSXP: if (pack) { if (R_nc_inherits (rv, "integer64")) { switch (xtype) { case NC_BYTE: return R_nc_r2c_pack_bit64_schar (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UBYTE: return R_nc_r2c_pack_bit64_uchar (rv, ndim, xdim, fillsize, fill, scale, add); case NC_SHORT: return R_nc_r2c_pack_bit64_short (rv, ndim, xdim, fillsize, fill, scale, add); case NC_USHORT: return R_nc_r2c_pack_bit64_ushort (rv, ndim, xdim, fillsize, fill, scale, add); case NC_INT: return R_nc_r2c_pack_bit64_int (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UINT: return R_nc_r2c_pack_bit64_uint (rv, ndim, xdim, fillsize, fill, scale, add); case NC_INT64: return R_nc_r2c_pack_bit64_ll (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UINT64: return R_nc_r2c_pack_bit64_ull (rv, ndim, xdim, fillsize, fill, scale, add); case NC_FLOAT: return R_nc_r2c_pack_bit64_float (rv, ndim, xdim, fillsize, fill, scale, add); case NC_DOUBLE: return R_nc_r2c_pack_bit64_dbl (rv, ndim, xdim, fillsize, fill, scale, add); } } else { switch (xtype) { case NC_BYTE: return R_nc_r2c_pack_dbl_schar (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UBYTE: return R_nc_r2c_pack_dbl_uchar (rv, ndim, xdim, fillsize, fill, scale, add); case NC_SHORT: return R_nc_r2c_pack_dbl_short (rv, ndim, xdim, fillsize, fill, scale, add); case NC_USHORT: return R_nc_r2c_pack_dbl_ushort (rv, ndim, xdim, fillsize, fill, scale, add); case NC_INT: return R_nc_r2c_pack_dbl_int (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UINT: return R_nc_r2c_pack_dbl_uint (rv, ndim, xdim, fillsize, fill, scale, add); case NC_INT64: return R_nc_r2c_pack_dbl_ll (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UINT64: return R_nc_r2c_pack_dbl_ull (rv, ndim, xdim, fillsize, fill, scale, add); case NC_FLOAT: return R_nc_r2c_pack_dbl_float (rv, ndim, xdim, fillsize, fill, scale, add); case NC_DOUBLE: return R_nc_r2c_pack_dbl_dbl (rv, ndim, xdim, fillsize, fill, scale, add); } } } else { if (R_nc_inherits (rv, "integer64")) { switch (xtype) { case NC_BYTE: return R_nc_r2c_bit64_schar (rv, ndim, xdim, fillsize, fill); case NC_UBYTE: return R_nc_r2c_bit64_uchar (rv, ndim, xdim, fillsize, fill); case NC_SHORT: return R_nc_r2c_bit64_short (rv, ndim, xdim, fillsize, fill); case NC_USHORT: return R_nc_r2c_bit64_ushort (rv, ndim, xdim, fillsize, fill); case NC_INT: return R_nc_r2c_bit64_int (rv, ndim, xdim, fillsize, fill); case NC_UINT: return R_nc_r2c_bit64_uint (rv, ndim, xdim, fillsize, fill); case NC_INT64: return R_nc_r2c_bit64_ll (rv, ndim, xdim, fillsize, fill); case NC_UINT64: return R_nc_r2c_bit64_ull (rv, ndim, xdim, fillsize, fill); case NC_FLOAT: return R_nc_r2c_bit64_float (rv, ndim, xdim, fillsize, fill); case NC_DOUBLE: return R_nc_r2c_bit64_dbl (rv, ndim, xdim, fillsize, fill); } } else { switch (xtype) { case NC_BYTE: return R_nc_r2c_dbl_schar (rv, ndim, xdim, fillsize, fill); case NC_UBYTE: return R_nc_r2c_dbl_uchar (rv, ndim, xdim, fillsize, fill); case NC_SHORT: return R_nc_r2c_dbl_short (rv, ndim, xdim, fillsize, fill); case NC_USHORT: return R_nc_r2c_dbl_ushort (rv, ndim, xdim, fillsize, fill); case NC_INT: return R_nc_r2c_dbl_int (rv, ndim, xdim, fillsize, fill); case NC_UINT: return R_nc_r2c_dbl_uint (rv, ndim, xdim, fillsize, fill); case NC_INT64: return R_nc_r2c_dbl_ll (rv, ndim, xdim, fillsize, fill); case NC_UINT64: return R_nc_r2c_dbl_ull (rv, ndim, xdim, fillsize, fill); case NC_FLOAT: return R_nc_r2c_dbl_float (rv, ndim, xdim, fillsize, fill); case NC_DOUBLE: return R_nc_r2c_dbl_dbl (rv, ndim, xdim, fillsize, fill); } } } break; case STRSXP: switch (xtype) { case NC_CHAR: return R_nc_strsxp_char (rv, ndim, xdim, fillsize, fill); case NC_STRING: return R_nc_strsxp_str (rv, ndim, xdim, fillsize, fill); } break; case RAWSXP: if (xtype == NC_CHAR) { return R_nc_raw_char (rv, ndim, xdim); } else if (xtype > NC_MAX_ATOMIC_TYPE && class == NC_OPAQUE) { return R_nc_raw_opaque (rv, ncid, xtype, ndim, xdim); } break; case VECSXP: if (xtype > NC_MAX_ATOMIC_TYPE) { switch (class) { case NC_VLEN: return R_nc_vecsxp_vlen (rv, ncid, xtype, ndim, xdim, fillsize, fill, scale, add); case NC_COMPOUND: return R_nc_vecsxp_compound (rv, ncid, xtype, ndim, xdim, fillsize, fill); } } break; } error (RNC_EDATATYPE); } SEXP \ R_nc_c2r_init (R_nc_buf *io, void **cbuf, int ncid, nc_type xtype, int ndim, const size_t *xdim, int rawchar, int fitnum, size_t fillsize, const void *fill, const void *min, const void *max, const double *scale, const double *add) { int class; if (!io) { error ("Pointer to R_nc_buf must not be NULL in R_nc_c2r_init"); } /* Initialise the R_nc_buf, making copies of pointer arguments */ io->rxp = NULL; io->cbuf = NULL; io->rbuf = NULL; io->xtype = xtype; io->ncid = ncid; io->ndim = ndim; io->rawchar = rawchar; io->fitnum = fitnum; io->xdim = NULL; io->fillsize = fillsize; io->fill = NULL; io->min = NULL; io->max = NULL; io->scale = NULL; io->add = NULL; if (cbuf) { io->cbuf = *cbuf; } if (xdim) { if (ndim > 0) { io->xdim = (size_t *) R_alloc (ndim, sizeof(size_t)); memcpy (io->xdim, xdim, ndim*sizeof(size_t)); } else if (ndim < 0) { /* Special case for vector without dim attribute */ io->xdim = (size_t *) R_alloc (1, sizeof(size_t)); memcpy (io->xdim, xdim, sizeof(size_t)); } /* Scalar has no dimensions */ } if (fill) { io->fill = R_alloc (1, fillsize); memcpy (io->fill, fill, fillsize); } if (min) { io->min = R_alloc (1, fillsize); memcpy (io->min, min, fillsize); } if (max) { io->max = R_alloc (1, fillsize); memcpy (io->max, max, fillsize); } if (scale) { io->scale = (double *) R_alloc (1, sizeof(double)); *(io->scale) = *scale; } if (add) { io->add = (double *) R_alloc (1, sizeof(double)); *(io->add) = *add; } /* Prepare buffers */ switch (xtype) { case NC_BYTE: case NC_UBYTE: case NC_SHORT: case NC_USHORT: case NC_INT: if (fitnum && !scale && !add) { PROTECT(R_nc_c2r_int_init (io)); break; } case NC_INT64: case NC_UINT64: if (fitnum && !scale && !add) { PROTECT(R_nc_c2r_bit64_init (io)); classgets(io->rxp, mkString("integer64")); break; } case NC_UINT: case NC_FLOAT: case NC_DOUBLE: PROTECT(R_nc_c2r_dbl_init (io)); break; case NC_CHAR: if (rawchar) { PROTECT(R_nc_char_raw_init (io)); } else { PROTECT(R_nc_char_strsxp_init (io)); } break; case NC_STRING: PROTECT(R_nc_str_strsxp_init (io)); break; default: if (xtype > NC_MAX_ATOMIC_TYPE) { R_nc_check (nc_inq_user_type (ncid, xtype, NULL, NULL, NULL, NULL, &class)); switch (class) { case NC_COMPOUND: PROTECT(R_nc_compound_vecsxp_init (io)); break; case NC_ENUM: PROTECT(R_nc_enum_factor_init (io)); break; case NC_VLEN: PROTECT(R_nc_vlen_vecsxp_init (io)); break; case NC_OPAQUE: PROTECT(R_nc_opaque_raw_init (io)); break; default: error (RNC_ETYPEDROP); } } else { error (RNC_ETYPEDROP); } } if (cbuf) { *cbuf = io->cbuf; } UNPROTECT(1); return io->rxp; } void R_nc_c2r (R_nc_buf *io) { int unpack, class; unpack = (io->scale || io->add); /* Type conversions */ switch (io->xtype) { case NC_BYTE: if (unpack) { R_nc_c2r_unpack_schar (io); } else if (io->fitnum) { R_nc_c2r_schar_int (io); } else { R_nc_c2r_schar_dbl (io); } break; case NC_UBYTE: if (unpack) { R_nc_c2r_unpack_uchar (io); } else if (io->fitnum) { R_nc_c2r_uchar_int (io); } else { R_nc_c2r_uchar_dbl (io); } break; case NC_SHORT: if (unpack) { R_nc_c2r_unpack_short (io); } else if (io->fitnum) { R_nc_c2r_short_int (io); } else { R_nc_c2r_short_dbl (io); } break; case NC_USHORT: if (unpack) { R_nc_c2r_unpack_ushort (io); } else if (io->fitnum) { R_nc_c2r_ushort_int (io); } else { R_nc_c2r_ushort_dbl (io); } break; case NC_INT: if (unpack) { R_nc_c2r_unpack_int (io); } else if (io->fitnum) { R_nc_c2r_int_int (io); } else { R_nc_c2r_int_dbl (io); } break; case NC_UINT: if (unpack) { R_nc_c2r_unpack_uint (io); } else { R_nc_c2r_uint_dbl (io); } break; case NC_FLOAT: if (unpack) { R_nc_c2r_unpack_float (io); } else { R_nc_c2r_float_dbl (io); } break; case NC_DOUBLE: if (unpack) { R_nc_c2r_unpack_dbl (io); } else { R_nc_c2r_dbl_dbl (io); } break; case NC_INT64: if (unpack) { R_nc_c2r_unpack_int64 (io); } else if (io->fitnum) { R_nc_c2r_int64_bit64 (io); } else { R_nc_c2r_int64_dbl (io); } break; case NC_UINT64: if (unpack) { R_nc_c2r_unpack_uint64 (io); } else if (io->fitnum) { R_nc_c2r_uint64_bit64 (io); } else { R_nc_c2r_uint64_dbl (io); } break; case NC_CHAR: if (io->rawchar) { R_nc_char_raw (io); } else { R_nc_char_strsxp (io); } break; case NC_STRING: R_nc_str_strsxp (io); break; default: if (io->xtype > NC_MAX_ATOMIC_TYPE) { R_nc_check (nc_inq_user_type ( io->ncid, io->xtype, NULL, NULL, NULL, NULL, &class)); switch (class) { case NC_COMPOUND: R_nc_compound_vecsxp (io); break; case NC_ENUM: R_nc_enum_factor (io); break; case NC_VLEN: R_nc_vlen_vecsxp (io); break; case NC_OPAQUE: R_nc_opaque_raw (io); break; default: error (RNC_ETYPEDROP); } } else { error (RNC_ETYPEDROP); } } } /*=============================================================================*\ * Dimension conversions \*=============================================================================*/ /* Reverse a vector in-place. Example: R_nc_rev_int (cv, cnt); */ dnl R_NC_REVERSE(FUN, TYPE) define(`R_NC_REVERSE',`dnl pushdef(`FUN',`$1')dnl pushdef(`TYPE',`$2')dnl void FUN (TYPE *data, size_t cnt) { size_t ii, jj; TYPE tmp; if (cnt<=0) return; for (ii=0, jj=cnt-1; ii&2 exit 1 fi newver="$1" if ! echo "$newver" | grep -q '^[0-9]\+.[0-9]\+-[0-9]\+$' ; then echo "ERROR: invalid format of release string" >&2 exit 1 fi # Set working directory to base directory of package: thisdir="$( dirname "$0" )" cd "$thisdir/.." # Use GNU versions of some utilities: kernel=$( uname ) if [[ "$kernel" == Darwin ]]; then alias date=gdate # MacPorts coreutils alias find=gfind # MacPorts findutils alias sed=gsed # MacPorts gsed fi # Define function to convert date formats: DATEFMT() { date -d "$1" +%Y%m%d%H%M.%S } # Check that package changes have been committed to git: if test -n "$( git status --porcelain )"; then echo "WARNING: uncommitted changes in package" >&2 fi # Ensure that generated files are up-to-date: tools/update-configure.sh tools/update-convert-c.sh # Check that NEWS contains a description of the release: if ! grep -q "$newver" NEWS; then echo "WARNING: NEWS has no entry for release $newver" >&2 fi # Get existing version string: oldver="$( grep 'Version: ' DESCRIPTION | awk '{ print $2 }' )" # Define copyright line: year=$( date +%Y ) copyright="Copyright (C) 2004-$year Pavel Michna and Milton Woods." # Replace version string in all files (excluding hidden files). find . -mindepth 1 -name '.*' -prune -o -type f \ ! -name NEWS ! -name release.sh -print | while read file; do sed -i "/RNetCDF\|[Vv][Ee][Rr][Ss][Ii][Oo][Nn]/ s|$oldver|$newver|g; /Copyright.*Michna/ s|\(.*\)Copyright.*|\1$copyright|" "$file" done # Update release date in DESCRIPTION: newdate="$( date +%Y-%m-%d )" sed -i "s|Date:.*|Date: $newdate|" DESCRIPTION RNetCDF/cleanup.win0000755000176200001440000000013214577713273013624 0ustar liggesusers#!/bin/sh rm -rf *.cache rm -f ./config.* rm -f ./src/Makevars rm -f ./src/*.so ./src/*.o RNetCDF/INSTALL0000644000176200001440000001325214577720574012515 0ustar liggesusersThis file describes the command line arguments which can be passed during installation of the RNetCDF package and gives some further hints. Software Requirements ===================== NetCDF library version 4.1.3 or greater. UDUNITS library version 2.0.4 or greater (optional, for calendar functions). On platforms that support both 32- and 64-bit executables, ensure that the above libraries and the R executable are compatible. Mixing 32-bit and 64-bit software will generally not work. R CMD INSTALL Options ===================== Libraries and include files are usually detected automatically by nc-config, which is part of most NetCDF4 installations. If this causes problems, you can disable nc-config using --without-nc-config. Shared or static libraries can be requested from nc-config, based on configure option --with-nc-config-static. Default values of this setting vary by platform, with shared libraries typically used in Unix-alikes and static libraries on Windows and macOS. The configure script can accept variables to define extra directories and libraries: CPPFLAGS='-I [-I ...]' # extra directories of header files LDFLAGS='-L [-L ...]' # extra directories for libraries LIBS='-l [-l ...]' # extra libraries to link Definitions for the above variables may be appended to the configure command line or passed through the environment. The final set of directories and libraries is obtained by joining variables from nc-config (if enabled), the above variables, and settings used when building R, in that order. The directories are searched in left-to-right order for required header files or libraries. The libraries are searched in left-to-right order for functions. Some R installations prepend the R library directory when linking the RNetCDF shared library, which may cause problems in rare cases when unwanted versions of other libraries are installed in the same directory. A possible solution involves passing the full pathname of the desired library through the LIBS variable, as explained below. Note that libraries may be specified in LIBS in a few different ways. The most common way is '-l' as shown above, and the compiler will typically search for a library called lib.so and then lib.a. But you can also specify the full pathname of a library if necessary, perhaps to force the use of a particular NetCDF or udunits library on systems with multiple versions available. MPI Support =========== Message Passing Interface (MPI) is a standardised method for programs to communicate between multiple processes within a machine or across machines. The NetCDF library has optional support for MPI, which allows multiple processes to read and write a shared NetCDF dataset. This ensures that NetCDF metadata is consistent across processes, while allowing parallel processing of huge datasets. Simple examples using RNetCDF with MPI are given in the demos directory of RNetCDF. These examples will be run as tests in R CMD check if NetCDF parallel I/O support is detected, packages Rmpi or pbdMPI are installed, and option --with-mpiexec is specified. Most MPI installations provide a compiler driver (e.g. mpicc) that simplifies the building of MPI software. This involves setting paths to headers and libraries, as well as linking libraries, in ways that may depend on compiler flags. The configure script has an option --with-mpicc=..., which allows the MPI compiler command to be specified. The MPI compiler command should be the same as that used when building the NetCDF library, which can often be found by running the command 'nc-config --cc'. Note that the NetCDF library supports several distinct file formats, and parallel I/O support is implemented separately for netcdf4 (hdf5) format and earlier formats. It is possible to build the NetCDF library with parallel I/O support for some, all, or none of the file formats. Installation of RNetCDF should succeed regardless, but RNetCDF will return errors when attempting to use parallel I/O on unsupported file formats. R CMD INSTALL Example ===================== R CMD INSTALL --configure-args="CPPFLAGS=-I/sw/include \ LDFLAGS=-L/sw/lib LIBS=-lhdf5 --with-mpicc=mpicc --with-mpiexec=mpiexec" \ RNetCDF_2.9-2.tar.gz LD_LIBRARY_PATH =============== If a runtime error occurs indicating that shared libraries cannot be found, you may need to set or modify the library search path to include directories where NetCDF, HDF5 and/or UDUNITS libraries are stored. This is sometimes necessary for custom installations of the libraries. The library search path is typically influenced by the environment variable LD_LIBRARY_PATH (or DYLD_LIBRARY_PATH for Mac OSX). For example: export LD_LIBRARY_PATH=/sw/lib:$LD_LIBRARY_PATH On some systems, it is possible to build R packages so that dependencies are found automatically at runtime. For example, some linkers provide an option such as '-rpath', which embeds the library search path when creating an executable or shared library. It may also be possible to avoid runtime dependencies by building your R package against static libraries (*.a), but this will only work if the functions in the libraries were compiled as position independent code (e.g. using the -fPIC option of gcc). R CMD check Example =================== R CMD check --install-args="--configure-args='CPPFLAGS=-I/sw/include \ LDFLAGS=-L/sw/lib'" RNetCDF_2.9-2.tar.gz Time units ========== Common udunits databases are distributed with RNetCDF, and these are used by default when RNetCDF is loaded by R. However, a different units database may be used by specifying the appropriate file in environment variable UDUNITS2_XML_PATH. RNetCDF/README.md0000644000176200001440000000071214577713273012736 0ustar liggesusers# RNetCDF - Interface to NetCDF Datasets for R RNetCDF provides an R interface to the NetCDF file format designed by Unidata for efficient storage of array-oriented scientific data and descriptions. This R interface is closely based on the C API of the NetCDF4 library, and it includes calendar conversions from the Unidata UDUNITS2 library. An introduction to the RNetCDF package is given in http://journal.r-project.org/archive/2013-2/michna-woods.pdf . RNetCDF/man/0000755000176200001440000000000014577713273012232 5ustar liggesusersRNetCDF/man/read.nc.Rd0000644000176200001440000000431614577713273014037 0ustar liggesusers\name{read.nc} \alias{read.nc} \title{Read a NetCDF Dataset} \description{Read all data from a NetCDF dataset.} \usage{ read.nc(ncfile, recursive=FALSE, ...) } \arguments{ \item{ncfile}{Object of class \code{NetCDF} which points to the NetCDF dataset (as returned from \code{\link[RNetCDF]{open.nc}}).} \item{recursive}{Descend recursively into any groups in the dataset if \code{TRUE}.} \item{...}{Optional arguments passed to \code{var.get.nc}.} } \value{A list with the list elements containing an array for each variable or a (possibly nested) list for each group in the NetCDF dataset.} \details{This function reads all variable data from a NetCDF dataset into a list. The list elements (arrays) have the same names as the variables in the NetCDF dataset. Groups in the dataset may optionally be read recursively and returned as nested lists. Each list has the name of the corresponding group in the dataset. } \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ ## Create a new NetCDF dataset file1 <- tempfile("read_", fileext=".nc") nc <- create.nc(file1, format="netcdf4") dim.def.nc(nc, "station", 5) dim.def.nc(nc, "time", unlim=TRUE) dim.def.nc(nc, "max_string_length", 32) ## Create two coordinate variables var.def.nc(nc, "time", "NC_INT", "time") var.def.nc(nc, "name", "NC_CHAR", c("max_string_length", "station")) ## Create a group to contain the data # This is not necessary, but shows it can be done. grp <- grp.def.nc(nc, "data") ## Create a data variable var.def.nc(grp, "temperature", "NC_DOUBLE", c("station","time")) ## Put some _FillValue attribute for temperature att.put.nc(grp, "temperature", "_FillValue", "NC_DOUBLE", -99999.9) ## Define variable values mytime <- c(1:2) mytemperature <- c(1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, NA, NA, 9.9) myname <- c("alfa", "bravo", "charlie", "delta", "echo") ## Put the data var.put.nc(nc, "time", mytime, 1, length(mytime)) var.put.nc(nc, "name", myname, c(1,1), c(32,5)) var.put.nc(grp, "temperature", mytemperature, c(1,1), c(5,2)) sync.nc(nc) ## Read the dataset, including the contents of any groups read.nc(nc, recursive=TRUE) close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/var.def.nc.Rd0000644000176200001440000001105414577713273014446 0ustar liggesusers\name{var.def.nc} \alias{var.def.nc} \title{Define a NetCDF Variable} \description{Define a new NetCDF variable.} \usage{var.def.nc(ncfile, varname, vartype, dimensions, chunking=NA, chunksizes=NULL, deflate=NA, shuffle=FALSE, big_endian=NA, fletcher32=FALSE, filter_id=integer(0), filter_params=list())} \arguments{ Arguments marked \code{"netcdf4"} are optional for datasets in that format and ignored for other formats. \item{ncfile}{Object of class \code{NetCDF} which points to the NetCDF dataset (as returned from \code{\link[RNetCDF]{open.nc}}).} \item{varname}{Variable name. Must begin with an alphabetic character, followed by zero or more alphanumeric characters including the underscore (\code{"_"}). Case is significant.} \item{vartype}{External NetCDF data type as one of the following labels: \code{NC_BYTE}, \code{NC_UBYTE}, \code{NC_CHAR}, \code{NC_SHORT}, \code{NC_USHORT}, \code{NC_INT}, \code{NC_UINT}, \code{NC_INT64}, \code{NC_UINT64}, \code{NC_FLOAT}, \code{NC_DOUBLE}, \code{NC_STRING}, or a user-defined type name.} \item{dimensions}{Vector of \code{ndims} dimension IDs or their names corresponding to the variable dimensions or \code{NA} if a scalar variable should be created. If the ID (or name) of the unlimited dimension is included, it must be last.} \item{chunking}{(\code{"netcdf4"}) \code{TRUE} selects chunking, \code{FALSE} implies contiguous storage, \code{NA} allows the NetCDF library to choose a storage layout. Ignored for scalar variables.} \item{chunksizes}{(\code{"netcdf4"}) Chunk size expressed as the number of elements along each dimension, in the same order as \code{dimensions}. If \code{NULL}, the NetCDF library uses a default chunking strategy, which is intended to give reasonable performance in typical applications. Ignored unless \code{chunking} is \code{TRUE}.} \item{deflate}{(\code{"netcdf4"}) Integer indicating level of compression, from 0 (minimum) to 9 (maximum), or \code{NA} for no compression.} \item{shuffle}{(\code{"netcdf4"}) \code{TRUE} to enable byte shuffling, which may improve compression with \code{deflate}.} \item{big_endian}{(\code{"netcdf4"}) Byte order of the variable. \code{TRUE} for big-endian, \code{FALSE} for little-endian, \code{NA} for native endianness of the platform.} \item{fletcher32}{(\code{"netcdf4"}) \code{TRUE} to enable the fletcher32 checksum.} \item{filter_id}{(\code{"netcdf4"}) Vector of filter IDs to associate with the variable (empty vector denotes no filters). For information about the available filters, please see the NetCDF documentation. Ignored if the installed NetCDF library does not support the multi-filter interface.} \item{filter_params}{(\code{"netcdf4"}) List with one element for each \code{filter_id}. Each list member is a vector of \code{numeric} parameters (which are converted to unsigned integers). The meaning of the parameters depends on the filter implementation, and RNetCDF is unable to perform any validation. Ignored if the installed NetCDF library does not support the multi-filter interface.} } \value{NetCDF variable identifier, returned invisibly.} \details{This function creates a new NetCDF variable. A NetCDF variable has a name, a type, and a shape, which are specified when it is defined. A variable may also have values, which are established later in data mode. Ordinarily, the name, type, and shape are fixed when the variable is first defined. The name may be changed, but the type and shape of a variable cannot be changed. However, a variable defined in terms of the unlimited dimension can grow without bound in that dimension. The fastest varying dimension has to be first in \code{dimensions}, the slowest varying dimension last (this is the same way as an array is defined in R; i.e., opposite to the CDL conventions). A NetCDF variable in an open NetCDF dataset is referred to by a small integer called a variable ID. Variable IDs are 0, 1, 2,..., in the order in which the variables were defined within a NetCDF dataset. Attributes may be associated with a variable to specify such properties as units.} \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ ## Create a new NetCDF dataset and define two dimensions file1 <- tempfile("var.def_", fileext=".nc") nc <- create.nc(file1) dim.def.nc(nc, "station", 5) dim.def.nc(nc, "time", unlim=TRUE) ## Create two variables, one as coordinate variable var.def.nc(nc, "time", "NC_INT", "time") var.def.nc(nc, "temperature", "NC_DOUBLE", c(0,1)) close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/dim.inq.nc.Rd0000644000176200001440000000263714577713273014467 0ustar liggesusers\name{dim.inq.nc} \alias{dim.inq.nc} \title{Inquire About a NetCDF Dimension} \description{Inquire about a NetCDF dimension.} \usage{dim.inq.nc(ncfile, dimension)} \arguments{ \item{ncfile}{Object of class \code{NetCDF} which points to the NetCDF dataset (as returned from \code{\link[RNetCDF]{open.nc}}).} \item{dimension}{Either the ID or the name of the dimension to be inquired.} } \value{ A list containing the following components: \item{id}{Dimension ID.} \item{name}{Dimension name.} \item{length}{Length of dimension. For the unlimited dimension, this is the number of records written so far.} \item{unlim}{\code{TRUE} if it is the unlimited dimension, \code{FALSE} otherwise.} } \details{This function returns information about a NetCDF dimension. Information about a dimension include its name, its ID, its length and a flag if it is the unlimited dimension of this NetCDF dataset, if any. The length of the unlimited dimension, if any, is the number of records written so far.} \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ ## Create a new NetCDF dataset and define two dimensions file1 <- tempfile("dim.inq_", fileext=".nc") nc <- create.nc(file1) dim.def.nc(nc, "station", 5) dim.def.nc(nc, "time", unlim=TRUE) ## Inquire about the dimensions dim.inq.nc(nc, 0) dim.inq.nc(nc, "time") close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/var.put.nc.Rd0000644000176200001440000002141214577713273014517 0ustar liggesusers\name{var.put.nc} \alias{var.put.nc} \title{Write Data to a NetCDF Variable} \description{Write the contents of a NetCDF variable.} \usage{var.put.nc(ncfile, variable, data, start=NA, count=NA, na.mode=4, pack=FALSE, cache_bytes=NA, cache_slots=NA, cache_preemption=NA)} \arguments{ Arguments marked \code{"netcdf4"} are optional for datasets in that format and ignored for other formats. \item{ncfile}{Object of class \code{NetCDF} which points to the NetCDF dataset (as returned from \code{\link[RNetCDF]{open.nc}}).} \item{variable}{ID or name of the NetCDF variable.} \item{data}{An R vector or array of data to be written to the NetCDF variable. Values are taken from \code{data} in the order of R vector elements, so that leftmost indices vary fastest over an array.} \item{start}{A vector of indices specifying the element where writing starts along each dimension of \code{variable}. Indices are numbered from 1 onwards, and the order of dimensions is shown by \code{\link[RNetCDF]{print.nc}} (array elements are stored sequentially with leftmost indices varying fastest). By default (\code{start=NA}), all dimensions of \code{variable} are written from the first element onwards. Otherwise, \code{start} must be a vector whose length is not less than the number of dimensions in \code{variable} (excess elements are ignored). Any \code{NA} values in vector \code{start} are set to 1.} \item{count}{A vector of integers specifying the number of values to write along each dimension of \code{variable}. The order of dimensions is the same as for \code{start}. By default (\code{count=NA}), \code{count} is set to \code{dim(data)} for an array or \code{length(data)} for a vector. Otherwise, \code{count} must be a vector whose length is not less than the number of dimensions in \code{variable} (excess elements are ignored). Any \code{NA} value in vector \code{count} indicates that the corresponding dimension should be written from the \code{start} index to the end of the dimension. Note that an unlimited dimension initially has zero length, and the dimension is extended by setting the corresponding element of \code{count} greater than the current length.} \item{na.mode}{\code{NA} values in \code{data} are converted to a missing value in the NetCDF dataset. The missing value is defined by attributes of the NetCDF \code{variable}, which are selected by the following modes: \tabular{lll}{ mode \tab data type \tab attribute(s) \cr 0 \tab numeric \tab \code{_FillValue}, then \code{missing_value} \cr 1 \tab numeric \tab \code{_FillValue} only \cr 2 \tab numeric \tab \code{missing_value} only \cr 3 \tab any \tab no conversion \cr 4 \tab numeric \tab \code{valid_range} \code{valid_min}, \code{valid_max}, \code{_FillValue} \cr 5 \tab any \tab same as mode 4 for numeric types; \cr \tab \tab \code{_FillValue} for other types \cr } For explanation of attribute conventions used by mode 4, please see: \url{https://docs.unidata.ucar.edu/nug/current/attribute_conventions.html} } \item{pack}{Variables are packed if \code{pack=TRUE} and the attributes \code{add_offset} and/or \code{scale_factor} are defined. Default is \code{FALSE}.} \item{cache_bytes}{(\code{"netcdf4"}) Size of chunk cache in bytes. Value of \code{NA} (default) implies no change.} \item{cache_slots}{(\code{"netcdf4"}) Number of slots in chunk cache. Value of \code{NA} (default) implies no change.} \item{cache_preemption}{(\code{"netcdf4"}) Value between 0 and 1 (inclusive) that biases the cache scheme towards eviction of chunks that have been fully read. Value of \code{NA} (default) implies no change.} } \details{This function writes values to a NetCDF variable. Data values in R are automatically converted to the correct type of NetCDF variable. Text represented by R type \code{character} can be written to NetCDF types \code{NC_CHAR} and \code{NC_STRING}, and R type \code{raw} can be written to NetCDF type \code{NC_CHAR}. When writing to \code{NC_CHAR} variables, \code{character} variables have an implied dimension corresponding to the string length. This implied dimension must be defined explicitly as the fastest-varying dimension of the \code{NC_CHAR} variable, and it must be included as the first element of arguments \code{start} and \code{count} taken by this function. Due to the lack of native support for 64-bit integers in R, NetCDF types \code{NC_INT64} and \code{NC_UINT64} require special attention. This function accepts the usual R \code{integer} (signed 32-bit) and \code{numeric} (double precision) types, but to represent integers larger than about 53-bits without truncation, \code{\link[bit64:bit64-package]{integer64}} vectors are also supported. NetCDF numeric variables cannot portably represent \code{NA} values from R. NetCDF does allow attributes to be defined for variables, and several conventions exist for attributes that define missing values and valid ranges. The convention in use can be specified by argument \code{na.mode}. Values of \code{NA} in argument \code{data} are converted to a missing or fill value before writing to the NetCDF variable. Unusual cases can be handled directly in user code by setting \code{na.mode=3}. Variables of user-defined types are supported, subject to conditions on the corresponding data structures in R. \code{"compound"} arrays must be stored in R as lists, with items named for the compound fields; items of base NetCDF data types are stored as R arrays, with leading dimensions from the field dimensions (if any) and trailing dimensions from the NetCDF variable. \code{"enum"} arrays are stored in R as factor arrays. \code{"opaque"} arrays are stored in R as raw (byte) arrays, with a leading dimension for bytes of the opaque type and trailing dimensions from the NetCDF variable. \code{"vlen"} arrays are stored in R as a list with dimensions of the NetCDF variable; items in the list may have different lengths; base NetCDF data types are stored as R vectors. To reduce the storage space required by a NetCDF file, numeric variables can be packed into types of lower precision. The packing operation involves subtraction of attribute \code{add_offset} before division by attribute \code{scale_factor}. This packing operation is performed automatically for variables defined with the attributes \code{add_offset} and/or \code{scale_factor} if argument \code{pack} is set to \code{TRUE}. If \code{pack} is \code{FALSE}, \code{data} values are assumed to be packed correctly and are written to the variable without alteration. Data in a NetCDF variable is represented as a multi-dimensional array. The number and length of dimensions is determined when the variable is created. The \code{start} and \code{count} arguments of this routine indicate where the writing starts and the number of values to write along each dimension. Awkwardness arises mainly from one thing: NetCDF data are written with the last dimension varying fastest, whereas R works opposite. Thus, the order of the dimensions according to the CDL conventions (e.g., time, latitude, longitude) is reversed in the R array (e.g., longitude, latitude, time). The arguments marked for \code{"netcdf4"} format refer to the chunk cache used for reading and writing variables. Default cache settings are defined by the NetCDF library, and they can be adjusted for each variable to improve performance in some applications. } \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \note{\code{NC_BYTE} is always interpreted as signed. For best performance, it is recommended that the definition of dimensions, variables and attributes is completed before variables are read or written.} \author{Pavel Michna, Milton Woods} \examples{ ## Create a new NetCDF dataset and define two dimensions file1 <- tempfile("var.put_", fileext=".nc") nc <- create.nc(file1) dim.def.nc(nc, "station", 5) dim.def.nc(nc, "time", unlim=TRUE) dim.def.nc(nc, "max_string_length", 32) ## Create three variables, one as coordinate variable var.def.nc(nc, "time", "NC_INT", "time") var.def.nc(nc, "temperature", "NC_DOUBLE", c(0,1)) var.def.nc(nc, "name", "NC_CHAR", c("max_string_length", "station")) ## Put some _FillValue attribute for temperature att.put.nc(nc, "temperature", "_FillValue", "NC_DOUBLE", -99999.9) ## Define variable values mytime <- c(1:2) mytemperature <- c(1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, NA, NA, 9.9) myname <- c("alfa", "bravo", "charlie", "delta", "echo") dim(mytemperature) <- c(5,2) ## Put subsets of the data: var.put.nc(nc, "time", mytime, start=2, count=1) var.put.nc(nc, "temperature", mytemperature[3:4,2], start=c(3,2), count=c(2,1)) var.put.nc(nc, "name", myname[3:4], start=c(NA,3), count=c(NA,2)) sync.nc(nc) ## Put all of the data: var.put.nc(nc, "time", mytime) var.put.nc(nc, "temperature", mytemperature) var.put.nc(nc, "name", myname) close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/att.rename.nc.Rd0000644000176200001440000000350414577713273015160 0ustar liggesusers\name{att.rename.nc} \alias{att.rename.nc} \title{Rename a NetCDF Attribute} \description{Rename a NetCDF attribute.} \usage{att.rename.nc(ncfile, variable, attribute, newname)} \arguments{ \item{ncfile}{Object of class \code{NetCDF} which points to the NetCDF dataset (as returned from \code{\link[RNetCDF]{open.nc}}).} \item{variable}{ID or name of the attribute's variable, or \code{"NC_GLOBAL"} for a global attribute.} \item{attribute}{The current attribute name or ID.} \item{newname}{The new name to be assigned to the specified attribute.} } \details{This function changes the name of an existing attribute in a NetCDF dataset open for writing. An attribute cannot be renamed to have the same name as another attribute of the same variable. Valid attribute ID numbers range from 0 to the number of attributes minus 1. The number of attributes of a file, group, or variable can be found using the relevant inquiry function (\code{\link[RNetCDF]{file.inq.nc}}, \code{\link[RNetCDF]{grp.inq.nc}}, or \code{\link[RNetCDF]{var.inq.nc}}).} \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ ## Create a new NetCDF dataset and define two dimensions file1 <- tempfile("att.rename_", fileext=".nc") nc <- create.nc(file1) dim.def.nc(nc, "station", 5) dim.def.nc(nc, "time", unlim=TRUE) ## Create two variables, one as coordinate variable var.def.nc(nc, "time", "NC_INT", "time") var.def.nc(nc, "temperature", "NC_DOUBLE", c(0,1)) ## Put some attributes att.put.nc(nc, "temperature", "_FillValue", "NC_DOUBLE", -99999.9) att.put.nc(nc, "NC_GLOBAL", "title", "NC_CHAR", "Data from Foo") ## Rename these attributes att.rename.nc(nc, "temperature", "_FillValue", "my__FillValue") att.rename.nc(nc, "NC_GLOBAL", "title", "my_title") close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/type.def.nc.Rd0000644000176200001440000000672614577713273014651 0ustar liggesusers\name{type.def.nc} \alias{type.def.nc} \title{Define a NetCDF Type} \description{Define complex data structures based on existing NetCDF data types.} \usage{ type.def.nc(ncfile, typename, class, size=NULL, basetype=NULL, names=NULL, values=NULL, subtypes=NULL, dimsizes=NULL) } \arguments{ \item{ncfile}{Object of class \code{NetCDF} which points to the NetCDF dataset (as returned from \code{\link[RNetCDF]{open.nc}}).} \item{typename}{Name to identify the new data type. Must begin with an alphabetic character, followed by zero or more alphanumeric characters including the underscore (\code{"_"}). Case is significant.} \item{class}{One of the keywords \code{"compound"}, \code{"enum"}, \code{"opaque"} or \code{"vlen"}.} \item{size}{(\code{"opaque"}) Size in bytes of a single item of the opaque type.} \item{basetype}{(\code{"enum"} or \code{"vlen"}) Base type, given as the name or identifier of an existing NetCDF type. Only built-in integer types (e.g. \code{"NC_INT"}) are allowed for \code{class="enum"}.} \item{names}{(\code{"compound"} or \code{"enum"}) Name of each field or member (character vector).} \item{values}{(\code{"enum"}) Numeric value of each member (numeric vector).} \item{subtypes}{(\code{"compound"}) NetCDF type of each field, given by name (character vector) or identifier (numeric vector).} \item{dimsizes}{(\code{"compound"}) Array dimensions of each field, specified as a list of numeric vectors. Dimensions are given in R order (leftmost index varies fastest; opposite to CDL conventions). If a list item is \code{NULL}, the corresponding field is a scalar.} } \value{NetCDF type identifier, returned invisibly.} \details{User-defined types are supported by files in \code{"netcdf4"} format. This function creates a new NetCDF data type, which can be used in definitions of NetCDF variables and attributes. Several varieties of data type are supported, as specified by argument \code{class}: \tabular{ll}{ \code{"compound"} \tab Combines atomic and user-defined types into C-like structs. \cr \code{"enum"} \tab Set of named integer values, similar to an R \code{factor}. \cr \code{"opaque"} \tab Blobs of arbitrary data with a given size. \cr \code{"vlen"} \tab Variable length vectors of a given base type. \cr } \code{type.def.nc} may be repeated to insert additional members of an \code{"enum"} type or fields of a \code{"compound"} type. However, the size of a \code{"compound"} type is calculated from the fields specified when it is first defined, and later insertion of fields will only succeed if there is sufficient free space after the last field. Existing fields/members cannot be modified, and types cannot be removed from a dataset. } \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ ## Create a new NetCDF4 dataset and define types file1 <- tempfile("type.def_", fileext=".nc") nc <- create.nc(file1, format="netcdf4") # Compound type: type.def.nc(nc, "astruct", "compound", names=c("siteid", "height", "colour"), subtypes=c("NC_INT", "NC_DOUBLE", "NC_SHORT"), dimsizes=list(NULL, NULL, c(3))) # Enum type: type.def.nc(nc, "afactor", "enum", basetype="NC_INT", names=c("peanut butter", "jelly"), values=c(101,102)) # Opaque type: type.def.nc(nc, "ablob", "opaque", size=128) # Vlen type: type.def.nc(nc, "avector", "vlen", basetype="NC_FLOAT") close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/utcal.nc.Rd0000644000176200001440000001215314577713273014232 0ustar liggesusers\name{utcal.nc} \alias{utcal.nc} \title{Convert Temporal Amounts to UTC Referenced Dates} \description{Convert temporal amounts to UTC referenced date and time.} \usage{utcal.nc(unitstring, value, type="n")} \arguments{ \item{unitstring}{A temporal unit with an origin (e.g., \code{"days since 1900-01-01"}).} \item{value}{An amount (quantity) of the given temporal unit.} \item{type}{Character string which determines the output type. Can be \code{"n"} for numeric, \code{"s"} for string or \code{"c"} for POSIXct output.} } \value{If the output type is set to numeric, result is a matrix containing the corresponding date(s) and time(s), with the following columns: year, month, day, hour, minute, second. If the output type is string, result is a vector of strings in the form \code{"YYYY-MM-DD hh:mm:ss"}. Otherwise result is a vector of POSIXct values.} \details{Converts the amount, \code{value}, of the temporal unit, \code{unitstring}, into a UTC-referenced date and time. Functions \code{utcal.nc} and \code{utinvcal.nc} provide a convenient way to convert time values between the forms used by NetCDF variables and R functions. Most R functions require times to be expressed as seconds since the beginning of 1970 in the UTC time zone, typically using objects of class \code{POSIXct} or \code{POSIXlt}. NetCDF files store times in numeric variables with a wide variety of units. The units and calendar are stored in attributes of the time variable, as described by the CF Conventions. Units are expressed as a string, in the form of a time unit since a fixed date-time (e.g. \code{"hours since 2000-01-01 00:00:00 +00:00"}, or more simply \code{"hours since 2000-01-01"}). The conversions of times between units are performed by the UDUNITS library using a mixed Gregorian/Julian calendar system. Dates prior to 1582-10-15 are assumed to use the Julian calendar, which was introduced by Julius Caesar in 46 BCE and is based on a year that is exactly 365.25 days long. Dates on and after 1582-10-15 are assumed to use the Gregorian calendar, which was introduced on that date and is based on a year that is exactly 365.2425 days long. (A year is actually approximately 365.242198781 days long.) Seemingly strange behavior of the UDUNITS package can result if a user-given time interval includes the changeover date. Conversions involving alternative calendars are not supported by UDUNITS, but they can be performed by other R packages. For example, \url{https://CRAN.R-project.org/package=PCICt} implements 360- and 365-day calendars. } \seealso{\code{\link{utinvcal.nc}}} \references{\url{https://www.unidata.ucar.edu/software/udunits/} \url{http://cfconventions.org}} \author{Pavel Michna, Milton Woods} \examples{ if (inherits(try(utcal.nc("seconds since 1970-01-01", 0)), "try-error")) { warning("UDUNITS calendar conversions not supported by this build of RNetCDF") } else { ## Convert units to UTC referenced time utcal.nc("hours since 1900-01-01 00:00:00 +01:00", c(0:5)) utcal.nc("hours since 1900-01-01 00:00:00 +01:00", c(0:5), type="s") utcal.nc("hours since 1900-01-01 00:00:00 +01:00", c(0:5), type="c") ## Create netcdf file with a time coordinate variable. # Create a time variable (using type POSIXct for convenience): nt <- 24 time_posixct <- seq(ISOdatetime(1900,1,1,0,0,0,tz="UTC"), by="hour", len=nt) # Convert time variable to specified units: time_unit <- "hours since 1900-01-01 00:00:00 +00:00" time_coord <- utinvcal.nc(time_unit, time_posixct) # Create a netcdf file: file1 <- tempfile("utcal_", fileext=".nc") nc <- create.nc(file1) # Global attributes: att.put.nc(nc, "NC_GLOBAL", "Conventions", "NC_CHAR", "CF-1.6") att.put.nc(nc, "NC_GLOBAL", "title", "NC_CHAR", "RNetCDF example: time coordinate") att.put.nc(nc, "NC_GLOBAL", "institution", "NC_CHAR", "University of Areland") att.put.nc(nc, "NC_GLOBAL", "source", "NC_CHAR", paste("RNetCDF", utils::packageVersion("RNetCDF"), sep="_")) att.put.nc(nc, "NC_GLOBAL", "history", "NC_CHAR", paste(Sys.time(), "File created")) att.put.nc(nc, "NC_GLOBAL", "references", "NC_CHAR", "https://www.unidata.ucar.edu/software/udunits") att.put.nc(nc, "NC_GLOBAL", "comment", "NC_CHAR", "Uses attributes recommended by http://cfconventions.org") # Define time coordinate and attributes: dim.def.nc(nc, "time", nt) var.def.nc(nc, "time", "NC_DOUBLE", "time") att.put.nc(nc, "time", "long_name", "NC_CHAR", "time") att.put.nc(nc, "time", "units", "NC_CHAR", time_unit) # Calendar is optional (gregorian is the default): att.put.nc(nc, "time", "calendar", "NC_CHAR", "gregorian") # Write the data: var.put.nc(nc, "time", time_coord) close.nc(nc) ## Read time coordinate from netcdf file: # Open the file prepared earlier: nc <- open.nc(file1) # Read time coordinate and attributes: time_coord2 <- var.get.nc(nc, "time") time_unit2 <- att.get.nc(nc, "time", "units") close.nc(nc) unlink(file1) # Convert the time variable to POSIXct: time_posixct2 <- utcal.nc(time_unit2, time_coord2, "c") # Compare with original POSIXct variable: stopifnot(all.equal(time_posixct, time_posixct2)) } } \keyword{utilities} RNetCDF/man/utinit.nc.Rd0000644000176200001440000000155614577713273014443 0ustar liggesusers\name{utinit.nc} \alias{utinit.nc} \title{Initialize the UDUNITS2 Library} \description{Initialize the UDUNITS2 library.} \usage{utinit.nc(path="")} \arguments{ \item{path}{Path to an XML-formatted unit-database for UDUNITS2.} } \details{This function initializes the UDUNITS2 library. It is called by \code{.onLoad} when the package is loaded. Normally, the user does not need to call this function. UDUNITS2 obtains a unit system by reading an XML file. The file name is given by argument \code{path}, if it is a non-empty character string. Otherwise, the file name is taken from environment variable \code{UDUNITS2_XML_PATH}, if it is a non-empty character string. By default, the file name is set to an XML file distributed with RNetCDF. } \references{\url{https://www.unidata.ucar.edu/software/udunits/}} \author{Pavel Michna, Milton Woods} \keyword{utilities} RNetCDF/man/close.nc.Rd0000644000176200001440000000160114577713273014223 0ustar liggesusers\name{close.nc} \alias{close.nc} \title{Close a NetCDF Dataset} \description{Close an open NetCDF dataset.} \usage{close.nc(con, ...)} \arguments{ \item{con}{Object of class \code{NetCDF} which points to the NetCDF dataset (as returned from \code{\link[RNetCDF]{open.nc}}).} \item{...}{Arguments passed to or from other methods (not used).} } \details{This function closes an open NetCDF dataset. After an open NetCDF dataset is closed, its NetCDF ID may be reassigned to the next NetCDF dataset that is opened or created. Therefore, the passed object (\code{ncfile}) should be deleted by the user after calling this function.} \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ ## Create a void NetCDF dataset file1 <- tempfile("close_", fileext=".nc") nc <- create.nc(file1) close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/att.inq.nc.Rd0000644000176200001440000000456714577713273014512 0ustar liggesusers\name{att.inq.nc} \alias{att.inq.nc} \title{Inquire About a NetCDF Attribute} \description{ Inquire about a NetCDF attribute. } \usage{att.inq.nc(ncfile, variable, attribute)} \arguments{ \item{ncfile}{Object of class \code{NetCDF} which points to the NetCDF dataset (as returned from \code{\link[RNetCDF]{open.nc}}).} \item{variable}{Either the ID or the name of the attribute's variable or \code{"NC_GLOBAL"} for a global attribute.} \item{attribute}{Either the ID or the name of the attribute to be inquired.} } \value{ A list containing the following components: \item{id}{Attribute ID.} \item{name}{Attribute name.} \item{type}{External NetCDF data type as one of the following labels: \code{NC_BYTE}, \code{NC_UBYTE}, \code{NC_CHAR}, \code{NC_SHORT}, \code{NC_USHORT}, \code{NC_INT}, \code{NC_UINT}, \code{NC_INT64}, \code{NC_UINT64}, \code{NC_FLOAT}, \code{NC_DOUBLE}, \code{NC_STRING}, or a user-defined type name.} \item{length}{Length of this attribute.} } \details{This function returns information about a NetCDF attribute. Information about an attribute include its ID, its name, its type, and its length. In general, attributes are accessed by name rather than by their ID number because the attribute number is more volatile than the name, since it can change when other attributes of the same variable are deleted. Valid attribute ID numbers range from 0 to the number of attributes minus 1. The number of attributes of a file, group, or variable can be found using the relevant inquiry function (\code{\link[RNetCDF]{file.inq.nc}}, \code{\link[RNetCDF]{grp.inq.nc}}, or \code{\link[RNetCDF]{var.inq.nc}}). } \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ ## Create a new NetCDF dataset and define two dimensions file1 <- tempfile("att.inq_", fileext=".nc") nc <- create.nc(file1) dim.def.nc(nc, "station", 5) dim.def.nc(nc, "time", unlim=TRUE) ## Create two variables, one as coordinate variable var.def.nc(nc, "time", "NC_INT", "time") var.def.nc(nc, "temperature", "NC_DOUBLE", c(0,1)) ## Put some attributes att.put.nc(nc, "temperature", "_FillValue", "NC_DOUBLE", -99999.9) att.put.nc(nc, "NC_GLOBAL", "title", "NC_CHAR", "Data from Foo") ## Inquire about these attributes att.inq.nc(nc, "temperature", "_FillValue") att.inq.nc(nc, "NC_GLOBAL", "title") close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/utinvcal.nc.Rd0000644000176200001440000000326314577713273014751 0ustar liggesusers\name{utinvcal.nc} \alias{utinvcal.nc} \title{Convert UTC Referenced Dates Into Temporal Amounts} \description{Convert a UTC referenced date into a temporal amount.} \usage{utinvcal.nc(unitstring, value)} \arguments{ \item{unitstring}{A temporal unit with an origin (e.g., \code{"days since 1900-01-01"}).} \item{value}{Dates to convert as a numeric vector or array, or a vector of strings or POSIXct values.} } \value{A vector containing the amount(s) of the temporal unit(s) corresponding to the given date(s).} \details{Uses the UDUNITS library to convert a UTC-referenced date and time into the amount, \code{value}, of the temporal unit, \code{unitstring}. If the dates are given in string form, the structure must be exactly \code{"YYYY-MM-DD hh:mm:ss"}. A vector of POSIXct values is also accepted as input. These are converted to the specified units by a linear transformation, without an intermediate separation into date components. } \seealso{\code{\link{utcal.nc}}} \references{\url{https://www.unidata.ucar.edu/software/udunits/}} \author{Pavel Michna, Milton Woods} \examples{ if (inherits(try(utcal.nc("seconds since 1970-01-01", 0)), "try-error")) { warning("UDUNITS calendar conversions not supported by this build of RNetCDF") } else { ## Convert UTC referenced time to other time units utinvcal.nc("hours since 1900-01-01 00:00:00 +01:00", c(1900,1,1,5,25,0)) utinvcal.nc("hours since 1900-01-01 00:00:00 +01:00", "1900-01-01 05:25:00") utinvcal.nc("hours since 1900-01-01 00:00:00 +01:00", ISOdatetime(1900,1,1,5,25,0,tz="UTC")) } ## An example of reading and writing a netcdf time coordinate ## is given in the help for utcal.nc } \keyword{utilities} RNetCDF/man/sync.nc.Rd0000644000176200001440000000313714577713273014100 0ustar liggesusers\name{sync.nc} \alias{sync.nc} \title{Synchronize a NetCDF Dataset} \description{Synchronize an open NetCDF dataset to disk.} \usage{sync.nc(ncfile)} \arguments{ \item{ncfile}{Object of class \code{NetCDF} which points to the NetCDF dataset (as returned from \code{\link[RNetCDF]{open.nc}}).} } \details{This function offers a way to synchronize the disk copy of a NetCDF dataset with in-memory buffers. There are two reasons one might want to synchronize after writes: To minimize data loss in case of abnormal termination, or to make data available to other processes for reading immediately after it is written.} \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ ## Create a new NetCDF dataset and define two dimensions file1 <- tempfile("sync_", fileext=".nc") nc <- create.nc(file1) dim.def.nc(nc, "station", 5) dim.def.nc(nc, "time", unlim=TRUE) ## Create two variables, one as coordinate variable var.def.nc(nc, "time", "NC_INT", "time") var.def.nc(nc, "temperature", "NC_DOUBLE", c(0,1)) ## Define variable values mytime <- c(1:2) dim(mytime) <- c(2) mytemp <- c(0.0, 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9) dim(mytemp) <- c(5,2) ## Put the data var.put.nc(nc, "time", mytime) var.put.nc(nc, "temperature", mytemp) ## Synchronize to disk sync.nc(nc) ## Open a new connection to the dataset and read data: nc2 <- open.nc(file1) newtime <- var.get.nc(nc2, 0) newtemp <- var.get.nc(nc2, "temperature") stopifnot(all.equal(newtime,mytime)) stopifnot(all.equal(newtemp,mytemp)) close.nc(nc) close.nc(nc2) unlink(file1) } \keyword{file} RNetCDF/man/open.nc.Rd0000644000176200001440000000555314577713273014071 0ustar liggesusers\name{open.nc} \alias{open.nc} \title{Open a NetCDF Dataset} \description{Open an existing NetCDF dataset for reading and (optionally) writing.} \usage{ open.nc(con, write=FALSE, share=FALSE, prefill=TRUE, diskless=FALSE, persist=FALSE, mpi_comm=NULL, mpi_info=NULL, ...) } \arguments{ \item{con}{Filename of the NetCDF dataset to be opened. If the underlying NetCDF library supports OPeNDAP, \code{con} may be an OPeNDAP URL.} \item{write}{If \code{FALSE} (default), the dataset will be opened read-only. If \code{TRUE}, the dataset will be opened read-write.} \item{share}{The buffer scheme. If \code{FALSE} (default), dataset access is buffered and cached for performance. However, if one or more processes may be reading while another process is writing the dataset, set to \code{TRUE}.} \item{prefill}{The prefill mode. If \code{TRUE} (default), newly defined variables are initialised with fill values when they are first accessed. This allows unwritten array elements to be detected when reading, but it also implies duplicate writes if all elements are subsequently written with user-specified data. Enhanced write performance can be obtained by setting \code{prefill=FALSE}.} \item{diskless}{When \code{diskless=TRUE}, the file is read entirely into memory, and any changes are kept in memory without writing to disk. The netcdf library may ignore this option for files in netcdf4 format.} \item{persist}{When \code{persist=TRUE}, a file opened with \code{diskless=TRUE} is flushed to disk when closed. In some cases, this may be faster than manipulating files directly on disk.} \item{mpi_comm}{Fortran handle of MPI communicator for parallel I/O. The default of \code{NULL} implies serial I/O. Valid Fortran handles may be obtained from your chosen MPI package for R - for example \link[pbdMPI]{comm.c2f} or \link[Rmpi]{mpi.comm.c2f}.} \item{mpi_info}{Fortran handle of MPI Info object for parallel I/O. The default value \code{NULL} specifies that the \code{MPI_INFO_NULL} object is used. Other valid Fortran handles may be obtained from your chosen MPI package for R - for example \link[pbdMPI]{info.c2f}.} \item{...}{Arguments passed to or from other methods (not used).} } \value{Object of class \code{NetCDF} which points to the NetCDF dataset, returned invisibly.} \details{This function opens an existing NetCDF dataset for access. By default, the dataset is opened read-only. If \code{write=TRUE}, then the dataset can be changed. This includes appending or changing data, adding dimensions, variables, and attributes.} \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ ## Create a void NetCDF dataset file1 <- tempfile("open_", fileext=".nc") nc <- create.nc(file1) close.nc(nc) ## Open the NetCDF dataset for writing nc <- open.nc(file1, write=TRUE) close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/grp.rename.nc.Rd0000644000176200001440000000257414577713273015166 0ustar liggesusers\name{grp.rename.nc} \alias{grp.rename.nc} \title{Rename a NetCDF Group} \description{Rename a NetCDF group.} \usage{grp.rename.nc(ncid, newname, oldname=NULL)} \arguments{ \item{ncid}{Object of class \code{NetCDF} which points to a NetCDF group (from \code{\link[RNetCDF]{grp.def.nc}}) or dataset (from \code{\link[RNetCDF]{open.nc}}).} \item{newname}{The new group name.} \item{oldname}{By default, the rename applies to the group represented by \code{ncid}. If \code{oldname} is a character string, a group with this name is renamed instead. A hierarchical search is performed if \code{oldname} contains \code{"/"}, otherwise only the immediate group of \code{ncid} is searched for a matching group name.} } \details{This function renames an existing group in a dataset of \code{"netcdf4"} format that is open for writing. A group cannot be renamed to have the same name as another group, type or variable in the parent group.} \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ ## Create a new NetCDF dataset and define a group file1 <- tempfile("grp.rename_", fileext=".nc") nc <- create.nc(file1, format="netcdf4") grp <- grp.def.nc(nc, "oldgroup") ## Rename the group (operation not supported by early versions of the netcdf4 library) try(grp.rename.nc(grp, "newgroup")) close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/create.nc.Rd0000644000176200001440000001036214577713273014365 0ustar liggesusers\name{create.nc} \alias{create.nc} \title{Create a NetCDF Dataset} \description{Create a new NetCDF dataset.} \usage{create.nc(filename, clobber=TRUE, share=FALSE, prefill=TRUE, format="classic", large=FALSE, diskless=FALSE, persist=FALSE, mpi_comm=NULL, mpi_info=NULL)} \arguments{ \item{filename}{Filename for the NetCDF dataset to be created.} \item{clobber}{The creation mode. If \code{TRUE} (default), any existing dataset with the same filename will be overwritten. Otherwise set to \code{FALSE}.} \item{share}{The buffer scheme. If \code{FALSE} (default), dataset access is buffered and cached for performance. However, if one or more processes may be reading while another process is writing the dataset, set to \code{TRUE}.} \item{prefill}{The prefill mode. If \code{TRUE} (default), newly defined variables are initialised with fill values when they are first accessed. This allows unwritten array elements to be detected when reading, but it also implies duplicate writes if all elements are subsequently written with user-specified data. Enhanced write performance can be obtained by setting \code{prefill=FALSE}.} \item{format}{The file format. One of \code{"classic"}, \code{"offset64"}, \code{"data64"}, \code{"netcdf4"} or \code{"classic4"}. See below for details.} \item{large}{(Deprecated) \code{large=TRUE} sets the file format to \code{"offset64"} when \code{format="classic"}.} \item{diskless}{When \code{diskless=TRUE}, the file is created in memory without writing to disk. This allows netcdf datasets to be used as fast, temporary files. When the file is closed, the contents are lost unless \code{persist=TRUE}.} \item{persist}{When \code{persist=TRUE}, a file created with \code{diskless=TRUE} is flushed to disk when closed. In some cases, this may be faster than manipulating files directly on disk.} \item{mpi_comm}{Fortran handle of MPI communicator for parallel I/O. The default of \code{NULL} implies serial I/O. Valid Fortran handles may be obtained from your chosen MPI package for R - for example \link[pbdMPI]{comm.c2f} or \link[Rmpi]{mpi.comm.c2f}.} \item{mpi_info}{Fortran handle of MPI Info object for parallel I/O. The default value \code{NULL} specifies that the \code{MPI_INFO_NULL} object is used. Other valid Fortran handles may be obtained from your chosen MPI package for R - for example \link[pbdMPI]{info.c2f}.} } \value{Object of class \code{NetCDF} which points to the NetCDF dataset, returned invisibly.} \details{This function creates a new NetCDF dataset, returning an object of class \code{NetCDF} that can be used in R. The file format is specified by the \code{format} argument, which may take the following values: \describe{ \item{\code{"classic"}}{(default) Original netcdf file format, still widely used and recommended for maximum portability of datasets. Uses a signed 32-bit offset in its internal structures, so files larger than 2GB can only be created under limited conditions.} \item{\code{"offset64"}}{64-bit offset extension of original format, introduced by netcdf-3.6. Allows larger files and variables than \code{"classic"} format, but there remain some restrictions on files larger than 2GB.} \item{\code{"data64"}}{Extension of \code{"classic"} format to support large files (i.e. over 2GB) and large variables (over 2B array elements). This format was introduced in netcdf-4.4.0.} \item{\code{"netcdf4"}}{Netcdf in an HDF5 container, introduced by netcdf-4.0. Allows dataset sizes up to filesystem limits, and extends the feature set of the older formats.} \item{\code{"classic4"}}{Same file format as \code{"netcdf4"}, but this option ensures that only classic netcdf data structures are stored in the file for compatibility with older software (when linked with the netcdf4 library).} } } \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ ## Create empty NetCDF datasets with different formats file1 <- tempfile("create3_", fileext=".nc") nc <- create.nc(file1) close.nc(nc) unlink(file1) file2 <- tempfile("create64_", fileext=".nc") nc2 <- create.nc(file2,format="offset64") close.nc(nc2) unlink(file2) file3 <- tempfile("create4_", fileext=".nc") nc3 <- create.nc(file3,format="netcdf4") close.nc(nc3) unlink(file3) } \keyword{file} RNetCDF/man/file.inq.nc.Rd0000644000176200001440000000335614577713273014634 0ustar liggesusers\name{file.inq.nc} \alias{file.inq.nc} \title{Inquire About a NetCDF Dataset} \description{Inquire about a NetCDF dataset.} \usage{file.inq.nc(ncfile)} \arguments{ \item{ncfile}{Object of class \code{NetCDF} which points to the NetCDF dataset (as returned from \code{\link[RNetCDF]{open.nc}}).} } \value{ A list containing the following components: \item{ndims}{Number of dimensions defined for this NetCDF dataset.} \item{nvars}{Number of variables defined for this NetCDF dataset.} \item{ngatts}{Number of global attributes for this NetCDF dataset.} \item{unlimdimid}{ID of the unlimited dimension, if there is one for this NetCDF dataset. Otherwise \code{NA} will be returned.} \item{format}{Format of file, typically \code{"classic"}, \code{"offset64"}, \code{"data64"}, \code{"classic4"} or \code{"netcdf4"}.} \item{libvers}{Version string of the NetCDF library in the current R session.} } \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ ## Create a new NetCDF dataset and define two dimensions file1 <- tempfile("file.inq_", fileext=".nc") nc <- create.nc(file1) dim.def.nc(nc, "station", 5) dim.def.nc(nc, "time", unlim=TRUE) ## Create two variables, one as coordinate variable var.def.nc(nc, "time", "NC_INT", "time") var.def.nc(nc, "temperature", "NC_DOUBLE", c(0,1)) ## Put some attributes att.put.nc(nc, "temperature", "_FillValue", "NC_DOUBLE", -99999.9) att.put.nc(nc, "temperature", "long_name", "NC_CHAR", "air temperature") att.put.nc(nc, "NC_GLOBAL", "title", "NC_CHAR", "Data from Foo") att.put.nc(nc, "NC_GLOBAL", "history", "NC_CHAR", paste("Created on", date())) ## Inquire about the dataset file.inq.nc(nc) close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/print.nc.Rd0000644000176200001440000000345314577713273014261 0ustar liggesusers\name{print.nc} \alias{print.nc} \title{Print Summary Information About a NetCDF Dataset} \description{Print summary information about a NetCDF dataset.} \usage{print.nc(x, ...)} \arguments{ \item{x}{Object of class \code{NetCDF} which points to the NetCDF dataset (as returned from \code{\link[RNetCDF]{open.nc}}).} \item{...}{Arguments passed to or from other methods (not used).} } \details{This function prints information about the structure of a NetCDF dataset, including lists of all groups, dimensions, user-defined types, variables and attributes. The output of this function is similar to the \code{ncdump -h} command supplied with the NetCDF C library. One important difference is that array dimensions are shown by \code{print.nc} in the order used by R, where the leftmost subscript varies fastest. } \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ ## Create a new NetCDF dataset file1 <- tempfile("print_", fileext=".nc") nc <- create.nc(file1, format="netcdf4") ## Create a group (just because we can!): grp <- grp.def.nc(nc, "data") ## Create some dimensions, putting one inside the group: dim.def.nc(nc, "time", unlim=TRUE) dim.def.nc(grp, "station", 5) ## Create two variables, putting one inside the group: var.def.nc(nc, "time", "NC_INT", "time") var.def.nc(grp, "temperature", "NC_DOUBLE", c("station","time")) ## Put some attributes att.put.nc(nc, "NC_GLOBAL", "history", "NC_CHAR", paste("Created on", date())) att.put.nc(grp, "temperature", "_FillValue", "NC_DOUBLE", -99999.9) att.put.nc(grp, "temperature", "long_name", "NC_CHAR", "air temperature") att.put.nc(grp, "NC_GLOBAL", "title", "NC_CHAR", "Data from Foo") ## Print summary information about the dataset print.nc(nc) close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/config.nc.Rd0000644000176200001440000000125714577713273014372 0ustar liggesusers\name{config.nc} \alias{config.nc} \title{Configured options} \description{Find NetCDF options detected when installing RNetCDF.} \usage{config.nc()} \details{This function is not intended for user code, and it is subject to change or removal without notice. It is currently needed for RNetCDF package tests, to determine expected behaviour of the NetCDF C library. Unless otherwise documented, optional NetCDF features that are not detected when installing RNetCDF will raise an error when called from R code. If necessary, work arounds can be implemented by wrapping the relevant code in \code{try} or \code{tryCatch}. } \author{Pavel Michna, Milton Woods} \keyword{utilities} RNetCDF/man/att.get.nc.Rd0000644000176200001440000000671214577713273014474 0ustar liggesusers\name{att.get.nc} \alias{att.get.nc} \title{Get a NetCDF Attribute} \description{Get an attribute from a NetCDF dataset.} \usage{att.get.nc(ncfile, variable, attribute, rawchar=FALSE, fitnum=FALSE)} \arguments{ \item{ncfile}{Object of class \code{NetCDF} which points to the NetCDF dataset (as returned from \code{\link[RNetCDF]{open.nc}}).} \item{variable}{ID or name of the variable from which the attribute will be read, or \code{"NC_GLOBAL"} for a global attribute.} \item{attribute}{Attribute name or ID.} \item{rawchar}{This option only relates to NetCDF attributes of type \code{NC_CHAR}. When \code{rawchar} is \code{FALSE} (default), a NetCDF attribute of type \code{NC_CHAR} is converted to a \code{character} string in R. If \code{rawchar} is \code{TRUE}, the bytes of \code{NC_CHAR} data are read into an R \code{raw} vector.} \item{fitnum}{By default, all numeric variables are read into R as double precision values. When \code{fitnum==TRUE}, the smallest R numeric type that can exactly represent each external type is used, as follows: \tabular{ll}{ \code{NC_BYTE} \tab \code{\link{integer}} \cr \code{NC_UBYTE} \tab \code{\link{integer}} \cr \code{NC_SHORT} \tab \code{\link{integer}} \cr \code{NC_USHORT} \tab \code{\link{integer}} \cr \code{NC_INT} \tab \code{\link{integer}} \cr \code{NC_UINT} \tab \code{\link{double}} \cr \code{NC_FLOAT} \tab \code{\link{double}} \cr \code{NC_DOUBLE} \tab \code{\link{double}} \cr \code{NC_INT64} \tab \code{\link[bit64:bit64-package]{integer64}} \cr \code{NC_UINT64} \tab \code{\link[bit64:bit64-package]{integer64}} \cr }} } \value{Vector with a data type that depends on the NetCDF variable. For NetCDF variables of type \code{NC_CHAR}, the R type is either \code{character} or \code{raw}, as specified by argument \code{rawchar}. For \code{NC_STRING}, the R type is \code{character}. Numeric variables are read as double precision by default, but the smallest R type that exactly represents each external type is used if \code{fitnum} is \code{TRUE}. Valid attribute ID numbers range from 0 to the number of attributes minus 1. The number of attributes of a file, group, or variable can be found using the relevant inquiry function (\code{\link[RNetCDF]{file.inq.nc}}, \code{\link[RNetCDF]{grp.inq.nc}}, or \code{\link[RNetCDF]{var.inq.nc}}). } \details{This function returns the value of the attribute.} \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \note{\code{NC_BYTE} is always interpreted as signed.} \author{Pavel Michna, Milton Woods} \examples{ ## Create a new NetCDF dataset and define two dimensions file1 <- tempfile("att.get_", fileext=".nc") nc <- create.nc(file1) dim.def.nc(nc, "station", 5) dim.def.nc(nc, "time", unlim=TRUE) ## Create two variables, one as coordinate variable var.def.nc(nc, "time", "NC_INT", "time") var.def.nc(nc, "temperature", "NC_DOUBLE", c(0,1)) ## Put some attributes att.put.nc(nc, "temperature", "_FillValue", "NC_DOUBLE", -99999.9) att.put.nc(nc, "temperature", "long_name", "NC_CHAR", "air temperature") att.put.nc(nc, "NC_GLOBAL", "title", "NC_CHAR", "Data from Foo") att.put.nc(nc, "NC_GLOBAL", "history", "NC_CHAR", paste("Created on", date())) ## Get these attributes att.get.nc(nc, "temperature", "_FillValue") att.get.nc(nc, "temperature", "long_name") att.get.nc(nc, "NC_GLOBAL", "title") att.get.nc(nc, "NC_GLOBAL", "history") close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/dim.rename.nc.Rd0000644000176200001440000000204314577713273015136 0ustar liggesusers\name{dim.rename.nc} \alias{dim.rename.nc} \title{Rename a NetCDF Dimension} \description{Rename a NetCDF dimension.} \usage{dim.rename.nc(ncfile, dimension, newname)} \arguments{ \item{ncfile}{Object of class \code{NetCDF} which points to the NetCDF dataset (as returned from \code{\link[RNetCDF]{open.nc}}).} \item{dimension}{Either the ID or the name of the dimension to be renamed.} \item{newname}{The new dimension name.} } \details{This function renames an existing dimension in a NetCDF dataset open for writing. A dimension cannot be renamed to have the same name as another dimension.} \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ ## Create a new NetCDF dataset and define two dimensions file1 <- tempfile("dim.rename_", fileext=".nc") nc <- create.nc(file1) dim.def.nc(nc, "station", 5) dim.def.nc(nc, "time", unlim=TRUE) ## Rename the dimensions dim.rename.nc(nc, 0, "mystation") dim.rename.nc(nc, "time", "mytime") close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/att.delete.nc.Rd0000644000176200001440000000316514577713273015156 0ustar liggesusers\name{att.delete.nc} \alias{att.delete.nc} \title{Delete a NetCDF Attribute} \description{Delete a NetCDF attribute.} \usage{att.delete.nc(ncfile, variable, attribute)} \arguments{ \item{ncfile}{Object of class \code{NetCDF} which points to the NetCDF dataset (as returned from \code{\link[RNetCDF]{open.nc}}).} \item{variable}{ID or name of the attribute's variable, or \code{"NC_GLOBAL"} for a global attribute.} \item{attribute}{The name or ID of the attribute to be deleted.} } \details{This function deletes a NetCDF attribute from a NetCDF dataset open for writing. Valid attribute ID numbers range from 0 to the number of attributes minus 1. The number of attributes of a file, group, or variable can be found using the relevant inquiry function (\code{\link[RNetCDF]{file.inq.nc}}, \code{\link[RNetCDF]{grp.inq.nc}}, or \code{\link[RNetCDF]{var.inq.nc}}). } \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ ## Create a new NetCDF dataset and define two dimensions file1 <- tempfile("att.delete_", fileext=".nc") nc <- create.nc(file1) dim.def.nc(nc, "station", 5) dim.def.nc(nc, "time", unlim=TRUE) ## Create two variables, one as coordinate variable var.def.nc(nc, "time", "NC_INT", "time") var.def.nc(nc, "temperature", "NC_DOUBLE", c(0,1)) ## Put some attributes att.put.nc(nc, "temperature", "_FillValue", "NC_DOUBLE", -99999.9) att.put.nc(nc, "NC_GLOBAL", "title", "NC_CHAR", "Data from Foo") ## Delete these attributes att.delete.nc(nc, "temperature", "_FillValue") att.delete.nc(nc, "NC_GLOBAL", "title") close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/att.copy.nc.Rd0000644000176200001440000000520314577713273014661 0ustar liggesusers\name{att.copy.nc} \alias{att.copy.nc} \title{Copy Attribute from One NetCDF to Another} \description{Copy attribute from one NetCDF to another.} \usage{att.copy.nc(ncfile.in, variable.in, attribute, ncfile.out, variable.out)} \arguments{ \item{ncfile.in}{Object of class \code{NetCDF} which points to the input NetCDF dataset from which the attribute will be copied (as returned from \code{\link[RNetCDF]{open.nc}}).} \item{variable.in}{ID or name of the variable in the input NetCDF dataset from which the attribute will be copied, or \code{"NC_GLOBAL"} for a global attribute.} \item{attribute}{Name or ID of the attribute in the input NetCDF dataset to be copied.} \item{ncfile.out}{Object of class \code{NetCDF} which points to the output NetCDF dataset to which the attribute will be copied (as returned from \code{\link[RNetCDF]{open.nc}}). It is permissible for the input and output NetCDF object to be the same.} \item{variable.out}{ID or name of the variable in the output NetCDF dataset to which the attribute will be copied, or \code{"NC_GLOBAL"} to copy to a global attribute.} } \details{This function copies an attribute from one open NetCDF dataset to another. It can also be used to copy an attribute from one variable to another within the same NetCDF dataset. Valid attribute ID numbers range from 0 to the number of attributes minus 1. The number of attributes of a file, group, or variable can be found using the relevant inquiry function (\code{\link[RNetCDF]{file.inq.nc}}, \code{\link[RNetCDF]{grp.inq.nc}}, or \code{\link[RNetCDF]{var.inq.nc}}). } \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ ## Create two new NetCDF datasets and define two dimensions file1 <- tempfile("att.copy_", fileext=".nc") file2 <- tempfile("att.copy_", fileext=".nc") nc.1 <- create.nc(file1) nc.2 <- create.nc(file2) dim.def.nc(nc.1, "station", 5) dim.def.nc(nc.1, "time", unlim=TRUE) dim.def.nc(nc.2, "station", 5) dim.def.nc(nc.2, "time", unlim=TRUE) ## Create two variables, one as coordinate variable var.def.nc(nc.1, "time", "NC_INT", "time") var.def.nc(nc.1, "temperature", "NC_DOUBLE", c(0,1)) var.def.nc(nc.2, "time", "NC_INT", "time") var.def.nc(nc.2, "temperature", "NC_DOUBLE", c(0,1)) ## Put some attributes to the first dataset att.put.nc(nc.1, "temperature", "_FillValue", "NC_DOUBLE", -99999.9) att.put.nc(nc.1, "NC_GLOBAL", "title", "NC_CHAR", "Data from Foo") ## Copy the attributes to the second dataset att.copy.nc(nc.1, 1, 0, nc.2, 1) att.copy.nc(nc.1, "NC_GLOBAL", "title", nc.2, "NC_GLOBAL") close.nc(nc.1) close.nc(nc.2) unlink(file1) unlink(file2) } \keyword{file} RNetCDF/man/var.par.nc.Rd0000644000176200001440000000512314577713273014472 0ustar liggesusers\name{var.par.nc} \alias{var.par.nc} \title{Change Parallel Access Mode} \description{Change the parallel access mode of a NetCDF variable from independent to collective and vice versa.} \usage{var.par.nc(ncfile, variable, access="NC_COLLECTIVE")} \arguments{ \item{ncfile}{Object of class \code{NetCDF} which points to the NetCDF dataset (as returned from \code{\link[RNetCDF]{open.nc}}).} \item{variable}{Numeric ID or name of the variable for which to change the parallel access mode. Use \code{"NC_GLOBAL"} to change the parallel access mode for all variables in the dataset.} \item{access}{Parallel access mode as one of the following strings: \code{"NC_COLLECTIVE"} or \code{"NC_INDEPENDENT"}.} } \details{Parallel file access is either collective (all processors must participate) or independent (any processor may access the data without waiting for others). Data reads and writes (i.e. calls to \code{var.put.nc} and \code{var.get.nc}) are independent by default. Use this function to change the parallel access mode for a variable from independent to collective mode or vice versa. All netCDF metadata writing operations are collective - all creation of groups, types, variables, dimensions, or attributes. Note that when the file format is \code{"classic"} or \code{"offset64"}, the change always applies to all variables in the file, even if a single variable is specified in argument \code{variable}.} \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{\dontrun{ # This example assumes that the NetCDF library was built with MPI support, # and that both RNetCDF and pbdMPI are installed in R. # If the example code is stored in a file myexample.R, # run R under MPI using a command similar to: # SHELL> mpiexec -np 2 Rscript --vanilla myexample.R library(pbdMPI, quiet = TRUE) library(RNetCDF, quiet = TRUE) # Get MPI parameters init() rank <- comm.rank() size <- comm.size() # Define dimensions and data nr <- 5 nc_local <- 4 nc <- nc_local * size data_local <- matrix(rank, nrow=nr, ncol=nc_local) # Open file for parallel access and define metadata filename <- "myexample.nc" info.create() ncid <- create.nc(filename, format="netcdf4", mpi_comm=comm.c2f(), mpi_info=info.c2f()) rdim <- dim.def.nc(ncid, "rows", nr) cdim <- dim.def.nc(ncid, "cols", nc) varid <- var.def.nc(ncid, "data", "NC_INT", c(rdim, cdim)) # Use collective I/O var.par.nc(ncid, "data", "NC_COLLECTIVE") # Write data var.put.nc(ncid, varid, data_local, start=c(1,rank*nc_local+1), count=c(nr,nc_local)) # Finish up close.nc(ncid) info.free() finalize() }} \keyword{file} RNetCDF/man/var.get.nc.Rd0000644000176200001440000002401414577713273014467 0ustar liggesusers\name{var.get.nc} \alias{var.get.nc} \title{Read Data from a NetCDF Variable} \description{Read the contents of a NetCDF variable.} \usage{var.get.nc(ncfile, variable, start=NA, count=NA, na.mode=4, collapse=TRUE, unpack=FALSE, rawchar=FALSE, fitnum=FALSE, cache_bytes=NA, cache_slots=NA, cache_preemption=NA)} \arguments{ Arguments marked \code{"netcdf4"} are optional for datasets in that format and ignored for other formats. \item{ncfile}{Object of class \code{NetCDF} which points to the NetCDF dataset (as returned from \code{\link[RNetCDF]{open.nc}}).} \item{variable}{ID or name of the NetCDF variable.} \item{start}{A vector of indices specifying the element where reading starts along each dimension of \code{variable}. Indices are numbered from 1 onwards, and the order of dimensions is shown by \code{\link[RNetCDF]{print.nc}} (array elements are stored sequentially with leftmost indices varying fastest). By default (\code{start=NA}), all dimensions of \code{variable} are read from the first element onwards. Otherwise, \code{start} must be a vector whose length is not less than the number of dimensions in \code{variable} (excess elements are ignored). Any \code{NA} values in vector \code{start} are set to 1.} \item{count}{A vector of integers specifying the number of values to read along each dimension of \code{variable}. The order of dimensions is the same as for \code{start}. By default (\code{count=NA}), all dimensions of \code{variable} are read from \code{start} to end. Otherwise, \code{count} must be a vector whose length is not less than the number of dimensions in \code{variable} (excess elements are ignored). Any \code{NA} value in vector \code{count} indicates that the corresponding dimension should be read from the \code{start} index to the end of the dimension.} \item{na.mode}{Missing values in the NetCDF dataset are converted to \code{NA} values in the result returned to R. The missing values are defined by attributes of the NetCDF \code{variable}, which are selected by the following modes: \tabular{lll}{ mode \tab data type \tab attribute(s) \cr 0 \tab numeric \tab \code{_FillValue}, then \code{missing_value} \cr 1 \tab numeric \tab \code{_FillValue} only \cr 2 \tab numeric \tab \code{missing_value} only \cr 3 \tab any \tab no conversion \cr 4 \tab numeric \tab \code{valid_range}, \code{valid_min}, \code{valid_max}, \code{_FillValue} \cr 5 \tab any \tab same as mode 4 for numeric types; \cr \tab \tab \code{_FillValue} for other types \cr } For explanation of attribute conventions used by mode 4, please see: \url{https://docs.unidata.ucar.edu/nug/current/attribute_conventions.html} } \item{collapse}{\code{TRUE} if degenerated dimensions (length=1) should be omitted.} \item{unpack}{Packed variables are unpacked if \code{unpack=TRUE} and the attributes \code{add_offset} and/or \code{scale_factor} are defined. Default is \code{FALSE}.} \item{rawchar}{This option only relates to NetCDF variables of type \code{NC_CHAR}. When \code{rawchar} is \code{FALSE} (default), a NetCDF variable of type \code{NC_CHAR} is converted to a \code{character} array in R. The \code{character} values are from the fastest-varying dimension of the NetCDF variable, so that the R \code{character} array has one fewer dimensions than the \code{NC_CHAR} array. If \code{rawchar} is \code{TRUE}, the bytes of \code{NC_CHAR} data are read into an R \code{raw} array of the same shape.} \item{fitnum}{By default, all numeric variables are read into R as double precision values. When \code{fitnum==TRUE}, the smallest R numeric type that can exactly represent each external type is used, as follows: \tabular{ll}{ \code{NC_BYTE} \tab \code{\link{integer}} \cr \code{NC_UBYTE} \tab \code{\link{integer}} \cr \code{NC_SHORT} \tab \code{\link{integer}} \cr \code{NC_USHORT} \tab \code{\link{integer}} \cr \code{NC_INT} \tab \code{\link{integer}} \cr \code{NC_UINT} \tab \code{\link{double}} \cr \code{NC_FLOAT} \tab \code{\link{double}} \cr \code{NC_DOUBLE} \tab \code{\link{double}} \cr \code{NC_INT64} \tab \code{\link[bit64:bit64-package]{integer64}} \cr \code{NC_UINT64} \tab \code{\link[bit64:bit64-package]{integer64}} \cr }} \item{cache_bytes}{(\code{"netcdf4"}) Size of chunk cache in bytes. Value of \code{NA} (default) implies no change.} \item{cache_slots}{(\code{"netcdf4"}) Number of slots in chunk cache. Value of \code{NA} (default) implies no change.} \item{cache_preemption}{(\code{"netcdf4"}) Value between 0 and 1 (inclusive) that biases the cache scheme towards eviction of chunks that have been fully read. Value of \code{NA} (default) implies no change.} } \details{ NetCDF numeric variables cannot portably represent \code{NA} values from R. NetCDF does allow attributes to be defined for variables, and several conventions exist for attributes that define missing values and valid ranges. The convention in use can be specified by argument \code{na.mode}. Values of a NetCDF variable that are deemed to be missing are automatically converted to \code{NA} in the results returned to R. Unusual cases can be handled directly in user code by setting \code{na.mode=3}. To reduce the storage space required by a NetCDF file, numeric variables are sometimes packed into types of lower precision. The original data can be recovered (approximately) by multiplication of the stored values by attribute \code{scale_factor} followed by addition of attribute \code{add_offset}. This unpacking operation is performed automatically for variables with attributes \code{scale_factor} and/or \code{add_offset} if argument \code{unpack} is set to \code{TRUE}. If \code{unpack} is \code{FALSE}, values are read from each variable without alteration. Data in a NetCDF variable is represented as a multi-dimensional array. The number and length of dimensions is determined when the variable is created. The \code{start} and \code{count} arguments of this routine indicate where the reading starts and the number of values to read along each dimension. The argument \code{collapse} allows to keep degenerated dimensions (if set to \code{FALSE}). As default, array dimensions with length=1 are omitted (e.g., an array with dimensions [2,1,3,4] in the NetCDF dataset is returned as [2,3,4]). Awkwardness arises mainly from one thing: NetCDF data are written with the last dimension varying fastest, whereas R works opposite. Thus, the order of the dimensions according to the CDL conventions (e.g., time, latitude, longitude) is reversed in the R array (e.g., longitude, latitude, time).} \value{An array with dimensions determined by \code{count} and a data type that depends on the type of \code{variable}. For NetCDF variables of type \code{NC_CHAR}, the R type is either \code{character} or \code{raw}, as specified by argument \code{rawchar}. For \code{NC_STRING}, the R type is \code{character}. Numeric variables are read as double precision by default, but the smallest R type that exactly represents each external type is used if \code{fitnum} is \code{TRUE}. Variables of user-defined types are supported. \code{"compound"} arrays are read into R as lists, with items named for the compound fields; items of base NetCDF data types are converted to R arrays, with leading dimensions from the field dimensions (if any) and trailing dimensions from the NetCDF variable. \code{"enum"} arrays are read into R as factor arrays. \code{"opaque"} arrays are read into R as raw (byte) arrays, with a leading dimension for bytes of the opaque type and trailing dimensions from the NetCDF variable. \code{"vlen"} arrays are read into R as a list with dimensions of the NetCDF variable; items in the list may have different lengths; base NetCDF data types are converted to R vectors. The dimension order in the R array is reversed relative to the order reported by NetCDF commands such as \code{ncdump}, because NetCDF arrays are stored in row-major (C) order whereas R arrays are stored in column-major (Fortran) order. Arrays of type \code{character} drop the fastest-varying dimension of the corresponding \code{NC_CHAR} array, because this dimension corresponds to the length of the individual \code{character} elements. For example, an \code{NC_CHAR} array with dimensions (5,10) would be returned as a \code{character} vector containing 5 elements, each with a maximum length of 10 characters. The arguments marked for \code{"netcdf4"} format refer to the chunk cache used for reading and writing variables. Default cache settings are defined by the NetCDF library, and they can be adjusted for each variable to improve performance in some applications. } \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \note{\code{NC_BYTE} is always interpreted as signed.} \author{Pavel Michna, Milton Woods} \examples{ ## Create a new NetCDF dataset and define two dimensions file1 <- tempfile("var.get_", fileext=".nc") nc <- create.nc(file1) dim.def.nc(nc, "station", 5) dim.def.nc(nc, "time", unlim=TRUE) dim.def.nc(nc, "max_string_length", 32) ## Create three variables, one as coordinate variable var.def.nc(nc, "time", "NC_INT", "time") var.def.nc(nc, "temperature", "NC_DOUBLE", c(0,1)) var.def.nc(nc, "name", "NC_CHAR", c("max_string_length", "station")) ## Put some _FillValue attribute for temperature att.put.nc(nc, "temperature", "_FillValue", "NC_DOUBLE", -99999.9) ## Define variable values mytime <- c(1:2) mytemperature <- c(1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, NA, NA, 9.9) myname <- c("alfa", "bravo", "charlie", "delta", "echo") ## Put the data var.put.nc(nc, "time", mytime, 1, length(mytime)) var.put.nc(nc, "temperature", mytemperature, c(1,1), c(5,2)) var.put.nc(nc, "name", myname, c(1,1), c(32,5)) sync.nc(nc) ## Get the data (or a subset) var.get.nc(nc, 0) var.get.nc(nc, "temperature") var.get.nc(nc, "temperature", c(3,1), c(1,1)) var.get.nc(nc, "temperature", c(3,2)) var.get.nc(nc, "temperature", c(NA,2), c(NA,1)) var.get.nc(nc, "name") var.get.nc(nc, "name", c(1,2), c(4,2)) var.get.nc(nc, "name", c(1,2), c(NA,2)) close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/type.inq.nc.Rd0000644000176200001440000000531114577713273014667 0ustar liggesusers\name{type.inq.nc} \alias{type.inq.nc} \title{Inquire About a NetCDF Type} \description{Inquire about a NetCDF builtin or user-defined data type.} \usage{type.inq.nc(ncfile, type, fields=TRUE)} \arguments{ \item{ncfile}{Object of class \code{NetCDF} which points to the NetCDF dataset or group.} \item{type}{ID or name of a NetCDF data type.} \item{fields}{Read members of enum types or fields of compound types (default \code{TRUE}).} } \value{ A list containing the following components: \item{id}{Type ID.} \item{name}{Type name.} \item{class}{One of the keywords \code{"builtin"}, \code{"compound"}, \code{"enum"}, \code{"opaque"} or \code{"vlen"}.} \item{size}{Size in bytes of a single item of the type (or a single element of a \code{"vlen"}).} \item{basetype}{(\code{"enum"} or \code{"vlen"}) Name of the NetCDF type of each element.} If \code{fields=TRUE}, the return list includes details about members of enum types or fields of compound types: \item{value}{(\code{"enum"} only) Named vector with numeric values of all members.} \item{offset}{(\code{"compound"} only) Named vector with the offset of each field in bytes from the beginning of the compound type.} \item{subtype}{(\code{"compound"} only) Named vector with the NetCDF type name of each field.} \item{dimsizes}{(\code{"compound"} only) Named list with array dimensions of each field. Dimension lengths are reported in R order (leftmost index varies fastest; opposite to CDL conventions). A \code{NULL} length indicates a scalar.} } \details{This function obtains information about a NetCDF data type, which could be builtin or user-defined. The items in the return list depend on the class of the NetCDF type.} \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \seealso{ \code{\link{grp.inq.nc}} - get a list of NetCDF types defined in a dataset or group. \code{\link{type.def.nc}} - define a new NetCDF type. } \examples{ ## Create a new NetCDF4 dataset and define types file1 <- tempfile("type.inq_", fileext=".nc") nc <- create.nc(file1, format="netcdf4") # Define a type of each class: type.def.nc(nc, "blob", "opaque", size=128) type.def.nc(nc, "vector", "vlen", basetype="NC_FLOAT") type.def.nc(nc, "factor", "enum", basetype="NC_INT", names=c("peanut butter", "jelly"), values=c(101, 102)) type.def.nc(nc, "struct", "compound", names=c("siteid", "height", "colour"), subtypes=c("NC_INT", "NC_DOUBLE", "NC_SHORT"), dimsizes=list(NULL, NULL, c(3))) # Inquire about the types: typeids <- grp.inq.nc(nc)$typeids for (typeid in typeids) { print(type.inq.nc(nc, typeid)) } close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/att.put.nc.Rd0000644000176200001440000000560714577713273014527 0ustar liggesusers\name{att.put.nc} \alias{att.put.nc} \title{Put a NetCDF Attribute} \description{Put an attribute to a NetCDF dataset.} \usage{att.put.nc(ncfile, variable, name, type, value)} \arguments{ \item{ncfile}{Object of class \code{NetCDF} which points to the NetCDF dataset (as returned from \code{\link[RNetCDF]{open.nc}}).} \item{variable}{ID or name of the variable to which the attribute will be assigned or \code{"NC_GLOBAL"} for a global attribute.} \item{name}{Attribute name. Must begin with an alphabetic character, followed by zero or more alphanumeric characters including the underscore (\code{"_"}). Case is significant. Attribute name conventions are assumed by some NetCDF generic applications, e.g., \code{units} as the name for a string attribute that gives the units for a NetCDF variable.} \item{type}{External NetCDF data type as one of the following labels: \code{NC_BYTE}, \code{NC_UBYTE}, \code{NC_CHAR}, \code{NC_SHORT}, \code{NC_USHORT}, \code{NC_INT}, \code{NC_UINT}, \code{NC_INT64}, \code{NC_UINT64}, \code{NC_FLOAT}, \code{NC_DOUBLE}, \code{NC_STRING}, or a user-defined type name.} \item{value}{Attribute value. This can be either a single numeric value or a vector of numeric values, or alternatively a character string.} } \details{Names commencing with underscore (\code{"_"}) are reserved for use by the NetCDF library. Most generic applications that process NetCDF datasets assume standard attribute conventions and it is strongly recommended that these be followed unless there are good reasons for not doing so. Text represented by R type \code{character} can be written to NetCDF types \code{NC_CHAR} and \code{NC_STRING}, and R type \code{raw} can be written to NetCDF type \code{NC_CHAR}. R \code{numeric} and \code{integer} variables can be written to NetCDF numeric types. The NetCDF library handles type conversions, but conversions of values outside the range of a type will result in an error. Due to the lack of native support for 64-bit integers in R, this function accepts \code{\link[bit64:bit64-package]{integer64}} vectors. } \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \note{\code{NC_BYTE} is always interpreted as signed.} \author{Pavel Michna, Milton Woods} \examples{ ## Create a new NetCDF dataset and define two dimensions file1 <- tempfile("att.put_", fileext=".nc") nc <- create.nc(file1) dim.def.nc(nc, "station", 5) dim.def.nc(nc, "time", unlim=TRUE) ## Create two variables, one as coordinate variable var.def.nc(nc, "time", "NC_INT", "time") var.def.nc(nc, "temperature", "NC_DOUBLE", c(0,1)) ## Put some attributes att.put.nc(nc, "temperature", "_FillValue", "NC_DOUBLE", -99999.9) att.put.nc(nc, "temperature", "long_name", "NC_CHAR", "air temperature") att.put.nc(nc, "NC_GLOBAL", "title", "NC_CHAR", "Data from Foo") att.put.nc(nc, "NC_GLOBAL", "history", "NC_CHAR", paste("Created on", date())) close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/grp.def.nc.Rd0000644000176200001440000000352414577713273014451 0ustar liggesusers\name{grp.def.nc} \alias{grp.def.nc} \title{Define a NetCDF Group} \description{Define a NetCDF Group.} \usage{grp.def.nc(ncid, grpname)} \arguments{ \item{ncid}{Object of class \code{NetCDF} which points to the NetCDF dataset (as returned from \code{\link[RNetCDF]{open.nc}}) or parent group (as returned by this function).} \item{grpname}{Group name. Must begin with an alphabetic character, followed by zero or more alphanumeric characters including the underscore (\code{"_"}). Case is significant.} } \value{Object of class \code{NetCDF} which points to the NetCDF group, returned invisibly.} \details{This function may only be used with datasets in \code{netcdf4} format. It creates a new NetCDF group, which may be used as a container for other NetCDF objects, including groups, dimensions, variables and attributes. Most NetCDF object types, including groups, variables and global attributes, are visible only in the group where they are defined. However, dimensions are visible in their groups and all child groups.} \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ ## Create a new NetCDF4 dataset file1 <- tempfile("grp.def_", fileext=".nc") nc <- create.nc(file1, format="netcdf4") ## Define dimensions, variables and attributes in the root group dim.def.nc(nc, "station", 5) var.def.nc(nc, "station", "NC_CHAR", c("station")) att.put.nc(nc, "NC_GLOBAL", "Description", "NC_CHAR", "Site-based measurements") ## Define a group grp <- grp.def.nc(nc, "time_series") ## Define dimensions and variables in the new group dim.def.nc(grp, "time", unlim=TRUE) var.def.nc(grp, "time", "NC_INT", "time") var.def.nc(grp, "temperature", "NC_DOUBLE", c("station","time")) att.put.nc(nc, "NC_GLOBAL", "Description", "NC_CHAR", "Time-series at sites") close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/grp.inq.nc.Rd0000644000176200001440000000742314577713273014504 0ustar liggesusers\name{grp.inq.nc} \alias{grp.inq.nc} \title{Inquire About a NetCDF Group} \description{Inquire about a NetCDF group.} \usage{grp.inq.nc(ncid,grpname=NULL,ancestors=TRUE)} \arguments{ \item{ncid}{Object of class \code{NetCDF} which points to a NetCDF group (from \code{\link[RNetCDF]{grp.def.nc}}) or dataset (from \code{\link[RNetCDF]{open.nc}}).} \item{grpname}{By default, the inquiry relates to the group represented by \code{ncid}. If \code{grpname} is a character string, a group with this name is examined instead. A hierarchical search is performed if \code{grpname} contains \code{"/"}, otherwise only the immediate group of \code{ncid} is searched for a matching group name.} \item{ancestors}{If \code{TRUE}, dimensions and names of ancestor groups are examined. Otherwise, only dimensions and names defined in the current group are reported.} } \value{ A list containing the following components: \item{self}{Object of class \code{NetCDF} representing the group.} \item{parent}{Object of class \code{NetCDF} representing the parent group, or \code{NULL} for the root group.} \item{grps}{List of objects of class \code{NetCDF} representing the groups in the group.} \item{name}{Name of the NetCDF group.} \item{fullname}{Full name of the NetCDF group, with ancestors listed in order from the root group of the dataset and separated by \code{"/"}. Omitted if \code{ancestors} is \code{FALSE}.} \item{dimids}{Vector of dimension identifiers. If \code{ancestors} is \code{TRUE} (default), all visible dimensions in the group and its ancestors are reported, otherwise only dimensions defined in the group of \code{ncid} are shown.} \item{unlimids}{Vector of identifiers for unlimited dimensions. If \code{ancestors} is \code{TRUE} (default), all unlimited dimensions in the group and its ancestors are reported, otherwise only unlimited dimensions defined in the group of \code{ncid} are shown.} \item{varids}{Vector of identifiers for variables in the group.} \item{typeids}{Vector of identifiers for types in the group.} \item{ngatts}{Number of group attributes.} } \details{This function provides information about the structure of a NetCDF group or dataset. The results allow programs to explore a dataset without prior knowledge of the contents.} \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ # Create a new NetCDF dataset: file1 <- tempfile("grp.inq_", fileext=".nc") nc <- create.nc(file1, format="netcdf4") # Define groups in root group. # (Any names can be used; hierarchical numbers are used here for clarity) grp11 <- grp.def.nc(nc, "group1.1") grp12 <- grp.def.nc(nc, "group1.2") # Define group nested in group1.1: grp111 <- grp.def.nc(grp11, "group1.1.1") # Put some attributes in each group. # (We could also define dimensions, types, and variables). att.put.nc(nc, "NC_GLOBAL", "title", "NC_CHAR", "Group 1 (root)") att.put.nc(grp11, "NC_GLOBAL", "title", "NC_CHAR", "Group 1.1") att.put.nc(grp12, "NC_GLOBAL", "title", "NC_CHAR", "Group 1.2") att.put.nc(grp111, "NC_GLOBAL", "title", "NC_CHAR", "Group 1.1.1") ## Examine contents of a group directly using its hierarchical name ... mygrp <- grp.inq.nc(nc, "/group1.1/group1.1.1") att.get.nc(mygrp$self, "NC_GLOBAL", "title") ## Recursively examine contents of nested groups ... # (See also print.nc for a visual overview) get_global_atts <- function(ncid) { inq <- grp.inq.nc(ncid) atts <- character(inq$ngatts) for (ii in seq_len(inq$ngatts)) { atts[ii] <- att.get.nc(ncid, "NC_GLOBAL", ii-1) } ngrps <- length(inq$grps) grps <- vector("list", ngrps + 1) grps[[1]] <- atts for (ii in seq_len(ngrps)) { grps[[ii + 1]] <- get_global_atts(inq$grps[[ii]]) } return(grps) } get_global_atts(nc) ## Tidy up: close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/var.rename.nc.Rd0000644000176200001440000000227014577713273015157 0ustar liggesusers\name{var.rename.nc} \alias{var.rename.nc} \title{Rename a NetCDF Variable} \description{Rename a NetCDF variable.} \usage{var.rename.nc(ncfile, variable, newname)} \arguments{ \item{ncfile}{Object of class \code{NetCDF} which points to the NetCDF dataset (as returned from \code{\link[RNetCDF]{open.nc}}).} \item{variable}{Either the ID or the name of the variable to be renamed.} \item{newname}{The new variable name.} } \details{This function renames an existing variable in a NetCDF dataset open for writing. A variable cannot be renamed to have the same name as another variable.} \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ ## Create a new NetCDF dataset and define two dimensions file1 <- tempfile("var.rename_", fileext=".nc") nc <- create.nc(file1) dim.def.nc(nc, "station", 5) dim.def.nc(nc, "time", unlim=TRUE) ## Create two variables, one as coordinate variable var.def.nc(nc, "time", "NC_INT", "time") var.def.nc(nc, "temperature", "NC_DOUBLE", c(0,1)) ## Rename these variables var.rename.nc(nc, 0, "mytime") var.rename.nc(nc, "temperature", "mytemperature") close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/var.inq.nc.Rd0000644000176200001440000000762114577713273014504 0ustar liggesusers\name{var.inq.nc} \alias{var.inq.nc} \title{Inquire About a NetCDF Variable} \description{Inquire about a NetCDF variable.} \usage{var.inq.nc(ncfile, variable)} \arguments{ \item{ncfile}{Object of class \code{NetCDF} which points to the NetCDF dataset (as returned from \code{\link[RNetCDF]{open.nc}}).} \item{variable}{Either the ID or the name of the variable to be inquired.} } \value{ A list of named components, some of which are only included for datasets in \code{"netcdf4"} format (as reported by \code{\link[RNetCDF]{file.inq.nc}}). \item{id}{Variable ID.} \item{name}{Variable name.} \item{type}{External NetCDF data type as one of the following labels: \code{NC_BYTE}, \code{NC_UBYTE}, \code{NC_CHAR}, \code{NC_SHORT}, \code{NC_USHORT}, \code{NC_INT}, \code{NC_UINT}, \code{NC_INT64}, \code{NC_UINT64}, \code{NC_FLOAT}, \code{NC_DOUBLE}, \code{NC_STRING}, or a user-defined type name.} \item{ndims}{Number of dimensions the variable was defined as using.} \item{dimids}{Vector of dimension IDs corresponding to the variable dimensions (\code{NA} for scalar variables). Order is leftmost varying fastest.} \item{natts}{Number of variable attributes assigned to this variable.} \item{chunksizes}{(\code{"netcdf4"}) Chunk size expressed as the number of elements along each dimension, in the same order as \code{dimids}. \code{NULL} implies contiguous storage.} \item{cache_bytes}{(\code{"netcdf4"}) Size of chunk cache in bytes (\code{NULL} if unsupported).} \item{cache_slots}{(\code{"netcdf4"}) The number of slots in the chunk cache (\code{NULL} if unsupported).} \item{cache_preemption}{(\code{"netcdf4"}) A value between 0 and 1 (inclusive) that biases the cache scheme towards eviction of chunks that have been fully read (\code{NULL} if unsupported).} \item{deflate}{(\code{"netcdf4"}) Integer indicating level of compression, from 0 (minimum) to 9 (maximum), or \code{NA} if compression is not enabled.} \item{shuffle}{(\code{"netcdf4"}) \code{TRUE} if byte shuffling is enabled for the variable, \code{FALSE} otherwise.} \item{big_endian}{(\code{"netcdf4"}) Byte order of the variable. \code{TRUE} for big-endian, \code{FALSE} for little-endian, \code{NA} for not yet determined, or \code{NULL} if unsupported.} \item{fletcher32}{(\code{"netcdf4"}) \code{TRUE} if the fletcher32 checksum is enabled for this variable, \code{FALSE} otherwise.} \item{szip_options}{(\code{"netcdf4"}) Integer containing a bitmask of szip options. \code{NA} if szip is not used, or \code{NULL} if unsupported.} \item{szip_bits}{(\code{"netcdf4"}) Number of bits per pixel for szip. \code{NA} if szip is not used, or \code{NULL} if unsupported.} \item{filter_id}{(\code{"netcdf4"}) Vector of filter IDs associated with the variable, or \code{NULL} if the NetCDF library does not support the multi-filter interface.} \item{filter_params}{(\code{"netcdf4"}) List with one element per \code{filter_id}, or \code{NULL} if the NetCDF library does not support the multi-filter interface. Each list member is a vector of \code{numeric} parameters for the corresponding filter. Please see the NetCDF documentation for information about the available filters and their parameters.} } \details{This function returns information about a NetCDF variable, including its name, ID, type, number of dimensions, a vector of the dimension IDs, and the number of attributes.} \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ ## Create a new NetCDF dataset and define two dimensions file1 <- tempfile("var.inq_", fileext=".nc") nc <- create.nc(file1) dim.def.nc(nc, "station", 5) dim.def.nc(nc, "time", unlim=TRUE) ## Create two variables, one as coordinate variable var.def.nc(nc, "time", "NC_INT", "time") var.def.nc(nc, "temperature", "NC_DOUBLE", c(0,1)) ## Inquire about these variables var.inq.nc(nc, 0) var.inq.nc(nc, "temperature") close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/00RNetCDF.Rd0000644000176200001440000001140614577713273014050 0ustar liggesusers\name{RNetCDF} \docType{package} \alias{RNetCDF} \alias{RNetCDF-package} \title{R Interface to NetCDF Datasets} \description{ This package provides an interface to Unidata's NetCDF library functions (version 4) and furthermore access to Unidata's UDUNITS (version 2) calendar conversions. The routines and the documentation follow the NetCDF and UDUNITS C interface, so the corresponding manuals can be consulted for more detailed information. NetCDF is an abstraction that supports a view of data as a collection of self-describing, portable objects that can be accessed through a simple interface. Array values may be accessed directly, without knowing details of how the data are stored. Auxiliary information about the data, such as what units are used, may be stored with the data. Generic utilities and application programs can access NetCDF datasets and transform, combine, analyze, or display specified fields of the data. First versions of the R and C code of this package were based on the \code{netCDF} package by Thomas Lumley and the \code{ncdf} package by David Pierce. Milton Woods added some enhancements of the NetCDF library versions 3.6 and 4.x. } \section{Functions}{ Help pages are available for the following RNetCDF functions: \tabular{ll}{ \bold{Category} \tab \bold{Function} \cr Dataset \tab \code{\link{close.nc}} \cr \tab \code{\link{create.nc}} \cr \tab \code{\link{file.inq.nc}} \cr \tab \code{\link{open.nc}} \cr \tab \code{\link{print.nc}} \cr \tab \code{\link{read.nc}} \cr \tab \code{\link{sync.nc}} \cr Group \tab \code{\link{grp.def.nc}} \cr \tab \code{\link{grp.inq.nc}} \cr \tab \code{\link{grp.rename.nc}} \cr Attribute \tab \code{\link{att.copy.nc}} \cr \tab \code{\link{att.delete.nc}} \cr \tab \code{\link{att.get.nc}} \cr \tab \code{\link{att.inq.nc}} \cr \tab \code{\link{att.put.nc}} \cr \tab \code{\link{att.rename.nc}} \cr Dimension \tab \code{\link{dim.def.nc}} \cr \tab \code{\link{dim.inq.nc}} \cr \tab \code{\link{dim.rename.nc}} \cr Data type \tab \code{\link{type.def.nc}} \cr \tab \code{\link{type.inq.nc}} \cr Variable \tab \code{\link{var.def.nc}} \cr \tab \code{\link{var.get.nc}} \cr \tab \code{\link{var.inq.nc}} \cr \tab \code{\link{var.par.nc}} \cr \tab \code{\link{var.put.nc}} \cr \tab \code{\link{var.rename.nc}} \cr Calendar \tab \code{\link{utcal.nc}} \cr \tab \code{\link{utinit.nc}} \cr \tab \code{\link{utinvcal.nc}} } } \section{Data Types}{ The external types supported by all NetCDF datasets are: \tabular{ll}{ \code{NC_CHAR} \tab 8-bit characters intended for representing text. \cr \code{NC_BYTE} \tab 8-bit signed integers. \cr \code{NC_SHORT} \tab 16-bit signed integers. \cr \code{NC_INT} \tab 32-bit signed integers. \cr \code{NC_FLOAT} \tab 32-bit IEEE floating-point. \cr \code{NC_DOUBLE} \tab 64-bit IEEE floating-point. \cr } Datasets in NetCDF4 format support additional external types, including: \tabular{ll}{ \code{NC_UBYTE} \tab 8-bit unsigned integers. \cr \code{NC_USHORT} \tab 16-bit unsigned integers. \cr \code{NC_UINT} \tab 32-bit unsigned integers. \cr \code{NC_INT64} \tab 64-bit signed integers. \cr \code{NC_UINT64} \tab 64-bit unsigned integers. \cr \code{NC_STRING} \tab variable length character strings. \cr } These types are called \dQuote{external}, because they correspond to the portable external representation for NetCDF data. When a program reads external NetCDF data into an internal variable, the data is converted, if necessary, into the specified internal type. Similarly, if you write internal data into a NetCDF variable, this may cause it to be converted to a different external type, if the external type for the NetCDF variable differs from the internal type. In addition to the external types, NetCDF4 supports user-defined types. See \code{\link{type.def.nc}} for more explanation. } \references{ \url{https://www.unidata.ucar.edu/software/netcdf/} \url{https://www.unidata.ucar.edu/software/udunits/} } \note{When installing RNetCDF from source code, the netcdf4 library and header files must be installed on the system. Calendar functions will only be enabled in RNetCDF if the udunits2 library and header files are detected during the build process. Parallel file access requires a netcdf4 library built with MPI support along with an MPI interface package installed in R (e.g. pbdMPI or Rmpi).} \author{Pavel Michna, Milton Woods} \keyword{file} RNetCDF/man/dim.def.nc.Rd0000644000176200001440000000370214577713273014430 0ustar liggesusers\name{dim.def.nc} \alias{dim.def.nc} \title{Define a NetCDF Dimension} \description{Define a new NetCDF dimension.} \usage{dim.def.nc(ncfile, dimname, dimlength=1, unlim=FALSE)} \arguments{ \item{ncfile}{Object of class \code{NetCDF} which points to the NetCDF dataset (as returned from \code{\link[RNetCDF]{open.nc}}).} \item{dimname}{Dimension name. Must begin with an alphabetic character, followed by zero or more alphanumeric characters including the underscore (\code{"_"}). Case is significant.} \item{dimlength}{Length of dimension, that is, number of values for this dimension as an index to variables that use it. This must be a positive integer. If an unlimited dimension is created (\code{unlim=TRUE}), the value of \code{length} is not used.} \item{unlim}{Set to \code{TRUE} if an unlimited dimension should be created, otherwise to \code{FALSE}.} } \value{NetCDF variable identifier, returned invisibly.} \details{This function creates a new NetCDF dimension. There is a suggested limit (100) to the number of dimensions. Ordinarily, the name and length of a dimension are fixed when the dimension is first defined. The name may be changed later, but the length of a dimension (other than the unlimited dimension) cannot be changed without copying all the data to a new NetCDF dataset with a redefined dimension length. A NetCDF dimension in an open NetCDF dataset is referred to by a small integer called a dimension ID. In the C interface, dimension IDs are 0, 1, 2, ..., in the order in which the dimensions were defined. At most one unlimited length dimension may be defined for each NetCDF dataset.} \references{\url{https://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ ## Create a new NetCDF dataset and define two dimensions file1 <- tempfile("dim.def_", fileext=".nc") nc <- create.nc(file1) dim.def.nc(nc, "station", 5) dim.def.nc(nc, "time", unlim=TRUE) close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/DESCRIPTION0000644000176200001440000000226614600137202013146 0ustar liggesusersPackage: RNetCDF Version: 2.9-2 Date: 2024-03-24 Title: Interface to 'NetCDF' Datasets Authors@R: c(person("Pavel", "Michna", role = "aut", email = "rnetcdf-devel@bluewin.ch"), person("Milton", "Woods", role = c("aut", "cre"), email = "miltonjwoods@gmail.com")) Depends: R (>= 3.0.0) SystemRequirements: netcdf (>=4.1.3), udunits-2 (>=2.0.4) Suggests: bit64, tools Enhances: pbdMPI, Rmpi Description: An interface to the 'NetCDF' file formats designed by Unidata for efficient storage of array-oriented scientific data and descriptions. Most capabilities of 'NetCDF' version 4 are supported. Optional conversions of time units are enabled by 'UDUNITS' version 2, also from Unidata. License: GPL (>= 2) | file LICENSE URL: https://github.com/mjwoods/RNetCDF https://www.unidata.ucar.edu/software/netcdf/ https://www.unidata.ucar.edu/software/udunits/ BugReports: https://github.com/mjwoods/RNetCDF/issues NeedsCompilation: yes Packaged: 2024-03-24 03:45:20 UTC; mwoods Author: Pavel Michna [aut], Milton Woods [aut, cre] Maintainer: Milton Woods Repository: CRAN Date/Publication: 2024-03-25 00:00:02 UTC RNetCDF/tests/0000755000176200001440000000000014577720574012623 5ustar liggesusersRNetCDF/tests/RNetCDF-test.R0000644000176200001440000015717714577720574015132 0ustar liggesusers#===============================================================================# # # Name: RNetCDF-test.R # # Version: 2.9-2 # # Purpose: Test functions to the NetCDF interface for R. # # Author: Pavel Michna (rnetcdf-devel@bluewin.ch) # Milton Woods (miltonjwoods@gmail.com) # # Copyright (C) 2004-2024 Pavel Michna and Milton Woods. # #===============================================================================# # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # #===============================================================================# # Fail on warnings: options(warn=2) # tools::assertWarning is not defined in old R versions, # so define a local function with similar behaviour: assertWarning <- function(expr) { warn <- FALSE withCallingHandlers(expr, warning=function(w) { warn <<- TRUE invokeRestart("muffleWarning") } ) if (!warn) { stop("Expected warning from expression, but none occurred") } } #===============================================================================# # Load library #===============================================================================# library(RNetCDF) has_bit64 <- require(bit64) loadNamespace("tools") #===============================================================================# # Optional NetCDF features detected during package installation. # Note that config.nc is not intended for user code. # If necessary, users can handle missing features using 'try'. #===============================================================================# cfg <- config.nc() #===============================================================================# # Run tests #===============================================================================# #-------------------------------------------------------------------------------# # NetCDF library functions #-------------------------------------------------------------------------------# #--Initialize ------------------------------------------------------------------# cat("Starting NetCDF tests...\n") testfun <- function(x,y,tally=NULL) { if (is.null(tally)) { tally <- c(pass=0,fail=0) } # Compare numeric values with single precision tolerance: if (isTRUE(all.equal(x,y,tolerance=2^(-23)))) { cat("OK\n") return(tally+c(1,0)) } else { cat("Failed\n") cat("x:\n") str(x) print(attributes(x)) cat("y:\n") str(y) print(attributes(y)) return(tally+c(0,1)) } } tally <- NULL ## Create a new NetCDF dataset and define dimensions for (format in c("classic","offset64","data64","classic4","netcdf4")) { ncfile <- tempfile(paste("RNetCDF-test", format, "", sep="_"), fileext=".nc") cat("Test", format, "file format in", ncfile, "...\n") if (format == "data64" && !cfg$data64) { message("NetCDF library does not support file format data64") nc <- try(create.nc(ncfile, format=format), silent=TRUE) tally <- testfun(inherits(nc, "try-error"), TRUE, tally) unlink(ncfile) next } nc <- create.nc(ncfile, format=format) tally <- testfun(TRUE, TRUE, tally) # Show library version: libvers <- file.inq.nc(nc)$libvers cat("Version of netcdf library ... ", libvers, "\n") verstr <- sub('([[:digit:]\\.]+).*', '\\1', libvers) nstation <- 5 ntime <- 2 nstring <- 7 nempty <- 0 cat("Defining dimensions ...\n") dim.def.nc(nc, "station", nstation) dim.def.nc(nc, "time", ntime) dim.def.nc(nc, "max_string_length", nstring) dim.def.nc(nc, "empty", unlim=TRUE) tally <- testfun(TRUE, TRUE, tally) if (format == "netcdf4") { ## Define a group cat("Defining a group ...\n") ncroot <- nc nc <- grp.def.nc(nc, "testgrp") tally <- testfun(TRUE, TRUE, tally) ## Define a type of each class: cat("Defining user-defined types ...\n") id_blob <- type.def.nc(nc, "blob", "opaque", size=128) inq_blob <- list(id=id_blob, name="blob", class="opaque", size=128) id_vector <- type.def.nc(nc, "vector", "vlen", basetype="NC_INT") inq_vector <- list(id=id_vector, name="vector", class="vlen", size=NA, basetype="NC_INT") id_vector_char <- type.def.nc(nc, "vector_char", "vlen", basetype="NC_CHAR") inq_vector_char <- list(id=id_vector_char, name="vector_char", class="vlen", size=NA, basetype="NC_CHAR") id_vector_string <- type.def.nc(nc, "vector_string", "vlen", basetype="NC_STRING") inq_vector_string <- list(id=id_vector_string, name="vector_string", class="vlen", size=NA, basetype="NC_STRING") id_vector_blob <- type.def.nc(nc, "vector_blob", "vlen", basetype=id_blob) inq_vector_blob <- list(id=id_vector_blob, name="vector_blob", class="vlen", size=NA, basetype="blob") id_factor <- type.def.nc(nc, "factor", "enum", basetype="NC_USHORT", names=c("NA", "peanut butter", "jelly"), values=c(100, 101, 102)) inq_factor <- list(id=id_factor, name="factor", class="enum", size=2, basetype="NC_USHORT", value=c("NA"=100,"peanut butter"=101,"jelly"=102)) id_struct <- type.def.nc(nc, "struct", "compound", names=c("siteid", "height", "colour"), subtypes=c("NC_INT", "NC_DOUBLE", "NC_SHORT"), dimsizes=list(NULL, NULL, c(3))) inq_struct <- list(id=id_struct, name="struct", class="compound", size=18, offset=c(siteid=0,height=4,colour=12), subtype=c(siteid="NC_INT",height="NC_DOUBLE",colour="NC_SHORT"), dimsizes=list("siteid"=NULL,"height"=NULL,"colour"=c(3))) typeids <- c(id_blob, id_vector, id_vector_char, id_vector_string, id_vector_blob, id_factor, id_struct) if (package_version(verstr) >= package_version("4.9.0")) { id_vector_vector <- type.def.nc(nc, "vector_vector", "vlen", basetype=id_vector) inq_vector_vector <- list(id=id_vector_vector, name="vector_vector", class="vlen", size=NA, basetype="vector") typeids <- c(typeids, id_vector_vector) } tally <- testfun(TRUE, TRUE, tally) } ## Define variables cat("Defining variables for netcdf3 ...\n") var.def.nc(nc, "time", "NC_INT", "time") inq_temperature <- list() inq_temperature$id <- var.def.nc(nc, "temperature", "NC_DOUBLE", c(0,1), chunking=TRUE, chunksizes=c(5,1), deflate=5, shuffle=TRUE, big_endian=TRUE, fletcher32=TRUE) inq_temperature$name <- "temperature" inq_temperature$type <- "NC_DOUBLE" inq_temperature$ndims <- as.integer(2) inq_temperature$dimids <- as.integer(c(0,1)) inq_temperature$natts <- as.integer(0) inq_temperature$chunksizes <- as.numeric(c(5,1)) inq_temperature$deflate <- as.integer(5) inq_temperature$shuffle <- TRUE inq_temperature$big_endian <- TRUE inq_temperature$fletcher32 <- TRUE var.def.nc(nc, "packvar", "NC_BYTE", c("station")) var.def.nc(nc, "name", "NC_CHAR", c("max_string_length", "station")) var.def.nc(nc, "name_fill", "NC_CHAR", c("max_string_length", "station")) var.def.nc(nc, "qcflag", "NC_CHAR", c("station")) var.def.nc(nc, "int0", "NC_INT", NA) var.def.nc(nc, "char0", "NC_CHAR", NA) var.def.nc(nc, "numempty", "NC_FLOAT", c("station","empty")) varcnt <- 9 numtypes <- c("NC_BYTE", "NC_SHORT", "NC_INT", "NC_FLOAT", "NC_DOUBLE") tally <- testfun(TRUE, TRUE, tally) if (format == "netcdf4") { cat("Defining variables for netcdf4 ...\n") var.def.nc(nc, "namestr", "NC_STRING", c("station")) var.def.nc(nc, "namestr_fill", "NC_STRING", c("station")) var.def.nc(nc, "profile", id_vector, c("station","time")) var.def.nc(nc, "profile_fill", id_vector, c("station","time")) var.def.nc(nc, "profile_pack", id_vector, c("station","time")) att.put.nc(nc, "profile_pack", "scale_factor", "NC_FLOAT", 10) var.def.nc(nc, "profile_char", id_vector_char, c("station","time")) var.def.nc(nc, "profile_string", id_vector_string, c("station","time")) var.def.nc(nc, "profile_blob", id_vector_blob, c("time")) var.def.nc(nc, "profile_scalar", id_vector, NA) var.def.nc(nc, "rawdata", id_blob, c("station","time")) var.def.nc(nc, "rawdata_scalar", id_blob, NA) var.def.nc(nc, "rawdata_vector", id_blob, c("station")) var.def.nc(nc, "snacks", "factor", c("station", "time")) var.def.nc(nc, "snacks_empty", "factor", c("station", "time")) var.def.nc(nc, "person", "struct", c("station", "time")) var.def.nc(nc, "person_fill", "struct", c("station", "time")) varcnt <- varcnt+16 if (package_version(verstr) >= package_version("4.9.0")) { var.def.nc(nc, "profile_vector", id_vector_vector, c("station","time")) var.def.nc(nc, "profile_vector_fill", id_vector_vector, c("station","time")) varcnt <- varcnt+2 } tally <- testfun(TRUE, TRUE, tally) numtypes <- c(numtypes, "NC_UBYTE", "NC_USHORT", "NC_UINT") if (has_bit64) { var.def.nc(nc, "stationid", "NC_UINT64", c("station")) varcnt <- varcnt+1 numtypes <- c(numtypes, "NC_INT64", "NC_UINT64") tally <- testfun(TRUE, TRUE, tally) } inq_filter <- list() inq_filter$filter_id <- c(2,1) # Shuffle, deflate inq_filter$filter_params <- list(numeric(0),c(9)) var.def.nc(nc, "temp_filter", "NC_FLOAT", c("station", "time"), chunking=TRUE, filter_id=inq_filter$filter_id, filter_params=inq_filter$filter_params) varcnt <- varcnt+1 } for (numtype in numtypes) { for (namode in seq(0,5)) { cat("Defining variables of type", numtype, "for na.mode", namode, "...\n") varname <- paste(numtype,namode,sep="_") var.def.nc(nc, varname, numtype, c("station")) tally <- testfun(TRUE, TRUE, tally) varname <- paste(numtype,"int",namode,sep="_") var.def.nc(nc, varname, numtype, c("station")) tally <- testfun(TRUE, TRUE, tally) varname <- paste(numtype,"fill",namode,sep="_") var.def.nc(nc, varname, numtype, c("station")) if (namode == 2) { att.put.nc(nc, varname, "missing_value", numtype, 99) } else if (namode == 4) { att.put.nc(nc, varname, "valid_range", numtype, c(1,5)) } else { att.put.nc(nc, varname, "_FillValue", numtype, 99) } tally <- testfun(TRUE, TRUE, tally) varname <- paste(numtype,"intfill",namode,sep="_") var.def.nc(nc, varname, numtype, c("station")) if (namode == 2) { att.put.nc(nc, varname, "missing_value", numtype, 99) } else if (namode == 4) { att.put.nc(nc, varname, "valid_min", numtype, 1) att.put.nc(nc, varname, "valid_max", numtype, 5) } else { att.put.nc(nc, varname, "_FillValue", numtype, 99) } tally <- testfun(TRUE, TRUE, tally) varname <- paste(numtype,"pack",namode,sep="_") var.def.nc(nc, varname, numtype, c("station")) att.put.nc(nc, varname, "scale_factor", numtype, 10) att.put.nc(nc, varname, "add_offset", numtype, 5) if (namode == 2) { att.put.nc(nc, varname, "missing_value", numtype, 99) } else if (namode == 4) { att.put.nc(nc, varname, "valid_min", numtype, 1) att.put.nc(nc, varname, "valid_max", numtype, 5) } else { att.put.nc(nc, varname, "_FillValue", numtype, 99) } tally <- testfun(TRUE, TRUE, tally) varname <- paste(numtype,"intpack",namode,sep="_") var.def.nc(nc, varname, numtype, "station") att.put.nc(nc, varname, "scale_factor", numtype, 10) att.put.nc(nc, varname, "add_offset", numtype, 5) if (namode == 2) { att.put.nc(nc, varname, "missing_value", numtype, 99) } else if (namode == 4) { att.put.nc(nc, varname, "valid_range", numtype, c(1,5)) } else { att.put.nc(nc, varname, "_FillValue", numtype, 99) } tally <- testfun(TRUE, TRUE, tally) varname <- paste(numtype,"inf",namode,sep="_") var.def.nc(nc, varname, numtype, c("station")) tally <- testfun(TRUE, TRUE, tally) varname <- paste(numtype,"packinf",namode,sep="_") var.def.nc(nc, varname, numtype, c("station")) att.put.nc(nc, varname, "scale_factor", numtype, 0) varname <- paste(numtype,"intpackinf",namode,sep="_") var.def.nc(nc, varname, numtype, c("station")) att.put.nc(nc, varname, "scale_factor", numtype, 0) varcnt <- varcnt+9 if (numtype == "NC_DOUBLE") { varname <- paste(numtype,"fillna",namode,sep="_") var.def.nc(nc, varname, numtype, c("station")) if (namode == 2) { att.put.nc(nc, varname, "missing_value", numtype, as.double(NA)) } else if (namode == 4) { att.put.nc(nc, varname, "valid_range", numtype, c(as.double(-Inf),as.double(Inf))) } else { att.put.nc(nc, varname, "_FillValue", numtype, as.double(NA)) } tally <- testfun(TRUE, TRUE, tally) varcnt <- varcnt+1 } if (numtype == "NC_INT") { varname <- paste(numtype,"intfillna",namode,sep="_") var.def.nc(nc, varname, numtype, c("station")) if (namode == 2) { att.put.nc(nc, varname, "missing_value", numtype, as.integer(NA)) } else if (namode == 4) { att.put.nc(nc, varname, "valid_min", numtype, 1) att.put.nc(nc, varname, "valid_max", numtype, 5) } else { att.put.nc(nc, varname, "_FillValue", numtype, as.integer(NA)) } tally <- testfun(TRUE, TRUE, tally) varcnt <- varcnt+1 } if (has_bit64) { varname <- paste(numtype,"bit64",namode,sep="_") var.def.nc(nc, varname, numtype, c("station")) if (namode == 2) { att.put.nc(nc, varname, "missing_value", numtype, 99) } else if (namode == 4) { att.put.nc(nc, varname, "valid_range", numtype, c(1,5)) } else { att.put.nc(nc, varname, "_FillValue", numtype, 99) } tally <- testfun(TRUE, TRUE, tally) varname <- paste(numtype,"fill64",namode,sep="_") var.def.nc(nc, varname, numtype, c("station")) if (namode == 2) { att.put.nc(nc, varname, "missing_value", numtype, 99) } else if (namode == 4) { att.put.nc(nc, varname, "valid_min", numtype, 1) att.put.nc(nc, varname, "valid_max", numtype, 5) } else { att.put.nc(nc, varname, "_FillValue", numtype, 99) } tally <- testfun(TRUE, TRUE, tally) varname <- paste(numtype,"pack64",namode,sep="_") var.def.nc(nc, varname, numtype, c("station")) att.put.nc(nc, varname, "scale_factor", numtype, 10) att.put.nc(nc, varname, "add_offset", numtype, 5) if (namode == 2) { att.put.nc(nc, varname, "missing_value", numtype, 99) } else if (namode == 4) { att.put.nc(nc, varname, "valid_min", numtype, 1) att.put.nc(nc, varname, "valid_max", numtype, 5) } else { att.put.nc(nc, varname, "_FillValue", numtype, 99) } tally <- testfun(TRUE, TRUE, tally) varname <- paste(numtype,"packinf64",namode,sep="_") var.def.nc(nc, varname, numtype, c("station")) att.put.nc(nc, varname, "scale_factor", numtype, 0) varcnt <- varcnt+4 } } } cat("Defining additional attributes ...") ## Set a _FillValue attribute for temperature att.put.nc(nc, "temperature", "_FillValue", "NC_DOUBLE", -99999.9) inq_temperature$natts <- inq_temperature$natts + as.integer(1) ## Set a _FillValue attribute for name_fill: att.put.nc(nc, "name_fill", "_FillValue", "NC_CHAR", "X") ## Define the packing used by packvar id_double <- type.inq.nc(nc, "NC_DOUBLE")$id att.put.nc(nc, "packvar", "scale_factor", id_double, 10) att.put.nc(nc, "packvar", "add_offset", "NC_DOUBLE", -5) ## Define some additional test attributes: att_text <- "This is some text" att_text2 <- c("This is string 1", "This is string 2") att.put.nc(nc, "NC_GLOBAL", "char_att", "NC_CHAR", att_text) att.put.nc(nc, "name", "char_att", "NC_CHAR", att_text) att.put.nc(nc, "name", "raw_att", "NC_CHAR", charToRaw(att_text)) tally <- testfun(TRUE, TRUE, tally) if (format == "netcdf4") { cat("Defining additional attributes for netcdf4 ...") att.put.nc(nc, "temperature", "string_att", "NC_STRING", att_text2) tally <- testfun(TRUE, TRUE, tally) inq_temperature$natts <- inq_temperature$natts + as.integer(1) if (has_bit64) { hugeint <- as.integer64("-1234567890123456789") att.put.nc(nc, "temperature", "int64_att", "NC_INT64", hugeint) inq_temperature$natts <- inq_temperature$natts + as.integer(1) tally <- testfun(TRUE, TRUE, tally) } } ## Define variable values mytime <- c(1:2) mytemperature <- matrix(c(1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, NA, NA, 9.9),ncol=ntime) mypackvar <- seq_len(5)*10-5 myname <- c("alfa", "bravo", "charlie", "delta", "echo") myqcflag <- "ABCDE" myint0 <- 12345 mychar0 <- "?" mynamefill <- myname for (ii in seq_along(myname)) { mynamefill[ii] <- paste(rep("X", nstring), collapse="") substr(mynamefill[ii], 1, nstring) <- myname[ii] } mynamestr <- myname mynamestr[5] <- "NA" mynamestr_fill <- myname mynamestr_fill[5] <- NA mysmall <- as.double(c(1,2,3,4,5)) mybig <- mysmall*1e100 myminus <- -mysmall mysmallfill <- as.double(c(1,2,NA,4,5)) mybigfill <- mysmallfill*1e100 mypack <- mysmallfill*10+5 myinffill <- c(-Inf,.Machine$double.xmin,NA,NaN,Inf) myinf <- c(1,2,-Inf,4,5) if (has_bit64) { mysmall64 <- as.integer64(mysmall) mysmallfill64 <- as.integer64(mysmallfill) myminus64 <- -mysmall64 mybig64 <- as.integer64("1234567890123456789")+mysmall mybigfill64 <- as.integer64("1234567890123456789")+mysmallfill mypack64 <- as.integer64(mypack) } if (format == "netcdf4") { profiles <- vector("list", nstation*ntime) dim(profiles) <- c(nstation, ntime) for (ii in seq_len(nstation)) { for (jj in seq_len(ntime)) { # Profiles have increasing length, starting from 0: profiles[[ii,jj]] <- 10*seq_len(ii+jj-2)*(ii+jj) } } profiles_char <- lapply(profiles,function(x) {paste(as.character(x),collapse=",")}) dim(profiles_char) <- dim(profiles) profiles_string <- lapply(profiles, as.character) dim(profiles_string) <- dim(profiles) if (package_version(verstr) >= package_version("4.9.0")) { profiles_vector <- lapply(profiles, function(x) {lapply(x, seq_len)}) dim(profiles_vector) <- dim(profiles) profiles_vector_fill <- profiles_vector profiles_vector_fillval <- list(list(-999999999)) profiles_vector[[3]][[2]][5] <- -999999999 profiles_vector_fill[[3]][[2]][5] <- NA } profiles_fill <- profiles profiles_fillval <- list(-999999999) profiles[[3]][2] <- -999999999 profiles_fill[[3]][2] <- NA rawdata <- as.raw(seq_len(nstation*ntime*128) %% 256) dim(rawdata) <- c(128,nstation,ntime) profiles_blob <- list(rawdata[,3:5,1], rawdata[,0,1]) dim(profiles_blob) <- ntime snack_foods <- names(inq_factor$value) snacks <- factor(rep(snack_foods, length.out=nstation*ntime), levels=snack_foods) dim(snacks) <- c(nstation, ntime) snacks_fill <- snacks snacks_fill[snacks_fill == "NA"] <- NA snacks_empty <- snacks snacks_empty[] <- NA person <- list(siteid=array(rep(seq(1,nstation),ntime), c(nstation,ntime)), height=array(1+0.1*seq(1,nstation*ntime), c(nstation,ntime)), colour=array(rep(c(0,0,0,64,128,192),nstation), c(3,nstation,ntime))) person_fillval <- list(siteid=person$siteid[1,1], height=person$height[1,1], colour=person$colour[,1,1]) person_fill <- person person_fill$siteid[person_fill$siteid == person_fillval$siteid] <- NA person_fill$height[person_fill$height == person_fillval$height] <- NA # Note that array in compound uses same fill value for all elements: person_fill$colour[person_fill$colour == person_fillval$colour[1]] <- NA } ## Define some user-defined test attributes: if (format == "netcdf4") { cat("Defining user-defined attributes ...") person1 <- list(siteid=array(person$siteid[1,1], 1), height=array(person$height[1,1], 1), colour=array(person$colour[,1,1], c(3,1))) person3 <- list(siteid=array(person$siteid[1:3,1], 3), height=array(person$height[1:3,1], 3), colour=array(person$colour[,1:3,1], c(3,3))) att.put.nc(nc, "NC_GLOBAL", "compound_scal_att", "struct", person1) att.put.nc(nc, "NC_GLOBAL", "compound_vect_att", "struct", person3) att.put.nc(nc, "NC_GLOBAL", "enum_scal_att", "factor", snacks[1]) att.put.nc(nc, "NC_GLOBAL", "enum_vect_att", "factor", snacks[1:3]) att.put.nc(nc, "NC_GLOBAL", "opaque_scal_att", "blob", rawdata[,1,1]) att.put.nc(nc, "NC_GLOBAL", "opaque_vect_att", "blob", rawdata[,1,]) att.put.nc(nc, "NC_GLOBAL", "vector_scal_att", "vector", profiles[1]) att.put.nc(nc, "NC_GLOBAL", "vector_vect_att", "vector", profiles[1:3]) tally <- testfun(TRUE, TRUE, tally) # Fill values for strings and user-defined variables: att.put.nc(nc, "namestr_fill", "_FillValue", "NC_STRING", "_MISSING") att.put.nc(nc, "snacks", "_FillValue", "factor", factor("NA")) att.put.nc(nc, "person_fill", "_FillValue", "struct", person_fillval) att.put.nc(nc, "profile_fill", "_FillValue", id_vector, profiles_fillval) if (package_version(verstr) >= package_version("4.9.0")) { att.put.nc(nc, "profile_vector_fill", "_FillValue", id_vector_vector, profiles_vector_fillval) } } ## Put the data cat("Writing netcdf3 variables ...") var.put.nc(nc, "time", mytime, 1, length(mytime)) var.put.nc(nc, "temperature", mytemperature, c(1,1), c(nstation,ntime), cache_preemption=0.5) var.put.nc(nc, "packvar", mypackvar, pack=TRUE) var.put.nc(nc, "name", myname, c(1,1), c(nstring,nstation)) var.put.nc(nc, "name_fill", myname, na.mode=5) var.put.nc(nc, "qcflag", charToRaw(myqcflag)) var.put.nc(nc, "int0", myint0) var.put.nc(nc, "char0", mychar0) tally <- testfun(TRUE, TRUE, tally) if (format == "netcdf4") { cat("Writing extra netcdf4 variables ...") var.put.nc(nc, "namestr", mynamestr_fill) var.put.nc(nc, "namestr_fill", mynamestr_fill, na.mode=5) var.put.nc(nc, "profile", profiles) var.put.nc(nc, "profile_fill", profiles_fill, na.mode=5) var.put.nc(nc, "profile_pack", profiles, pack=TRUE) var.put.nc(nc, "profile_char", profiles_char) var.put.nc(nc, "profile_string", profiles_string) var.put.nc(nc, "profile_blob", profiles_blob) var.put.nc(nc, "profile_scalar", profiles[1]) var.put.nc(nc, "rawdata", rawdata) var.put.nc(nc, "rawdata_scalar", rawdata[,1,1]) var.put.nc(nc, "rawdata_vector", rawdata[,,1]) if (package_version(verstr) >= package_version("4.9.0")) { var.put.nc(nc, "profile_vector", profiles_vector) var.put.nc(nc, "profile_vector_fill", profiles_vector_fill, na.mode=5) } y <- try(var.put.nc(nc, "snacks", snacks_fill, na.mode=3), silent=TRUE) tally <- testfun(inherits(y, "try-error"), TRUE, tally) var.put.nc(nc, "snacks", snacks_fill, na.mode=5) tally <- testfun(TRUE, TRUE, tally) var.put.nc(nc, "person", person, na.mode=3) tally <- testfun(TRUE, TRUE, tally) var.put.nc(nc, "person_fill", person_fill, na.mode=5) tally <- testfun(TRUE, TRUE, tally) if (has_bit64) { var.put.nc(nc, "stationid", mybig64) tally <- testfun(TRUE, TRUE, tally) } var.put.nc(nc, "temp_filter", mytemperature) tally <- testfun(TRUE, TRUE, tally) } for (numtype in numtypes) { for (namode in seq(0,5)) { cat("Writing to variable type", numtype, "with na.mode", namode, "...\n") # Should not succeed except for NC_DOUBLE: cat("Writing huge values ...") y <- try(var.put.nc(nc, paste(numtype,namode,sep="_"), mybig, na.mode=namode), silent=TRUE) tally <- testfun(inherits(y, "try-error"), numtype!="NC_DOUBLE", tally) y <- try(var.put.nc(nc, paste(numtype,"fill",namode,sep="_"), mybigfill, na.mode=namode), silent=TRUE) tally <- testfun(inherits(y, "try-error"), numtype!="NC_DOUBLE", tally) # Should not succeed except for NC_FLOAT and 64-bit types: if (has_bit64) { cat("Writing huge bit64 values ...") y <- try(var.put.nc(nc, paste(numtype,"bit64",namode,sep="_"), mybig64, na.mode=namode), silent=TRUE) tally <- testfun(inherits(y, "try-error"), !(numtype %in% c("NC_FLOAT","NC_INT64","NC_UINT64","NC_DOUBLE")), tally) } # Should not succeed for unsigned types: cat("Writing negative values ...") y <- try(var.put.nc(nc, paste(numtype,namode,sep="_"), myminus, na.mode=namode), silent=TRUE) tally <- testfun(inherits(y, "try-error"), any(numtype==c("NC_UBYTE", "NC_USHORT", "NC_UINT", "NC_UINT64")), tally) # Allow wrapping of negative bit64 values when converting to NC_UINT64: if (has_bit64) { cat("Writing negative bit64 values ...") y <- try(var.put.nc(nc, paste(numtype,"bit64",namode,sep="_"), myminus64, na.mode=namode), silent=TRUE) tally <- testfun(inherits(y, "try-error"), numtype %in% c("NC_UBYTE","NC_USHORT","NC_UINT"), tally) } # Should succeed for all types: cat("Writing data without missing values ...") var.put.nc(nc, paste(numtype,namode,sep="_"), mysmall, na.mode=namode) var.put.nc(nc, paste(numtype,"int",namode,sep="_"), as.integer(mysmall), na.mode=namode) tally <- testfun(TRUE, TRUE, tally) if (has_bit64) { cat("Writing bit64 data without missing values ...") var.put.nc(nc, paste(numtype,"bit64",namode,sep="_"), mysmall64, na.mode=namode) tally <- testfun(TRUE, TRUE, tally) } # Should succeed except in the following cases: inffail <- !(numtype %in% c("NC_FLOAT","NC_DOUBLE")) nafail <- (namode==3 && !(numtype %in% c("NC_FLOAT","NC_DOUBLE"))) naintfail <- (namode==3 && !(numtype %in% c("NC_INT","NC_INT64","NC_FLOAT","NC_DOUBLE"))) nabit64fail <- (namode==3 && !(numtype %in% c("NC_INT64","NC_UINT64","NC_FLOAT","NC_DOUBLE"))) napack64fail <- (namode==3 && !(numtype %in% c("NC_INT64","NC_FLOAT","NC_DOUBLE"))) cat("Writing Inf values ...") y <- try(var.put.nc(nc, paste(numtype,"inf",namode,sep="_"), myinf, na.mode=namode), silent=TRUE) tally <- testfun(inherits(y, "try-error"), inffail, tally) cat("Writing doubles with non-finite packing ...") y <- try(var.put.nc(nc, paste(numtype,"packinf",namode,sep="_"), mypack, pack=TRUE, na.mode=namode), silent=TRUE) tally <- testfun(inherits(y, "try-error"), inffail, tally) cat("Writing integers with non-finite packing ...") y <- try(var.put.nc(nc, paste(numtype,"intpackinf",namode,sep="_"), as.integer(mypack), pack=TRUE, na.mode=namode), silent=TRUE) tally <- testfun(inherits(y, "try-error"), inffail, tally) cat("Writing data with missing values ...") y <- try(var.put.nc(nc, paste(numtype,"fill",namode,sep="_"), mysmallfill, na.mode=namode), silent=TRUE) tally <- testfun(inherits(y, "try-error"), nafail, tally) y <- try(var.put.nc(nc, paste(numtype,"intfill",namode,sep="_"), as.integer(mysmallfill), na.mode=namode), silent=TRUE) tally <- testfun(inherits(y, "try-error"), naintfail, tally) if (numtype == "NC_INT") { cat("Writing data with missing values and NA fill ...") y <- try(var.put.nc(nc, paste(numtype,"intfillna",namode,sep="_"), as.integer(mysmallfill), na.mode=namode), silent=TRUE) tally <- testfun(inherits(y, "try-error"), naintfail, tally) } else if (numtype == "NC_DOUBLE") { cat("Writing data with non-finite values and NA fill ...") y <- try(var.put.nc(nc, paste(numtype,"fillna",namode,sep="_"), myinffill, na.mode=namode), silent=TRUE) tally <- testfun(inherits(y, "try-error"), nafail, tally) } cat("Writing data with missing values and packing ...") y <- try(var.put.nc(nc, paste(numtype,"pack",namode,sep="_"), mypack, pack=TRUE, na.mode=namode), silent=TRUE) tally <- testfun(inherits(y, "try-error"), nafail, tally) y <- try(var.put.nc(nc, paste(numtype,"intpack",namode,sep="_"), as.integer(mypack), pack=TRUE, na.mode=namode), silent=TRUE) tally <- testfun(inherits(y, "try-error"), naintfail, tally) if (has_bit64) { cat("Writing bit64 data with missing values ...") y <- try(var.put.nc(nc, paste(numtype,"fill64",namode,sep="_"), mysmallfill64, na.mode=namode), silent=TRUE) tally <- testfun(inherits(y, "try-error"), nabit64fail, tally) cat("Writing bit64 data with missing values and packing ...") y <- try(var.put.nc(nc, paste(numtype,"pack64",namode,sep="_"), mypack64, pack=TRUE, na.mode=namode), silent=TRUE) tally <- testfun(inherits(y, "try-error"), napack64fail, tally) cat("Writing integer64 with non-finite packing ...") y <- try(var.put.nc(nc, paste(numtype,"packinf64",namode,sep="_"), mypack64, pack=TRUE, na.mode=namode), silent=TRUE) tally <- testfun(inherits(y, "try-error"), inffail, tally) } } } if (format == "netcdf4") { # Check chunk cache settings for temperature: cat("Check chunk cache settings after writing temperature ...") x <- var.inq.nc(nc, "temperature")$cache_preemption if (is.na(x)) { cat("Feature not available in this NetCDF library version.\n") } else { y <- 0.5 tally <- testfun(x,y,tally) } # Check multi-filter inquiry: cat("Check filter settings after writing temp_filter ...") x <- var.inq.nc(nc, "temp_filter") if (is.null(x$filter_id) && is.null(x$filter_params)) { cat("Multi-filters not available in this NetCDF library version.\n") } else { tally <- testfun(x[names(inq_filter)], inq_filter, tally) } } # sync.nc(nc) if (format == "netcdf4") { close.nc(ncroot) ncroot <- open.nc(ncfile) nc <- grp.inq.nc(ncroot, "testgrp")$self } else { close.nc(nc) nc <- open.nc(ncfile) } cat("Check file format ...") x <- file.inq.nc(nc)$format y <- format tally <- testfun(x,y,tally) ## Display file structure print.nc(nc) ## Read tests cat("Read NC_CHAR global attribute ...") x <- att_text y <- att.get.nc(nc, "NC_GLOBAL", "char_att") tally <- testfun(x,y,tally) cat("Read NC_CHAR variable attribute ...") x <- att_text y <- att.get.nc(nc, "name", "char_att") tally <- testfun(x,y,tally) cat("Read NC_CHAR variable attribute as raw bytes ...") x <- charToRaw(att_text) y <- att.get.nc(nc, "name", "raw_att", rawchar=TRUE) tally <- testfun(x,y,tally) if (format == "netcdf4") { cat("Read NC_STRING variable attribute ...") x <- att_text2 y <- att.get.nc(nc, "temperature", "string_att") tally <- testfun(x,y,tally) if (has_bit64) { cat("Read NC_INT64 variable attribute ...") x <- hugeint y <- att.get.nc(nc, "temperature", "int64_att", fitnum=TRUE) tally <- testfun(x,y,tally) cat("Read NC_INT64 variable attribute as numeric ...") x <- suppressWarnings(as.numeric(hugeint)) y <- att.get.nc(nc, "temperature", "int64_att") tally <- testfun(x,y,tally) } } grpinfo <- grp.inq.nc(nc) cat("Inquire about groups in file/group ...") tally <- testfun(grpinfo$grps,list(),tally) cat("Inquire about dimension ids in file/group ...") tally <- testfun(grpinfo$dimids,c(0:3),tally) cat("Inquire about variable ids in file/group ...") tally <- testfun(grpinfo$varids,c(0:(varcnt-1)),tally) cat("Inquire about fullname of file/group ...") if (format == "netcdf4") { tally <- testfun(grpinfo$fullname,"/testgrp",tally) } else { tally <- testfun(grpinfo$fullname,"/",tally) } cat("Inquire about unlimited dimension ids of file/group ...") if (format == "netcdf4") { # Some versions of netcdf4 do not list unlimited dimensions in ancestor groups: if (length(grpinfo$unlimids)==0) { tally <- testfun(grpinfo$unlimids,integer(0),tally) } else { tally <- testfun(grpinfo$unlimids,3,tally) } } else { tally <- testfun(grpinfo$unlimids,3,tally) } if (format == "netcdf4") { cat("Inquire about user-defined types in file/group ...") tally <- testfun(grpinfo$typeids,typeids,tally) } cat("Read integer vector as double ... ") x <- mytime dim(x) <- length(x) y <- var.get.nc(nc, 0) tally <- testfun(x,y,tally) tally <- testfun(is.double(y),TRUE,tally) for (numtype in numtypes) { for (namode in seq(0,5)) { x <- mysmall dim(x) <- length(x) varname <- paste(numtype,namode,sep="_") cat("Read", varname, "...") y <- var.get.nc(nc, varname, na.mode=namode) tally <- testfun(x,y,tally) tally <- testfun(is.double(y),TRUE,tally) varname <- paste(numtype,"int",namode,sep="_") cat("Read", varname, "...") y <- var.get.nc(nc, varname, na.mode=namode) tally <- testfun(x,y,tally) tally <- testfun(is.double(y),TRUE,tally) if (has_bit64) { varname <- paste(numtype,"bit64",namode,sep="_") cat("Read", varname, "...") y <- var.get.nc(nc, varname, na.mode=namode) tally <- testfun(x,y,tally) tally <- testfun(is.double(y),TRUE,tally) } # Some cases are expected to fail when writing the data, # so there is nothing to read: nafail <- (namode==3 && numtype != "NC_DOUBLE") naintfail <- (namode==3 && !(numtype %in% c("NC_INT","NC_INT64","NC_FLOAT","NC_DOUBLE"))) nabit64fail <- (namode==3 && !(numtype %in% c("NC_INT64","NC_FLOAT","NC_DOUBLE"))) x <- mysmallfill dim(x) <- length(x) if (!nafail) { varname <- paste(numtype,"fill",namode,sep="_") cat("Read", varname, "...") y <- var.get.nc(nc, varname, na.mode=namode) tally <- testfun(x,y,tally) tally <- testfun(is.double(y),TRUE,tally) } if (!naintfail) { varname <- paste(numtype,"intfill",namode,sep="_") cat("Read", varname, "...") y <- var.get.nc(nc, varname, na.mode=namode) if (namode==3) { tally <- testfun(x[!is.na(x)],y[!is.na(x)],tally) tally <- testfun(isTRUE(all.equal(x[is.na(x)],y[is.na(x)])),FALSE,tally) } else { tally <- testfun(x,y,tally) } tally <- testfun(is.double(y),TRUE,tally) } if (has_bit64 && !nabit64fail) { varname <- paste(numtype,"fill64",namode,sep="_") cat("Read", varname, "...") y <- var.get.nc(nc, varname, na.mode=namode) if (namode==3) { tally <- testfun(x[!is.na(x)],y[!is.na(x)],tally) tally <- testfun(isTRUE(all.equal(x[is.na(x)],y[is.na(x)])),FALSE,tally) } else { tally <- testfun(x,y,tally) } tally <- testfun(is.double(y),TRUE,tally) } if (numtype == "NC_INT" && !naintfail) { x <- mysmallfill dim(x) <- length(x) varname <- paste(numtype,"intfillna",namode,sep="_") cat("Read", varname, "...") y <- var.get.nc(nc, varname, na.mode=namode) if (namode==3) { tally <- testfun(x[!is.na(x)],y[!is.na(x)],tally) tally <- testfun(isTRUE(all.equal(x[is.na(x)],y[is.na(x)])),FALSE,tally) } else { tally <- testfun(x,y,tally) } tally <- testfun(is.double(y),TRUE,tally) } else if (numtype == "NC_DOUBLE" && !nafail) { x <- myinffill dim(x) <- length(x) varname <- paste(numtype,"fillna",namode,sep="_") cat("Read", varname, "...") y <- var.get.nc(nc, varname, na.mode=namode) tally <- testfun(x,y,tally) tally <- testfun(is.double(y),TRUE,tally) } x <- mypack dim(x) <- length(x) if (!nafail) { varname <- paste(numtype,"pack",namode,sep="_") cat("Read", varname, "...") y <- var.get.nc(nc, varname, unpack=TRUE, na.mode=namode) tally <- testfun(x,y,tally) tally <- testfun(is.double(y),TRUE,tally) } if (!naintfail) { varname <- paste(numtype,"intpack",namode,sep="_") cat("Read", varname, "...") y <- var.get.nc(nc, varname, unpack=TRUE, na.mode=namode) if (namode==3) { tally <- testfun(x[!is.na(x)],y[!is.na(x)],tally) tally <- testfun(isTRUE(all.equal(x[is.na(x)],y[is.na(x)])),FALSE,tally) } else { tally <- testfun(x,y,tally) } tally <- testfun(is.double(y),TRUE,tally) } if (has_bit64 && !nabit64fail) { varname <- paste(numtype,"pack64",namode,sep="_") cat("Read", varname, "...") y <- var.get.nc(nc, varname, unpack=TRUE, na.mode=namode) if (namode==3) { tally <- testfun(x[!is.na(x)],y[!is.na(x)],tally) tally <- testfun(isTRUE(all.equal(x[is.na(x)],y[is.na(x)])),FALSE,tally) } else { tally <- testfun(x,y,tally) } tally <- testfun(is.double(y),TRUE,tally) } } } cat("Read integer vector as smallest R type ... ") x <- mytime dim(x) <- length(x) y <- var.get.nc(nc, 0, fitnum=TRUE) tally <- testfun(x,y,tally) tally <- testfun(is.integer(y),TRUE,tally) for (numtype in numtypes) { x <- mysmall if (has_bit64 && any(numtype==c("NC_INT64","NC_UINT64"))) { x <- as.integer64(x) } dim(x) <- length(x) varname <- paste(numtype,namode,sep="_") cat("Read", varname, "...") y <- var.get.nc(nc, varname, fitnum=TRUE) tally <- testfun(x,y,tally) tally <- testfun(is.integer(y), any(numtype==c("NC_BYTE","NC_UBYTE","NC_SHORT","NC_USHORT","NC_INT")), tally) x <- mysmallfill if (has_bit64 && any(numtype==c("NC_INT64","NC_UINT64"))) { x <- as.integer64(x) } dim(x) <- length(x) varname <- paste(numtype,"fill",namode,sep="_") cat("Read", varname, "...") y <- var.get.nc(nc, varname, fitnum=TRUE) tally <- testfun(x,y,tally) tally <- testfun(is.integer(y), any(numtype==c("NC_BYTE","NC_UBYTE","NC_SHORT","NC_USHORT","NC_INT")), tally) } cat("Read numeric matrix ... ") x <- mytemperature y <- var.get.nc(nc, "temperature", cache_preemption=0.4) tally <- testfun(x,y,tally) cat("Inquire about numeric variable ...") x <- inq_temperature y <- var.inq.nc(nc, "temperature") var_inq_names <- c("id", "name", "type", "ndims", "dimids", "natts") if (format == "netcdf4") { var_inq_names_nc4 <- c(var_inq_names, "chunksizes", "deflate", "shuffle", "fletcher32") tally <- testfun(x[var_inq_names_nc4], y[var_inq_names_nc4], tally) big_endian <- y$big_endian # May be NULL or NA for older netcdf libraries, TRUE otherwise. if (!is.null(big_endian) && !isTRUE(is.na(big_endian))) { tally <- testfun(TRUE, big_endian, tally) } preempt <- y$cache_preemption # May be NULL for older netcdf libraries, numeric otherwise. if (!is.null(preempt)) { tally <- testfun(0.4, preempt, tally) } } else { tally <- testfun(x[var_inq_names], y[var_inq_names], tally) } cat("Read numeric matrix slice ... ") x <- mytemperature[,2,drop=FALSE] y <- var.get.nc(nc, "temperature", c(NA,2), c(NA,1), collapse=FALSE) tally <- testfun(x,y,tally) x <- mytemperature[,2] y <- var.get.nc(nc, "temperature", c(NA,2), c(NA,1), collapse=TRUE) tally <- testfun(x,y,tally) cat("Read numeric matrix empty slice ... ") x <- numeric(0) dim(x) <- c(0,1) y <- var.get.nc(nc, "temperature", c(NA,2), c(0,1), collapse=FALSE) tally <- testfun(x,y,tally) y <- var.get.nc(nc, "temperature", c(NA,2), c(0,1), collapse=TRUE) tally <- testfun(drop(x),y,tally) cat("Read numeric scalar ... ") x <- myint0 y <- var.get.nc(nc, "int0") tally <- testfun(x,y,tally) cat("Read numeric empty array ... ") x <- numeric(0) dim(x) <- c(nstation,nempty) y <- var.get.nc(nc, "numempty") tally <- testfun(x,y,tally) cat("Read 2D char array ... ") x <- myname dim(x) <- length(x) y <- var.get.nc(nc, "name") tally <- testfun(x,y,tally) cat("Read 2D char array with fill value ... ") x <- mynamefill dim(x) <- length(x) y <- var.get.nc(nc, "name_fill", na.mode=3) tally <- testfun(x,y,tally) x <- myname dim(x) <- length(x) y <- var.get.nc(nc, "name_fill", na.mode=5) tally <- testfun(x,y,tally) cat("Read 2D char slice ... ") x <- substring(myname[2:3],1,4) dim(x) <- length(x) y <- var.get.nc(nc, "name", c(1,2), c(4,2)) tally <- testfun(x,y,tally) cat("Read 2D char slice as raw bytes ... ") x <- substring(myname[2:3],1,4) dim(x) <- length(x) x <- apply(x,MARGIN=1,FUN=charToRaw) y <- var.get.nc(nc, "name", c(1,2), c(4,2), rawchar=TRUE) tally <- testfun(x,y,tally) cat("Read 2D char slice as characters ... ") x <- myname[2:3] dim(x) <- length(x) y <- var.get.nc(nc, "name", c(1,2), c(NA,2)) tally <- testfun(x,y,tally) cat("Read empty 2D char array ... ") x <- character(0) dim(x) <- 0 y <- var.get.nc(nc, "name", NA, c(0,0), collapse=FALSE) tally <- testfun(x,y,tally) y <- var.get.nc(nc, "name", NA, c(0,0), collapse=TRUE) tally <- testfun(drop(x),y,tally) cat("Read 1D char slice ... ") x <- substring(myqcflag,2,3) y <- var.get.nc(nc, "qcflag", c(2), c(2)) tally <- testfun(x,y,tally) cat("Read scalar char ... ") x <- mychar0 y <- var.get.nc(nc, "char0") tally <- testfun(x,y,tally) if (format == "netcdf4") { cat("Read 1D string array ...") x <- mynamestr dim(x) <- length(x) y <- var.get.nc(nc, "namestr") tally <- testfun(x,y,tally) cat("Read 1D string array with fill values ...") x <- mynamestr_fill dim(x) <- length(x) y <- var.get.nc(nc, "namestr_fill", na.mode=5) tally <- testfun(x,y,tally) cat("Read 1D string slice ...") x <- mynamestr[2:3] dim(x) <- length(x) y <- var.get.nc(nc, "namestr", c(2), c(2)) tally <- testfun(x,y,tally) if (has_bit64) { cat("Read 1D int64 array as integer64 ...") x <- mybig64 dim(x) <- length(x) y <- var.get.nc(nc, "stationid", fitnum=TRUE) tally <- testfun(x,y,tally) } cat("Read details of user-defined types ...") x <- inq_blob y <- type.inq.nc(nc, id_blob) tally <- testfun(x,y,tally) # Reported size may depend on netcdf version and pointer size: x <- inq_vector[-4] y <- type.inq.nc(nc, id_vector)[-4] tally <- testfun(x,y,tally) x <- inq_vector_char[-4] y <- type.inq.nc(nc, id_vector_char)[-4] tally <- testfun(x,y,tally) x <- inq_vector_blob[-4] y <- type.inq.nc(nc, id_vector_blob)[-4] tally <- testfun(x,y,tally) x <- inq_factor y <- type.inq.nc(nc, id_factor) tally <- testfun(x,y,tally) x <- inq_factor[1:5] y <- type.inq.nc(nc, id_factor, fields=FALSE) tally <- testfun(x,y,tally) # Size and offset of compound types may differ between writing and reading. # The layout for writing (reading) is defined by the user (compiler). x <- inq_struct[c(-4,-5)] y <- type.inq.nc(nc, id_struct)[c(-4,-5)] tally <- testfun(x,y,tally) x <- inq_struct[1:3] y <- type.inq.nc(nc, id_struct, fields=FALSE)[-4] tally <- testfun(x,y,tally) cat("Read vlen as double ...") x <- profiles y <- var.get.nc(nc, "profile") tally <- testfun(x,y,tally) tally <- testfun(isTRUE(all(sapply(y,is.double))), TRUE, tally) cat("Read vlen as integer ...") x <- profiles y <- var.get.nc(nc, "profile", fitnum=TRUE) tally <- testfun(x,y,tally) tally <- testfun(isTRUE(all(sapply(y,is.integer))), TRUE, tally) cat("Read vlen with fill ...") x <- profiles_fill y <- var.get.nc(nc, "profile_fill", na.mode=5) tally <- testfun(x,y,tally) cat("Read vlen scalar ...") x <- profiles[1] y <- var.get.nc(nc, "profile_scalar") tally <- testfun(x,y,tally) cat("Reading packed vlen ...") x <- profiles y <- var.get.nc(nc, "profile_pack", unpack=TRUE) tally <- testfun(x,y,tally) tally <- testfun(isTRUE(all(sapply(y,is.double))), TRUE, tally) cat("Read character vlen ...") x <- profiles_char y <- var.get.nc(nc, "profile_char") tally <- testfun(x,y,tally) cat("Read character vlen as raw ...") x <- lapply(profiles_char,charToRaw) dim(x) <- dim(profiles_char) y <- var.get.nc(nc, "profile_char", rawchar=TRUE) tally <- testfun(x,y,tally) cat("Read string vlen ...") x <- profiles_string y <- var.get.nc(nc, "profile_string") tally <- testfun(x,y,tally) if (package_version(verstr) >= package_version("4.9.0")) { cat("Read nested vlen ...") x <- profiles_vector y <- var.get.nc(nc, "profile_vector", na.mode=3) tally <- testfun(x,y,tally) cat("Read nested vlen with fill ...") x <- profiles_vector_fill y <- var.get.nc(nc, "profile_vector_fill", na.mode=5) tally <- testfun(x,y,tally) } cat("Read opaque ...") x <- rawdata y <- var.get.nc(nc, "rawdata") tally <- testfun(x,y,tally) cat("Read opaque scalar ...") x <- rawdata[,1,1] dim(x) <- length(x) y <- var.get.nc(nc, "rawdata_scalar") tally <- testfun(x,y,tally) cat("Read opaque vector ...") x <- rawdata[,,1] y <- var.get.nc(nc, "rawdata_vector") tally <- testfun(x,y,tally) cat("Read opaque vlen ...") x <- profiles_blob y <- var.get.nc(nc, "profile_blob") tally <- testfun(x,y,tally) cat("Read enum ...") x <- snacks y <- var.get.nc(nc, "snacks", na.mode=3) tally <- testfun(x,y,tally) x <- snacks_fill y <- var.get.nc(nc, "snacks", na.mode=5) tally <- testfun(x,y,tally) cat("Read empty enum ...") x <- snacks_empty y <- NULL assertWarning(y <- var.get.nc(nc, "snacks_empty")) tally <- testfun(x,y,tally) cat("Read compound ...") x <- person y <- var.get.nc(nc, "person", na.mode=3) tally <- testfun(x,y,tally) cat("Read compound with fill ...") x <- person_fill y <- var.get.nc(nc, "person_fill", na.mode=5) tally <- testfun(x,y,tally) cat("Read compound scalar attribute ...") x <- person1 y <- att.get.nc(nc, "NC_GLOBAL", "compound_scal_att") tally <- testfun(x,y,tally) cat("Read compound vector attribute ...") x <- person3 y <- att.get.nc(nc, "NC_GLOBAL", "compound_vect_att") tally <- testfun(x,y,tally) cat("Read enum scalar attribute ...") x <- snacks[1] y <- att.get.nc(nc, "NC_GLOBAL", "enum_scal_att") tally <- testfun(x,y,tally) cat("Read enum vector attribute ...") x <- snacks[1:3] y <- att.get.nc(nc, "NC_GLOBAL", "enum_vect_att") tally <- testfun(x,y,tally) cat("Read opaque scalar attribute ...") x <- rawdata[,1,1] dim(x) <- c(length(x),1) y <- att.get.nc(nc, "NC_GLOBAL", "opaque_scal_att") tally <- testfun(x,y,tally) cat("Read opaque vector attribute ...") x <- rawdata[,1,] y <- att.get.nc(nc, "NC_GLOBAL", "opaque_vect_att") tally <- testfun(x,y,tally) cat("Read vlen scalar attribute ...") x <- profiles[1] y <- att.get.nc(nc, "NC_GLOBAL", "vector_scal_att") tally <- testfun(x,y,tally) cat("Read vlen vector attribute ...") x <- profiles[1:3] y <- att.get.nc(nc, "NC_GLOBAL", "vector_vect_att") tally <- testfun(x,y,tally) } cat("Read and unpack numeric array ... ") x <- mypackvar dim(x) <- length(x) y <- var.get.nc(nc, "packvar", unpack=TRUE) tally <- testfun(x,y,tally) cat("Check that closing any NetCDF handle closes the file for all handles ... ") close.nc(nc) y <- try(file.inq.nc(grpinfo$self), silent=TRUE) tally <- testfun(inherits(y, "try-error"), TRUE, tally) cat("Check that garbage collector closes file that is not referenced ... ") attr(nc,"handle_ptr") <- NULL # NetCDF objects should not normally be modified rm(grpinfo) gc() y <- try(file.inq.nc(nc), silent=TRUE) tally <- testfun(inherits(y, "try-error"), TRUE, tally) unlink(ncfile) cat("Removed test file", ncfile, "\n") } # Try diskless files: ncfile <- tempfile("RNetCDF-test-diskless", fileext=".nc") cat("Test diskless creation of ", ncfile, "...\n") if (cfg$diskless) { nc <- create.nc(ncfile, diskless=TRUE) tally <- testfun(file.exists(ncfile), FALSE, tally) close.nc(nc) } else { message("NetCDF library does not support diskless datasets") nc <- try(create.nc(ncfile, diskless=TRUE), silent=TRUE) tally <- testfun(inherits(nc, "try-error"), TRUE, tally) } unlink(ncfile) #-------------------------------------------------------------------------------# # UDUNITS calendar functions #-------------------------------------------------------------------------------# # Test if udunits support is available: if (!cfg$udunits) { message("UDUNITS calendar conversions not supported by this build of RNetCDF") x <- try(utcal.nc("seconds since 1970-01-01", 0), silent=TRUE) tally <- testfun(inherits(x, "try-error"), TRUE, tally) } else { cat("utcal.nc - numeric values ...") x <- matrix(data=c(1899, 1900, 1900, 1900, 1900, 1900, 12, 1, 1, 1, 1, 1, 31, 1, 1, 1, 1, 1, 23, 0, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), ncol=6) colnames(x) <- c("year","month","day","hour","minute","second") y <- utcal.nc("hours since 1900-01-01 00:00:00 +01:00", c(0:5)) tally <- testfun(x,y,tally) cat("utcal.nc - string values ...") x <- c("1899-12-31 23:00:00", "1900-01-01 00:00:00", "1900-01-01 01:00:00", "1900-01-01 02:00:00", "1900-01-01 03:00:00", "1900-01-01 04:00:00") y <- utcal.nc("hours since 1900-01-01 00:00:00 +01:00", c(0:5), type="s") tally <- testfun(x,y,tally) cat("utcal.nc - POSIXct values ...") x <- ISOdatetime(c(1899,1900,1900,1900,1900,1900), c( 12, 1, 1, 1, 1, 1), c( 31, 1, 1, 1, 1, 1), c( 23, 0, 1, 2, 3, 4), c( 0, 0, 0, 0, 0, 0), c( 0, 0, 0, 0, 0, 0), tz="UTC") y <- utcal.nc("hours since 1900-01-01 00:00:00 +01:00", c(0:5), type="c") tally <- testfun(x,y,tally) cat("utcal.nc - error for unknown units ...") x <- try(utcal.nc("unknown", 1), silent=TRUE) tally <- testfun(inherits(x, "try-error"), TRUE, tally) cat("utinvcal.nc - numeric values ...") x <- 6.416667 y <- utinvcal.nc("hours since 1900-01-01 00:00:00 +01:00", c(1900,1,1,5,25,0)) tally <- testfun(x,y,tally) cat("utinvcal.nc - string values ...") x <- 6.416667 y <- utinvcal.nc("hours since 1900-01-01 00:00:00 +01:00", "1900-01-01 05:25:00") tally <- testfun(x,y,tally) cat("utinvcal.nc - POSIXct values ...") x <- 6.416667 y <- utinvcal.nc("hours since 1900-01-01 00:00:00 +01:00", ISOdatetime(1900,1,1,5,25,0,tz="UTC")) tally <- testfun(x,y,tally) cat("utinvcal.nc - error for bad values ...") x <- try(utinvcal.nc("hours since 1900-01-01 00:00:00 +01:00", "1900-01-01 24:61:61"), silent=TRUE) tally <- testfun(inherits(x, "try-error"), TRUE, tally) } #-------------------------------------------------------------------------------# # Parallel I/O demos #-------------------------------------------------------------------------------# mpiexec <- cfg$mpiexec parallel <- cfg$parallel if (mpiexec != "") { # mpiexec is specified, so assume that parallel I/O is meant to be enabled. # List of MPI packages to test: mpipkgs <- c("Rmpi", "pbdMPI") # Try to find demo script directory: demodirs <- c("demo", file.path("..", "demo"), file.path("..", "RNetCDF", "demo")) demodir <- demodirs[dir.exists(demodirs)] stopifnot(length(demodir) > 0) # Check if any of the packages are loaded: for (mpipkg in mpipkgs) { if (isNamespaceLoaded(mpipkg)) { warning("Package ", mpipkg, " is loaded, so mpiexec may fail") } } for (mpipkg in c("Rmpi", "pbdMPI")) { # We cannot use requireNamespace to check for installed MPI packages, # because they may initialise the MPI library via .onLoad, # which causes failure when we try to mpiexec another R script. if (length(find.package(mpipkg, quiet=TRUE) > 0)) { cat("Testing parallel I/O with package", mpipkg, "...\n") demoscripts <- list.files( demodir, pattern=paste0(mpipkg, ".*\\.R"), full.names=TRUE) stopifnot(length(demoscripts) >= 1) for (demoscript in demoscripts) { ncfile <- tempfile("RNetCDF-MPI-test", fileext=".nc") cat("Running script", demoscript, "with MPI ...\n") x <- system2(mpiexec, args=c('-n', '2', 'Rscript', '--vanilla', demoscript, ncfile)) unlink(ncfile) tally <- testfun(x, 0, tally) } } else { message("Package ", mpipkg, " not available for parallel I/O tests\n") } } } else if (parallel) { # Parallel I/O may be enabled, but we cannot test without mpiexec being specified. cat("Skipping parallel I/O tests as mpiexec is not defined\n") } else { # Assume that parallel I/O is meant to be disabled, # because parallel is FALSE and mpiexec is not specified. ncfile <- tempfile("RNetCDF-MPI-test", fileext=".nc") cat("Testing that create.nc fails with mpi_comm ... ") x <- try(create.nc(ncfile, format="netcdf4", mpi_comm=1), silent=TRUE) unlink(ncfile) if (inherits(x, "try-error") && conditionMessage(attr(x, "condition")) == "MPI not supported") { tally <- testfun(TRUE, TRUE, tally) } else { tally <- testfun(FALSE, TRUE, tally) } cat("Testing that open.nc fails with mpi_comm ... ") x <- try(open.nc(ncfile, mpi_comm=1), silent=TRUE) if (inherits(x, "try-error") && conditionMessage(attr(x, "condition")) == "MPI not supported") { tally <- testfun(TRUE, TRUE, tally) } else { tally <- testfun(FALSE, TRUE, tally) } cat("Testing that var.par.nc fails ... ") ncid <- create.nc(ncfile, format="netcdf4") x <- try(var.par.nc(ncid, "dummy", "NC_COLLECTIVE"), silent=TRUE) close.nc(ncid) unlink(ncfile) if (inherits(x, "try-error") && conditionMessage(attr(x, "condition")) == "MPI not supported") { tally <- testfun(TRUE, TRUE, tally) } else { tally <- testfun(FALSE, TRUE, tally) } } #-------------------------------------------------------------------------------# # Check that package can be unloaded: #-------------------------------------------------------------------------------# cat("Unload RNetCDF ...\n") detach("package:RNetCDF",unload=TRUE) #-------------------------------------------------------------------------------# # Overall summary #-------------------------------------------------------------------------------# cat("Summary:", tally["pass"], "pass /", tally["fail"], "fail.\n") if (tally["fail"]==0) { cat("Package seems to work properly.\n") } else { stop(tally["fail"]," of ",sum(tally)," test cases failed.") } #===============================================================================# #===============================================================================# # SCRATCH #===============================================================================# RNetCDF/configure.ac0000644000176200001440000003212214577720574013747 0ustar liggesusers#-------------------------------------------------------------------------------# # Initialize # #-------------------------------------------------------------------------------# AC_INIT([RNetCDF],[2.9-2]) : ${R_HOME=`R RHOME`} AS_IF([test -z "${R_HOME}"], AC_MSG_ERROR([could not determine R_HOME]) ) #-------------------------------------------------------------------------------# # Get compiler/linker variables from environment # #-------------------------------------------------------------------------------# AC_MSG_NOTICE([Find compiler/linker variables from environment:]) AC_MSG_CHECKING([CFLAGS]) PKG_CFLAGS="$CFLAGS" AC_MSG_RESULT([${PKG_CFLAGS}]) AC_MSG_CHECKING([CPPFLAGS]) PKG_CPPFLAGS="$CPPFLAGS" AC_MSG_RESULT([${PKG_CPPFLAGS}]) AC_MSG_CHECKING([LDFLAGS]) PKG_LDFLAGS="$LDFLAGS" AC_MSG_RESULT([${PKG_LDFLAGS}]) AC_MSG_CHECKING([LIBS]) AC_MSG_RESULT([$LIBS]) #-------------------------------------------------------------------------------# # Select compiler from R unless --with-mpicc has non-empty value # #-------------------------------------------------------------------------------# AC_MSG_NOTICE([Select C compiler:]) AC_MSG_CHECKING([C compiler from --with-mpicc]) AC_ARG_WITH([mpicc], AS_HELP_STRING([--with-mpicc], [command for C compiler from MPI, otherwise C compiler from R is used]), [CC="$withval"], [CC=""]) AC_MSG_RESULT([$CC]) AS_IF([test -z "$CC"], [AC_MSG_CHECKING([C compiler from R]) R_CC=`"${R_HOME}/bin/R" CMD config CC` CC="${R_CC}" AC_MSG_RESULT([$CC])]) #-------------------------------------------------------------------------------# # Get compiler/linker variables from R # #-------------------------------------------------------------------------------# AC_MSG_NOTICE([Find compiler/linker variables from R:]) AC_MSG_CHECKING([R_CFLAGS]) R_CFLAGS=`"${R_HOME}/bin/R" CMD config CFLAGS` AC_MSG_RESULT([${R_CFLAGS}]) AC_MSG_CHECKING([R_CPPFLAGS]) R_CPPFLAGS=`"${R_HOME}/bin/R" CMD config CPPFLAGS` AC_MSG_RESULT([${R_CPPFLAGS}]) AC_MSG_CHECKING([R_LDFLAGS]) R_LDFLAGS=`"${R_HOME}/bin/R" CMD config LDFLAGS` AC_MSG_RESULT([${R_LDFLAGS}]) # No LIBS from R #-------------------------------------------------------------------------------# # Identify OS # #-------------------------------------------------------------------------------# # Initial compiler test with CC found earlier and compiler flags from R. # Original variable contents were copied to PKG_ variables earlier. CFLAGS="${R_CFLAGS}" CPPFLAGS="${R_CPPFLAGS}" LDFLAGS="${R_LDFLAGS}" AC_CHECK_DECLS([_WIN32], [platform=Windows], [AC_CHECK_DECLS([__APPLE__], [platform=macOS], [platform=Unix-alike])]) AC_MSG_NOTICE([Operating system is $platform]) #-------------------------------------------------------------------------------# # Prepend compiler/linker variables from nc-config (if specified) # #-------------------------------------------------------------------------------# # Enable nc-config by default, # except on Windows which currently needs special handling (see later): AC_ARG_WITH([nc-config], AS_HELP_STRING([--with-nc-config], [get compiler options from nc-config (default except on Windows)]), [], [with_nc_config=unset]) AS_IF([test "x${with_nc_config}" = xunset], [AS_IF([test "x$platform" = xWindows], [with_nc_config=no], [with_nc_config=yes])]) AS_IF([test "x${with_nc_config}" = xyes], [AC_CHECK_PROG(have_nc_config, nc-config, yes, no, [], [])], [have_nc_config=no]) AC_ARG_WITH([nc-config-static], AS_HELP_STRING([--with-nc-config-static], [use static libraries from nc-config (default on Windows & macOS)]), [], [with_nc_config_static=unset]) AS_IF([test "x${with_nc_config_static}" = xunset], [AS_IF([test "x$platform" = xWindows || test "x$platform" = xmacOS], [with_nc_config_static=yes], [with_nc_config_static=no]) ] ) AS_IF([test "x${have_nc_config}" = xyes], [ AC_MSG_NOTICE([Check compiler/linker variables from nc-config:]) AC_MSG_CHECKING([NC_CC]) NC_CC=`nc-config --cc` AC_MSG_RESULT([${NC_CC}]) AC_MSG_CHECKING([NC_CC matches selected C compiler]) AS_IF([test "$CC" != "${NC_CC}"], [AC_MSG_RESULT([no ... specify --with-mpicc if needed])], [AC_MSG_RESULT([yes])]) AC_MSG_CHECKING([nc-config --cflags]) NC_CFLAGS=`nc-config --cflags` AC_MSG_RESULT([${NC_CFLAGS}]) nc_config_static_flag="" AS_IF([test "x${with_nc_config_static}" = xyes], [AC_MSG_CHECKING([nc-config allows --static option]) AS_IF([nc-config --libs --static >/dev/null 2>&1], [nc_config_static_flag="--static" AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])]) ]) AC_MSG_CHECKING([nc-config --libs ${nc_config_static_flag}]) NC_LIBS=`nc-config --libs ${nc_config_static_flag}` AC_MSG_RESULT([${NC_LIBS}]) # Prepend to PKG variables: PKG_CFLAGS="${NC_CFLAGS} ${PKG_CFLAGS}" LIBS="${NC_LIBS} $LIBS" ], [ AC_MSG_NOTICE([Skipping nc-config]) ] ) #-------------------------------------------------------------------------------# # Append R compiler/linker variables to PKG variables for feature tests # #-------------------------------------------------------------------------------# # CC is unchanged CFLAGS="${PKG_CFLAGS} ${R_CFLAGS}" CPPFLAGS="${PKG_CPPFLAGS} ${R_CPPFLAGS}" LDFLAGS="${PKG_LDFLAGS} ${R_LDFLAGS}" # No LIBS from R #-------------------------------------------------------------------------------# # Set libraries to link on Windows # #-------------------------------------------------------------------------------# # As of Rtools43, nc-config does not link all required libraries, # and it also tries to link libraries that are not installed. # If nc-config is fixed, this section could be removed, # and nc-config could be re-enabled above. AS_IF([test "x$platform" = xWindows], [ AC_MSG_NOTICE([Find libraries that may be needed on Windows:]) LIBS="-ladvapi32 -lgdi32 -lcrypt32 -lwldap32 -lwsock32 -lws2_32 $LIBS" AC_SEARCH_LIBS(atan, m) AC_SEARCH_LIBS(pthread_mutex_init, pthread) AC_SEARCH_LIBS(lzma_lzma_decoder_init, lzma) AC_SEARCH_LIBS(deflate, z) AC_SEARCH_LIBS(ZSTD_decompress, zstd) AC_SEARCH_LIBS(SZ_BufftoBuffDecompress, sz) AC_SEARCH_LIBS(BCryptDecrypt, bcrypt) AC_SEARCH_LIBS(gpg_strerror, gpg-error) AC_SEARCH_LIBS(gcry_md_open, gcrypt) AC_SEARCH_LIBS(EVP_CIPHER_CTX_new, crypto) AC_SEARCH_LIBS(SSL_CTX_new, ssl) AC_SEARCH_LIBS(libssh2_init, ssh2) AC_SEARCH_LIBS(libiconv_open, iconv) AC_SEARCH_LIBS(locale_charset, charset) AC_SEARCH_LIBS(u8_to_u16, unistring) AC_SEARCH_LIBS(idn2_to_ascii_8z, idn2) AC_SEARCH_LIBS(H5Fopen, hdf5) AC_SEARCH_LIBS(H5TBmake_table, hdf5_hl) AC_SEARCH_LIBS(xdr_int, portablexdr) AC_SEARCH_LIBS(xmlReadMemory, xml2) AC_SEARCH_LIBS(nghttp2_submit_request, nghttp2) AC_SEARCH_LIBS(curl_easy_init, curl) AC_SEARCH_LIBS(jpeg_start_compress, jpeg) AC_SEARCH_LIBS(Hopen, df) AC_SEARCH_LIBS(SDstart, mfhdf) ]) #-------------------------------------------------------------------------------# # Check type sizes and language features supported by compiler # #-------------------------------------------------------------------------------# AC_MSG_NOTICE([Check compiler type sizes and language features]) AC_CHECK_SIZEOF([int]) AC_CHECK_SIZEOF([long long]) AC_CHECK_SIZEOF([size_t]) AC_C_RESTRICT() #-------------------------------------------------------------------------------# # Check NetCDF features # #-------------------------------------------------------------------------------# AC_MSG_NOTICE([Check NetCDF features:]) # Check that netcdf header files can be compiled: AC_CHECK_HEADERS(netcdf.h, [], AC_MSG_ERROR([netcdf.h was not compiled - defining CPPFLAGS may help])) # Check that netcdf library can be found. # Linker flags are prepended to LIBS if needed. AC_SEARCH_LIBS(nc_open, netcdf, [], AC_MSG_ERROR([netcdf library was not linked - defining LDFLAGS may help])) # Check for the existence of optional netcdf routines. # C preprocessor macros HAVE_routine are defined for existing routines. AC_CHECK_FUNCS([nc_rename_grp nc_get_var_chunk_cache nc_inq_var_szip \ nc_inq_var_endian nc_def_var_filter nc_inq_var_filter_ids nc_inq_var_filter_info \ nc_reclaim_data]) # Check for filter header file. AC_CHECK_HEADERS(netcdf_filter.h, [], [], [#include ]) # Check for optional features that depend only on preprocessor declarations: AC_CHECK_DECLS([NC_64BIT_DATA, NC_FORMAT_64BIT_DATA, NC_DISKLESS, NC_PERSIST], [], [], [#include ]) #-------------------------------------------------------------------------------# # Check for parallel netcdf features # #-------------------------------------------------------------------------------# AC_MSG_NOTICE([Check for parallel NetCDF features:]) AC_ARG_WITH([mpiexec], [AS_HELP_STRING( [--with-mpiexec], [command to run small parallel MPI tests after installation (none by default)] )], [mpiexec="$withval"], [mpiexec=""]) # MPI support: has_mpi=TRUE AC_CHECK_HEADERS([mpi.h], [], [has_mpi=FALSE]) AC_CHECK_FUNCS([MPI_Init], [], [has_mpi=FALSE]) AS_IF([test "$has_mpi" != TRUE], [AC_MSG_WARN([MPI not available. Specify --with-mpicc if needed.])]) # Parallel I/O support in NetCDF: AS_IF([test "$has_mpi" = TRUE], [ has_parallel=TRUE AC_CHECK_HEADERS([netcdf_par.h], [], [has_parallel=FALSE], [#include ]) AC_CHECK_DECLS([NC_COLLECTIVE, NC_INDEPENDENT], [], [has_parallel=FALSE], [#include #include ]) AC_CHECK_DECLS([MPI_INFO_NULL, MPI_Info_c2f], [], [has_parallel=FALSE], [#include ]) AC_CHECK_FUNCS( [nc_create_par_fortran nc_open_par_fortran nc_var_par_access], [], [has_parallel=FALSE]) AS_IF([test "$has_parallel" = TRUE], [AC_DEFINE(HAVE_NETCDF_MPI)], [AC_MSG_WARN([Parallel I/O not supported by NetCDF installation])]) ], [ has_parallel=FALSE AC_MSG_WARN([NetCDF parallel I/O requires MPI]) ]) #-------------------------------------------------------------------------------# # Find UDUNITS2 library and header files # #-------------------------------------------------------------------------------# AC_MSG_NOTICE([Check for udunits2 features:]) # The udunits2 library depends on expat, which may need to be linked explicitly: AC_SEARCH_LIBS(XML_ErrorString, expat) # Check that selected routines from udunits2 can be used in programs, # including udunits2 in LIBS if needed. # Also search for udunits2.h on its own or in a subdirectory, # and define macro HAVE_UDUNITS2_H or HAVE_UDUNITS2_UDUNITS2_H accordingly. has_udunits=FALSE AC_SEARCH_LIBS(ut_read_xml, udunits2, AC_CHECK_FUNC(ut_offset_by_time, AC_CHECK_FUNC(ut_decode_time, AC_CHECK_FUNC(ut_encode_time, AC_CHECK_HEADERS(udunits2.h udunits2/udunits2.h, [has_udunits=TRUE; break] ) ) ) ) ) # Define HAVE_LIBUDUNITS2 if all udunits2 checks were successful: AS_IF([test "$has_udunits" = "TRUE"], AC_DEFINE(HAVE_LIBUDUNITS2), AC_MSG_WARN([disabling calendar functions in RNetCDF]) ) #-------------------------------------------------------------------------------# # Indicate optional features to R test script # #-------------------------------------------------------------------------------# AS_IF([test "$ac_cv_have_decl_NC_64BIT_DATA" = "yes" -a \ "$ac_cv_have_decl_NC_FORMAT_64BIT_DATA" = "yes"], [has_data64=TRUE], [has_data64=FALSE]) AC_SUBST(has_data64) AS_IF([test "$ac_cv_have_decl_NC_DISKLESS" = "yes" -a \ "$ac_cv_have_decl_NC_PERSIST" = "yes"], [has_diskless=TRUE], [has_diskless=FALSE]) AC_SUBST(has_diskless) AC_SUBST(has_udunits) AC_SUBST(has_parallel) AC_SUBST(mpiexec) #-------------------------------------------------------------------------------# # Final configuration variables # #-------------------------------------------------------------------------------# AC_MSG_NOTICE([Final compiler and linker variables for make: CC=$CC PKG_CFLAGS=${PKG_CFLAGS} PKG_CPPFLAGS=${PKG_CPPFLAGS} PKG_LDFLAGS=${PKG_LDFLAGS} LIBS=${LIBS}]) AC_SUBST(PKG_CFLAGS) AC_SUBST(PKG_CPPFLAGS) AC_SUBST(PKG_LDFLAGS) # CC and LIBS are substituted automatically. #-------------------------------------------------------------------------------# # Do substitution # #-------------------------------------------------------------------------------# AC_CONFIG_FILES([src/Makefile.common R/config.R]) AC_OUTPUT #-------------------------------------------------------------------------------# # Done # #-------------------------------------------------------------------------------# RNetCDF/src/0000755000176200001440000000000014577720574012250 5ustar liggesusersRNetCDF/src/RNetCDF.h0000644000176200001440000000773414577720574013621 0ustar liggesusers/*=============================================================================*\ * * Name: RNetCDF.h * * Version: 2.9-2 * * Purpose: Declare RNetCDF functions callable from R * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright (C) 2004-2024 Pavel Michna and Milton Woods. * *=============================================================================* * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *=============================================================================* */ #ifndef RNC_RNETCDF_H_INCLUDED #define RNC_RNETCDF_H_INCLUDED /* Attributes */ SEXP R_nc_copy_att (SEXP nc_in, SEXP var_in, SEXP att, SEXP nc_out, SEXP var_out); SEXP R_nc_delete_att (SEXP nc, SEXP var, SEXP att); SEXP R_nc_get_att (SEXP nc, SEXP var, SEXP att, SEXP rawchar, SEXP fitnum); SEXP R_nc_inq_att (SEXP nc, SEXP var, SEXP att); SEXP R_nc_put_att (SEXP nc, SEXP var, SEXP att, SEXP type, SEXP data); SEXP R_nc_rename_att (SEXP nc, SEXP var, SEXP att, SEXP newname); /* Datasets */ SEXP R_nc_close (SEXP ptr); SEXP R_nc_create (SEXP filename, SEXP clobber, SEXP share, SEXP prefill, SEXP format, SEXP diskless, SEXP persist, SEXP mpi_comm, SEXP mpi_info); SEXP R_nc_inq_file (SEXP nc); SEXP R_nc_open (SEXP filename, SEXP write, SEXP share, SEXP prefill, SEXP diskless, SEXP persist, SEXP mpi_comm, SEXP mpi_info); SEXP R_nc_sync (SEXP nc); /* Dimensions */ SEXP R_nc_def_dim (SEXP nc, SEXP dimname, SEXP size, SEXP unlim); SEXP R_nc_inq_dim (SEXP nc, SEXP dim); SEXP R_nc_inq_unlimids (SEXP nc); SEXP R_nc_rename_dim (SEXP nc, SEXP dim, SEXP newname); /* Groups */ SEXP R_nc_def_grp (SEXP nc, SEXP grpname); SEXP R_nc_inq_grp_parent (SEXP nc); SEXP R_nc_inq_natts (SEXP nc); SEXP R_nc_inq_grpname (SEXP nc, SEXP full); SEXP R_nc_inq_grp_ncid (SEXP nc, SEXP grpname, SEXP full); SEXP R_nc_inq_grps (SEXP nc); SEXP R_nc_inq_typeids (SEXP nc); SEXP R_nc_inq_varids (SEXP nc); SEXP R_nc_inq_dimids (SEXP nc, SEXP ancestors); SEXP R_nc_rename_grp (SEXP nc, SEXP grpname); /* Types */ SEXP R_nc_def_type (SEXP nc, SEXP typename, SEXP class, SEXP size, SEXP basetype, SEXP names, SEXP values, SEXP subtypes, SEXP dimsizes); SEXP R_nc_inq_type (SEXP nc, SEXP type, SEXP fields); /* Units */ SEXP R_nc_calendar (SEXP unitstring, SEXP values); SEXP R_nc_utinit (SEXP path); SEXP R_nc_inv_calendar (SEXP unitstring, SEXP values); SEXP R_nc_utterm (void); /* Variables */ SEXP R_nc_def_var (SEXP nc, SEXP varname, SEXP type, SEXP dims, SEXP chunking, SEXP chunksizes, SEXP deflate, SEXP shuffle, SEXP big_endian, SEXP fletcher32, SEXP filter_id, SEXP filter_params); SEXP R_nc_get_var (SEXP nc, SEXP var, SEXP start, SEXP count, SEXP rawchar, SEXP fitnum, SEXP namode, SEXP unpack, SEXP cache_bytes, SEXP cache_slots, SEXP cache_preemption); SEXP R_nc_inq_var (SEXP nc, SEXP var); SEXP R_nc_par_var (SEXP nc, SEXP var, SEXP access); SEXP R_nc_put_var (SEXP nc, SEXP var, SEXP start, SEXP count, SEXP data, SEXP namode, SEXP pack, SEXP cache_bytes, SEXP cache_slots, SEXP cache_preemption); SEXP R_nc_rename_var (SEXP nc, SEXP var, SEXP newname); #endif /* RNC_RNETCDF_H_INCLUDED */ RNetCDF/src/udunits.c0000644000176200001440000002374514577720574014122 0ustar liggesusers/*=============================================================================*\ * * Name: udunits.c * * Version: 2.9-2 * * Purpose: udunits2 functions for RNetCDF. * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright (C) 2004-2024 Pavel Michna and Milton Woods. * *=============================================================================* * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *=============================================================================* */ /*=============================================================================*\ * Includes \*=============================================================================*/ #include #include #include #include #include #include #include #include #include #include "common.h" #include "RNetCDF.h" #if !(defined HAVE_LIBUDUNITS2 && \ (defined HAVE_UDUNITS2_H || defined HAVE_UDUNITS2_UDUNITS2_H)) /*=============================================================================*\ * UDUNITS2 is NOT installed \*=============================================================================*/ SEXP R_nc_calendar (SEXP unitstring, SEXP values) { error ("RNetCDF was built without UDUNITS-2"); } SEXP R_nc_utinit (SEXP path) { return R_NilValue; } SEXP R_nc_inv_calendar (SEXP unitstring, SEXP values) { error ("RNetCDF was built without UDUNITS-2"); } SEXP R_nc_utterm () { return R_NilValue; } #else /*=============================================================================*\ * UDUNITS2 is installed \*=============================================================================*/ #ifdef HAVE_UDUNITS2_UDUNITS2_H # include #else # include #endif /* Static variables */ static ut_system *R_nc_units=NULL; /* Convert udunits2 error code to a string. The udunits2 library allows us to define a global error handler, but that could conflict with other R packages (e.g. units, udunits2). */ static const char * R_nc_uterror (ut_status errcode) { switch (errcode) { case UT_BAD_ARG: return "Bad argument (udunits)"; case UT_EXISTS: return "Unit, prefix, or identifier already exists (udunits)"; case UT_NO_UNIT: return "No such unit exists (udunits)"; case UT_OS: return "Operating-system error (udunits)"; case UT_NOT_SAME_SYSTEM: return "Units belong to different unit-systems (udunits)"; case UT_MEANINGLESS: return "Operation on the unit or units is meaningless (udunits)"; case UT_NO_SECOND: return "Unit-system doesn't have a unit named 'second' (udunits)"; case UT_VISIT_ERROR: return "Error occurred while visiting a unit (udunits)"; case UT_CANT_FORMAT: return "Unit can't be formatted in the desired manner (udunits)"; case UT_SYNTAX: return "String unit representation contains syntax error (udunits)"; case UT_UNKNOWN: return "String unit representation contains unknown word (udunits)"; case UT_OPEN_ARG: return "Can't open argument-specified unit database (udunits)"; case UT_OPEN_ENV: return "Can't open environment-specified unit database (udunits)"; case UT_OPEN_DEFAULT: return "Can't open installed, default, unit database (udunits)"; case UT_PARSE: return "Error parsing unit database (udunits)"; default: return "Unknown error (udunits)"; } } /*-----------------------------------------------------------------------------*\ * R_nc_calendar() \*-----------------------------------------------------------------------------*/ SEXP R_nc_calendar (SEXP unitstring, SEXP values) { int year, month, day, hour, minute, isreal; double second, res, din, dencode, *dout; const int *ivals=NULL; const double *dvals=NULL; const char *cstring; size_t ii, count; ut_unit *inunit=NULL, *refunit=NULL, *secunit=NULL; cv_converter *converter=NULL; ut_status status; SEXP result; /* Handle arguments and initialise outputs */ cstring = R_nc_strarg (unitstring); isreal = isReal (values); if (isreal) { dvals = REAL (values); } else { ivals = INTEGER (values); } count = xlength (values); result = PROTECT(allocMatrix (REALSXP, count, 6)); dout = REAL (result); /* Parse unitstring */ inunit = ut_parse (R_nc_units, cstring, UT_ASCII); if (!inunit) { goto cleanup; } /* Prepare for conversion to encoded time values used internally by udunits2 */ secunit = ut_get_unit_by_name (R_nc_units, "second"); if (!secunit) { goto cleanup; } refunit = ut_offset_by_time (secunit, 0.0); if (!refunit) { goto cleanup; } converter = ut_get_converter (inunit, refunit); if (!converter) { goto cleanup; } /*-- Convert values ---------------------------------------------------------*/ for (ii = 0; ii < count; ii++) { if (isreal) { din = dvals[ii]; } else { din = (ivals[ii] == NA_INTEGER) ? NA_REAL : ((double) ivals[ii]); } if (R_FINITE (din)) { dencode = cv_convert_double (converter, din); ut_decode_time (dencode, &year, &month, &day, &hour, &minute, &second, &res); dout[ii] = year; dout[ii + count] = month; dout[ii + 2 * count] = day; dout[ii + 3 * count] = hour; dout[ii + 4 * count] = minute; dout[ii + 5 * count] = second; } else { dout[ii] = NA_REAL; dout[ii + count] = NA_REAL; dout[ii + 2 * count] = NA_REAL; dout[ii + 3 * count] = NA_REAL; dout[ii + 4 * count] = NA_REAL; dout[ii + 5 * count] = NA_REAL; } } /*-- Returning the array ----------------------------------------------------*/ cleanup: status = ut_get_status (); if (inunit) { ut_free (inunit); } if (refunit) { ut_free (refunit); } if (secunit) { ut_free (secunit); } if (converter) { cv_free (converter); } if (status != UT_SUCCESS) { error ("%s", R_nc_uterror (status)); } UNPROTECT(1); return result; } /*-----------------------------------------------------------------------------*\ * R_nc_utinit() \*-----------------------------------------------------------------------------*/ SEXP R_nc_utinit (SEXP path) { const char *pathp; /* Free units if initialised previously */ R_nc_utterm(); /* Initialise a units system */ pathp = R_nc_strarg (path); R_nc_units = ut_read_xml (pathp); if (!R_nc_units) { error ("%s", R_nc_uterror (ut_get_status ())); } return R_NilValue; } /*-----------------------------------------------------------------------------*\ * R_nc_inv_calendar() \*-----------------------------------------------------------------------------*/ SEXP R_nc_inv_calendar (SEXP unitstring, SEXP values) { int itmp, isreal, isfinite; const int *ivals=NULL; const double *dvals=NULL; const char *cstring; double datetime[6], dtmp, dencode, *dout; size_t ii, jj, count; ut_unit *outunit=NULL, *refunit=NULL, *secunit=NULL; cv_converter *converter=NULL; ut_status status; SEXP result; /* Handle arguments and initialise outputs */ cstring = R_nc_strarg (unitstring); isreal = isReal (values); if (isreal) { dvals = REAL (values); } else { ivals = INTEGER (values); } count = xlength (values) / 6; result = PROTECT(allocVector (REALSXP, count)); dout = REAL (result); /* Parse unitstring */ outunit = ut_parse (R_nc_units, cstring, UT_ASCII); if (!outunit) { goto cleanup; } /* Prepare for conversion to encoded time values used internally by udunits2 */ secunit = ut_get_unit_by_name (R_nc_units, "second"); if (!secunit) { goto cleanup; } refunit = ut_offset_by_time (secunit, 0.0); if (!refunit) { goto cleanup; } converter = ut_get_converter (refunit, outunit); if (!converter) { goto cleanup; } /*-- Convert values ---------------------------------------------------------*/ for (ii = 0; ii < count; ii++) { isfinite = 1; if (isreal) { for (jj = 0; jj < 6; jj++) { dtmp = dvals[ii + jj*count]; if (R_FINITE (dtmp)) { datetime[jj] = dtmp; } else { isfinite = 0; break; } } } else { for (jj = 0; jj < 6; jj++) { itmp = ivals[ii + jj*count]; if (itmp == NA_INTEGER) { isfinite = 0; break; } else { datetime[jj] = itmp; } } } if (isfinite) { dencode = ut_encode_time (datetime[0], datetime[1], datetime[2], datetime[3], datetime[4], datetime[5]); dout[ii] = cv_convert_double (converter, dencode); } else { dout[ii] = NA_REAL; } } /* Returning the array */ cleanup: status = ut_get_status (); if (outunit) { ut_free (outunit); } if (refunit) { ut_free (refunit); } if (secunit) { ut_free (secunit); } if (converter) { cv_free (converter); } if (status != UT_SUCCESS) { error ("%s", R_nc_uterror (status)); } UNPROTECT(1); return result; } /*-----------------------------------------------------------------------------*\ * R_nc_utterm() \*-----------------------------------------------------------------------------*/ SEXP R_nc_utterm (void) { if (R_nc_units) { ut_free_system (R_nc_units); R_nc_units = NULL; } return R_NilValue; } #endif /* Conditional compilation with UDUNITS2 */ RNetCDF/src/init.c0000644000176200001440000000662414577720574013367 0ustar liggesusers/*=============================================================================*\ * * Name: common.c * * Version: 2.9-2 * * Purpose: RNetCDF initialisation * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright (C) 2004-2024 Pavel Michna and Milton Woods. * *=============================================================================* * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *=============================================================================* */ #include #include #include "RNetCDF.h" /* Register native routines */ static const R_CallMethodDef callMethods[] = { {"R_nc_copy_att", (DL_FUNC) &R_nc_copy_att, 5}, {"R_nc_delete_att", (DL_FUNC) &R_nc_delete_att, 3}, {"R_nc_get_att", (DL_FUNC) &R_nc_get_att, 5}, {"R_nc_inq_att", (DL_FUNC) &R_nc_inq_att, 3}, {"R_nc_put_att", (DL_FUNC) &R_nc_put_att, 5}, {"R_nc_rename_att", (DL_FUNC) &R_nc_rename_att, 4}, {"R_nc_close", (DL_FUNC) &R_nc_close, 1}, {"R_nc_create", (DL_FUNC) &R_nc_create, 9}, {"R_nc_inq_file", (DL_FUNC) &R_nc_inq_file, 1}, {"R_nc_open", (DL_FUNC) &R_nc_open, 8}, {"R_nc_sync", (DL_FUNC) &R_nc_sync, 1}, {"R_nc_def_dim", (DL_FUNC) &R_nc_def_dim, 4}, {"R_nc_inq_dim", (DL_FUNC) &R_nc_inq_dim, 2}, {"R_nc_inq_unlimids", (DL_FUNC) &R_nc_inq_unlimids, 1}, {"R_nc_rename_dim", (DL_FUNC) &R_nc_rename_dim, 3}, {"R_nc_def_grp", (DL_FUNC) &R_nc_def_grp, 2}, {"R_nc_inq_grp_parent", (DL_FUNC) &R_nc_inq_grp_parent, 1}, {"R_nc_inq_natts", (DL_FUNC) &R_nc_inq_natts, 1}, {"R_nc_inq_grpname", (DL_FUNC) &R_nc_inq_grpname, 2}, {"R_nc_inq_grp_ncid", (DL_FUNC) &R_nc_inq_grp_ncid, 3}, {"R_nc_inq_grps", (DL_FUNC) &R_nc_inq_grps, 1}, {"R_nc_inq_typeids", (DL_FUNC) &R_nc_inq_typeids, 1}, {"R_nc_inq_varids", (DL_FUNC) &R_nc_inq_varids, 1}, {"R_nc_inq_dimids", (DL_FUNC) &R_nc_inq_dimids, 2}, {"R_nc_rename_grp", (DL_FUNC) &R_nc_rename_grp, 2}, {"R_nc_def_type", (DL_FUNC) &R_nc_def_type, 9}, {"R_nc_inq_type", (DL_FUNC) &R_nc_inq_type, 3}, {"R_nc_calendar", (DL_FUNC) &R_nc_calendar, 2}, {"R_nc_utinit", (DL_FUNC) &R_nc_utinit, 1}, {"R_nc_inv_calendar", (DL_FUNC) &R_nc_inv_calendar, 2}, {"R_nc_utterm", (DL_FUNC) &R_nc_utterm, 0}, {"R_nc_def_var", (DL_FUNC) &R_nc_def_var, 12}, {"R_nc_get_var", (DL_FUNC) &R_nc_get_var, 11}, {"R_nc_inq_var", (DL_FUNC) &R_nc_inq_var, 2}, {"R_nc_par_var", (DL_FUNC) &R_nc_par_var, 3}, {"R_nc_put_var", (DL_FUNC) &R_nc_put_var, 10}, {"R_nc_rename_var", (DL_FUNC) &R_nc_rename_var, 3}, {NULL, NULL, 0} }; void R_init_RNetCDF(DllInfo *info) { R_registerRoutines(info, NULL, callMethods, NULL, NULL); R_useDynamicSymbols(info, FALSE); R_forceSymbols(info, TRUE); } RNetCDF/src/type.c0000644000176200001440000004102314577720574013375 0ustar liggesusers/*=============================================================================*\ * * Name: type.c * * Version: 2.9-2 * * Purpose: NetCDF type functions for RNetCDF * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright (C) 2004-2024 Pavel Michna and Milton Woods. * *=============================================================================* * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *=============================================================================* */ #include #include #include #include #include #include #include #include #include #include "common.h" #include "convert.h" #include "RNetCDF.h" /*-----------------------------------------------------------------------------*\ * R_nc_def_type() \*-----------------------------------------------------------------------------*/ /* Private functions called by R_nc_def_type */ static nc_type R_nc_def_compound (int ncid, const char *typename, SEXP names, SEXP subtypes, SEXP dimsizes) { int ndims, status; nc_type typeid, *xtypes; int class, *csizes; size_t ifld, nfld, *coffset, xsize, xsizemax, xcnt, typesize, align, nskip; SEXP shape; /*-- Check arguments -------------------------------------------------------*/ nfld = xlength (names); if ((size_t) xlength (subtypes) != nfld || (size_t) xlength (dimsizes) != nfld) { error ("Lengths of names, subtypes and dimsizes must match"); } else if (nfld < 1) { error ("Compound type must have at least one field"); } /*-- Calculate field offsets with suitable alignment for each native subtype, recording the total size of the compound type and its largest subtype ---*/ coffset = (size_t *) R_alloc (nfld, sizeof(size_t)); xtypes = (nc_type *) R_alloc (nfld, sizeof(nc_type)); typesize = 0; xsizemax = 0; for (ifld=0; ifld xsizemax) { xsizemax = xsize; } xcnt = R_nc_length_sexp (VECTOR_ELT (dimsizes, ifld)); align = xsize < 8 ? xsize : 8; if (typesize % align == 0) { coffset[ifld] = typesize; } else { coffset[ifld] = align * (typesize / align + 1); } typesize = coffset[ifld] + xsize * xcnt; } /*-- Pad the compound type to align the largest native subtype -------------*/ align = xsizemax < 8 ? xsizemax : 8; if (typesize % align != 0) { typesize = align * (typesize / align + 1); } /*-- Enter define mode -----------------------------------------------------*/ R_nc_check( R_nc_redef (ncid)); /*-- Define the type, continuing if a compatible type already exists -------*/ status = nc_def_compound (ncid, typesize, typename, &typeid); if (status == NC_ENAMEINUSE) { R_nc_check (nc_inq_typeid (ncid, typename, &typeid)); R_nc_check (nc_inq_user_type (ncid, typeid, NULL, &xsize, NULL, NULL, &class)); if (class != NC_COMPOUND || xsize != typesize) { error ("Existing type has same name but different class or size"); } warning("Inserting fields in existing type %s", typename); } else { R_nc_check (status); } /*-- Insert fields, skipping any field that already exists -----------------*/ nskip = 0; for (ifld=0; ifld 0) { csizes = R_nc_dim_r2c_int(shape, ndims, 0); } } else { error ("Dimensions of field must be numeric or null"); return NC_NAT; } status = nc_insert_array_compound (ncid, typeid, CHAR (STRING_ELT(names, ifld)), coffset[ifld], xtypes[ifld], ndims, csizes); if (status == NC_ENAMEINUSE) { nskip++; } else { R_nc_check (status); } } if (nskip > 0) { warning("Skipped existing fields of type %s", typename); } return typeid; } static nc_type R_nc_def_enum (int ncid, const char *typename, SEXP basetype, SEXP names, SEXP values) { nc_type xtype, xtype2, typeid; int status, class; size_t size, ival, nval, nskip; const char *tmpname, *cvals, *thisval; /*-- Decode arguments -------------------------------------------------------*/ R_nc_check (R_nc_type_id (basetype, ncid, &xtype, 0)); nval = xlength (values); if ((size_t) xlength (names) != nval) { error ("Lengths of names and values must match"); } cvals = R_nc_r2c (values, ncid, xtype, 1, &nval, 0, NULL, NULL, NULL); /*-- Enter define mode ------------------------------------------------------*/ R_nc_check (R_nc_redef (ncid)); /*-- Define the type, continuing if a compatible type already exists --------*/ status = nc_def_enum (ncid, xtype, typename, &typeid); if (status == NC_ENAMEINUSE) { R_nc_check (nc_inq_typeid (ncid, typename, &typeid)); R_nc_check (nc_inq_user_type (ncid, typeid, NULL, NULL, &xtype2, NULL, &class)); if (class != NC_ENUM || xtype != xtype2) { error ("Existing type has same name but different class or basetype"); } warning("Inserting members in existing type %s", typename); } else { R_nc_check (status); } /*-- Insert members, skipping any member that already exists ----------------*/ R_nc_check (nc_inq_type(ncid, typeid, NULL, &size)); nskip = 0; for (ival=0, thisval=cvals; ival 0) { warning("Skipped existing members of type %s", typename); } return typeid; } SEXP R_nc_def_type (SEXP nc, SEXP typename, SEXP class, SEXP size, SEXP basetype, SEXP names, SEXP values, SEXP subtypes, SEXP dimsizes) { int ncid; const char *typenamep; nc_type typeid=0, xtype=0; size_t xsize=0; /*-- Decode arguments -------------------------------------------------------*/ ncid = asInteger (nc); typenamep = R_nc_strarg (typename); /*-- Enter define mode ------------------------------------------------------*/ R_nc_check( R_nc_redef (ncid)); /*-- Create the type --------------------------------------------------------*/ if (R_nc_strcmp (class, "compound")) { typeid = R_nc_def_compound (ncid, typenamep, names, subtypes, dimsizes); } else if (R_nc_strcmp (class, "enum")) { typeid = R_nc_def_enum (ncid, typenamep, basetype, names, values); } else if (R_nc_strcmp (class, "opaque")) { xsize = R_nc_sizearg (size); R_nc_check (nc_def_opaque (ncid, xsize, typenamep, &typeid)); } else if (R_nc_strcmp (class, "vlen")) { R_nc_check (R_nc_type_id (basetype, ncid, &xtype, 0)); R_nc_check (nc_def_vlen (ncid, typenamep, xtype, &typeid)); } else { error ("Unknown class for type definition"); } return ScalarInteger (typeid); } /*-----------------------------------------------------------------------------*\ * R_nc_insert_type() \*-----------------------------------------------------------------------------*/ SEXP R_nc_insert_type (SEXP nc, SEXP type, SEXP name, SEXP value, SEXP offset, SEXP subtype, SEXP dimsizes) { int ncid, idim, ndims=0; nc_type typeid, xtype; const char *fldname; int class, *csizes=NULL; size_t coffset=0, xsize, subsize, nelem; const void *tmpval=NULL; /*-- Decode arguments -------------------------------------------------------*/ ncid = asInteger (nc); R_nc_check (R_nc_type_id (type, ncid, &typeid, 0)); fldname = R_nc_strarg (name); R_nc_check (nc_inq_user_type (ncid, typeid, NULL, &xsize, &xtype, NULL, &class)); if (class == NC_ENUM) { if (!isNull (value)) { tmpval = R_nc_r2c (value, ncid, xtype, 0, NULL, 0, NULL, NULL, NULL); } else { error ("No value given for enumerated type"); } } else if (class == NC_COMPOUND) { if (!isNull (offset) && !isNull (subtype)) { coffset = R_nc_sizearg (offset); R_nc_check (R_nc_type_id (subtype, ncid, &xtype, 0)); R_nc_check (nc_inq_type (ncid, xtype, NULL, &subsize)); nelem = 1; if (isNull (dimsizes)) { ndims = 0; } else { ndims = length (dimsizes); if (ndims > 0) { csizes = R_nc_dim_r2c_int(dimsizes, ndims, -1); for (idim=0; idim xsize) { error("Field exceeds size of compound type"); } // Keep size checks; allow repeat definition with same details. } else { error ("Missing offset or subtype for compound type"); } } else { error ("Expected enumerated or compound type"); } /*-- Enter define mode ------------------------------------------------------*/ R_nc_check( R_nc_redef (ncid)); /*-- Insert the member or field ---------------------------------------------*/ if (class == NC_ENUM) { R_nc_check (nc_insert_enum (ncid, typeid, fldname, tmpval)); } else if (class == NC_COMPOUND) { if (ndims > 0) { R_nc_check (nc_insert_array_compound (ncid, typeid, fldname, coffset, xtype, ndims, csizes)); } else { R_nc_check (nc_insert_compound (ncid, typeid, fldname, coffset, xtype)); } } return R_NilValue; } /*-----------------------------------------------------------------------------*\ * R_nc_inq_type() \*-----------------------------------------------------------------------------*/ SEXP R_nc_inq_type (SEXP nc, SEXP type, SEXP fields) { int ncid, class, extend; nc_type xtype, basetype, subtype; char typename[NC_MAX_NAME + 1], basename[NC_MAX_NAME + 1]; char fieldname[NC_MAX_NAME + 1], subname[NC_MAX_NAME + 1]; size_t size, nfields, offset; int ii, imax, ndims; char *cval; SEXP result=R_NilValue, resultnames=R_NilValue; SEXP fieldnames, values, offsets, subnames, dimsize, dimsizes; R_nc_buf io; /*-- Convert arguments to netcdf ids ----------------------------------------*/ ncid = asInteger (nc); R_nc_check (R_nc_type_id (type, ncid, &xtype, 0)); extend = (asLogical (fields) == TRUE); /*-- General properties -----------------------------------------------------*/ R_nc_check (nc_inq_type (ncid, xtype, NULL, &size)); R_nc_check (R_nc_type2str (ncid, xtype, typename)); if (xtype > NC_MAX_ATOMIC_TYPE) { /*-- User-defined types -----------------------------------------------------*/ R_nc_check (nc_inq_user_type (ncid, xtype, NULL, NULL, &basetype, &nfields, &class)); switch (class) { case NC_COMPOUND: if (extend) { result = PROTECT(allocVector (VECSXP, 7)); resultnames = PROTECT(allocVector (STRSXP, 7)); setAttrib (result, R_NamesSymbol, resultnames); UNPROTECT(1); SET_STRING_ELT (resultnames, 4, PROTECT(mkChar ("offset"))); SET_STRING_ELT (resultnames, 5, PROTECT(mkChar ("subtype"))); SET_STRING_ELT (resultnames, 6, PROTECT(mkChar ("dimsizes"))); UNPROTECT(3); /* Read named vectors of offsets, typenames, list of array dimensions */ offsets = PROTECT(allocVector (REALSXP, nfields)); subnames = PROTECT(allocVector (STRSXP, nfields)); dimsizes = PROTECT(allocVector (VECSXP, nfields)); SET_VECTOR_ELT (result, 4, offsets); SET_VECTOR_ELT (result, 5, subnames); SET_VECTOR_ELT (result, 6, dimsizes); UNPROTECT(3); fieldnames = PROTECT(allocVector (STRSXP, nfields)); setAttrib (offsets, R_NamesSymbol, fieldnames); setAttrib (subnames, R_NamesSymbol, fieldnames); setAttrib (dimsizes, R_NamesSymbol, fieldnames); UNPROTECT(1); imax = nfields; // netcdf field index is int for (ii=0; ii < imax; ii++) { R_nc_check (nc_inq_compound_field (ncid, xtype, ii, fieldname, &offset, &subtype, &ndims, NULL)); SET_STRING_ELT (fieldnames, ii, PROTECT(mkChar (fieldname))); REAL (offsets)[ii] = offset; R_nc_check (R_nc_type2str (ncid, subtype, subname)); SET_STRING_ELT (subnames, ii, PROTECT(mkChar (subname))); UNPROTECT(2); if (ndims > 0) { dimsize = PROTECT(allocVector (INTSXP, ndims)); R_nc_check (nc_inq_compound_fielddim_sizes ( ncid, xtype, ii, INTEGER (dimsize))); SET_VECTOR_ELT (dimsizes, ii, dimsize); UNPROTECT(1); } } } else { result = PROTECT(allocVector (VECSXP, 4)); resultnames = PROTECT(allocVector (STRSXP, 4)); setAttrib (result, R_NamesSymbol, resultnames); UNPROTECT(1); } SET_VECTOR_ELT (result, 2, PROTECT(mkString ("compound"))); UNPROTECT(1); break; case NC_ENUM: R_nc_check (R_nc_type2str (ncid, basetype, basename)); if (extend) { result = PROTECT(allocVector (VECSXP, 6)); resultnames = PROTECT(allocVector (STRSXP, 6)); setAttrib (result, R_NamesSymbol, resultnames); SET_STRING_ELT (resultnames, 5, PROTECT(mkChar ("value"))); UNPROTECT(2); /* Read named vector of member values */ fieldnames = PROTECT(allocVector (STRSXP, nfields)); cval = NULL; values = PROTECT(R_nc_c2r_init (&io, (void **) &cval, ncid, basetype, -1, &nfields, 0, 1, 0, NULL, NULL, NULL, NULL, NULL)); imax = nfields; // netcdf member index is int for (ii=0; ii < imax; ii++, cval+=size) { R_nc_check (nc_inq_enum_member (ncid, xtype, ii, fieldname, cval)); SET_STRING_ELT (fieldnames, ii, PROTECT(mkChar (fieldname))); UNPROTECT(1); } R_nc_c2r (&io); SET_VECTOR_ELT (result, 5, values); setAttrib (values, R_NamesSymbol, fieldnames); UNPROTECT(2); } else { result = PROTECT(allocVector (VECSXP, 5)); resultnames = PROTECT(allocVector (STRSXP, 5)); setAttrib (result, R_NamesSymbol, resultnames); UNPROTECT(1); } SET_VECTOR_ELT (result, 2, PROTECT(mkString ("enum"))); SET_VECTOR_ELT (result, 4, PROTECT(mkString (basename))); SET_STRING_ELT (resultnames, 4, PROTECT(mkChar ("basetype"))); UNPROTECT(3); break; case NC_OPAQUE: result = PROTECT(allocVector (VECSXP, 4)); SET_VECTOR_ELT (result, 2, PROTECT(mkString ("opaque"))); resultnames = PROTECT(allocVector (STRSXP, 4)); setAttrib (result, R_NamesSymbol, resultnames); UNPROTECT(2); break; case NC_VLEN: R_nc_check (R_nc_type2str (ncid, basetype, basename)); result = PROTECT(allocVector (VECSXP, 5)); SET_VECTOR_ELT (result, 2, PROTECT(mkString ("vlen"))); SET_VECTOR_ELT (result, 4, PROTECT(mkString (basename))); resultnames = PROTECT(allocVector (STRSXP, 5)); setAttrib (result, R_NamesSymbol, resultnames); SET_STRING_ELT (resultnames, 4, PROTECT(mkChar ("basetype"))); UNPROTECT(4); break; default: error ("Unknown class of user defined type"); } } else { /*-- Built-in types ---------------------------------------------------------*/ result = PROTECT(allocVector (VECSXP, 4)); SET_VECTOR_ELT (result, 2, PROTECT(mkString ("builtin"))); resultnames = PROTECT(allocVector (STRSXP, 4)); setAttrib (result, R_NamesSymbol, resultnames); UNPROTECT(2); } /*-- Common components of output list ----------------------------------------------*/ SET_VECTOR_ELT (result, 0, PROTECT(ScalarInteger (xtype))); SET_VECTOR_ELT (result, 1, PROTECT(mkString (typename))); SET_VECTOR_ELT (result, 3, PROTECT(ScalarReal (size))); SET_STRING_ELT (resultnames, 0, PROTECT(mkChar ("id"))); SET_STRING_ELT (resultnames, 1, PROTECT(mkChar ("name"))); SET_STRING_ELT (resultnames, 2, PROTECT(mkChar ("class"))); SET_STRING_ELT (resultnames, 3, PROTECT(mkChar ("size"))); UNPROTECT(8); return result; } RNetCDF/src/attribute.c0000644000176200001440000002520414577720574014422 0ustar liggesusers/*=============================================================================* * * Name: attribute.c * * Version: 2.9-2 * * Purpose: NetCDF attribute functions for RNetCDF * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright (C) 2004-2024 Pavel Michna and Milton Woods. * *=============================================================================* * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *=============================================================================* */ #include #include #include #include #include #include #include #include #include #include "common.h" #include "convert.h" #include "RNetCDF.h" /* Convert attribute identifier from R string or number to a C string. Argument attname must have space for NC_MAX_NAME+1 characters. Result is a netcdf status value. */ static int R_nc_att_name (SEXP att, int ncid, int varid, char *attname) { if (isNumeric (att)) { return nc_inq_attname (ncid, varid, asInteger (att), attname); } else if (isString (att) && xlength (att) > 0) { strncpy (attname, CHAR (STRING_ELT (att, 0)), NC_MAX_NAME); attname[NC_MAX_NAME] = '\0'; return NC_NOERR; } else { return NC_EINVAL; } } /*-----------------------------------------------------------------------------*\ * R_nc_copy_att() \*-----------------------------------------------------------------------------*/ SEXP R_nc_copy_att (SEXP nc_in, SEXP var_in, SEXP att, SEXP nc_out, SEXP var_out) { int ncid_in, ncid_out, varid_in, varid_out; char attname[NC_MAX_NAME+1]; /*-- Convert arguments to netcdf ids ----------------------------------------*/ ncid_in = asInteger (nc_in); ncid_out = asInteger (nc_out); if (R_nc_strcmp(var_in, "NC_GLOBAL")) { varid_in = NC_GLOBAL; } else { R_nc_check (R_nc_var_id (var_in, ncid_in, &varid_in)); } if (R_nc_strcmp(var_out, "NC_GLOBAL")) { varid_out = NC_GLOBAL; } else { R_nc_check (R_nc_var_id (var_out, ncid_out, &varid_out)); } R_nc_check (R_nc_att_name (att, ncid_in, varid_in, attname)); /*-- Enter define mode ------------------------------------------------------*/ R_nc_check( R_nc_redef (ncid_out)); /*-- Copy the attribute -----------------------------------------------------*/ R_nc_check (nc_copy_att (ncid_in, varid_in, attname, ncid_out, varid_out)); return R_NilValue; } /*-----------------------------------------------------------------------------*\ * R_nc_delete_att() \*-----------------------------------------------------------------------------*/ SEXP R_nc_delete_att (SEXP nc, SEXP var, SEXP att) { int ncid, varid; char attname[NC_MAX_NAME+1]; /*-- Convert arguments to netcdf ids ----------------------------------------*/ ncid = asInteger (nc); if (R_nc_strcmp(var, "NC_GLOBAL")) { varid = NC_GLOBAL; } else { R_nc_check (R_nc_var_id (var, ncid, &varid)); } R_nc_check (R_nc_att_name (att, ncid, varid, attname)); /*-- Enter define mode ------------------------------------------------------*/ R_nc_check( R_nc_redef (ncid)); /*-- Delete the attribute ---------------------------------------------------*/ R_nc_check (nc_del_att (ncid, varid, attname)); return R_NilValue; } /*-----------------------------------------------------------------------------*\ * R_nc_get_att() \*-----------------------------------------------------------------------------*/ SEXP R_nc_get_att (SEXP nc, SEXP var, SEXP att, SEXP rawchar, SEXP fitnum) { int ncid, varid, israw, isfit; char attname[NC_MAX_NAME+1]; size_t cnt; nc_type xtype; SEXP result; void *buf; R_nc_buf io; /*-- Convert arguments ------------------------------------------------------*/ ncid = asInteger (nc); if (R_nc_strcmp(var, "NC_GLOBAL")) { varid = NC_GLOBAL; } else { R_nc_check (R_nc_var_id (var, ncid, &varid)); } R_nc_check (R_nc_att_name (att, ncid, varid, attname)); israw = (asLogical (rawchar) == TRUE); isfit = (asLogical (fitnum) == TRUE); /*-- Get the attribute's type and size --------------------------------------*/ R_nc_check(nc_inq_att (ncid, varid, attname, &xtype, &cnt)); /*-- Enter data mode (if necessary) -----------------------------------------*/ R_nc_check (R_nc_enddef (ncid)); /*-- Allocate memory and read attribute from file ---------------------------*/ buf = NULL; result = PROTECT(R_nc_c2r_init (&io, &buf, ncid, xtype, -1, &cnt, israw, isfit, 0, NULL, NULL, NULL, NULL, NULL)); if (cnt > 0) { R_nc_check (nc_get_att (ncid, varid, attname, buf)); } R_nc_c2r (&io); UNPROTECT(1); return result; } /*-----------------------------------------------------------------------------*\ * R_nc_inq_att() \*-----------------------------------------------------------------------------*/ SEXP R_nc_inq_att (SEXP nc, SEXP var, SEXP att) { int ncid, varid, attid; char attname[NC_MAX_NAME+1], atttype[NC_MAX_NAME+1]; nc_type type; size_t cnt; SEXP result; /*-- Convert arguments to netcdf ids ----------------------------------------*/ ncid = asInteger (nc); if (R_nc_strcmp(var, "NC_GLOBAL")) { varid = NC_GLOBAL; } else { R_nc_check (R_nc_var_id (var, ncid, &varid)); } R_nc_check (R_nc_att_name (att, ncid, varid, attname)); /*-- Inquire about the attribute --------------------------------------------*/ R_nc_check (nc_inq_attid (ncid, varid, attname, &attid)); R_nc_check (nc_inq_att (ncid, varid, attname, &type, &cnt)); /*-- Convert nc_type to char ------------------------------------------------*/ R_nc_check (R_nc_type2str (ncid, type, atttype)); /*-- Returning the list -----------------------------------------------------*/ result = PROTECT(allocVector (VECSXP, 4)); SET_VECTOR_ELT (result, 0, PROTECT(ScalarInteger (attid))); SET_VECTOR_ELT (result, 1, PROTECT(mkString (attname))); SET_VECTOR_ELT (result, 2, PROTECT(mkString (atttype))); /* cnt may not fit in integer, so return as double */ SET_VECTOR_ELT (result, 3, PROTECT(ScalarReal (cnt))); UNPROTECT(5); return result; } /*-----------------------------------------------------------------------------*\ * R_nc_put_att() \*-----------------------------------------------------------------------------*/ SEXP R_nc_put_att (SEXP nc, SEXP var, SEXP att, SEXP type, SEXP data) { int ncid, varid, class, idim, ndimfld, *dimlenfld, ismatch; size_t cnt, xsize, ilist, nlist, datalen, typelen; nc_type xtype; const char *attname; const void *buf; char namefld[NC_MAX_NAME+1]; SEXP namelist; /*-- Convert arguments to netcdf ids ----------------------------------------*/ ncid = asInteger (nc); if (R_nc_strcmp(var, "NC_GLOBAL")) { varid = NC_GLOBAL; } else { R_nc_check (R_nc_var_id (var, ncid, &varid)); } attname = R_nc_strarg (att); R_nc_check (R_nc_type_id (type, ncid, &xtype, 0)); /*-- Enter define mode ------------------------------------------------------*/ R_nc_check( R_nc_redef (ncid)); /*-- Find number of input items of the specified type -----------------------*/ if (xtype > NC_MAX_ATOMIC_TYPE) { R_nc_check (nc_inq_user_type (ncid, xtype, NULL, &xsize, NULL, NULL, &class)); if (class == NC_COMPOUND && TYPEOF(data) == VECSXP) { /* Find number of elements in first field of compound type */ R_nc_check (nc_inq_compound_field (ncid, xtype, 0, namefld, NULL, NULL, &ndimfld, NULL)); if (ndimfld > 0) { dimlenfld = (int *) R_alloc (ndimfld, sizeof(int)); R_nc_check (nc_inq_compound_fielddim_sizes (ncid, xtype, 0, dimlenfld)); typelen = 1; for (idim=0; idim 0) { cnt = xlength(data) / xsize; } else { cnt = xlength(data); } } else if (xtype == NC_CHAR && isString (data)) { cnt = strlen (R_nc_strarg (data)); } else { cnt = xlength (data); } /* -- Write attribute to file -----------------------------------------------*/ if (cnt > 0) { buf = R_nc_r2c (data, ncid, xtype, 1, &cnt, 0, NULL, NULL, NULL); R_nc_check (nc_put_att (ncid, varid, attname, xtype, cnt, buf)); } return R_NilValue; } /*-----------------------------------------------------------------------------*\ * R_nc_rename_att() \*-----------------------------------------------------------------------------*/ SEXP R_nc_rename_att (SEXP nc, SEXP var, SEXP att, SEXP newname) { int ncid, varid; const char *attname, *newattname; /*-- Convert arguments to netcdf ids ----------------------------------------*/ ncid = asInteger (nc); if (R_nc_strcmp(var, "NC_GLOBAL")) { varid = NC_GLOBAL; } else { R_nc_check (R_nc_var_id (var, ncid, &varid)); } attname = R_nc_strarg (att); newattname = R_nc_strarg (newname); /*-- Enter define mode ------------------------------------------------------*/ R_nc_check( R_nc_redef (ncid)); /*-- Rename the attribute ---------------------------------------------------*/ R_nc_check (nc_rename_att (ncid, varid, attname, newattname)); return R_NilValue; } RNetCDF/src/convert.c0000644000176200001440000061250314577720574014103 0ustar liggesusers/* NOTE: This code was generated from tools/convert.m4 */ /*=============================================================================*\ * * Name: convert.c * * Version: 2.9-2 * * Purpose: Type conversions for RNetCDF * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright (C) 2004-2024 Pavel Michna and Milton Woods. * *=============================================================================* * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *=============================================================================* */ /*=============================================================================*\ * Includes \*=============================================================================*/ #include #include #include #include #include #include #include #include #include #include "common.h" #include "convert.h" /*=============================================================================*\ * Local macros, constants and variables \*=============================================================================*/ /* Definition of missing value used by bit64 package */ #define NA_INTEGER64 LLONG_MIN /* Maximum length of R character string */ #define RNC_CHARSXP_MAXLEN 2147483647 /* Conversion from 64-bit integers to double may round upwards, so that the double cannot be converted back to the original type. The following limits can be safely converted both ways. */ static const double LLONG_MAX_DBL = \ ((double) LLONG_MAX) * (1.0 - DBL_EPSILON); static const double LLONG_MIN_DBL = \ ((double) LLONG_MIN) * (1.0 - DBL_EPSILON); static const double ULLONG_MAX_DBL = \ ((double) ULLONG_MAX) * (1.0 - DBL_EPSILON); static const double SIZE_MAX_DBL = \ ((double) SIZE_MAX) * (1.0 - DBL_EPSILON); /*=============================================================================*\ * Memory management. \*=============================================================================*/ size_t R_nc_length (int ndims, const size_t *count) { int ii; size_t length; if (ndims < 0) { /* Vector of length count[0] */ ndims = 1; } length = 1; for ( ii=0; ii 0) { rdim = PROTECT( allocVector (INTSXP, ndims)); intp = INTEGER (rdim); for ( ii=0, jj=ndims-1; ii 0) { /* Omit fastest-varying dimension from R character array */ rowlen = xdim[ndim-1]; cnt = R_nc_length (ndim-1, xdim); } else if (ndim == 0) { /* Scalar character */ rowlen = 1; cnt = 1; } else { /* Single string */ rowlen = xdim[0]; cnt = 1; } if ((size_t) xlength (rstr) < cnt) { error (RNC_EDATALEN); } carr = R_alloc (cnt*rowlen, sizeof (char)); /* Prefill the buffer with the defined value or null characters */ if (fill != NULL && fillsize == sizeof (char)) { fillval = *(char *) fill; } else { fillval = '\0'; } memset(carr, fillval, cnt*rowlen); for (ii=0, thiscstr=carr; iindim > 0) { io->rxp = PROTECT(R_nc_allocArray (STRSXP, (io->ndim)-1, io->xdim)); } else { /* Single character or string */ io->rxp = PROTECT(R_nc_allocArray (STRSXP, 0, io->xdim)); } if (!io->cbuf) { io->cbuf = R_alloc (R_nc_length (io->ndim, io->xdim), sizeof (char)); } UNPROTECT(1); return io->rxp; } static void R_nc_char_strsxp (R_nc_buf *io) { size_t ii, cnt, clen, rlen, thislen; char *thisstr, fillval; int hasfill; /* Find fill value */ if (io->fill != NULL && io->fillsize == sizeof (char)) { hasfill = 1; fillval = *(char *) io->fill; } else { hasfill = 0; } /* Find maximum length of strings returned to R, based on array dimensions of the C buffer */ if (io->ndim > 0) { /* Omit fastest-varying dimension from R character array */ clen = io->xdim[(io->ndim)-1]; } else if (io->ndim == 0) { /* Scalar character */ clen = 1; } else { /* Single string */ clen = io->xdim[0]; } rlen = (clen <= RNC_CHARSXP_MAXLEN) ? clen : RNC_CHARSXP_MAXLEN; cnt = xlength (io->rxp); /* If C buffer has row length > 0, convert rows of C buffer to separate R strings, otherwise return empty R strings as initialised by R_nc_allocArray */ if (clen > 0) { for (ii=0, thisstr=io->cbuf; iirxp, ii, PROTECT(mkCharLen (thisstr, thislen))); UNPROTECT(1); } } } static const char * R_nc_raw_char (SEXP rarr, int ndim, const size_t *xdim) { size_t cnt; cnt = R_nc_length (ndim, xdim); if ((size_t) xlength (rarr) < cnt) { error (RNC_EDATALEN); } return (const char *) RAW (rarr); } static SEXP R_nc_char_raw_init (R_nc_buf *io) { io->rxp = PROTECT(R_nc_allocArray (RAWSXP, io->ndim, io->xdim)); io->rbuf = RAW (io->rxp); if (!io->cbuf) { io->cbuf = io->rbuf; } UNPROTECT(1); return io->rxp; } static void R_nc_char_raw (R_nc_buf *io) { if (io->cbuf != io->rbuf) { memcpy(io->rbuf, io->cbuf, xlength(io->rxp) * sizeof(char)); } return; } static const char ** R_nc_strsxp_str (SEXP rstr, int ndim, const size_t *xdim, size_t fillsize, const void *fill) { size_t ii, cnt; const char **cstr, *fillval; SEXP thissxp; int hasfill; hasfill = (fill != NULL && fillsize == sizeof (size_t)); if (hasfill) { fillval = *(const char **) fill; } cnt = R_nc_length (ndim, xdim); if ((size_t) xlength (rstr) < cnt) { error (RNC_EDATALEN); } cstr = (const char **) R_alloc (cnt, sizeof(size_t)); for (ii=0; iirxp = PROTECT(R_nc_allocArray (STRSXP, io->ndim, io->xdim)); if (!io->cbuf) { io->cbuf = R_alloc (xlength (io->rxp), sizeof(size_t)); } UNPROTECT(1); return io->rxp; } static void R_nc_str_strsxp (R_nc_buf *io) { size_t ii, nchar, cnt; char **cstr; const char *fillval; int hasfill; hasfill = (io->fill != NULL && io->fillsize == sizeof (size_t)); if (hasfill) { fillval = *(const char **) io->fill; } cnt = xlength (io->rxp); cstr = (char **) io->cbuf; for (ii=0; iirxp, ii, NA_STRING); } else { /* Truncate excessively long strings while reading into R */ nchar = R_nc_strnlen (cstr[ii], '\0', RNC_CHARSXP_MAXLEN); SET_STRING_ELT (io->rxp, ii, PROTECT(mkCharLen (cstr[ii], nchar))); UNPROTECT(1); } } /* Free pointers to strings created by netcdf */ if (cnt > 0) { R_nc_check (nc_free_string (cnt, io->cbuf)); } } /*=============================================================================*\ * Numeric type conversions \*=============================================================================*/ /* Convert numeric values from R to C format. Memory for the result is allocated if necessary (and freed by R). In special cases, the output is a pointer to the input data, so the output data should not be modified. An error is raised if any input values are outside the range of the output type. */ static const signed char* R_nc_r2c_int_schar (SEXP rv, int ndim, const size_t *xdim, size_t fillsize, const signed char *fill) { size_t ii, cnt, hasfill; const int *in; signed char fillval=0, *out; in = (int *) INTEGER (rv); cnt = R_nc_length (ndim, xdim); if ((size_t) xlength (rv) < cnt) { error (RNC_EDATALEN); } hasfill = (fill != NULL); out = (signed char *) R_alloc (cnt, sizeof(signed char)); if (hasfill) { if (fillsize != sizeof(signed char)) { error ("Size of fill value does not match output type"); } fillval = *fill; } if (hasfill) { for (ii=0; ii SIZEOF_SIZE_T static const size_t* R_nc_r2c_int_size (SEXP rv, int ndim, const size_t *xdim, size_t fillsize, const size_t *fill) { size_t ii, cnt, hasfill; const int *in; size_t fillval=0, *out; in = (int *) INTEGER (rv); cnt = R_nc_length (ndim, xdim); if ((size_t) xlength (rv) < cnt) { error (RNC_EDATALEN); } hasfill = (fill != NULL); out = (size_t *) R_alloc (cnt, sizeof(size_t)); if (hasfill) { if (fillsize != sizeof(size_t)) { error ("Size of fill value does not match output type"); } fillval = *fill; } if (hasfill) { for (ii=0; ii SIZEOF_SIZE_T static const size_t* R_nc_r2c_bit64_size (SEXP rv, int ndim, const size_t *xdim, size_t fillsize, const size_t *fill) { size_t ii, cnt, hasfill; const long long *in; size_t fillval=0, *out; in = (long long *) REAL (rv); cnt = R_nc_length (ndim, xdim); if ((size_t) xlength (rv) < cnt) { error (RNC_EDATALEN); } hasfill = (fill != NULL); out = (size_t *) R_alloc (cnt, sizeof(size_t)); if (hasfill) { if (fillsize != sizeof(size_t)) { error ("Size of fill value does not match output type"); } fillval = *fill; } if (hasfill) { for (ii=0; iicbuf is NULL, a separate C buffer is allocated for data before conversion, which will be freed automatically on return to R. The SEXP is returned and should be PROTECTed by the caller. */ static SEXP R_nc_c2r_int_init (R_nc_buf *io) { size_t xsize; io->rxp = PROTECT(R_nc_allocArray (INTSXP, io->ndim, io->xdim)); io->rbuf = INTEGER (io->rxp); if (!io->cbuf) { R_nc_check (nc_inq_type(io->ncid, io->xtype, NULL, &xsize)); io->cbuf = R_alloc (R_nc_length (io->ndim, io->xdim), xsize); } UNPROTECT(1); return io->rxp; } static SEXP R_nc_c2r_dbl_init (R_nc_buf *io) { size_t xsize; io->rxp = PROTECT(R_nc_allocArray (REALSXP, io->ndim, io->xdim)); io->rbuf = REAL (io->rxp); if (!io->cbuf) { R_nc_check (nc_inq_type(io->ncid, io->xtype, NULL, &xsize)); io->cbuf = R_alloc (R_nc_length (io->ndim, io->xdim), xsize); } UNPROTECT(1); return io->rxp; } static SEXP R_nc_c2r_bit64_init (R_nc_buf *io) { size_t xsize; io->rxp = PROTECT(R_nc_allocArray (REALSXP, io->ndim, io->xdim)); io->rbuf = REAL (io->rxp); if (!io->cbuf) { R_nc_check (nc_inq_type(io->ncid, io->xtype, NULL, &xsize)); io->cbuf = R_alloc (R_nc_length (io->ndim, io->xdim), xsize); } UNPROTECT(1); return io->rxp; } /* Convert numeric values from C to R format. Parameters and buffers for the conversion are passed via the R_nc_buf struct. Non-overlapping buffers must be used for input and output. Fill values and values outside the valid range are set to missing, but NA or NaN values in floating point data are transferred to the output (because all comparisons with NA or NaN are false). */ static void R_nc_c2r_schar_int (R_nc_buf *io) { size_t ii, cnt; signed char fillval=0, minval=0, maxval=0, *in; int *out; int hasfill, hasmin, hasmax; cnt = xlength (io->rxp); in = (signed char *) io->cbuf; out = (int *) io->rbuf; if ((io->fill || io->min || io->max ) && io->fillsize != sizeof(signed char)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((signed char *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((signed char *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((signed char *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (unsigned char *) io->cbuf; out = (int *) io->rbuf; if ((io->fill || io->min || io->max ) && io->fillsize != sizeof(unsigned char)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((unsigned char *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((unsigned char *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((unsigned char *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (short *) io->cbuf; out = (int *) io->rbuf; if ((io->fill || io->min || io->max ) && io->fillsize != sizeof(short)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((short *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((short *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((short *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (unsigned short *) io->cbuf; out = (int *) io->rbuf; if ((io->fill || io->min || io->max ) && io->fillsize != sizeof(unsigned short)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((unsigned short *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((unsigned short *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((unsigned short *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (int *) io->cbuf; out = (int *) io->rbuf; if ((io->fill || io->min || io->max ) && io->fillsize != sizeof(int)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((int *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((int *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((int *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (signed char *) io->cbuf; out = (double *) io->rbuf; if ((io->fill || io->min || io->max ) && io->fillsize != sizeof(signed char)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((signed char *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((signed char *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((signed char *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (unsigned char *) io->cbuf; out = (double *) io->rbuf; if ((io->fill || io->min || io->max ) && io->fillsize != sizeof(unsigned char)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((unsigned char *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((unsigned char *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((unsigned char *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (short *) io->cbuf; out = (double *) io->rbuf; if ((io->fill || io->min || io->max ) && io->fillsize != sizeof(short)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((short *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((short *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((short *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (unsigned short *) io->cbuf; out = (double *) io->rbuf; if ((io->fill || io->min || io->max ) && io->fillsize != sizeof(unsigned short)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((unsigned short *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((unsigned short *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((unsigned short *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (int *) io->cbuf; out = (double *) io->rbuf; if ((io->fill || io->min || io->max ) && io->fillsize != sizeof(int)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((int *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((int *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((int *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (unsigned int *) io->cbuf; out = (double *) io->rbuf; if ((io->fill || io->min || io->max ) && io->fillsize != sizeof(unsigned int)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((unsigned int *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((unsigned int *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((unsigned int *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (float *) io->cbuf; out = (double *) io->rbuf; if ((io->fill || io->min || io->max ) && io->fillsize != sizeof(float)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((float *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((float *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((float *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (double *) io->cbuf; out = (double *) io->rbuf; if ((io->fill || io->min || io->max ) && io->fillsize != sizeof(double)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((double *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((double *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((double *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (long long *) io->cbuf; out = (double *) io->rbuf; if ((io->fill || io->min || io->max ) && io->fillsize != sizeof(long long)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((long long *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((long long *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((long long *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (unsigned long long *) io->cbuf; out = (double *) io->rbuf; if ((io->fill || io->min || io->max ) && io->fillsize != sizeof(unsigned long long)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((unsigned long long *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((unsigned long long *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((unsigned long long *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (long long *) io->cbuf; out = (long long *) io->rbuf; if ((io->fill || io->min || io->max ) && io->fillsize != sizeof(long long)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((long long *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((long long *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((long long *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (unsigned long long *) io->cbuf; out = (long long *) io->rbuf; if ((io->fill || io->min || io->max ) && io->fillsize != sizeof(unsigned long long)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((unsigned long long *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((unsigned long long *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((unsigned long long *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (signed char *) io->cbuf; out = (double *) io->rbuf; if (io->scale) { factor = *(io->scale); } if (io->add) { offset = *(io->add); } if ((io->fill || io->min || io->max) && io->fillsize != sizeof(signed char)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((signed char *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((signed char *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((signed char *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (unsigned char *) io->cbuf; out = (double *) io->rbuf; if (io->scale) { factor = *(io->scale); } if (io->add) { offset = *(io->add); } if ((io->fill || io->min || io->max) && io->fillsize != sizeof(unsigned char)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((unsigned char *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((unsigned char *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((unsigned char *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (short *) io->cbuf; out = (double *) io->rbuf; if (io->scale) { factor = *(io->scale); } if (io->add) { offset = *(io->add); } if ((io->fill || io->min || io->max) && io->fillsize != sizeof(short)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((short *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((short *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((short *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (unsigned short *) io->cbuf; out = (double *) io->rbuf; if (io->scale) { factor = *(io->scale); } if (io->add) { offset = *(io->add); } if ((io->fill || io->min || io->max) && io->fillsize != sizeof(unsigned short)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((unsigned short *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((unsigned short *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((unsigned short *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (int *) io->cbuf; out = (double *) io->rbuf; if (io->scale) { factor = *(io->scale); } if (io->add) { offset = *(io->add); } if ((io->fill || io->min || io->max) && io->fillsize != sizeof(int)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((int *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((int *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((int *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (unsigned int *) io->cbuf; out = (double *) io->rbuf; if (io->scale) { factor = *(io->scale); } if (io->add) { offset = *(io->add); } if ((io->fill || io->min || io->max) && io->fillsize != sizeof(unsigned int)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((unsigned int *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((unsigned int *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((unsigned int *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (float *) io->cbuf; out = (double *) io->rbuf; if (io->scale) { factor = *(io->scale); } if (io->add) { offset = *(io->add); } if ((io->fill || io->min || io->max) && io->fillsize != sizeof(float)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((float *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((float *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((float *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (double *) io->cbuf; out = (double *) io->rbuf; if (io->scale) { factor = *(io->scale); } if (io->add) { offset = *(io->add); } if ((io->fill || io->min || io->max) && io->fillsize != sizeof(double)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((double *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((double *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((double *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (long long *) io->cbuf; out = (double *) io->rbuf; if (io->scale) { factor = *(io->scale); } if (io->add) { offset = *(io->add); } if ((io->fill || io->min || io->max) && io->fillsize != sizeof(long long)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((long long *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((long long *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((long long *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; iirxp); in = (unsigned long long *) io->cbuf; out = (double *) io->rbuf; if (io->scale) { factor = *(io->scale); } if (io->add) { offset = *(io->add); } if ((io->fill || io->min || io->max) && io->fillsize != sizeof(unsigned long long)) { error ("Size of fill value does not match input type"); } hasfill = (io->fill != NULL); if (hasfill) { fillval = *((unsigned long long *) io->fill); } hasmin = (io->min != NULL); if (hasmin) { minval = *((unsigned long long *) io->min); } hasmax = (io->max != NULL); if (hasmax) { maxval = *((unsigned long long *) io->max); } if (hasfill) { if (hasmin) { if (hasmax) { for (ii=0; ii NC_MAX_ATOMIC_TYPE) { R_nc_check (nc_inq_user_type (ncid, basetype, NULL, &basesize, NULL, NULL, &baseclass)); } else { R_nc_check (nc_inq_type (ncid, basetype, NULL, &basesize)); baseclass = NC_NAT; } /* Check if fill value is properly defined */ hasfill = (fill != NULL && fillsize == size); basefill = NULL; basefillsize = 0; if (hasfill) { vfill = (nc_vlen_t *) fill; if (vfill[0].len > 0) { basefill = vfill[0].p; basefillsize = basesize; } } /* Convert list items to vlen elements */ vbuf = (nc_vlen_t *) R_alloc (cnt, sizeof(nc_vlen_t)); for (ii=0; ii 0) { len = strlen (CHAR (STRING_ELT (item, 0))); } else { len = 0; } } else if (baseclass == NC_OPAQUE && TYPEOF (item) == RAWSXP) { len = xlength(item) / basesize; } else { len = xlength(item); } vbuf[ii].len = len; if (len > 0) { vbuf[ii].p = (void *) R_nc_r2c (item, ncid, basetype, -1, &len, basefillsize, basefill, scale, add); } else { vbuf[ii].p = NULL; } UNPROTECT(1); } return vbuf; } /* Allocate memory for reading a slice of a netcdf vlen variable and converting the results to an R variable. On input, the R_nc_buf structure contains dimensions of the buffer (ndim, *xdim). On output, the R_nc_buf structure contains an allocated R list (with dim attribute), and the C buffer is an array of pointers which are allocated by netcdf when reading from the variable (and which must be freed later by netcdf). */ static SEXP R_nc_vlen_vecsxp_init (R_nc_buf *io) { io->rxp = PROTECT(R_nc_allocArray (VECSXP, io->ndim, io->xdim)); if (!io->cbuf) { io->cbuf = R_alloc (xlength (io->rxp), sizeof(nc_vlen_t)); } UNPROTECT(1); return io->rxp; } /* Convert netcdf vlen array from C to R format. Parameters and buffers for the conversion are passed via the R_nc_buf struct. On input, the C data is stored in io->cbuf. On output, the R data is copied to io->rxp, and memory used by netcdf is freed. */ static void R_nc_vlen_vecsxp (R_nc_buf *io) { size_t ii, cnt, size, basesize, basefillsize; nc_type basetype; nc_vlen_t *vbuf, *vfill; R_nc_buf tmpio; SEXP tmprxp; int baseclass, hasfill; const void *basefill; vbuf = io->cbuf; cnt = xlength (io->rxp); R_nc_check (nc_inq_user_type (io->ncid, io->xtype, NULL, &size, &basetype, NULL, NULL)); if (basetype > NC_MAX_ATOMIC_TYPE) { R_nc_check (nc_inq_user_type (io->ncid, basetype, NULL, &basesize, NULL, NULL, &baseclass)); } else { R_nc_check (nc_inq_type (io->ncid, basetype, NULL, &basesize)); baseclass = NC_NAT; } /* Check if fill value is properly defined */ hasfill = (io->fill != NULL && io->fillsize == size); basefill = NULL; basefillsize = 0; if (hasfill) { vfill = (nc_vlen_t *) io->fill; if (vfill[0].len > 0) { basefill = vfill[0].p; basefillsize = basesize; } } /* Convert vlen elements to list items */ for (ii=0; iincid, basetype, -1, &(vbuf[ii].len), io->rawchar, io->fitnum, basefillsize, basefill, io->min, io->max, io->scale, io->add)); R_nc_c2r (&tmpio); SET_VECTOR_ELT (io->rxp, ii, tmprxp); if (vbuf[ii].len > 0) { /* nc_free_vlen fails if length is 0; no need to free anyway */ nc_free_vlen(&(vbuf[ii])); } UNPROTECT(1); } } /* -- Opaque class -- */ /* Convert raw array from R to netcdf opaque type. Memory for the result is allocated if necessary (and freed by R). In special cases, the output may point to the input data, so the output data should not be modified. */ static const char * R_nc_raw_opaque (SEXP rv, int ncid, nc_type xtype, int ndim, const size_t *xdim) { size_t cnt, size; R_nc_check (nc_inq_user_type (ncid, xtype, NULL, &size, NULL, NULL, NULL)); cnt = R_nc_length (ndim, xdim); if ((size_t) xlength (rv) < (cnt * size)) { error (RNC_EDATALEN); } return (const char *) RAW (rv); } static SEXP R_nc_opaque_raw_init (R_nc_buf *io) { int ndim; size_t *xdim, size; /* Fastest varying dimension of R array contains bytes of opaque data */ R_nc_check (nc_inq_user_type (io->ncid, io->xtype, NULL, &size, NULL, NULL, NULL)); ndim = io->ndim; if (ndim < 0) { /* Special case for an R vector without dimension attribute, but dimensions are needed to select opaque elements of a vector */ ndim = 1; } xdim = (size_t *) R_alloc (ndim + 1, sizeof(size_t)); if (ndim != 0) { /* Scalar has no dimensions to copy */ memcpy (xdim, io->xdim, ndim * sizeof(size_t)); } xdim[ndim] = size; io->rxp = PROTECT(R_nc_allocArray (RAWSXP, ndim + 1, xdim)); io->rbuf = RAW (io->rxp); if (!io->cbuf) { io->cbuf = io->rbuf; } UNPROTECT(1); return io->rxp; } static void R_nc_opaque_raw (R_nc_buf *io) { if (io->cbuf != io->rbuf) { memcpy(io->rbuf, io->cbuf, xlength(io->rxp) * sizeof(char)); } return; } /* -- Enum class -- */ /* Convert factor array from R to netcdf enum type. Memory for the result is allocated if necessary (and freed by R). */ static void * R_nc_factor_enum (SEXP rv, int ncid, nc_type xtype, int ndim, const size_t *xdim, size_t fillsize, const void *fill) { SEXP levels; size_t size, imem, nmem, ilev, nlev, *ilev2mem, ifac, nfac, cnt; char *memnames, *memname, *memvals, *memval, *out; const char **levnames; int hasfill, ismatch, *in, inval; /* Extract indices and level names of R factor */ in = INTEGER (rv); levels = getAttrib (rv, R_LevelsSymbol); if (!isString (levels)) { error ("Expected character vector for levels of factor array"); } nlev = xlength (levels); levnames = (const char **) R_alloc (nlev, sizeof(size_t)); for (ilev=0; ilevrxp = PROTECT(R_nc_allocArray (INTSXP, io->ndim, io->xdim)); io->rbuf = INTEGER (io->rxp); if (!io->cbuf) { R_nc_check (nc_inq_type (io->ncid, io->xtype, NULL, &size)); io->cbuf = R_alloc (xlength (io->rxp), size); } UNPROTECT(1); return io->rxp; } /* Convert specified number of bytes to an R symbol, as required to store and retrieve values from a hashed environment. The work array must have minimum size 2*size+2 bytes. */ static SEXP R_nc_char_symbol (char *in, size_t size, char *work) { size_t ii; work[0]='X'; for (ii=0; iicbuf to R factor array in io->rbuf. Memory for the result must be pre-allocated by R_nc_enum_factor_init. */ static void R_nc_enum_factor (R_nc_buf *io) { SEXP levels, env, cmd, symbol, index; size_t size, nmem, ifac, nfac; char *memname, *memval, *work, *inval; int ncid, imem, imemmax, *out, any_undef; nc_type xtype; /* Get size and number of enum members */ ncid = io->ncid; xtype = io->xtype; R_nc_check (nc_inq_enum(ncid, xtype, NULL, NULL, &size, &nmem)); /* Set attributes for R factor */ levels = PROTECT(R_nc_allocArray (STRSXP, -1, &nmem)); setAttrib(io->rxp, R_LevelsSymbol, levels); setAttrib(io->rxp, R_ClassSymbol, mkString("factor")); /* Create a hashed environment for value-index pairs. Members inherit PROTECTion from the env. */ cmd = PROTECT(lang1 (install ("new.env"))); env = PROTECT(eval (cmd, R_BaseEnv)); /* Read values and names of netcdf enum members. Store names as R factor levels. Store values and their R indices (1-based) in hashed environment. */ memname = R_alloc (nmem, NC_MAX_NAME+1); memval = R_alloc (1, size); work = R_alloc (2*size+2, 1); imemmax = nmem; // netcdf member index is int for (imem=0; imemfill != NULL && io->fillsize == size) { symbol = PROTECT (R_nc_char_symbol (io->fill, size, work)); index = PROTECT (ScalarInteger( NA_INTEGER)); defineVar (symbol, index, env); UNPROTECT(2); } /* Convert netcdf enum values to R indices. Use hashed environment prepared above for efficient lookups. */ nfac = xlength (io->rxp); out = io->rbuf; any_undef = 0; for (ifac=0, inval=io->cbuf; ifac 0) { /* Use the first element of this field in fill as the fill value, because fill values are generally required to be scalar; this allows us to convert arrays with a single R_nc_r2c call. */ fillfld = (const char *) fill + offset; fillfldlen = fldsize; } else { fillfld = NULL; fillfldlen = 0; } buffld = R_nc_r2c (PROTECT(VECTOR_ELT (rv, ilist)), ncid, typefld, ndimfld+1, dimsizefld, fillfldlen, fillfld, NULL, NULL); UNPROTECT(1); /* Copy elements from the field array into the compound array */ for (ielem=0; ielemncid) == NC_NOERR) { /* Dataset must be writable because it is now in define mode */ error ("Please read compound type from a read-only dataset"); } /* Get number of fields in compound type */ R_nc_check (nc_inq_compound(io->ncid, io->xtype, NULL, &size, &nfld)); /* Allocate memory for output list */ io->rxp = PROTECT(R_nc_allocArray (VECSXP, -1, &nfld)); /* Allocate memory for compound array */ if (!io->cbuf) { cnt = R_nc_length (io->ndim, io->xdim); io->cbuf = R_alloc (cnt, size); } UNPROTECT(1); return io->rxp; } /* Convert netcdf compound values in io->cbuf to R list of arrays in io->rxp. Data structures are prepared by a prior call to R_nc_compound_vecsxp_init. */ static void R_nc_compound_vecsxp (R_nc_buf *io) { int ncid, ifld, ifldmax, idim, ndim, idimfld, ndimfld, *dimlenfld, ndimslice; int hasfill; nc_type xtype, typefld; size_t size, nfld, cnt, offset, fldsize, *dimslice, fldcnt, fldlen, ielem; size_t fillfldlen; SEXP namelist, rxpfld; char namefld[NC_MAX_NAME+1], *buffld, *bufcmp; R_nc_buf iofld; void *highwater; const char *fillfld; /* Get size and number of fields in compound type */ ncid = io->ncid; xtype = io->xtype; R_nc_check (nc_inq_compound(ncid, xtype, NULL, &size, &nfld)); cnt = R_nc_length (io->ndim, io->xdim); /* Check if fill value is properly defined */ hasfill = (io->fill != NULL && io->fillsize == size); /* Set names attribute of R list */ namelist = PROTECT(R_nc_allocArray (STRSXP, -1, &nfld)); setAttrib(io->rxp, R_NamesSymbol, namelist); /* Convert each field in turn */ bufcmp = io->cbuf; ifldmax = nfld; for (ifld=0; ifldndim; if (ndim < 0) { /* Special case to drop dimensions of a vector, but dimensions are needed for a compound vector. */ ndim = 1; } ndim = io->ndim < 0 ? 1 : io->ndim ; ndimslice = ndim + ndimfld; dimslice = (size_t *) R_alloc (ndimslice, sizeof(size_t)); for (idim=0; idimxdim[idim]; } for (idimfld=0; idimfld 0) { fillfld = (const char *) io->fill + offset; fillfldlen = fldsize; } else { fillfld = NULL; fillfldlen = 0; } buffld = NULL; rxpfld = PROTECT(R_nc_c2r_init (&iofld, (void **) &buffld, ncid, typefld, ndimslice, dimslice, io->rawchar, io->fitnum, fillfldlen, fillfld, NULL, NULL, NULL, NULL)); /* Copy elements from the compound array into the field array */ for (ielem=0; ielemrxp, ifld, rxpfld); /* Allow memory from R_alloc since vmaxget to be reclaimed */ UNPROTECT(1); vmaxset (highwater); } UNPROTECT(1); } /*=============================================================================*\ * Generic type conversions \*=============================================================================*/ const void * R_nc_r2c (SEXP rv, int ncid, nc_type xtype, int ndim, const size_t *xdim, size_t fillsize, const void *fill, const double *scale, const double *add) { int pack, class; pack = (scale || add); if (xtype > NC_MAX_ATOMIC_TYPE) { R_nc_check (nc_inq_user_type (ncid, xtype, NULL, NULL, NULL, NULL, &class)); } switch (TYPEOF(rv)) { case INTSXP: if (pack) { switch (xtype) { case NC_BYTE: return R_nc_r2c_pack_int_schar (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UBYTE: return R_nc_r2c_pack_int_uchar (rv, ndim, xdim, fillsize, fill, scale, add); case NC_SHORT: return R_nc_r2c_pack_int_short (rv, ndim, xdim, fillsize, fill, scale, add); case NC_USHORT: return R_nc_r2c_pack_int_ushort (rv, ndim, xdim, fillsize, fill, scale, add); case NC_INT: return R_nc_r2c_pack_int_int (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UINT: return R_nc_r2c_pack_int_uint (rv, ndim, xdim, fillsize, fill, scale, add); case NC_INT64: return R_nc_r2c_pack_int_ll (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UINT64: return R_nc_r2c_pack_int_ull (rv, ndim, xdim, fillsize, fill, scale, add); case NC_FLOAT: return R_nc_r2c_pack_int_float (rv, ndim, xdim, fillsize, fill, scale, add); case NC_DOUBLE: return R_nc_r2c_pack_int_dbl (rv, ndim, xdim, fillsize, fill, scale, add); } } else { switch (xtype) { case NC_BYTE: return R_nc_r2c_int_schar (rv, ndim, xdim, fillsize, fill); case NC_UBYTE: return R_nc_r2c_int_uchar (rv, ndim, xdim, fillsize, fill); case NC_SHORT: return R_nc_r2c_int_short (rv, ndim, xdim, fillsize, fill); case NC_USHORT: return R_nc_r2c_int_ushort (rv, ndim, xdim, fillsize, fill); case NC_INT: return R_nc_r2c_int_int (rv, ndim, xdim, fillsize, fill); case NC_UINT: return R_nc_r2c_int_uint (rv, ndim, xdim, fillsize, fill); case NC_INT64: return R_nc_r2c_int_ll (rv, ndim, xdim, fillsize, fill); case NC_UINT64: return R_nc_r2c_int_ull (rv, ndim, xdim, fillsize, fill); case NC_FLOAT: return R_nc_r2c_int_float (rv, ndim, xdim, fillsize, fill); case NC_DOUBLE: return R_nc_r2c_int_dbl (rv, ndim, xdim, fillsize, fill); } } if (xtype > NC_MAX_ATOMIC_TYPE && class == NC_ENUM && R_nc_inherits (rv, "factor")) { return R_nc_factor_enum (rv, ncid, xtype, ndim, xdim, fillsize, fill); } break; case REALSXP: if (pack) { if (R_nc_inherits (rv, "integer64")) { switch (xtype) { case NC_BYTE: return R_nc_r2c_pack_bit64_schar (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UBYTE: return R_nc_r2c_pack_bit64_uchar (rv, ndim, xdim, fillsize, fill, scale, add); case NC_SHORT: return R_nc_r2c_pack_bit64_short (rv, ndim, xdim, fillsize, fill, scale, add); case NC_USHORT: return R_nc_r2c_pack_bit64_ushort (rv, ndim, xdim, fillsize, fill, scale, add); case NC_INT: return R_nc_r2c_pack_bit64_int (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UINT: return R_nc_r2c_pack_bit64_uint (rv, ndim, xdim, fillsize, fill, scale, add); case NC_INT64: return R_nc_r2c_pack_bit64_ll (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UINT64: return R_nc_r2c_pack_bit64_ull (rv, ndim, xdim, fillsize, fill, scale, add); case NC_FLOAT: return R_nc_r2c_pack_bit64_float (rv, ndim, xdim, fillsize, fill, scale, add); case NC_DOUBLE: return R_nc_r2c_pack_bit64_dbl (rv, ndim, xdim, fillsize, fill, scale, add); } } else { switch (xtype) { case NC_BYTE: return R_nc_r2c_pack_dbl_schar (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UBYTE: return R_nc_r2c_pack_dbl_uchar (rv, ndim, xdim, fillsize, fill, scale, add); case NC_SHORT: return R_nc_r2c_pack_dbl_short (rv, ndim, xdim, fillsize, fill, scale, add); case NC_USHORT: return R_nc_r2c_pack_dbl_ushort (rv, ndim, xdim, fillsize, fill, scale, add); case NC_INT: return R_nc_r2c_pack_dbl_int (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UINT: return R_nc_r2c_pack_dbl_uint (rv, ndim, xdim, fillsize, fill, scale, add); case NC_INT64: return R_nc_r2c_pack_dbl_ll (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UINT64: return R_nc_r2c_pack_dbl_ull (rv, ndim, xdim, fillsize, fill, scale, add); case NC_FLOAT: return R_nc_r2c_pack_dbl_float (rv, ndim, xdim, fillsize, fill, scale, add); case NC_DOUBLE: return R_nc_r2c_pack_dbl_dbl (rv, ndim, xdim, fillsize, fill, scale, add); } } } else { if (R_nc_inherits (rv, "integer64")) { switch (xtype) { case NC_BYTE: return R_nc_r2c_bit64_schar (rv, ndim, xdim, fillsize, fill); case NC_UBYTE: return R_nc_r2c_bit64_uchar (rv, ndim, xdim, fillsize, fill); case NC_SHORT: return R_nc_r2c_bit64_short (rv, ndim, xdim, fillsize, fill); case NC_USHORT: return R_nc_r2c_bit64_ushort (rv, ndim, xdim, fillsize, fill); case NC_INT: return R_nc_r2c_bit64_int (rv, ndim, xdim, fillsize, fill); case NC_UINT: return R_nc_r2c_bit64_uint (rv, ndim, xdim, fillsize, fill); case NC_INT64: return R_nc_r2c_bit64_ll (rv, ndim, xdim, fillsize, fill); case NC_UINT64: return R_nc_r2c_bit64_ull (rv, ndim, xdim, fillsize, fill); case NC_FLOAT: return R_nc_r2c_bit64_float (rv, ndim, xdim, fillsize, fill); case NC_DOUBLE: return R_nc_r2c_bit64_dbl (rv, ndim, xdim, fillsize, fill); } } else { switch (xtype) { case NC_BYTE: return R_nc_r2c_dbl_schar (rv, ndim, xdim, fillsize, fill); case NC_UBYTE: return R_nc_r2c_dbl_uchar (rv, ndim, xdim, fillsize, fill); case NC_SHORT: return R_nc_r2c_dbl_short (rv, ndim, xdim, fillsize, fill); case NC_USHORT: return R_nc_r2c_dbl_ushort (rv, ndim, xdim, fillsize, fill); case NC_INT: return R_nc_r2c_dbl_int (rv, ndim, xdim, fillsize, fill); case NC_UINT: return R_nc_r2c_dbl_uint (rv, ndim, xdim, fillsize, fill); case NC_INT64: return R_nc_r2c_dbl_ll (rv, ndim, xdim, fillsize, fill); case NC_UINT64: return R_nc_r2c_dbl_ull (rv, ndim, xdim, fillsize, fill); case NC_FLOAT: return R_nc_r2c_dbl_float (rv, ndim, xdim, fillsize, fill); case NC_DOUBLE: return R_nc_r2c_dbl_dbl (rv, ndim, xdim, fillsize, fill); } } } break; case STRSXP: switch (xtype) { case NC_CHAR: return R_nc_strsxp_char (rv, ndim, xdim, fillsize, fill); case NC_STRING: return R_nc_strsxp_str (rv, ndim, xdim, fillsize, fill); } break; case RAWSXP: if (xtype == NC_CHAR) { return R_nc_raw_char (rv, ndim, xdim); } else if (xtype > NC_MAX_ATOMIC_TYPE && class == NC_OPAQUE) { return R_nc_raw_opaque (rv, ncid, xtype, ndim, xdim); } break; case VECSXP: if (xtype > NC_MAX_ATOMIC_TYPE) { switch (class) { case NC_VLEN: return R_nc_vecsxp_vlen (rv, ncid, xtype, ndim, xdim, fillsize, fill, scale, add); case NC_COMPOUND: return R_nc_vecsxp_compound (rv, ncid, xtype, ndim, xdim, fillsize, fill); } } break; } error (RNC_EDATATYPE); } SEXP \ R_nc_c2r_init (R_nc_buf *io, void **cbuf, int ncid, nc_type xtype, int ndim, const size_t *xdim, int rawchar, int fitnum, size_t fillsize, const void *fill, const void *min, const void *max, const double *scale, const double *add) { int class; if (!io) { error ("Pointer to R_nc_buf must not be NULL in R_nc_c2r_init"); } /* Initialise the R_nc_buf, making copies of pointer arguments */ io->rxp = NULL; io->cbuf = NULL; io->rbuf = NULL; io->xtype = xtype; io->ncid = ncid; io->ndim = ndim; io->rawchar = rawchar; io->fitnum = fitnum; io->xdim = NULL; io->fillsize = fillsize; io->fill = NULL; io->min = NULL; io->max = NULL; io->scale = NULL; io->add = NULL; if (cbuf) { io->cbuf = *cbuf; } if (xdim) { if (ndim > 0) { io->xdim = (size_t *) R_alloc (ndim, sizeof(size_t)); memcpy (io->xdim, xdim, ndim*sizeof(size_t)); } else if (ndim < 0) { /* Special case for vector without dim attribute */ io->xdim = (size_t *) R_alloc (1, sizeof(size_t)); memcpy (io->xdim, xdim, sizeof(size_t)); } /* Scalar has no dimensions */ } if (fill) { io->fill = R_alloc (1, fillsize); memcpy (io->fill, fill, fillsize); } if (min) { io->min = R_alloc (1, fillsize); memcpy (io->min, min, fillsize); } if (max) { io->max = R_alloc (1, fillsize); memcpy (io->max, max, fillsize); } if (scale) { io->scale = (double *) R_alloc (1, sizeof(double)); *(io->scale) = *scale; } if (add) { io->add = (double *) R_alloc (1, sizeof(double)); *(io->add) = *add; } /* Prepare buffers */ switch (xtype) { case NC_BYTE: case NC_UBYTE: case NC_SHORT: case NC_USHORT: case NC_INT: if (fitnum && !scale && !add) { PROTECT(R_nc_c2r_int_init (io)); break; } case NC_INT64: case NC_UINT64: if (fitnum && !scale && !add) { PROTECT(R_nc_c2r_bit64_init (io)); classgets(io->rxp, mkString("integer64")); break; } case NC_UINT: case NC_FLOAT: case NC_DOUBLE: PROTECT(R_nc_c2r_dbl_init (io)); break; case NC_CHAR: if (rawchar) { PROTECT(R_nc_char_raw_init (io)); } else { PROTECT(R_nc_char_strsxp_init (io)); } break; case NC_STRING: PROTECT(R_nc_str_strsxp_init (io)); break; default: if (xtype > NC_MAX_ATOMIC_TYPE) { R_nc_check (nc_inq_user_type (ncid, xtype, NULL, NULL, NULL, NULL, &class)); switch (class) { case NC_COMPOUND: PROTECT(R_nc_compound_vecsxp_init (io)); break; case NC_ENUM: PROTECT(R_nc_enum_factor_init (io)); break; case NC_VLEN: PROTECT(R_nc_vlen_vecsxp_init (io)); break; case NC_OPAQUE: PROTECT(R_nc_opaque_raw_init (io)); break; default: error (RNC_ETYPEDROP); } } else { error (RNC_ETYPEDROP); } } if (cbuf) { *cbuf = io->cbuf; } UNPROTECT(1); return io->rxp; } void R_nc_c2r (R_nc_buf *io) { int unpack, class; unpack = (io->scale || io->add); /* Type conversions */ switch (io->xtype) { case NC_BYTE: if (unpack) { R_nc_c2r_unpack_schar (io); } else if (io->fitnum) { R_nc_c2r_schar_int (io); } else { R_nc_c2r_schar_dbl (io); } break; case NC_UBYTE: if (unpack) { R_nc_c2r_unpack_uchar (io); } else if (io->fitnum) { R_nc_c2r_uchar_int (io); } else { R_nc_c2r_uchar_dbl (io); } break; case NC_SHORT: if (unpack) { R_nc_c2r_unpack_short (io); } else if (io->fitnum) { R_nc_c2r_short_int (io); } else { R_nc_c2r_short_dbl (io); } break; case NC_USHORT: if (unpack) { R_nc_c2r_unpack_ushort (io); } else if (io->fitnum) { R_nc_c2r_ushort_int (io); } else { R_nc_c2r_ushort_dbl (io); } break; case NC_INT: if (unpack) { R_nc_c2r_unpack_int (io); } else if (io->fitnum) { R_nc_c2r_int_int (io); } else { R_nc_c2r_int_dbl (io); } break; case NC_UINT: if (unpack) { R_nc_c2r_unpack_uint (io); } else { R_nc_c2r_uint_dbl (io); } break; case NC_FLOAT: if (unpack) { R_nc_c2r_unpack_float (io); } else { R_nc_c2r_float_dbl (io); } break; case NC_DOUBLE: if (unpack) { R_nc_c2r_unpack_dbl (io); } else { R_nc_c2r_dbl_dbl (io); } break; case NC_INT64: if (unpack) { R_nc_c2r_unpack_int64 (io); } else if (io->fitnum) { R_nc_c2r_int64_bit64 (io); } else { R_nc_c2r_int64_dbl (io); } break; case NC_UINT64: if (unpack) { R_nc_c2r_unpack_uint64 (io); } else if (io->fitnum) { R_nc_c2r_uint64_bit64 (io); } else { R_nc_c2r_uint64_dbl (io); } break; case NC_CHAR: if (io->rawchar) { R_nc_char_raw (io); } else { R_nc_char_strsxp (io); } break; case NC_STRING: R_nc_str_strsxp (io); break; default: if (io->xtype > NC_MAX_ATOMIC_TYPE) { R_nc_check (nc_inq_user_type ( io->ncid, io->xtype, NULL, NULL, NULL, NULL, &class)); switch (class) { case NC_COMPOUND: R_nc_compound_vecsxp (io); break; case NC_ENUM: R_nc_enum_factor (io); break; case NC_VLEN: R_nc_vlen_vecsxp (io); break; case NC_OPAQUE: R_nc_opaque_raw (io); break; default: error (RNC_ETYPEDROP); } } else { error (RNC_ETYPEDROP); } } } /*=============================================================================*\ * Dimension conversions \*=============================================================================*/ /* Reverse a vector in-place. Example: R_nc_rev_int (cv, cnt); */ void R_nc_rev_int (int *data, size_t cnt) { size_t ii, jj; int tmp; if (cnt<=0) return; for (ii=0, jj=cnt-1; ii #include #include #include #include #include #include #include #include #include "common.h" #include "RNetCDF.h" #if defined HAVE_NETCDF_MPI #include #include #endif /* Convert netcdf file format code to string label. */ static const char * R_nc_format2str (int format) { switch (format) { case NC_FORMAT_CLASSIC: return "classic"; #ifdef NC_FORMAT_64BIT case NC_FORMAT_64BIT: return "offset64"; #elif defined NC_FORMAT_64BIT_OFFSET case NC_FORMAT_64BIT_OFFSET: return "offset64"; #endif #ifdef NC_FORMAT_64BIT_DATA case NC_FORMAT_64BIT_DATA: return "data64"; #endif case NC_FORMAT_NETCDF4: return "netcdf4"; case NC_FORMAT_NETCDF4_CLASSIC: return "classic4"; default: return "unknown"; } } /*-----------------------------------------------------------------------------*\ * R_nc_close() \*-----------------------------------------------------------------------------*/ SEXP R_nc_close (SEXP ptr) { int *fileid; if (TYPEOF (ptr) != EXTPTRSXP) { error ("Not a valid NetCDF object"); } fileid = R_ExternalPtrAddr (ptr); if (!fileid) { return R_NilValue; } R_nc_check (nc_close (*fileid)); R_Free (fileid); R_ClearExternalPtr (ptr); return R_NilValue; } /* Private function used as finalizer during garbage collection. It is required to have no return value. */ static void R_nc_finalizer (SEXP ptr) { R_nc_close (ptr); } /*-----------------------------------------------------------------------------*\ * R_nc_create() \*-----------------------------------------------------------------------------*/ SEXP R_nc_create (SEXP filename, SEXP clobber, SEXP share, SEXP prefill, SEXP format, SEXP diskless, SEXP persist, SEXP mpi_comm, SEXP mpi_info) { int cmode, fillmode, old_fillmode, ncid, *fileid, icommf; SEXP Rptr, result; const char *filep; #ifdef HAVE_NETCDF_MPI int iinfof; #endif /*-- Determine the cmode ----------------------------------------------------*/ if (asLogical(clobber) == TRUE) { cmode = NC_CLOBBER; } else { cmode = NC_NOCLOBBER; } #if defined NC_DISKLESS && defined NC_PERSIST if (asLogical(diskless) == TRUE) { cmode = cmode | NC_DISKLESS; } if (asLogical(persist) == TRUE) { cmode = cmode | NC_PERSIST; } #else if (asLogical(diskless) == TRUE) { error("NetCDF library does not support diskless files"); } #endif /*-- Determine which buffer scheme shall be used ----------------------------*/ if (asLogical(share) == TRUE) { cmode = cmode | NC_SHARE; } /*-- Determine the fillmode -------------------------------------------------*/ if (asLogical(prefill) == TRUE) { fillmode = NC_FILL; } else { fillmode = NC_NOFILL; } /*-- Set file format (default is netcdf classic) ----------------------------*/ if (R_nc_strcmp(format, "netcdf4")) { cmode = cmode | NC_NETCDF4; } else if (R_nc_strcmp(format, "classic4")) { cmode = cmode | NC_NETCDF4 | NC_CLASSIC_MODEL; } else if (R_nc_strcmp(format, "offset64")) { cmode = cmode | NC_64BIT_OFFSET; } else if (R_nc_strcmp(format, "data64")) { #ifdef NC_64BIT_DATA cmode = cmode | NC_64BIT_DATA; #else error("NetCDF library does not support data64 format"); #endif } /*-- Create the file --------------------------------------------------------*/ filep = R_nc_strarg (filename); if (strlen (filep) > 0) { icommf = asInteger(mpi_comm); if (icommf == NA_INTEGER) { R_nc_check (nc_create (R_ExpandFileName (filep), cmode, &ncid)); } else { #ifdef HAVE_NETCDF_MPI iinfof = asInteger(mpi_info); if (iinfof == NA_INTEGER) { iinfof = MPI_Info_c2f(MPI_INFO_NULL); } R_nc_check (nc_create_par_fortran (R_ExpandFileName (filep), cmode, icommf, iinfof, &ncid)); #else error("MPI not supported"); #endif } } else { error ("Filename must be a non-empty string"); } result = PROTECT(ScalarInteger (ncid)); /*-- Arrange for file to be closed if handle is garbage collected -----------*/ fileid = R_Calloc (1, int); *fileid = ncid; Rptr = PROTECT(R_MakeExternalPtr (fileid, R_NilValue, R_NilValue)); R_RegisterCFinalizerEx (Rptr, &R_nc_finalizer, TRUE); setAttrib (result, install ("handle_ptr"), Rptr); /*-- Set the fill mode ------------------------------------------------------*/ R_nc_check (nc_set_fill (ncid, fillmode, &old_fillmode)); UNPROTECT(2); return result; } /*-----------------------------------------------------------------------------*\ * R_nc_inq_file() \*-----------------------------------------------------------------------------*/ SEXP R_nc_inq_file (SEXP nc) { int ncid, ndims, nvars, ngatts, unlimdimid, format; const char *libvers; SEXP result; /*-- Convert arguments to netcdf ids ----------------------------------------*/ ncid = asInteger (nc); /*-- Inquire about the NetCDF dataset ---------------------------------------*/ R_nc_check (nc_inq (ncid, &ndims, &nvars, &ngatts, &unlimdimid)); if (unlimdimid == -1 ) { unlimdimid = NA_INTEGER; } /*-- Inquire about the NetCDF format and library version --------------------*/ R_nc_check (nc_inq_format (ncid, &format)); libvers = nc_inq_libvers (); /*-- Returning the list -----------------------------------------------------*/ result = PROTECT(allocVector (VECSXP, 6)); SET_VECTOR_ELT (result, 0, PROTECT(ScalarInteger (ndims))); SET_VECTOR_ELT (result, 1, PROTECT(ScalarInteger (nvars))); SET_VECTOR_ELT (result, 2, PROTECT(ScalarInteger (ngatts))); SET_VECTOR_ELT (result, 3, PROTECT(ScalarInteger (unlimdimid))); SET_VECTOR_ELT (result, 4, PROTECT(mkString (R_nc_format2str (format)))); SET_VECTOR_ELT (result, 5, PROTECT(mkString (libvers))); UNPROTECT(7); return result; } /*-----------------------------------------------------------------------------*\ * R_nc_open() \*-----------------------------------------------------------------------------*/ SEXP R_nc_open (SEXP filename, SEXP write, SEXP share, SEXP prefill, SEXP diskless, SEXP persist, SEXP mpi_comm, SEXP mpi_info) { int ncid, omode, fillmode, old_fillmode, *fileid, icommf; const char *filep; SEXP Rptr, result; #ifdef HAVE_NETCDF_MPI int iinfof; #endif /*-- Determine the omode ----------------------------------------------------*/ if (asLogical(write) == TRUE) { omode = NC_WRITE; } else { omode = NC_NOWRITE; } #if defined NC_DISKLESS && defined NC_PERSIST if (asLogical(diskless) == TRUE) { omode = omode | NC_DISKLESS; } if (asLogical(persist) == TRUE) { omode = omode | NC_PERSIST; } #else if (asLogical(diskless) == TRUE) { error("NetCDF library does not support diskless files"); } #endif if (asLogical(share) == TRUE) { omode = omode | NC_SHARE; } /*-- Determine the fillmode -------------------------------------------------*/ if (asLogical(prefill) == TRUE) { fillmode = NC_FILL; } else { fillmode = NC_NOFILL; } /*-- Open the file ----------------------------------------------------------*/ filep = R_nc_strarg (filename); if (strlen (filep) > 0) { icommf = asInteger(mpi_comm); if (icommf == NA_INTEGER) { R_nc_check (nc_open (R_ExpandFileName (filep), omode, &ncid)); } else { #ifdef HAVE_NETCDF_MPI iinfof = asInteger(mpi_info); if (iinfof == NA_INTEGER) { iinfof = MPI_Info_c2f(MPI_INFO_NULL); } R_nc_check (nc_open_par_fortran (R_ExpandFileName (filep), omode, icommf, iinfof, &ncid)); #else error("MPI not supported"); #endif } } else { error ("Filename must be a non-empty string"); } result = PROTECT(ScalarInteger (ncid)); /*-- Arrange for file to be closed if handle is garbage collected -----------*/ fileid = R_Calloc (1, int); *fileid = ncid; Rptr = PROTECT(R_MakeExternalPtr (fileid, R_NilValue, R_NilValue)); R_RegisterCFinalizerEx (Rptr, &R_nc_finalizer, TRUE); setAttrib (result, install ("handle_ptr"), Rptr); /*-- Set the fill mode ------------------------------------------------------*/ if (asLogical(write) == TRUE) { R_nc_check (nc_set_fill (ncid, fillmode, &old_fillmode)); } UNPROTECT(2); return result; } /*-----------------------------------------------------------------------------*\ * R_nc_sync() \*-----------------------------------------------------------------------------*/ SEXP R_nc_sync (SEXP nc) { int ncid; /*-- Enter data mode (if necessary) -----------------------------------------*/ ncid = asInteger(nc); R_nc_check( R_nc_enddef (ncid)); /*-- Sync the file ----------------------------------------------------------*/ R_nc_check (nc_sync (ncid)); return R_NilValue; } RNetCDF/src/group.c0000644000176200001440000001343714577720574013560 0ustar liggesusers/*=============================================================================*\ * * Name: group.c * * Version: 2.9-2 * * Purpose: NetCDF group functions for RNetCDF. * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright (C) 2004-2024 Pavel Michna and Milton Woods. * *=============================================================================* * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *=============================================================================* */ #include #include #include #include #include #include #include #include #include #include "common.h" #include "RNetCDF.h" /*-----------------------------------------------------------------------------*\ * R_nc_def_grp() \*-----------------------------------------------------------------------------*/ SEXP R_nc_def_grp (SEXP nc, SEXP grpname) { int ncid, grpid; const char *cgrpname; /* Convert arguments to netcdf ids */ ncid = asInteger (nc); cgrpname = R_nc_strarg (grpname); /* Enter define mode */ R_nc_check( R_nc_redef (ncid)); /* Define the group */ R_nc_check (nc_def_grp (ncid, cgrpname, &grpid)); return ScalarInteger (grpid); } /*-----------------------------------------------------------------------------*\ * R_nc_inq_grp_parent() \*-----------------------------------------------------------------------------*/ SEXP R_nc_inq_grp_parent (SEXP nc) { int ncid, grpid; /* Get parent group */ ncid = asInteger (nc); R_nc_check (nc_inq_grp_parent (ncid, &grpid)); return ScalarInteger (grpid); } /*-----------------------------------------------------------------------------*\ * R_nc_inq_natts() \*-----------------------------------------------------------------------------*/ SEXP R_nc_inq_natts (SEXP nc) { int ncid, natts; /* Get number of attributes in group */ ncid = asInteger (nc); R_nc_check (nc_inq_natts (ncid, &natts)); return ScalarInteger (natts); } /*-----------------------------------------------------------------------------*\ * R_nc_inq_grpname() \*-----------------------------------------------------------------------------*/ SEXP R_nc_inq_grpname (SEXP nc, SEXP full) { int ncid; size_t namelen; char *name, *fullname, namebuf[NC_MAX_NAME+1]; ncid = asInteger (nc); if (asLogical (full) == TRUE) { R_nc_check (nc_inq_grpname_full (ncid, &namelen, NULL)); fullname = R_alloc (namelen + 1, sizeof (char)); R_nc_check (nc_inq_grpname_full (ncid, NULL, fullname)); name = fullname; } else { R_nc_check (nc_inq_grpname (ncid, namebuf)); name = namebuf; } return mkString (name); } /*-----------------------------------------------------------------------------*\ * R_nc_inq_grp_ncid() \*-----------------------------------------------------------------------------*/ SEXP R_nc_inq_grp_ncid (SEXP nc, SEXP grpname, SEXP full) { int ncid, grpid; const char *cgrpname; ncid = asInteger (nc); cgrpname = R_nc_strarg (grpname); if (asLogical (full) == TRUE) { R_nc_check (nc_inq_grp_full_ncid (ncid, cgrpname, &grpid)); } else { R_nc_check (nc_inq_grp_ncid (ncid, cgrpname, &grpid)); } return ScalarInteger (grpid); } /*-----------------------------------------------------------------------------*\ * Get lists of ncids for components of a group \*-----------------------------------------------------------------------------*/ /* Template function returning a list of ncids for a group */ #define INQGRPIDS(RFUN, NCFUN) \ SEXP RFUN (SEXP nc) \ { \ int ncid, count; \ SEXP result; \ ncid = asInteger (nc); \ R_nc_check(NCFUN(ncid, &count, NULL)); \ result = PROTECT(allocVector (INTSXP, count)); \ R_nc_check(NCFUN(ncid, NULL, INTEGER(result))); \ UNPROTECT(1); \ return result; \ } INQGRPIDS (R_nc_inq_grps, nc_inq_grps) INQGRPIDS (R_nc_inq_typeids, nc_inq_typeids) INQGRPIDS (R_nc_inq_varids, nc_inq_varids) /*-----------------------------------------------------------------------------*\ * R_nc_inq_dimids() \*-----------------------------------------------------------------------------*/ SEXP R_nc_inq_dimids (SEXP nc, SEXP ancestors) { int ncid, full, count; SEXP result; ncid = asInteger (nc); full = (asLogical (ancestors) == TRUE); R_nc_check (nc_inq_dimids (ncid, &count, NULL, full)); result = PROTECT(allocVector (INTSXP, count)); R_nc_check (nc_inq_dimids (ncid, NULL, INTEGER (result), full)); UNPROTECT(1); return result; } /*-----------------------------------------------------------------------------*\ * R_nc_rename_grp() \*-----------------------------------------------------------------------------*/ SEXP R_nc_rename_grp (SEXP nc, SEXP grpname) { #ifdef HAVE_NC_RENAME_GRP int ncid; const char *cgrpname; ncid = asInteger (nc); cgrpname = R_nc_strarg (grpname); /* Enter define mode */ R_nc_check( R_nc_redef (ncid)); /* Rename the group */ R_nc_check (nc_rename_grp (ncid, cgrpname)); return R_NilValue; #else error ("nc_rename_grp not supported by netcdf library"); #endif } RNetCDF/src/common.c0000644000176200001440000001513014577720574013704 0ustar liggesusers/*=============================================================================*\ * * Name: common.c * * Version: 2.9-2 * * Purpose: Common definitions for RNetCDF functions * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright (C) 2004-2024 Pavel Michna and Milton Woods. * *=============================================================================* * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *=============================================================================* */ #include #include #include #include #include "common.h" int R_nc_check(int status) { if (status != NC_NOERR) { error ("%s", nc_strerror (status)); } return status; } int R_nc_strcmp (SEXP var, const char *str) { return (isString(var) && xlength(var) >= 1 && strcmp(CHAR (STRING_ELT (var, 0)), str) == 0); } size_t R_nc_strnlen (const char *str, char chr, size_t maxlen) { char *nullchr; nullchr = memchr(str, (int) chr, maxlen); return (nullchr == NULL) ? maxlen : ((size_t) (nullchr - str)); } int R_nc_inherits (SEXP var, const char *class) { SEXP classes; size_t ii, cnt; classes = getAttrib (var, R_ClassSymbol); if (isString (classes)) { cnt = xlength (classes); for (ii=0; ii= 6) { switch (str[3]) { case 'B': if (strcmp (str, "NC_BYTE") == 0) { *xtype = NC_BYTE; } break; case 'C': if (strcmp (str, "NC_CHAR") == 0) { *xtype = NC_CHAR; } break; case 'D': if (strcmp (str, "NC_DOUBLE") == 0) { *xtype = NC_DOUBLE; } break; case 'F': if (strcmp (str, "NC_FLOAT") == 0) { *xtype = NC_FLOAT; } break; case 'I': switch (str[6]) { case '\0': if (strcmp (str, "NC_INT") == 0) { *xtype = NC_INT; } break; case '6': if (strcmp (str, "NC_INT64") == 0) { *xtype = NC_INT64; } break; } break; case 'L': if (strcmp (str, "NC_LONG") == 0) { *xtype = NC_LONG; } break; case 'S': switch (str[4]) { case 'H': if (strcmp (str, "NC_SHORT") == 0) { *xtype = NC_SHORT; } break; case 'T': if (strcmp (str, "NC_STRING") == 0) { *xtype = NC_STRING; } break; } break; case 'U': if (typelen >= 7) { switch (str[7]) { case '\0': if (strcmp (str, "NC_UINT") == 0) { *xtype = NC_UINT; } break; case '6': if (strcmp (str, "NC_UINT64") == 0) { *xtype = NC_UINT64; } break; case 'E': if (strcmp (str, "NC_UBYTE") == 0) { *xtype = NC_UBYTE; } break; case 'R': if (strcmp (str, "NC_USHORT") == 0) { *xtype = NC_USHORT; } break; } } break; } } if (*xtype == NC_NAT) { /* Try to get id of a user defined type */ return nc_inq_typeid (ncid, str, xtype); } else { return NC_NOERR; } } const char * R_nc_strarg (SEXP str) { if (xlength (str) > 0 && isString (str)) { return CHAR (STRING_ELT (str, 0)); } else { error ("Expected character string as argument"); } } int R_nc_redef (int ncid) { int status; status = nc_redef(ncid); if (status == NC_EINDEFINE) { status = NC_NOERR; } return status; } int R_nc_enddef (int ncid) { nc_enddef(ncid); return NC_NOERR; } RNetCDF/src/Makefile0000644000176200001440000000126514577720720013705 0ustar liggesusers## Makefile for RNetCDF. # Although Makevars is the recommended way to compile R packages, # it forces use of the C compiler (CC) defined during R installation. # This Makefile allows users to specify an MPI compiler wrapper which: # - sets include and library paths; # - links MPI libraries, whose names may vary with compiler flags and vendors; # - is the most common and reliable method to build software with MPI. # Updates to the Makefile may be required if the R build system changes. # Default for non-Windows: WINDOWS = FALSE all: WINDOWS="$(WINDOWS)" \ MAKE="$(MAKE)" \ R_HOME="$(R_HOME)" \ R_ARCH="$(R_ARCH)" \ $(SHELL) ../tools/make-recursive.sh RNetCDF/src/variable.c0000644000176200001440000010034214577720574014201 0ustar liggesusers/*=============================================================================*\ * * Name: variable.c * * Version: 2.9-2 * * Purpose: NetCDF variable functions for RNetCDF * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright (C) 2004-2024 Pavel Michna and Milton Woods. * *=============================================================================* * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *=============================================================================* */ #include #include #include #include #include #include #include #include #include #include "common.h" #include "convert.h" #include "RNetCDF.h" #ifdef HAVE_NETCDF_MPI #include #endif #ifdef HAVE_NETCDF_FILTER_H #include #endif #if defined HAVE_NC_DEF_VAR_FILTER && \ defined HAVE_NC_INQ_VAR_FILTER_IDS && \ defined HAVE_NC_INQ_VAR_FILTER_INFO #define HAVE_NC_MULTI_FILTER #endif /*-----------------------------------------------------------------------------*\ * R_nc_def_var() \*-----------------------------------------------------------------------------*/ SEXP R_nc_def_var (SEXP nc, SEXP varname, SEXP type, SEXP dims, SEXP chunking, SEXP chunksizes, SEXP deflate, SEXP shuffle, SEXP big_endian, SEXP fletcher32, SEXP filter_id, SEXP filter_params) { int ncid, ii, jj, *dimids, ndims, varid, chunkmode, format, withnc4; int deflate_mode, deflate_level, shuffle_mode, fletcher_mode; size_t *chunksize_t; nc_type xtype; const char *varnamep; #ifdef HAVE_NC_INQ_VAR_ENDIAN int endian_mode; #endif #ifdef HAVE_NC_MULTI_FILTER unsigned int *ufiltid, *ufiltparm; size_t ifilter, nfilter, nfiltparm; SEXP rfiltparm; #endif /*-- Convert arguments to netcdf ids ----------------------------------------*/ ncid = asInteger (nc); varnamep = R_nc_strarg (varname); R_nc_check (R_nc_type_id (type, ncid, &xtype, 0)); ndims = length(dims); dimids = (void *) R_alloc (ndims, sizeof(int)); for (ii=0, jj=ndims-1; ii 0) { /* Convert filter_id to unsigned int; memory is allocated by R_alloc and automatically freed. */ ufiltid = (unsigned int *) R_nc_r2c ( filter_id, ncid, NC_UINT, 1, &nfilter, 0, NULL, NULL, NULL); for (ifilter=0; ifilter (TYPE) 0) { \ *max = R_alloc (1, sizeof(TYPE)); \ **(TYPE **) max = **(TYPE **) fill * ((TYPE) 1 - (TYPE) 2 * (TYPE) EPS); \ } else { \ *min = R_alloc (1, sizeof(TYPE)); \ **(TYPE **) min = **(TYPE **) fill * ((TYPE) 1 + (TYPE) 2 * (TYPE) EPS); \ } \ } \ } #define FILL2RANGE_INT(TYPE) { \ if (**(TYPE **) fill > (TYPE) 0) { \ *max = R_alloc (1, sizeof(TYPE)); \ **(TYPE **) max = **(TYPE **) fill - (TYPE) 1; \ } else { \ *min = R_alloc (1, sizeof(TYPE)); \ **(TYPE **) min = **(TYPE **) fill + (TYPE) 1; \ }; \ } /* Find attributes related to missing values for a netcdf variable. On exit, relevant parameters are returned via double pointers to fill, min and max, which are either NULL or allocated by R_alloc. The function returns the in-memory size (bytes) of a missing value. Argument mode specifies the attributes used for missing values: 0 - (numeric types) _FillValue, or missing_value 1 - (numeric types) _FillValue only 2 - (numeric types) missing_value only 3 - (all types) none 4 - (numeric types) fill value and valid range determined as described at http://www.unidata.ucar.edu/software/netcdf/docs/attribute_conventions.html 5 - (all types) mode 4 for numeric types; _FillValue for other types Example: R_nc_miss_att (ncid, varid, mode, &fill, &min, &max); */ static size_t R_nc_miss_att (int ncid, int varid, int mode, void **fill, void **min, void **max) { size_t cnt, size; nc_type atype, xtype; char *range; *fill = NULL; *min = NULL; *max = NULL; /* Get details about type and size of netcdf variable */ R_nc_check (nc_inq_vartype (ncid, varid, &xtype)); R_nc_check (nc_inq_type (ncid, xtype, NULL, &size)); if (mode == 5) { /* Mode 5 is equivalent to mode 4 for numeric types and mode 1 for non-numeric types */ if (xtype == NC_CHAR || xtype == NC_STRING || xtype > NC_MAX_ATOMIC_TYPE) { mode = 1; } else { mode = 4; } } else { /* For other modes, let users handle missing values in non-numeric types */ if (xtype == NC_CHAR || xtype == NC_STRING || xtype > NC_MAX_ATOMIC_TYPE) { return 0; } } if (mode == 0 || mode == 1) { if (nc_inq_att (ncid, varid, "_FillValue", &atype, &cnt) == NC_NOERR && cnt == 1 && atype == xtype) { *fill = R_alloc (1, size); R_nc_check (nc_get_att (ncid, varid, "_FillValue", *fill)); } } else if (mode == 0 || mode == 2) { if (nc_inq_att (ncid, varid, "missing_value", &atype, &cnt) == NC_NOERR && cnt == 1 && atype == xtype) { *fill = R_alloc (1, size); R_nc_check (nc_get_att (ncid, varid, "missing_value", *fill)); } } else if (mode == 3) { /* Let user code handle missing values */ return 0; } else if (mode == 4) { /* Special rules apply to byte data */ if ((xtype == NC_BYTE) || (xtype == NC_UBYTE)) { /* For byte data, valid_range, valid_min and valid_max attributes * may differ from the type of variable, so we read the attributes * with routines that convert to the expected type. */ if (nc_inq_att (ncid, varid, "valid_min", &atype, &cnt) == NC_NOERR && cnt == 1) { *min = R_alloc (1, 1); if (xtype == NC_UBYTE) { R_nc_check (nc_get_att_uchar (ncid, varid, "valid_min", *min)); } else { R_nc_check (nc_get_att_schar (ncid, varid, "valid_min", *min)); } } if (nc_inq_att (ncid, varid, "valid_max", &atype, &cnt) == NC_NOERR && cnt == 1) { *max = R_alloc (1, 1); if (xtype == NC_UBYTE) { R_nc_check (nc_get_att_uchar (ncid, varid, "valid_max", *max)); } else { R_nc_check (nc_get_att_schar (ncid, varid, "valid_max", *max)); } } if (!*min && !*max && nc_inq_att (ncid, varid, "valid_range", &atype, &cnt) == NC_NOERR && cnt == 2) { range = R_alloc (2, 1); *min = range; *max = range + 1; if (xtype == NC_UBYTE) { R_nc_check (nc_get_att_uchar ( ncid, varid, "valid_range", (unsigned char *) range)); } else { R_nc_check (nc_get_att_schar ( ncid, varid, "valid_range", (signed char *) range)); } } /* Only set fill value if explicitly defined. * _FillValue attribute should have same type as variable. */ if (nc_inq_att (ncid, varid, "_FillValue", &atype, &cnt) == NC_NOERR && cnt == 1 && atype == xtype) { *fill = R_alloc (1, 1); R_nc_check (nc_get_att (ncid, varid, "_FillValue", *fill)); } /* If _FillValue is defined without a valid range, * set the valid range to exclude _FillValue */ if (*fill && !*max && !*min) { if (xtype == NC_UBYTE) { FILL2RANGE_INT(unsigned char) } else { FILL2RANGE_INT(signed char) } } /* If a valid range is defined without a fill value, * use the default fill value if it is outside the valid range */ if (!*fill && *max) { if (xtype == NC_UBYTE) { if (NC_FILL_UBYTE > **(unsigned char **) max) { *fill = R_alloc(1, 1); **(unsigned char **) fill = NC_FILL_UBYTE; } } else { if (NC_FILL_BYTE > **(signed char **) max) { *fill = R_alloc(1, 1); **(signed char **) fill = NC_FILL_BYTE; } } } if (!*fill && *min) { if (xtype == NC_UBYTE) { if (NC_FILL_UBYTE < **(unsigned char **) min) { *fill = R_alloc(1, 1); **(unsigned char **) fill = NC_FILL_UBYTE; } } else { if (NC_FILL_BYTE < **(signed char **) min) { *fill = R_alloc(1, 1); **(signed char **) fill = NC_FILL_BYTE; } } } } else { /* All types other than byte data */ /* Type of valid_* attribute must match type of variable data */ if (nc_inq_att (ncid, varid, "valid_min", &atype, &cnt) == NC_NOERR && cnt == 1 && atype == xtype) { *min = R_alloc (1, size); R_nc_check (nc_get_att (ncid, varid, "valid_min", *min)); } if (nc_inq_att (ncid, varid, "valid_max", &atype, &cnt) == NC_NOERR && cnt == 1 && atype == xtype) { *max = R_alloc (1, size); R_nc_check (nc_get_att (ncid, varid, "valid_max", *max)); } if (!*min && !*max && nc_inq_att (ncid, varid, "valid_range", &atype, &cnt) == NC_NOERR && cnt == 2 && atype == xtype) { range = R_alloc (2, size); *min = range; *max = range + size; R_nc_check (nc_get_att (ncid, varid, "valid_range", range)); } /* Get fill value from attribute or use default */ if (nc_inq_att (ncid, varid, "_FillValue", &atype, &cnt) == NC_NOERR && cnt == 1 && atype == xtype) { *fill = R_alloc (1, size); R_nc_check (nc_get_att (ncid, varid, "_FillValue", *fill)); } else { *fill = R_alloc (1, size); switch (xtype) { case NC_SHORT: **(short **) fill = NC_FILL_SHORT; break; case NC_USHORT: **(unsigned short **) fill = NC_FILL_USHORT; break; case NC_INT: **(int **) fill = NC_FILL_INT; break; case NC_UINT: **(unsigned int **) fill = NC_FILL_UINT; break; case NC_FLOAT: **(float **) fill = NC_FILL_FLOAT; break; case NC_DOUBLE: **(double **) fill = NC_FILL_DOUBLE; break; case NC_INT64: **(long long **) fill = NC_FILL_INT64; break; case NC_UINT64: **(unsigned long long **) fill = NC_FILL_UINT64; break; default: error ("Default fill value not implemented"); } } /* If _FillValue is defined without a valid range, * set the valid range to exclude _FillValue */ if (*fill && !*max && !*min) { switch (xtype) { case NC_SHORT: FILL2RANGE_INT(short); break; case NC_USHORT: FILL2RANGE_INT(unsigned short); break; case NC_INT: FILL2RANGE_INT(int); break; case NC_UINT: FILL2RANGE_INT(unsigned int); break; case NC_INT64: FILL2RANGE_INT(long long); break; case NC_UINT64: FILL2RANGE_INT(unsigned long long); break; case NC_FLOAT: FILL2RANGE_REAL(float, FLT_EPSILON); break; case NC_DOUBLE: FILL2RANGE_REAL(double, DBL_EPSILON); break; default: error ("Default valid range not implemented"); } } } } else { error ("Unknown mode for handling missing values"); } return size; } /* Free memory allocated by netcdf for fill values in R_nc_miss_att */ static void R_nc_fill_free (int ncid, int xtype, void *fillp) { if (fillp) { #ifdef HAVE_NC_RECLAIM_DATA R_nc_check (nc_reclaim_data (ncid, xtype, fillp, 1)); #else int class; if (xtype == NC_STRING) { R_nc_check (nc_free_string (1, fillp)); } else if (xtype > NC_MAX_ATOMIC_TYPE) { R_nc_check (nc_inq_user_type (ncid, xtype, NULL, NULL, NULL, NULL, &class)); if (class == NC_VLEN) { R_nc_check (nc_free_vlens (1, fillp)); } } #endif } } /* Find packing attributes for a given netcdf variable. On entry, pointers for results are passed from caller. On exit, either values are set or pointers are NULLed. Example: R_nc_pack_att (ncid, varid, scalep, addp); */ static void R_nc_pack_att (int ncid, int varid, double **scale, double **add) { size_t cnt; if (nc_inq_attlen (ncid, varid, "scale_factor", &cnt) != NC_NOERR || cnt != 1 || nc_get_att_double (ncid, varid, "scale_factor", *scale) != NC_NOERR ) { *scale = NULL; } if (nc_inq_attlen (ncid, varid, "add_offset", &cnt) != NC_NOERR || cnt != 1 || nc_get_att_double (ncid, varid, "add_offset", *add) != NC_NOERR ) { *add = NULL; } } /*-----------------------------------------------------------------------------*\ * R_nc_get_var() \*-----------------------------------------------------------------------------*/ SEXP R_nc_get_var (SEXP nc, SEXP var, SEXP start, SEXP count, SEXP rawchar, SEXP fitnum, SEXP namode, SEXP unpack, SEXP cache_bytes, SEXP cache_slots, SEXP cache_preemption) { int ncid, varid, ndims, ii, israw, isfit, inamode, isunpack; size_t *cstart=NULL, *ccount=NULL; nc_type xtype; SEXP result=R_NilValue; void *buf; R_nc_buf io; double add, scale, *addp=NULL, *scalep=NULL; void *fillp=NULL, *minp=NULL, *maxp=NULL; size_t fillsize; #ifdef HAVE_NC_GET_VAR_CHUNK_CACHE int storeprop, format, withnc4; size_t bytes, slots; float preemption; double bytes_in, slots_in, preempt_in; #endif /*-- Convert arguments ------------------------------------------------------*/ ncid = asInteger (nc); R_nc_check (R_nc_var_id (var, ncid, &varid)); israw = (asLogical (rawchar) == TRUE); isfit = (asLogical (fitnum) == TRUE); inamode = asInteger (namode); isunpack = (asLogical (unpack) == TRUE); /*-- Chunk cache options for netcdf4 files ----------------------------------*/ #ifdef HAVE_NC_GET_VAR_CHUNK_CACHE R_nc_check (nc_inq_format (ncid, &format)); withnc4 = (format == NC_FORMAT_NETCDF4); if (withnc4) { R_nc_check (nc_inq_var_chunking (ncid, varid, &storeprop, NULL)); if (storeprop == NC_CHUNKED) { R_nc_check (nc_get_var_chunk_cache(ncid, varid, &bytes, &slots, &preemption)); bytes_in = asReal (cache_bytes); slots_in = asReal (cache_slots); preempt_in = asReal (cache_preemption); if (R_FINITE(bytes_in) || R_FINITE(slots_in) || R_FINITE(preempt_in)) { if (R_FINITE(bytes_in)) { bytes = bytes_in; } if (R_FINITE(slots_in)) { slots = slots_in; } if (R_FINITE(preempt_in)) { preemption = preempt_in; } R_nc_check (nc_set_var_chunk_cache(ncid, varid, bytes, slots, preemption)); } } } #endif /*-- Get type and rank of the variable --------------------------------------*/ R_nc_check (nc_inq_var (ncid, varid, NULL, &xtype, &ndims, NULL, NULL)); /*-- Convert start and count from R to C indices ----------------------------*/ if (ndims > 0) { cstart = R_nc_dim_r2c_size (start, ndims, 0); ccount = R_nc_dim_r2c_size (count, ndims, 0); for (ii=0; ii 0) { R_nc_check (nc_get_vara (ncid, varid, cstart, ccount, buf)); } R_nc_c2r (&io); /* Free memory allocated by netcdf for fill values */ R_nc_fill_free (ncid, xtype, fillp); UNPROTECT(1); return result; } /*-----------------------------------------------------------------------------*\ * R_nc_inq_var() \*-----------------------------------------------------------------------------*/ SEXP R_nc_inq_var (SEXP nc, SEXP var) { int ncid, varid, idim, ndims, natts, *dimids, storeprop, format, withnc4; int shuffle, deflate, deflate_level, fletcher; int status; size_t *chunksize_t; double *chunkdbl; char varname[NC_MAX_NAME + 1], vartype[NC_MAX_NAME+1]; nc_type xtype; SEXP result, rdimids, rchunks; #ifdef HAVE_NC_GET_VAR_CHUNK_CACHE size_t cache_bytes, cache_slots; float cache_preemption; #endif #ifdef HAVE_NC_INQ_VAR_ENDIAN int endian; #endif #ifdef HAVE_NC_INQ_VAR_SZIP int szip_options, szip_bits; #endif #ifdef HAVE_NC_MULTI_FILTER R_nc_buf filtio; double *dfiltid; unsigned int *ufiltid, *ufiltparm; size_t ifilter, nfilter, nfiltparm; SEXP rfilter_id, rfilter_params, rfiltparm; #endif /*-- Convert arguments to netcdf ids ----------------------------------------*/ ncid = asInteger (nc); R_nc_check (R_nc_var_id (var, ncid, &varid)); /*-- Inquire the variable ---------------------------------------------------*/ R_nc_check (nc_inq_format (ncid, &format)); withnc4 = (format == NC_FORMAT_NETCDF4); R_nc_check (nc_inq_var (ncid, varid, varname, &xtype, &ndims, NULL, &natts)); R_nc_check (R_nc_type2str (ncid, xtype, vartype)); if (withnc4) { result = PROTECT(allocVector (VECSXP, 18)); } else { result = PROTECT(allocVector (VECSXP, 6)); } SET_VECTOR_ELT (result, 0, PROTECT(ScalarInteger (varid))); SET_VECTOR_ELT (result, 1, PROTECT(mkString (varname))); SET_VECTOR_ELT (result, 2, PROTECT(mkString (vartype))); SET_VECTOR_ELT (result, 3, PROTECT(ScalarInteger (ndims))); SET_VECTOR_ELT (result, 5, PROTECT(ScalarInteger (natts))); UNPROTECT(5); if (ndims > 0) { rdimids = PROTECT(allocVector (INTSXP, ndims)); SET_VECTOR_ELT (result, 4, rdimids); UNPROTECT(1); dimids = INTEGER (rdimids); R_nc_check (nc_inq_vardimid (ncid, varid, dimids)); /* Return dimension ids in reverse (Fortran) order */ R_nc_rev_int (dimids, ndims); } else { /* Return single NA for scalar dimensions */ SET_VECTOR_ELT (result, 4, PROTECT(ScalarInteger (NA_INTEGER))); UNPROTECT(1); } if (withnc4) { R_nc_check (nc_inq_var_chunking (ncid, varid, &storeprop, NULL)); if (storeprop == NC_CHUNKED) { rchunks = PROTECT(allocVector (REALSXP, ndims)); SET_VECTOR_ELT (result, 6, rchunks); UNPROTECT(1); chunkdbl = REAL (rchunks); chunksize_t = (size_t *) R_alloc (ndims, sizeof(size_t)); R_nc_check (nc_inq_var_chunking (ncid, varid, NULL, chunksize_t)); /* Return chunk sizes as double precision in reverse (Fortran) order */ R_nc_rev_size (chunksize_t, ndims); for (idim=0; idim=4.7.4 sets results to 0 if szip is not used */ SET_VECTOR_ELT (result, 14, PROTECT(ScalarInteger (NA_INTEGER))); SET_VECTOR_ELT (result, 15, PROTECT(ScalarInteger (NA_INTEGER))); } else { SET_VECTOR_ELT (result, 14, PROTECT(ScalarInteger (szip_options))); SET_VECTOR_ELT (result, 15, PROTECT(ScalarInteger (szip_bits))); } UNPROTECT(2); # if defined NC_EFILTER } else if (status == NC_EFILTER) { /* netcdf<4.7.4 returns NC_EFILTER if szip is not used */ SET_VECTOR_ELT (result, 14, PROTECT(ScalarInteger (NA_INTEGER))); SET_VECTOR_ELT (result, 15, PROTECT(ScalarInteger (NA_INTEGER))); UNPROTECT(2); # endif } else { error ("%s", nc_strerror (status)); } #else SET_VECTOR_ELT (result, 14, R_NilValue); SET_VECTOR_ELT (result, 15, R_NilValue); #endif /* filter */ #ifdef HAVE_NC_MULTI_FILTER if (storeprop == NC_CHUNKED) { /* Query number of filters for the variable */ R_nc_check (nc_inq_var_filter_ids (ncid, varid, &nfilter, NULL)); /* Prepare R list items */ rfilter_id = PROTECT(allocVector(REALSXP, nfilter)); rfilter_params = PROTECT(allocVector(VECSXP, nfilter)); SET_VECTOR_ELT (result, 16, rfilter_id); SET_VECTOR_ELT (result, 17, rfilter_params); UNPROTECT(2); if (nfilter > 0) { /* Query filter ids, converting from unsigned int to R real */ dfiltid = REAL (rfilter_id); ufiltid = (unsigned int *) R_alloc (nfilter, sizeof(unsigned int)); R_nc_check (nc_inq_var_filter_ids (ncid, varid, &nfilter, ufiltid)); for (ifilter=0; ifilter=4.7.4 returns NC_EINVAL for non-chunked variables */ SET_VECTOR_ELT (result, 16, PROTECT(allocVector(REALSXP, 0))); SET_VECTOR_ELT (result, 17, PROTECT(allocVector(VECSXP, 0))); UNPROTECT(2); } #else SET_VECTOR_ELT (result, 16, R_NilValue); SET_VECTOR_ELT (result, 17, R_NilValue); #endif } UNPROTECT(1); return result; } /*-----------------------------------------------------------------------------*\ * R_nc_par_var() \*-----------------------------------------------------------------------------*/ SEXP R_nc_par_var (SEXP nc, SEXP var, SEXP access) { #ifdef HAVE_NETCDF_MPI int ncid, varid, iaccess; /*-- Convert arguments to netcdf ids ----------------------------------------*/ ncid = asInteger (nc); if (R_nc_strcmp(var, "NC_GLOBAL")) { varid = NC_GLOBAL; } else { R_nc_check (R_nc_var_id (var, ncid, &varid)); } if (R_nc_strcmp(access, "NC_COLLECTIVE")) { iaccess = NC_COLLECTIVE; } else if (R_nc_strcmp(access, "NC_INDEPENDENT")) { iaccess = NC_INDEPENDENT; } else { error("Unknown parallel access mode"); } /*-- Change parallel access mode --------------------------------------------*/ R_nc_check (nc_var_par_access(ncid, varid, iaccess)); return R_NilValue; #else error("MPI not supported"); #endif } /*-----------------------------------------------------------------------------*\ * R_nc_put_var() \*-----------------------------------------------------------------------------*/ SEXP R_nc_put_var (SEXP nc, SEXP var, SEXP start, SEXP count, SEXP data, SEXP namode, SEXP pack, SEXP cache_bytes, SEXP cache_slots, SEXP cache_preemption) { int ncid, varid, ndims, ii, inamode, ispack; size_t *cstart=NULL, *ccount=NULL; nc_type xtype; const void *buf; double scale, add, *scalep=NULL, *addp=NULL; void *fillp=NULL, *minp=NULL, *maxp=NULL; size_t fillsize; #ifdef HAVE_NC_GET_VAR_CHUNK_CACHE int storeprop, format, withnc4; size_t bytes, slots; float preemption; double bytes_in, slots_in, preempt_in; #endif /*-- Convert arguments to netcdf ids ----------------------------------------*/ ncid = asInteger (nc); R_nc_check (R_nc_var_id (var, ncid, &varid)); inamode = asInteger (namode); ispack = (asLogical (pack) == TRUE); /*-- Chunk cache options for netcdf4 files ----------------------------------*/ #ifdef HAVE_NC_GET_VAR_CHUNK_CACHE R_nc_check (nc_inq_format (ncid, &format)); withnc4 = (format == NC_FORMAT_NETCDF4); if (withnc4) { R_nc_check (nc_inq_var_chunking (ncid, varid, &storeprop, NULL)); if (storeprop == NC_CHUNKED) { R_nc_check (nc_get_var_chunk_cache(ncid, varid, &bytes, &slots, &preemption)); bytes_in = asReal (cache_bytes); slots_in = asReal (cache_slots); preempt_in = asReal (cache_preemption); if (R_FINITE(bytes_in) || R_FINITE(slots_in) || R_FINITE(preempt_in)) { if (R_FINITE(bytes_in)) { bytes = bytes_in; } if (R_FINITE(slots_in)) { slots = slots_in; } if (R_FINITE(preempt_in)) { preemption = preempt_in; } R_nc_check (nc_set_var_chunk_cache(ncid, varid, bytes, slots, preemption)); } } } #endif /*-- Get type and rank of the variable --------------------------------------*/ R_nc_check (nc_inq_var (ncid, varid, NULL, &xtype, &ndims, NULL, NULL)); /*-- Convert start and count from R to C indices ----------------------------*/ if (ndims > 0) { cstart = R_nc_dim_r2c_size (start, ndims, 0); ccount = R_nc_dim_r2c_size (count, ndims, 0); for (ii=0; ii 0) { buf = R_nc_r2c (data, ncid, xtype, ndims, ccount, fillsize, fillp, scalep, addp); R_nc_check (nc_put_vara (ncid, varid, cstart, ccount, buf)); } /* Free memory allocated by netcdf for fill values */ R_nc_fill_free (ncid, xtype, fillp); return R_NilValue; } /*-----------------------------------------------------------------------------*\ * R_nc_rename_var() \*-----------------------------------------------------------------------------*/ SEXP R_nc_rename_var (SEXP nc, SEXP var, SEXP newname) { int ncid, varid; const char *cnewname; /*-- Convert arguments to netcdf ids ----------------------------------------*/ ncid = asInteger (nc); R_nc_check (R_nc_var_id (var, ncid, &varid)); cnewname = R_nc_strarg (newname); /*-- Enter define mode ------------------------------------------------------*/ R_nc_check( R_nc_redef (ncid)); /*-- Rename the variable ----------------------------------------------------*/ R_nc_check (nc_rename_var (ncid, varid, cnewname)); return R_NilValue; } RNetCDF/src/Makefile.common.in0000644000176200001440000000043714577713273015606 0ustar liggesusers## Override CC defined by R to enable use of MPI compiler wrapper. # This file is included after all other makefiles by tools/make-recursive.sh CC = @CC@ PKG_CFLAGS = @PKG_CFLAGS@ PKG_CPPFLAGS = @DEFS@ @PKG_CPPFLAGS@ PKG_LIBS = @PKG_LDFLAGS@ @LIBS@ RNetCDF_all: $(SHLIB) symbols.rds RNetCDF/src/convert.h0000644000176200001440000001216214577720574014103 0ustar liggesusers/*=============================================================================*\ * * Name: convert.h * * Version: 2.9-2 * * Purpose: Type conversions for RNetCDF * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright (C) 2004-2024 Pavel Michna and Milton Woods. * *=============================================================================* * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *=============================================================================* */ #ifndef RNC_CONVERT_H_INCLUDED #define RNC_CONVERT_H_INCLUDED /* Find total number of elements in an array from dimension lengths. Result is 1 for a scalar or product of dimensions for an array. The special case ndims < 0 implies a vector of length count[0]. */ size_t R_nc_length (int ndims, const size_t *count); size_t R_nc_length_sexp (SEXP count); /* Allocate array with dimensions specified in C order. ndims > 0 implies an array with ndims dimension lengths in ccount[]. ndims == 0 implies a scalar (vector of length 1). ndims < 0 implies a dimensionless vector of length ccount[0]. */ SEXP R_nc_allocArray (SEXPTYPE type, int ndims, const size_t *ccount); /* Structure whose members are used by R_nc_c2r_init and R_nc_c2r. Other functions should not access members directly. */ typedef struct { SEXP rxp; void *restrict cbuf, *restrict rbuf; nc_type xtype; int ncid, ndim, rawchar, fitnum; size_t *restrict xdim, fillsize; void *restrict fill, *restrict min, *restrict max; double *restrict scale, *restrict add; } R_nc_buf; /* Convert an R vector to a netcdf external type (xtype). Memory for the results is allocated by R_alloc (freed by R), except in special cases where no modification of the input is required, when the output is a pointer to the input data. The number and lengths of netcdf dimensions are ndim and xdim (C-order). An error is raised for out-of-range values. Missing and NaN values are replaced by a fill value. Packing is performed if either scale or add are not NULL. */ const void * R_nc_r2c (SEXP rv, int ncid, nc_type xtype, int ndim, const size_t *xdim, size_t fillsize, const void *fill, const double *scale, const double *add); /* Convert an array of netcdf external type (xtype) to R. Memory buffers for R and (optionally) C arrays are allocated by R_nc_c2r_init; the C to R conversion is performed by R_nc_c2r, and memory is freed by R. The SEXP result of R_nc_c2r_init should be PROTECTed by the caller. Argument io is a pointer to an existing R_nc_buf (must not be NULL). Argument cbuf is a pointer to a pointer to a buffer for netcdf data, which will be allocated internally if *cbuf is NULL. The number and lengths of netcdf dimensions are ndim and xdim (C-order). The special case ndims < 0 gives a vector (no dim attribute) of length xdim[0]. If fitnum is true (non-zero), rv is the smallest compatible R numeric type, otherwise rv is double precision. If rawchar is true, NC_CHAR is returned to R as raw bytes, otherwise all elements in the fastest-varying dimension are combined into R strings. Elements are set to missing if they equal the fill value. Unpacking is performed if either scale or add are not NULL. */ SEXP \ R_nc_c2r_init (R_nc_buf *io, void **cbuf, int ncid, nc_type xtype, int ndim, const size_t *xdim, int rawchar, int fitnum, size_t fillsize, const void *fill, const void *min, const void *max, const double *scale, const double *add); void \ R_nc_c2r (R_nc_buf *io); /* Reverse a vector in-place. Example: R_nc_rev_int (cv, cnt); */ #define R_NC_REVERSE_H(FUN, TYPE) \ void \ FUN (TYPE *data, size_t cnt); R_NC_REVERSE_H(R_nc_rev_int, int) R_NC_REVERSE_H(R_nc_rev_size, size_t) /* Define R_nc_rev for other types as needed */ /* Copy the leading nr elements of R vector rv to C vector cv, converting type to TYPE and reversing from Fortran to C storage order. Elements beyond the length of rv and non-finite values are stored as fillval. */ #define R_NC_DIM_R2C_H(FUN, TYPE) \ TYPE * \ FUN (SEXP rv, size_t nr, TYPE fillval); R_NC_DIM_R2C_H (R_nc_dim_r2c_int, int) R_NC_DIM_R2C_H (R_nc_dim_r2c_size, size_t) /* Convert R numeric scalar argument to size_t. Raise an error if R type or value is not compatible. */ size_t R_nc_sizearg (SEXP size); #endif /* RNC_CONVERT_H_INCLUDED */ RNetCDF/src/common.h0000644000176200001440000000710714577720574013716 0ustar liggesusers/*=============================================================================*\ * * Name: common.h * * Version: 2.9-2 * * Purpose: Common definitions for RNetCDF functions * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright (C) 2004-2024 Pavel Michna and Milton Woods. * *=============================================================================* * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *=============================================================================* */ #ifndef RNC_COMMON_H_INCLUDED #define RNC_COMMON_H_INCLUDED #include #include #ifndef NC_MAX_ATOMIC_TYPE #define NC_MAX_ATOMIC_TYPE NC_STRING #endif /* Common error strings */ static const char RNC_EDATALEN[]="Not enough data", \ RNC_EDATATYPE[]="Incompatible data for external type", \ RNC_ETYPEDROP[]="Unsupported external type"; /* If status is a netcdf error, raise an R error with a suitable message, otherwise return to caller. */ int R_nc_check(int status); /* Determine if a C string matches the first element of an R variable. Result is a logical value. */ int R_nc_strcmp (SEXP var, const char *str); /* Find length of string up to first character chr and a maximum of maxlen characters. */ size_t R_nc_strnlen (const char *str, char chr, size_t maxlen); /* Determine if an R object inherits from a given class. Result is a logical value. */ int R_nc_inherits (SEXP var, const char *class); /* Convert dimension identifier from R string or number to an integer. Result is a netcdf status value. */ int R_nc_dim_id (SEXP dim, int ncid, int *dimid, int idx); /* Convert variable identifier from R string or number to an integer. Result is a netcdf status value. */ int R_nc_var_id (SEXP var, int ncid, int *varid); /* Convert type identifier from R string or number to an integer. Result is a netcdf status value. */ int R_nc_type_id (SEXP type, int ncid, nc_type *xtype, int idx); /* Convert netcdf type code to string label. Return NC_NOERR if ok, netcdf error code otherwise. The string buffer is assumed to have length NC_MAX_NAME or more. */ int R_nc_type2str (int ncid, nc_type xtype, char *str); /* Convert netcdf string label to type code. Return NC_NOERR if ok, netcdf error code otherwise. */ int R_nc_str2type (int ncid, const char *str, nc_type * xtype); /* Extract C string from R character vector argument. Raise an error if no string is found. */ const char * R_nc_strarg (SEXP str); /* Enter netcdf define mode if possible. Returns netcdf error code if an unhandled error occurs. */ int R_nc_redef (int ncid); /* Enter netcdf data mode if possible. Errors are ignored to avoid false alarms with some datasets (e.g. OPeNDAP), but we assume that subsequent function calls are checked for errors. */ int R_nc_enddef (int ncid); #endif /* RNC_COMMON_H_INCLUDED */ RNetCDF/src/dimension.c0000644000176200001440000001402714577720574014405 0ustar liggesusers/*=============================================================================*\ * * Name: dimension.c * * Version: 2.9-2 * * Purpose: NetCDF dimension functions for RNetCDF * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright (C) 2004-2024 Pavel Michna and Milton Woods. * *=============================================================================* * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *=============================================================================* */ #include #include #include #include #include #include #include #include #include #include "common.h" #include "convert.h" #include "RNetCDF.h" /*-----------------------------------------------------------------------------*\ * R_nc_def_dim() \*-----------------------------------------------------------------------------*/ SEXP R_nc_def_dim (SEXP nc, SEXP dimname, SEXP size, SEXP unlim) { int ncid, dimid; const char *dimnamep; size_t nccnt; /*-- Convert arguments to netcdf ids ----------------------------------------*/ ncid = asInteger (nc); dimnamep = R_nc_strarg (dimname); /*-- Enter define mode ------------------------------------------------------*/ R_nc_check( R_nc_redef (ncid)); /*-- Create the dimension ---------------------------------------------------*/ if (asLogical(unlim) == TRUE) { nccnt = NC_UNLIMITED; } else { nccnt = R_nc_sizearg (size); } R_nc_check (nc_def_dim (ncid, dimnamep, nccnt, &dimid)); return ScalarInteger (dimid); } /*-----------------------------------------------------------------------------*\ * R_nc_inq_unlimids() \*-----------------------------------------------------------------------------*/ /* Private function to find unlimited dimensions of a file or group. Returns netcdf status. If no error occurs, nunlim and unlimids are set. Note - some netcdf4 versions only return unlimited dimensions defined in a group, not those defined in the group and its ancestors as claimed in documentation. */ static int R_nc_unlimdims (int ncid, int *nunlim, int **unlimids) { int status, format; *nunlim = 0; status = nc_inq_format (ncid, &format); if (status != NC_NOERR) { return status; } if (format == NC_FORMAT_NETCDF4) { status = nc_inq_unlimdims (ncid, nunlim, NULL); if (status != NC_NOERR) { return status; } *unlimids = (void *) (R_alloc (*nunlim, sizeof (int))); status = nc_inq_unlimdims (ncid, NULL, *unlimids); } else { *unlimids = (void *) (R_alloc (1, sizeof (int))); status = nc_inq_unlimdim (ncid, *unlimids); if (status == NC_NOERR && **unlimids != -1) { *nunlim = 1; } } return status; } SEXP R_nc_inq_unlimids (SEXP nc) { int ncid, nunlim, *unlimids=NULL; SEXP result; ncid = asInteger (nc); R_nc_check (R_nc_unlimdims (ncid, &nunlim, &unlimids)); result = PROTECT(allocVector (INTSXP, nunlim)); /* Sort temporary results and copy to output structure */ if (nunlim > 0) { R_isort(unlimids, nunlim); memcpy (INTEGER (result), unlimids, nunlim * sizeof (int)); } UNPROTECT(1); return result; } /*-----------------------------------------------------------------------------*\ * R_nc_inq_dim() \*-----------------------------------------------------------------------------*/ SEXP R_nc_inq_dim (SEXP nc, SEXP dim) { int ncid, nunlim, *unlimids=NULL, isunlim, dimid, ii; size_t dimlen; char dimname[NC_MAX_NAME + 1]; SEXP result; /*-- Convert arguments to netcdf ids ----------------------------------------*/ ncid = asInteger (nc); R_nc_check (R_nc_dim_id (dim, ncid, &dimid, 0)); /*-- Inquire the dimension --------------------------------------------------*/ R_nc_check (nc_inq_dim (ncid, dimid, dimname, &dimlen)); /*-- Check if it is an unlimited dimension ----------------------------------*/ R_nc_check (R_nc_unlimdims (ncid, &nunlim, &unlimids)); isunlim = 0; for (ii = 0; ii < nunlim; ii++) { if (unlimids[ii] == dimid) { isunlim = 1; break; } } /*-- Returning the list -----------------------------------------------------*/ result = PROTECT(allocVector (VECSXP, 4)); SET_VECTOR_ELT (result, 0, PROTECT(ScalarInteger (dimid))); SET_VECTOR_ELT (result, 1, PROTECT(mkString (dimname))); /* Dimension length may be larger than integer, so return as double */ SET_VECTOR_ELT (result, 2, PROTECT(ScalarReal (dimlen))); SET_VECTOR_ELT (result, 3, PROTECT(ScalarLogical (isunlim))); UNPROTECT(5); return result; } /*-----------------------------------------------------------------------------*\ * R_nc_rename_dim() \*-----------------------------------------------------------------------------*/ SEXP R_nc_rename_dim (SEXP nc, SEXP dim, SEXP newname) { int ncid, dimid; const char *newnamep; /*-- Convert arguments to netcdf ids ----------------------------------------*/ ncid = asInteger (nc); R_nc_check (R_nc_dim_id (dim, ncid, &dimid, 0)); newnamep = R_nc_strarg (newname); /*-- Enter define mode ------------------------------------------------------*/ R_nc_check( R_nc_redef (ncid)); /*-- Rename the dimension ---------------------------------------------------*/ R_nc_check (nc_rename_dim (ncid, dimid, newnamep)); return R_NilValue; } RNetCDF/src/Makefile.win0000644000176200001440000000010614577713273014477 0ustar liggesusers## Makefile for RNetCDF on Windows. include Makefile WINDOWS = TRUE RNetCDF/NEWS0000644000176200001440000001372314577720574012166 0ustar liggesusersVersion 2.9-2, 2024-03-24 * Use pkg-config on Windows to fix linking with upcoming Rtools version Version 2.9-1, 2023-12-30 * Fix support for parallel I/O with MPICH (and related MPI variants) * Fix error handlers to remove potentially insecure format strings Version 2.8-1, 2023-10-21 * Fix builds on platforms where share directory is not under $R_HOME * Fix UBSAN warning when converting empty NC_CHAR to R string * Fix type conversions with oneAPI compiler Version 2.7-1, 2023-10-02 * Fix crash when calling nc_free_vlen on vlen with zero-length * Support packing and unpacking of vlen * Support fill value conversions in non-numeric data types: NC_CHAR, NC_STRING, enum, compound, and vlen * Improve support for NetCDF parallel I/O in configure script: - Specify MPI compiler via argument --with-mpicc - Enable MPI tests in R CMD check via argument --with-mpiexec - Give warnings if MPI and/or NetCDF parallel I/O not detected * Add configure option --with-nc-config-static to allow selection of static libraries from nc-config * Build Windows package with NetCDF library from RTools4x - Adapt to newer RTools by using configure script on Windows * Add examples using hierarchical groups to help for grp.inq.nc Version 2.6-2, 2023-01-16 * Fix compiler warnings reported by R-devel Version 2.6-1, 2021-06-25 * Windows: update binary packages to netcdf 4.9.0 with OpenDAP Version 2.5-2, 2021-08-20 * Support hdf5 filters via multi-filter interface (netcdf>=4.8.0) * Windows: update binary packages to netcdf 4.7.4 with OpenDAP * Generate type conversions with m4 macros * Reduce CPU time for utcal.nc example to pass CRAN checks Version 2.4-2, 2020-09-12 * Support reading/writing special values (e.g. NA, Inf) without substitution, mainly in cases where type conversion between R and NetCDF is not required. * Fix selection of na.mode values 0,1,2 * Fix range checks for numeric conversions with packing * Significantly increase test coverage of type conversion routines * Support parallel NetCDF when running with MPI * Allow creation of datasets in "data64" (CDF5) format * Support diskless files and in-memory manipulation of persistent files Version 2.3-1, 2020-04-27 * Fix problem when defining scalar variables with netcdf-4.7.4 Version 2.1-1, 2019-10-18 * Remove automatic handling of fill values in user-defined types * Link rwinlib libraries by pathname to fix r-hub Windows builds * Correct quoting of external software names in DESCRIPTION Version 2.0-4, 2019-10-13 * Fix OSX packages by linking expat library Version 2.0-3, 2019-10-05 * Support NetCDF-4 features for reading and writing of datasets. * Suggest bit64 package for NC_INT64 and NC_UINT64 types. * Drop support for netcdf-3.x library, require netcdf-4.x. * Drop support for udunits-1 library. * Disable calendar functions if udunits-2.x is not found during build. Version 1.9-1, 2017-10-04 * Allow multiple NA values in count argument of var.get.nc/var.put.nc, so that corresponding dimensions are read/written to their defined length. * Fix support for OPeNDAP (if enabled by the netcdf library) * Build Windows packages with netcdf4 library - Enable OPeNDAP in Win64 - Disable OPeNDAP in Win32, because it causes RNetCDF to crash - Thanks to Jeroen Ooms for giving us https://github.com/rwinlib/netcdf! * Register C routines for efficient access by R Version 1.8-2, 2016-02-21 * Add support for POSIXct timestamps to utcal.nc and utinvcal.nc. * Use nc-config by default in configure to find netcdf build settings. * Allow customisation of configure by variables CPPFLAGS, LDFLAGS and LIBS, and remove the following options: --with-netcdf-include, --with-netcdf-lib, --with-hdf5-lib, --with-udunits-include, --with-udunits-lib. Version 1.7-3, 2015-05-09 * Support reading/writing NC_CHAR as vectors of raw bytes * Avoid intermediate copies of array data when possible * Fix memory errors reported by valgrind for udunits2 calendar functions. * Support compilation with udunits.h inside a udunits2 sub-directory. * Add udunits data files to source package to ensure they can be found when building binary packages for Windows and Mac. Version 1.6.3-1, 2014-09-01 * Allow reading of character vector or scalar Version 1.6.2-3, 2014-06-16 * Added HDF5 licence file for distribution Version 1.6.2-2, 2014-05-27 * Corrected potential memory leak in read/write of character arrays Version 1.6.1-2, 2012-07-20 * Added function read.nc * Added packing/unpacking of data Version 1.5.3-1, 2012-02-15 * Optionally copy udunits data files during installation of RNetCDF. * When loading RNetCDF in R, initialise udunits with copied data files. Version 1.5.2-2, 2011-01-06 * configure adds tests for extra libraries used by netcdf4 on some systems. * Avoid repeated zeroing of character arrays in C interface. Version 1.5.0-1, 2010-12-30 * Add new modes (large, prefill, share) to nc_open and nc_create. * Avoid unnecessary switching of define and data modes in C library to prevent unwanted data movement within a file. * configure script accepts optional path for hdf5 (for netcdf4 library). * Added basic functional tests of package. Version 1.2-1.1, 2010-05-11 * Add build scripts for Windows. Version 1.2-1, 2006-07-26 * utcal.nc and utinvcal.nc optionally handle dates in string form. * configure script accepts optional paths for netcdf and udunits. Version 1.1-3, 2005-03-21 * Minor bugfix for detection of udunits headers in configure script. Version 1.1-2, 2005-01-04 * Return proper error status in C functions R_nc_sync and R_nc_get_vara_text. Version 1.1-1, 2004-09-19 * Add option to collapse singleton dimensions when reading arrays. * Allow reading of arrays without conversion of missing values. Version 1.0-4, 2004-09-11 * Search extra directories during configure. Version 1.0-3, 2004-08-01 * First release based on netcdf package by Thomas Lumley and ncdf package by David Pierce. RNetCDF/configure.win0000644000176200001440000000021514577713273014155 0ustar liggesusers#!/bin/sh if [ X"`pkg-config --version 2>/dev/null`" != X ] ; then ./configure LIBS="`pkg-config --libs netcdf`" else ./configure fi RNetCDF/COPYING0000644000176200001440000004325414577713273012522 0ustar liggesusers GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. RNetCDF/R/0000755000176200001440000000000014577720574011662 5ustar liggesusersRNetCDF/R/load.R0000644000176200001440000000016214577713273012721 0ustar liggesusers".onLoad" <- function(lib, pkg) { utinit.nc() } ".onUnload" <- function(libpath) { .Call(R_nc_utterm) } RNetCDF/R/config.R.in0000644000176200001440000000341114577720574013656 0ustar liggesusers#=============================================================================== # # Name: config.R # # Purpose: Record options enabled in RNetCDF at build time # # Author: Pavel Michna (rnetcdf-devel@bluewin.ch) # Milton Woods (miltonjwoods@gmail.com) # # Copyright (C) 2004-2024 Pavel Michna and Milton Woods. # #=============================================================================== # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # #=============================================================================== # This function is exported so that RNetCDF tests can detect configured options, # but it is not intended for user code, # and the output format is subject to change without notice. config.nc <- function() { # RHS values are replaced by configure script: config <- list( data64=@has_data64@, diskless=@has_diskless@, udunits=@has_udunits@, parallel=@has_parallel@, mpiexec="@mpiexec@" ) # Special case for packages with multiple architectures (e.g. Windows): config$data64 <- config$data64 && .Machine$sizeof.pointer >= 8 return(config) } RNetCDF/R/RNetCDF.R0000644000176200001440000011165114577720574013177 0ustar liggesusers#=============================================================================== # # Name: RNetCDF.R # # Purpose: NetCDF interface for R. # # Author: Pavel Michna (rnetcdf-devel@bluewin.ch) # Milton Woods (miltonjwoods@gmail.com) # # Copyright (C) 2004-2024 Pavel Michna and Milton Woods. # #=============================================================================== # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # #=============================================================================== # =============================================================================== # NetCDF library functions # =============================================================================== #------------------------------------------------------------------------------- # att.copy.nc() #------------------------------------------------------------------------------- att.copy.nc <- function(ncfile.in, variable.in, attribute, ncfile.out, variable.out) { #-- Check args ------------------------------------------------------------- stopifnot(inherits(ncfile.in, "NetCDF")) stopifnot(inherits(ncfile.out, "NetCDF")) stopifnot(is.character(attribute) || is.numeric(attribute)) stopifnot(is.character(variable.in) || is.numeric(variable.in)) stopifnot(is.character(variable.out) || is.numeric(variable.out)) #-- C function call -------------------------------------------------------- nc <- .Call(R_nc_copy_att, ncfile.in, variable.in, attribute, ncfile.out, variable.out) return(invisible(NULL)) } #------------------------------------------------------------------------------- # att.delete.nc() #------------------------------------------------------------------------------- att.delete.nc <- function(ncfile, variable, attribute) { #-- Check args ------------------------------------------------------------- stopifnot(inherits(ncfile, "NetCDF")) stopifnot(is.character(variable) || is.numeric(variable)) stopifnot(is.character(attribute) || is.numeric(attribute)) #-- C function call -------------------------------------------------------- nc <- .Call(R_nc_delete_att, ncfile, variable, attribute) return(invisible(NULL)) } #------------------------------------------------------------------------------- # att.get.nc() #------------------------------------------------------------------------------- att.get.nc <- function(ncfile, variable, attribute, rawchar = FALSE, fitnum = FALSE) { #-- Check args ------------------------------------------------------------- stopifnot(inherits(ncfile, "NetCDF")) stopifnot(is.character(variable) || is.numeric(variable)) stopifnot(is.character(attribute) || is.numeric(attribute)) stopifnot(is.logical(rawchar)) stopifnot(is.logical(fitnum)) #-- C function call -------------------------------------------------------- nc <- .Call(R_nc_get_att, ncfile, variable, attribute, rawchar, fitnum) if (inherits(nc, "integer64") && !requireNamespace("bit64", quietly=TRUE)) { stop("Package 'bit64' required for class 'integer64'") } return(nc) } #------------------------------------------------------------------------------- # att.inq.nc() #------------------------------------------------------------------------------- att.inq.nc <- function(ncfile, variable, attribute) { #-- Check args ------------------------------------------------------------- stopifnot(inherits(ncfile, "NetCDF")) stopifnot(is.character(variable) || is.numeric(variable)) stopifnot(is.character(attribute) || is.numeric(attribute)) #-- C function call -------------------------------------------------------- nc <- .Call(R_nc_inq_att, ncfile, variable, attribute) names(nc) <- c("id", "name", "type", "length") return(nc) } #------------------------------------------------------------------------------- # att.put.nc() #------------------------------------------------------------------------------- att.put.nc <- function(ncfile, variable, name, type, value) { #-- Check args ------------------------------------------------------------- stopifnot(inherits(ncfile, "NetCDF")) stopifnot(is.character(variable) || is.numeric(variable)) stopifnot(is.character(name)) stopifnot(is.character(type) || is.numeric(type)) stopifnot(is.numeric(value) || is.character(value) || is.raw(value) || is.logical(value) || is.list(value) || is.factor(value)) #-- C function call -------------------------------------------------------- nc <- .Call(R_nc_put_att, ncfile, variable, name, type, value) return(invisible(NULL)) } #------------------------------------------------------------------------------- # att.rename.nc() #------------------------------------------------------------------------------- att.rename.nc <- function(ncfile, variable, attribute, newname) { #-- Check args ------------------------------------------------------------- stopifnot(inherits(ncfile, "NetCDF")) stopifnot(is.character(variable) || is.numeric(variable)) stopifnot(is.character(attribute) || is.numeric(attribute)) stopifnot(is.character(newname)) #-- C function call -------------------------------------------------------- nc <- .Call(R_nc_rename_att, ncfile, variable, attribute, newname) return(invisible(NULL)) } #------------------------------------------------------------------------------- # close.nc() #------------------------------------------------------------------------------- close.nc <- function(con, ...) { #-- Check args ------------------------------------------------------------- stopifnot(inherits(con, "NetCDF")) #-- C function call -------------------------------------------------------- nc <- .Call(R_nc_close, attr(con, "handle_ptr")) return(invisible(NULL)) } #------------------------------------------------------------------------------- # create.nc() #------------------------------------------------------------------------------- create.nc <- function(filename, clobber = TRUE, share = FALSE, prefill = TRUE, format = "classic", large = FALSE, diskless = FALSE, persist = FALSE, mpi_comm=NULL, mpi_info=NULL) { #-- Check args ------------------------------------------------------------- stopifnot(is.character(filename)) stopifnot(is.logical(clobber)) stopifnot(is.logical(share)) stopifnot(is.logical(prefill)) stopifnot(is.character(format) && format[1] %in% c("classic", "offset64", "data64", "netcdf4", "classic4")) stopifnot(is.logical(large)) stopifnot(is.logical(diskless)) stopifnot(is.logical(persist)) stopifnot(is.null(mpi_comm) || is.numeric(mpi_comm)) stopifnot(is.null(mpi_info) || is.numeric(mpi_info)) # Handle deprecated argument: if (isTRUE(large) && format[1] == "classic") { format <- "offset64" warning("Argument 'large' is deprecated; please specify 'format' instead") } #-- C function call -------------------------------------------------------- nc <- .Call(R_nc_create, filename, clobber, share, prefill, format, diskless, persist, mpi_comm, mpi_info) attr(nc, "class") <- "NetCDF" return(invisible(nc)) } #------------------------------------------------------------------------------- # dim.def.nc() #------------------------------------------------------------------------------- dim.def.nc <- function(ncfile, dimname, dimlength = 1, unlim = FALSE) { #-- Check args ------------------------------------------------------------- stopifnot(inherits(ncfile, "NetCDF")) stopifnot(is.character(dimname)) stopifnot(is.numeric(dimlength)) stopifnot(is.logical(unlim)) #-- C function call -------------------------------------------------------- nc <- .Call(R_nc_def_dim, ncfile, dimname, dimlength, unlim) return(invisible(nc)) } #------------------------------------------------------------------------------- # dim.inq.nc() #------------------------------------------------------------------------------- dim.inq.nc <- function(ncfile, dimension) { #-- Check args ------------------------------------------------------------- stopifnot(inherits(ncfile, "NetCDF")) stopifnot(is.character(dimension) || is.numeric(dimension)) #-- C function call -------------------------------------------------------- nc <- .Call(R_nc_inq_dim, ncfile, dimension) #-- Return object ---------------------------------------------------------- names(nc) <- c("id", "name", "length", "unlim") return(nc) } #------------------------------------------------------------------------------- # dim.rename.nc() #------------------------------------------------------------------------------- dim.rename.nc <- function(ncfile, dimension, newname) { #-- Check args ------------------------------------------------------------- stopifnot(inherits(ncfile, "NetCDF")) stopifnot(is.character(dimension) || is.numeric(dimension)) stopifnot(is.character(newname)) #-- C function call -------------------------------------------------------- nc <- .Call(R_nc_rename_dim, ncfile, dimension, newname) return(invisible(NULL)) } #------------------------------------------------------------------------------- # file.inq.nc() #------------------------------------------------------------------------------- file.inq.nc <- function(ncfile) { #-- Check args ------------------------------------------------------------- stopifnot(inherits(ncfile, "NetCDF")) #-- C function call -------------------------------------------------------- nc <- .Call(R_nc_inq_file, ncfile) names(nc) <- c("ndims", "nvars", "ngatts", "unlimdimid", "format", "libvers") return(nc) } #------------------------------------------------------------------------------- # open.nc() #------------------------------------------------------------------------------- open.nc <- function(con, write = FALSE, share = FALSE, prefill = TRUE, diskless = FALSE, persist = FALSE, mpi_comm=NULL, mpi_info=NULL, ...) { #-- Check args ------------------------------------------------------------- stopifnot(is.character(con)) stopifnot(is.logical(write)) stopifnot(is.logical(share)) stopifnot(is.logical(prefill)) stopifnot(is.logical(diskless)) stopifnot(is.logical(persist)) stopifnot(is.null(mpi_comm) || is.numeric(mpi_comm)) stopifnot(is.null(mpi_info) || is.numeric(mpi_info)) #-- C function call -------------------------------------------------------- nc <- .Call(R_nc_open, con, write, share, prefill, diskless, persist, mpi_comm, mpi_info) attr(nc, "class") <- "NetCDF" return(invisible(nc)) } #------------------------------------------------------------------------------- # print.nc() #------------------------------------------------------------------------------- # Private function to print attributes, # given results from var.inq.nc and att.inq.nc: print_att <- function(grp, attinfo, indent, varinfo=NULL) { if (is.null(varinfo)) { varid <- "NC_GLOBAL" varname <- "" } else { varid <- varinfo$id varname <- varinfo$name } typeinfo <- type.inq.nc(grp, attinfo$type, fields=FALSE) if (attinfo$type == "NC_CHAR" || attinfo$type == "NC_STRING") { atttypestr <- attinfo$type attvalstr <- paste("\"", att.get.nc(grp, varid, attinfo$id), "\"", collapse=", ", sep="") } else if (typeinfo$class != "builtin") { atttypestr <- paste("//", attinfo$type, sep=""); attvalstr <- "..." } else { atttypestr <- attinfo$type attval <- att.get.nc(grp, varid, attinfo$id, fitnum=requireNamespace("bit64", quietly=TRUE)) if (inherits(attval, "integer64")) { attvalchar <- bit64::as.character.integer64(attval) } else { attvalchar <- as.character(attval) } attvalstr <- paste(attvalchar, collapse=", ", sep="") } tab <- "\t" cat(indent, tab, tab, atttypestr, " ", varname, ":", attinfo$name, " = ", attvalstr, " ;\n", sep="") } # Private function to print metadata of groups recursively: print_grp <- function(x, level = 0) { gap <- " " indent <- paste(rep(gap, level), collapse = "") tab <- "\t" #-- Inquire about the group ------------------------------------------------ grpinfo <- try(grp.inq.nc(x, ancestors = FALSE), silent = TRUE) if (inherits(grpinfo, "try-error") || is.null(grpinfo)) { return(invisible(NULL)) } #-- Inquire about all dimensions ------------------------------------------- if (length(grpinfo$dimids) != 0) { cat(indent, "dimensions:\n", sep = "") for (id in grpinfo$dimids) { diminfo <- dim.inq.nc(x, id) if (diminfo$unlim == FALSE) { cat(indent, tab, diminfo$name, " = ", diminfo$length, " ;\n", sep = "") } else { cat(indent, tab, diminfo$name, " = UNLIMITED ; // (", diminfo$length, " currently)\n", sep = "") } } } #-- Inquire about all types ------------------------------------------------ if (length(grpinfo$typeids) != 0) { cat(indent, "types:\n", sep = "") for (id in grpinfo$typeids) { typeinfo <- type.inq.nc(x, id, fields=TRUE) if (typeinfo$class == "compound") { cat(indent, gap, "compound ", typeinfo$name, " {\n", sep="") field_names = names(typeinfo$subtype) field_types = unname(typeinfo$subtype) field_sizes = unname(typeinfo$dimsizes) for (item in seq_along(typeinfo$subtype)) { cat(indent, gap, gap, field_types[item], " ", field_names[item], sep="") if (!is.null(field_sizes[[item]])) { cat("(", paste(field_sizes[[item]], collapse=","), ")", sep="") } cat(" ;\n") } cat(indent, gap, "}; // ", typeinfo$name, "\n", sep="") } else if (typeinfo$class == "enum") { cat(indent, gap, typeinfo$basetype, " enum ", typeinfo$name, " {\n", sep="") member_names <- names(typeinfo$value) member_values <- unname(typeinfo$value) for (item in seq_along(typeinfo$value)) { cat(indent, gap, gap, "\"", member_names[item], "\"", " = ", member_values[item], ",\n", sep="") } cat(indent, gap, "} ; // ", typeinfo$name, "\n", sep="") } else if (typeinfo$class == "opaque") { cat(indent, gap, "opaque(", typeinfo$size, ") ", typeinfo$name, " ;\n", sep="") } else if (typeinfo$class == "vlen") { cat(indent, gap, typeinfo$basetype, "(*) ", typeinfo$name, " ;\n", sep="") } } } #-- Inquire about all variables -------------------------------------------- if (length(grpinfo$varids) != 0) { cat(indent, "variables:\n", sep = "") for (id in grpinfo$varids) { varinfo <- var.inq.nc(x, id) vartype <- varinfo$type cat(indent, tab, vartype, " ", varinfo$name, sep = "") if (varinfo$ndims > 0) { cat("(") for (jj in seq_len(varinfo$ndims - 1)) { cat(dim.inq.nc(x, varinfo$dimids[jj])$name, ", ", sep = "") } cat(dim.inq.nc(x, varinfo$dimids[varinfo$ndims])$name, sep = "") cat(")") } cat(" ;\n") #-- Inquire about variable attributes ------------------------------ if (varinfo$natts != 0) { for (jj in 0:(varinfo$natts - 1)) { attinfo <- att.inq.nc(x, id, jj) print_att(x, attinfo, indent, varinfo) } } } } #-- Inquire about global attributes ---------------------------------------- if (grpinfo$ngatts != 0) { if (level == 0) { cat("\n", indent, "// global attributes:\n", sep = "") } else { cat("\n", indent, "// group attributes:\n", sep = "") } id <- "NC_GLOBAL" for (jj in 0:(grpinfo$ngatts - 1)) { attinfo <- att.inq.nc(x, id, jj) print_att(x, attinfo, indent) } } #-- Print groups recursively ----------------------------------------------- if (length(grpinfo$grps) != 0) { for (id in grpinfo$grps) { subgrpinfo <- grp.inq.nc(id, ancestors = FALSE) cat("\n", indent, "group: ", subgrpinfo$name, " {\n", sep = "") print_grp(id, level = (level + 1)) cat(indent, gap, "} // group ", subgrpinfo$name, "\n", sep = "") } } } print.nc <- function(x, ...) { #-- Check args ------------------------------------------------------------- stopifnot(inherits(x, "NetCDF")) cat("netcdf ", file.inq.nc(x)$format, " {\n", sep="") # Display groups recursively: print_grp(x, level = 0) cat("}\n") return(invisible(NULL)) } #------------------------------------------------------------------------------- # sync.nc() #------------------------------------------------------------------------------- sync.nc <- function(ncfile) { #-- Check args ------------------------------------------------------------- stopifnot(inherits(ncfile, "NetCDF")) #-- C function call -------------------------------------------------------- nc <- .Call(R_nc_sync, ncfile) return(invisible(NULL)) } #------------------------------------------------------------------------------- # var.def.nc() #------------------------------------------------------------------------------- var.def.nc <- function(ncfile, varname, vartype, dimensions, chunking=NA, chunksizes=NULL, deflate=NA, shuffle=FALSE, big_endian=NA, fletcher32=FALSE, filter_id=integer(0), filter_params=list()) { #-- Check args ------------------------------------------------------------- stopifnot(inherits(ncfile, "NetCDF")) stopifnot(is.character(varname)) stopifnot(is.character(vartype) || is.numeric(vartype)) if (length(dimensions) == 1 && is.na(dimensions)) { dimensions <- integer(0) } stopifnot(is.character(dimensions) || is.numeric(dimensions)) stopifnot(is.logical(chunking)) stopifnot(is.null(chunksizes) || is.numeric(chunksizes)) stopifnot(isTRUE(is.na(deflate)) || is.numeric(deflate)) stopifnot(is.logical(shuffle)) stopifnot(is.logical(big_endian)) stopifnot(is.logical(fletcher32)) stopifnot(is.numeric(filter_id)) stopifnot(is.list(filter_params)) stopifnot(all(sapply(filter_params, FUN=is.numeric))) stopifnot(length(filter_id) == length(filter_params)) #-- C function call -------------------------------------------------------- nc <- .Call(R_nc_def_var, ncfile, varname, vartype, dimensions, chunking, chunksizes, deflate, shuffle, big_endian, fletcher32, filter_id, filter_params) return(invisible(nc)) } #------------------------------------------------------------------------------- # var.get.nc() #------------------------------------------------------------------------------- var.get.nc <- function(ncfile, variable, start = NA, count = NA, na.mode = 4, collapse = TRUE, unpack = FALSE, rawchar = FALSE, fitnum = FALSE, cache_bytes=NA, cache_slots=NA, cache_preemption=NA) { #-- Check args ------------------------------------------------------------- stopifnot(inherits(ncfile, "NetCDF")) stopifnot(is.character(variable) || is.numeric(variable)) stopifnot(is.numeric(start) || is.logical(start)) stopifnot(is.numeric(count) || is.logical(count)) stopifnot(is.logical(collapse)) stopifnot(is.logical(unpack)) stopifnot(is.logical(rawchar)) stopifnot(is.logical(fitnum)) stopifnot(is.logical(cache_bytes) || is.numeric(cache_bytes)) stopifnot(is.logical(cache_slots) || is.numeric(cache_slots)) stopifnot(is.logical(cache_preemption) || is.numeric(cache_preemption)) # Truncate start & count and replace NA as described in the man page: varinfo <- var.inq.nc(ncfile, variable) ndims <- varinfo$ndims if (isTRUE(is.na(start))) { start <- rep(1, ndims) } else if (length(start) > ndims) { start <- start[seq_len(ndims)] } stopifnot(length(start) == ndims) start[is.na(start)] <- 1 if (isTRUE(is.na(count))) { count <- rep(NA, ndims) } else if (length(count) > ndims) { count <- count[seq_len(ndims)] } stopifnot(length(count) == ndims) for (idim in seq_len(ndims)) { if (is.na(count[idim])) { diminfo <- dim.inq.nc(ncfile, varinfo$dimids[idim]) count[idim] <- ( diminfo$length - start[idim] + 1 ) } } #-- C function call -------------------------------------------------------- nc <- .Call(R_nc_get_var, ncfile, variable, start, count, rawchar, fitnum, na.mode, unpack, cache_bytes, cache_slots, cache_preemption) if (inherits(nc, "integer64") && !requireNamespace("bit64", quietly=TRUE)) { stop("Package 'bit64' required for class 'integer64'") } #-- Collapse singleton dimensions -------------------------------------- if (isTRUE(collapse) && !is.null(dim(nc))) { nc <- drop(nc) } return(nc) } #------------------------------------------------------------------------------- # var.inq.nc() #------------------------------------------------------------------------------- var.inq.nc <- function(ncfile, variable) { #-- Check args ------------------------------------------------------------- stopifnot(inherits(ncfile, "NetCDF")) stopifnot(is.character(variable) || is.numeric(variable)) #-- C function call -------------------------------------------------------- nc <- .Call(R_nc_inq_var, ncfile, variable) if (length(nc) == 6) { names(nc) <- c("id", "name", "type", "ndims", "dimids", "natts") } else { names(nc) <- c("id", "name", "type", "ndims", "dimids", "natts", "chunksizes", "cache_bytes", "cache_slots", "cache_preemption", "deflate", "shuffle", "big_endian", "fletcher32", "szip_options", "szip_bits", "filter_id", "filter_params") } return(nc) } #------------------------------------------------------------------------------- # var.par.nc() #------------------------------------------------------------------------------- var.par.nc <- function(ncfile, variable, access="NC_COLLECTIVE") { #-- Check args ------------------------------------------------------------- stopifnot(inherits(ncfile, "NetCDF")) stopifnot(is.character(variable) || is.numeric(variable)) stopifnot(is.character(access) && access[1] %in% c("NC_COLLECTIVE", "NC_INDEPENDENT")) #-- C function call -------------------------------------------------------- nc <- .Call(R_nc_par_var, ncfile, variable, access) return(invisible(NULL)) } #------------------------------------------------------------------------------- # var.put.nc() #------------------------------------------------------------------------------- var.put.nc <- function(ncfile, variable, data, start = NA, count = NA, na.mode = 4, pack = FALSE, cache_bytes=NA, cache_slots=NA, cache_preemption=NA) { #-- Check args ------------------------------------------------------------- stopifnot(inherits(ncfile, "NetCDF")) stopifnot(is.character(variable) || is.numeric(variable)) stopifnot(is.numeric(data) || is.character(data) || is.raw(data) || is.logical(data) || is.list(data) || is.factor(data)) stopifnot(is.numeric(start) || is.logical(start)) stopifnot(is.numeric(count) || is.logical(count)) stopifnot(is.logical(pack)) stopifnot(is.logical(cache_bytes) || is.numeric(cache_bytes)) stopifnot(is.logical(cache_slots) || is.numeric(cache_slots)) stopifnot(is.logical(cache_preemption) || is.numeric(cache_preemption)) # Determine type and dimensions of variable: varinfo <- var.inq.nc(ncfile, variable) typeinfo <- type.inq.nc(ncfile, varinfo$type) ndims <- varinfo$ndims str2char <- is.character(data) && varinfo$type == "NC_CHAR" opaque <- is.raw(data) && typeinfo$class == "opaque" compound <- is.list(data) && typeinfo$class == "compound" # Truncate start & count and replace NA as described in the man page: if (isTRUE(is.na(start))) { start <- rep(1, ndims) } else if (length(start) > ndims) { start <- start[seq_len(ndims)] } stopifnot(length(start) == ndims) start[is.na(start)] <- 1 if (isTRUE(is.na(count))) { if (!is.null(dim(data))) { count <- dim(data) } else if (ndims==0 && length(data)==1) { count <- integer(0) } else if (compound) { # Compound type is stored as an R list, # and fields may have different dimensions. # Use dimensions from the netcdf variable instead. count <- rep(NA, ndims) } else { count <- length(data) } if (str2char && ndims > 0) { strlen <- dim.inq.nc(ncfile, varinfo$dimids[1])$length count <- c(strlen, count) } else if (opaque && length(count) > 0) { # Opaque items in R have an extra leading dimension count <- count[-1] } } else if (length(count) > ndims) { count <- count[seq_len(ndims)] } stopifnot(length(count) == ndims) for (idim in seq_len(ndims)) { if (is.na(count[idim])) { diminfo <- dim.inq.nc(ncfile, varinfo$dimids[idim]) count[idim] <- ( diminfo$length - start[idim] + 1 ) } } #-- Check that length of data is sufficient --------------------------------# if (str2char && ndims > 0) { numelem <- prod(count[-1]) } else if (opaque) { numelem <- prod(c(typeinfo$size,count)) } else if (compound) { numelem <- length(typeinfo$offset) } else { numelem <- prod(count) # Returns 1 if ndims==0 (scalar variable) } if (length(data) < numelem) { stop(paste("Not enough data elements (found ",length(data), ", need ",numelem,")", sep=""), call.=FALSE) } #-- Warn if strings will be truncated --------------------------------------# if (str2char) { if (ndims > 0) { strlen <- count[1] } else { strlen <- 1 } if (isTRUE(max(nchar(data,type="bytes")) > strlen)) { warning(paste("Strings truncated to length",strlen), call.=FALSE) } } #-- Warn if array data is not conformable with count -----------------------# if (!is.null(dim(data))) { if (str2char && ndims > 0) { count_drop <- count[-1] } else if (opaque) { count_drop <- c(typeinfo$size,count) } else { count_drop <- count } count_drop <- count_drop[count_drop!=1] dim_drop <- dim(data) dim_drop <- dim_drop[dim_drop!=1] if ((length(count_drop) != length(dim_drop)) || any(count_drop != dim_drop)) { warning(paste("Data coerced from dimensions (", paste(dim(data),collapse=","), ") to dimensions (", paste(count,collapse=","), ")", sep=""), call.=FALSE) } } #-- C function call -------------------------------------------------------- nc <- .Call(R_nc_put_var, ncfile, variable, start, count, data, na.mode, pack, cache_bytes, cache_slots, cache_preemption) return(invisible(NULL)) } #------------------------------------------------------------------------------- # var.rename.nc() #------------------------------------------------------------------------------- var.rename.nc <- function(ncfile, variable, newname) { #-- Check args ------------------------------------------------------------- stopifnot(inherits(ncfile, "NetCDF")) stopifnot(is.character(variable) || is.numeric(variable)) stopifnot(is.character(newname)) #-- C function call -------------------------------------------------------- nc <- .Call(R_nc_rename_var, ncfile, variable, newname) return(invisible(NULL)) } #------------------------------------------------------------------------------- # grp.def.nc() #------------------------------------------------------------------------------- grp.def.nc <- function(ncid, grpname) { # Check arguments: stopifnot(inherits(ncid, "NetCDF")) stopifnot(is.character(grpname)) # C function call: nc <- .Call(R_nc_def_grp, ncid, grpname) # Return object: attributes(nc) <- attributes(ncid) return(invisible(nc)) } #------------------------------------------------------------------------------- # grp.find() (internal only) #------------------------------------------------------------------------------- grp.find <- function(ncid, grpname, full = isTRUE(grepl("/", grpname))) { # Check arguments: stopifnot(inherits(ncid, "NetCDF")) stopifnot(is.character(grpname)) stopifnot(is.logical(full)) # C function call: nc <- .Call(R_nc_inq_grp_ncid, ncid, grpname, full) # Return object: attributes(nc) <- attributes(ncid) return(nc) } #------------------------------------------------------------------------------- # grp.inq.nc() #------------------------------------------------------------------------------- grp.inq.nc <- function(ncid, grpname = NULL, ancestors = TRUE) { # Check arguments: stopifnot(inherits(ncid, "NetCDF")) stopifnot(is.logical(ancestors)) stopifnot(is.null(grpname) || is.character(grpname)) # If optional argument is specified, find a group by name: if (!is.null(grpname)) { ncid <- grp.find(ncid, grpname) } # Initialise output list: out <- list() out$self <- ncid # Get parent of group (NULL if none): pgrp <- try(.Call(R_nc_inq_grp_parent, ncid), silent = TRUE) if (!inherits(pgrp, "try-error")) { attributes(pgrp) <- attributes(ncid) out$parent <- pgrp } # Get sub-groups of group (empty list if none): grpids <- try(.Call(R_nc_inq_grps, ncid), silent = TRUE) if (inherits(grpids, "try-error")) { out$grps <- list() } else { out$grps <- lapply(as.list(grpids), function(x) { attributes(x) <- attributes(ncid) return(x) }) } # Names of group: out$name <- .Call(R_nc_inq_grpname, ncid, FALSE) if (isTRUE(ancestors)) { out$fullname <- .Call(R_nc_inq_grpname, ncid, TRUE) } # Dimensions visible in group (empty vector if none): out$dimids <- .Call(R_nc_inq_dimids, ncid, ancestors) # Unlimited dimensions visible in group (empty vector if none): out$unlimids <- .Call(R_nc_inq_unlimids, ncid) # Variables in group (empty vector if none): out$varids <- .Call(R_nc_inq_varids, ncid) # Types in group (empty vector if none): out$typeids <- .Call(R_nc_inq_typeids, ncid) # Number of group attributes: out$ngatts <- .Call(R_nc_inq_natts, ncid) return(out) } #------------------------------------------------------------------------------- # grp.rename.nc() #------------------------------------------------------------------------------- grp.rename.nc <- function(ncid, newname, oldname = NULL) { # Check arguments: stopifnot(inherits(ncid, "NetCDF")) stopifnot(is.character(newname)) stopifnot(is.null(oldname) || is.character(oldname)) # If optional argument is specified, find a group by name: if (!is.null(oldname)) { ncid <- grp.find(ncid, oldname) } # C function call: nc <- .Call(R_nc_rename_grp, ncid, newname) return(invisible(NULL)) } #------------------------------------------------------------------------------- # read.nc() #------------------------------------------------------------------------------- read.nc <- function(ncfile, recursive = FALSE, ...) { #-- Check args ------------------------------------------------------------- stopifnot(inherits(ncfile, "NetCDF")) stopifnot(is.logical(recursive)) #-- Initialise storage ----------------------------------------------------- inq <- grp.inq.nc(ncfile) nvars <- length(inq$varids) if (isTRUE(recursive)) { ngrps <- length(inq$grps) nelem <- nvars + ngrps } else { ngrps <- 0 nelem <- nvars } elemnames <- character(nelem) retlist <- vector("list", nelem) #-- Read data from each variable ------------------------------------------- for (ii in seq_len(nvars)) { retlist[[ii]] <- var.get.nc(ncfile, inq$varids[ii], ...) elemnames[ii] <- var.inq.nc(ncfile, inq$varids[ii])$name } #-- Recursively read each group -------------------------------------------- for (ii in seq_len(ngrps)) { retlist[[nvars + ii]] <- read.nc(inq$grps[[ii]], recursive = TRUE, ...) elemnames[nvars + ii] <- grp.inq.nc(inq$grps[[ii]])$name } #-- Set names of list elements --------------------------------------------- names(retlist) <- elemnames return(retlist) } #------------------------------------------------------------------------------- # type.def.nc() #------------------------------------------------------------------------------- type.def.nc <- function(ncfile, typename, class, size=NULL, basetype=NULL, names=NULL, values=NULL, subtypes=NULL, dimsizes=NULL) { # Check arguments stopifnot(inherits(ncfile, "NetCDF")) stopifnot(is.character(typename)) stopifnot(is.character(class)) if (isTRUE(class == "compound")) { stopifnot(is.character(names)) stopifnot(is.character(subtypes) || is.numeric(subtypes)) stopifnot(is.list(dimsizes)) } else if (isTRUE(class == "enum")) { stopifnot(is.character(basetype) || is.numeric(basetype)) stopifnot(is.character(names)) stopifnot(is.numeric(values)) } else if (isTRUE(class == "opaque")) { stopifnot(is.numeric(size)) } else if (isTRUE(class == "vlen")) { stopifnot (is.character(basetype) || is.numeric(basetype)) } else { stop("Unknown class for type definition", call.=FALSE) } id <- .Call(R_nc_def_type, ncfile, typename, class, size, basetype, names, values, subtypes, dimsizes) return(invisible(id)) } #------------------------------------------------------------------------------- # type.inq.nc() #------------------------------------------------------------------------------- type.inq.nc <- function(ncfile, type, fields=TRUE) { # Check arguments: stopifnot(inherits(ncfile, "NetCDF")) stopifnot(is.numeric(type) || is.character(type)) stopifnot(is.logical(fields)) result <- .Call(R_nc_inq_type, ncfile, type, fields) return(result) } # =============================================================================== # Udunits library functions # =============================================================================== #------------------------------------------------------------------------------- # utcal.nc() #------------------------------------------------------------------------------- utcal.nc <- function(unitstring, value, type = "n") { #-- Check args ------------------------------------------------------------- stopifnot(is.character(unitstring)) stopifnot(is.numeric(value)) stopifnot(type == "n" || type == "s" || type == "c") #-- C function call to udunits calendar function ----------------------- ut <- .Call(R_nc_calendar, unitstring, value) #-- Return object if no error ------------------------------------------ if (isTRUE(type == "n")) { colnames(ut) <- c("year", "month", "day", "hour", "minute", "second") return(ut) } else if (isTRUE(type == "s")) { x <- sprintf("%02g-%02g-%02g %02g:%02g:%02g",ut[,1],ut[,2],ut[,3],ut[,4],ut[,5],ut[,6]) return(x) } else if (isTRUE(type == "c")) { ct <- utinvcal.nc("seconds since 1970-01-01 00:00:00 +00:00", ut) attr(ct, "class") <- c("POSIXct","POSIXt") attr(ct, "tzone") <- "UTC" return(ct) } } #------------------------------------------------------------------------------- # utinit.nc() #------------------------------------------------------------------------------- utinit.nc <- function(path = "") { stopifnot(is.character(path) && length(path) > 0) if (nchar(path[1]) == 0) { # Check environment for database requested by user: envdb <- Sys.getenv("UDUNITS2_XML_PATH", unset=NA) if (is.na(envdb)) { # Initialise unit system with database packaged in RNetCDF: path <- system.file("udunits", "udunits2.xml", package="RNetCDF", mustWork=TRUE) } else { # Initialise udunits2 library with user-specified database: path <- envdb } } ut <- .Call(R_nc_utinit, path) return(invisible(NULL)) } #------------------------------------------------------------------------------- # utinvcal.nc() #------------------------------------------------------------------------------- utinvcal.nc <- function(unitstring, value) { #-- Check args ------------------------------------------------------------- stopifnot(is.character(unitstring)) if (is.character(value)) { stopifnot(isTRUE(all(nchar(value) == 19))) value <- cbind(substr(value, 1, 4), substr(value, 6, 7), substr(value, 9, 10), substr(value, 12, 13), substr(value, 15, 16), substr(value, 18, 19)) value <- matrix(as.numeric(value), ncol = 6) } else if (inherits(value, "POSIXct")) { value <- utcal.nc("seconds since 1970-01-01 00:00:00 +00:00", as.vector(value), "n") } stopifnot(is.numeric(value)) #-- C function call -------------------------------------------------------- ut <- .Call(R_nc_inv_calendar, unitstring, value) return(ut) } # =============================================================================== RNetCDF/MD50000644000176200001440000000712014600137202011742 0ustar liggesusersb234ee4d69f5fce4486a80fdaf4a4263 *COPYING e4ee097ac2d1516128b6990d632b398d *DESCRIPTION a79d364603ffc327f51ecbda73d62483 *INSTALL 13bebe56c891faf6544b45d054b75f0e *LICENSE 537ae4d17831bfa5e4bb053c53bcd933 *NAMESPACE cb0c36e4f8974038c6331cc50bde0e1b *NEWS db2f4e82e0f7477dadc190dca68277db *R/RNetCDF.R cddc319b8feee45357763d70d833e5d5 *R/config.R.in 900ad9ec5d6b3f465f65621c2ac90b3f *R/load.R 3ee2d313b01e8c75dd118451997b2fee *README.md a38544db104bdfa10be73ab380052d1e *cleanup a38544db104bdfa10be73ab380052d1e *cleanup.win f12d14ee95b87a0b15dd96616c67f87d *configure 47ed8a07fb5d03e2346459de43bc60f9 *configure.ac 69f3b0beae9dfcdc8e11d289731cbd13 *configure.win a7639956a6d3c2528e09f0cd0a7b4798 *demo/00Index 193be507df49c73091c1e7e35248011d *demo/Rmpi_writeN_read1.R 4c5317591535e85344501d23353cb188 *demo/pbdMPI_writeN_read1.R 5bac89bca74222d4bb68c09e5981202d *inst/udunits/udunits2.xml d626a8de94b985b9fe9f49f6ccdfcecf *man/00RNetCDF.Rd c264156c117eaa614cb1818956a617b9 *man/att.copy.nc.Rd 3dcc32eb8b8063d7c97284dc9667f66d *man/att.delete.nc.Rd 8a8916e5bfdc903e8b22d4f7a93d9800 *man/att.get.nc.Rd 5bf941e6a0de10ac82e2cc77180cbf9c *man/att.inq.nc.Rd 9202ae90cf97f1dd38649cc54a6b4a1e *man/att.put.nc.Rd 78fa7bb178c0761203bfb98ed73b9622 *man/att.rename.nc.Rd 416e71a277df5657d5146de9893bfda6 *man/close.nc.Rd a891f9834827e7f36f8b4f19de503872 *man/config.nc.Rd 5b6859726917caf447078257678f14d3 *man/create.nc.Rd 443f8b2ccc09212b4e10055d13bbc5c0 *man/dim.def.nc.Rd c525fffbe97fa0ce6599b3ca17f9e5f2 *man/dim.inq.nc.Rd e4167671e209b0d13c7e175f4aa8a09b *man/dim.rename.nc.Rd 2f6ef932c600559ab52e00b002d7f8e8 *man/file.inq.nc.Rd 09f1d66f3a73613d1b0214a9efaed361 *man/grp.def.nc.Rd c2501e7a8b5b6842b647200c4c26ce21 *man/grp.inq.nc.Rd 6e24f6cac86b802eb7fe704d06b6dd48 *man/grp.rename.nc.Rd 458acabdd6cb64a43a46626920aafffb *man/open.nc.Rd e3f0fca36ec9363975c3029f2f662cfd *man/print.nc.Rd 55eb09ee8a45caeb5c5ed209e2a08b7e *man/read.nc.Rd 3282bcde27b54c13c0b63d7f8b28cfb3 *man/sync.nc.Rd a4b1adf689ca084a601287014ce568d4 *man/type.def.nc.Rd 0bd2ef2eedb2b17194f214f46eb37699 *man/type.inq.nc.Rd 00951d71c6c398e3dfb7711c5860084a *man/utcal.nc.Rd 10d8ce364b64327489da9fd206ceb9c1 *man/utinit.nc.Rd 31acb414bb303799bc50b297b2841db6 *man/utinvcal.nc.Rd eced4fb94d47f164649fb3d854774e5e *man/var.def.nc.Rd 05ee281e914c7f51e8f2196c51c2f45c *man/var.get.nc.Rd 3f111e6ed9d64142966bc5d2be843a3c *man/var.inq.nc.Rd 48c8f5d61bc5682ce81c57515729815f *man/var.par.nc.Rd 0d7d4b6aaec555eafd6a5ab3ebc23013 *man/var.put.nc.Rd d377aceb8a368a8edd949ebe69d4df2c *man/var.rename.nc.Rd 23ad145221fc84e9dbf51bbfdaf4f069 *src/Makefile c1573f53ff0df7aa00b022686276156c *src/Makefile.common.in 8e093f31050d64e1907258dbaea8532d *src/Makefile.win 0fa94e309594bbc021bbbb6d9b490445 *src/RNetCDF.h 2625f6b4feb7ceb812b93a94955dff56 *src/attribute.c e8cccbe0605338f871b75a85b85370e9 *src/common.c 9895cf35a7ba4135cf51c6fbac668a5c *src/common.h f3dd9bcc7db8156875b803eafa2146a4 *src/convert.c e252e07cdbb308fb441bb9c4bc10d6f1 *src/convert.h 59267ab4d162854588bc6ebc13679a9d *src/dataset.c be9589bd251ecc521c64afb195f4dae9 *src/dimension.c 1948a42cb41e39b753f331c55051bdf8 *src/group.c cc44687bad2486cf4f975dbe98027693 *src/init.c 1f811f8bdb0163386d5cfd0a60d33e98 *src/type.c 21aca5e06ae50468ced4eca2d87902f1 *src/udunits.c ef788cc9b403781cea9a8a4cfdf8a64d *src/variable.c c5d6ef0415ad4f3c89af53b9806fb719 *tests/RNetCDF-test.R 6007f02fe511f6656a267afb3c164c23 *tools/convert.m4 54164ec98c7242d4d2426001f999709e *tools/make-recursive.sh ce9b8ca8f97913179228b861aa48246c *tools/release.sh bcfc8f2177ef73109253405fb8fcd84c *tools/update-configure.sh c7ab72592ca7c5f1554e13da35f9089f *tools/update-convert-c.sh RNetCDF/inst/0000755000176200001440000000000014152655334012424 5ustar liggesusersRNetCDF/inst/udunits/0000755000176200001440000000000014577713273014127 5ustar liggesusersRNetCDF/inst/udunits/udunits2.xml0000644000176200001440000001711214577713273016430 0ustar liggesusers 1e24 yotta Y 1e21 zetta Z 1e18 exa E 1e15 peta P 1e12 tera T 1e9 giga G 1e6 mega M 1e3 kilo k 100 hecto h 10 deka da .1 deci d .01 centi c 1e-3 milli m 1e-6 micro µ μ u 1e-9 nano n 1e-12 pico p 1e-15 femto f 1e-18 atto a 1e-21 zepto z 1e-24 yocto y second s 60 s minute min 60 min hour h hr 24 h day d s sec 1e-8 s shake 8.616409e4 s sidereal_day 3.590170e3 s sidereal_hour 5.983617e1 s sidereal_minute 0.9972696 s sidereal_second 3.155815e7 s sidereal_year 3.15569259747e7 s tropical_year year yr 29.530589 day lunar_month 365 day common_year 366 day leap_year 365.25 day Julian_year 365.2425 day Gregorian_year 27.321661 day sidereal_month 27.321582 day tropical_month 14 day fortnight 7 day week 0.01 s jiffy 1e9 year eon year/12 month 2056 hours work_year work_year/12 work_month RNetCDF/cleanup0000755000176200001440000000013214577720720013023 0ustar liggesusers#!/bin/sh rm -rf *.cache rm -f ./config.* rm -f ./src/Makevars rm -f ./src/*.so ./src/*.o RNetCDF/configure0000755000176200001440000062336314577720720013376 0ustar liggesusers#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.71 for RNetCDF 2.9-2. # # # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, # Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="as_nop=: if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else \$as_nop case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ) then : else \$as_nop exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 blah=\$(echo \$(echo blah)) test x\"\$blah\" = xblah || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null then : as_have_required=yes else $as_nop as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null then : else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$as_shell as_have_required=yes if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null then : break 2 fi fi done;; esac as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop if { test -f "$SHELL" || test -f "$SHELL.exe"; } && as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$SHELL as_have_required=yes fi fi if test "x$CONFIG_SHELL" != x then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno then : printf "%s\n" "$0: This script requires a shell more modern than all" printf "%s\n" "$0: the shells that I found on your system." if test ${ZSH_VERSION+y} ; then printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." else printf "%s\n" "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='RNetCDF' PACKAGE_TARNAME='rnetcdf' PACKAGE_VERSION='2.9-2' PACKAGE_STRING='RNetCDF 2.9-2' PACKAGE_BUGREPORT='' PACKAGE_URL='' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_STDIO_H # include #endif #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_header_c_list= ac_subst_vars='LTLIBOBJS LIBOBJS PKG_LDFLAGS PKG_CPPFLAGS PKG_CFLAGS mpiexec has_parallel has_udunits has_diskless has_data64 have_nc_config OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking with_mpicc with_nc_config with_nc_config_static with_mpiexec ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures RNetCDF 2.9-2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/rnetcdf] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of RNetCDF 2.9-2:";; esac cat <<\_ACEOF Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-mpicc command for C compiler from MPI, otherwise C compiler from R is used --with-nc-config get compiler options from nc-config (default except on Windows) --with-nc-config-static use static libraries from nc-config (default on Windows & macOS) --with-mpiexec command to run small parallel MPI tests after installation (none by default) Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for configure.gnu first; this name is used for a wrapper for # Metaconfig's "Configure" on case-insensitive file systems. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF RNetCDF configure 2.9-2 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_check_decl LINENO SYMBOL VAR INCLUDES EXTRA-OPTIONS FLAG-VAR # ------------------------------------------------------------------ # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR # accordingly. Pass EXTRA-OPTIONS to the compiler, using FLAG-VAR. ac_fn_check_decl () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack as_decl_name=`echo $2|sed 's/ *(.*//'` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 printf %s "checking whether $as_decl_name is declared... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` eval ac_save_FLAGS=\$$6 as_fn_append $6 " $5" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { #ifndef $as_decl_name #ifdef __cplusplus (void) $as_decl_use; #else (void) $as_decl_name; #endif #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext eval $6=\$ac_save_FLAGS fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_check_decl # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_try_run LINENO # ---------------------- # Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that # executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: program exited with status $ac_status" >&5 printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_c_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_hi=$ac_mid; break else $as_nop as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext done else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_lo=$ac_mid; break else $as_nop as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext done else $as_nop ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_hi=$ac_mid else $as_nop as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval (void) { return $2; } static unsigned long int ulongval (void) { return $2; } #include #include int main (void) { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO" then : echo >>conftest.val; read $3 &5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. */ #include #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main (void) { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func ac_configure_args_raw= for ac_arg do case $ac_arg in *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append ac_configure_args_raw " '$ac_arg'" done case $ac_configure_args_raw in *$as_nl*) ac_safe_unquote= ;; *) ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. ac_unsafe_a="$ac_unsafe_z#~" ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; esac cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by RNetCDF $as_me 2.9-2, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac printf "%s\n" "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Sanitize IFS. IFS=" "" $as_nl" # Save into config.log some information that might help in debugging. { echo printf "%s\n" "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo printf "%s\n" "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then printf "%s\n" "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then printf "%s\n" "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && printf "%s\n" "$as_me: caught signal $ac_signal" printf "%s\n" "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h printf "%s\n" "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then ac_site_files="$CONFIG_SITE" elif test "x$prefix" != xNONE; then ac_site_files="$prefix/share/config.site $prefix/etc/config.site" else ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi for ac_site_file in $ac_site_files do case $ac_site_file in #( */*) : ;; #( *) : ac_site_file=./$ac_site_file ;; esac if test -f "$ac_site_file" && test -r "$ac_site_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 printf "%s\n" "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 printf "%s\n" "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Test code for whether the C compiler supports C89 (global declarations) ac_c_conftest_c89_globals=' /* Does the compiler advertise C89 conformance? Do not test the value of __STDC__, because some compilers set it to 0 while being otherwise adequately conformant. */ #if !defined __STDC__ # error "Compiler does not advertise C89 conformance" #endif #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ struct buf { int x; }; struct buf * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not \xHH hex character constants. These do not provoke an error unfortunately, instead are silently treated as an "x". The following induces an error, until -std is added to get proper ANSI mode. Curiously \x00 != x always comes out true, for an array size at least. It is necessary to write \x00 == 0 to get something that is true only with -std. */ int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) '\''x'\'' int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int), int, int);' # Test code for whether the C compiler supports C89 (body of main). ac_c_conftest_c89_main=' ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); ' # Test code for whether the C compiler supports C99 (global declarations) ac_c_conftest_c99_globals=' // Does the compiler advertise C99 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L # error "Compiler does not advertise C99 conformance" #endif #include extern int puts (const char *); extern int printf (const char *, ...); extern int dprintf (int, const char *, ...); extern void *malloc (size_t); // Check varargs macros. These examples are taken from C99 6.10.3.5. // dprintf is used instead of fprintf to avoid needing to declare // FILE and stderr. #define debug(...) dprintf (2, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK #error "your preprocessor is broken" #endif #if BIG_OK #else #error "your preprocessor is broken" #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) continue; return 0; } // Check varargs and va_copy. static bool test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str = ""; int number = 0; float fnumber = 0; while (*format) { switch (*format++) { case '\''s'\'': // string str = va_arg (args_copy, const char *); break; case '\''d'\'': // int number = va_arg (args_copy, int); break; case '\''f'\'': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); return *str && number && fnumber; } ' # Test code for whether the C compiler supports C99 (body of main). ac_c_conftest_c99_main=' // Check bool. _Bool success = false; success |= (argc != 0); // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[0] = argv[0][0]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' || dynamic_array[ni.number - 1] != 543); ' # Test code for whether the C compiler supports C11 (global declarations) ac_c_conftest_c11_globals=' // Does the compiler advertise C11 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L # error "Compiler does not advertise C11 conformance" #endif // Check _Alignas. char _Alignas (double) aligned_as_double; char _Alignas (0) no_special_alignment; extern char aligned_as_int; char _Alignas (0) _Alignas (int) aligned_as_int; // Check _Alignof. enum { int_alignment = _Alignof (int), int_array_alignment = _Alignof (int[100]), char_alignment = _Alignof (char) }; _Static_assert (0 < -_Alignof (int), "_Alignof is signed"); // Check _Noreturn. int _Noreturn does_not_return (void) { for (;;) continue; } // Check _Static_assert. struct test_static_assert { int x; _Static_assert (sizeof (int) <= sizeof (long int), "_Static_assert does not work in struct"); long int y; }; // Check UTF-8 literals. #define u8 syntax error! char const utf8_literal[] = u8"happens to be ASCII" "another string"; // Check duplicate typedefs. typedef long *long_ptr; typedef long int *long_ptr; typedef long_ptr long_ptr; // Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. struct anonymous { union { struct { int i; int j; }; struct { int k; long int l; } w; }; int m; } v1; ' # Test code for whether the C compiler supports C11 (body of main). ac_c_conftest_c11_main=' _Static_assert ((offsetof (struct anonymous, i) == offsetof (struct anonymous, w.k)), "Anonymous union alignment botch"); v1.i = 2; v1.w.k = 5; ok |= v1.i != 5; ' # Test code for whether the C compiler supports C11 (complete). ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} ${ac_c_conftest_c11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} ${ac_c_conftest_c11_main} return ok; } " # Test code for whether the C compiler supports C99 (complete). ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} return ok; } " # Test code for whether the C compiler supports C89 (complete). ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} return ok; } " as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu : ${R_HOME=`R RHOME`} if test -z "${R_HOME}" then : as_fn_error $? "could not determine R_HOME" "$LINENO" 5 fi #-------------------------------------------------------------------------------# # Get compiler/linker variables from environment # #-------------------------------------------------------------------------------# { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Find compiler/linker variables from environment:" >&5 printf "%s\n" "$as_me: Find compiler/linker variables from environment:" >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking CFLAGS" >&5 printf %s "checking CFLAGS... " >&6; } PKG_CFLAGS="$CFLAGS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${PKG_CFLAGS}" >&5 printf "%s\n" "${PKG_CFLAGS}" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking CPPFLAGS" >&5 printf %s "checking CPPFLAGS... " >&6; } PKG_CPPFLAGS="$CPPFLAGS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${PKG_CPPFLAGS}" >&5 printf "%s\n" "${PKG_CPPFLAGS}" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking LDFLAGS" >&5 printf %s "checking LDFLAGS... " >&6; } PKG_LDFLAGS="$LDFLAGS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${PKG_LDFLAGS}" >&5 printf "%s\n" "${PKG_LDFLAGS}" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking LIBS" >&5 printf %s "checking LIBS... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIBS" >&5 printf "%s\n" "$LIBS" >&6; } #-------------------------------------------------------------------------------# # Select compiler from R unless --with-mpicc has non-empty value # #-------------------------------------------------------------------------------# { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Select C compiler:" >&5 printf "%s\n" "$as_me: Select C compiler:" >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking C compiler from --with-mpicc" >&5 printf %s "checking C compiler from --with-mpicc... " >&6; } # Check whether --with-mpicc was given. if test ${with_mpicc+y} then : withval=$with_mpicc; CC="$withval" else $as_nop CC="" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } if test -z "$CC" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking C compiler from R" >&5 printf %s "checking C compiler from R... " >&6; } R_CC=`"${R_HOME}/bin/R" CMD config CC` CC="${R_CC}" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } fi #-------------------------------------------------------------------------------# # Get compiler/linker variables from R # #-------------------------------------------------------------------------------# { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Find compiler/linker variables from R:" >&5 printf "%s\n" "$as_me: Find compiler/linker variables from R:" >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking R_CFLAGS" >&5 printf %s "checking R_CFLAGS... " >&6; } R_CFLAGS=`"${R_HOME}/bin/R" CMD config CFLAGS` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${R_CFLAGS}" >&5 printf "%s\n" "${R_CFLAGS}" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking R_CPPFLAGS" >&5 printf %s "checking R_CPPFLAGS... " >&6; } R_CPPFLAGS=`"${R_HOME}/bin/R" CMD config CPPFLAGS` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${R_CPPFLAGS}" >&5 printf "%s\n" "${R_CPPFLAGS}" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking R_LDFLAGS" >&5 printf %s "checking R_LDFLAGS... " >&6; } R_LDFLAGS=`"${R_HOME}/bin/R" CMD config LDFLAGS` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${R_LDFLAGS}" >&5 printf "%s\n" "${R_LDFLAGS}" >&6; } # No LIBS from R #-------------------------------------------------------------------------------# # Identify OS # #-------------------------------------------------------------------------------# # Initial compiler test with CC found earlier and compiler flags from R. # Original variable contents were copied to PKG_ variables earlier. CFLAGS="${R_CFLAGS}" CPPFLAGS="${R_CPPFLAGS}" LDFLAGS="${R_LDFLAGS}" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. set dummy ${ac_tool_prefix}clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "clang", so it can be a program name with args. set dummy clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi fi test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion -version; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 printf %s "checking whether the C compiler works... " >&6; } ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else $as_nop ac_file='' fi if test -z "$ac_file" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 printf %s "checking for C compiler default output file name... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 printf "%s\n" "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 printf %s "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 printf "%s\n" "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 printf %s "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 printf "%s\n" "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 printf %s "checking for suffix of object files... " >&6; } if test ${ac_cv_objext+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 printf "%s\n" "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 printf %s "checking whether the compiler supports GNU C... " >&6; } if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 printf %s "checking whether $CC accepts -g... " >&6; } if test ${ac_cv_prog_cc_g+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes else $as_nop CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 printf "%s\n" "$ac_cv_prog_cc_g" >&6; } if test $ac_test_CFLAGS; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi ac_prog_cc_stdc=no if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 printf %s "checking for $CC option to enable C11 features... " >&6; } if test ${ac_cv_prog_cc_c11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c11_program _ACEOF for ac_arg in '' -std=gnu11 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c11" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } CC="$CC $ac_cv_prog_cc_c11" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 ac_prog_cc_stdc=c11 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 printf %s "checking for $CC option to enable C99 features... " >&6; } if test ${ac_cv_prog_cc_c99+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c99_program _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c99" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c99" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } CC="$CC $ac_cv_prog_cc_c99" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 ac_prog_cc_stdc=c99 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 printf %s "checking for $CC option to enable C89 features... " >&6; } if test ${ac_cv_prog_cc_c89+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c89_program _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c89" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c89" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } CC="$CC $ac_cv_prog_cc_c89" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 ac_prog_cc_stdc=c89 fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC options needed to detect all undeclared functions" >&5 printf %s "checking for $CC options needed to detect all undeclared functions... " >&6; } if test ${ac_cv_c_undeclared_builtin_options+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_CFLAGS=$CFLAGS ac_cv_c_undeclared_builtin_options='cannot detect' for ac_arg in '' -fno-builtin; do CFLAGS="$ac_save_CFLAGS $ac_arg" # This test program should *not* compile successfully. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { (void) strchr; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop # This test program should compile successfully. # No library function is consistently available on # freestanding implementations, so test against a dummy # declaration. Include always-available headers on the # off chance that they somehow elicit warnings. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include extern void ac_decl (int, char *); int main (void) { (void) ac_decl (0, (char *) 0); (void) ac_decl; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : if test x"$ac_arg" = x then : ac_cv_c_undeclared_builtin_options='none needed' else $as_nop ac_cv_c_undeclared_builtin_options=$ac_arg fi break fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext done CFLAGS=$ac_save_CFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_undeclared_builtin_options" >&5 printf "%s\n" "$ac_cv_c_undeclared_builtin_options" >&6; } case $ac_cv_c_undeclared_builtin_options in #( 'cannot detect') : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot make $CC report undeclared builtins See \`config.log' for more details" "$LINENO" 5; } ;; #( 'none needed') : ac_c_undeclared_builtin_options='' ;; #( *) : ac_c_undeclared_builtin_options=$ac_cv_c_undeclared_builtin_options ;; esac ac_header= ac_cache= for ac_item in $ac_header_c_list do if test $ac_cache; then ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then printf "%s\n" "#define $ac_item 1" >> confdefs.h fi ac_header= ac_cache= elif test $ac_header; then ac_cache=$ac_item else ac_header=$ac_item fi done if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes then : printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h fi ac_fn_check_decl "$LINENO" "_WIN32" "ac_cv_have_decl__WIN32" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS" if test "x$ac_cv_have_decl__WIN32" = xyes then : ac_have_decl=1 else $as_nop ac_have_decl=0 fi printf "%s\n" "#define HAVE_DECL__WIN32 $ac_have_decl" >>confdefs.h if test $ac_have_decl = 1 then : platform=Windows else $as_nop ac_fn_check_decl "$LINENO" "__APPLE__" "ac_cv_have_decl___APPLE__" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS" if test "x$ac_cv_have_decl___APPLE__" = xyes then : ac_have_decl=1 else $as_nop ac_have_decl=0 fi printf "%s\n" "#define HAVE_DECL___APPLE__ $ac_have_decl" >>confdefs.h if test $ac_have_decl = 1 then : platform=macOS else $as_nop platform=Unix-alike fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Operating system is $platform" >&5 printf "%s\n" "$as_me: Operating system is $platform" >&6;} #-------------------------------------------------------------------------------# # Prepend compiler/linker variables from nc-config (if specified) # #-------------------------------------------------------------------------------# # Enable nc-config by default, # except on Windows which currently needs special handling (see later): # Check whether --with-nc-config was given. if test ${with_nc_config+y} then : withval=$with_nc_config; else $as_nop with_nc_config=unset fi if test "x${with_nc_config}" = xunset then : if test "x$platform" = xWindows then : with_nc_config=no else $as_nop with_nc_config=yes fi fi if test "x${with_nc_config}" = xyes then : # Extract the first word of "nc-config", so it can be a program name with args. set dummy nc-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_have_nc_config+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$have_nc_config"; then ac_cv_prog_have_nc_config="$have_nc_config" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_have_nc_config="yes" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_have_nc_config" && ac_cv_prog_have_nc_config="no" fi fi have_nc_config=$ac_cv_prog_have_nc_config if test -n "$have_nc_config"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_nc_config" >&5 printf "%s\n" "$have_nc_config" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi else $as_nop have_nc_config=no fi # Check whether --with-nc-config-static was given. if test ${with_nc_config_static+y} then : withval=$with_nc_config_static; else $as_nop with_nc_config_static=unset fi if test "x${with_nc_config_static}" = xunset then : if test "x$platform" = xWindows || test "x$platform" = xmacOS then : with_nc_config_static=yes else $as_nop with_nc_config_static=no fi fi if test "x${have_nc_config}" = xyes then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Check compiler/linker variables from nc-config:" >&5 printf "%s\n" "$as_me: Check compiler/linker variables from nc-config:" >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking NC_CC" >&5 printf %s "checking NC_CC... " >&6; } NC_CC=`nc-config --cc` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${NC_CC}" >&5 printf "%s\n" "${NC_CC}" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking NC_CC matches selected C compiler" >&5 printf %s "checking NC_CC matches selected C compiler... " >&6; } if test "$CC" != "${NC_CC}" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no ... specify --with-mpicc if needed" >&5 printf "%s\n" "no ... specify --with-mpicc if needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking nc-config --cflags" >&5 printf %s "checking nc-config --cflags... " >&6; } NC_CFLAGS=`nc-config --cflags` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${NC_CFLAGS}" >&5 printf "%s\n" "${NC_CFLAGS}" >&6; } nc_config_static_flag="" if test "x${with_nc_config_static}" = xyes then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking nc-config allows --static option" >&5 printf %s "checking nc-config allows --static option... " >&6; } if nc-config --libs --static >/dev/null 2>&1 then : nc_config_static_flag="--static" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking nc-config --libs ${nc_config_static_flag}" >&5 printf %s "checking nc-config --libs ${nc_config_static_flag}... " >&6; } NC_LIBS=`nc-config --libs ${nc_config_static_flag}` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${NC_LIBS}" >&5 printf "%s\n" "${NC_LIBS}" >&6; } # Prepend to PKG variables: PKG_CFLAGS="${NC_CFLAGS} ${PKG_CFLAGS}" LIBS="${NC_LIBS} $LIBS" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Skipping nc-config" >&5 printf "%s\n" "$as_me: Skipping nc-config" >&6;} fi #-------------------------------------------------------------------------------# # Append R compiler/linker variables to PKG variables for feature tests # #-------------------------------------------------------------------------------# # CC is unchanged CFLAGS="${PKG_CFLAGS} ${R_CFLAGS}" CPPFLAGS="${PKG_CPPFLAGS} ${R_CPPFLAGS}" LDFLAGS="${PKG_LDFLAGS} ${R_LDFLAGS}" # No LIBS from R #-------------------------------------------------------------------------------# # Set libraries to link on Windows # #-------------------------------------------------------------------------------# # As of Rtools43, nc-config does not link all required libraries, # and it also tries to link libraries that are not installed. # If nc-config is fixed, this section could be removed, # and nc-config could be re-enabled above. if test "x$platform" = xWindows then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Find libraries that may be needed on Windows:" >&5 printf "%s\n" "$as_me: Find libraries that may be needed on Windows:" >&6;} LIBS="-ladvapi32 -lgdi32 -lcrypt32 -lwldap32 -lwsock32 -lws2_32 $LIBS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing atan" >&5 printf %s "checking for library containing atan... " >&6; } if test ${ac_cv_search_atan+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char atan (); int main (void) { return atan (); ; return 0; } _ACEOF for ac_lib in '' m do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_atan=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_atan+y} then : break fi done if test ${ac_cv_search_atan+y} then : else $as_nop ac_cv_search_atan=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_atan" >&5 printf "%s\n" "$ac_cv_search_atan" >&6; } ac_res=$ac_cv_search_atan if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_mutex_init" >&5 printf %s "checking for library containing pthread_mutex_init... " >&6; } if test ${ac_cv_search_pthread_mutex_init+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main (void) { return pthread_mutex_init (); ; return 0; } _ACEOF for ac_lib in '' pthread do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_pthread_mutex_init=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_pthread_mutex_init+y} then : break fi done if test ${ac_cv_search_pthread_mutex_init+y} then : else $as_nop ac_cv_search_pthread_mutex_init=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pthread_mutex_init" >&5 printf "%s\n" "$ac_cv_search_pthread_mutex_init" >&6; } ac_res=$ac_cv_search_pthread_mutex_init if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing lzma_lzma_decoder_init" >&5 printf %s "checking for library containing lzma_lzma_decoder_init... " >&6; } if test ${ac_cv_search_lzma_lzma_decoder_init+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char lzma_lzma_decoder_init (); int main (void) { return lzma_lzma_decoder_init (); ; return 0; } _ACEOF for ac_lib in '' lzma do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_lzma_lzma_decoder_init=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_lzma_lzma_decoder_init+y} then : break fi done if test ${ac_cv_search_lzma_lzma_decoder_init+y} then : else $as_nop ac_cv_search_lzma_lzma_decoder_init=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_lzma_lzma_decoder_init" >&5 printf "%s\n" "$ac_cv_search_lzma_lzma_decoder_init" >&6; } ac_res=$ac_cv_search_lzma_lzma_decoder_init if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing deflate" >&5 printf %s "checking for library containing deflate... " >&6; } if test ${ac_cv_search_deflate+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char deflate (); int main (void) { return deflate (); ; return 0; } _ACEOF for ac_lib in '' z do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_deflate=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_deflate+y} then : break fi done if test ${ac_cv_search_deflate+y} then : else $as_nop ac_cv_search_deflate=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_deflate" >&5 printf "%s\n" "$ac_cv_search_deflate" >&6; } ac_res=$ac_cv_search_deflate if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing ZSTD_decompress" >&5 printf %s "checking for library containing ZSTD_decompress... " >&6; } if test ${ac_cv_search_ZSTD_decompress+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char ZSTD_decompress (); int main (void) { return ZSTD_decompress (); ; return 0; } _ACEOF for ac_lib in '' zstd do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_ZSTD_decompress=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_ZSTD_decompress+y} then : break fi done if test ${ac_cv_search_ZSTD_decompress+y} then : else $as_nop ac_cv_search_ZSTD_decompress=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ZSTD_decompress" >&5 printf "%s\n" "$ac_cv_search_ZSTD_decompress" >&6; } ac_res=$ac_cv_search_ZSTD_decompress if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing SZ_BufftoBuffDecompress" >&5 printf %s "checking for library containing SZ_BufftoBuffDecompress... " >&6; } if test ${ac_cv_search_SZ_BufftoBuffDecompress+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char SZ_BufftoBuffDecompress (); int main (void) { return SZ_BufftoBuffDecompress (); ; return 0; } _ACEOF for ac_lib in '' sz do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_SZ_BufftoBuffDecompress=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_SZ_BufftoBuffDecompress+y} then : break fi done if test ${ac_cv_search_SZ_BufftoBuffDecompress+y} then : else $as_nop ac_cv_search_SZ_BufftoBuffDecompress=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_SZ_BufftoBuffDecompress" >&5 printf "%s\n" "$ac_cv_search_SZ_BufftoBuffDecompress" >&6; } ac_res=$ac_cv_search_SZ_BufftoBuffDecompress if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing BCryptDecrypt" >&5 printf %s "checking for library containing BCryptDecrypt... " >&6; } if test ${ac_cv_search_BCryptDecrypt+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char BCryptDecrypt (); int main (void) { return BCryptDecrypt (); ; return 0; } _ACEOF for ac_lib in '' bcrypt do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_BCryptDecrypt=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_BCryptDecrypt+y} then : break fi done if test ${ac_cv_search_BCryptDecrypt+y} then : else $as_nop ac_cv_search_BCryptDecrypt=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_BCryptDecrypt" >&5 printf "%s\n" "$ac_cv_search_BCryptDecrypt" >&6; } ac_res=$ac_cv_search_BCryptDecrypt if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing gpg_strerror" >&5 printf %s "checking for library containing gpg_strerror... " >&6; } if test ${ac_cv_search_gpg_strerror+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char gpg_strerror (); int main (void) { return gpg_strerror (); ; return 0; } _ACEOF for ac_lib in '' gpg-error do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_gpg_strerror=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_gpg_strerror+y} then : break fi done if test ${ac_cv_search_gpg_strerror+y} then : else $as_nop ac_cv_search_gpg_strerror=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gpg_strerror" >&5 printf "%s\n" "$ac_cv_search_gpg_strerror" >&6; } ac_res=$ac_cv_search_gpg_strerror if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing gcry_md_open" >&5 printf %s "checking for library containing gcry_md_open... " >&6; } if test ${ac_cv_search_gcry_md_open+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char gcry_md_open (); int main (void) { return gcry_md_open (); ; return 0; } _ACEOF for ac_lib in '' gcrypt do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_gcry_md_open=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_gcry_md_open+y} then : break fi done if test ${ac_cv_search_gcry_md_open+y} then : else $as_nop ac_cv_search_gcry_md_open=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gcry_md_open" >&5 printf "%s\n" "$ac_cv_search_gcry_md_open" >&6; } ac_res=$ac_cv_search_gcry_md_open if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing EVP_CIPHER_CTX_new" >&5 printf %s "checking for library containing EVP_CIPHER_CTX_new... " >&6; } if test ${ac_cv_search_EVP_CIPHER_CTX_new+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char EVP_CIPHER_CTX_new (); int main (void) { return EVP_CIPHER_CTX_new (); ; return 0; } _ACEOF for ac_lib in '' crypto do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_EVP_CIPHER_CTX_new=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_EVP_CIPHER_CTX_new+y} then : break fi done if test ${ac_cv_search_EVP_CIPHER_CTX_new+y} then : else $as_nop ac_cv_search_EVP_CIPHER_CTX_new=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_EVP_CIPHER_CTX_new" >&5 printf "%s\n" "$ac_cv_search_EVP_CIPHER_CTX_new" >&6; } ac_res=$ac_cv_search_EVP_CIPHER_CTX_new if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing SSL_CTX_new" >&5 printf %s "checking for library containing SSL_CTX_new... " >&6; } if test ${ac_cv_search_SSL_CTX_new+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char SSL_CTX_new (); int main (void) { return SSL_CTX_new (); ; return 0; } _ACEOF for ac_lib in '' ssl do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_SSL_CTX_new=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_SSL_CTX_new+y} then : break fi done if test ${ac_cv_search_SSL_CTX_new+y} then : else $as_nop ac_cv_search_SSL_CTX_new=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_SSL_CTX_new" >&5 printf "%s\n" "$ac_cv_search_SSL_CTX_new" >&6; } ac_res=$ac_cv_search_SSL_CTX_new if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing libssh2_init" >&5 printf %s "checking for library containing libssh2_init... " >&6; } if test ${ac_cv_search_libssh2_init+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char libssh2_init (); int main (void) { return libssh2_init (); ; return 0; } _ACEOF for ac_lib in '' ssh2 do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_libssh2_init=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_libssh2_init+y} then : break fi done if test ${ac_cv_search_libssh2_init+y} then : else $as_nop ac_cv_search_libssh2_init=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_libssh2_init" >&5 printf "%s\n" "$ac_cv_search_libssh2_init" >&6; } ac_res=$ac_cv_search_libssh2_init if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing libiconv_open" >&5 printf %s "checking for library containing libiconv_open... " >&6; } if test ${ac_cv_search_libiconv_open+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char libiconv_open (); int main (void) { return libiconv_open (); ; return 0; } _ACEOF for ac_lib in '' iconv do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_libiconv_open=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_libiconv_open+y} then : break fi done if test ${ac_cv_search_libiconv_open+y} then : else $as_nop ac_cv_search_libiconv_open=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_libiconv_open" >&5 printf "%s\n" "$ac_cv_search_libiconv_open" >&6; } ac_res=$ac_cv_search_libiconv_open if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing locale_charset" >&5 printf %s "checking for library containing locale_charset... " >&6; } if test ${ac_cv_search_locale_charset+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char locale_charset (); int main (void) { return locale_charset (); ; return 0; } _ACEOF for ac_lib in '' charset do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_locale_charset=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_locale_charset+y} then : break fi done if test ${ac_cv_search_locale_charset+y} then : else $as_nop ac_cv_search_locale_charset=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_locale_charset" >&5 printf "%s\n" "$ac_cv_search_locale_charset" >&6; } ac_res=$ac_cv_search_locale_charset if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing u8_to_u16" >&5 printf %s "checking for library containing u8_to_u16... " >&6; } if test ${ac_cv_search_u8_to_u16+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char u8_to_u16 (); int main (void) { return u8_to_u16 (); ; return 0; } _ACEOF for ac_lib in '' unistring do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_u8_to_u16=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_u8_to_u16+y} then : break fi done if test ${ac_cv_search_u8_to_u16+y} then : else $as_nop ac_cv_search_u8_to_u16=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_u8_to_u16" >&5 printf "%s\n" "$ac_cv_search_u8_to_u16" >&6; } ac_res=$ac_cv_search_u8_to_u16 if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing idn2_to_ascii_8z" >&5 printf %s "checking for library containing idn2_to_ascii_8z... " >&6; } if test ${ac_cv_search_idn2_to_ascii_8z+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char idn2_to_ascii_8z (); int main (void) { return idn2_to_ascii_8z (); ; return 0; } _ACEOF for ac_lib in '' idn2 do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_idn2_to_ascii_8z=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_idn2_to_ascii_8z+y} then : break fi done if test ${ac_cv_search_idn2_to_ascii_8z+y} then : else $as_nop ac_cv_search_idn2_to_ascii_8z=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_idn2_to_ascii_8z" >&5 printf "%s\n" "$ac_cv_search_idn2_to_ascii_8z" >&6; } ac_res=$ac_cv_search_idn2_to_ascii_8z if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing H5Fopen" >&5 printf %s "checking for library containing H5Fopen... " >&6; } if test ${ac_cv_search_H5Fopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char H5Fopen (); int main (void) { return H5Fopen (); ; return 0; } _ACEOF for ac_lib in '' hdf5 do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_H5Fopen=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_H5Fopen+y} then : break fi done if test ${ac_cv_search_H5Fopen+y} then : else $as_nop ac_cv_search_H5Fopen=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_H5Fopen" >&5 printf "%s\n" "$ac_cv_search_H5Fopen" >&6; } ac_res=$ac_cv_search_H5Fopen if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing H5TBmake_table" >&5 printf %s "checking for library containing H5TBmake_table... " >&6; } if test ${ac_cv_search_H5TBmake_table+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char H5TBmake_table (); int main (void) { return H5TBmake_table (); ; return 0; } _ACEOF for ac_lib in '' hdf5_hl do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_H5TBmake_table=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_H5TBmake_table+y} then : break fi done if test ${ac_cv_search_H5TBmake_table+y} then : else $as_nop ac_cv_search_H5TBmake_table=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_H5TBmake_table" >&5 printf "%s\n" "$ac_cv_search_H5TBmake_table" >&6; } ac_res=$ac_cv_search_H5TBmake_table if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing xdr_int" >&5 printf %s "checking for library containing xdr_int... " >&6; } if test ${ac_cv_search_xdr_int+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char xdr_int (); int main (void) { return xdr_int (); ; return 0; } _ACEOF for ac_lib in '' portablexdr do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_xdr_int=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_xdr_int+y} then : break fi done if test ${ac_cv_search_xdr_int+y} then : else $as_nop ac_cv_search_xdr_int=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_xdr_int" >&5 printf "%s\n" "$ac_cv_search_xdr_int" >&6; } ac_res=$ac_cv_search_xdr_int if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing xmlReadMemory" >&5 printf %s "checking for library containing xmlReadMemory... " >&6; } if test ${ac_cv_search_xmlReadMemory+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char xmlReadMemory (); int main (void) { return xmlReadMemory (); ; return 0; } _ACEOF for ac_lib in '' xml2 do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_xmlReadMemory=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_xmlReadMemory+y} then : break fi done if test ${ac_cv_search_xmlReadMemory+y} then : else $as_nop ac_cv_search_xmlReadMemory=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_xmlReadMemory" >&5 printf "%s\n" "$ac_cv_search_xmlReadMemory" >&6; } ac_res=$ac_cv_search_xmlReadMemory if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing nghttp2_submit_request" >&5 printf %s "checking for library containing nghttp2_submit_request... " >&6; } if test ${ac_cv_search_nghttp2_submit_request+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char nghttp2_submit_request (); int main (void) { return nghttp2_submit_request (); ; return 0; } _ACEOF for ac_lib in '' nghttp2 do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_nghttp2_submit_request=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_nghttp2_submit_request+y} then : break fi done if test ${ac_cv_search_nghttp2_submit_request+y} then : else $as_nop ac_cv_search_nghttp2_submit_request=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_nghttp2_submit_request" >&5 printf "%s\n" "$ac_cv_search_nghttp2_submit_request" >&6; } ac_res=$ac_cv_search_nghttp2_submit_request if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing curl_easy_init" >&5 printf %s "checking for library containing curl_easy_init... " >&6; } if test ${ac_cv_search_curl_easy_init+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char curl_easy_init (); int main (void) { return curl_easy_init (); ; return 0; } _ACEOF for ac_lib in '' curl do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_curl_easy_init=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_curl_easy_init+y} then : break fi done if test ${ac_cv_search_curl_easy_init+y} then : else $as_nop ac_cv_search_curl_easy_init=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_curl_easy_init" >&5 printf "%s\n" "$ac_cv_search_curl_easy_init" >&6; } ac_res=$ac_cv_search_curl_easy_init if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing jpeg_start_compress" >&5 printf %s "checking for library containing jpeg_start_compress... " >&6; } if test ${ac_cv_search_jpeg_start_compress+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char jpeg_start_compress (); int main (void) { return jpeg_start_compress (); ; return 0; } _ACEOF for ac_lib in '' jpeg do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_jpeg_start_compress=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_jpeg_start_compress+y} then : break fi done if test ${ac_cv_search_jpeg_start_compress+y} then : else $as_nop ac_cv_search_jpeg_start_compress=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_jpeg_start_compress" >&5 printf "%s\n" "$ac_cv_search_jpeg_start_compress" >&6; } ac_res=$ac_cv_search_jpeg_start_compress if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing Hopen" >&5 printf %s "checking for library containing Hopen... " >&6; } if test ${ac_cv_search_Hopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char Hopen (); int main (void) { return Hopen (); ; return 0; } _ACEOF for ac_lib in '' df do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_Hopen=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_Hopen+y} then : break fi done if test ${ac_cv_search_Hopen+y} then : else $as_nop ac_cv_search_Hopen=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_Hopen" >&5 printf "%s\n" "$ac_cv_search_Hopen" >&6; } ac_res=$ac_cv_search_Hopen if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing SDstart" >&5 printf %s "checking for library containing SDstart... " >&6; } if test ${ac_cv_search_SDstart+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char SDstart (); int main (void) { return SDstart (); ; return 0; } _ACEOF for ac_lib in '' mfhdf do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_SDstart=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_SDstart+y} then : break fi done if test ${ac_cv_search_SDstart+y} then : else $as_nop ac_cv_search_SDstart=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_SDstart" >&5 printf "%s\n" "$ac_cv_search_SDstart" >&6; } ac_res=$ac_cv_search_SDstart if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi fi #-------------------------------------------------------------------------------# # Check type sizes and language features supported by compiler # #-------------------------------------------------------------------------------# { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Check compiler type sizes and language features" >&5 printf "%s\n" "$as_me: Check compiler type sizes and language features" >&6;} # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 printf %s "checking size of int... " >&6; } if test ${ac_cv_sizeof_int+y} then : printf %s "(cached) " >&6 else $as_nop if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default" then : else $as_nop if test "$ac_cv_type_int" = yes; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_int=0 fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 printf "%s\n" "$ac_cv_sizeof_int" >&6; } printf "%s\n" "#define SIZEOF_INT $ac_cv_sizeof_int" >>confdefs.h # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5 printf %s "checking size of long long... " >&6; } if test ${ac_cv_sizeof_long_long+y} then : printf %s "(cached) " >&6 else $as_nop if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default" then : else $as_nop if test "$ac_cv_type_long_long" = yes; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long long) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long_long=0 fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5 printf "%s\n" "$ac_cv_sizeof_long_long" >&6; } printf "%s\n" "#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long" >>confdefs.h # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5 printf %s "checking size of size_t... " >&6; } if test ${ac_cv_sizeof_size_t+y} then : printf %s "(cached) " >&6 else $as_nop if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t" "$ac_includes_default" then : else $as_nop if test "$ac_cv_type_size_t" = yes; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (size_t) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_size_t=0 fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5 printf "%s\n" "$ac_cv_sizeof_size_t" >&6; } printf "%s\n" "#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C/C++ restrict keyword" >&5 printf %s "checking for C/C++ restrict keyword... " >&6; } if test ${ac_cv_c_restrict+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_c_restrict=no # Put '__restrict__' first, to avoid problems with glibc and non-GCC; see: # https://lists.gnu.org/archive/html/bug-autoconf/2016-02/msg00006.html # Put 'restrict' last, because C++ lacks it. for ac_kw in __restrict__ __restrict _Restrict restrict; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ typedef int *int_ptr; int foo (int_ptr $ac_kw ip) { return ip[0]; } int bar (int [$ac_kw]); /* Catch GCC bug 14050. */ int bar (int ip[$ac_kw]) { return ip[0]; } int main (void) { int s[1]; int *$ac_kw t = s; t[0] = 0; return foo (t) + bar (t); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_c_restrict=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext test "$ac_cv_c_restrict" != no && break done fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_restrict" >&5 printf "%s\n" "$ac_cv_c_restrict" >&6; } case $ac_cv_c_restrict in restrict) ;; no) printf "%s\n" "#define restrict /**/" >>confdefs.h ;; *) printf "%s\n" "#define restrict $ac_cv_c_restrict" >>confdefs.h ;; esac #-------------------------------------------------------------------------------# # Check NetCDF features # #-------------------------------------------------------------------------------# { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Check NetCDF features:" >&5 printf "%s\n" "$as_me: Check NetCDF features:" >&6;} # Check that netcdf header files can be compiled: for ac_header in netcdf.h do : ac_fn_c_check_header_compile "$LINENO" "netcdf.h" "ac_cv_header_netcdf_h" "$ac_includes_default" if test "x$ac_cv_header_netcdf_h" = xyes then : printf "%s\n" "#define HAVE_NETCDF_H 1" >>confdefs.h else $as_nop as_fn_error $? "netcdf.h was not compiled - defining CPPFLAGS may help" "$LINENO" 5 fi done # Check that netcdf library can be found. # Linker flags are prepended to LIBS if needed. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing nc_open" >&5 printf %s "checking for library containing nc_open... " >&6; } if test ${ac_cv_search_nc_open+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char nc_open (); int main (void) { return nc_open (); ; return 0; } _ACEOF for ac_lib in '' netcdf do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_nc_open=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_nc_open+y} then : break fi done if test ${ac_cv_search_nc_open+y} then : else $as_nop ac_cv_search_nc_open=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_nc_open" >&5 printf "%s\n" "$ac_cv_search_nc_open" >&6; } ac_res=$ac_cv_search_nc_open if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" else $as_nop as_fn_error $? "netcdf library was not linked - defining LDFLAGS may help" "$LINENO" 5 fi # Check for the existence of optional netcdf routines. # C preprocessor macros HAVE_routine are defined for existing routines. ac_fn_c_check_func "$LINENO" "nc_rename_grp" "ac_cv_func_nc_rename_grp" if test "x$ac_cv_func_nc_rename_grp" = xyes then : printf "%s\n" "#define HAVE_NC_RENAME_GRP 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "nc_get_var_chunk_cache" "ac_cv_func_nc_get_var_chunk_cache" if test "x$ac_cv_func_nc_get_var_chunk_cache" = xyes then : printf "%s\n" "#define HAVE_NC_GET_VAR_CHUNK_CACHE 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "nc_inq_var_szip" "ac_cv_func_nc_inq_var_szip" if test "x$ac_cv_func_nc_inq_var_szip" = xyes then : printf "%s\n" "#define HAVE_NC_INQ_VAR_SZIP 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "nc_inq_var_endian" "ac_cv_func_nc_inq_var_endian" if test "x$ac_cv_func_nc_inq_var_endian" = xyes then : printf "%s\n" "#define HAVE_NC_INQ_VAR_ENDIAN 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "nc_def_var_filter" "ac_cv_func_nc_def_var_filter" if test "x$ac_cv_func_nc_def_var_filter" = xyes then : printf "%s\n" "#define HAVE_NC_DEF_VAR_FILTER 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "nc_inq_var_filter_ids" "ac_cv_func_nc_inq_var_filter_ids" if test "x$ac_cv_func_nc_inq_var_filter_ids" = xyes then : printf "%s\n" "#define HAVE_NC_INQ_VAR_FILTER_IDS 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "nc_inq_var_filter_info" "ac_cv_func_nc_inq_var_filter_info" if test "x$ac_cv_func_nc_inq_var_filter_info" = xyes then : printf "%s\n" "#define HAVE_NC_INQ_VAR_FILTER_INFO 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "nc_reclaim_data" "ac_cv_func_nc_reclaim_data" if test "x$ac_cv_func_nc_reclaim_data" = xyes then : printf "%s\n" "#define HAVE_NC_RECLAIM_DATA 1" >>confdefs.h fi # Check for filter header file. ac_fn_c_check_header_compile "$LINENO" "netcdf_filter.h" "ac_cv_header_netcdf_filter_h" "#include " if test "x$ac_cv_header_netcdf_filter_h" = xyes then : printf "%s\n" "#define HAVE_NETCDF_FILTER_H 1" >>confdefs.h fi # Check for optional features that depend only on preprocessor declarations: ac_fn_check_decl "$LINENO" "NC_64BIT_DATA" "ac_cv_have_decl_NC_64BIT_DATA" "#include " "$ac_c_undeclared_builtin_options" "CFLAGS" if test "x$ac_cv_have_decl_NC_64BIT_DATA" = xyes then : ac_have_decl=1 else $as_nop ac_have_decl=0 fi printf "%s\n" "#define HAVE_DECL_NC_64BIT_DATA $ac_have_decl" >>confdefs.h ac_fn_check_decl "$LINENO" "NC_FORMAT_64BIT_DATA" "ac_cv_have_decl_NC_FORMAT_64BIT_DATA" "#include " "$ac_c_undeclared_builtin_options" "CFLAGS" if test "x$ac_cv_have_decl_NC_FORMAT_64BIT_DATA" = xyes then : ac_have_decl=1 else $as_nop ac_have_decl=0 fi printf "%s\n" "#define HAVE_DECL_NC_FORMAT_64BIT_DATA $ac_have_decl" >>confdefs.h ac_fn_check_decl "$LINENO" "NC_DISKLESS" "ac_cv_have_decl_NC_DISKLESS" "#include " "$ac_c_undeclared_builtin_options" "CFLAGS" if test "x$ac_cv_have_decl_NC_DISKLESS" = xyes then : ac_have_decl=1 else $as_nop ac_have_decl=0 fi printf "%s\n" "#define HAVE_DECL_NC_DISKLESS $ac_have_decl" >>confdefs.h ac_fn_check_decl "$LINENO" "NC_PERSIST" "ac_cv_have_decl_NC_PERSIST" "#include " "$ac_c_undeclared_builtin_options" "CFLAGS" if test "x$ac_cv_have_decl_NC_PERSIST" = xyes then : ac_have_decl=1 else $as_nop ac_have_decl=0 fi printf "%s\n" "#define HAVE_DECL_NC_PERSIST $ac_have_decl" >>confdefs.h #-------------------------------------------------------------------------------# # Check for parallel netcdf features # #-------------------------------------------------------------------------------# { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Check for parallel NetCDF features:" >&5 printf "%s\n" "$as_me: Check for parallel NetCDF features:" >&6;} # Check whether --with-mpiexec was given. if test ${with_mpiexec+y} then : withval=$with_mpiexec; mpiexec="$withval" else $as_nop mpiexec="" fi # MPI support: has_mpi=TRUE for ac_header in mpi.h do : ac_fn_c_check_header_compile "$LINENO" "mpi.h" "ac_cv_header_mpi_h" "$ac_includes_default" if test "x$ac_cv_header_mpi_h" = xyes then : printf "%s\n" "#define HAVE_MPI_H 1" >>confdefs.h else $as_nop has_mpi=FALSE fi done for ac_func in MPI_Init do : ac_fn_c_check_func "$LINENO" "MPI_Init" "ac_cv_func_MPI_Init" if test "x$ac_cv_func_MPI_Init" = xyes then : printf "%s\n" "#define HAVE_MPI_INIT 1" >>confdefs.h else $as_nop has_mpi=FALSE fi done if test "$has_mpi" != TRUE then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: MPI not available. Specify --with-mpicc if needed." >&5 printf "%s\n" "$as_me: WARNING: MPI not available. Specify --with-mpicc if needed." >&2;} fi # Parallel I/O support in NetCDF: if test "$has_mpi" = TRUE then : has_parallel=TRUE for ac_header in netcdf_par.h do : ac_fn_c_check_header_compile "$LINENO" "netcdf_par.h" "ac_cv_header_netcdf_par_h" "#include " if test "x$ac_cv_header_netcdf_par_h" = xyes then : printf "%s\n" "#define HAVE_NETCDF_PAR_H 1" >>confdefs.h else $as_nop has_parallel=FALSE fi done ac_fn_check_decl "$LINENO" "NC_COLLECTIVE" "ac_cv_have_decl_NC_COLLECTIVE" "#include #include " "$ac_c_undeclared_builtin_options" "CFLAGS" if test "x$ac_cv_have_decl_NC_COLLECTIVE" = xyes then : ac_have_decl=1 else $as_nop ac_have_decl=0 fi printf "%s\n" "#define HAVE_DECL_NC_COLLECTIVE $ac_have_decl" >>confdefs.h if test $ac_have_decl = 1 then : else $as_nop has_parallel=FALSE fi ac_fn_check_decl "$LINENO" "NC_INDEPENDENT" "ac_cv_have_decl_NC_INDEPENDENT" "#include #include " "$ac_c_undeclared_builtin_options" "CFLAGS" if test "x$ac_cv_have_decl_NC_INDEPENDENT" = xyes then : ac_have_decl=1 else $as_nop ac_have_decl=0 fi printf "%s\n" "#define HAVE_DECL_NC_INDEPENDENT $ac_have_decl" >>confdefs.h if test $ac_have_decl = 1 then : else $as_nop has_parallel=FALSE fi ac_fn_check_decl "$LINENO" "MPI_INFO_NULL" "ac_cv_have_decl_MPI_INFO_NULL" "#include " "$ac_c_undeclared_builtin_options" "CFLAGS" if test "x$ac_cv_have_decl_MPI_INFO_NULL" = xyes then : ac_have_decl=1 else $as_nop ac_have_decl=0 fi printf "%s\n" "#define HAVE_DECL_MPI_INFO_NULL $ac_have_decl" >>confdefs.h if test $ac_have_decl = 1 then : else $as_nop has_parallel=FALSE fi ac_fn_check_decl "$LINENO" "MPI_Info_c2f" "ac_cv_have_decl_MPI_Info_c2f" "#include " "$ac_c_undeclared_builtin_options" "CFLAGS" if test "x$ac_cv_have_decl_MPI_Info_c2f" = xyes then : ac_have_decl=1 else $as_nop ac_have_decl=0 fi printf "%s\n" "#define HAVE_DECL_MPI_INFO_C2F $ac_have_decl" >>confdefs.h if test $ac_have_decl = 1 then : else $as_nop has_parallel=FALSE fi for ac_func in nc_create_par_fortran nc_open_par_fortran nc_var_par_access do : as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes" then : cat >>confdefs.h <<_ACEOF #define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else $as_nop has_parallel=FALSE fi done if test "$has_parallel" = TRUE then : printf "%s\n" "#define HAVE_NETCDF_MPI 1" >>confdefs.h else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Parallel I/O not supported by NetCDF installation" >&5 printf "%s\n" "$as_me: WARNING: Parallel I/O not supported by NetCDF installation" >&2;} fi else $as_nop has_parallel=FALSE { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: NetCDF parallel I/O requires MPI" >&5 printf "%s\n" "$as_me: WARNING: NetCDF parallel I/O requires MPI" >&2;} fi #-------------------------------------------------------------------------------# # Find UDUNITS2 library and header files # #-------------------------------------------------------------------------------# { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Check for udunits2 features:" >&5 printf "%s\n" "$as_me: Check for udunits2 features:" >&6;} # The udunits2 library depends on expat, which may need to be linked explicitly: { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing XML_ErrorString" >&5 printf %s "checking for library containing XML_ErrorString... " >&6; } if test ${ac_cv_search_XML_ErrorString+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char XML_ErrorString (); int main (void) { return XML_ErrorString (); ; return 0; } _ACEOF for ac_lib in '' expat do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_XML_ErrorString=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_XML_ErrorString+y} then : break fi done if test ${ac_cv_search_XML_ErrorString+y} then : else $as_nop ac_cv_search_XML_ErrorString=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_XML_ErrorString" >&5 printf "%s\n" "$ac_cv_search_XML_ErrorString" >&6; } ac_res=$ac_cv_search_XML_ErrorString if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi # Check that selected routines from udunits2 can be used in programs, # including udunits2 in LIBS if needed. # Also search for udunits2.h on its own or in a subdirectory, # and define macro HAVE_UDUNITS2_H or HAVE_UDUNITS2_UDUNITS2_H accordingly. has_udunits=FALSE { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing ut_read_xml" >&5 printf %s "checking for library containing ut_read_xml... " >&6; } if test ${ac_cv_search_ut_read_xml+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char ut_read_xml (); int main (void) { return ut_read_xml (); ; return 0; } _ACEOF for ac_lib in '' udunits2 do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_ut_read_xml=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_ut_read_xml+y} then : break fi done if test ${ac_cv_search_ut_read_xml+y} then : else $as_nop ac_cv_search_ut_read_xml=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ut_read_xml" >&5 printf "%s\n" "$ac_cv_search_ut_read_xml" >&6; } ac_res=$ac_cv_search_ut_read_xml if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" ac_fn_c_check_func "$LINENO" "ut_offset_by_time" "ac_cv_func_ut_offset_by_time" if test "x$ac_cv_func_ut_offset_by_time" = xyes then : ac_fn_c_check_func "$LINENO" "ut_decode_time" "ac_cv_func_ut_decode_time" if test "x$ac_cv_func_ut_decode_time" = xyes then : ac_fn_c_check_func "$LINENO" "ut_encode_time" "ac_cv_func_ut_encode_time" if test "x$ac_cv_func_ut_encode_time" = xyes then : for ac_header in udunits2.h udunits2/udunits2.h do : as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes" then : cat >>confdefs.h <<_ACEOF #define `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF has_udunits=TRUE; break fi done fi fi fi fi # Define HAVE_LIBUDUNITS2 if all udunits2 checks were successful: if test "$has_udunits" = "TRUE" then : printf "%s\n" "#define HAVE_LIBUDUNITS2 1" >>confdefs.h else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: disabling calendar functions in RNetCDF" >&5 printf "%s\n" "$as_me: WARNING: disabling calendar functions in RNetCDF" >&2;} fi #-------------------------------------------------------------------------------# # Indicate optional features to R test script # #-------------------------------------------------------------------------------# if test "$ac_cv_have_decl_NC_64BIT_DATA" = "yes" -a \ "$ac_cv_have_decl_NC_FORMAT_64BIT_DATA" = "yes" then : has_data64=TRUE else $as_nop has_data64=FALSE fi if test "$ac_cv_have_decl_NC_DISKLESS" = "yes" -a \ "$ac_cv_have_decl_NC_PERSIST" = "yes" then : has_diskless=TRUE else $as_nop has_diskless=FALSE fi #-------------------------------------------------------------------------------# # Final configuration variables # #-------------------------------------------------------------------------------# { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Final compiler and linker variables for make: CC=$CC PKG_CFLAGS=${PKG_CFLAGS} PKG_CPPFLAGS=${PKG_CPPFLAGS} PKG_LDFLAGS=${PKG_LDFLAGS} LIBS=${LIBS}" >&5 printf "%s\n" "$as_me: Final compiler and linker variables for make: CC=$CC PKG_CFLAGS=${PKG_CFLAGS} PKG_CPPFLAGS=${PKG_CPPFLAGS} PKG_LDFLAGS=${PKG_LDFLAGS} LIBS=${LIBS}" >&6;} # CC and LIBS are substituted automatically. #-------------------------------------------------------------------------------# # Do substitution # #-------------------------------------------------------------------------------# ac_config_files="$ac_config_files src/Makefile.common R/config.R" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 printf "%s\n" "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' :mline /\\$/{ N s,\\\n,, b mline } t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by RNetCDF $as_me 2.9-2, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to the package provider." _ACEOF ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ RNetCDF config.status 2.9-2 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" Copyright (C) 2021 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) printf "%s\n" "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) printf "%s\n" "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) printf "%s\n" "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX printf "%s\n" "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "src/Makefile.common") CONFIG_FILES="$CONFIG_FILES src/Makefile.common" ;; "R/config.R") CONFIG_FILES="$CONFIG_FILES R/config.R" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" eval set X " :F $CONFIG_FILES " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 printf "%s\n" "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`printf "%s\n" "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi #-------------------------------------------------------------------------------# # Done # #-------------------------------------------------------------------------------#