2010-06-03 21:24:43 +08:00
|
|
|
/* This is part of the netCDF package.
|
|
|
|
Copyright 2006 University Corporation for Atmospheric Research/Unidata.
|
|
|
|
See COPYRIGHT file for conditions of use.
|
|
|
|
|
|
|
|
This is a very simple example which tests rejection of bad names for
|
2016-10-22 01:17:39 +08:00
|
|
|
netCDF data objects, including names with "/" character, trailing spaces,
|
2010-06-03 21:24:43 +08:00
|
|
|
leading special characters, and invalid UTF-8 strings.
|
|
|
|
|
2015-08-16 06:26:35 +08:00
|
|
|
$Id: tst_names.c 2792 2014-10-27 06:02:59Z wkliao $
|
2010-06-03 21:24:43 +08:00
|
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <netcdf.h>
|
2015-08-16 06:26:35 +08:00
|
|
|
#ifdef USE_PARALLEL
|
|
|
|
#include <netcdf_par.h>
|
|
|
|
#endif
|
2010-06-03 21:24:43 +08:00
|
|
|
#include <nc_tests.h>
|
2016-10-22 01:17:39 +08:00
|
|
|
#include "err_macros.h"
|
2010-06-03 21:24:43 +08:00
|
|
|
|
|
|
|
/* The data file we will create. */
|
|
|
|
#define FILE_NAME "tst_names.nc"
|
|
|
|
#define NDIMS 1
|
|
|
|
#define DIMLEN 1
|
|
|
|
|
2015-08-16 06:26:35 +08:00
|
|
|
#define ERROR {printf("Error at line %d: %s\n",__LINE__,nc_strerror(res)); continue;}
|
|
|
|
#define ERRORI {printf("Error at line %d (loop=%d): %s\n",__LINE__,i,nc_strerror(res)); continue;}
|
|
|
|
|
2010-06-03 21:24:43 +08:00
|
|
|
int
|
|
|
|
main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
char *valid[] = {
|
|
|
|
/* pressure in 23 languages */
|
|
|
|
"\xd8\xa7\xd9\x84\xd8\xb6\xd8\xba\xd8\xb7",
|
|
|
|
"\xd0\xbd\xd0\xb0\xd0\xbb\xd1\x8f\xd0\xb3\xd0\xb0\xd0\xbd\xd0\xb5",
|
|
|
|
"\xe5\x8e\x8b\xe5\x8a\x9b",
|
|
|
|
"\xe5\xa3\x93\xe5\x8a\x9b",
|
|
|
|
"pritisak",
|
|
|
|
"tlaku",
|
|
|
|
"pres",
|
|
|
|
"druk",
|
|
|
|
"pressure",
|
|
|
|
"paine",
|
|
|
|
"pression",
|
|
|
|
"Druck",
|
|
|
|
"\xcf\x80\xce\xaf\xce\xb5\xcf\x83\xce\xb7",
|
|
|
|
"\xe0\xa4\xa6\xe0\xa4\xac\xe0\xa4\xbe\xe0\xa4\xb5",
|
|
|
|
"pressione",
|
|
|
|
"\xe5\x9c\xa7\xe5\x8a\x9b",
|
|
|
|
"\xec\x95\x95\xeb\xa0\xa5",
|
|
|
|
"press",
|
|
|
|
"ci\xc5\x9bnienie",
|
|
|
|
"Press\xc3\xa3o",
|
|
|
|
"presiune",
|
|
|
|
"\xd0\xb4\xd0\xb0\xd0\xb2\xd0\xbb\xd0\xb5\xd0\xbd\xd0\xb8\xd0\xb5",
|
|
|
|
"presi\xc3\xb3n",
|
|
|
|
/* special characters in names, numeric characters at the start of names */
|
|
|
|
"has blank",
|
|
|
|
"has:colon",
|
|
|
|
"a",
|
|
|
|
"A",
|
|
|
|
"0leading_numeric_char",
|
|
|
|
"1",
|
|
|
|
"0x123"
|
|
|
|
};
|
|
|
|
char *notvalid[] = {
|
|
|
|
"-leading_special_char",
|
|
|
|
"trailing_space ",
|
|
|
|
"trailing_tab\t",
|
|
|
|
"trailing_newline\n",
|
|
|
|
"has_control_char_\a_in_name",
|
|
|
|
"has ascii_del_\x7f_in name",
|
|
|
|
/* Invalid UTF-8 of various sorts, thanks to Markus Kuhn */
|
|
|
|
"\xA0\xB0\xC0\xD0",
|
|
|
|
"xyz\x80", /* unexpected continuation bytes */
|
|
|
|
"\x80xyz",
|
|
|
|
"xyz\xBF",
|
|
|
|
"\xBFxyz",
|
|
|
|
"\xC0xyz", /* lonely start characters */
|
|
|
|
"x\xC0yz",
|
|
|
|
"xy\xC0z",
|
|
|
|
"xyz\xC0",
|
|
|
|
"\xDFxyz",
|
|
|
|
"x\xDFyz",
|
|
|
|
"xy\xDFz",
|
|
|
|
"xyz\xDF",
|
|
|
|
"\xE0xyz",
|
|
|
|
"x\xE0yz",
|
|
|
|
"xy\xE0z",
|
|
|
|
"xyz\xE0",
|
|
|
|
"\xE0\xBFxy",
|
|
|
|
"x\xE0\xBFy",
|
|
|
|
"xy\xE0\xBF",
|
|
|
|
"\xEFxyz",
|
|
|
|
"x\xEFyz",
|
|
|
|
"xy\xEFz",
|
|
|
|
"xyz\xEF",
|
|
|
|
"\xEF\x80xy",
|
|
|
|
"x\xEF\x80y",
|
|
|
|
"xy\xEF\x80",
|
|
|
|
"\xF0xyz",
|
|
|
|
"x\xF0yz",
|
|
|
|
"xy\xF0z",
|
|
|
|
"xyz\xF0",
|
|
|
|
"\xF7xyz",
|
|
|
|
"x\xF7yz",
|
|
|
|
"xy\xF7z",
|
|
|
|
"xyz\xF7",
|
|
|
|
"\xF8xyz",
|
|
|
|
"x\xF8yz",
|
|
|
|
"xy\xF8z",
|
|
|
|
"xyz\xF8",
|
|
|
|
"\xFBxyz",
|
|
|
|
"x\xFByz",
|
|
|
|
"xy\xFBz",
|
|
|
|
"xyz\xFB",
|
|
|
|
"\xFCxyz",
|
|
|
|
"x\xFCyz",
|
|
|
|
"xy\xFCz",
|
|
|
|
"xyz\xFC",
|
|
|
|
"\xFDxyz",
|
|
|
|
"x\xFDyz",
|
|
|
|
"xy\xFDz",
|
|
|
|
"xyz\xFD",
|
|
|
|
"\xC0\xC0xy", /* last continuation byte missing */
|
|
|
|
"x\xC0\xC0y",
|
|
|
|
"xy\xC0\xC0",
|
|
|
|
"\xDF\xDFxy",
|
|
|
|
"x\xDF\xDFy",
|
|
|
|
"xy\xDF\xDF",
|
|
|
|
"\xE0\x80xy",
|
|
|
|
"x\xE0\x80y",
|
|
|
|
"xy\xE0\x80",
|
|
|
|
"\xEF\x80xy",
|
|
|
|
"x\xEF\x80y",
|
|
|
|
"xy\xEF\x80",
|
|
|
|
"\xF0\x80\x80x",
|
|
|
|
"x\xF0\x80\x80",
|
|
|
|
"\xF7\x80\x80x",
|
|
|
|
"x\xF7\x80\x80",
|
|
|
|
"\xF8\x80\x80\x80x",
|
|
|
|
"x\xF8\x80\x80\x80",
|
|
|
|
"\xFB\x80\x80\x80x",
|
|
|
|
"x\xFB\x80\x80\x80",
|
|
|
|
"\xFC\x80\x80\x80\x80x",
|
|
|
|
"x\xFC\x80\x80\x80\x80",
|
|
|
|
"\xFD\x80\x80\x80\x80x",
|
|
|
|
"x\xFD\x80\x80\x80\x80",
|
|
|
|
"\xFExyz", /* impossible bytes */
|
|
|
|
"x\xFEyz",
|
|
|
|
"xy\xFEz",
|
|
|
|
"xyz\xFE",
|
|
|
|
"\xFFxyz",
|
|
|
|
"x\xFFyz",
|
|
|
|
"xy\xFFz",
|
|
|
|
"xyz\xFF",
|
|
|
|
"\xC0\xAFxy", /* overlong sequences */
|
|
|
|
"x\xC0\xAFy",
|
|
|
|
"xy\xC0\xAF",
|
|
|
|
"\xE0\x80\xAFx",
|
|
|
|
"x\xE0\x80\xAF",
|
|
|
|
"\xF0\x80\x80\xAFx",
|
|
|
|
"x\xF0\x80\x80\xAF",
|
|
|
|
"\xF8\x80\x80\x80\xAFx",
|
|
|
|
"x\xF8\x80\x80\x80\xAF",
|
|
|
|
"\xFC\x80\x80\x80\x80\xAFx",
|
|
|
|
"x\xFC\x80\x80\x80\x80\xAF",
|
|
|
|
"\xC1\xBFxy",
|
|
|
|
"x\xC1\xBFy",
|
|
|
|
"xy\xC1\xBF",
|
|
|
|
"\xE0\x9F\xBFx",
|
|
|
|
"x\xE0\x9F\xBF",
|
|
|
|
"\xF0\x8F\xBF\xBFx",
|
|
|
|
"x\xF0\x8F\xBF\xBF",
|
|
|
|
"\xF8\x87\xBF\xBF\xBFx",
|
|
|
|
"x\xF8\x87\xBF\xBF\xBF",
|
|
|
|
"\xFC\x83\xBF\xBF\xBF\xBFx",
|
|
|
|
"x\xFC\x83\xBF\xBF\xBF\xBF",
|
|
|
|
"x\xC0\x80", /* overlong NULs */
|
|
|
|
"x\xE0\x80\x80",
|
|
|
|
"x\xF0\x80\x80\x80",
|
|
|
|
"x\xF8\x80\x80\x80\x80",
|
|
|
|
"x\xFC\x80\x80\x80\x80\x80",
|
|
|
|
/* single UTF-16 surrogates */
|
|
|
|
"x\xED\xA0\x80",
|
|
|
|
"x\xED\xAD\xBF",
|
|
|
|
"x\xED\xAE\x80",
|
|
|
|
"x\xED\xAF\xBF",
|
|
|
|
"x\xED\xB0\x80",
|
|
|
|
"x\xED\xBE\x80",
|
|
|
|
"x\xED\xBF\xBF",
|
|
|
|
"x\xED\xA0\x80\xED\xB0\x80", /* paired UTF-16 surrogates */
|
|
|
|
"x\xED\xA0\x80\xED\xBF\xBF",
|
|
|
|
"x\xED\xAD\xBF\xED\xB0\x80",
|
|
|
|
"x\xED\xAD\xBF\xED\xBF\xBF",
|
|
|
|
"x\xED\xAE\x80\xED\xB0\x80",
|
|
|
|
"x\xED\xAE\x80\xED\xBF\xBF",
|
|
|
|
"x\xED\xAF\xBF\xED\xB0\x80",
|
|
|
|
"x\xED\xAF\xBF\xED\xBF\xBF",
|
|
|
|
"x\xEF\xBF\xBE", /* other illegal code positions */
|
|
|
|
"x\xEF\xBF\xBF"
|
|
|
|
};
|
|
|
|
int i, j;
|
|
|
|
#define NUM_BAD (sizeof notvalid / sizeof notvalid[0])
|
|
|
|
#define NUM_GOOD (sizeof valid / sizeof valid[0])
|
|
|
|
int ncid, dimid, varid, res;
|
|
|
|
double attvals[] = {-2.0};
|
|
|
|
double attvals_in[1];
|
|
|
|
#define NATTVALS (sizeof attvals / sizeof attvals[0])
|
|
|
|
char *attstring = "text";
|
|
|
|
#define MAX_ATTSTRING_LEN 100
|
|
|
|
char attstr_in[MAX_ATTSTRING_LEN];
|
|
|
|
int dimids[NUM_GOOD];
|
|
|
|
int varids[NUM_GOOD];
|
2012-03-26 09:34:32 +08:00
|
|
|
#if 0
|
2010-06-03 21:24:43 +08:00
|
|
|
int attnums[NUM_GOOD];
|
2012-03-26 09:34:32 +08:00
|
|
|
#endif
|
2010-06-03 21:24:43 +08:00
|
|
|
char *testfile = FILE_NAME;
|
|
|
|
int formats[] = {
|
|
|
|
NC_FORMAT_CLASSIC
|
|
|
|
,
|
2015-08-16 06:26:35 +08:00
|
|
|
NC_FORMAT_64BIT_OFFSET
|
|
|
|
,
|
|
|
|
NC_FORMAT_CDF5
|
2010-06-03 21:24:43 +08:00
|
|
|
#ifdef USE_NETCDF4
|
|
|
|
,
|
|
|
|
NC_FORMAT_NETCDF4
|
|
|
|
,
|
|
|
|
NC_FORMAT_NETCDF4_CLASSIC
|
|
|
|
#endif /* USE_NETCDF4 */
|
|
|
|
};
|
|
|
|
int num_formats = (sizeof formats) / (sizeof formats[0]);
|
|
|
|
char *format_names[] = {
|
2015-08-16 06:26:35 +08:00
|
|
|
"classic", "64-bit offset", "64-bit data", "netCDF-4/HDF5", "netCDF-4 classic model"
|
2010-06-03 21:24:43 +08:00
|
|
|
};
|
|
|
|
|
2015-08-16 06:26:35 +08:00
|
|
|
#ifdef TEST_PNETCDF
|
|
|
|
MPI_Init(&argc, &argv);
|
|
|
|
#endif
|
|
|
|
|
2010-06-03 21:24:43 +08:00
|
|
|
printf("\n*** testing names with file %s...\n", testfile);
|
|
|
|
for (j = 0; j < num_formats; j++)
|
|
|
|
{
|
|
|
|
printf("*** switching to netCDF %s format...", format_names[j]);
|
|
|
|
nc_set_default_format(formats[j], NULL);
|
2015-08-16 06:26:35 +08:00
|
|
|
#ifdef TEST_PNETCDF
|
|
|
|
if((res = nc_create_par(testfile, NC_CLOBBER|NC_PNETCDF, MPI_COMM_WORLD, MPI_INFO_NULL, &ncid)))
|
|
|
|
#else
|
2010-06-03 21:24:43 +08:00
|
|
|
if((res = nc_create(testfile, NC_CLOBBER, &ncid)))
|
2015-08-16 06:26:35 +08:00
|
|
|
#endif
|
|
|
|
ERROR
|
2016-10-22 01:17:39 +08:00
|
|
|
|
2010-06-03 21:24:43 +08:00
|
|
|
/* Define dimensions, variables, and attributes with various
|
|
|
|
* acceptable names */
|
|
|
|
for (i = 0; i < NUM_GOOD; i++) {
|
|
|
|
if ((res = nc_def_dim(ncid, valid[i], DIMLEN, &dimid)))
|
2015-08-16 06:26:35 +08:00
|
|
|
ERRORI
|
|
|
|
|
2010-06-03 21:24:43 +08:00
|
|
|
dimids[i] = dimid;
|
|
|
|
/* Define variable with same name */
|
2016-10-22 01:17:39 +08:00
|
|
|
if ((res = nc_def_var(ncid, valid[i], NC_FLOAT, NDIMS, &dimids[i],
|
2010-06-03 21:24:43 +08:00
|
|
|
&varid)))
|
2015-08-16 06:26:35 +08:00
|
|
|
ERRORI
|
2010-06-03 21:24:43 +08:00
|
|
|
varids[i] = varid;
|
|
|
|
/* Define variable and global attributes with same name and value */
|
2016-10-22 01:17:39 +08:00
|
|
|
if ((res = nc_put_att_text(ncid, varid, valid[i],
|
2010-06-03 21:24:43 +08:00
|
|
|
strlen(valid[i]), valid[i])))
|
2015-08-16 06:26:35 +08:00
|
|
|
ERRORI
|
2016-10-22 01:17:39 +08:00
|
|
|
if ((res = nc_put_att_double(ncid, NC_GLOBAL, valid[i], NC_DOUBLE,
|
2010-06-03 21:24:43 +08:00
|
|
|
NATTVALS, attvals)))
|
2015-08-16 06:26:35 +08:00
|
|
|
ERRORI
|
2012-03-26 09:34:32 +08:00
|
|
|
#if 0
|
2010-06-03 21:24:43 +08:00
|
|
|
attnums[i] = i;
|
2012-03-26 09:34:32 +08:00
|
|
|
#endif
|
2010-06-03 21:24:43 +08:00
|
|
|
}
|
2016-10-22 01:17:39 +08:00
|
|
|
|
2010-06-03 21:24:43 +08:00
|
|
|
/* Try defining dimensions, variables, and attributes with various
|
|
|
|
* bad names and make sure these are rejected */
|
|
|
|
for (i = 0; i < NUM_BAD; i++) {
|
2016-10-22 01:17:39 +08:00
|
|
|
if ((res = nc_def_dim(ncid, notvalid[i], DIMLEN, &dimid))
|
2015-08-16 06:26:35 +08:00
|
|
|
!= NC_EBADNAME) ERRORI
|
2016-10-22 01:17:39 +08:00
|
|
|
if ((res = nc_def_var(ncid, notvalid[i], NC_FLOAT, NDIMS, dimids,
|
2010-06-03 21:24:43 +08:00
|
|
|
&varid))
|
2015-08-16 06:26:35 +08:00
|
|
|
!= NC_EBADNAME) ERRORI
|
2016-10-22 01:17:39 +08:00
|
|
|
if ((res = nc_put_att_text(ncid, varid, notvalid[i],
|
2010-06-03 21:24:43 +08:00
|
|
|
strlen(attstring), attstring))
|
2015-08-16 06:26:35 +08:00
|
|
|
!= NC_EBADNAME) ERRORI
|
2016-10-22 01:17:39 +08:00
|
|
|
if ((res = nc_put_att_double(ncid, NC_GLOBAL, notvalid[i], NC_DOUBLE,
|
2010-06-03 21:24:43 +08:00
|
|
|
NATTVALS, attvals))
|
2015-08-16 06:26:35 +08:00
|
|
|
!= NC_EBADNAME) ERRORI
|
2010-06-03 21:24:43 +08:00
|
|
|
}
|
|
|
|
if ((res = nc_enddef(ncid)))
|
2015-08-16 06:26:35 +08:00
|
|
|
ERROR
|
2010-06-03 21:24:43 +08:00
|
|
|
if ((res = nc_close(ncid)))
|
2015-08-16 06:26:35 +08:00
|
|
|
ERROR
|
2016-10-22 01:17:39 +08:00
|
|
|
|
2010-06-03 21:24:43 +08:00
|
|
|
/* Check it out, make sure all objects with good names were defined OK */
|
2015-08-16 06:26:35 +08:00
|
|
|
#ifdef TEST_PNETCDF
|
|
|
|
if ((res = nc_open_par(testfile, NC_NOWRITE|NC_PNETCDF, MPI_COMM_WORLD, MPI_INFO_NULL, &ncid)))
|
|
|
|
#else
|
2010-06-03 21:24:43 +08:00
|
|
|
if ((res = nc_open(testfile, NC_NOWRITE, &ncid)))
|
2015-08-16 06:26:35 +08:00
|
|
|
#endif
|
|
|
|
ERROR
|
2010-06-03 21:24:43 +08:00
|
|
|
for (i = 0; i < NUM_GOOD; i++) {
|
|
|
|
size_t attlen;
|
2016-10-22 01:17:39 +08:00
|
|
|
if ((res = nc_inq_dimid(ncid, valid[i], &dimid)) ||
|
2010-06-03 21:24:43 +08:00
|
|
|
dimid != dimids[i])
|
2015-08-16 06:26:35 +08:00
|
|
|
ERRORI
|
2016-10-22 01:17:39 +08:00
|
|
|
if ((res = nc_inq_varid(ncid, valid[i], &varid)) ||
|
2010-06-03 21:24:43 +08:00
|
|
|
varid != varids[i])
|
2015-08-16 06:26:35 +08:00
|
|
|
ERRORI
|
2010-06-03 21:24:43 +08:00
|
|
|
res = nc_inq_attlen(ncid, varid, valid[i], &attlen);
|
2016-10-22 01:17:39 +08:00
|
|
|
if ((res = nc_get_att_text(ncid, varid, valid[i], attstr_in)))
|
2015-08-16 06:26:35 +08:00
|
|
|
ERRORI
|
2010-06-03 21:24:43 +08:00
|
|
|
attstr_in[attlen] = '\0';
|
2016-10-22 01:17:39 +08:00
|
|
|
if (strcmp(valid[i], attstr_in) != 0)
|
2015-08-16 06:26:35 +08:00
|
|
|
ERRORI
|
2016-10-22 01:17:39 +08:00
|
|
|
if ((res = nc_get_att_double(ncid, NC_GLOBAL, valid[i],
|
|
|
|
attvals_in))
|
|
|
|
|| attvals[0] != attvals_in[0])
|
2015-08-16 06:26:35 +08:00
|
|
|
ERRORI
|
2010-06-03 21:24:43 +08:00
|
|
|
}
|
|
|
|
if ((res = nc_close(ncid)))
|
2015-08-16 06:26:35 +08:00
|
|
|
ERROR
|
2010-06-03 21:24:43 +08:00
|
|
|
/* (void) remove(testfile); */
|
2015-08-16 06:26:35 +08:00
|
|
|
|
2010-06-03 21:24:43 +08:00
|
|
|
SUMMARIZE_ERR;
|
|
|
|
}
|
|
|
|
FINAL_RESULTS;
|
|
|
|
|
2015-08-16 06:26:35 +08:00
|
|
|
#ifdef TEST_PNETCDF
|
|
|
|
MPI_Finalize();
|
|
|
|
#endif
|
2010-06-03 21:24:43 +08:00
|
|
|
return 0;
|
|
|
|
}
|