Skip to content

Commit 67c640f

Browse files
authored
Merge pull request #1984 from DennisHeimbigner/kwaliasfix.dmh
Fix the handling of certain alias types in CDL files.
2 parents 1e99bb4 + 30ee991 commit 67c640f

12 files changed

Lines changed: 1564 additions & 1324 deletions

File tree

RELEASE_NOTES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Release Notes {#RELEASE_NOTES}
66
This file contains a high-level description of this package's evolution. Releases are in reverse chronological order (most recent first). Note that, as of netcdf 4.2, the `netcdf-c++` and `netcdf-fortran` libraries have been separated into their own libraries.
77
## 4.8.1 - TBD
88

9+
* [Bug Fix] Allow some primitive type names to be used as identifiers depending on the file format. See [Github #1984](https://github.com/Unidata/netcdf-c/issues/1984).
910
* [Enhancement] Add support for reading/writing pure Zarr storage format that supports the XArray _ARRAY_DIMENSIONS attribute. See [Github #1952](https://github.com/Unidata/netcdf-c/pull/1952) for more information.
1011
* [Update] Updated version of bzip2 used in filter testing/functionality, in support of [Github #1969](https://github.com/Unidata/netcdf-c/issues/1969).
1112
* [Bug Fix] Corrected HDF5 version detection logic as described in [Github #1962](https://github.com/Unidata/netcdf-c/issues/1962).

ncdump/Makefile.am

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,9 @@ ref_provenance_v1.nc ref_tst_radix.cdl tst_radix.cdl test_radix.sh \
162162
ref_nccopy_w.cdl tst_nccopy_w3.sh tst_nccopy_w4.sh \
163163
ref_no_ncproperty.nc test_unicode_directory.sh \
164164
ref_roman_szip_simple.cdl ref_roman_szip_unlim.cdl ref_tst_perdimspecs.cdl \
165-
test_keywords.sh ref_keyword1.cdl ref_keyword2.cdl ref_tst_nofilters.cdl \
166-
test_unicode_path.sh
165+
test_keywords.sh ref_keyword1.cdl ref_keyword2.cdl \
166+
ref_keyword3.cdl ref_keyword4.cdl \
167+
ref_tst_nofilters.cdl test_unicode_path.sh
167168

168169
# The L512.bin file is file containing exactly 512 bytes each of value 0.
169170
# It is used for creating hdf5 files with varying offsets for testing.
@@ -199,5 +200,7 @@ tst_ncf199.cdl tst_tst_gattenum.cdl tst_tst_usuffix.cdl ctest.c \
199200
ctest64.c nccopy3_subset_out.nc camrun.c tst_ncf213.cdl tst_ncf213.nc \
200201
tst_radix.nc tmp_radix.cdl ctest_small_3.c ctest_small_4.c \
201202
ctest_special_atts_4.c tst_roman_szip_simple.cdl \
202-
tst_roman_szip_unlim.cdl tst_perdimpspecs.nc tmppds.* \
203-
keyword1.nc keyword2.nc tmp_keyword1.cdl tmp_keyword2.cdl
203+
tst_roman_szip_unlim.cdl tst_perdimpspecs.nc tmppds.* \
204+
keyword1.nc keyword2.nc keyword3.nc keyword4.nc \
205+
tmp_keyword1.cdl tmp_keyword2.cdl tmp_keyword3.cdl tmp_keyword4.cdl
206+

ncdump/ref_keyword3.cdl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
netcdf keyword3 {
2+
variables:
3+
real f;
4+
long l;
5+
}

ncdump/ref_keyword4.cdl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
netcdf x {
2+
dimensions:
3+
string = 17;
4+
variables:
5+
int string;
6+
int string:x = 17;
7+
int :string = 17;
8+
data: string = 1;
9+
}

ncdump/test_keywords.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,25 @@ ${NCDUMP} -h keyword2.nc > tmp_keyword2.cdl
2020
echo "*** comparing tmp_keyword2.cdl to ref_keyword2.cdl..."
2121
diff -b -w tmp_keyword2.cdl $srcdir/ref_keyword2.cdl
2222

23+
echo "*** Test use of type aliases such as 'long' or 'real'..."
24+
echo "*** classic: creating keyword3.nc from ref_keyword3.cdl..."
25+
${NCGEN} -3 -lb -o keyword3.nc $srcdir/ref_keyword3.cdl
26+
echo "*** creating tmp_keyword3.cdl from keyword3.nc..."
27+
# We need to convert float back to real and int back to long
28+
${NCDUMP} -h keyword3.nc | sed -e 's/float/real/g' -e 's/int/long/g' >tmp_keyword3.cdl
29+
echo "*** comparing tmp_keyword3.cdl to ref_keyword3.cdl..."
30+
diff -b -w tmp_keyword3.cdl $srcdir/ref_keyword3.cdl
31+
32+
echo "*** Test use of keywords both pass and fail"
33+
# This should succeed
34+
${NCGEN} -3 -lb -o keyword4.nc $srcdir/ref_keyword4.cdl
35+
echo "***pass: ncgen -3 X ref_keyword4"
36+
# This should (x)fail
37+
if ${NCGEN} -4 -lb -o keyword4.nc $srcdir/ref_keyword4.cdl ; then
38+
echo "***erroneous pass: ncgen -4 X ref_keyword4"
39+
exit 1
40+
else
41+
echo "***xfail: ncgen -4 X ref_keyword4"
42+
fi
43+
2344
exit 0

ncgen/generate.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,8 +449,10 @@ generate_array(Symbol* vsym, Bytebuffer* code, Datalist* filler, Generator* gene
449449
}
450450
nunlimited = countunlimited(args.dimset);
451451

452-
if(vsym->var.special._Storage == NC_CHUNKED)
453-
memcpy(args.chunksizes,vsym->var.special._ChunkSizes,sizeof(size_t)*args.rank);
452+
if(vsym->var.special._Storage == NC_CHUNKED) {
453+
if(vsym->var.special._ChunkSizes)
454+
memcpy(args.chunksizes,vsym->var.special._ChunkSizes,sizeof(size_t)*args.rank);
455+
}
454456

455457
memset(index,0,sizeof(index));
456458

ncgen/genlib.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ extern struct Datalist* getfiller(Symbol*); /* symbol isa variable|type */
8282

8383
/* from: ncgen.y */
8484
extern Symbol* install(const char *sname);
85+
extern Symbol* installin(const char *sname,Symbol* grp);
8586
extern void freesymbol(Symbol*);
8687
extern Symbol* basetypefor(nc_type nctype);/* Convert nctype to a Symbol*/
8788
extern Symbol* makearraytype(Symbol*, Dimset*);

ncgen/ncgen.l

Lines changed: 46 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,15 @@ char char_val; /* last char value read */
115115
signed char byte_val; /* last byte value read */
116116
unsigned char ubyte_val; /* last byte value read */
117117

118+
/* Forward */
118119
static Symbol* makepath(char* text);
119120
static int lexdebug(int);
120121
static unsigned long long parseULL(int radix, char* text, int*);
121122
static nc_type downconvert(unsigned long long uint64, int*, int, int);
122123
static int tagmatch(nc_type nct, int tag);
123124
static int nct2lexeme(nc_type nct);
124125
static int collecttag(char* text, char** stagp);
126+
static int identcheck(int token);
125127

126128
struct Specialtoken specials[] = {
127129
{"_FillValue",_FILLVALUE,_FILLVALUE_FLAG},
@@ -140,35 +142,6 @@ struct Specialtoken specials[] = {
140142
{NULL,0} /* null terminate */
141143
};
142144

143-
/* Track keywords that may be identifiers depending on
144-
format being produced */
145-
/* Define the possible format classes */
146-
#define KWALL (1<<NC_FORMAT_CLASSIC|1<<NC_FORMAT_64BIT_OFFSET|1<<NC_FORMAT_NETCDF4|1<<NC_FORMAT_NETCDF4_CLASSIC|1<<NC_FORMAT_64BIT_DATA) /* Used in all formats */
147-
#define KWCDF5 (1<<NC_FORMAT_64BIT_DATA) /* Used in cdf5 */
148-
#define KWNC4 (1<<NC_FORMAT_NETCDF4) /* Used in netcdf-4 */
149-
150-
#define NKWIDENT 12
151-
struct KWIDENT {
152-
int token;
153-
const char* keyword;
154-
int formats; /* Which formats use this keyword */
155-
} kwident[NKWIDENT] = {
156-
/* Order by token for binary search */
157-
{CHAR_K, "char", KWALL},
158-
{BYTE_K, "byte", KWALL},
159-
{SHORT_K, "short", KWALL},
160-
{INT_K, "int", KWALL},
161-
{FLOAT_K, "float", KWALL},
162-
{DOUBLE_K, "double", KWALL},
163-
{UBYTE_K, "ubyte", KWCDF5|KWNC4},
164-
{USHORT_K, "ushort", KWCDF5|KWNC4},
165-
{UINT_K, "uint", KWCDF5|KWNC4},
166-
{INT64_K, "int64", KWCDF5|KWNC4},
167-
{UINT64_K, "uint64", KWCDF5|KWNC4},
168-
{STRING_K, "string", KWNC4}
169-
};
170-
static int identorkw(int token);
171-
172145
%}
173146
%x ST_C_COMMENT
174147
%x TEXT
@@ -290,27 +263,33 @@ yytext[MAXTRST-1] = '\0';
290263
return lexdebug(OPAQUESTRING);
291264
}
292265

293-
compound|struct|structure {return lexdebug(identorkw(COMPOUND));}
294-
enum {return lexdebug(identorkw(ENUM));}
266+
compound|struct|structure {return lexdebug(COMPOUND);}
267+
enum {return lexdebug(ENUM);}
295268
opaque {return lexdebug(OPAQUE_);}
296269

297-
float|real {return lexdebug(identorkw(FLOAT_K));}
298-
char {return lexdebug(identorkw(CHAR_K));}
299-
byte {return lexdebug(identorkw(BYTE_K));}
300-
ubyte {return lexdebug(identorkw(UBYTE_K));}
301-
short {return lexdebug(identorkw(SHORT_K));}
302-
ushort {return lexdebug(identorkw(USHORT_K));}
303-
long|int|integer {return lexdebug(identorkw(INT_K));}
304-
ulong|uint|uinteger {return lexdebug(identorkw(UINT_K));}
305-
int64 {return lexdebug(identorkw(INT64_K));}
306-
uint64 {return lexdebug(identorkw(UINT64_K));}
307-
double {return lexdebug(identorkw(DOUBLE_K));}
308-
string {return lexdebug(identorkw(STRING_K));}
270+
float {return lexdebug(FLOAT_K);}
271+
double {return lexdebug(DOUBLE_K);}
272+
char {return lexdebug(CHAR_K);}
273+
byte {return lexdebug(BYTE_K);}
274+
short {return lexdebug(SHORT_K);}
275+
int {return lexdebug(INT_K);}
276+
ubyte {return lexdebug(identcheck(UBYTE_K));}
277+
ushort {return lexdebug(identcheck(USHORT_K));}
278+
uint {return lexdebug(identcheck(UINT_K));}
279+
int64 {return lexdebug(identcheck(INT64_K));}
280+
uint64 {return lexdebug(identcheck(UINT64_K));}
281+
string {return lexdebug(identcheck(STRING_K));}
282+
283+
real {return lexdebug(FLOAT_K);}
284+
long {return lexdebug(INT_K);}
285+
integer {return lexdebug(INT_K);}
286+
ulong {return lexdebug(identcheck(UINT_K));}
287+
uinteger {return lexdebug(identcheck(UINT_K));}
288+
309289

310290
unlimited|UNLIMITED {int32_val = -1;
311-
return lexdebug(identorkw(NC_UNLIMITED_K));}
291+
return lexdebug(NC_UNLIMITED_K);}
312292

313-
/* These are currently only keywords */
314293
types: {return lexdebug(TYPES);}
315294
dimensions: {return lexdebug(DIMENSIONS);}
316295
variables: {return lexdebug(VARIABLES);}
@@ -620,9 +599,7 @@ lexdebug(int token)
620599
{
621600
if(debug >= 2)
622601
{
623-
char* text = yytext;
624-
text[yyleng] = 0;
625-
fprintf(stderr,"Token=%d |%s| line=%d\n",token,text,lineno);
602+
fprintf(stderr,"Token=%d |%s| line=%d\n",token,yytext,lineno);
626603
}
627604
return token;
628605
}
@@ -907,38 +884,28 @@ collecttag(char* text, char** stagp)
907884
return tag;
908885
}
909886

910-
/* Depending on the format, a name may be a keword or an ident */
911887
static int
912-
identorkw(int token)
888+
identcheck(int token)
913889
{
914-
/* Binary search for yytext */
915-
int n = NKWIDENT;
916-
int L = 0;
917-
int R = (n - 1);
918-
int m, cmp;
919-
struct KWIDENT* p;
920-
int found = 0;
921-
size_t len;
922-
char* id = NULL;
923-
924-
for(;;) {
925-
if(L > R) break;
926-
m = (L + R) / 2;
927-
p = &kwident[m];
928-
cmp = (p->token - token);
929-
if(cmp == 0) {found = 1; break;}
930-
if(cmp < 0)
931-
L = (m + 1);
932-
else /*cmp > 0*/
933-
R = (m - 1);
890+
switch (token) {
891+
case UBYTE_K:
892+
case USHORT_K:
893+
case UINT_K:
894+
case INT64_K:
895+
case UINT64_K:
896+
if(k_flag != NC_FORMAT_NETCDF4 && k_flag != NC_FORMAT_64BIT_DATA) {
897+
yylval.sym = install(yytext);
898+
token = IDENT;
899+
}
900+
break;
901+
case STRING_K:
902+
if(k_flag != NC_FORMAT_NETCDF4) {
903+
yylval.sym = install(yytext);
904+
token = IDENT;
905+
}
906+
break;
907+
default:
908+
break;
934909
}
935-
if(!found) return token; /* Not a keyword of interest */
936-
/* See if the format applies */
937-
if(p->formats & ((int)1<<k_flag)) return token;
938-
/* Need to convert a non-ident token to an ident symbol */
939-
len = strlen(yytext);
940-
len = unescape(yytext,len,ISIDENT,&id);
941-
yylval.sym = install(id);
942-
efree(id);
943-
return IDENT; /* treat as identifier */
910+
return token;
944911
}

ncgen/ncgen.y

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ static char SccsId[] = "$Id: ncgen.y,v 1.42 2010/05/18 21:32:46 dmh Exp $";
2626
#define ncvar_t void
2727
#include "nctime.h"
2828

29+
#undef GENLIB1
30+
2931
/* parser controls */
3032
#define YY_NO_INPUT 1
3133

@@ -966,14 +968,19 @@ makeprimitivetype(nc_type nctype)
966968
/* install sname in symbol table even if it is already there */
967969
Symbol*
968970
install(const char *sname)
971+
{
972+
return installin(sname,currentgroup());
973+
}
974+
975+
Symbol*
976+
installin(const char *sname, Symbol* grp)
969977
{
970978
Symbol* sp;
971979
sp = (Symbol*) ecalloc (sizeof (struct Symbol));
972980
sp->name = nulldup(sname);
973981
sp->lineno = lineno;
974-
sp->location = currentgroup();
975-
sp->container = currentgroup();
976-
sp->var.special._Storage = NC_CONTIGUOUS;
982+
sp->location = grp;
983+
sp->container = grp;
977984
listpush(symlist,sp);
978985
return sp;
979986
}
@@ -1245,8 +1252,6 @@ makespecial(int tag, Symbol* vsym, Symbol* tsym, void* data, int isconst)
12451252
globalspecials._Format = kvalue->k_flag;
12461253
/*Main.*/format_attribute = 1;
12471254
found = 1;
1248-
if(kvalue->deprecated)
1249-
fprintf(stderr,"_Format=%s is deprecated; use corresponding _Format=<name>\n",sdata);
12501255
break;
12511256
}
12521257
}
@@ -1569,21 +1574,21 @@ done:
15691574

15701575
#ifdef GENDEBUG1
15711576
static void
1572-
printfilters(int nfilters, NC_Filterspec** filters)
1577+
printfilters(int nfilters, NC_FilterSpec** filters)
15731578
{
15741579
int i;
15751580
fprintf(stderr,"xxx: nfilters=%lu: ",(unsigned long)nfilters);
15761581
for(i=0;i<nfilters;i++) {
15771582
int k;
15781583
NC_Filterspec* sp = filters[i];
15791584
fprintf(stderr,"{");
1580-
fprintf(stderr,"filterid=%s format=%s nparams=%lu params=%p",
1585+
fprintf(stderr,"filterid=%llu format=%d nparams=%lu params=%p",
15811586
sp->filterid,sp->format,(unsigned long)sp->nparams,sp->params);
15821587
if(sp->nparams > 0 && sp->params != NULL) {
15831588
fprintf(stderr," params={");
15841589
for(k=0;k<sp->nparams;k++) {
15851590
if(i==0) fprintf(stderr,",");
1586-
fprintf(stderr,"%s",sp->params[i]);
1591+
fprintf(stderr,"%u",sp->params[i]);
15871592
}
15881593
fprintf(stderr,"}");
15891594
} else

0 commit comments

Comments
 (0)