Improve UTF8 Support On Windows

re: Issue https://github.com/Unidata/netcdf-c/issues/2190

The primary purpose of this PR is to improve the utf8 support
for windows. This is persuant to a change in Windows that
supports utf8 natively (almost). The almost means that it is
still utf16 internally and the set of characters representable
by utf8 is larger than those representable by utf16.

This leaves open the question in the Issue about handling
the Windows 1252 character set.

This required the following changes:

1. Test the Windows build and major version in order to see if
   native utf8 is supported.
2. If native utf8 is supported, Modify dpathmgr.c to call the 8-bit
   version of the windows fopen() and open() functions.
3. In support of this, programs that use XGetOpt (Windows versions)
   need to get the command line as utf8 and then parse to
   arc+argv as utf8. This requires using a homegrown command line parser
   named XCommandLineToArgvA.
4. Add a utility program called "acpget" that prints out the
   current Windows code page and locale.

Additionally, some technical debt was cleaned up as follows:

1. Unify all the places which attempt to read all or a part
   of a file into the dutil.c#NC_readfile code.
2. Similary unify all the code that creates temp files into
   dutil.c#NC_mktmp code.
3. Convert almost all remaining calls to fopen() and open()
   to NCfopen() and NCopen3(). This is to ensure that path management
   is used consistently. This touches a number of files.
4. extern->EXTERNL as needed to get it to work under Windows.
This commit is contained in:
Dennis Heimbigner 2022-02-08 20:53:30 -07:00
parent 46149b2d75
commit 36102e3c32
60 changed files with 855 additions and 615 deletions

View File

@ -7,7 +7,7 @@
name: Run macOS-based netCDF Tests
on: [pull_request]
on: [pull_request,push]
jobs:

View File

@ -4,7 +4,7 @@
name: Run Ubuntu/Linux netCDF Tests
on: [pull_request]
on: [pull_request,push]
jobs:

View File

@ -7,7 +7,7 @@
name: Run MSYS2, MinGW64-based Tests
on: [ pull_request ]
on: [pull_request,push]
jobs:

View File

@ -55,6 +55,21 @@ IF(UNAME)
set(TMP_BUILDNAME "${osname}-${osrel}-${cpu}")
ENDIF()
# Define some Platforms
if(osname MATCHES "CYGWIN.*")
SET(ISCYGWIN yes)
endif()
if(osname MATCHES "Darwin.*")
SET(ISOSX yes)
endif()
if(MSVC)
SET(ISMSVC yes)
endif()
if(osname MATCHES "MINGW.*")
SET(ISMINGW yes)
SET(MINGW yes)
endif()
###
# Allow for some customization of the buildname.
# This will make it easier to identify different builds,
@ -86,6 +101,7 @@ INCLUDE(GNUInstallDirs)
IF(MSVC)
SET(GLOBAL PROPERTY USE_FOLDERS ON)
ADD_COMPILE_OPTIONS("/utf-8")
ENDIF()
#Add custom CMake Module
@ -412,7 +428,6 @@ IF(NOT MSVC)
ENDIF(BUILD_FORTRAN)
ENDIF()
###
# Allow the user to specify libraries
# to link against, similar to automakes 'LIBS' variable.
@ -1794,6 +1809,26 @@ IF(ENABLE_MMAP)
ENDIF(ENABLE_MMAP)
#CHECK_FUNCTION_EXISTS(alloca HAVE_ALLOCA)
# Used in the `configure_file` calls below
SET(ISCMAKE "1")
IF(MSVC)
SET(ISMSVC ON CACHE BOOL "" FORCE)
SET(REGEDIT ON CACHE BOOL "" FORCE)
# Get windows major version and build number
EXECUTE_PROCESS(COMMAND "systeminfo" OUTPUT_VARIABLE WININFO)
IF(WININFO STREQUAL "")
SET(WVM 0)
SET(WVB 0)
ELSE()
STRING(REGEX MATCH "\nOS Version:[ \t]+[0-9.]+" WINVERLINE "${WININFO}")
STRING(REGEX REPLACE "[^0-9]*([0-9]+)[.]([0-9])+[.]([0-9]+)" "\\1" WVM "${WINVERLINE}")
STRING(REGEX REPLACE "[^0-9]*([0-9]+)[.]([0-9])+[.]([0-9]+)" "\\3" WVB "${WINVERLINE}")
ENDIF()
SET(WINVERMAJOR ${WVM} CACHE STRING "" FORCE)
SET(WINVERBUILD ${WVB} CACHE STRING "" FORCE)
ENDIF()
#####
# End system inspection checks.
#####
@ -2418,13 +2453,6 @@ configure_file(
${netCDF_SOURCE_DIR}/include/netcdf_dispatch.h.in
${netCDF_BINARY_DIR}/include/netcdf_dispatch.h @ONLY NEWLINE_STYLE LF)
# Used in the `configure_file` calls below
SET(ISCMAKE "1")
IF(MSVC)
SET(ISMSVC "1")
SET(REGEDIT 1)
ENDIF()
####
# Build test_common.sh
#####

View File

