RNetCDF/0000755000176200001440000000000013553005253011440 5ustar liggesusersRNetCDF/NAMESPACE0000755000176200001440000000011213440605615012657 0ustar liggesusersuseDynLib(RNetCDF, .registration = TRUE) exportPattern("^[^\\.].*\\.nc$") RNetCDF/LICENSE0000644000176200001440000002517213541627213012457 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-2019 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/0000755000176200001440000000000013551002772012601 5ustar liggesusersRNetCDF/tools/winlibs.R0000644000176200001440000000066213551002225014370 0ustar liggesusers# Download netcdf library and headers from rwinlib project VERSION <- commandArgs(TRUE) if(!file.exists(sprintf("../windows/netcdf-%s/include/netcdf.h", VERSION))){ if(getRversion() < "3.3.0") setInternet2() download.file(sprintf("https://github.com/rwinlib/netcdf/archive/v%s.zip", VERSION), "lib.zip", quiet = TRUE) dir.create("../windows", showWarnings = FALSE) unzip("lib.zip", exdir = "../windows") unlink("lib.zip") } RNetCDF/INSTALL0000644000176200001440000000605313552423027012477 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. The configure script can accept variables to define extra paths or libraries: CPPFLAGS='-I [-I ...]' extra directories of header files LDFLAGS='-L [-L ...]' extra directories for libraries LIBS='-l [-l ...]' libraries to link Definitions for the above variables may be appended to the configure command line. 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. R CMD INSTALL Example ===================== R CMD INSTALL --configure-args="CPPFLAGS=-I/sw/include \ LDFLAGS=-L/sw/lib LIBS=-lhdf5" RNetCDF_2.1-1.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.1-1.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.md0000644000176200001440000000071213532406374012725 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/0000755000176200001440000000000013546330606012220 5ustar liggesusersRNetCDF/man/read.nc.Rd0000644000176200001440000000431713546330606014026 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{http://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.Rd0000644000176200001440000001044313546330606014435 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=NA, filter_params=integer(0))} \arguments{ \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.} The following arguments are optional for datasets in "netcdf4" format (and ignored for other formats): \item{chunking}{\code{TRUE} selects chunking, \code{FALSE} implies contiguous storage, \code{NA} allows the NetCDF library to choose a storage layout.} \item{chunksizes}{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}{Integer indicating level of compression, from 0 (minimum) to 9 (maximum), or \code{NA} for no compression.} \item{shuffle}{\code{TRUE} to enable byte shuffling, which may improve compression with \code{deflate}.} \item{big_endian}{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{TRUE} to enable the fletcher32 checksum.} \item{filter_id}{Identifier of filter to associate with the variable, or \code{NA} for no filter. For information about the available filters, please see the NetCDF documentation. Ignored if the installed NetCDF library does not support this feature.} \item{filter_params}{Vector of \code{integer} parameters for the filter specified by \code{filter_id}. The meaning of the parameters depends on the filter implementation, and RNetCDF is unable to perform any validation. Ignored if no filter is defined or if the installed NetCDF library does not support this feature.} } \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{http://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.Rd0000644000176200001440000000264013546330606014447 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{http://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.Rd0000644000176200001440000002042013546330606014503 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{ \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}{Set the mode for handling missing values (\code{NA}) in numeric variables: 0=accept \code{_FillValue}, then \code{missing_value} attribute; 1=accept only \code{_FillValue} attribute; 2=accept only \code{missing_value} attribute; 3=no missing value conversion; 4=valid range from valid_min and valid_max or valid_range, fill value from _FillValue, with defaults for each type except \code{NC_BYTE} and \code{NC_UBYTE} (see \url{http://www.unidata.ucar.edu/software/netcdf/docs/attribute_conventions.html}).} \item{pack}{Variables are packed if \code{pack=TRUE} and the attributes \code{add_offset} and \code{scale_factor} are defined. Default is \code{FALSE}.} The arguments below apply only to datasets in "netcdf4" format. Reading and writing of variables involves a "chunk cache", and default cache settings are defined by the NetCDF library. Performance may be improved in some applications by adjusting the cache settings through the following options: \item{cache_bytes}{Size of chunk cache in bytes. Value of \code{NA} (default) implies no change.} \item{cache_slots}{Number of slots in chunk cache. Value of \code{NA} (default) implies no change.} \item{cache_preemption}{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. "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. "enum" arrays are stored in R as factor arrays. "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. "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 two attributes \code{add_offset} and \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).} \references{\url{http://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.Rd0000644000176200001440000000304013546330606015141 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.} \references{\url{http://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.Rd0000644000176200001440000000650413546330606014631 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 "compound", "enum", "opaque" or "vlen".} \item{size}{("opaque") Size in bytes of a single item of the opaque type.} \item{basetype}{("enum" or "vlen") Base type, given as the name or identifier of an existing NetCDF type. Only built-in integer types (e.g. "NC_INT") are allowed for \code{class} "enum".} \item{names}{("compound" or "enum") Name of each field or member (character vector).} \item{values}{("enum") Numeric value of each member (numeric vector).} \item{subtypes}{("compound") NetCDF type of each field, given by name (character vector) or identifier (numeric vector).} \item{dimsizes}{("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 "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}{ "compound" \tab Combines atomic and user-defined types into C-like structs. \cr "enum" \tab Set of named integer values, similar to an R \code{factor}. \cr "opaque" \tab Blobs of arbitrary data with a given size. \cr "vlen" \tab Variable length vectors of a given base type. \cr } \code{type.def.nc} may be repeated to insert additional members of an "enum" type or fields of a "compound" type. However, the size of a "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{http://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.Rd0000644000176200001440000001213513546330606014220 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., ``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. ``hours since 2000-01-01 00:00:00 +00:00'', or more simply ``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{http://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", installed.packages()["RNetCDF","Version"], sep="_")) att.put.nc(nc, "NC_GLOBAL", "history", "NC_CHAR", paste(Sys.time(), "File created")) att.put.nc(nc, "NC_GLOBAL", "references", "NC_CHAR", "http://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) # 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)) unlink(file1) } } \keyword{utilities} RNetCDF/man/utinit.nc.Rd0000644000176200001440000000155513541532702014424 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{http://www.unidata.ucar.edu/software/udunits/}} \author{Pavel Michna, Milton Woods} \keyword{utilities} RNetCDF/man/close.nc.Rd0000644000176200001440000000160213546330606014212 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{http://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.Rd0000644000176200001440000000412213546330606014463 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.} \references{\url{http://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.Rd0000644000176200001440000000325513541532702014734 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., ``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{http://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.Rd0000644000176200001440000000314013546330606014060 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{http://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.Rd0000644000176200001440000000356513546330606014060 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, ...) } \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{...}{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{http://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.Rd0000644000176200001440000000255113546330606015147 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 "/", otherwise only the immediate group of \code{ncid} is searched for a matching group name.} } \details{This function renames an existing group in a NetCDF dataset or group 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{http://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 support by early versions of the netcdf4 library) try(grp.rename.nc(grp, "newgroup")) close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/create.nc.Rd0000644000176200001440000000571113546330606014355 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)} \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 "classic", "offset64", "netcdf4" or "classic4". See below for details.} \item{large}{(Deprecated) \code{large=TRUE} sets the file format to "offset64" when \code{format="classic"}.} } \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{"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{"offset64"}{64-bit offset extension of original format, introduced by netcdf-3.6. Allows larger files and variables than "classic" format, but there remain some restrictions on files larger than 2GB.} \item{"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{"classic4"}{Same file format as "netcdf4", but this options 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{http://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.Rd0000644000176200001440000000330213546330606014611 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 "classic", "offset64", "classic4" or "netcdf4".} \item{libvers}{Version string of the NetCDF library in the current R session.} } \references{\url{http://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.Rd0000644000176200001440000000345413546330606014250 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{http://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/att.get.nc.Rd0000644000176200001440000000624513546330606014463 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}.} \details{This function returns the value of the attribute.} \references{\url{http://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.Rd0000644000176200001440000000204413546330606015125 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{http://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.Rd0000644000176200001440000000251213546330606015137 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 of the attribute to be deleted.} } \details{This function deletes a NetCDF attribute from a NetCDF dataset open for writing.} \references{\url{http://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.Rd0000644000176200001440000000454013546330606014652 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.} \references{\url{http://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.get.nc.Rd0000644000176200001440000002277713546330606014473 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{ \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}{Set the mode for handling missing values (\code{NA}) in numeric variables: 0=accept \code{_FillValue}, then \code{missing_value} attribute; 1=accept only \code{_FillValue} attribute; 2=accept only \code{missing_value} attribute; 3=no missing value conversion; 4=valid range from valid_min and valid_max or valid_range, fill value from _FillValue, with defaults for each type except \code{NC_BYTE} and \code{NC_UBYTE} (see \url{http://www.unidata.ucar.edu/software/netcdf/docs/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 \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 }} The arguments below apply only to datasets in "netcdf4" format. Reading and writing of variables involves a "chunk cache", and default cache settings are defined by the NetCDF library. Performance may be improved in some applications by adjusting the cache settings through the following options: \item{cache_bytes}{Size of chunk cache in bytes. Value of \code{NA} (default) implies no change.} \item{cache_slots}{Number of slots in chunk cache. Value of \code{NA} (default) implies no change.} \item{cache_preemption}{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 \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. "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. "enum" arrays are read into R as factor arrays. "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. "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.} \references{\url{http://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.Rd0000644000176200001440000000516413546330606014663 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 "builtin", "compound", "enum", "opaque" or "vlen".} \item{size}{Size in bytes of a single item of the type (or a single element of a "vlen").} \item{basetype}{("enum" or "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}{("enum" only) Named vector with numeric values of all members.} \item{offset}{("compound" only) Named vector with the offset of each field in bytes from the beginning of the compound type.} \item{subtype}{("compound" only) Named vector with the NetCDF type name of each field.} \item{dimsizes}{("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{http://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.Rd0000644000176200001440000000561013546330606014507 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{http://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.Rd0000644000176200001440000000351713546330606014441 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 files in 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{http://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.Rd0000644000176200001440000000566313546330606014476 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 "/", 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 "/". 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{http://www.unidata.ucar.edu/software/netcdf/}} \author{Pavel Michna, Milton Woods} \examples{ ## Create a new NetCDF dataset and define two dimensions file1 <- tempfile("grp.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, "NC_GLOBAL", "title", "NC_CHAR", "Data from Foo") att.put.nc(nc, "NC_GLOBAL", "history", "NC_CHAR", paste("Created on", date())) ## Inquire about the root group grp.inq.nc(nc) close.nc(nc) unlink(file1) } \keyword{file} RNetCDF/man/var.rename.nc.Rd0000644000176200001440000000227113546330606015146 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{http://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.Rd0000644000176200001440000000714013546330606014466 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 "netcdf4" format (as indicated 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.} The arguments below apply only to datasets in "netcdf4" format: \item{chunksizes}{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}{Size of chunk cache in bytes (\code{NULL} if unsupported).} \item{cache_slots}{The number of slots in the chunk cache (\code{NULL} if unsupported).} \item{cache_preemption}{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}{Integer indicating level of compression, from 0 (minimum) to 9 (maximum), or \code{NA} if compression is not enabled.} \item{shuffle}{\code{TRUE} if byte shuffling is enabled for the variable, \code{FALSE} otherwise.} \item{big_endian}{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{TRUE} if the fletcher32 checksum is enabled for this variable, \code{FALSE} otherwise.} \item{szip_options}{Integer containing a bitmask of szip options. \code{NA} if szip is not used, or \code{NULL} if unsupported.} \item{szip_bits}{Number of bits per pixel for szip. \code{NA} if szip is not used, or \code{NULL} if unsupported.} \item{filter_id}{Identifier of filter associated with the variable. \code{NA} if no filter is defined, or \code{NULL} if unsupported.} \item{filter_params}{Vector of integer parameters for the filter associated with the variable. \code{NA} if no filter is defined, or \code{NULL} if unsupported.} } \details{This function returns information about a NetCDF variable. Information about a variable include its name, its ID, its type, its number of dimensions, a vector of the dimension IDs of this variable and the number of attributes.} \references{\url{http://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.Rd0000644000176200001440000001107713541627213014040 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.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 ``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{http://www.unidata.ucar.edu/software/netcdf/} \url{http://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.} \author{Pavel Michna, Milton Woods} \keyword{file} RNetCDF/man/dim.def.nc.Rd0000644000176200001440000000370313546330606014417 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{http://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/DESCRIPTION0000644000176200001440000000220113553005253013141 0ustar liggesusersPackage: RNetCDF Version: 2.1-1 Date: 2019-10-18 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 udunits-2 Suggests: bit64 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 http://www.unidata.ucar.edu/software/netcdf/ http://www.unidata.ucar.edu/software/udunits/ BugReports: https://github.com/mjwoods/RNetCDF/issues NeedsCompilation: yes Packaged: 2019-10-19 08:59:31 UTC; mwoods Author: Pavel Michna [aut], Milton Woods [aut, cre] Maintainer: Milton Woods Repository: CRAN Date/Publication: 2019-10-20 07:20:11 UTC RNetCDF/tests/0000755000176200001440000000000013552423027012604 5ustar liggesusersRNetCDF/tests/RNetCDF-test.R0000644000176200001440000007242313552423027015101 0ustar liggesusers#===============================================================================# # # Name: RNetCDF-test.R # # Version: 2.1-1 # # Purpose: Test functions to the NetCDF interface for R. # # Author: Pavel Michna (rnetcdf-devel@bluewin.ch) # Milton Woods (miltonjwoods@gmail.com) # # Copyright: (C) 2010-2019 Pavel Michna, 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. # #===============================================================================# #===============================================================================# # Load library #===============================================================================# library(RNetCDF) has_bit64 <- require(bit64) #===============================================================================# # 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","classic4","netcdf4")) { ncfile <- tempfile(paste("RNetCDF-test", format, "", sep="_"), fileext=".nc") cat("Test", format, "file format in", ncfile, "...\n") nc <- create.nc(ncfile, format=format) # Show library version: libvers <- file.inq.nc(nc)$libvers cat("Version of netcdf library ... ", libvers, "\n") nstation <- 5 ntime <- 2 nstring <- 32 nempty <- 0 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) if (format == "netcdf4") { ## Define a group ncroot <- nc nc <- grp.def.nc(nc, "testgrp") ## Define a type of each class: 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_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_UBYTE", names=c("peanut butter", "jelly"), values=c(101, 102)) inq_factor <- list(id=id_factor, name="factor", class="enum", size=1, basetype="NC_UBYTE", value=c("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_blob,id_factor,id_struct) } ## Define variables 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, "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 <- 8 numtypes <- c("NC_BYTE", "NC_SHORT", "NC_INT", "NC_FLOAT", "NC_DOUBLE") if (format == "netcdf4") { var.def.nc(nc, "namestr", "NC_STRING", c("station")) var.def.nc(nc, "profile", id_vector, c("station","time")) var.def.nc(nc, "profile_char", id_vector_char, 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, "person", "struct", c("station", "time")) varcnt <- varcnt+10 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") } } for (numtype in numtypes) { var.def.nc(nc, numtype, numtype, c("station")) var.def.nc(nc, paste(numtype,"_int",sep=""), numtype, c("station")) var.def.nc(nc, paste(numtype,"_fill",sep=""), numtype, c("station")) att.put.nc(nc, paste(numtype,"_fill",sep=""), "_FillValue", numtype, 99) var.def.nc(nc, paste(numtype,"_intfill",sep=""), numtype, c("station")) att.put.nc(nc, paste(numtype,"_intfill",sep=""), "_FillValue", numtype, 99) var.def.nc(nc, paste(numtype,"_pack",sep=""), numtype, c("station")) att.put.nc(nc, paste(numtype,"_pack",sep=""), "scale_factor", numtype, 10) att.put.nc(nc, paste(numtype,"_pack",sep=""), "add_offset", numtype, 5) var.def.nc(nc, paste(numtype,"_intpack",sep=""), numtype, c("station")) att.put.nc(nc, paste(numtype,"_intpack",sep=""), "scale_factor", numtype, 10) att.put.nc(nc, paste(numtype,"_intpack",sep=""), "add_offset", numtype, 5) varcnt <- varcnt+6 } ## 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) ## 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)) if (format == "netcdf4") { att.put.nc(nc, "temperature", "string_att", "NC_STRING", att_text2) 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) } } ## 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 <- "?" 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 <- mysmall*10+5 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[[ii,jj]] <- seq_len(ii+jj)*(ii+jj) } } profiles_char <- lapply(profiles,function(x) {paste(as.character(x),collapse=",")}) dim(profiles_char) <- dim(profiles) rawdata <- as.raw(seq_len(nstation*ntime*128) %% 256) dim(rawdata) <- c(128,nstation,ntime) profiles_blob <- list(rawdata[,1:2,1], rawdata[,3:5,1]) dim(profiles_blob) <- ntime snack_foods <- names(inq_factor$value) snacks <- factor(rep(snack_foods,times=5), levels=snack_foods) dim(snacks) <- c(nstation, ntime) 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))) } ## Define some user-defined test attributes: if (format == "netcdf4") { 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]) } ## Put the data cat("Writing variables ...\n") 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, "qcflag", charToRaw(myqcflag)) var.put.nc(nc, "int0", myint0) var.put.nc(nc, "char0", mychar0) if (format == "netcdf4") { var.put.nc(nc, "namestr", myname) var.put.nc(nc, "profile", profiles) var.put.nc(nc, "profile_char", profiles_char) 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]) var.put.nc(nc, "snacks", snacks) var.put.nc(nc, "person", person) if (has_bit64) { myid <- as.integer64("1234567890123456789")+c(0,1,2,3,4) var.put.nc(nc, "stationid", myid) } } for (numtype in numtypes) { # Should not succeed except for NC_DOUBLE: y <- try(var.put.nc(nc, numtype, mybig), silent=TRUE) tally <- testfun(inherits(y, "try-error"), numtype!="NC_DOUBLE", tally) y <- try(var.put.nc(nc, paste(numtype,"_fill",sep=""), mybigfill), silent=TRUE) tally <- testfun(inherits(y, "try-error"), numtype!="NC_DOUBLE", tally) # Should not succeed for unsigned types: y <- try(var.put.nc(nc, numtype, myminus), silent=TRUE) tally <- testfun(inherits(y, "try-error"), any(numtype==c("NC_UBYTE", "NC_USHORT", "NC_UINT", "NC_UINT64")), tally) # Should succeed for all types: var.put.nc(nc, numtype, mysmall) var.put.nc(nc, paste(numtype,"_int",sep=""), as.integer(mysmall)) var.put.nc(nc, paste(numtype,"_fill",sep=""), mysmallfill) var.put.nc(nc, paste(numtype,"_intfill",sep=""), as.integer(mysmallfill)) var.put.nc(nc, paste(numtype,"_pack",sep=""), mypack, pack=TRUE) var.put.nc(nc, paste(numtype,"_intpack",sep=""), as.integer(mypack), pack=TRUE) } 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) } # 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) { cat("Read", numtype, "...") x <- mysmall dim(x) <- length(x) y <- var.get.nc(nc, numtype) tally <- testfun(x,y,tally) tally <- testfun(is.double(y),TRUE,tally) y <- var.get.nc(nc, paste(numtype,"_int",sep="")) tally <- testfun(x,y,tally) tally <- testfun(is.double(y),TRUE,tally) x <- mysmallfill dim(x) <- length(x) y <- var.get.nc(nc, paste(numtype,"_fill",sep="")) tally <- testfun(x,y,tally) tally <- testfun(is.double(y),TRUE,tally) y <- var.get.nc(nc, paste(numtype,"_intfill",sep="")) tally <- testfun(x,y,tally) tally <- testfun(is.double(y),TRUE,tally) x <- mypack dim(x) <- length(x) y <- var.get.nc(nc, paste(numtype,"_pack",sep=""), unpack=TRUE) tally <- testfun(x,y,tally) tally <- testfun(is.double(y),TRUE,tally) y <- var.get.nc(nc, paste(numtype,"_intpack",sep=""), unpack=TRUE) 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) y <- var.get.nc(nc, numtype, 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) y <- var.get.nc(nc, paste(numtype,"_fill",sep=""), 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 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 <- myname dim(x) <- length(x) y <- var.get.nc(nc, "namestr") tally <- testfun(x,y,tally) cat("Read 1D string slice ...") x <- myname[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 <- myid 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 scalar ...") x <- profiles[1] y <- var.get.nc(nc, "profile_scalar") tally <- testfun(x,y,tally) cat("Read vlen as character ...") x <- profiles_char y <- var.get.nc(nc, "profile_char") tally <- testfun(x,y,tally) cat("Read 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 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") tally <- testfun(x,y,tally) cat("Read compound ...") x <- person y <- var.get.nc(nc, "person") 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") } #-------------------------------------------------------------------------------# # UDUNITS calendar functions #-------------------------------------------------------------------------------# # Test if udunits support is available: 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 { 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("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) } # Check that package can be unloaded: cat("Unload RNetCDF ...") detach("package:RNetCDF",unload=TRUE) #-------------------------------------------------------------------------------# # Overall summary #-------------------------------------------------------------------------------# cat("Summary:", tally["pass"], "pass /", tally["fail"], "fail. ") if (tally["fail"]==0) { cat("Package seems to work properly.\n") } else { stop(tally["fail"]," of ",sum(tally)," test cases failed.") } #===============================================================================# #===============================================================================# # SCRATCH #===============================================================================# RNetCDF/configure.ac0000644000176200001440000000764213552547644013755 0ustar liggesusers#-------------------------------------------------------------------------------# # Initialize # #-------------------------------------------------------------------------------# AC_INIT([RNetCDF], [2.1-1]) #-------------------------------------------------------------------------------# # Find the compiler and compiler options to use for tests # #-------------------------------------------------------------------------------# : ${R_HOME=`R RHOME`} AS_IF([test -z "${R_HOME}"], AC_MSG_ERROR([could not determine R_HOME]) ) CC=`"${R_HOME}/bin/R" CMD config CC` CFLAGS=`"${R_HOME}/bin/R" CMD config CFLAGS` # Prepend user-specified CPPFLAGS to those from R: R_CPPFLAGS=`"${R_HOME}/bin/R" CMD config CPPFLAGS` CPPFLAGS="$CPPFLAGS $R_CPPFLAGS" #-------------------------------------------------------------------------------# # Find NetCDF library and header files # #-------------------------------------------------------------------------------# AC_ARG_WITH([nc-config], AS_HELP_STRING([--without-nc-config], [do not use nc-config to get netcdf configuration]), [], [with_nc_config=yes]) AS_IF([test "x$with_nc_config" != xno], [AC_CHECK_PROG(have_nc_config, nc-config, yes, no, [], [])] ) AS_IF([test "x$have_nc_config" == xyes], [ # Prepend linker flags to LDFLAGS: AC_MSG_CHECKING(netcdf linker flags) NETCDF_LIBS=`nc-config --libs` AC_MSG_RESULT($NETCDF_LIBS) LDFLAGS="$NETCDF_LIBS $LDFLAGS" # Prepend preprocessor and compiler flags to CPPFLAGS: AC_MSG_CHECKING(netcdf preprocessor and compiler flags) NETCDF_CFLAGS=`nc-config --cflags` AC_MSG_RESULT($NETCDF_CFLAGS) CPPFLAGS="$NETCDF_CFLAGS $CPPFLAGS" ] ) # 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_inq_var_filter]) #-------------------------------------------------------------------------------# # Find UDUNITS2 library and header files # #-------------------------------------------------------------------------------# # 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. 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, [enable_calendar=yes; break] ) ) ) ) ) # Define HAVE_LIBUDUNITS2 if all udunits2 checks were successful: AS_IF([test "x$enable_calendar" == xyes], AC_DEFINE(HAVE_LIBUDUNITS2), AC_MSG_WARN([disabling calendar functions in RNetCDF]) ) #-------------------------------------------------------------------------------# # Do substitution # #-------------------------------------------------------------------------------# AC_OUTPUT(src/Makevars) #-------------------------------------------------------------------------------# # Done # #-------------------------------------------------------------------------------# RNetCDF/src/0000755000176200001440000000000013552547774012251 5ustar liggesusersRNetCDF/src/RNetCDF.h0000644000176200001440000000742313552423027013575 0ustar liggesusers/*=============================================================================*\ * * Name: RNetCDF.h * * Version: 2.1-1 * * Purpose: Declare RNetCDF functions callable from R * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright: (C) 2004-2019 Pavel Michna, 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 R_nc_inq_file (SEXP nc); SEXP R_nc_open (SEXP filename, SEXP write, SEXP share, SEXP prefill); 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 (); /* 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_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.c0000644000176200001440000002371213552423027014075 0ustar liggesusers/*=============================================================================*\ * * Name: udunits.c * * Version: 2.1-1 * * Purpose: udunits2 functions for RNetCDF. * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright: (C) 2004-2019 Pavel Michna, 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) { RERROR ("RNetCDF was built without UDUNITS-2"); } SEXP R_nc_utinit (SEXP path) { RRETURN(R_NilValue); } SEXP R_nc_inv_calendar (SEXP unitstring, SEXP values) { RERROR ("RNetCDF was built without UDUNITS-2"); } SEXP R_nc_utterm () { RRETURN(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 = R_nc_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) { RERROR (R_nc_uterror (status)); } RRETURN(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) { RERROR (R_nc_uterror (ut_get_status ())); } RRETURN(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 = R_nc_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) { RERROR (R_nc_uterror (status)); } RRETURN(result); } /*-----------------------------------------------------------------------------*\ * R_nc_utterm() \*-----------------------------------------------------------------------------*/ SEXP R_nc_utterm () { if (R_nc_units) { ut_free_system (R_nc_units); R_nc_units = NULL; } RRETURN(R_NilValue); } #endif /* Conditional compilation with UDUNITS2 */ RNetCDF/src/init.c0000644000176200001440000000654213552423027013347 0ustar liggesusers/*=============================================================================*\ * * Name: common.c * * Version: 2.1-1 * * Purpose: RNetCDF initialisation * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright: (C) 2004-2019 Pavel Michna, 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, 5}, {"R_nc_inq_file", (DL_FUNC) &R_nc_inq_file, 1}, {"R_nc_open", (DL_FUNC) &R_nc_open, 4}, {"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_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.c0000644000176200001440000003740013552423027013362 0ustar liggesusers/*=============================================================================*\ * * Name: type.c * * Version: 2.1-1 * * Purpose: NetCDF type functions for RNetCDF * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright: (C) 2004-2019 Pavel Michna, 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 (xlength (subtypes) != nfld || xlength (dimsizes) != nfld) { R_nc_error ("Lengths of names, subtypes and dimsizes must match"); } else if (nfld < 1) { R_nc_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) { R_nc_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 { R_nc_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 (xlength (names) != nval) { R_nc_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) { R_nc_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; SEXP result; /*-- 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 { RERROR ("Unknown class for type definition"); } result = R_nc_protect (ScalarInteger (typeid)); RRETURN(result); } /*-----------------------------------------------------------------------------*\ * 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 { RERROR ("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) { RERROR("Field exceeds size of compound type") } // Keep size checks; allow repeat definition with same details. } else { RERROR ("Missing offset or subtype for compound type"); } } else { RERROR ("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)); } } RRETURN(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) { /* Read named vectors of offsets, typenames, list of array dimensions */ fieldnames = R_nc_protect (allocVector (STRSXP, nfields)); offsets = R_nc_protect (allocVector (REALSXP, nfields)); subnames = R_nc_protect (allocVector (STRSXP, nfields)); dimsizes = R_nc_protect (allocVector (VECSXP, nfields)); 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, mkChar (fieldname)); REAL (offsets)[ii] = offset; R_nc_check (R_nc_type2str (ncid, subtype, subname)); SET_STRING_ELT (subnames, ii, mkChar (subname)); if (ndims > 0) { dimsize = R_nc_protect (allocVector (INTSXP, ndims)); R_nc_check (nc_inq_compound_fielddim_sizes ( ncid, xtype, ii, INTEGER (dimsize))); SET_VECTOR_ELT (dimsizes, ii, dimsize); } } setAttrib (offsets, R_NamesSymbol, fieldnames); setAttrib (subnames, R_NamesSymbol, fieldnames); setAttrib (dimsizes, R_NamesSymbol, fieldnames); result = R_nc_protect (allocVector (VECSXP, 7)); SET_VECTOR_ELT (result, 4, offsets); SET_VECTOR_ELT (result, 5, subnames); SET_VECTOR_ELT (result, 6, dimsizes); resultnames = R_nc_protect (allocVector (STRSXP, 7)); SET_STRING_ELT (resultnames, 4, mkChar ("offset")); SET_STRING_ELT (resultnames, 5, mkChar ("subtype")); SET_STRING_ELT (resultnames, 6, mkChar ("dimsizes")); } else { result = R_nc_protect (allocVector (VECSXP, 4)); resultnames = R_nc_protect (allocVector (STRSXP, 4)); } SET_VECTOR_ELT (result, 2, mkString ("compound")); break; case NC_ENUM: R_nc_check (R_nc_type2str (ncid, basetype, basename)); if (extend) { /* Read named vector of member values */ fieldnames = R_nc_protect (allocVector (STRSXP, nfields)); cval = R_nc_c2r_init (&io, NULL, 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, mkChar (fieldname)); } values = R_nc_c2r (&io); setAttrib (values, R_NamesSymbol, fieldnames); result = R_nc_protect (allocVector (VECSXP, 6)); SET_VECTOR_ELT (result, 5, values); resultnames = R_nc_protect (allocVector (STRSXP, 6)); SET_STRING_ELT (resultnames, 5, mkChar ("value")); } else { result = R_nc_protect (allocVector (VECSXP, 5)); resultnames = R_nc_protect (allocVector (STRSXP, 5)); } SET_VECTOR_ELT (result, 2, mkString ("enum")); SET_VECTOR_ELT (result, 4, mkString (basename)); SET_STRING_ELT (resultnames, 4, mkChar ("basetype")); break; case NC_OPAQUE: result = R_nc_protect (allocVector (VECSXP, 4)); SET_VECTOR_ELT (result, 2, mkString ("opaque")); resultnames = R_nc_protect (allocVector (STRSXP, 4)); break; case NC_VLEN: R_nc_check (R_nc_type2str (ncid, basetype, basename)); result = R_nc_protect (allocVector (VECSXP, 5)); SET_VECTOR_ELT (result, 2, mkString ("vlen")); SET_VECTOR_ELT (result, 4, mkString (basename)); resultnames = R_nc_protect (allocVector (STRSXP, 5)); SET_STRING_ELT (resultnames, 4, mkChar ("basetype")); break; default: R_nc_error ("Unknown class of user defined type"); } } else { /*-- Built-in types ---------------------------------------------------------*/ result = R_nc_protect (allocVector (VECSXP, 4)); SET_VECTOR_ELT (result, 2, mkString ("builtin")); resultnames = R_nc_protect (allocVector (STRSXP, 4)); } /*-- Common components of output list ----------------------------------------------*/ SET_VECTOR_ELT (result, 0, ScalarInteger (xtype)); SET_VECTOR_ELT (result, 1, mkString (typename)); SET_VECTOR_ELT (result, 3, ScalarReal (size)); SET_STRING_ELT (resultnames, 0, mkChar ("id")); SET_STRING_ELT (resultnames, 1, mkChar ("name")); SET_STRING_ELT (resultnames, 2, mkChar ("class")); SET_STRING_ELT (resultnames, 3, mkChar ("size")); setAttrib (result, R_NamesSymbol, resultnames); RRETURN(result); } RNetCDF/src/attribute.c0000644000176200001440000002511713552423027014406 0ustar liggesusers/*=============================================================================* * * Name: attribute.c * * Version: 2.1-1 * * Purpose: NetCDF attribute functions for RNetCDF * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright: (C) 2004-2019 Pavel Michna, 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)); RRETURN(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)); RRETURN(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 = R_nc_c2r_init (&io, NULL, 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)); } result = R_nc_c2r (&io); RRETURN (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 = R_nc_protect (allocVector (VECSXP, 4)); SET_VECTOR_ELT (result, 0, ScalarInteger (attid)); SET_VECTOR_ELT (result, 1, mkString (attname)); SET_VECTOR_ELT (result, 2, mkString (atttype)); /* cnt may not fit in integer, so return as double */ SET_VECTOR_ELT (result, 3, ScalarReal (cnt)); RRETURN(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)); } RRETURN (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)); RRETURN(R_NilValue); } RNetCDF/src/convert.c0000644000176200001440000014601213552423027014061 0ustar liggesusers/*=============================================================================*\ * * Name: convert.c * * Version: 2.1-1 * * Purpose: Type conversions for RNetCDF * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright: (C) 2004-2019 Pavel Michna, 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 \*=============================================================================*/ #define RNC_CHARSXP_MAXLEN 2147483647 #ifdef __WIN32__ # define RNC_FMT_LL "%I64d" #else # define RNC_FMT_LL "%lld" #endif #ifdef __WIN32__ # define RNC_FMT_ULL "%I64u" #else # define RNC_FMT_ULL "%llu" #endif #define RNC_DBL_DIG 24 /* 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 = R_nc_protect( allocVector (INTSXP, ndims)); intp = INTEGER (rdim); for ( ii=0, jj=ndims-1; ii 0) { /* Omit fastest-varying dimension from R character array */ strlen = xdim[ndim-1]; cnt = R_nc_length (ndim-1, xdim); } else if (ndim == 0) { /* Scalar character */ strlen = 1; cnt = 1; } else { /* Single string */ strlen = xdim[0]; cnt = 1; } if (xlength (rstr) < cnt) { RERROR (RNC_EDATALEN); } carr = R_alloc (cnt*strlen, sizeof (char)); for (ii=0, thisstr=carr; iindim > 0) { io->rxp = R_nc_allocArray (STRSXP, (io->ndim)-1, io->xdim); } else { /* Single character or string */ io->rxp = R_nc_allocArray (STRSXP, 0, io->xdim); } if (!io->cbuf) { io->cbuf = R_alloc (R_nc_length (io->ndim, io->xdim), sizeof (char)); } } static void R_nc_char_strsxp (R_nc_buf *io) { size_t ii, cnt, clen, rlen; char *thisstr, *endstr; 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); for (ii=0, thisstr=io->cbuf; iirxp, ii, mkCharLen (thisstr, rlen)); } else { SET_STRING_ELT (io->rxp, ii, mkChar (thisstr)); } } } 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 (xlength (rarr) < cnt) { RERROR (RNC_EDATALEN); } return (const char *) RAW (rarr); } static void R_nc_char_raw_init (R_nc_buf *io) { io->rxp = R_nc_allocArray (RAWSXP, io->ndim, io->xdim); io->rbuf = RAW (io->rxp); if (!io->cbuf) { io->cbuf = io->rbuf; } } 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 ii, cnt; const char **cstr; cnt = R_nc_length (ndim, xdim); if (xlength (rstr) < cnt) { RERROR (RNC_EDATALEN); } cstr = (const char **) R_alloc (cnt, sizeof(size_t)); for (ii=0; iirxp = R_nc_allocArray (STRSXP, io->ndim, io->xdim); if (!io->cbuf) { io->cbuf = R_alloc (xlength (io->rxp), sizeof(size_t)); } } static void R_nc_str_strsxp (R_nc_buf *io) { size_t ii, nchar, cnt; char **cstr; cnt = xlength (io->rxp); cstr = (char **) io->cbuf; for (ii=0; ii RNC_CHARSXP_MAXLEN) { /* Truncate excessively long strings while reading into R */ SET_STRING_ELT (io->rxp, ii, mkCharLen (cstr[ii], RNC_CHARSXP_MAXLEN)); } else if (nchar > 0) { SET_STRING_ELT (io->rxp, ii, mkChar (cstr[ii])); } } /* Free pointers to strings created by netcdf */ if (cnt > 0) { R_nc_check (nc_free_string (cnt, io->cbuf)); } } /*=============================================================================*\ * Numeric type conversions \*=============================================================================*/ #define R_NC_ISNA_INT(value) (value==NA_INTEGER) #define R_NC_ISNA_REAL(value) (ISNAN(value)) #define R_NC_ISNA_BIT64(value) (value==NA_INTEGER64) #define R_NC_RANGE_MIN(VAL,LIM,TYPE) ((TYPE) LIM <= (TYPE) VAL) #define R_NC_RANGE_MAX(VAL,LIM,TYPE) ((TYPE) VAL <= (TYPE) LIM) #define R_NC_RANGE_NONE(VAL,LIM,TYPE) (1) /* 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. For certain combinations of types, some or all range checks are always true, and we assume that an optimising compiler will remove these checks. */ #define R_NC_R2C_NUM(FUN, \ NCITYPE, ITYPE, IFUN, NCOTYPE, OTYPE, \ NATEST, MINTEST, MINVAL, MAXTEST, MAXVAL) \ 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; \ int erange=0, efill=0; \ double factor, offset; \ const ITYPE *in; \ OTYPE fillval, *out; \ in = (ITYPE *) IFUN (rv); \ cnt = R_nc_length (ndim, xdim); \ if (xlength (rv) < cnt) { \ RERROR (RNC_EDATALEN); \ } \ if (fill || scale || add || (NCITYPE != NCOTYPE)) { \ out = (OTYPE *) R_alloc (cnt, sizeof(OTYPE)); \ } else { \ out = (OTYPE *) IFUN (rv); \ } \ if (scale) { \ factor = *scale; \ } else { \ factor = 1.0; \ } \ if (add) { \ offset = *add; \ } else { \ offset = 0.0; \ } \ if (fill) { \ if (fillsize != sizeof(OTYPE)) { \ R_nc_error ("Size of fill value does not match output type"); \ } \ fillval = *fill; \ } \ for (ii=0; ii SIZE_MAX /* size_t is smaller than unsigned long long. Only allow positive values of bit64 */ R_NC_R2C_NUM(R_nc_r2c_bit64_size, NC_INT64, long long, REAL, NC_NAT, size_t, \ R_NC_ISNA_BIT64, R_NC_RANGE_MIN, 0, R_NC_RANGE_MAX, SIZE_MAX) #else /* Allow wrapping from negative bit64 to positive size_t */ R_NC_R2C_NUM(R_nc_r2c_bit64_size, NC_INT64, long long, REAL, NC_NAT, size_t, \ R_NC_ISNA_BIT64, R_NC_RANGE_NONE, , R_NC_RANGE_MAX, SIZE_MAX) #endif /* Allocate memory for reading a netcdf variable slice 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 SEXP and a pointer to its data. */ #define R_NC_C2R_NUM_INIT(FUN, SEXPTYPE, OFUN) \ static void \ FUN (R_nc_buf *io) \ { \ io->rxp = R_nc_allocArray (SEXPTYPE, io->ndim, io->xdim); \ io->rbuf = OFUN (io->rxp); \ if (!io->cbuf) { \ io->cbuf = io->rbuf; \ } \ } 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. The same buffer may be used for input and output. Output type may be larger (not smaller) than input, so convert in reverse order to avoid overwriting input with output. Fill values and values outside the valid range are set to missing. */ #define R_NC_C2R_NUM(FUN, NCITYPE, ITYPE, NCOTYPE, OTYPE, \ MISSVAL, MINVAL, MAXVAL) \ static void \ FUN (R_nc_buf *io) \ { \ size_t ii; \ ITYPE fillval, minval, maxval, *in; \ OTYPE *out; \ ii = xlength (io->rxp); \ in = (ITYPE *) io->cbuf; \ out = (OTYPE *) io->rbuf; \ if ((io->fill || io->min || io->max ) && io->fillsize != sizeof(ITYPE)) { \ R_nc_error ("Size of fill value does not match input type"); \ } \ if (io->fill) { \ fillval = *((ITYPE *) io->fill); \ } \ if (io->min) { \ minval = *((ITYPE *) io->min); \ } else { \ minval = MINVAL; \ } \ if (io->max) { \ maxval = *((ITYPE *) io->max); \ } else { \ maxval = MAXVAL; \ } \ if (io->fill) { \ while (ii-- > 0) { \ if ((in[ii] == fillval) || (in[ii] < minval) || (maxval < in[ii])) { \ out[ii] = MISSVAL; \ } else { \ out[ii] = in[ii]; \ } \ } \ } else { \ while (ii-- > 0) { \ if ((in[ii] < minval) || (maxval < in[ii])) { \ out[ii] = MISSVAL; \ } else { \ out[ii] = in[ii]; \ } \ } \ } \ } R_NC_C2R_NUM(R_nc_c2r_schar_int, NC_BYTE, signed char, NC_INT, int, \ NA_INTEGER, SCHAR_MIN, SCHAR_MAX) R_NC_C2R_NUM(R_nc_c2r_uchar_int, NC_UBYTE, unsigned char, NC_INT, int, \ NA_INTEGER, 0, UCHAR_MAX) R_NC_C2R_NUM(R_nc_c2r_short_int, NC_SHORT, short, NC_INT, int, \ NA_INTEGER, SHRT_MIN, SHRT_MAX) R_NC_C2R_NUM(R_nc_c2r_ushort_int, NC_USHORT, unsigned short, NC_INT, int, \ NA_INTEGER, 0, USHRT_MAX) R_NC_C2R_NUM(R_nc_c2r_int_int, NC_INT, int, NC_INT, int, \ NA_INTEGER, INT_MIN, INT_MAX) R_NC_C2R_NUM(R_nc_c2r_schar_dbl, NC_BYTE, signed char, NC_DOUBLE, double, \ NA_REAL, SCHAR_MIN, SCHAR_MAX) R_NC_C2R_NUM(R_nc_c2r_uchar_dbl, NC_UBYTE, unsigned char, NC_DOUBLE, double, \ NA_REAL, 0, UCHAR_MAX) R_NC_C2R_NUM(R_nc_c2r_short_dbl, NC_SHORT, short, NC_DOUBLE, double, \ NA_REAL, SHRT_MIN, SHRT_MAX) R_NC_C2R_NUM(R_nc_c2r_ushort_dbl, NC_USHORT, unsigned short, NC_DOUBLE, double, \ NA_REAL, 0, USHRT_MAX) R_NC_C2R_NUM(R_nc_c2r_int_dbl, NC_INT, int, NC_DOUBLE, double, \ NA_REAL, INT_MIN, INT_MAX) R_NC_C2R_NUM(R_nc_c2r_uint_dbl, NC_UINT, unsigned int, NC_DOUBLE, double, \ NA_REAL, 0, UINT_MAX) R_NC_C2R_NUM(R_nc_c2r_float_dbl, NC_FLOAT, float, NC_DOUBLE, double, \ NA_REAL, -FLT_MAX, FLT_MAX) R_NC_C2R_NUM(R_nc_c2r_dbl_dbl, NC_DOUBLE, double, NC_DOUBLE, double, \ NA_REAL, -DBL_MAX, DBL_MAX) R_NC_C2R_NUM(R_nc_c2r_int64_dbl, NC_INT64, long long, NC_DOUBLE, double, \ NA_REAL, LLONG_MIN, LLONG_MAX) R_NC_C2R_NUM(R_nc_c2r_uint64_dbl, NC_UINT64, unsigned long long, NC_DOUBLE, double, \ NA_REAL, 0, ULLONG_MAX) /* 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. */ R_NC_C2R_NUM(R_nc_c2r_int64_bit64, NC_INT64, long long, NC_INT64, long long, \ NA_INTEGER64, LLONG_MIN, LLONG_MAX) R_NC_C2R_NUM(R_nc_c2r_uint64_bit64, NC_UINT64, unsigned long long, NC_INT64, long long, \ NA_INTEGER64, 0, ULLONG_MAX) /* Convert numeric values from C to R format with unpacking. Parameters and buffers for the conversion are passed via the R_nc_buf struct. Output type is assumed not to be smaller than input type, so the same buffer may be used for input and output by converting in reverse order. Fill values and values outside the valid range are set to missing. */ #define R_NC_C2R_NUM_UNPACK(FUN, ITYPE, MINVAL, MAXVAL) \ static void \ FUN (R_nc_buf *io) \ { \ size_t ii; \ double factor, offset; \ ITYPE fillval, minval, maxval, *in; \ double *out; \ ii = xlength (io->rxp); \ in = (ITYPE *) io->cbuf; \ out = (double *) io->rbuf; \ if (io->scale) { \ factor = *(io->scale); \ } else { \ factor = 1.0; \ } \ if (io->add) { \ offset = *(io->add); \ } else { \ offset = 0.0; \ } \ if ((io->fill || io->min || io->max) && io->fillsize != sizeof(ITYPE)) { \ R_nc_error ("Size of fill value does not match input type"); \ } \ if (io->fill) { \ fillval = *((ITYPE *) io->fill); \ } \ if (io->min) { \ minval = *((ITYPE *) io->min); \ } else { \ minval = MINVAL; \ } \ if (io->max) { \ maxval = *((ITYPE *) io->max); \ } else { \ maxval = MAXVAL; \ } \ if (io->fill) { \ while (ii-- > 0) { \ if ((in[ii] == fillval) || (in[ii] < minval) || (maxval < in[ii])) { \ out[ii] = NA_REAL; \ } else { \ out[ii] = in[ii] * factor + offset; \ } \ } \ } else { \ while (ii-- > 0) { \ if ((in[ii] < minval) || (maxval < in[ii])) { \ out[ii] = NA_REAL; \ } else { \ out[ii] = in[ii] * factor + offset; \ } \ } \ } \ } R_NC_C2R_NUM_UNPACK(R_nc_c2r_unpack_schar, signed char, SCHAR_MIN, SCHAR_MAX) R_NC_C2R_NUM_UNPACK(R_nc_c2r_unpack_uchar, unsigned char, 0, UCHAR_MAX) R_NC_C2R_NUM_UNPACK(R_nc_c2r_unpack_short, short, SHRT_MIN, SHRT_MAX) R_NC_C2R_NUM_UNPACK(R_nc_c2r_unpack_ushort, unsigned short, 0, USHRT_MAX) R_NC_C2R_NUM_UNPACK(R_nc_c2r_unpack_int, int, INT_MIN, INT_MAX) R_NC_C2R_NUM_UNPACK(R_nc_c2r_unpack_uint, unsigned int, 0, UINT_MAX) R_NC_C2R_NUM_UNPACK(R_nc_c2r_unpack_float, float, -FLT_MAX, FLT_MAX) R_NC_C2R_NUM_UNPACK(R_nc_c2r_unpack_dbl, double, -DBL_MAX, DBL_MAX) R_NC_C2R_NUM_UNPACK(R_nc_c2r_unpack_int64, long long, LLONG_MIN, LLONG_MAX) R_NC_C2R_NUM_UNPACK(R_nc_c2r_unpack_uint64, unsigned long long, 0, ULLONG_MAX) /*=============================================================================*\ * User-defined type conversions \*=============================================================================*/ /* -- VLEN class -- */ /* Convert list of vectors from R to nc_vlen_t format. 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. An error is raised if input values cannot be converted to the vlen base type. */ static nc_vlen_t * R_nc_vecsxp_vlen (SEXP rv, int ncid, nc_type xtype, int ndim, const size_t *xdim) { size_t ii, cnt, len, size; int baseclass; nc_type basetype; nc_vlen_t *vbuf; SEXP item; cnt = R_nc_length (ndim, xdim); if (xlength (rv) < cnt) { RERROR (RNC_EDATALEN); } R_nc_check (nc_inq_user_type (ncid, xtype, NULL, NULL, &basetype, NULL, NULL)); if (basetype > NC_MAX_ATOMIC_TYPE) { R_nc_check (nc_inq_user_type (ncid, basetype, NULL, &size, NULL, NULL, &baseclass)); } else { baseclass = NC_NAT; size = 0; } 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) / size; } else { len = xlength(item); } vbuf[ii].len = len; if (len > 0) { vbuf[ii].p = (void *) R_nc_r2c (item, ncid, basetype, -1, &len, 0, NULL, NULL, NULL); } else { vbuf[ii].p = NULL; } } 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 void R_nc_vlen_vecsxp_init (R_nc_buf *io) { io->rxp = R_nc_allocArray (VECSXP, io->ndim, io->xdim); if (!io->cbuf) { io->cbuf = R_alloc (xlength (io->rxp), sizeof(nc_vlen_t)); } } /* 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; nc_type basetype; nc_vlen_t *vbuf; R_nc_buf tmpio; vbuf = io->cbuf; cnt = xlength (io->rxp); R_nc_check (nc_inq_user_type (io->ncid, io->xtype, NULL, NULL, &basetype, NULL, NULL)); for (ii=0; iincid, basetype, -1, &(vbuf[ii].len), io->rawchar, io->fitnum, 0, NULL, NULL, NULL, NULL, NULL); SET_VECTOR_ELT (io->rxp, ii, R_nc_c2r (&tmpio)); nc_free_vlen(&(vbuf[ii])); } } /* -- 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 (xlength (rv) < (cnt * size)) { RERROR (RNC_EDATALEN); } return (const char *) RAW (rv); } static void 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 = R_nc_allocArray (RAWSXP, ndim + 1, xdim); io->rbuf = RAW (io->rxp); if (!io->cbuf) { io->cbuf = io->rbuf; } } 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) { SEXP levels; size_t size, imem, nmem, ilev, nlev, *ilev2mem, ifac, nfac; char *memnames, *memname, *memvals, *memval, *out; const char **levnames; int ismatch, *in, inval; /* Extract indices and level names of R factor */ in = INTEGER (rv); levels = getAttrib (rv, R_LevelsSymbol); if (!isString (levels)) { RERROR ("Expected character vector for levels of factor array") } nlev = xlength (levels); levnames = (const char **) R_alloc (nlev, sizeof(size_t)); for (ilev=0; ilevrxp = 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); } } /* 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, classname, env, cmd, symbol, value; size_t size, nmem, ifac, nfac; char *memname, *memval, *work, *inval; int ncid, imem, imemmax, *out; nc_type xtype; /* Read values and names of netcdf enum members. Store names in an R character vector for use as R factor levels. Store values and their R indices (1-based) in a hashed environment. The env is PROTECTed, so individual variables need not be. But values do need PROTECTing before assignment to env, otherwise gctorture reveals problems. I'm not sure if symbols need PROTECTing, but better safe than sorry. */ ncid = io->ncid; xtype = io->xtype; R_nc_check (nc_inq_enum(ncid, xtype, NULL, NULL, &size, &nmem)); cmd = R_nc_protect (lang1 (install ("new.env"))); env = R_nc_protect (eval (cmd, R_BaseEnv)); levels = R_nc_allocArray (STRSXP, -1, &nmem); 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; imemrxp); out = io->rbuf; for (ifac=0, inval=io->cbuf; ifacrxp, R_LevelsSymbol, levels); classname = R_nc_protect (allocVector (STRSXP, 1)); SET_STRING_ELT(classname, 0, mkChar("factor")); setAttrib(io->rxp, R_ClassSymbol, classname); } /* -- Compound class -- */ /* Convert list of arrays from R to netcdf compound type. Memory for the result is allocated (and freed by R). */ static void * R_nc_vecsxp_compound (SEXP rv, int ncid, nc_type xtype, int ndim, const size_t *xdim) { size_t cnt, size, nfld, offset, fldsize, fldcnt, fldlen, nlist, ilist, ielem, *dimsizefld; nc_type typefld; int ifldmax, ifld, idimfld, ndimfld, *dimlenfld, ismatch; char *bufout, namefld[NC_MAX_NAME+1]; const char *buffld; void *highwater; SEXP namelist; /* Get size and number of fields in compound type */ R_nc_check (nc_inq_compound(ncid, xtype, NULL, &size, &nfld)); /* Check names attribute of R list */ namelist = R_nc_protect (getAttrib (rv, R_NamesSymbol)); if (!isString (namelist)) { R_nc_error ("Named list required for conversion to compound type"); } nlist = xlength (namelist); if (nlist < nfld) { R_nc_error ("Not enough fields in list for conversion to compound type"); } /* Allocate memory for compound array, filling with zeros so that valgrind does not complain about uninitialised values in gaps inserted for alignment */ cnt = R_nc_length (ndim, xdim); bufout = R_alloc (cnt, size); memset(bufout, 0, cnt*size); /* Convert each field in turn */ ifldmax = nfld; for (ifld=0; ifldncid) == NC_NOERR) { /* Dataset must be writable because it is now in define mode */ R_nc_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 = 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); } } /* 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; nc_type xtype, typefld; size_t size, nfld, cnt, offset, fldsize, *dimslice, fldcnt, fldlen, ielem; SEXP namelist, rxpfld; char namefld[NC_MAX_NAME+1], *buffld, *bufcmp; R_nc_buf iofld; void *highwater; /* 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); /* Set names attribute of R list */ namelist = 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; idimfldrawchar, io->fitnum, 0, NULL, NULL, NULL, NULL, NULL); /* Copy elements from the compound array into the field array */ fldlen = fldsize * fldcnt; for (ielem=0; ielemrxp, ifld, rxpfld); /* Allow memory from R_alloc since vmaxget to be reclaimed */ vmaxset (highwater); } } /*=============================================================================*\ * 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 class; 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: switch (xtype) { case NC_BYTE: return R_nc_r2c_int_schar (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UBYTE: return R_nc_r2c_int_uchar (rv, ndim, xdim, fillsize, fill, scale, add); case NC_SHORT: return R_nc_r2c_int_short (rv, ndim, xdim, fillsize, fill, scale, add); case NC_USHORT: return R_nc_r2c_int_ushort (rv, ndim, xdim, fillsize, fill, scale, add); case NC_INT: return R_nc_r2c_int_int (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UINT: return R_nc_r2c_int_uint (rv, ndim, xdim, fillsize, fill, scale, add); case NC_INT64: return R_nc_r2c_int_ll (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UINT64: return R_nc_r2c_int_ull (rv, ndim, xdim, fillsize, fill, scale, add); case NC_FLOAT: return R_nc_r2c_int_float (rv, ndim, xdim, fillsize, fill, scale, add); case NC_DOUBLE: return R_nc_r2c_int_dbl (rv, ndim, xdim, fillsize, fill, scale, add); } if (xtype > NC_MAX_ATOMIC_TYPE && class == NC_ENUM && R_nc_inherits (rv, "factor")) { return R_nc_factor_enum (rv, ncid, xtype, ndim, xdim); } break; case REALSXP: if (R_nc_inherits (rv, "integer64")) { switch (xtype) { case NC_BYTE: return R_nc_r2c_bit64_schar (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UBYTE: return R_nc_r2c_bit64_uchar (rv, ndim, xdim, fillsize, fill, scale, add); case NC_SHORT: return R_nc_r2c_bit64_short (rv, ndim, xdim, fillsize, fill, scale, add); case NC_USHORT: return R_nc_r2c_bit64_ushort (rv, ndim, xdim, fillsize, fill, scale, add); case NC_INT: return R_nc_r2c_bit64_int (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UINT: return R_nc_r2c_bit64_uint (rv, ndim, xdim, fillsize, fill, scale, add); case NC_INT64: return R_nc_r2c_bit64_ll (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UINT64: return R_nc_r2c_bit64_ull (rv, ndim, xdim, fillsize, fill, scale, add); case NC_FLOAT: return R_nc_r2c_bit64_float (rv, ndim, xdim, fillsize, fill, scale, add); case NC_DOUBLE: return R_nc_r2c_bit64_dbl (rv, ndim, xdim, fillsize, fill, scale, add); } } else { switch (xtype) { case NC_BYTE: return R_nc_r2c_dbl_schar (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UBYTE: return R_nc_r2c_dbl_uchar (rv, ndim, xdim, fillsize, fill, scale, add); case NC_SHORT: return R_nc_r2c_dbl_short (rv, ndim, xdim, fillsize, fill, scale, add); case NC_USHORT: return R_nc_r2c_dbl_ushort (rv, ndim, xdim, fillsize, fill, scale, add); case NC_INT: return R_nc_r2c_dbl_int (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UINT: return R_nc_r2c_dbl_uint (rv, ndim, xdim, fillsize, fill, scale, add); case NC_INT64: return R_nc_r2c_dbl_ll (rv, ndim, xdim, fillsize, fill, scale, add); case NC_UINT64: return R_nc_r2c_dbl_ull (rv, ndim, xdim, fillsize, fill, scale, add); case NC_FLOAT: return R_nc_r2c_dbl_float (rv, ndim, xdim, fillsize, fill, scale, add); case NC_DOUBLE: return R_nc_r2c_dbl_dbl (rv, ndim, xdim, fillsize, fill, scale, add); } } break; case STRSXP: switch (xtype) { case NC_CHAR: return R_nc_strsxp_char (rv, ndim, xdim); case NC_STRING: return R_nc_strsxp_str (rv, ndim, xdim); } 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); case NC_COMPOUND: return R_nc_vecsxp_compound (rv, ncid, xtype, ndim, xdim); } } break; } RERROR (RNC_EDATATYPE); } void * \ 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) { RERROR ("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 = cbuf; 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 (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) { R_nc_c2r_int_init (io); break; } case NC_INT64: case NC_UINT64: if (fitnum && !scale && !add) { R_nc_c2r_bit64_init (io); classgets(io->rxp, mkString("integer64")); break; } case NC_UINT: case NC_FLOAT: case NC_DOUBLE: R_nc_c2r_dbl_init (io); break; case NC_CHAR: if (rawchar) { R_nc_char_raw_init (io); } else { R_nc_char_strsxp_init (io); } break; case NC_STRING: 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: R_nc_compound_vecsxp_init (io); break; case NC_ENUM: R_nc_enum_factor_init (io); break; case NC_VLEN: R_nc_vlen_vecsxp_init (io); break; case NC_OPAQUE: R_nc_opaque_raw_init (io); break; default: RERROR (RNC_ETYPEDROP); } } else { RERROR (RNC_ETYPEDROP); } } return io->cbuf; } SEXP 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: RERROR (RNC_ETYPEDROP); } } else { RERROR (RNC_ETYPEDROP); } } return io->rxp; } /*=============================================================================*\ * Dimension conversions \*=============================================================================*/ /* Reverse a vector in-place. Example: R_nc_rev_int (cv, cnt); */ #define R_NC_REVERSE(FUN, TYPE) \ void \ FUN (TYPE *data, size_t cnt) \ { \ size_t ii, jj; \ TYPE 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" /* 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: #elif defined NC_FORMAT_64BIT_OFFSET case NC_FORMAT_64BIT_OFFSET: #endif return "offset64"; #ifdef NC_FORMAT_CDF5 case NC_FORMAT_CDF5: return "cdf5"; #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) { RERROR ("Not a valid NetCDF object"); } fileid = R_ExternalPtrAddr (ptr); if (!fileid) { RRETURN(R_NilValue); } R_nc_check (nc_close (*fileid)); R_Free (fileid); R_ClearExternalPtr (ptr); RRETURN(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) { int cmode, fillmode, old_fillmode, ncid, *fileid; SEXP Rptr, result; const char *filep; /*-- Determine the cmode ----------------------------------------------------*/ if (asLogical(clobber) == TRUE) { cmode = NC_CLOBBER; } else { cmode = NC_NOCLOBBER; } /*-- 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; } /*-- Create the file --------------------------------------------------------*/ filep = R_nc_strarg (filename); if (strlen (filep) > 0) { R_nc_check (nc_create (R_ExpandFileName (filep), cmode, &ncid)); } else { RERROR ("Filename must be a non-empty string"); } result = R_nc_protect (ScalarInteger (ncid)); /*-- Arrange for file to be closed if handle is garbage collected -----------*/ fileid = R_Calloc (1, int); *fileid = ncid; Rptr = R_nc_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)); RRETURN(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 = R_nc_protect (allocVector (VECSXP, 6)); SET_VECTOR_ELT (result, 0, ScalarInteger (ndims)); SET_VECTOR_ELT (result, 1, ScalarInteger (nvars)); SET_VECTOR_ELT (result, 2, ScalarInteger (ngatts)); SET_VECTOR_ELT (result, 3, ScalarInteger (unlimdimid)); SET_VECTOR_ELT (result, 4, mkString (R_nc_format2str (format))); SET_VECTOR_ELT (result, 5, mkString (libvers)); RRETURN(result); } /*-----------------------------------------------------------------------------*\ * R_nc_open() \*-----------------------------------------------------------------------------*/ SEXP R_nc_open (SEXP filename, SEXP write, SEXP share, SEXP prefill) { int ncid, omode, fillmode, old_fillmode, *fileid; const char *filep; SEXP Rptr, result; /*-- Determine the omode ----------------------------------------------------*/ if (asLogical(write) == TRUE) { omode = NC_WRITE; } else { omode = NC_NOWRITE; } 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) { R_nc_check (nc_open (R_ExpandFileName (filep), omode, &ncid)); } else { RERROR ("Filename must be a non-empty string"); } result = R_nc_protect (ScalarInteger (ncid)); /*-- Arrange for file to be closed if handle is garbage collected -----------*/ fileid = R_Calloc (1, int); *fileid = ncid; Rptr = R_nc_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)); } RRETURN(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)); RRETURN(R_NilValue); } RNetCDF/src/group.c0000644000176200001440000001401613552423027013533 0ustar liggesusers/*=============================================================================*\ * * Name: group.c * * Version: 2.1-1 * * Purpose: NetCDF group functions for RNetCDF. * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright: (C) 2004-2019 Pavel Michna, 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; SEXP result; /* 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)); result = R_nc_protect (ScalarInteger (grpid)); RRETURN(result); } /*-----------------------------------------------------------------------------*\ * R_nc_inq_grp_parent() \*-----------------------------------------------------------------------------*/ SEXP R_nc_inq_grp_parent (SEXP nc) { int ncid, grpid; SEXP result; /* Get parent group */ ncid = asInteger (nc); R_nc_check (nc_inq_grp_parent (ncid, &grpid)); result = R_nc_protect (ScalarInteger (grpid)); RRETURN(result); } /*-----------------------------------------------------------------------------*\ * R_nc_inq_natts() \*-----------------------------------------------------------------------------*/ SEXP R_nc_inq_natts (SEXP nc) { int ncid, natts; SEXP result; /* Get number of attributes in group */ ncid = asInteger (nc); R_nc_check (nc_inq_natts (ncid, &natts)); result = R_nc_protect (ScalarInteger (natts)); RRETURN(result); } /*-----------------------------------------------------------------------------*\ * 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]; SEXP result; 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; } result = R_nc_protect (mkString (name)); RRETURN(result); } /*-----------------------------------------------------------------------------*\ * R_nc_inq_grp_ncid() \*-----------------------------------------------------------------------------*/ SEXP R_nc_inq_grp_ncid (SEXP nc, SEXP grpname, SEXP full) { int ncid, grpid; const char *cgrpname; SEXP result; 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)); } result = R_nc_protect (ScalarInteger (grpid)); RRETURN(result); } /*-----------------------------------------------------------------------------*\ * 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 = R_nc_protect (allocVector (INTSXP, count)); \ R_nc_check(NCFUN(ncid, NULL, INTEGER(result))); \ RRETURN(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 = R_nc_protect (allocVector (INTSXP, count)); R_nc_check (nc_inq_dimids (ncid, NULL, INTEGER (result), full)); RRETURN(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)); RRETURN(R_NilValue); #else RERROR ("nc_rename_grp not supported by netcdf library"); #endif } RNetCDF/src/common.c0000644000176200001440000002014013552423027013662 0ustar liggesusers/*=============================================================================*\ * * Name: common.c * * Version: 2.1-1 * * Purpose: Common definitions for RNetCDF functions * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright: (C) 2004-2019 Pavel Michna, 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" static int R_nc_protect_count = 0; SEXP R_nc_protect (SEXP obj) { PROTECT(obj); R_nc_protect_count++; return obj; } void R_nc_unprotect (void) { if (R_nc_protect_count > 0) { UNPROTECT (R_nc_protect_count); R_nc_protect_count = 0; } } void R_nc_error(const char *msg) { R_nc_unprotect (); error (msg); } int R_nc_check(int status) { if (status != NC_NOERR) { R_nc_error (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); } 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 { RERROR ("Expected character string as argument"); } } size_t R_nc_sizearg (SEXP size) { int erange=0; size_t result=0; if (xlength (size) > 0) { if (TYPEOF (size) == INTSXP) { int ival; ival = INTEGER (size)[0]; erange = (ival < 0 || ival > SIZE_MAX || ival == NA_INTEGER); if (!erange) { result = ival; } } else if (TYPEOF (size) == REALSXP) { if (R_nc_inherits (size, "integer64")) { long long llval; llval = *(long long *) REAL (size); /* Allow wrapping of negative to positive values by converting from signed to unsigned long long */ if (sizeof (long long) > sizeof (size_t)) { erange = (llval < 0 || llval > SIZE_MAX || llval == NA_INTEGER64); } else { /* Allow wrapping of negative to positive values in conversion from signed long long to (unsigned) size_t */ erange = (llval == NA_INTEGER64); } if (!erange) { result = llval; } } else { double dval; dval = REAL (size)[0]; erange = (dval < 0 || dval > SIZE_MAX || ! R_FINITE (dval)); result = dval; } } else { R_nc_error ("Size argument has unsupported R type"); } } else { R_nc_error ("Size argument must contain at least one numeric value"); } if (erange) { R_nc_error ("Size argument is outside valid range"); } return result; } 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/Makevars.win0000755000176200001440000000136013552317654014534 0ustar liggesusersVERSION=4.4.1.1-dap PKG_CPPFLAGS = -I../windows/netcdf-${VERSION}/include \ -DHAVE_LIBUDUNITS2 -DHAVE_UDUNITS2_H \ -DHAVE_NC_RENAME_GRP \ -DHAVE_NC_GET_VAR_CHUNK_CACHE \ -DHAVE_NC_INQ_VAR_SZIP \ -DHAVE_NC_INQ_VAR_ENDIAN \ WINLIBS = ../windows/netcdf-${VERSION}/lib${R_ARCH} PKG_LIBS = $(WINLIBS)/libnetcdf.a $(WINLIBS)/libcurl.a \ $(WINLIBS)/libhdf5_hl.a $(WINLIBS)/libhdf5.a $(WINLIBS)/libszip.a \ $(WINLIBS)/libudunits2.a $(WINLIBS)/libexpat.a \ -lz -lws2_32 -lcrypt32 -lwldap32 all: clean winlibs winlibs: "${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" "../tools/winlibs.R" ${VERSION} mkdir -p ../inst rm -Rf ../inst/share cp -r ../windows/netcdf-${VERSION}/share ../inst/ clean: rm -Rf $(SHLIB) $(OBJECTS) .PHONY: all winlibs clean RNetCDF/src/variable.c0000644000176200001440000006617313552547774014217 0ustar liggesusers/*=============================================================================*\ * * Name: variable.c * * Version: 2.1-1 * * Purpose: NetCDF variable functions for RNetCDF * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright: (C) 2004-2019 Pavel Michna, 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_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; SEXP result; #ifdef HAVE_NC_INQ_VAR_ENDIAN int endian_mode; #endif #ifdef HAVE_NC_INQ_VAR_FILTER int filter_mode, filtid, *filtparm; #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 (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 - _FillValue, or missing_value 1 - _FillValue only 2 - missing_value only 3 - none 4 - fill value and valid range determined as described at http://www.unidata.ucar.edu/software/netcdf/docs/attribute_conventions.html 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)); if (xtype == NC_CHAR || xtype == NC_STRING || xtype > NC_MAX_ATOMIC_TYPE) { /* NetCDF attribute conventions describe the handling of missing values in atomic numeric types. Let users handle other types as needed. */ return 0; } R_nc_check (nc_inq_type (ncid, xtype, NULL, &size)); if ((mode == 0 || mode == 1) && 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) && 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) } } } 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: R_nc_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: R_nc_error ("Default valid range not implemented"); } } } } else { R_nc_error ("Unknown mode for handling missing values"); } return size; } /* 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 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 if (nc_get_var_chunk_cache(ncid, varid, &bytes, &slots, &preemption) == NC_NOERR) { 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)); } result = R_nc_c2r (&io); RRETURN (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, rbytes, rslots, rpreempt, rshuffle, rdeflate, rendian, rfletcher, rszip_options, rszip_bits, rfilter_id, rfilter_params; #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_INQ_VAR_FILTER int filter_id; size_t filter_nparams; #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)); if (ndims > 0) { rdimids = R_nc_protect (allocVector (INTSXP, ndims)); 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); rchunks = R_NilValue; if (withnc4) { R_nc_check (nc_inq_var_chunking (ncid, varid, &storeprop, NULL)); if (storeprop == NC_CHUNKED) { rchunks = R_nc_protect (allocVector (REALSXP, ndims)); 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 0) { R_nc_check (nc_inq_var_filter (ncid, varid, NULL, NULL, (unsigned int *) INTEGER (rfilter_params))); } } else if (status == NC_EFILTER) { rfilter_id = R_nc_protect (ScalarInteger (NA_INTEGER)); rfilter_params = R_nc_protect (ScalarInteger (NA_INTEGER)); } else { R_nc_check (status); return R_NilValue; } #else rfilter_id = R_NilValue; rfilter_params = R_NilValue; #endif } else { rdeflate = R_NilValue; rshuffle = R_NilValue; rendian = R_NilValue; rfletcher = R_NilValue; rszip_bits = R_NilValue; rszip_options = R_NilValue; rfilter_id = R_NilValue; rfilter_params = R_NilValue; } /*-- Convert nc_type to char ------------------------------------------------*/ R_nc_check (R_nc_type2str (ncid, xtype, vartype)); /*-- Construct the output list ----------------------------------------------*/ if (withnc4) { result = R_nc_protect (allocVector (VECSXP, 18)); } else { result = R_nc_protect (allocVector (VECSXP, 6)); } SET_VECTOR_ELT (result, 0, ScalarInteger (varid)); SET_VECTOR_ELT (result, 1, mkString (varname)); SET_VECTOR_ELT (result, 2, mkString (vartype)); SET_VECTOR_ELT (result, 3, ScalarInteger (ndims)); SET_VECTOR_ELT (result, 4, rdimids); SET_VECTOR_ELT (result, 5, ScalarInteger (natts)); if (withnc4) { SET_VECTOR_ELT (result, 6, rchunks); SET_VECTOR_ELT (result, 7, rbytes); SET_VECTOR_ELT (result, 8, rslots); SET_VECTOR_ELT (result, 9, rpreempt); SET_VECTOR_ELT (result, 10, rdeflate); SET_VECTOR_ELT (result, 11, rshuffle); SET_VECTOR_ELT (result, 12, rendian); SET_VECTOR_ELT (result, 13, rfletcher); SET_VECTOR_ELT (result, 14, rszip_options); SET_VECTOR_ELT (result, 15, rszip_bits); SET_VECTOR_ELT (result, 16, rfilter_id); SET_VECTOR_ELT (result, 17, rfilter_params); } RRETURN(result); } /*-----------------------------------------------------------------------------*\ * 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 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 if (nc_get_var_chunk_cache(ncid, varid, &bytes, &slots, &preemption) == NC_NOERR) { 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)); } RRETURN (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)); RRETURN(R_NilValue); } RNetCDF/src/convert.h0000644000176200001440000001157413552423027014072 0ustar liggesusers/*=============================================================================*\ * * Name: convert.h * * Version: 2.1-1 * * Purpose: Type conversions for RNetCDF * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright: (C) 2004-2019 Pavel Michna, 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 *cbuf, *rbuf; nc_type xtype; int ncid, ndim, rawchar, fitnum; size_t *xdim, fillsize; void *fill, *min, *max; double *scale, *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. Argument io is a pointer to an existing R_nc_buf (must not be NULL). The result of R_nc_c2r_init is a pointer to the C buffer used for netcdf functions, which may be specified by argument cbuf or internally allocated 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. */ void * \ 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); SEXP 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) #endif /* RNC_CONVERT_H_INCLUDED */ RNetCDF/src/common.h0000644000176200001440000001001713552423027013671 0ustar liggesusers/*=============================================================================*\ * * Name: common.h * * Version: 2.1-1 * * Purpose: Common definitions for RNetCDF functions * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright: (C) 2004-2019 Pavel Michna, 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 #define RRETURN(object) { R_nc_unprotect (); return (object); } #define RERROR(msg) { R_nc_error (msg); return NULL; } #define NA_SIZE SIZE_MAX /* Definition of missing value used by bit64 package */ #define NA_INTEGER64 LLONG_MIN /* Common error strings */ static const char RNC_EDATALEN[]="Not enough data", \ RNC_EDATATYPE[]="Incompatible data for external type", \ RNC_ETYPEDROP[]="Unsupported external type"; /* Protect an object from garbage collection by R */ SEXP R_nc_protect (SEXP obj); /* Unprotect all objects to enable garbage collection by R */ void R_nc_unprotect (void); /* Raise an error in R */ void R_nc_error(const char *msg); /* 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); /* 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); /* 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); /* 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.c0000644000176200001440000001400113552423027014356 0ustar liggesusers/*=============================================================================*\ * * Name: dimension.c * * Version: 2.1-1 * * Purpose: NetCDF dimension functions for RNetCDF * * Author: Pavel Michna (rnetcdf-devel@bluewin.ch) * Milton Woods (miltonjwoods@gmail.com) * * Copyright: (C) 2004-2019 Pavel Michna, 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_dim() \*-----------------------------------------------------------------------------*/ SEXP R_nc_def_dim (SEXP nc, SEXP dimname, SEXP size, SEXP unlim) { int ncid, dimid; const char *dimnamep; size_t nccnt; SEXP result; /*-- 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)); result = R_nc_protect (ScalarInteger (dimid)); RRETURN(result); } /*-----------------------------------------------------------------------------*\ * 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 = R_nc_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)); } RRETURN(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 = R_nc_protect (allocVector (VECSXP, 4)); SET_VECTOR_ELT (result, 0, ScalarInteger (dimid)); SET_VECTOR_ELT (result, 1, mkString (dimname)); /* Dimension length may be larger than integer, so return as double */ SET_VECTOR_ELT (result, 2, ScalarReal (dimlen)); SET_VECTOR_ELT (result, 3, ScalarLogical (isunlim)); RRETURN(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)); RRETURN(R_NilValue); } RNetCDF/src/Makevars.in0000644000176200001440000000007613210113255014323 0ustar liggesusersPKG_CPPFLAGS = @DEFS@ @CPPFLAGS@ PKG_LIBS = @LDFLAGS@ @LIBS@ RNetCDF/NEWS0000644000176200001440000000727113552423027012150 0ustar liggesusersVersion 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.win0000755000176200001440000000000013210113255014121 0ustar liggesusersRNetCDF/COPYING0000644000176200001440000004325413541627213012506 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/0000755000176200001440000000000013541627213011644 5ustar liggesusersRNetCDF/R/load.R0000644000176200001440000000016213532406374012710 0ustar liggesusers".onLoad" <- function(lib, pkg) { utinit.nc() } ".onUnload" <- function(libpath) { .Call(R_nc_utterm) } RNetCDF/R/RNetCDF.R0000644000176200001440000010723513541627213013164 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-2019 Pavel Michna, 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(class(ncfile.in) == "NetCDF") stopifnot(class(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(class(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(class(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(class(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(class(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(class(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(class(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) { #-- 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", "netcdf4", "classic4")) stopifnot(is.logical(large)) # 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) attr(nc, "class") <- "NetCDF" return(invisible(nc)) } #------------------------------------------------------------------------------- # dim.def.nc() #------------------------------------------------------------------------------- dim.def.nc <- function(ncfile, dimname, dimlength = 1, unlim = FALSE) { #-- Check args ------------------------------------------------------------- stopifnot(class(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(class(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(class(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(class(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, ...) { #-- Check args ------------------------------------------------------------- stopifnot(is.character(con)) stopifnot(is.logical(write)) stopifnot(is.logical(share)) stopifnot(is.logical(prefill)) #-- C function call -------------------------------------------------------- nc <- .Call(R_nc_open, con, write, share, prefill) 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 (class(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(class(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(class(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=NA, filter_params=integer(0)) { #-- Check args ------------------------------------------------------------- stopifnot(class(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(isTRUE(is.na(filter_id)) || is.numeric(filter_id)) stopifnot(is.integer(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(class(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(class(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.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(class(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(class(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(class(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(class(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(class(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(class(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(class(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(class(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(class(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 <- apply(ut, 1, function(x) { paste(x[1], "-", sprintf("%02g", x[2]), "-", sprintf("%02g", x[3]), " ", sprintf("%02g", x[4]), ":", sprintf("%02g", x[5]), ":", sprintf("%02g", x[6]), sep = "") }) return(x) } else if (isTRUE(type == "c")) { ct <- as.POSIXct(utinvcal.nc("seconds since 1970-01-01 00:00:00 +00:00", ut), tz = "UTC", origin = ISOdatetime(1970, 1, 1, 0, 0, 0, tz = "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/MD50000644000176200001440000000571013553005253011753 0ustar liggesusersb234ee4d69f5fce4486a80fdaf4a4263 *COPYING b89039bd7dafb780af33bbd049af8d3e *DESCRIPTION 18f138b6e63657f37e2ac2dfc2507f23 *INSTALL a65f65191aacb737b62d6e354faf6b4e *LICENSE 537ae4d17831bfa5e4bb053c53bcd933 *NAMESPACE fde09d0f394474aee5a0ba3f1294502b *NEWS 899c70973b35f89c7a048b87a6cadb31 *R/RNetCDF.R 900ad9ec5d6b3f465f65621c2ac90b3f *R/load.R 3ee2d313b01e8c75dd118451997b2fee *README.md a38544db104bdfa10be73ab380052d1e *cleanup e0952877b15035d3c52d9354f4477230 *configure 8e1d722d55807ec1eda95a4900dbbc58 *configure.ac d41d8cd98f00b204e9800998ecf8427e *configure.win 5bac89bca74222d4bb68c09e5981202d *inst/udunits/udunits2.xml 05c4596a4b2d91c91a8a878ec641c169 *man/00RNetCDF.Rd 632be6d1c36318d740ec25941ba604c4 *man/att.copy.nc.Rd 36f02d0d665297b764c487a17968baec *man/att.delete.nc.Rd 623f23a3e2604051ae84a6d79330e6be *man/att.get.nc.Rd e7f4a084305537500a73b8edd695fa14 *man/att.inq.nc.Rd ef95d6d3a882ee40a5584247c77b60f2 *man/att.put.nc.Rd caa2e214d9d3cf71baf1a201ed0ccd61 *man/att.rename.nc.Rd cd5ba399ca144bcc2641b4ac10e8885a *man/close.nc.Rd 3c4ac1c78c17f1a473f42e7360eb418d *man/create.nc.Rd e5c0c4cef60cc3042a2710b1ea485011 *man/dim.def.nc.Rd ea5750fa4957f624be80d3841ecd2e34 *man/dim.inq.nc.Rd e6b613bd2cf3b6452f50141b46292aa4 *man/dim.rename.nc.Rd 4456b1315414d28b9372a7275b72bc49 *man/file.inq.nc.Rd 89889eee0a95487e7cff4822ea185db3 *man/grp.def.nc.Rd b2f69838aa99b836081a37063681a6e9 *man/grp.inq.nc.Rd 41e97ac2558871797f7d8f49c9d997e8 *man/grp.rename.nc.Rd 7f678f411ee8481027ee512c40584038 *man/open.nc.Rd d31dc8db4b3f72b635661ce71a3cbefa *man/print.nc.Rd 6969e8431c6b32ab445aacb1828306cc *man/read.nc.Rd e3b274794165a747afea5740ca5ca4d2 *man/sync.nc.Rd 97045283562230c5cc5bfdc965fc4c86 *man/type.def.nc.Rd da762783a05a75a65474b1ab7baa98d0 *man/type.inq.nc.Rd 5e7f5ba8b258bf09e22c4499d10ee4aa *man/utcal.nc.Rd 051a52216edcd32a0f02ef0d7ea32e3c *man/utinit.nc.Rd 2ae3026ea5c8f2911d45fe92fb2da82b *man/utinvcal.nc.Rd 9865790904e41bd9e771994ab6b7374d *man/var.def.nc.Rd 25ca1ce4f392bb47b72be05a42d2a075 *man/var.get.nc.Rd 12af376099d51bd139c6e64643c9b5a2 *man/var.inq.nc.Rd 10b6bd5b00a98838be31d23035c7d48a *man/var.put.nc.Rd 4abff3b45abf39350509758c00433787 *man/var.rename.nc.Rd 6cc969080e30d435ab12eb4cd6b30180 *src/Makevars.in 37b01015145664927959b56a1b82a4cd *src/Makevars.win d6261a0184183dccb6558ead351e9108 *src/RNetCDF.h d5c46cdd5b4d3ee52051438777f67f93 *src/attribute.c 0beda9a493f5e9acb5d32440c840b18d *src/common.c 70e91b6f756df48f6119e886865ecab5 *src/common.h cc9335fd4f012e138e71ae8acb5a0e3d *src/convert.c cfb9f41418e87ece79a6a7a894c774ed *src/convert.h f28b44ca0f78e990b95b3e2326627604 *src/dataset.c 328d1274c24456401bd77dd1042a2f2d *src/dimension.c 8d1d415642b07edc9c17a216930ec42f *src/group.c f278b50c8764beafff3556f6df8a7236 *src/init.c 380df8dfcd53391b00d090e7410f69a3 *src/type.c 892998a4f14e30050120e4c7f9fbdd1a *src/udunits.c eb7d81ed7fb7c32c7172a3dbc59d8d31 *src/variable.c d2159dbfee3f7709f0856eb17baabde7 *tests/RNetCDF-test.R b501f8ce4175db84ae9b49d876742144 *tools/winlibs.R RNetCDF/inst/0000755000176200001440000000000013443315100012406 5ustar liggesusersRNetCDF/inst/udunits/0000755000176200001440000000000013532406374014116 5ustar liggesusersRNetCDF/inst/udunits/udunits2.xml0000644000176200001440000001711213532406374016417 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/cleanup0000755000176200001440000000013213552550163013015 0ustar liggesusers#!/bin/sh rm -rf *.cache rm -f ./config.* rm -f ./src/Makevars rm -f ./src/*.so ./src/*.o RNetCDF/configure0000755000176200001440000042213313552550163013360 0ustar liggesusers#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for RNetCDF 2.1-1. # # # Copyright (C) 1992-1996, 1998-2012 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 if test -n "${ZSH_VERSION+set}" && (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 case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; 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 # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # 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 test -z "$as_dir" && as_dir=. 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 $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # 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'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_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="if test -n \"\${ZSH_VERSION+set}\" && (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 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 exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || 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_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else 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 test -z "$as_dir" && as_dir=. 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_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS 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'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$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_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=`$as_echo "$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 || $as_echo 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_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_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # 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 $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$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 || $as_echo 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" || { $as_echo "$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 } 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 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.1-1' PACKAGE_STRING='RNetCDF 2.1-1' PACKAGE_BUGREPORT='' PACKAGE_URL='' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='LTLIBOBJS LIBOBJS EGREP GREP CPP OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC have_nc_config 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 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_nc_config ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # 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' 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 # Accept the important Cygnus configure options, so we can diagnose typos. 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=`$as_echo "$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=`$as_echo "$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 ;; -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=`$as_echo "$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=`$as_echo "$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. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$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" ;; *) $as_echo "$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 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 || $as_echo 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.1-1 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] --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.1-1:";; esac cat <<\_ACEOF Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --without-nc-config do not use nc-config to get netcdf configuration 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 CPP C preprocessor 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=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$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 guested configure. 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 $as_echo "$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.1-1 generated by GNU Autoconf 2.69 Copyright (C) 2012 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 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\"" $as_echo "$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 $as_echo "$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_echo "$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_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" 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\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 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 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$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_cpp # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_try_run LINENO # ---------------------- # Try to link 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\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$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\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$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_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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else 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 eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$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$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\"" $as_echo "$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 $as_echo "$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_echo "$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_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else 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. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #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 () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func 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.1-1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _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 test -z "$as_dir" && as_dir=. $as_echo "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=`$as_echo "$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=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## 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_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$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 $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$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 $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # 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,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$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=`$as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`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 #-------------------------------------------------------------------------------# # Find the compiler and compiler options to use for tests # #-------------------------------------------------------------------------------# : ${R_HOME=`R RHOME`} if test -z "${R_HOME}"; then : as_fn_error $? "could not determine R_HOME" "$LINENO" 5 fi CC=`"${R_HOME}/bin/R" CMD config CC` CFLAGS=`"${R_HOME}/bin/R" CMD config CFLAGS` # Prepend user-specified CPPFLAGS to those from R: R_CPPFLAGS=`"${R_HOME}/bin/R" CMD config CPPFLAGS` CPPFLAGS="$CPPFLAGS $R_CPPFLAGS" #-------------------------------------------------------------------------------# # Find NetCDF library and header files # #-------------------------------------------------------------------------------# # Check whether --with-nc-config was given. if test "${with_nc_config+set}" = set; then : withval=$with_nc_config; else with_nc_config=yes fi if test "x$with_nc_config" != xno; then : # Extract the first word of "nc-config", so it can be a program name with args. set dummy nc-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_have_nc_config+:} false; then : $as_echo_n "(cached) " >&6 else 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 test -z "$as_dir" && as_dir=. 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" $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_nc_config" >&5 $as_echo "$have_nc_config" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test "x$have_nc_config" == xyes; then : # Prepend linker flags to LDFLAGS: { $as_echo "$as_me:${as_lineno-$LINENO}: checking netcdf linker flags" >&5 $as_echo_n "checking netcdf linker flags... " >&6; } NETCDF_LIBS=`nc-config --libs` { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NETCDF_LIBS" >&5 $as_echo "$NETCDF_LIBS" >&6; } LDFLAGS="$NETCDF_LIBS $LDFLAGS" # Prepend preprocessor and compiler flags to CPPFLAGS: { $as_echo "$as_me:${as_lineno-$LINENO}: checking netcdf preprocessor and compiler flags" >&5 $as_echo_n "checking netcdf preprocessor and compiler flags... " >&6; } NETCDF_CFLAGS=`nc-config --cflags` { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NETCDF_CFLAGS" >&5 $as_echo "$NETCDF_CFLAGS" >&6; } CPPFLAGS="$NETCDF_CFLAGS $CPPFLAGS" fi # Check that netcdf header files can be compiled: 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else 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 test -z "$as_dir" && as_dir=. 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" $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else 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 test -z "$as_dir" && as_dir=. 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" $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else 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 test -z "$as_dir" && as_dir=. 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" $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else 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 test -z "$as_dir" && as_dir=. 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" $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else 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 test -z "$as_dir" && as_dir=. 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" $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else 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 test -z "$as_dir" && as_dir=. 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" $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$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. $as_echo "$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; 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\"" $as_echo "$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 $as_echo "$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 () { ; 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. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$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\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$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+set}" = set && 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 ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$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_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "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\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$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_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$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 () { 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. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "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\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$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\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$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 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; 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\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$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_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else 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 () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; 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.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*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 don't provoke an error unfortunately, instead are silently treated as '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's necessary to write '\x00'==0 to get something that's 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 **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _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 test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : 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 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "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 `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in netcdf.h do : ac_fn_c_check_header_mongrel "$LINENO" "netcdf.h" "ac_cv_header_netcdf_h" "$ac_includes_default" if test "x$ac_cv_header_netcdf_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NETCDF_H 1 _ACEOF else 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. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing nc_open" >&5 $as_echo_n "checking for library containing nc_open... " >&6; } if ${ac_cv_search_nc_open+:} false; then : $as_echo_n "(cached) " >&6 else 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. */ #ifdef __cplusplus extern "C" #endif char nc_open (); int main () { 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$ac_exeext if ${ac_cv_search_nc_open+:} false; then : break fi done if ${ac_cv_search_nc_open+:} false; then : else ac_cv_search_nc_open=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_nc_open" >&5 $as_echo "$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_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. for ac_func in nc_rename_grp nc_get_var_chunk_cache nc_inq_var_szip nc_inq_var_endian nc_inq_var_filter do : as_ac_var=`$as_echo "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 `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done #-------------------------------------------------------------------------------# # Find UDUNITS2 library and header files # #-------------------------------------------------------------------------------# # The udunits2 library depends on expat, which may need to be linked explicitly: { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing XML_ErrorString" >&5 $as_echo_n "checking for library containing XML_ErrorString... " >&6; } if ${ac_cv_search_XML_ErrorString+:} false; then : $as_echo_n "(cached) " >&6 else 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. */ #ifdef __cplusplus extern "C" #endif char XML_ErrorString (); int main () { 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$ac_exeext if ${ac_cv_search_XML_ErrorString+:} false; then : break fi done if ${ac_cv_search_XML_ErrorString+:} false; then : else ac_cv_search_XML_ErrorString=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_XML_ErrorString" >&5 $as_echo "$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. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ut_read_xml" >&5 $as_echo_n "checking for library containing ut_read_xml... " >&6; } if ${ac_cv_search_ut_read_xml+:} false; then : $as_echo_n "(cached) " >&6 else 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. */ #ifdef __cplusplus extern "C" #endif char ut_read_xml (); int main () { 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$ac_exeext if ${ac_cv_search_ut_read_xml+:} false; then : break fi done if ${ac_cv_search_ut_read_xml+:} false; then : else ac_cv_search_ut_read_xml=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ut_read_xml" >&5 $as_echo "$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=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF enable_calendar=yes; break fi done fi fi fi fi # Define HAVE_LIBUDUNITS2 if all udunits2 checks were successful: if test "x$enable_calendar" == xyes; then : $as_echo "#define HAVE_LIBUDUNITS2 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: disabling calendar functions in RNetCDF" >&5 $as_echo "$as_me: WARNING: disabling calendar functions in RNetCDF" >&2;} fi #-------------------------------------------------------------------------------# # Do substitution # #-------------------------------------------------------------------------------# ac_config_files="$ac_config_files src/Makevars" 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_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$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+set}" = set || &/ 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 { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$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=`$as_echo "$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" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$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 if test -n "${ZSH_VERSION+set}" && (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 case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; 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 # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # 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 test -z "$as_dir" && as_dir=. 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 $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # 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 $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$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_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_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 || $as_echo 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 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 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=`$as_echo "$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 || $as_echo 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.1-1, which was generated by GNU Autoconf 2.69. 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 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ RNetCDF config.status 2.1-1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 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 ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$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 ) $as_echo "$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 \$as_echo "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 $as_echo "$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/Makevars") CONFIG_FILES="$CONFIG_FILES src/Makevars" ;; *) 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+set}" = set || 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=`$as_echo "$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 '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$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 || $as_echo 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=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$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@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$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"; } && { $as_echo "$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 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi #-------------------------------------------------------------------------------# # Done # #-------------------------------------------------------------------------------#