[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:
dmh 2013-09-21 16:19:06 -06:00
parent fc16046432
commit 06d91c3084
9 changed files with 107 additions and 34 deletions

View File

@ -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,

View File

@ -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;
}

View File

@ -318,8 +318,8 @@ data:
39000, 38990 ;
c213 =
"1",
"two" ;
"",
"" ;
s221 =
2500,

View File

@ -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,

View File

@ -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? */

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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;
}
/**