@ -7,8 +7,9 @@ This file contains a high-level description of this package's evolution. Release
## 4.8.2 - TBD
* [Bug Fix] Improve UTF8 support on windows to use utf8 natively. See [Github #????](https://github.com/Unidata/netcdf-c/pull/????).
* [Enhancement] Add complete bitgroom support to NCZarr. See [Github #2197](https://github.com/Unidata/netcdf-c/pull/2197).
* [Bug Fix] Clean up the handling of deeply nested VLEN types. Marks nc_free_vlen() and nc_free_string as deprecated in favor of ncaux_reclaim_data(). See [Github #2179(https://github.com/Unidata/netcdf-c/pull/2179).
* [Bug Fix] Clean up the handling of deeply nested VLEN types. Marks nc_free_vlen() and nc_free_string as deprecated in favor of ncaux_reclaim_data(). See [Github #2179](https://github.com/Unidata/netcdf-c/pull/2179).
* [Bug Fix] Make sure that netcdf.h accurately defines the flags in the open/create mode flags. See [Github #2183](https://github.com/Unidata/netcdf-c/pull/2183).
* [Enhancement] Improve support for msys2+mingw platform. See [Github #2171](https://github.com/Unidata/netcdf-c/pull/2171).
* [Bug Fix] Clean up the various inter-test dependencies in ncdump for CMake. See [Github #2168](https://github.com/Unidata/netcdf-c/pull/2168).

View File

@ -157,12 +157,6 @@ are set when opening a binary file on Windows. */
/* if true, Allow dynamically loaded plugins */
#cmakedefine ENABLE_PLUGINS 1
/* Do we have access to the Windows Registry */
#cmakedefine REGEDIT 1
/* define the possible sources for remote test servers */
#cmakedefine REMOTETESTSERVERS "${REMOTETESTSERVERS}"
/* if true, run extra tests which may not work yet */
#cmakedefine EXTRA_TESTS 1
@ -505,6 +499,12 @@ with zip */
/* Define to the version of this package. */
#cmakedefine PACKAGE_VERSION "${netCDF_VERSION}"
/* Do we have access to the Windows Registry */
#cmakedefine REGEDIT 1
/* define the possible sources for remote test servers */
#cmakedefine REMOTETESTSERVERS "${REMOTETESTSERVERS}"
/* The size of `ulonglong` as computed by sizeof. */
#cmakedefine SIZEOF_ULONGLONG @SIZEOF_ULONGLONG@
@ -626,6 +626,10 @@ with zip */
/* Version number of package */
#cmakedefine VERSION "${netCDF_VERSION}"
/* Capture Windows version and build */
#cmakedefine WINVERMAJOR ${WINVERMAJOR}
#cmakedefine WINVERBUILD ${WINVERBUILD}
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD

View File

@ -106,6 +106,15 @@ ISMINGW=yes
ISMSYS=yes
fi
# Get windows version info
WINVER=`systeminfo | sed -e '/^OS Version:/p' -ed | sed -e 's|[^0-9]*\([0-9.]*\).*|\1|'`
WINVERMAJOR=`echo $WVER | sed -e 's|\([^.]*\)[.]\([^.]*\)[.]\(.*\)|\1|'`
WINVERBUILD=`echo $WVER | sed -e 's|\([^.]*\)[.]\([^.]*\)[.]\(.*\)|\3|'`
if test "x$WINVERMAJOR" = x ; then WINVERMAJOR=0; fi
if test "x$WINVERBUILD" = x ; then WINVERBUILD=0; fi
AC_DEFINE_UNQUOTED([WINVERMAJOR], [$WINVERMAJOR], [windows version major])
AC_DEFINE_UNQUOTED([WINVERBUILD], [$WINVERBUILD], [windows version build])
AC_MSG_NOTICE([checking supported formats])
# An explicit disable of netcdf-4 | netcdf4 is treated as if it was disable-hdf5
@ -1218,6 +1227,8 @@ AM_CONDITIONAL(ISMINGW, [test "x$ISMINGW" = xyes])
AM_CONDITIONAL(ISMSYS, [test "x$ISMSYS" = xyes])
AC_SUBST([ISMSVC], [${ISMSVC}])
AC_SUBST([WINVERMAJOR], [${WINVERMAJOR}])
AC_SUBST([WINVERBUILD], [${WINVERBUILD}])
AC_SUBST([ISCYGWIN], [${ISCYGWIN}])
AC_SUBST([ISOSX], [${ISOSX}])
AC_SUBST([ISMINGW], [${ISMINGW}])

View File

@ -26,26 +26,6 @@ static char* outfile = NULL;
static int ncid = 0;
static int translatenc4 = 0;
static int
readfile(const char* filename, NCbytes* content)
{
FILE* stream;
char part[1024];
stream = fopen(filename,"r");
if(stream == NULL) return errno;
for(;;) {
size_t count = fread(part, 1, sizeof(part), stream);
if(count <= 0) break;
ncbytesappendn(content,part,count);
if(ferror(stream)) {fclose(stream); return NC_EIO;}
if(feof(stream)) break;
}
ncbytesnull(content);
fclose(stream);
return NC_NOERR;
}
static void
fail(int code)
{
@ -86,7 +66,7 @@ setup(int tdmr, int argc, char** argv)
outfile = NULL;
input = ncbytesnew();
output = ncbytesnew();
if((ret = readfile(infile,input))) fail(ret);
if((ret = NC_readfile(infile,input))) fail(ret);
{
const char* trans = getenv("translatenc4");
if(trans != NULL)

View File

@ -12,7 +12,7 @@ Test the netcdf-4 data building process.
#include <stdio.h>
#include "netcdf.h"
#define DEBUG
#undef DEBUG
static void
fail(int code)

View File

@ -20,6 +20,8 @@
#include "netcdf.h"
#include "netcdf_filter.h"
#include "nc_logging.h"
#include "ncpathmgr.h"
#include "ncrc.h"
#ifdef USE_PARALLEL
#include "netcdf_par.h"
#endif

View File

@ -103,6 +103,8 @@ EXTERNL int NC__testurl(const char* path, char** basenamep);
EXTERNL int NC_isLittleEndian(void);
EXTERNL char* NC_entityescape(const char* s);
EXTERNL int NC_readfile(const char* filename, NCbytes* content);
EXTERNL int NC_readfilen(const char* filename, NCbytes* content, long long len);
EXTERNL int NC_readfileF(FILE* fp, NCbytes* content, long long len);
EXTERNL int NC_writefile(const char* filename, size_t size, void* content);
EXTERNL char* NC_mktmp(const char* base);
EXTERNL int NC_getmodelist(const char* modestr, NClist** modelistp);

View File

@ -13,7 +13,7 @@
#include "dapincludes.h"
#include "dceparselex.h"
#define DEBUG
#undef DEBUG
#define LBRACE "{"
#define RBRACE "}"

View File

@ -395,17 +395,17 @@ set_curl_properties(NCD4INFO* d4info)
FILE* f = NULL;
char* fname = d4info->auth->curlflags.cookiejar;
/* See if the file exists already */
f = fopen(fname,"r");
f = NCfopen(fname,"r");
if(f == NULL) {
/* Ok, create it */
f = fopen(fname,"w+");
f = NCfopen(fname,"w+");
if(f == NULL) {
fprintf(stderr,"Cookie file cannot be read and written: %s\n",fname);
{ret= NC_EPERM; goto fail;}
}
} else { /* test if file can be written */
fclose(f);
f = fopen(fname,"r+");
f = NCfopen(fname,"r+");
if(f == NULL) {
fprintf(stderr,"Cookie file is cannot be written: %s\n",fname);
{ret = NC_EPERM; goto fail;}

View File

@ -42,6 +42,7 @@
#include "ncuri.h"
#include "nclog.h"
#include "ncdap.h"
#include "ncpathmgr.h"
#include "d4util.h"

View File

@ -346,73 +346,6 @@ NCD4_elidenuls(char* s, size_t slen)
return j;
}
int
NCD4_readfile(const char* filename, NCbytes* content)
{
int ret = NC_NOERR;
FILE* stream = NULL;
char part[1024];
stream = fopen(filename,"r");
if(stream == NULL) {ret=errno; goto done;}
for(;;) {
size_t count = fread(part, 1, sizeof(part), stream);
if(count <= 0) break;
ncbytesappendn(content,part,count);
if(ferror(stream)) {ret = NC_EIO; goto done;}
if(feof(stream)) break;
}
ncbytesnull(content);
done:
if(stream) fclose(stream);
return ret;
}
/**
Wrap mktmp and return the generated name
*/
int
NCD4_mktmp(const char* base, char** tmpnamep)
{
int fd;
char tmp[NC_MAX_PATH];
#ifdef HAVE_MKSTEMP
mode_t mask;
#endif
strncpy(tmp,base,sizeof(tmp));
#ifdef HAVE_MKSTEMP
strlcat(tmp,"XXXXXX", sizeof(tmp));
/* Note Potential problem: old versions of this function
leave the file in mode 0666 instead of 0600 */
mask=umask(0077);
fd = mkstemp(tmp);
(void)umask(mask);
#else /* !HAVE_MKSTEMP */
/* Need to simulate by using some kind of pseudo-random number */
{
int rno = rand();
char spid[7];
if(rno < 0) rno = -rno;
snprintf(spid,sizeof(spid),"%06d",rno);
strlcat(tmp,spid,sizeof(tmp));
#if defined(_WIN32) || defined(_WIN64)
fd=open(tmp,O_RDWR|O_BINARY|O_CREAT, _S_IREAD|_S_IWRITE);
# else
fd=open(tmp,O_RDWR|O_CREAT|O_EXCL, S_IRWXU);
# endif
}
#endif /* !HAVE_MKSTEMP */
if(fd < 0) {
nclog(NCLOGERR, "Could not create temp file: %s",tmp);
return THROW(NC_EPERM);
} else
close(fd);
if(tmpnamep) *tmpnamep = strdup(tmp);
return THROW(NC_NOERR);
}
void
NCD4_hostport(NCURI* uri, char* space, size_t len)
{

View File

@ -64,114 +64,114 @@ defined here, including function-like #defines.
/* DSP API wrappers */
#ifdef FIX
extern int dsp_getDMR(ND4dsp* dsp, DCR** dcrp);
extern int dsp_getDAP(ND4dsp* dsp, DCR** dcrp);
extern int dsp_close(ND4dsp* dsp);
EXTERNL int dsp_getDMR(ND4dsp* dsp, DCR** dcrp);
EXTERNL int dsp_getDAP(ND4dsp* dsp, DCR** dcrp);
EXTERNL int dsp_close(ND4dsp* dsp);
/* DSP API */
extern int dsp_open(const char* path, ND4dsp** dspp);
EXTERNL int dsp_open(const char* path, ND4dsp** dspp);
#endif
/**************************************************/
/* From d4http.c */
extern long NCD4_fetchhttpcode(CURL* curl);
extern int NCD4_fetchurl_file(CURL* curl, const char* url, FILE* stream, d4size_t* sizep, long* filetime);
extern int NCD4_fetchurl(CURL* curl, const char* url, NCbytes* buf, long* filetime, int* httpcode);
extern int NCD4_curlopen(CURL** curlp);
extern void NCD4_curlclose(CURL* curl);
extern int NCD4_fetchlastmodified(CURL* curl, char* url, long* filetime);
extern int NCD4_ping(const char* url);
EXTERNL long NCD4_fetchhttpcode(CURL* curl);
EXTERNL int NCD4_fetchurl_file(CURL* curl, const char* url, FILE* stream, d4size_t* sizep, long* filetime);
EXTERNL int NCD4_fetchurl(CURL* curl, const char* url, NCbytes* buf, long* filetime, int* httpcode);
EXTERNL int NCD4_curlopen(CURL** curlp);
EXTERNL void NCD4_curlclose(CURL* curl);
EXTERNL int NCD4_fetchlastmodified(CURL* curl, char* url, long* filetime);
EXTERNL int NCD4_ping(const char* url);
/* From d4read.c */
extern int NCD4_readDMR(NCD4INFO* state, int flags);
extern int NCD4_readDAP(NCD4INFO* state, int flags);
extern int NCD4_seterrormessage(NCD4meta* metadata, size_t len, char* msg);
EXTERNL int NCD4_readDMR(NCD4INFO* state, int flags);
EXTERNL int NCD4_readDAP(NCD4INFO* state, int flags);
EXTERNL int NCD4_seterrormessage(NCD4meta* metadata, size_t len, char* msg);
/* From d4parser.c */
extern int NCD4_parse(NCD4meta*);
extern NCD4node* NCD4_findAttr(NCD4node* container, const char* attrname);
extern NCD4node* NCD4_groupFor(NCD4node* node);
extern int NCD4_defineattr(NCD4meta* meta, NCD4node* parent, const char* aname, const char* typename, NCD4node** attrp);
EXTERNL int NCD4_parse(NCD4meta*);
EXTERNL NCD4node* NCD4_findAttr(NCD4node* container, const char* attrname);
EXTERNL NCD4node* NCD4_groupFor(NCD4node* node);
EXTERNL int NCD4_defineattr(NCD4meta* meta, NCD4node* parent, const char* aname, const char* typename, NCD4node** attrp);
/* From d4printer.c */
extern int NCD4_print(NCD4meta*, NCbytes* output);
EXTERNL int NCD4_print(NCD4meta*, NCbytes* output);
/* From d4meta.c */
extern NCD4meta* NCD4_newmeta(NCD4INFO*);
extern void NCD4_attachraw(NCD4meta*, size_t size, void* rawdata);
extern void NCD4_reclaimMeta(NCD4meta*);
extern void NCD4_resetMeta(NCD4meta*);
extern void reclaimNode(NCD4node* node);
extern void NCD4_setdebuglevel(NCD4meta*,int);
extern int NCD4_metabuild(NCD4meta*, int ncid);
extern size_t NCD4_computeTypeSize(NCD4meta*, NCD4node* type);
extern int NCD4_findvar(NC* ncp, int ncid, int varid, NCD4node** varp, NCD4node** grpp);
EXTERNL NCD4meta* NCD4_newmeta(NCD4INFO*);
EXTERNL void NCD4_attachraw(NCD4meta*, size_t size, void* rawdata);
EXTERNL void NCD4_reclaimMeta(NCD4meta*);
EXTERNL void NCD4_resetMeta(NCD4meta*);
EXTERNL void reclaimNode(NCD4node* node);
EXTERNL void NCD4_setdebuglevel(NCD4meta*,int);
EXTERNL int NCD4_metabuild(NCD4meta*, int ncid);
EXTERNL size_t NCD4_computeTypeSize(NCD4meta*, NCD4node* type);
EXTERNL int NCD4_findvar(NC* ncp, int ncid, int varid, NCD4node** varp, NCD4node** grpp);
/* From d4chunk.c */
extern int NCD4_dechunk(NCD4meta*);
extern int NCD4_infermode(NCD4meta* meta);
EXTERNL int NCD4_dechunk(NCD4meta*);
EXTERNL int NCD4_infermode(NCD4meta* meta);
struct NCD4serial;
extern void NCD4_resetSerial(struct NCD4serial* serial, size_t rawsize, void* rawdata);
EXTERNL void NCD4_resetSerial(struct NCD4serial* serial, size_t rawsize, void* rawdata);
/* From d4swap.c */
extern int NCD4_swapdata(NCD4meta*, NClist* topvars);
EXTERNL int NCD4_swapdata(NCD4meta*, NClist* topvars);
/* From d4fix.c */
extern int NCD4_delimit(NCD4meta*, NCD4node* var, void** offsetp);
extern int NCD4_moveto(NCD4meta*, NCD4node* var, d4size_t count, void** offsetp);
extern int NCD4_toposort(NCD4meta*);
EXTERNL int NCD4_delimit(NCD4meta*, NCD4node* var, void** offsetp);
EXTERNL int NCD4_moveto(NCD4meta*, NCD4node* var, d4size_t count, void** offsetp);
EXTERNL int NCD4_toposort(NCD4meta*);
/* From d4data.c */
extern int NCD4_processdata(NCD4meta*);
extern int NCD4_fillinstance(NCD4meta*, NCD4node* type, void** offsetp, void** dstp, NClist* blobs);
extern int NCD4_getToplevelVars(NCD4meta* meta, NCD4node* group, NClist* toplevel);
EXTERNL int NCD4_processdata(NCD4meta*);
EXTERNL int NCD4_fillinstance(NCD4meta*, NCD4node* type, void** offsetp, void** dstp, NClist* blobs);
EXTERNL int NCD4_getToplevelVars(NCD4meta* meta, NCD4node* group, NClist* toplevel);
/* From d4util.c */
extern d4size_t NCD4_dimproduct(NCD4node* node);
extern size_t NCD4_typesize(nc_type tid);
extern int NCD4_isLittleEndian(void);/* Return 1 if this machine is little endian */
extern int NCD4_errorNC(int code, const int line, const char* file);
extern int NCD4_error(int code, const int line, const char* file, const char* fmt, ...);
extern char* NCD4_makeFQN(NCD4node* node);
extern char* NCD4_makeName(NCD4node*,const char* sep);
extern int NCD4_parseFQN(const char* fqn0, NClist* pieces);
extern char* NCD4_deescape(const char* esc);
extern char* NCD4_entityescape(const char* s);
extern size_t NCD4_elidenuls(char* s, size_t slen);
extern void* NCD4_getheader(void* p, NCD4HDR* hdr, int hostlittleendian);
extern void NCD4_reporterror(NCD4INFO* state);
EXTERNL d4size_t NCD4_dimproduct(NCD4node* node);
EXTERNL size_t NCD4_typesize(nc_type tid);
EXTERNL int NCD4_isLittleEndian(void);/* Return 1 if this machine is little endian */
EXTERNL int NCD4_errorNC(int code, const int line, const char* file);
EXTERNL int NCD4_error(int code, const int line, const char* file, const char* fmt, ...);
EXTERNL char* NCD4_makeFQN(NCD4node* node);
EXTERNL char* NCD4_makeName(NCD4node*,const char* sep);
EXTERNL int NCD4_parseFQN(const char* fqn0, NClist* pieces);
EXTERNL char* NCD4_deescape(const char* esc);
EXTERNL char* NCD4_entityescape(const char* s);
EXTERNL size_t NCD4_elidenuls(char* s, size_t slen);
EXTERNL void* NCD4_getheader(void* p, NCD4HDR* hdr, int hostlittleendian);
EXTERNL void NCD4_reporterror(NCD4INFO* state);
/* From d4dump.c */
extern void NCD4_dumpbytes(size_t size, const void* data0, int swap);
extern void NCD4_tagdump(size_t size, const void* data0, int swap, const char* tag);
extern void NCD4_dumpvars(NCD4node* group);
extern union ATOMICS* NCD4_dumpatomic(NCD4node* var, void* data);
EXTERNL void NCD4_dumpbytes(size_t size, const void* data0, int swap);
EXTERNL void NCD4_tagdump(size_t size, const void* data0, int swap, const char* tag);
EXTERNL void NCD4_dumpvars(NCD4node* group);
EXTERNL union ATOMICS* NCD4_dumpatomic(NCD4node* var, void* data);
/* From d4rc.c */
extern int NCD4_rcload(void);
extern int NCD4_rcprocess(NCD4INFO* info);
extern void NCD4_rcfree(NClist* rc);
extern char* NCD4_rclookup(char* key, char* hostport);
extern int NCD4_parseproxy(NCD4INFO* info, const char* surl);
extern int NCD4_rcdefault(NCD4INFO*);
EXTERNL int NCD4_rcload(void);
EXTERNL int NCD4_rcprocess(NCD4INFO* info);
EXTERNL void NCD4_rcfree(NClist* rc);
EXTERNL char* NCD4_rclookup(char* key, char* hostport);
EXTERNL int NCD4_parseproxy(NCD4INFO* info, const char* surl);
EXTERNL int NCD4_rcdefault(NCD4INFO*);
/* From d4cvt.c */
extern int NCD4_convert(nc_type srctype, nc_type dsttype, char* memory0, char* value0, size_t count);
EXTERNL int NCD4_convert(nc_type srctype, nc_type dsttype, char* memory0, char* value0, size_t count);
/* d4file.c */
extern void NCD4_applyclientparamcontrols(NCD4INFO*);
extern int NCD4_readDMRorDAP(NCD4INFO* d4info, NCD4mode mode);
EXTERNL void NCD4_applyclientparamcontrols(NCD4INFO*);
EXTERNL int NCD4_readDMRorDAP(NCD4INFO* d4info, NCD4mode mode);
/* ncd4dispatch.c */
struct NC_reservedatt; /*forward*/
extern const struct NC_reservedatt* NCD4_lookupreserved(const char* name);
EXTERNL const struct NC_reservedatt* NCD4_lookupreserved(const char* name);
/* Add an extra function whose sole purpose is to allow
configure(.ac) to test for the presence of this code.
*/
extern int nc__dap4(void);
EXTERNL int nc__dap4(void);
/**************************************************/
/* Macro defined functions */

View File

@ -199,7 +199,7 @@ local void make_crc_table()
{
FILE *out;
out = fopen("dcrc32.h", "w");
out = NCfopen("dcrc32.h", "w");
if (out == NULL) return;
fprintf(out, "/* dcrc32.h -- tables for rapid CRC calculation\n");
fprintf(out, " * Generated automatically by dcrc32.c\n */\n\n");

View File

@ -1263,9 +1263,8 @@ openmagic(struct MagicFile* file)
} else
#endif /* USE_PARALLEL */
{
if(file->path == NULL || strlen(file->path)==0)
{status = NC_EINVAL; goto done;}
if (file->path == NULL || strlen(file->path) == 0)
{status = NC_EINVAL; goto done;}
file->fp = NCfopen(file->path, "r");
if(file->fp == NULL)
{status = errno; goto done;}
@ -1296,6 +1295,8 @@ static int
readmagic(struct MagicFile* file, long pos, char* magic)
{
int status = NC_NOERR;
NCbytes* buf = ncbytesnew();
memset(magic,0,MAGIC_NUMBER_LEN);
if(fIsSet(file->omode,NC_INMEMORY)) {
char* mempos;
@ -1315,19 +1316,18 @@ readmagic(struct MagicFile* file, long pos, char* magic)
if(file->iss3) {
if((status = NC_s3sdkread(file->s3client,file->s3.bucket,file->s3.rootkey,start,count,(void*)magic,&file->errmsg)))
{goto done;}
} else
}
else
#endif
{
NCbytes* buf = ncbytesnew();
status = nc_http_read(file->state,file->curlurl,start,count,buf);
if(status == NC_NOERR) {
if(ncbyteslength(buf) != count)
status = NC_EINVAL;
else
memcpy(magic,ncbytescontents(buf),count);
}
ncbytesfree(buf);
}
{
status = nc_http_read(file->state, file->curlurl, start, count, buf);
if (status == NC_NOERR) {
if (ncbyteslength(buf) != count)
status = NC_EINVAL;
else
memcpy(magic, ncbytescontents(buf), count);
}
}
#endif
} else {
#ifdef USE_PARALLEL
@ -1337,23 +1337,21 @@ readmagic(struct MagicFile* file, long pos, char* magic)
if((retval = MPI_File_read_at_all(file->fh, pos, magic,
MAGIC_NUMBER_LEN, MPI_CHAR, &mstatus)) != MPI_SUCCESS)
{status = NC_EPARINIT; goto done;}
} else
}
else
#endif /* USE_PARALLEL */
{
int count;
int i = fseek(file->fp,pos,SEEK_SET);
if(i < 0)
{status = errno; goto done;}
for(i=0;i<MAGIC_NUMBER_LEN;) {/* make sure to read proper # of bytes */
count=fread(&magic[i],1,(size_t)(MAGIC_NUMBER_LEN-i),file->fp);
if(count == 0 || ferror(file->fp))
{status = errno; goto done;}
i += count;
}
}
{ /* Ordinary read */
long i;
i = fseek(file->fp, pos, SEEK_SET);
if (i < 0) { status = errno; goto done; }
ncbytessetlength(buf, 0);
if ((status = NC_readfileF(file->fp, buf, MAGIC_NUMBER_LEN))) goto done;
memcpy(magic, ncbytescontents(buf), MAGIC_NUMBER_LEN);
}
}
done:
ncbytesfree(buf);
if(file && file->fp) clearerr(file->fp);
return check(status);
}

View File

@ -153,14 +153,15 @@ reclaim_datar(int ncid, nc_type xtype, Position* offset)
int klass, isf;
if((stat = NC4_inq_type_fixed_size(ncid,xtype,&isf))) goto done;
/* Get relevant type info */
if((stat = NC_inq_any_type(ncid,xtype,NULL,&xsize,&basetype,&nfields,&klass))) goto done;
if(isf) { /* no need to reclaim anything */
offset->offset += xsize;
goto done;
}
/* Get relevant type info */
if((stat = NC_inq_any_type(ncid,xtype,NULL,&xsize,&basetype,&nfields,&klass))) goto done;
switch (xtype) {
case NC_STRING: {
char** sp = (char**)(offset->memory + offset->offset);

View File

@ -25,13 +25,9 @@
#include <windows.h>
#include <io.h>
#include <wchar.h>
#include <locale.h>
#include <direct.h>
#endif
#ifdef __hpux
#include <locale.h>
#endif
#include "netcdf.h"
#include "ncpathmgr.h"
#include "nclog.h"
@ -42,7 +38,7 @@
#undef DEBUGPATH
static int pathdebug = -1;
#define DEBUG
#undef DEBUG
#ifdef DEBUG
#define REPORT(e,msg) report((e),(msg),__LINE__)
@ -55,6 +51,14 @@ static int pathdebug = -1;
#define mkdir _mkdir
#define rmdir _rmdir
#define getcwd _getcwd
#if WINVERMAJOR > 10 || (WINVERMAJOR == 10 && WINVERBUILD >= 17134)
/* Should be possible to use UTF8 directly */
#define WINUTF8
#else
#undef WINUTF8
#endif
#endif
/*
@ -87,6 +91,11 @@ static const struct Path {
/* Keep the working directory kind and drive */
static char wdprefix[8192];
/* The current codepage */
#ifdef _WIN32
static int acp = -1;
#endif
/* Keep CYGWIN/MSYS2 mount point */
static struct MountPoint {
int defined;
@ -265,6 +274,7 @@ static void
pathinit(void)
{
if(pathinitialized) return;
pathinitialized = 1; /* avoid recursion */
/* Check for path debug env vars */
if(pathdebug < 0) {
@ -272,6 +282,12 @@ pathinit(void)
pathdebug = (s == NULL ? 0 : 1);
}
(void)getwdpath();
#ifdef _WIN32
/* Get the current code page */
acp = GetACP();
#endif
memset(&mountpoint,0,sizeof(mountpoint));
#ifdef REGEDIT
{ /* See if we can get the MSYS2 prefix from the registry */
@ -367,31 +383,44 @@ NCfopen(const char* path, const char* flags)
{
int stat = NC_NOERR;
FILE* f = NULL;
char* bflags = NULL;
char bflags[64];
char* path8 = NULL; /* ACP -> UTF=8 */
char* bflags8 = NULL;
char* cvtpath = NULL;
wchar_t* wpath = NULL;
wchar_t* wflags = NULL;
size_t flaglen = strlen(flags)+1+1;
bflags = (char*)malloc(flaglen);
bflags[0] = '\0';
strlcat(bflags,flags,flaglen);
strlcat(bflags, flags, sizeof(bflags));
#ifdef _WIN32
strlcat(bflags,"b",flaglen);
strlcat(bflags,"b",sizeof(bflags));
#endif
cvtpath = NCpathcvt(path);
if(cvtpath == NULL) return NULL;
/* Convert from local to wide */
if((stat = utf82wide(cvtpath,&wpath)))
{REPORT(stat,"utf282wide"); goto done;}
if((stat = ansi2wide(bflags,&wflags)))
{REPORT(stat,"ansi2wide"); goto done;}
f = _wfopen(wpath,wflags);
/* First, convert from current Code Page to utf8 */
if((stat = ansi2utf8(path,&path8))) goto done;
if((stat = ansi2utf8(bflags,&bflags8))) goto done;
/* Localize */
if((cvtpath = NCpathcvt(path8))==NULL) goto done;
#ifdef WINUTF8
if(acp == CP_UTF8) {
/* This should take utf8 directly */
f = fopen(cvtpath,bflags8);
} else
#endif
{
/* Convert from utf8 to wide */
if((stat = utf82wide(cvtpath,&wpath))) goto done;
if((stat = utf82wide(bflags8,&wflags))) goto done;
f = _wfopen(wpath,wflags);
}
done:
nullfree(cvtpath);
nullfree(path8);
nullfree(wpath);
nullfree(wflags);
nullfree(bflags);
return f;
}
@ -402,17 +431,32 @@ NCopen3(const char* path, int flags, int mode)
int stat = NC_NOERR;
int fd = -1;
char* cvtpath = NULL;
char* path8 = NULL;
wchar_t* wpath = NULL;
cvtpath = NCpathcvt(path);
if(cvtpath == NULL) goto done;
/* Convert from utf8 to wide */
if((stat = utf82wide(cvtpath,&wpath))) goto done;
/* First, convert from current Code Page to utf8 */
if((stat = ansi2utf8(path,&path8))) goto done;
if((cvtpath = NCpathcvt(path8))==NULL) goto done;
#ifdef _WIN32
flags |= O_BINARY;
#endif
fd = _wopen(wpath,flags,mode);
#ifdef WINUTF8
if(acp == CP_UTF8) {
/* This should take utf8 directly */
fd = _open(cvtpath,flags,mode);
} else
#endif
{
/* Convert from utf8 to wide */
if((stat = utf82wide(cvtpath,&wpath))) goto done;
fd = _wopen(wpath,flags,mode);
}
done:
nullfree(cvtpath);
nullfree(path8);
nullfree(wpath);
return fd;
}
@ -433,7 +477,7 @@ NCopendir(const char* path)
char* cvtname = NCpathcvt(path);
if(cvtname == NULL) return NULL;
ent = opendir(cvtname);
free(cvtname);
nullfree(cvtname);
return ent;
}
@ -456,17 +500,32 @@ EXTERNL
int
NCaccess(const char* path, int mode)
{
int status = 0;
int stat = 0;
char* cvtpath = NULL;
char* path8 = NULL;
wchar_t* wpath = NULL;
if((cvtpath = NCpathcvt(path)) == NULL)
{status = EINVAL; goto done;}
if((status = utf82wide(cvtpath,&wpath))) {status = ENOENT; goto done;}
if(_waccess(wpath,mode) < 0) {status = errno; goto done;}
/* First, convert from current Code Page to utf8 */
if((stat = ansi2utf8(path,&path8))) goto done;
if((cvtpath = NCpathcvt(path8)) == NULL) {stat = EINVAL; goto done;}
#ifdef WINUTF8
if(acp == CP_UTF8) {
/* This should take utf8 directly */
if(_access(cvtpath,mode) < 0) {stat = errno; goto done;}
} else
#endif
{
/* Convert from utf8 to wide */
if((stat = utf82wide(cvtpath,&wpath))) goto done;
if(_waccess(wpath,mode) < 0) {stat = errno; goto done;}
}
done:
free(cvtpath);
free(wpath);
errno = status;
nullfree(cvtpath);
nullfree(path8);
nullfree(wpath);
errno = stat;
return (errno?-1:0);
}
@ -475,14 +534,29 @@ int
NCremove(const char* path)
{
int status = 0;
char* path8 = NULL;
char* cvtpath = NULL;
wchar_t* wpath = NULL;
if((cvtpath = NCpathcvt(path)) == NULL) {status=ENOMEM; goto done;}
if((status = utf82wide(cvtpath,&wpath))) {status = ENOENT; goto done;}
if(_wremove(wpath) < 0) {status = errno; goto done;}
/* First, convert from current Code Page to utf8 */
if((status = ansi2utf8(path,&path8))) goto done;
if((cvtpath = NCpathcvt(path8)) == NULL) {status=ENOMEM; goto done;}
#ifdef WINUTF8
if(acp == CP_UTF8) {
/* This should take utf8 directly */
if(remove(cvtpath) < 0) {status = errno; goto done;}
} else
#endif
{
if((status = utf82wide(cvtpath,&wpath))) {status = ENOENT; goto done;}
if(_wremove(wpath) < 0) {status = errno; goto done;}
}
done:
free(cvtpath);
free(wpath);
nullfree(cvtpath);
nullfree(path8);
nullfree(wpath);
errno = status;
return (errno?-1:0);
}
@ -493,13 +567,28 @@ NCmkdir(const char* path, int mode)
{
int status = 0;
char* cvtpath = NULL;
char* path8 = NULL;
wchar_t* wpath = NULL;
if((cvtpath = NCpathcvt(path)) == NULL) {status=ENOMEM; goto done;}
if((status = utf82wide(cvtpath,&wpath))) {status = ENOENT; goto done;}
if(_wmkdir(wpath) < 0) {status = errno; goto done;}
/* First, convert from current Code Page to utf8 */
if((status = ansi2utf8(path,&path8))) goto done;
if((cvtpath = NCpathcvt(path8)) == NULL) {status=ENOMEM; goto done;}
#ifdef WINUTF8
if(acp == CP_UTF8) {
/* This should take utf8 directly */
if(_mkdir(cvtpath) < 0) {status = errno; goto done;}
} else
#endif
{
if((status = utf82wide(cvtpath,&wpath))) {status = ENOENT; goto done;}
if(_wmkdir(wpath) < 0) {status = errno; goto done;}
}
done:
free(cvtpath);
free(wpath);
nullfree(cvtpath);
nullfree(path8);
nullfree(wpath);
errno = status;
return (errno?-1:0);
}
@ -509,10 +598,18 @@ int
NCrmdir(const char* path)
{
int status = 0;
char* cvtname = NCpathcvt(path);
if(cvtname == NULL) {errno = ENOENT; return -1;}
char* cvtname = NULL;
char* path8 = NULL;
/* First, convert from current Code Page to utf8 */
if((status = ansi2utf8(path,&path8))) goto done;
cvtname = NCpathcvt(path8);
if(cvtname == NULL) {errno = ENOENT; status = -1;}
status = rmdir(cvtname);
free(cvtname);
done:
nullfree(cvtname);
nullfree(path8);
return status;
}
@ -589,13 +686,26 @@ NCstat(const char* path, struct stat* buf)
{
int status = 0;
char* cvtpath = NULL;
char* path8 = NULL;
wchar_t* wpath = NULL;
if((cvtpath = NCpathcvt(path)) == NULL) {status=ENOMEM; goto done;}
if((status = utf82wide(cvtpath,&wpath))) {status = ENOENT; goto done;}
if(_wstat64(wpath,buf) < 0) {status = errno; goto done;}
if((status = ansi2utf8(path,&path8))) goto done;
if((cvtpath = NCpathcvt(path8)) == NULL) {status=ENOMEM; goto done;}
#ifdef WINUTF8
if(acp == CP_UTF8) {
if(_stat64(cvtpath,buf) < 0) {status = errno; goto done;}
} else
#endif
{
if((status = utf82wide(cvtpath,&wpath))) {status = ENOENT; goto done;}
if(_wstat64(wpath,buf) < 0) {status = errno; goto done;}
}
done:
free(cvtpath);
free(wpath);
nullfree(cvtpath);
nullfree(path8);
nullfree(wpath);
errno = status;
return (errno?-1:0);
}
@ -672,6 +782,7 @@ parsepath(const char* inpath, struct Path* path)
memset(path,0,sizeof(struct Path));
if(inpath == NULL) goto done; /* defensive driving */
if(!pathinitialized) pathinit();
#if 0
/* Convert to UTF8 */
@ -999,7 +1110,7 @@ getwdpath(void)
wpath = _wgetcwd(wcwd, 8192);
path = NULL;
stat = wide2utf8(wpath, &path);
free(wcwd);
nullfree(wcwd);
if (stat) return stat;
strlcat(wdprefix,path,sizeof(wdprefix));
}
@ -1067,9 +1178,9 @@ NCgetkindname(int kind)
#ifdef WINPATH
/**
* Converts the filename from Locale character set (presumably some
* Converts the file path from current character set (presumably some
* ANSI character set like ISO-Latin-1 or UTF-8 to UTF-8
* @param local Pointer to a nul-terminated string in locale char set.
* @param local Pointer to a nul-terminated string in current char set.
* @param u8p Pointer for returning the output utf8 string
*
* @return NC_NOERR return converted filename
@ -1078,21 +1189,32 @@ NCgetkindname(int kind)
*
*/
static int
ansi2utf8(const char* local, char** u8p)
ansi2utf8(const char* path, char** u8p)
{
int stat=NC_NOERR;
char* u8 = NULL;
int n;
wchar_t* u16 = NULL;
if(path == NULL) goto done;
if(!pathinitialized) pathinit();
#ifdef WINUTF8
if(acp == CP_UTF8) { /* Current code page is UTF8 and Windows supports */
u8 = strdup(path);
if(u8 == NULL) stat = NC_ENOMEM;
} else
#endif
/* Use wide character conversion plus current code page*/
{
/* Get length of the converted string */
n = MultiByteToWideChar(CP_ACP, 0, local, -1, NULL, 0);
n = MultiByteToWideChar(acp, 0, path, -1, NULL, 0);
if (!n) {stat = NC_EINVAL; goto done;}
if((u16 = malloc(sizeof(wchar_t) * n))==NULL)
if((u16 = malloc(sizeof(wchar_t) * (n)))==NULL)
{stat = NCTHROW(NC_ENOMEM); goto done;}
/* do the conversion */
if (!MultiByteToWideChar(CP_ACP, 0, local, -1, u16, n))
if (!MultiByteToWideChar(CP_ACP, 0, path, -1, u16, n))
{stat = NC_EINVAL; goto done;}
/* Now reverse the process to produce utf8 */
n = WideCharToMultiByte(CP_UTF8, 0, u16, -1, NULL, 0, NULL, NULL);
@ -1102,8 +1224,8 @@ ansi2utf8(const char* local, char** u8p)
if (!WideCharToMultiByte(CP_UTF8, 0, u16, -1, u8, n, NULL, NULL))
{stat = NC_EINVAL; goto done;}
}
if(u8p) {*u8p = u8; u8 = NULL;}
done:
if(u8p) {*u8p = u8; u8 = NULL;}
nullfree(u8);
nullfree(u16);
return stat;
@ -1116,6 +1238,8 @@ ansi2wide(const char* local, wchar_t** u16p)
wchar_t* u16 = NULL;
int n;
if(!pathinitialized) pathinit();
/* Get length of the converted string */
n = MultiByteToWideChar(CP_ACP, 0, local, -1, NULL, 0);
if (!n) {stat = NC_EINVAL; goto done;}
@ -1137,6 +1261,8 @@ utf82wide(const char* utf8, wchar_t** u16p)
wchar_t* u16 = NULL;
int n;
if(!pathinitialized) pathinit();
/* Get length of the converted string */
n = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
if (!n) {stat = NC_EINVAL; goto done;}
@ -1158,6 +1284,8 @@ wide2utf8(const wchar_t* u16, char** u8p)
char* u8 = NULL;
int n;
if(!pathinitialized) pathinit();
/* Get length of the converted string */
n = WideCharToMultiByte(CP_UTF8, 0, u16, -1, NULL, 0, NULL, NULL);
if (!n) {stat = NC_EINVAL; goto done;}
@ -1172,17 +1300,6 @@ done:
return stat;
}
/* Set locale */
void
nc_setlocale_utf8(void)
{
#ifdef __hpux
setlocale(LC_CTYPE,"");
#else
setlocale(LC_ALL,"C.UTF8");
#endif
}
#endif /*WINPATH*/
static char*

View File

@ -195,7 +195,7 @@ NC_shellUnescape(const char* esc)
}
/**
Wrap mktmp and return the generated path,
Wrap mkstemp and return the generated path,
or null if failed.
Base is the base file path. XXXXX is appended
to allow mktmp add its unique id.
@ -208,16 +208,41 @@ NC_mktmp(const char* base)
int fd = -1;
char* tmp = NULL;
size_t len;
int tries;
#define MAXTRIES 4
#ifdef HAVE_MKSTEMP
mode_t mask;
#endif
len = strlen(base)+6+1;
if((tmp = (char*)malloc(len))==NULL)
if((tmp = (char*)calloc(1,len))==NULL)
goto done;
strncpy(tmp,base,len);
#ifdef HAVE_MKSTEMP
strlcat(tmp,base,len);
strlcat(tmp, "XXXXXX", len);
mask=umask(0077);
fd = NCmkstemp(tmp);
(void)umask(mask);
#else /* !HAVE_MKSTEMP */
/* Need to simulate by using some kind of pseudo-random number */
for(tries=0;tries<MAXTRIES;tries++) {
int rno = rand();
char spid[7];
if(rno < 0) rno = -rno;
tmp[0] = '\0';
strlcat(tmp,base,len);
snprintf(spid,sizeof(spid),"%06d",rno);
strlcat(tmp,spid,len);
fd=NCopen3(tmp,O_RDWR|O_CREAT, _S_IREAD|_S_IWRITE);
if(fd >= 0) break; /* sucess */
fd = -1; /* try again */
}
#endif /* !HAVE_MKSTEMP */
if(fd < 0) {
nclog(NCLOGERR, "Could not create temp file: %s",tmp);
goto done;
nclog(NCLOGERR, "Could not create temp file: %s",tmp);
nullfree(tmp);
tmp = NULL;
goto done;
}
done:
if(fd >= 0) close(fd);
@ -226,23 +251,47 @@ done:
int
NC_readfile(const char* filename, NCbytes* content)
{
int stat;
stat = NC_readfilen(filename, content, -1);
return stat;
}
int
NC_readfilen(const char* filename, NCbytes* content, long long amount)
{
int ret = NC_NOERR;
FILE* stream = NULL;
char part[1024];
stream = NCfopen(filename,"r");
if(stream == NULL) {ret=errno; goto done;}
for(;;) {
ret = NC_readfileF(stream,content,amount);
if (stream) fclose(stream);
done:
return ret;
}
int
NC_readfileF(FILE* stream, NCbytes* content, long long amount)
{
int ret = NC_NOERR;
long long red = 0;
char part[1024];
while(amount < 0 || red < amount) {
size_t count = fread(part, 1, sizeof(part), stream);
if(count <= 0) break;
ncbytesappendn(content,part,count);
if(ferror(stream)) {ret = NC_EIO; goto done;}
if(feof(stream)) break;
if(count > 0) ncbytesappendn(content,part,(unsigned long)count);
red += count;
if (feof(stream)) break;
}
/* Keep only amount */
if(amount >= 0) {
if(red > amount) ncbytessetlength(content,amount); /* read too much */
if(red < amount) ret = NC_ETRUNC; /* |file| < amount */
}
ncbytesnull(content);
done:
if(stream) fclose(stream);
return ret;
}
@ -263,8 +312,8 @@ NC_writefile(const char* filename, size_t size, void* content)
while(remain > 0) {
size_t written = fwrite(p, 1, remain, stream);
if(ferror(stream)) {ret = NC_EIO; goto done;}
if(feof(stream)) break;
remain -= written;
if (feof(stream)) break;
}
done:
if(stream) fclose(stream);

View File

@ -73,9 +73,8 @@ NC_s3sdkinitialize(void)
ncs3_finalized = 0;
NCTRACE(11,NULL);
Aws::InitAPI(ncs3options);
NCUNTRACE(NC_NOERR);
}
return 1;
return NCUNTRACE(NC_NOERR);
}
EXTERNL int
@ -86,9 +85,8 @@ NC_s3sdkfinalize(void)
ncs3_finalized = 1;
NCTRACE(11,NULL);
Aws::ShutdownAPI(ncs3options);
NCUNTRACE(NC_NOERR);
}
return 1;
return NCUNTRACE(NC_NOERR);
}
static char*

View File

@ -1,220 +1,284 @@
// XGetopt.cpp Version 1.2
//
// Author: Hans Dietrich
// hdietrich2@hotmail.com
//
// Description:
// XGetopt.cpp implements getopt(), a function to parse command lines.
//
// History
// Version 1.2 - 2003 May 17
// - Added Unicode support
//
// Version 1.1 - 2002 March 10
// - Added example to XGetopt.cpp module header
//
// This software is released into the public domain.
// You are free to use it in any way you like.
//
// This software is provided "as is" with no expressed
// or implied warranty. I accept no liability for any
// damage or loss of business that this software may cause.
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// if you are not using precompiled headers then include these lines:
///////////////////////////////////////////////////////////////////////////////
// XGetopt.cpp Version 1.2
//
// Author: Hans Dietrich
// hdietrich2@hotmail.com
//
// Description:
// XGetopt.cpp implements getopt(), a function to parse command lines.
//
// History
// Version 1.2 - 2003 May 17
// - Added Unicode support
//
// Version 1.1 - 2002 March 10
// - Added example to XGetopt.cpp module header
//
// This software is released into the public domain.
// You are free to use it in any way you like.
//
// This software is provided "as is" with no expressed
// or implied warranty. I accept no liability for any
// damage or loss of business that this software may cause.
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// if you are not using precompiled headers then include these lines:
///////////////////////////////////////////////////////////////////////////////
#ifndef DLL_EXPORT
#define DLL_EXPORT
#endif
#include "XGetopt.h"
///////////////////////////////////////////////////////////////////////////////
//
// X G e t o p t . c p p
//
//
// NAME
// getopt -- parse command line options
//
// SYNOPSIS
// int getopt(int argc, TCHAR *argv[], TCHAR *optstring)
//
// extern TCHAR *optarg;
// extern int optind;
//
// DESCRIPTION
// The getopt() function parses the command line arguments. Its
// arguments argc and argv are the argument count and array as
// passed into the application on program invocation. In the case
// of Visual C++ programs, argc and argv are available via the
// variables __argc and __argv (double underscores), respectively.
// getopt returns the next option letter in argv that matches a
// letter in optstring. (Note: Unicode programs should use
// __targv instead of __argv. Also, all character and string
// literals should be enclosed in _T( ) ).
//
// optstring is a string of recognized option letters; if a letter
// is followed by a colon, the option is expected to have an argument
// that may or may not be separated from it by white space. optarg
// is set to point to the start of the option argument on return from
// getopt.
//
// Option letters may be combined, e.g., "-ab" is equivalent to
// "-a -b". Option letters are case sensitive.
//
// getopt places in the external variable optind the argv index
// of the next argument to be processed. optind is initialized
// to 0 before the first call to getopt.
//
// When all options have been processed (i.e., up to the first
// non-option argument), getopt returns EOF, optarg will point
// to the argument, and optind will be set to the argv index of
// the argument. If there are no non-option arguments, optarg
// will be set to NULL.
//
// The special option "--" may be used to delimit the end of the
// options; EOF will be returned, and "--" (and everything after it)
// will be skipped.
//
// RETURN VALUE
// For option letters contained in the string optstring, getopt
// will return the option letter. getopt returns a question mark (?)
// when it encounters an option letter not included in optstring.
// EOF is returned when processing is finished.
//
// BUGS
// 1) Long options are not supported.
// 2) The GNU double-colon extension is not supported.
// 3) The environment variable POSIXLY_CORRECT is not supported.
// 4) The + syntax is not supported.
// 5) The automatic permutation of arguments is not supported.
// 6) This implementation of getopt() returns EOF if an error is
// encountered, instead of -1 as the latest standard requires.
//
// EXAMPLE
// BOOL CMyApp::ProcessCommandLine(int argc, TCHAR *argv[])
// {
// int c;
//
// while ((c = getopt(argc, argv, _T("aBn:"))) != EOF)
// {
// switch (c)
// {
// case _T('a'):
// TRACE(_T("option a\n"));
// //
// // set some flag here
// //
// break;
//
// case _T('B'):
// TRACE( _T("option B\n"));
// //
// // set some other flag here
// //
// break;
//
// case _T('n'):
// TRACE(_T("option n: value=%d\n"), atoi(optarg));
// //
// // do something with value here
// //
// break;
//
// case _T('?'):
// TRACE(_T("ERROR: illegal option %s\n"), argv[optind-1]);
// return FALSE;
// break;
//
// default:
// TRACE(_T("WARNING: no handler for option %c\n"), c);
// return FALSE;
// break;
// }
// }
// //
// // check for non-option args here
// //
// return TRUE;
// }
//
///////////////////////////////////////////////////////////////////////////////
GTOPT_EXTRA TCHAR *optarg; // global argument pointer
GTOPT_EXTRA int optind = 0; // global argv index
#include "XGetopt.h"
#include "nclist.h"
#include "ncbytes.h"
#ifdef _MSC_VER
static void XCommandLineToArgvA(int* argcp, char*** argvp);
#endif
///////////////////////////////////////////////////////////////////////////////
//
// X G e t o p t . c p p
//
//
// NAME
// getopt -- parse command line options
//
// SYNOPSIS
// int getopt(int argc, TCHAR *argv[], TCHAR *optstring)
//
// extern TCHAR *optarg;
// extern int optind;
//
// DESCRIPTION
// The getopt() function parses the command line arguments. Its
// arguments argc and argv are the argument count and array as
// passed into the application on program invocation. In the case
// of Visual C++ programs, argc and argv are available via the
// variables __argc and __argv (double underscores), respectively.
// getopt returns the next option letter in argv that matches a
// letter in optstring. (Note: Unicode programs should use
// __targv instead of __argv. Also, all character and string
// literals should be enclosed in _T( ) ).
//
// optstring is a string of recognized option letters; if a letter
// is followed by a colon, the option is expected to have an argument
// that may or may not be separated from it by white space. optarg
// is set to point to the start of the option argument on return from
// getopt.
//
// Option letters may be combined, e.g., "-ab" is equivalent to
// "-a -b". Option letters are case sensitive.
//
// getopt places in the external variable optind the argv index
// of the next argument to be processed. optind is initialized
// to 0 before the first call to getopt.
//
// When all options have been processed (i.e., up to the first
// non-option argument), getopt returns EOF, optarg will point
// to the argument, and optind will be set to the argv index of
// the argument. If there are no non-option arguments, optarg
// will be set to NULL.
//
// The special option "--" may be used to delimit the end of the
// options; EOF will be returned, and "--" (and everything after it)
// will be skipped.
//
// RETURN VALUE
// For option letters contained in the string optstring, getopt
// will return the option letter. getopt returns a question mark (?)
// when it encounters an option letter not included in optstring.
// EOF is returned when processing is finished.
//
// BUGS
// 1) Long options are not supported.
// 2) The GNU double-colon extension is not supported.
// 3) The environment variable POSIXLY_CORRECT is not supported.
// 4) The + syntax is not supported.
// 5) The automatic permutation of arguments is not supported.
// 6) This implementation of getopt() returns EOF if an error is
// encountered, instead of -1 as the latest standard requires.
//
// EXAMPLE
// BOOL CMyApp::ProcessCommandLine(int argc, TCHAR *argv[])
// {
// int c;
//
// while ((c = getopt(argc, argv, _T("aBn:"))) != EOF)
// {
// switch (c)
// {
// case _T('a'):
// TRACE(_T("option a\n"));
// //
// // set some flag here
// //
// break;
//
// case _T('B'):
// TRACE( _T("option B\n"));
// //
// // set some other flag here
// //
// break;
//
// case _T('n'):
// TRACE(_T("option n: value=%d\n"), atoi(optarg));
// //
// // do something with value here
// //
// break;
//
// case _T('?'):
// TRACE(_T("ERROR: illegal option %s\n"), argv[optind-1]);
// return FALSE;
// break;
//
// default:
// TRACE(_T("WARNING: no handler for option %c\n"), c);
// return FALSE;
// break;
// }
// }
// //
// // check for non-option args here
// //
// return TRUE;
// }
//
///////////////////////////////////////////////////////////////////////////////
GTOPT_EXTRA TCHAR *optarg; // global argument pointer
GTOPT_EXTRA int optind = 0; // global argv index
GTOPT_EXTRA int opterr; // print error
GTOPT_EXTRA
int getopt(int argc, TCHAR *argv[], TCHAR *optstring)
{
static TCHAR *next = NULL;
TCHAR c;
TCHAR *cp = malloc(sizeof(TCHAR)*1024);
if (optind == 0)
next = NULL;
optarg = NULL;
if (next == NULL || *next == _T('\0'))
{
if (optind == 0)
optind++;
if (optind >= argc || argv[optind][0] != _T('-') || argv[optind][1] == _T('\0'))
{
optarg = NULL;
if (optind < argc)
optarg = argv[optind];
return EOF;
}
if (_tcscmp(argv[optind], _T("--")) == 0)
{
optind++;
optarg = NULL;
if (optind < argc)
optarg = argv[optind];
return EOF;
}
next = argv[optind];
next++; // skip past -
optind++;
}
c = *next++;
cp = strchr(optstring, c);
if (cp == NULL || c == _T(':'))
return _T('?');
cp++;
if (*cp == _T(':'))
{
if (*next != _T('\0'))
{
optarg = next;
next = NULL;
}
else if (optind < argc)
{
optarg = argv[optind];
optind++;
}
else
{
return _T('?');
}
}
return c;
}
int getopt(int argc, TCHAR *argv[], TCHAR *optstring)
{
static TCHAR *next = NULL;
TCHAR c;
TCHAR *cp = malloc(sizeof(TCHAR)*1024);
#ifdef _MSC_VER
{
int xargc = -1;
char** xargv = NULL;
XCommandLineToArgvA(&xargc, &xargv);
}
#endif
if (optind == 0)
next = NULL;
optarg = NULL;
if (next == NULL || *next == _T('\0'))
{
if (optind == 0)
optind++;
if (optind >= argc || argv[optind][0] != _T('-') || argv[optind][1] == _T('\0'))
{
optarg = NULL;
if (optind < argc)
optarg = argv[optind];
return EOF;
}
if (_tcscmp(argv[optind], _T("--")) == 0)
{
optind++;
optarg = NULL;
if (optind < argc)
optarg = argv[optind];
return EOF;
}
next = argv[optind];
next++; // skip past -
optind++;
}
c = *next++;
cp = strchr(optstring, c);
if (cp == NULL || c == _T(':'))
return _T('?');
cp++;
if (*cp == _T(':'))
{
if (*next != _T('\0'))
{
optarg = next;
next = NULL;
}
else if (optind < argc)
{
optarg = argv[optind];
optind++;
}
else
{
return _T('?');
}
}
return c;
}
/**************************************************/
#define ESCAPE '\\'
#define SQUOTE '\''
#define DQUOTE '"'
/* Convert a UTF8 command line into a series of words for use by XGetOpt */
/* Note only checks for ASCII '\' '\'' '"' */
static void
XCommandLineToArgvA(int* argcp, char*** argvp)
{
const char* line = NULL;
size_t len;
int whitespace;
int quote = 0;
enum State state;
NClist* argv = NULL;
NCbytes* word = NULL;
char** p;
line = GetCommandLineA();
len = strlen(line);
argv = nclistnew();
word = ncbytesnew();
whitespace = 1; /* start in whitespace mode */
for(p=line;*p;p++) {
int c = *p;
if(whitespace && c <= ' ' || c == 127) continue; /* more whitespace */
if(!whitespace && c <= ' ' || c == 127) {
whitespace = 1; /* end of word */
ncbytesnull(word);
nclistpush(argv,ncbytesextract(word)); /* capture the word */
continue;
}
whitespace = 0; /* end whitespace */
if(c == ESCAPE) {
c = *(++p); /* move to next char */
} else if(c == SQUOTE || c == DQUOTE) {
if(!quote) {quote = c; continue;} /* Start quoted text */
if(quote == c) {quote = 0; continue;} /* end quoted text */
}
/* Just collect the character as part of the current word */
ncbytesappend(word,c);
}
/* Return parsed words */
if(argcp) *argcp = nclistlength(argv);
nclistpush(argv,NULL); /* Just to be sure */
if(argvp) *argvp = (char**)nclistextract(argv);
nclistfree(argv);
ncbytesfree(word);
}

View File

@ -63,7 +63,7 @@ ncFile_create(const char *path, int ioflags, ncstdio** filepp)
File* f;
struct ncFileState* state;
f = fopen(path,"w+");
f = NCfopen(path,"w+");
if(f == NULL)
return errno;
filep = (ncstdio*)calloc(sizeof(ncstdio),1);

View File

@ -83,7 +83,9 @@ ncio_open(const char *path, int ioflags,
void* parameters,
ncio** iopp, void** const mempp)
{
#ifdef ENABLE_BYTERANGE
int modetest = urlmodetest(path);
#endif
/* Diskless open has the following constraints:
1. file must be classic version 1 or 2 or 5

View File

@ -83,7 +83,7 @@ get_file_size(char *filename, size_t *file_size)
FILE *fp;
assert(filename && file_size);
fp = fopen(filename, "r");
fp = NCfopen(filename, "r");
if (fp)
{
fseek(fp, 0 , SEEK_END);

View File

@ -82,7 +82,7 @@ get_file_size(char *filename, size_t *file_size)
FILE *fp;
assert(filename && file_size);
fp = fopen(filename, "r");
fp = NCfopen(filename, "r");
if (fp)
{
fseek(fp, 0 , SEEK_END);

View File

@ -45,7 +45,7 @@ get_mem_used1(int *mem_used)
system(cmd);
/* Read the results and delete temp file. */
if (!(fp = fopen(TMP_FILE_NAME, "r"))) ERR;
if (!(fp = NCfopen(TMP_FILE_NAME, "r"))) ERR;
fread(blob, MAX_LEN, 1, fp);
sscanf(blob, "%d", mem_used);
fclose(fp);
@ -60,7 +60,7 @@ get_mem_used2(int *mem_used)
FILE *pf;
snprintf(buf, 30, "/proc/%u/statm", (unsigned)getpid());
pf = fopen(buf, "r");
pf = NCfopen(buf, "r");
if (pf) {
unsigned size; /* total program size */
unsigned resident;/* resident set size */

View File

@ -167,7 +167,7 @@ get_mem_used2(int *mem_used)
FILE *pf;
snprintf(buf, 30, "/proc/%u/statm", (unsigned)getpid());
pf = fopen(buf, "r");
pf = NCfopen(buf, "r");
if (pf) {
unsigned size; /* total program size */
unsigned resident;/* resident set size */

View File

@ -30,7 +30,7 @@ get_mem_used2(int *mem_used)
FILE *pf;
snprintf(buf, 30, "/proc/%u/statm", (unsigned)getpid());
pf = fopen(buf, "r");
pf = NCfopen(buf, "r");
if (pf) {
unsigned size; /* total program size */
unsigned resident;/* resident set size */

View File

@ -91,7 +91,7 @@ main(int argc, const char* argv[])
#endif
#ifdef MEM
fd = open(PATH,O_RDONLY);
fd = NCopen2(PATH,O_RDONLY);
if(fd < 0) {
fprintf(stderr,"could not open foo.nc\n");
assert(0);

View File

@ -31,6 +31,7 @@ See \ref copyright file for more info.
#endif
#include "netcdf.h"
#include "ncpathmgr.h"
#define CLEANUP
@ -131,7 +132,8 @@ fail(int ret)
void
exists(const char* file)
{
FILE* f = fopen(file,"r");
int stat = 0;
FILE* f = NCfopen(file, "r");
if(f == NULL) fail(NC_EPERM);
fclose(f);
}
@ -139,7 +141,7 @@ exists(const char* file)
void
notexists(const char* file)
{
FILE* f = fopen(file,"r");
FILE* f = NCfopen(file,"r");
if(f != NULL) {fclose(f); fail(NC_EEXIST);}
}

View File

@ -162,80 +162,27 @@ static int
readfile(const char* path, NC_memio* memio)
{
int status = NC_NOERR;
FILE* f = NULL;
size_t filesize = 0;
size_t count = 0;
char* memory = NULL;
char* p = NULL;
/* Open the file for reading */
f = NCfopen(path,"r");
if(f == NULL)
{status = errno; goto done;}
/* get current filesize */
if(fseek(f,0,SEEK_END) < 0)
{status = errno; goto done;}
filesize = (size_t)ftell(f);
/* allocate memory */
memory = malloc((size_t)filesize);
if(memory == NULL)
{status = NC_ENOMEM; goto done;}
/* move pointer back to beginning of file */
rewind(f);
count = filesize;
p = memory;
while(count > 0) {
size_t actual;
actual = fread(p,1,count,f);
if(actual == 0 || ferror(f))
{status = NC_EIO; goto done;}
count -= actual;
p += actual;
}
NCbytes* buf = ncbytesnew();
if((status = NC_readfile(path,buf))) goto done;
if(memio) {
memio->size = (size_t)filesize;
memio->memory = memory;
memio->size = (size_t)ncbyteslength(buf);
memio->memory = ncbytesextract(buf);
}
done:
if(status != NC_NOERR && memory != NULL)
free(memory);
if(f != NULL) fclose(f);
ncbytesfree(buf);
return status;
}
static int
writefile(const char* path, NC_memio* memio)
{
int status = NC_NOERR;
FILE* f = NULL;
size_t count = 0;
char* p = NULL;
/* Open the file for writing */
#ifdef _WIN32
f = fopen(path,"wb");
#else
f = fopen(path,"w");
#endif
if(f == NULL)
{status = errno; goto done;}
count = memio->size;
p = memio->memory;
while(count > 0) {
size_t actual;
actual = fwrite(p,1,count,f);
if(actual == 0 || ferror(f))
{status = NC_EIO; goto done;}
count -= actual;
p += actual;
}
if((status = NC_writefile(path,memio->size,memio->memory))) goto done;
done:
if(f != NULL) fclose(f);
return status;
}
/* Duplicate an NC_memio instance; needed to avoid
attempting to use memory that might have been realloc'd
Allow the new memory to be larger than the src memory

View File

@ -43,7 +43,7 @@ main(int argc, char **argv)
for (i = DATA_LEN; i >= 0; i--)
{
/* Create a small file which is not a netCDF file. */
if (!(file = fopen(FILE_NAME, "w+"))) ERR;
if (!(file = NCfopen(FILE_NAME, "w+"))) ERR;
if (fwrite(dummy_data, 1, i, file) != i) ERR;
if (fclose(file)) ERR;

View File

@ -680,7 +680,7 @@ get_mem_used2(int *mem_used)
assert(mem_used);
snprintf(buf, 30, "/proc/%u/statm", (unsigned)getpid());
if ((pf = fopen(buf, "r")))
if ((pf = NCfopen(buf, "r")))
{
(void)fscanf(pf, "%u %u %u %u %u %u", &size, &resident, &share,
&text, &lib, &data);

View File

@ -311,7 +311,7 @@ main(int argc, char **argv)
int i;
/* Create a file with magic number at start. */
if (!(FP = fopen(FILE_NAME, "w"))) ERR;
if (!(FP = NCfopen(FILE_NAME, "w"))) ERR;
if (fwrite(magic_number, sizeof(char), strlen(magic_number), FP)
!= strlen(magic_number)) ERR;
if (fwrite(dummy_data, sizeof(char), strlen(dummy_data), FP)

View File

@ -16,7 +16,7 @@ See \ref copyright file for more info.
#include <unistd.h>
#endif
#define DEBUG
#undef DEBUG
#include "netcdf.h"
#include "nctestserver.h"
@ -150,7 +150,7 @@ testrc(const char* prefix, const char* url)
FILE* rc;
snprintf(rcpath,sizeof(rcpath),"%s/%s",prefix,RC);
rc = fopen(rcpath,"w");
rc = NCfopen(rcpath,"w");
if(rc == NULL) {
fprintf(stderr,"Cannot create ./%s\n",RC);
exit(1);
@ -178,7 +178,7 @@ fillrc(const char* path)
FILE* rc;
killrc();
rc = fopen(path,"w");
rc = NCfopen(path,"w");
if(rc == NULL) {
fprintf(stderr,"cannot create rc file: %s\n",path);
exit(1);

View File

@ -117,6 +117,7 @@ IF(MSVC)
${CMAKE_CURRENT_BINARY_DIR})
ENDIF(ENABLE_DAP)
ENDIF()
IF(ENABLE_TESTS)
@ -304,14 +305,11 @@ endif()
ENDIF()
ENDIF(EXTRA_TESTS)
# The unicode tests are complicated
IF(USE_HDF5)
IF(NOT MSVC AND NOT MINGW)
# These tests do not work under windows
add_sh_test(ncdump test_unicode_directory)
add_sh_test(ncdump test_unicode_path)
ENDIF()
ENDIF(USE_HDF5)
# The unicode tests
if(NOT ISMINGW)
add_sh_test(ncdump test_unicode_directory)
add_sh_test(ncdump test_unicode_path)
ENDIF()
IF(USE_CDF5)
add_sh_test(ncdump test_keywords)

View File

@ -144,7 +144,6 @@ if !ISMINGW
if !ISCYGWIN
TESTS += tst_output.sh
TESTS += tst_nccopy3.sh
TESTS += test_unicode_directory.sh test_unicode_path.sh
if USE_HDF5
TESTS += run_back_comp_tests.sh tst_netcdf4_4.sh
TESTS += tst_nccopy4.sh tst_nccopy5.sh
@ -152,6 +151,11 @@ endif
endif
endif
# The unicode tests
if !ISMINGW
TESTS += test_unicode_directory.sh test_unicode_path.sh
endif
endif BUILD_TESTSETS
# These files all have to be included with the distribution.

30
ncdump/acpget.c Normal file
View File

@ -0,0 +1,30 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <locale.h>
#include <windows.h>
int
main(int argc, char** argv)
{
int acp = -1;
const char* acpid = NULL;
const char* lcall = NULL;
const char* lcctype = NULL;
char digits[16];
switch (acp = GetACP()) {
case 1252: acpid = "CP_1252"; break;
case 65001: acpid = "CP_UTF8"; break;
default:
snprintf(digits,sizeof(digits),"%d",acp);
acpid = digits;
break;
}
lcall = setlocale(LC_ALL,NULL);
lcctype = setlocale(LC_CTYPE,NULL);
printf("ACP=%s locale: LC_ALL=%s LC_CTYPE=%s\n",acpid,lcall,lcctype);
return 0;
}

View File

@ -6,6 +6,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "nc_tests.h"
#define BUFLEN 100000
@ -19,7 +20,7 @@ main(int argc, char** argv)
FILE* input = stdin;
if(argc > 1) {
input = fopen(argv[1],"r");
input = NCfopen(argv[1],"r");
}
/* Read the whole file */

View File

@ -243,7 +243,7 @@ main(int argc, char **argv)
if(ocopt.output != NULL) fclose(ocopt.output);
if(optarg == NULL)
usage("-o does not specify a file name");
ocopt.output = fopen(optarg,"w");
ocopt.output = NCfopen(optarg,"w");
if(ocopt.output == NULL)
usage("-o file not writeable");
break;

10
ncdump/run_cygutf8.sh Executable file
View File

@ -0,0 +1,10 @@
#!/bin/bash -x
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
. ../test_common.sh
echo "Test unicode paths"
${execdir}/acpget
${execdir}/tst_cygutf8
ls xutf8*
rm xutf8*

View File

@ -10,9 +10,6 @@ if test "x$srcdir" = x ; then srcdir=`pwd`; fi
set -e
LC_ALL="C.UTF-8"
export LC_ALL
# Passing a utf8 name using either \x or actual characters
# to Visual Studio does not work well.
if test "x$FP_ISMSVC" = x ; then

View File

@ -9,7 +9,7 @@
#include <nc_tests.h>
#include "err_macros.h"
#define DEBUG
#undef DEBUG
static int ret = NC_NOERR;

55
ncdump/tst_cygutf8.c Normal file
View File

@ -0,0 +1,55 @@
/*
https://www.cygwin.com/cygwin-ug-net/using-specialnames.html
https://docs.microsoft.com/en-us/archive/msdn-magazine/2016/september/c-unicode-encoding-conversions-with-stl-strings-and-win32-apis
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef _WIN32
#include <windows.h>
#endif
#include "netcdf.h"
#include "ncpathmgr.h"
static const unsigned char name1[] = {
'x','u','t','f','8','_',
'\xe6', '\xb5', '\xb7',
'\0'
};
static unsigned char name2[] = {
'x','u','t','f','8','_',
0xCE, 0x9A, /* GREEK CAPITAL LETTER KAPPA : 2-bytes utf8 */
0xCE, 0xB1, /* GREEK SMALL LETTER LAMBDA : 2-bytes utf8 */
0xCE, 0xBB, /* GREEK SMALL LETTER ALPHA : 2-bytes utf8 */
0xCE, 0xB7, /* GREEK SMALL LETTER ETA : 2-bytes utf8 */
0xCE, 0xBC, /* GREEK SMALL LETTER MU : 2-bytes utf8 */
0xCE, 0xAD, /* GREEK SMALL LETTER EPSILON WITH TONOS
: 2-bytes utf8 */
0xCF, 0x81, /* GREEK SMALL LETTER RHO : 2-bytes utf8 */
0xCE, 0xB1, /* GREEK SMALL LETTER ALPHA : 2-bytes utf8 */
0x00
};
static char* name3 = "xutf8_사람/접는사람";
/* This is CP_1252 */
//static char* name4 = "xutf8_Å";
static char name4[8] = {'x','u','t','f','8','_',0XC5,0x00} ;
int
main()
{
FILE* f;
f = NCfopen((char*)name1,"w");
if (f) fclose(f);
f = NCfopen((char*)name2,"w");
if (f) fclose(f);
f = NCfopen((char*)name3,"w");
if (f) fclose(f);
printf("|name4|=%u\n",(unsigned)strlen(name4));
f = NCfopen((char*)name4,"w");
if (f) fclose(f);
return 0;
}

View File

@ -23,7 +23,7 @@
#include <locale.h>
#endif
#define DEBUG
#undef DEBUG
/* The data file we will create. */
static const unsigned char prefix[] = {

View File

@ -8,7 +8,7 @@
#include "includes.h"
#include "dump.h"
#define DEBUGSRC
#undef DEBUGSRC
#define MAXELEM 8
#define MAXDEPTH 4

View File

@ -5,9 +5,10 @@
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
. ../test_common.sh
set -e
echo "*** Testing ncgen3 for netCDF-4."
set -e
echo "*** creating netCDF-4 file c0_4.nc from c0.cdl..."
${NCGEN3} -k3 -b -o c0_4.nc ${ncgen3c0}
echo "*** creating netCDF-4 classic model file c0_4c.nc from c0.cdl..."

Binary file not shown.

View File

@ -73,11 +73,11 @@ case "$zext" in
# Move into position
rm -f ${execdir}/ref_zarr_test_data.cdl
# Use gunzip because it always appears to be available
if gunzip ${srcdir}/ref_zarr_test_data.cdl.gz ; then ignore=1; fi
if test -f ${srcdir}/ref_zarr_test_data.cdl ; then
testcases3 zarr_test_data.zarr ref_zarr_test_data xarray
fi
;;
if ! test -f ${srcdir}/ref_zarr_test_data.cdl ; then
gunzip -c ${srcdir}/ref_zarr_test_data.cdl.gz > ${srcdir}/ref_zarr_test_data.cdl
fi
testcases3 zarr_test_data.zarr ref_zarr_test_data xarray
;;
*) echo "unimplemented kind: $1" ; exit 1;;
esac
}

View File

@ -27,7 +27,7 @@
#undef NODELETE
#define DEBUG
#undef DEBUG
#define DATANAME "data"

View File

@ -8,7 +8,7 @@
#include "ut_includes.h"
#include "test_nczarr_utils.h"
#define DEBUG
#undef DEBUG
static int ret = NC_NOERR;
#define FILE_NAME "tmp_chunks3.nc"

View File

@ -5,7 +5,7 @@
#include "ut_includes.h"
#define DEBUG
#undef DEBUG
typedef enum Cmds {
cmd_none = 0,

View File

@ -12,7 +12,7 @@
#include <unistd.h>
#endif
#define DEBUG
#undef DEBUG
static char hex[16] = "0123456789abcdef";

View File

@ -23,7 +23,7 @@
#include "nclog.h"
#include "ncuri.h"
#define DEBUG
#undef DEBUG
#define DATANAME "data"

View File

@ -21,7 +21,7 @@
#include "zincludes.h"
#include "ncpathmgr.h"
#define DEBUG
#undef DEBUG
#define AWSHOST ".amazonaws.com"

View File

@ -10,11 +10,13 @@ TOPSRCDIR='@abs_top_srcdir@'
TOPBUILDDIR='@abs_top_builddir@'
FP_ISCMAKE=@ISCMAKE@
FP_ISMSVC=@ISMSVC@
FP_WINVERMAJOR=@WINVERMAJOR@
FP_WINVERBUILD=@WINVERBUILD@
FP_ISCYGWIN=@ISCYGWIN@
FP_ISMINGW=@ISMINGW@
FP_ISMSYS=@ISMSYS@
FP_ISREGEDIT=@ISREGEDIT@
FP_USEPLUGINS=@USEPLUGINS@
FP_ISREGEDIT=@ISREGEDIT@
# Feature flags
FEATURE_HDF5=@HAS_HDF5@
@ -150,5 +152,7 @@ ncgen3c0="${top_srcdir}/ncgen3/c0.cdl"
ncgenc0="${top_srcdir}/ncgen/c0.cdl"
ncgenc04="${top_srcdir}/ncgen/c0_4.cdl"
if test "x$FP_ISMSVC" = xyes || test "x$FP_ISCYGWIN" = xyes; then export LC_ALL="en_US.utf8"; fi
# Make sure we are in builddir (not execdir)
cd $builddir

View File

@ -15,7 +15,7 @@ Test the handling of aws profiles and regions.
#include "ncrc.h"
#include "ncpathmgr.h"
#define DEBUG
#undef DEBUG
typedef struct ProfileTest {
const char* profile;

View File

@ -13,7 +13,7 @@ Test the NCpathcvt
#include "netcdf.h"
#include "ncpathmgr.h"
#define DEBUG
#undef DEBUG
#define NKINDS 4
static const int kinds[NKINDS] = {NCPD_NIX,NCPD_MSYS,NCPD_CYGWIN,NCPD_WIN};