mirror of
https://github.com/Unidata/netcdf-c.git
synced 2025-03-31 17:50:26 +08:00
[NCF-265] again.
Added code to verify that enum constants (and other constants) are consistent with the type of the variable or attribute to which they are assigned. This addresses the ncdump failure.
This commit is contained in:
parent
fc16046432
commit
06d91c3084
@ -318,10 +318,9 @@ data:
|
||||
40000, 39990,
|
||||
39000, 38990 ;
|
||||
|
||||
// The following trips a bug on Cray T3E, but should work on other platforms
|
||||
c213 =
|
||||
"1",
|
||||
"two" ;
|
||||
"",
|
||||
"" ;
|
||||
|
||||
s221 =
|
||||
2500,
|
||||
|
@ -1,13 +1,13 @@
|
||||
netcdf tim {
|
||||
netcdf ref_tst_econst {
|
||||
types:
|
||||
byte enum e1{pass=0, fail=1, undefined=2};
|
||||
byte enum e2{defined=0, undefined=1};
|
||||
variables:
|
||||
e1 test1;
|
||||
e2 test2;
|
||||
e2 test3;
|
||||
e1 test3;
|
||||
data:
|
||||
test1=pass;
|
||||
test2=e1.undefined;
|
||||
test2=e2.undefined;
|
||||
test3=/e1.fail;
|
||||
}
|
||||
|
@ -318,8 +318,8 @@ data:
|
||||
39000, 38990 ;
|
||||
|
||||
c213 =
|
||||
"1",
|
||||
"two" ;
|
||||
"",
|
||||
"" ;
|
||||
|
||||
s221 =
|
||||
2500,
|
||||
|
@ -317,10 +317,9 @@ data:
|
||||
40000, 39990,
|
||||
39000, 38990 ;
|
||||
|
||||
// The following trips a bug on Cray T3E, but should work on other platforms
|
||||
// c213 =
|
||||
// "1",
|
||||
// "two" ;
|
||||
c213 =
|
||||
"",
|
||||
"" ;
|
||||
|
||||
s221 =
|
||||
2500,
|
||||
|
@ -49,7 +49,7 @@ typedef union Constvalue {
|
||||
} Constvalue;
|
||||
|
||||
typedef struct NCConstant {
|
||||
nc_type nctype;
|
||||
nc_type nctype; /* NC_INT,... */
|
||||
int lineno;
|
||||
Constvalue value;
|
||||
int filled; /* was this originally NC_FILLVALUE? */
|
||||
|
@ -186,7 +186,7 @@ static struct {
|
||||
{'|', "_VERTICALBAR_"},
|
||||
{'}', "_RIGHTCURLY_"},
|
||||
{'~', "_TILDE_"},
|
||||
{'/', "__"},
|
||||
{'/', "_SLASH_"},
|
||||
};
|
||||
static int idtlen;
|
||||
static int hexlen;
|
||||
@ -529,7 +529,7 @@ f77codify(const char* s0)
|
||||
|
||||
/**************************************************/
|
||||
/* Escape Fqn segment names by replacing
|
||||
'/' and '.' by ascii hex equivalent
|
||||
'/' and '.' by alternate representation.
|
||||
*/
|
||||
|
||||
char*
|
||||
@ -539,8 +539,16 @@ fqnescape(const char* s)
|
||||
char* q;
|
||||
int c;
|
||||
int l = strlen(s);
|
||||
char* newname = poolalloc(l*3+1);
|
||||
|
||||
/*
|
||||
1234567
|
||||
_SLASH_
|
||||
_DOT__
|
||||
*/
|
||||
char* newname = poolalloc(l*7+1);
|
||||
*newname = '\0';
|
||||
for(q=newname,p=s;(c=*p++);) {
|
||||
#if 0
|
||||
if(c == '/' || c == '.') {
|
||||
/* Do hex escape */
|
||||
int hex1 = (c & 0x0f);
|
||||
@ -550,6 +558,18 @@ fqnescape(const char* s)
|
||||
*q++ = hexdigits[hex2];
|
||||
} else
|
||||
*q++ = c;
|
||||
#else
|
||||
if(c == '/') {
|
||||
strcat(q,"_SLASH_");
|
||||
q += 7;
|
||||
} else if(c == '.') {
|
||||
strcat(q,"_DOT_");
|
||||
q += 5;
|
||||
} else {
|
||||
*q++ = c;
|
||||
*q = '\0';
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return newname;
|
||||
}
|
||||
|
@ -648,8 +648,9 @@ dimncid(Symbol* dsym)
|
||||
const char* tmp1;
|
||||
char* dimtmp;
|
||||
tmp1 = cname(dsym);
|
||||
dimtmp = poolalloc(strlen(tmp1)+1);
|
||||
dimtmp = poolalloc(strlen(tmp1)+strlen("_dim")+1);
|
||||
strcpy(dimtmp,tmp1);
|
||||
strcat(dimtmp,"_dim");
|
||||
return dimtmp;
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ generate_vardata(Symbol* vsym, Generator* generator, Writer writer, Bytebuffer*
|
||||
bbSetalloc(code, nciterbuffersize);
|
||||
|
||||
if(rank == 0) {/*scalar case*/
|
||||
NCConstant* c0 = datalistith(vsym->data,0);
|
||||
NCConstant* c0 = datalistith(vsym->data,0);
|
||||
generate_basetype(basetype,c0,code,filler,generator);
|
||||
writer(generator,vsym,code,0,NULL,NULL);
|
||||
} else {/*rank > 0*/
|
||||
@ -463,6 +463,7 @@ generate_primdata(Symbol* basetype, NCConstant* prim, Bytebuffer* codebuf,
|
||||
Datalist* filler, Generator* generator)
|
||||
{
|
||||
NCConstant target;
|
||||
int match;
|
||||
|
||||
if(prim == NULL || isfillconst(prim)) {
|
||||
Datalist* fill = (filler==NULL?getfiller(basetype):filler);
|
||||
@ -472,6 +473,52 @@ generate_primdata(Symbol* basetype, NCConstant* prim, Bytebuffer* codebuf,
|
||||
|
||||
ASSERT(prim->nctype != NC_COMPOUND);
|
||||
|
||||
/* Verify that the constant is consistent with the type */
|
||||
match = 1;
|
||||
switch (prim->nctype) {
|
||||
case NC_CHAR:
|
||||
case NC_BYTE:
|
||||
case NC_SHORT:
|
||||
case NC_INT:
|
||||
case NC_FLOAT:
|
||||
case NC_DOUBLE:
|
||||
case NC_UBYTE:
|
||||
case NC_USHORT:
|
||||
case NC_UINT:
|
||||
case NC_INT64:
|
||||
case NC_UINT64:
|
||||
case NC_STRING:
|
||||
match = (basetype->subclass == NC_PRIM ? 1 : 0);
|
||||
break;
|
||||
|
||||
#ifdef USE_NETCDF4
|
||||
case NC_NIL:
|
||||
match = (basetype->subclass == NC_PRIM && basetype->typ.typecode == NC_STRING ? 1 : 0);
|
||||
break;
|
||||
|
||||
case NC_OPAQUE:
|
||||
/* OPAQUE is also consistent with numbers */
|
||||
match = (basetype->subclass == NC_OPAQUE
|
||||
|| basetype->subclass == NC_PRIM ? 1 : 0);
|
||||
break;
|
||||
case NC_ECONST:
|
||||
match = (basetype->subclass == NC_ENUM ? 1 : 0);
|
||||
if(match) {
|
||||
/* Make sure this econst belongs to this enum */
|
||||
Symbol* ec = prim->value.enumv;
|
||||
Symbol* en = ec->container;
|
||||
match = (en == basetype);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
match = 0;
|
||||
}
|
||||
if(!match) {
|
||||
semerror(constline(prim),"Data value is not consistent with the expected type: %s",
|
||||
basetype->name);
|
||||
}
|
||||
|
||||
target.nctype = basetype->typ.typecode;
|
||||
|
||||
if(target.nctype != NC_ECONST) {
|
||||
|
@ -102,23 +102,30 @@ topfqn(Symbol* sym)
|
||||
if(sym->fqn != NULL)
|
||||
return; /* already defined */
|
||||
|
||||
parent = sym->container;
|
||||
/* Recursively compute parent fqn */
|
||||
if(parent == NULL) { /* implies this is the rootgroup */
|
||||
assert(sym->grp.is_root);
|
||||
sym->fqn = strdup("");
|
||||
return;
|
||||
} else if(parent->fqn == NULL) {
|
||||
topfqn(parent);
|
||||
#ifdef USE_NETCDF4
|
||||
if(!usingclassic) {
|
||||
parent = sym->container;
|
||||
/* Recursively compute parent fqn */
|
||||
if(parent == NULL) { /* implies this is the rootgroup */
|
||||
assert(sym->grp.is_root);
|
||||
sym->fqn = strdup("");
|
||||
return;
|
||||
} else if(parent->fqn == NULL) {
|
||||
topfqn(parent);
|
||||
}
|
||||
parentfqn = parent->fqn;
|
||||
|
||||
fqnname = fqnescape(sym->name);
|
||||
fqn = (char*)malloc(strlen(fqnname) + strlen(parentfqn) + 1 + 1);
|
||||
strcpy(fqn,parentfqn);
|
||||
strcat(fqn,"/");
|
||||
strcat(fqn,fqnname);
|
||||
sym->fqn = fqn;
|
||||
} else
|
||||
#endif /*USE_NETCDF4*/
|
||||
{
|
||||
sym->fqn = strdup(sym->name);
|
||||
}
|
||||
parentfqn = parent->fqn;
|
||||
|
||||
fqnname = fqnescape(sym->name);
|
||||
fqn = (char*)malloc(strlen(fqnname) + strlen(parentfqn) + 1 + 1);
|
||||
strcpy(fqn,parentfqn);
|
||||
strcat(fqn,"/");
|
||||
strcat(fqn,fqnname);
|
||||
sym->fqn = fqn;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user