char*
dumpselection(NCselection* sel)
{
    NCbytes* buf = ncbytesnew();
    NCbytes* segbuf = ncbytesnew();
    char* sstring;
    NClist* segments = NULL;
    int j;

    if(sel == NULL) return nulldup("");
    segments = sel->lhs->var->segments;
    ncbytescat(buf,"&");
    tostringncsegments(segments,segbuf);
    ncbytescat(buf,ncbytescontents(segbuf));
    ncbytescat(buf,opstrings[sel->operator]);
    ncbytescat(buf,"{");
    for(j=0;j<nclistlength(sel->rhs);j++) {
        NCvalue* value = (NCvalue*)nclistget(sel->rhs,j);
        NCconstant* con = value->constant;
        char tmp[64];
        if(j > 0) ncbytescat(buf,",");
        switch (value->discrim) {
        case NS_STR:
            ncbytescat(buf,con->text);
            break;          
	case NS_CONST:
            switch (con->discrim) {	    
            case NS_INT:
                snprintf(tmp,sizeof(tmp),"%lld",con->intvalue);
                ncbytescat(buf,tmp);
                break;
            case NS_FLOAT:
                snprintf(tmp,sizeof(tmp),"%g",con->floatvalue);
                ncbytescat(buf,tmp);
                break;
            default: PANIC1("unexpected discriminator %d",(int)con->discrim);
	    }
	    break;
        case NS_VAR:
            segments = value->var->segments;
	    ncbytesclear(segbuf);
	    tostringncsegments(segments,segbuf);
            ncbytescat(buf,ncbytescontents(segbuf));
            break;
        default: PANIC1("unexpected discriminator %d",(int)value->discrim);
        }
    }
    ncbytescat(buf,"}");
    sstring = ncbytesdup(buf);
    ncbytesfree(buf);
    ncbytesfree(segbuf);
    return sstring;
}
static void
fill(Symbol* tvsym, Datalist* filler)
{
    int i;
    Constant con;
    Datalist* sublist;
    /* NC_TYPE case*/
    switch (tvsym->subclass) {
    case NC_ENUM: case NC_OPAQUE: case NC_PRIM:
        con.nctype = tvsym->typ.typecode;
        nc_getfill(&con);
	break;
    case NC_COMPOUND:
	sublist = builddatalist(listlength(tvsym->subnodes));
        for(i=0;i<listlength(tvsym->subnodes);i++) {
	    Symbol* field = (Symbol*)listget(tvsym->subnodes,i);
	    if(field->typ.dimset.ndims > 0) {	
                fillarray(field->typ.basetype,&field->typ.dimset,0,filler);
	    } else
		filllist(field->typ.basetype,sublist);
        }	  
	con = builddatasublist(sublist);
	break;
    case NC_VLEN:
	sublist = builddatalist(0);
	filllist(tvsym->typ.basetype,sublist); /* generate a single instance*/
	con = builddatasublist(sublist);
	break;
    default: PANIC1("fill: unexpected subclass %d",tvsym->subclass);
    }
    dlappend(filler,&con);
}
Beispiel #3
0
static void
filllist(Symbol* tsym, Datalist* dl)
{
    int i;
    Datalist* sublist;
    NCConstant con;
    con.filled = 0;

    ASSERT(tsym->objectclass == NC_TYPE);
    switch (tsym->subclass) {
    case NC_ENUM: case NC_OPAQUE: case NC_PRIM:
        con.nctype = tsym->typ.typecode;
        nc_getfill(&con);
	dlappend(dl,&con);
	break;
    case NC_COMPOUND:
	sublist = builddatalist(listlength(tsym->subnodes));
        for(i=0;i<listlength(tsym->subnodes);i++) {
	    Symbol* field = (Symbol*)listget(tsym->subnodes,i);
	    filllist(field->typ.basetype,sublist);
        }	  
	con = builddatasublist(sublist);
	dlappend(dl,&con);
	break;
    case NC_VLEN:
	sublist = builddatalist(0);
	filllist(tsym->typ.basetype,sublist); /* generate a single instance*/
	con = builddatasublist(sublist);
	dlappend(dl,&con);
	break;
    default: PANIC1("fill: unexpected subclass %d",tsym->subclass);
    }
}
Beispiel #4
0
unsigned int
ncctypealignment(int nctype)
{
    NCtypealignment* align = NULL;
    int index = 0;
    if(!dapaligninit) compute_nccalignments();
    switch (nctype) {
      case NC_BYTE:   index = NCCTYPEUCHAR; break;
      case NC_CHAR:   index = NCCTYPECHAR; break;
      case NC_SHORT:  index = NCCTYPESHORT; break;
      case NC_INT:    index = NCCTYPEINT; break;
      case NC_FLOAT:  index = NCCTYPEFLOAT; break;
      case NC_DOUBLE: index = NCCTYPEDOUBLE; break;
      case NC_UBYTE:  index = NCCTYPEUCHAR; break;
      case NC_USHORT: index = NCCTYPEUSHORT; break;
      case NC_UINT:   index = NCCTYPEUINT; break;
      case NC_INT64:  index = NCCTYPELONGLONG; break;
      case NC_UINT64: index = NCCTYPEULONGLONG; break;
      case NC_STRING: index = NCCTYPEPTR; break;
      case NC_VLEN:   index = NCCTYPENCVLEN; break;
      case NC_OPAQUE: index = NCCTYPEUCHAR; break;
      default:
#ifndef OFFSETTEST
	PANIC1("nctypealignment: bad type code: %d",nctype);
#else
	return 0;
#endif
    }
    align = &vec[index];
    return align->alignment;
}
Beispiel #5
0
unsigned int
nctypealignment(nc_type nctype)
{
    Alignment* align = NULL;
    int index = 0;
    switch (nctype) {
      case NC_BYTE: index = UCHARINDEX; break;
      case NC_CHAR: index = CHARINDEX; break;
      case NC_SHORT: index = SHORTINDEX; break;
      case NC_INT: index = INTINDEX; break;
      case NC_FLOAT: index = FLOATINDEX; break;
      case NC_DOUBLE: index = DOUBLEINDEX; break;
      case NC_UBYTE: index = UCHARINDEX; break;
      case NC_USHORT: index = USHORTINDEX; break;
      case NC_UINT: index = UINTINDEX; break;
      case NC_INT64: index = LONGLONGINDEX; break;
      case NC_UINT64: index = ULONGLONGINDEX; break;
      case NC_STRING: index = PTRINDEX; break;
      case NC_VLEN: index = NCVLENINDEX; break;
      case NC_OPAQUE: index = UCHARINDEX; break;
      default: PANIC1("nctypealignment: bad type code: %d",nctype);
    }
    align = &vec[index];
    return align->alignment;
}
Beispiel #6
0
static int
checkfill(Symbol* tsym, Datasrc* src)
{
    int i,iscmpd,result;
    Constant* con;
    Symbol* original = tsym;

    result = 1;
    switch (tsym->subclass) {
    case NC_ENUM: case NC_OPAQUE: case NC_PRIM:
	con = srcnext(src);
	if(src == NULL) {
	    semerror(srcline(src),"%s: malformed _FillValue",original->name);
	    result = 0;
	} else if(con->nctype != tsym->typ.typecode) result = 0; /* wrong type*/
	break;

    case NC_COMPOUND:
        if(!issublist(src)) {/* fail on no compound*/
           semerror(srcline(src),"Compound constants must be enclosed in {..}");
        }
	srcpush(src);
        for(i=0;i<listlength(tsym->subnodes);i++) {
	    Symbol* field = (Symbol*)listget(tsym->subnodes,i);
	    result = checkfill(field,src,original);
	    if(!result) break;
        }	  
	srcpop(src);
	break;

    case NC_VLEN:
	if(!issublist(src)) {
	    semerror(srcline(src),"%s: vlen instances in _FillValue must be enclosed in {...}",original->name);
	    result = 0;
	} else {
	    srcpush(src);
            while(srcmore(src)) {
		result = checkfill(tsym->typ.basetype,src,original);
		if(!result) break;
	    }
	    srcpop(src);
	}
	break;

    case NC_FIELD:
	/* Braces are optional */
	if((iscmpd=issublist(src))) srcpush(src);
	if(tsym->typ.dimset.ndims > 0) {
            result = checkarray(tsym->typ.basetype,&tsym->typ.dimset,0,src,original,!TOPLEVEL);
	} else
	    result = checkfill(tsym->typ.basetype,src,original);
	if(iscmpd) srcpop(src);
	break;

    default: PANIC1("checkfillvalue: unexpected subclass %d",tsym->subclass);
    }
    return result;
}
Beispiel #7
0
static void
genbin_data(Symbol* tsym, Datasrc* datasrc, Datalist* fillsrc,
		Bytebuffer* memory)
{
    int usecmpd;
    Constant* con = srcpeek(datasrc);
    if(con == NULL || con->nctype == NC_FILLVALUE) {
	srcnext(datasrc);
	genbin_fillvalue(tsym,fillsrc,datasrc,memory);
	return;
    }

    switch (tsym->subclass) {

    case NC_ENUM:
    case NC_OPAQUE:
    case NC_PRIM:
	if(issublist(datasrc)) {
	    semerror(srcline(datasrc),"Expected primitive found {..}");
	}
	genbin_primdata(tsym,datasrc,fillsrc,memory);
	break;

    case NC_COMPOUND:
	genbin_compound(tsym,datasrc,fillsrc,memory);
	break;

    case NC_VLEN: {
        Constant* cp;
        nc_vlen_t ptr;
        if(!issublist(datasrc)) {
	    semerror(srcline(datasrc),"Vlen data must be enclosed in {..}");
        }
        cp = srcnext(datasrc);
        /* generate the nc_vlen_t instance*/
        ptr.p = vlendata[cp->value.compoundv->vlen.uid].data;
        ptr.len = vlendata[cp->value.compoundv->vlen.uid].count;
        bbAppendn(memory,(char*)&ptr,sizeof(ptr));
        } break;

    case NC_FIELD:
	/* enclose in braces if and only if field is an array */
	usecmpd = (issublist(datasrc) && tsym->typ.dimset.ndims > 0);
	if(usecmpd) srcpush(datasrc);
	if(tsym->typ.dimset.ndims > 0) {
            genbin_fieldarray(tsym->typ.basetype,datasrc,&tsym->typ.dimset,0,memory);
	} else {
	    genbin_data(tsym->typ.basetype,datasrc,NULL,memory);
	}
	if(usecmpd) srcpop(datasrc);
	break;

    default: PANIC1("genbin_data: unexpected subclass %d",tsym->subclass);
    }
}
Beispiel #8
0
char*
dumpselection1(NCselection* sel)
{
    NCbytes* buf = ncbytesnew();
    char* sstring;
    NClist* path = NULL;
    char* pathstring = NULL;
    int j;

    if(sel == NULL) return nulldup("");
    path = sel->path;
    ncbytescat(buf,"&");
    if(path == NULL)
	pathstring = makecdfpathstring3(sel->node,".");
    else
	pathstring = simplepathstring3(path,".");
    ncbytescat(buf,pathstring);
    efree(pathstring);
    ncbytescat(buf,opstrings[sel->operator]);
    ncbytescat(buf,"{");
    for(j=0;j<nclistlength(sel->values);j++) {
        NCvalue* value = (NCvalue*)nclistget(sel->values,j);
        char tmp[64];
        if(j > 0) ncbytescat(buf,",");
        switch (value->kind) {
        case ST_STR:
            ncbytescat(buf,value->value.text);
            break;          
        case ST_INT:
            snprintf(tmp,sizeof(tmp),"%lld",value->value.intvalue);
            ncbytescat(buf,tmp);
            break;
        case ST_FLOAT:
            snprintf(tmp,sizeof(tmp),"%g",value->value.floatvalue);
            ncbytescat(buf,tmp);
            break;
        case ST_VAR:
            path = value->value.var.path;
            if(path == NULL)
                pathstring = makecdfpathstring3(value->value.var.node,".");
            else
                pathstring = simplepathstring3(path,".");
            ncbytescat(buf,pathstring);
            efree(pathstring);
            break;
        default: PANIC1("unexpected tag: %d",(int)value->kind);
        }
    }
    ncbytescat(buf,"}");
    sstring = ncbytesdup(buf);
    ncbytesfree(buf);
    return sstring;
}
/* Result is a pool string or a constant => do not free*/
char*
f77data_const(Constant* ci)
{
    char tmp[64];
    char* result = NULL;

    tmp[0] = '\0';
    switch (ci->nctype) {
    case NC_CHAR:
	{
	    strcpy(tmp,"'");
	    escapifychar(ci->value.charv,tmp+1,'\'');
	    strcat(tmp,"'");
	}
	break;
    case NC_BYTE:
	sprintf(tmp,"%hhd",ci->value.int8v);
	break;
    case NC_SHORT:
	sprintf(tmp,"%hd",ci->value.int16v);
	break;
    case NC_INT:
	sprintf(tmp,"%d",ci->value.int32v);
	break;
    case NC_FLOAT:
	sprintf(tmp,"%.8g",ci->value.floatv);
	break;
    case NC_DOUBLE: { 
	char* p = tmp;
	/* FORTRAN requires e|E->D */
	sprintf(tmp,"%.16g",ci->value.doublev);
	while(*p) {if(*p == 'e' || *p == 'E') {*p = 'D';}; p++;}
	} break;
    case NC_STRING:
	{
	    Bytebuffer* buf = bbNew();
	    bbAppendn(buf,ci->value.stringv.stringv,ci->value.stringv.len);
	    f77quotestring(buf);
	    result = bbDup(buf);
	    bbFree(buf);
	    goto done;
	}
	break;

    default: PANIC1("ncstype: bad type code: %d",ci->nctype);
    }
    result = pooldup(tmp);
done:
    return result; /*except for NC_STRING and NC_OPAQUE*/
}
Beispiel #10
0
static int
f77_constant(Generator* generator, NCConstant* ci, Bytebuffer* codebuf,...)
{
    char tmp[64];
    char* special = NULL;
    switch (ci->nctype) {

    case NC_CHAR:
	if(ci->value.charv == '\'')
	    sprintf(tmp,"'\\''");
	else
	    sprintf(tmp,"'%c'",ci->value.charv);
	break;
    case NC_BYTE:
	sprintf(tmp,"%hhd",ci->value.int8v);
	break;
    case NC_SHORT:
	sprintf(tmp,"%hd",ci->value.int16v);
	break;
    case NC_INT:
	sprintf(tmp,"%d",ci->value.int32v);
	break;
    case NC_FLOAT:
	sprintf(tmp,"%.8g",ci->value.floatv);
	break;
    case NC_DOUBLE: {
	char* p = tmp;
	/* FORTRAN requires e|E->D */
	sprintf(tmp,"%.16g",ci->value.doublev);
	while(*p) {if(*p == 'e' || *p == 'E') {*p = 'D';}; p++;}
	} break;
    case NC_STRING:
	{
	    Bytebuffer* buf = bbNew();
	    bbAppendn(buf,ci->value.stringv.stringv,ci->value.stringv.len);
	    f77quotestring(buf);
	    special = bbDup(buf);
	    bbFree(buf);
	}
	break;

    default: PANIC1("f77data: bad type code: %d",ci->nctype);

    }
    if(special != NULL)
	bbCat(codebuf,special);
    else
	bbCat(codebuf,tmp);
    return 1;
}
/* Generate an instance of the basetype using datasrc */
void
f77data_basetype(Symbol* tsym, Datasrc* datasrc, Bytebuffer* codebuf, Datalist* fillsrc)
{
    switch (tsym->subclass) {

    case NC_PRIM:
	if(issublist(datasrc)) {
	    semerror(srcline(datasrc),"Expected primitive found {..}");
	}
	bbAppend(codebuf,' ');
	f77data_primdata(tsym,datasrc,codebuf,fillsrc);
	break;

    default: PANIC1("f77data_basetype: unexpected subclass %d",tsym->subclass);
    }
}
Beispiel #12
0
const char* 
jtypeallcaps(nc_type type)
{
    switch (type) {
      case NC_CHAR: return "CHAR";
      case NC_BYTE: return "BYTE";
      case NC_SHORT: return "SHORT";
      case NC_INT: return "INT";
      case NC_FLOAT: return "FLOAT";
      case NC_DOUBLE: return "DOUBLE";
      case NC_UBYTE: return "LONG";
      case NC_USHORT: return "LONG";
      case NC_UINT: return "LONG";
      case NC_INT64: return "LONG";
      case NC_UINT64: return "LONG";
      case NC_STRING: return "STRING";
      default: PANIC1("ncctype: bad type code:%d",type);
    }
    return 0;
}
Beispiel #13
0
static void
checkconsistency(void)
{
    int i;
    for(i=0;i<listlength(grpdefs);i++) {
	Symbol* sym = (Symbol*)listget(grpdefs,i);
	if(sym == rootgroup) {
	    if(sym->container != NULL)
	        PANIC("rootgroup has a container");
	} else if(sym->container == NULL && sym != rootgroup)
	    PANIC1("symbol with no container: %s",sym->name);
	else if(sym->container->ref.is_ref != 0)
	    PANIC1("group with reference container: %s",sym->name);
	else if(sym != rootgroup && !sqContains(sym->container->subnodes,sym))
	    PANIC1("group not in container: %s",sym->name);
	if(sym->subnodes == NULL)
	    PANIC1("group with null subnodes: %s",sym->name);
    }
    for(i=0;i<listlength(typdefs);i++) {
	Symbol* sym = (Symbol*)listget(typdefs,i);
        if(!sqContains(sym->container->subnodes,sym))
	    PANIC1("type not in container: %s",sym->name);
    }
    for(i=0;i<listlength(dimdefs);i++) {
	Symbol* sym = (Symbol*)listget(dimdefs,i);
        if(!sqContains(sym->container->subnodes,sym))
	    PANIC1("dimension not in container: %s",sym->name);
    }
    for(i=0;i<listlength(vardefs);i++) {
	Symbol* sym = (Symbol*)listget(vardefs,i);
        if(!sqContains(sym->container->subnodes,sym))
	    PANIC1("variable not in container: %s",sym->name);
	if(!(isprimplus(sym->typ.typecode)
	     || sqContains(typdefs,sym->typ.basetype)))
	    PANIC1("variable with undefined type: %s",sym->name);
    }
}
Beispiel #14
0
const char* 
jtypecap(nc_type type)
{
    switch (type) {
      case NC_CHAR: return "Char";
      case NC_BYTE: return "Byte";
      case NC_SHORT: return "Short";
      case NC_INT: return "Int";
      case NC_FLOAT: return "Float";
      case NC_DOUBLE: return "Double";
      case NC_UBYTE: return "Long";
      case NC_USHORT: return "Long";
      case NC_UINT: return "Long";
      case NC_INT64: return "Long";
      case NC_UINT64: return "Long";
      case NC_STRING: return "String";
      case NC_ENUM: return "Int";
      case NC_OPAQUE: return "String";
      default: PANIC1("ncctype: bad type code:%d",type);
    }
    return 0;
}
Beispiel #15
0
/*
 * Return java type name for netCDF type, given type code.
 */
static const char* 
jtype(nc_type type)
{
    switch (type) {
      case NC_CHAR: return "char";
      case NC_BYTE: return "byte";
      case NC_SHORT: return "short";
      case NC_INT: return "int";
      case NC_FLOAT: return "float";
      case NC_DOUBLE: return "double";
      case NC_UBYTE: return "long";
      case NC_USHORT: return "long";
      case NC_UINT: return "long";
      case NC_INT64: return "long";
      case NC_UINT64: return "long";
      case NC_STRING: return "String";
      case NC_ENUM: return "int";
      case NC_OPAQUE: return "String";
      default: PANIC1("ncctype: bad type code:%d",type);
    }
    return 0;
}
Beispiel #16
0
/* Generate an instance of the basetype using datasrc */
void
cdata_basetype(Symbol* tsym, Datasrc* datasrc, Bytebuffer* codebuf, Datalist* fillsrc)
{
    int usecmpd;

    switch (tsym->subclass) {

    case NC_ENUM:
    case NC_OPAQUE:
    case NC_PRIM:
	if(issublist(datasrc)) {
	    semerror(srcline(datasrc),"Expected primitive found {..}");
	}
	bbAppend(codebuf,' ');
	cdata_primdata(tsym,datasrc,codebuf,fillsrc);
	break;

    case NC_COMPOUND: {
	int i;
        Constant* con;
	if(!isfillvalue(datasrc) && !issublist(datasrc)) {/* fail on no compound*/
	    semerror(srcline(datasrc),"Compound data must be enclosed in {..}");
        }
        con = srcnext(datasrc);
	if(con->nctype == NC_FILLVALUE) {
	    Datalist* filler = getfiller(tsym,fillsrc);
	    ASSERT(filler->length == 1);
	    con = &filler->data[0];
	    if(con->nctype != NC_COMPOUND) {
	        semerror(con->lineno,"Compound data fill value is not enclosed in {..}");
	    }
	}
        srcpushlist(datasrc,con->value.compoundv); /* enter the sublist*/
        bbAppend(codebuf,'{');
        for(i=0;i<listlength(tsym->subnodes);i++) {
            Symbol* field = (Symbol*)listget(tsym->subnodes,i);
            bbAppend(codebuf,' ');
            cdata_basetype(field,datasrc,codebuf,NULL);
	}
        bbAppend(codebuf,'}');
        srcpop(datasrc);
	} break;

    case NC_VLEN: {
        Constant* con;
	if(!isfillvalue(datasrc) && !issublist(datasrc)) {/* fail on no compound*/
	    semerror(con->lineno,"Vlen data must be enclosed in {..}");
        }
        con = srcnext(datasrc);
	if(con->nctype == NC_FILLVALUE) {
	    Datalist* filler = getfiller(tsym,fillsrc);
	    ASSERT(filler->length == 1);
	    con = &filler->data[0];
	    if(con->nctype != NC_COMPOUND) {
	        semerror(con->lineno,"Vlen data fill value is not enclosed in {..}");
	    }
	}
        /* generate the nc_vlen_t instance*/
        bbprintf0(stmt,"{%u (void*)vlen_%u}",
	         con->value.compoundv->vlen.count,
    		 con->value.compoundv->vlen.uid);
        bbCatbuf(codebuf,stmt);
        } break;

    case NC_FIELD:
	/* enclose in braces if and only if field is an array */
	usecmpd = (issublist(datasrc) && tsym->typ.dimset.ndims > 0);
	if(usecmpd) srcpush(datasrc);
	if(tsym->typ.dimset.ndims > 0) {
	    Odometer* fullodom = newodometer(&tsym->typ.dimset,NULL,NULL);
            cdata_fieldarray(tsym->typ.basetype,datasrc,fullodom,0,codebuf);
	    odometerfree(fullodom);
	} else {
	    cdata_basetype(tsym->typ.basetype,datasrc,codebuf,NULL);
	}
	if(usecmpd) srcpop(datasrc);
	break;

    default: PANIC1("cdata_basetype: unexpected subclass %d",tsym->subclass);
    }
}
Beispiel #17
0
NCerror
nc3d_getvarx(int ncid, int varid,
	    const size_t *startp,
	    const size_t *countp,
	    const ptrdiff_t* stridep,
	    void *data,
	    nc_type dsttype0)
{
    NCerror ncstat = NC_NOERR;
    OCerror ocstat = OC_NOERR;
    int i;
    NC* drno;
    NC* substrate;
    NCDAPCOMMON* dapcomm;
    CDFnode* cdfvar = NULL; /* cdf node mapping to var*/
    NClist* varnodes;
    nc_type dsttype;
    Getvara* varainfo = NULL;
    CDFnode* xtarget = NULL; /* target in DATADDS */
    CDFnode* target = NULL; /* target in constrained DDS */
    DCEprojection* varaprojection = NULL;
    NCcachenode* cachenode = NULL;
    size_t localcount[NC_MAX_VAR_DIMS];
    NClist* ncdimsall;
    size_t ncrank;
    NClist* vars = NULL;
    DCEconstraint* fetchconstraint = NULL;
    DCEprojection* fetchprojection = NULL;
    DCEprojection* walkprojection = NULL;
    int state;
#define FETCHWHOLE 1 /* fetch whole data set */
#define FETCHVAR   2 /* fetch whole variable */
#define FETCHPART  4 /* fetch constrained variable */
#define CACHED     8 /* whole variable is already in the cache */

    ncstat = NC_check_id(ncid, (NC**)&drno);
    if(ncstat != NC_NOERR) goto fail;
    dapcomm = (NCDAPCOMMON*)drno->dispatchdata;
    
    ncstat = NC_check_id(drno->substrate, (NC**)&substrate);
    if(ncstat != NC_NOERR) goto fail;

    /* Locate var node via varid */
    varnodes = dapcomm->cdf.ddsroot->tree->varnodes;
    for(i=0;i<nclistlength(varnodes);i++) {
	CDFnode* node = (CDFnode*)nclistget(varnodes,i);
	if(node->array.basevar == NULL
           && node->nctype == NC_Atomic
           && node->ncid == varid) {
	    cdfvar = node;
	    break;
	}
    }

    ASSERT((cdfvar != NULL));

    /* If the variable is prefetchable, then now
       is the time to do a lazy prefetch */
   if(FLAGSET(dapcomm->controls,NCF_PREFETCH)
      && !FLAGSET(dapcomm->controls,NCF_PREFETCH_EAGER)) {
        if(dapcomm->cdf.cache != NULL && dapcomm->cdf.cache->prefetch == NULL) {
            ncstat = prefetchdata3(dapcomm);
            if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
	}
    }
    
    /* Get the dimension info */
    ncdimsall = cdfvar->array.dimsetall;
    ncrank = nclistlength(ncdimsall);

#ifdef DEBUG
 {
int i;
fprintf(stderr,"getvarx: %s",cdfvar->ncfullname);
for(i=0;i<ncrank;i++)
  fprintf(stderr,"(%ld:%ld:%ld)",
	(long)startp[i],
	(long)countp[i],
	(long)stridep[i]
	);
fprintf(stderr,"\n");
 }
#endif

    /* Fill in missing arguments */
    if(startp == NULL)
	startp = nc_sizevector0;

    if(countp == NULL) {
        /* Accumulate the dimension sizes */
        for(i=0;i<ncrank;i++) {
	    CDFnode* dim = (CDFnode*)nclistget(ncdimsall,i);
	    localcount[i] = dim->dim.declsize;
	}
	countp = localcount;
    }

    if(stridep == NULL)
	stridep = nc_ptrdiffvector1;

    /* Validate the dimension sizes */
    for(i=0;i<ncrank;i++) {
        CDFnode* dim = (CDFnode*)nclistget(ncdimsall,i);
	if(startp[i] > dim->dim.declsize
	   || startp[i]+countp[i] > dim->dim.declsize) {
	    ncstat = NC_EINVALCOORDS;
	    goto fail;	    
	}
    }	     

#ifdef DEBUG
 {
NClist* dims = cdfvar->array.dimsetall;
fprintf(stderr,"getvarx: %s",cdfvar->ncfullname);
if(nclistlength(dims) > 0) {int i;
for(i=0;i<nclistlength(dims);i++) 
fprintf(stderr,"(%lu:%lu:%lu)",(unsigned long)startp[i],(unsigned long)countp[i],(unsigned long)stridep[i]);
fprintf(stderr," -> ");
for(i=0;i<nclistlength(dims);i++) 
if(stridep[i]==1)
fprintf(stderr,"[%lu:%lu]",(unsigned long)startp[i],(unsigned long)((startp[i]+countp[i])-1));
else {
unsigned long iend = (stridep[i] * countp[i]);
iend = (iend + startp[i]);
iend = (iend - 1);
fprintf(stderr,"[%lu:%lu:%lu]",
(unsigned long)startp[i],(unsigned long)stridep[i],iend);
 }
 }
fprintf(stderr,"\n");
 }
#endif

    dsttype = (dsttype0);

    /* Default to using the inquiry type for this var*/
    if(dsttype == NC_NAT) dsttype = cdfvar->externaltype;

    /* Validate any implied type conversion*/
    if(cdfvar->etype != dsttype && dsttype == NC_CHAR) {
        /* The only disallowed conversion is to/from char and non-byte
           numeric types*/
	switch (cdfvar->etype) {
	case NC_STRING: case NC_URL:
	case NC_CHAR: case NC_BYTE: case NC_UBYTE:
	    break;
	default:
	    return THROW(NC_ECHAR);
	}
    }

    ncstat = makegetvar34(dapcomm,cdfvar,data,dsttype,&varainfo);
    if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}

    /* Compile the start/stop/stride info into a projection */
    ncstat = buildvaraprojection3(varainfo->target,
		                  startp,countp,stridep,
                                  &varaprojection);
    if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}

    fetchprojection = NULL;
    walkprojection = NULL;

    /* Create walkprojection as the merge of the url projections
       and the vara projection; may change in FETCHPART case below*/
    ncstat = daprestrictprojection(dapcomm->oc.dapconstraint->projections,
				   varaprojection,&walkprojection);
    if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}

#ifdef DEBUG
fprintf(stderr,"getvarx: walkprojection: |%s|\n",dumpprojection(walkprojection));
#endif

    /* define the var list of interest */
    vars = nclistnew();
    nclistpush(vars,(void*)varainfo->target);

    state = 0;
    if(iscached(dapcomm,cdfvar,&cachenode)) { /* ignores non-whole variable cache entries */
	state = CACHED;
	ASSERT((cachenode != NULL));
#ifdef DEBUG
fprintf(stderr,"var is in cache\n");
#endif
        /* If it is cached, then it is a whole variable but may still
           need to apply constraints during the walk */
	ASSERT(cachenode->wholevariable); /* by construction */
    } else if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) {
	state = FETCHWHOLE;
    } else {/* load using constraints */
        if(FLAGSET(dapcomm->controls,NCF_WHOLEVAR))
	    state = FETCHVAR;
	else
	    state = FETCHPART;
    }
    ASSERT(state != 0);    

    switch (state) {

    case FETCHWHOLE: {
        /* buildcachenode3 will create a new cachenode and
           will also fetch the whole corresponding datadds.
	*/
        /* Build the complete constraint to use in the fetch */
        fetchconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT);
        /* Use no projections or selections */
        fetchconstraint->projections = nclistnew();
        fetchconstraint->selections = nclistnew();
#ifdef DEBUG
fprintf(stderr,"getvarx: FETCHWHOLE: fetchconstraint: %s\n",dumpconstraint(fetchconstraint));
#endif
        ncstat = buildcachenode34(dapcomm,fetchconstraint,vars,&cachenode,0);
	fetchconstraint = NULL; /*buildcachenode34 takes control of fetchconstraint.*/
	if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
    } break;

    case CACHED: {
    } break;

    case FETCHVAR: { /* Fetch a complete single variable */
        /* Create fetch projection as the merge of the url projections
           and the vara projection */
        ncstat = daprestrictprojection(dapcomm->oc.dapconstraint->projections,
				       varaprojection,&fetchprojection);
	/* elide any sequence and string dimensions (dap servers do not allow such). */
	ncstat = removepseudodims(fetchprojection);
        if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}

	/* Convert to a whole variable projection */
	dcemakewholeprojection(fetchprojection);

#ifdef DEBUG
fprintf(stderr,"getvarx: FETCHVAR: fetchprojection: |%s|\n",dumpprojection(fetchprojection));
#endif

        /* Build the complete constraint to use in the fetch */
        fetchconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT);
        /* merged constraint just uses the url constraint selection */
        fetchconstraint->selections = dceclonelist(dapcomm->oc.dapconstraint->selections);
	/* and the created fetch projection */
        fetchconstraint->projections = nclistnew();
	nclistpush(fetchconstraint->projections,(void*)fetchprojection);
#ifdef DEBUG
fprintf(stderr,"getvarx: FETCHVAR: fetchconstraint: %s\n",dumpconstraint(fetchconstraint));
#endif
        /* buildcachenode3 will create a new cachenode and
           will also fetch the corresponding datadds.
        */
        ncstat = buildcachenode34(dapcomm,fetchconstraint,vars,&cachenode,0);
	fetchconstraint = NULL; /*buildcachenode34 takes control of fetchconstraint.*/
	if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
    } break;

    case FETCHPART: {
        /* Create fetch projection as the merge of the url projections
           and the vara projection */
        ncstat = daprestrictprojection(dapcomm->oc.dapconstraint->projections,
				       varaprojection,&fetchprojection);
	/* elide any sequence and string dimensions (dap servers do not allow such). */
	ncstat = removepseudodims(fetchprojection);
        if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}

	/* Shift the varaprojection for simple walk */
	dcefree((DCEnode*)walkprojection) ; /* reclaim any existing walkprojection */        
	walkprojection = (DCEprojection*)dceclone((DCEnode*)varaprojection);
        dapshiftprojection(walkprojection);

#ifdef DEBUG
fprintf(stderr,"getvarx: FETCHPART: fetchprojection: |%s|\n",dumpprojection(fetchprojection));
#endif

        /* Build the complete constraint to use in the fetch */
        fetchconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT);
        /* merged constraint just uses the url constraint selection */
        fetchconstraint->selections = dceclonelist(dapcomm->oc.dapconstraint->selections);
	/* and the created fetch projection */
        fetchconstraint->projections = nclistnew();
	nclistpush(fetchconstraint->projections,(void*)fetchprojection);
#ifdef DEBUG
fprintf(stderr,"getvarx: FETCHPART: fetchconstraint: %s\n",dumpconstraint(fetchconstraint));
#endif
        /* buildcachenode3 will create a new cachenode and
           will also fetch the corresponding datadds.
        */
        ncstat = buildcachenode34(dapcomm,fetchconstraint,vars,&cachenode,0);
	fetchconstraint = NULL; /*buildcachenode34 takes control of fetchconstraint.*/
	if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
    } break;

    default: PANIC1("unknown fetch state: %d\n",state);
    }

    ASSERT(cachenode != NULL);

#ifdef DEBUG
fprintf(stderr,"cache.datadds=%s\n",dumptree(cachenode->datadds));
#endif

    /* attach DATADDS to (constrained) DDS */
    unattach34(dapcomm->cdf.ddsroot);
    ncstat = attachsubset34(cachenode->datadds,dapcomm->cdf.ddsroot);
    if(ncstat) goto fail;	

    /* Fix up varainfo to use the cache */
    varainfo->cache = cachenode;
    cachenode = NULL;
    varainfo->varaprojection = walkprojection;
    walkprojection = NULL;

    /* Get the var correlate from the datadds */
    target = varainfo->target;
    xtarget = target->attachment;
    if(xtarget == NULL) 
	{THROWCHK(ncstat=NC_ENODATA); goto fail;}

    /* Switch to datadds tree space*/
    varainfo->target = xtarget;
save = (DCEnode*)varaprojection;
    ncstat = moveto(dapcomm,varainfo,varainfo->cache->datadds,data);
    if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}

    nclistfree(vars);
    dcefree((DCEnode*)varaprojection);
    dcefree((DCEnode*)fetchconstraint);
    freegetvara(varainfo);
fail:
    if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat);
    return THROW(ncstat);
}
Beispiel #18
0
/* Result is a pool string or a constant => do not free*/
char*
cdata_const(Constant* ci)
{
    Bytebuffer* codetmp = bbNew();
    char* result;

    switch (ci->nctype) {
    case NC_CHAR:
	{ 
	    char tmp[64];
	    tmp[0] = '\0';
	    escapifychar(ci->value.charv,tmp,'\'');
	    bbCat(codetmp,"'");
	    bbCat(codetmp,tmp);
	    bbCat(codetmp,"'");
	}
	break;
    case NC_BYTE:
	bbprintf(codetmp,"%hhd",ci->value.int8v);
	break;
    case NC_SHORT:
	bbprintf(codetmp,"%hd",ci->value.int16v);
	break;
    case NC_INT:
	bbprintf(codetmp,"%d",ci->value.int32v);
	break;
    case NC_FLOAT:
	bbprintf(codetmp,"%f",ci->value.floatv);
	break;
    case NC_DOUBLE:
	bbprintf(codetmp,"%lf",ci->value.doublev);
	break;
    case NC_UBYTE:
	    bbprintf(codetmp,"%hhu",ci->value.uint8v);
	break;
    case NC_USHORT:
	bbprintf(codetmp,"%hu",ci->value.uint16v);
	break;
    case NC_UINT:
	bbprintf(codetmp,"%uU",ci->value.uint32v);
	break;
    case NC_INT64:
	bbprintf(codetmp,"%lldLL",ci->value.int64v);
	break;
    case NC_UINT64:
	bbprintf(codetmp,"%lluLLU",ci->value.uint64v);
	break;
    case NC_ECONST:
	bbprintf(codetmp,"%s",cname(ci->value.enumv));
	break;
    case NC_STRING:
	{ /* handle separately */
	    char* escaped = escapify(ci->value.stringv.stringv,
				 '"',ci->value.stringv.len);
	    result = poolalloc(1+2+strlen(escaped));
	    strcpy(result,"\"");
	    strcat(result,escaped);
	    strcat(result,"\"");
	    goto done;
	}
	break;
    case NC_OPAQUE: {
	char* p;
	int bslen;
	bslen=(4*ci->value.opaquev.len);
	result = poolalloc(bslen+2+1);
	strcpy(result,"\"");
	p = ci->value.opaquev.stringv;
	while(*p) {
	    strcat(result,"\\x");
	    strncat(result,p,2);	    	    
	    p += 2;	
	}
	strcat(result,"\"");
	goto done;
	} break;

    default: PANIC1("ncstype: bad type code: %d",ci->nctype);
    }
    result = pooldup(bbContents(codetmp)); /*except for NC_STRING and NC_OPAQUE*/
    bbFree(codetmp);
done:
    return result;
}
Beispiel #19
0
/* Generate an instance of the basetype */
void
generate_basetype(Symbol* tsym, NCConstant* con, Bytebuffer* codebuf, Datalist* filler, Generator* generator)
{
    Datalist* data;

    switch (tsym->subclass) {

    case NC_ENUM:
    case NC_OPAQUE:
    case NC_PRIM:
	if(islistconst(con)) {
	    semerror(constline(con),"Expected primitive found {..}");
	}
	generate_primdata(tsym,con,codebuf,filler,generator);
	break;

    case NC_COMPOUND: {
	int i,uid, nfields, dllen;
	if(con == NULL || isfillconst(con)) {
	    Datalist* fill = (filler==NULL?getfiller(tsym):filler);
	    ASSERT(fill->length == 1);
	    con = &fill->data[0];
	    if(!islistconst(con))
	        semerror(con->lineno,"Compound data fill value is not enclosed in {..}");
	}
	if(!islistconst(con)) {/* fail on no compound*/
	    semerror(constline(con),"Compound data must be enclosed in {..}");
        }
	data = con->value.compoundv;
        nfields = listlength(tsym->subnodes);
	dllen = datalistlen(data);
	if(dllen > nfields) {
	    semerror(con->lineno,"Datalist longer than the number of compound fields");
	    break;
	}
	generator->listbegin(generator,LISTCOMPOUND,listlength(tsym->subnodes),codebuf,&uid);
        for(i=0;i<nfields;i++) {
            Symbol* field = (Symbol*)listget(tsym->subnodes,i);
	    con = datalistith(data,i);
	    generator->list(generator,LISTCOMPOUND,uid,i,codebuf);
            generate_basetype(field,con,codebuf,NULL,generator);
	}
	generator->listend(generator,LISTCOMPOUND,uid,i,codebuf);
	} break;

    case NC_VLEN: {
	Bytebuffer* vlenbuf;
        int uid;
	size_t count;

	if(con == NULL || isfillconst(con)) {
	    Datalist* fill = (filler==NULL?getfiller(tsym):filler);
	    ASSERT(fill->length == 1);
	    con = &fill->data[0];
	    if(con->nctype != NC_COMPOUND) {
	        semerror(con->lineno,"Vlen data fill value is not enclosed in {..}");
	    }
	}

	if(!islistconst(con)) {
	    semerror(constline(con),"Vlen data must be enclosed in {..}");
        }
        data = con->value.compoundv;
        /* generate the nc_vlen_t instance*/
	vlenbuf = bbNew();
	if(tsym->typ.basetype->typ.typecode == NC_CHAR) {
	    gen_charvlen(data,vlenbuf);
	    generator->vlenstring(generator,vlenbuf,&uid,&count);
	} else {
    	    generator->listbegin(generator,LISTVLEN,data->length,codebuf,&uid);
            for(count=0;count<data->length;count++) {
	      NCConstant* con;
   	        generator->list(generator,LISTVLEN,uid,count,vlenbuf);
		con = datalistith(data,count);
                generate_basetype(tsym->typ.basetype,con,vlenbuf,NULL,generator);
	    }
   	    generator->listend(generator,LISTVLEN,uid,count,codebuf,(void*)vlenbuf);
	}
	generator->vlendecl(generator,codebuf,tsym,uid,count,vlenbuf);
	bbFree(vlenbuf);
        } break;

    case NC_FIELD:
	if(tsym->typ.dimset.ndims > 0) {
	    /* Verify that we have a sublist (or fill situation) */
	    if(con != NULL && !isfillconst(con) && !islistconst(con))
		semerror(constline(con),"Dimensioned fields must be enclose in {...}");
            generate_fieldarray(tsym->typ.basetype,con,&tsym->typ.dimset,codebuf,filler,generator);
	} else {
	    generate_basetype(tsym->typ.basetype,con,codebuf,NULL,generator);
	}
	break;

    default: PANIC1("generate_basetype: unexpected subclass %d",tsym->subclass);
    }
}
Beispiel #20
0
static void
genbin_primdata(Symbol* basetype, Datasrc* src, Datalist* fillsrc,
		Bytebuffer* memory)
{
    Constant* prim;
    Constant target;

    prim = srcnext(src);

    if(prim == NULL || prim->nctype == NC_FILLVALUE) {
	genbin_fillvalue(basetype,fillsrc,src,memory);	
	return;
    }

    target.nctype = basetype->typ.typecode;

    if(prim == NULL) {
#ifdef GENFILL
        /* generate a fill value*/
	nc_getfill(&target);
	/* fall thru*/
#else
	return;	
#endif
    }

    ASSERT(prim->nctype != NC_COMPOUND);

    if(target.nctype != NC_ECONST) {
	convert1(prim,&target);
        alignbuffer(&target,memory);
    }

    switch (target.nctype) {
        case NC_ECONST:
	    if(basetype->subclass != NC_ENUM) {
	        semerror(prim->lineno,"Conversion to enum not supported (yet)");
	    } else {
		Datalist* econ = builddatalist(1);
		srcpushlist(src,econ);
		dlappend(econ,&prim->value.enumv->typ.econst);
	        genbin_primdata(prim->value.enumv->typ.basetype,src,
				fillsrc,memory);
		srcpop(src);
	    }
   	    break;
        case NC_OPAQUE: {
	    unsigned char* bytes;
	    size_t len;
	    setprimlength(&target,basetype->typ.size*2);
	    bytes=makebytestring(target.value.opaquev.stringv,&len);
	    bbAppendn(memory,(void*)bytes,len);
	    } break;

        case NC_CHAR:
            bbAppendn(memory,&target.value.charv,sizeof(target.value.charv));
	    break;
        case NC_BYTE:
            bbAppendn(memory,(void*)&target.value.int8v,sizeof(target.value.int8v));
	    break;
        case NC_SHORT:
            bbAppendn(memory,(void*)&target.value.int16v,sizeof(target.value.int16v));
	    break;
        case NC_INT:
            bbAppendn(memory,(void*)&target.value.int32v,sizeof(target.value.int32v));
	    break;
        case NC_FLOAT:
            bbAppendn(memory,(void*)&target.value.floatv,sizeof(target.value.floatv));
	    break;
        case NC_DOUBLE:
            bbAppendn(memory,(void*)&target.value.doublev,sizeof(target.value.doublev));
	    break;
        case NC_UBYTE:
            bbAppendn(memory,(void*)&target.value.uint8v,sizeof(target.value.uint8v));
	    break;
        case NC_USHORT:
            bbAppendn(memory,(void*)&target.value.uint16v,sizeof(target.value.uint16v));
	    break;
        case NC_UINT:
            bbAppendn(memory,(void*)&target.value.uint32v,sizeof(target.value.uint32v));
	    break;
        case NC_INT64: {
	    union SI64 { char ch[8]; long long i64;} si64;
	    si64.i64 = target.value.int64v;
            bbAppendn(memory,(void*)si64.ch,sizeof(si64.ch));
	    } break;
        case NC_UINT64: {
	    union SU64 { char ch[8]; unsigned long long i64;} su64;
	    su64.i64 = target.value.uint64v;
            bbAppendn(memory,(void*)su64.ch,sizeof(su64.ch));
	    } break;
        case NC_STRING: {
            if(usingclassic) {
                bbAppendn(memory,target.value.stringv.stringv,target.value.stringv.len);
            } else if(target.nctype == NC_CHAR) {
                bbAppendn(memory,target.value.stringv.stringv,target.value.stringv.len);
            } else {
                char* ptr;
                int len = (size_t)target.value.stringv.len;
                ptr = poolalloc(len+1); /* CAREFUL: this has short lifetime*/
                memcpy(ptr,target.value.stringv.stringv,len);
                ptr[len] = '\0';
                bbAppendn(memory,(void*)&ptr,sizeof(ptr));
            }
        } break;

        default: PANIC1("genbin_primdata: unexpected type: %d",target.nctype);
    }
}
Beispiel #21
0
/*
Figure out the names for variables.
*/
NCerror
computecdfvarnames(NCDAPCOMMON* nccomm, CDFnode* root, NClist* varnodes)
{
    unsigned int i,j,d;

    /* clear all elided marks; except for dataset and grids */
    for(i=0; i<nclistlength(root->tree->nodes); i++) {
        CDFnode* node = (CDFnode*)nclistget(root->tree->nodes,i);
        node->elided = 0;
        if(node->nctype == NC_Grid || node->nctype == NC_Dataset)
            node->elided = 1;
    }

    /* ensure all variables have an initial full name defined */
    for(i=0; i<nclistlength(varnodes); i++) {
        CDFnode* var = (CDFnode*)nclistget(varnodes,i);
        nullfree(var->ncfullname);
        var->ncfullname = makecdfpathstring(var,nccomm->cdf.separator);
#ifdef DEBUG2
        fprintf(stderr,"var names: %s %s %s\n",
                var->ocname,var->ncbasename,var->ncfullname);
#endif
    }

    /*  unify all variables with same fullname and dimensions
    basevar fields says: "for duplicate grid variables";
        when does this happen?
    */
    if(FLAGSET(nccomm->controls,NCF_NC3)) {
        for(i=0; i<nclistlength(varnodes); i++) {
            int match;
            CDFnode* var = (CDFnode*)nclistget(varnodes,i);
            for(j=0; j<i; j++) {
                CDFnode* testnode = (CDFnode*)nclistget(varnodes,j);
                match = 1;
                if(testnode->array.basevar != NULL)
                    continue; /* already processed */
                if(strcmp(var->ncfullname,testnode->ncfullname) != 0)
                    match = 0;
                else if(nclistlength(testnode->array.dimsetall)
                        != nclistlength(var->array.dimsetall))
                    match = 0;
                else for(d=0; d<nclistlength(testnode->array.dimsetall); d++) {
                        CDFnode* vdim = (CDFnode*)nclistget(var->array.dimsetall,d);
                        CDFnode* tdim = (CDFnode*)nclistget(testnode->array.dimsetall,d);
                        if(vdim->dim.declsize != tdim->dim.declsize) {
                            match = 0;
                            break;
                        }
                    }
                if(match) {
                    testnode->array.basevar = var;
                    fprintf(stderr,"basevar invoked: %s\n",var->ncfullname);
                }
            }
        }
    }

    /* Finally, verify unique names */
    for(i=0; i<nclistlength(varnodes); i++) {
        CDFnode* var1 = (CDFnode*)nclistget(varnodes,i);
        if(var1->array.basevar != NULL) continue;
        for(j=0; j<i; j++) {
            CDFnode* var2 = (CDFnode*)nclistget(varnodes,j);
            if(var2->array.basevar != NULL) continue;
            if(strcmp(var1->ncfullname,var2->ncfullname)==0) {
                PANIC1("duplicate var names: %s",var1->ncfullname);
            }
        }
    }
    return NC_NOERR;
}
Beispiel #22
0
NCerror
dapcvtattrval(nc_type etype, void* dst, NClist* src)
{
    int i,ok;
    NCerror  ncstat = NC_NOERR;
    unsigned int memsize = nctypesizeof(etype);
    unsigned int nvalues = nclistlength(src);
    char* dstmem = (char*)dst;

    for(i=0;i<nvalues;i++) {
	char* s = (char*)nclistget(src,i);
	size_t slen = strlen(s);
        int nread = 0; /* # of chars read by sscanf */

	ok = 0;
	switch (etype) {
	case NC_BYTE: {
		char tmp[128];
		
		unsigned char* p = (unsigned char*)dstmem;
#ifdef _MSC_VER
		ok = sscanf(s,"%hC%n",p,&nread);
		_ASSERTE(_CrtCheckMemory());
#else	
		ok = sscanf(s,"%hhu%n",p,&nread);
#endif
	    } break;
	case NC_CHAR: {
	    signed char* p = (signed char*)dstmem;
	    ok = sscanf(s,"%c%n",p,&nread);
	    } break;
	case NC_SHORT: {
	    short* p = (short*)dstmem;
	    ok = sscanf(s,"%hd%n",p,&nread);
	    } break;
	case NC_INT: {
	    int* p = (int*)dstmem;
	    ok = sscanf(s,"%d%n",p,&nread);
	    } break;
	case NC_FLOAT: {
	    float* p = (float*)dstmem;
	    ok = sscanf(s,"%g%n",p,&nread);
	    } break;
	case NC_DOUBLE: {
	    double* p = (double*)dstmem;
	    ok = sscanf(s,"%lg%n",p,&nread);
	    } break;
	case NC_UBYTE: {
	    unsigned char* p = (unsigned char*)dstmem;
#ifdef _MSC_VER
		ok = sscanf(s, "%hc%n", p,&nread);
		_ASSERTE(_CrtCheckMemory());
#else
	    ok = sscanf(s,"%hhu%n",p,&nread);
#endif
		} break;
	case NC_USHORT: {
	    unsigned short* p = (unsigned short*)dstmem;
	    ok = sscanf(s,"%hu%n",p,&nread);
	    } break;
	case NC_UINT: {
	    unsigned int* p = (unsigned int*)dstmem;
	    ok = sscanf(s,"%u%n",p,&nread);
	    } break;
	case NC_INT64: {
	    long long* p = (long long*)dstmem;
#ifdef _MSC_VER
		ok = sscanf(s, "%I64d%n", p,&nread);
#else
		ok = sscanf(s,"%lld%n",p,&nread);
#endif
	} break;
	case NC_UINT64: {
	    unsigned long long* p = (unsigned long long*)dstmem;
	    ok = sscanf(s,"%llu%n",p,&nread);
	    } break;
	case NC_STRING: case NC_URL: {
	    char** p = (char**)dstmem;
	    *p = nulldup(s);
	    ok = 1;
	    } break;
	default:
   	    PANIC1("unexpected nc_type: %d",(int)etype);
	}
	if(ok != 1 || nread != slen) {ncstat = NC_EINVAL; goto done;}
	dstmem += memsize;
    }
done:
    return THROW(ncstat);
}
Beispiel #23
0
static int
c_constant(Generator* generator, NCConstant* con, Bytebuffer* buf,...)
{
    Bytebuffer* codetmp = bbNew();
    char* special = NULL;

    switch (con->nctype) {
    case NC_CHAR:
	if(con->value.charv == '\'') 
	    bbprintf(codetmp,"'\\''");
	else
	    bbprintf(codetmp,"'%s'",cescapifychar(con->value.charv,'\''));
	break;
    case NC_BYTE:
	bbprintf(codetmp,"%hhd",con->value.int8v);
	break;
    case NC_SHORT:
	bbprintf(codetmp,"%hd",con->value.int16v);
	break;
    case NC_INT:
	bbprintf(codetmp,"%d",con->value.int32v);
	break;
    case NC_FLOAT:
	/* Special case for nanf */
	if(isnan(con->value.floatv))
	    bbprintf(codetmp,"nanf");
	else
	    bbprintf(codetmp,"%f",con->value.floatv);
	break;
    case NC_DOUBLE:
	/* Special case for nan */
	if(isnan(con->value.doublev))
	    bbprintf(codetmp,"nan");
	else
	    bbprintf(codetmp,"%lf",con->value.doublev);
	break;
    case NC_UBYTE:
        bbprintf(codetmp,"%hhu",con->value.uint8v);
	break;
    case NC_USHORT:
	bbprintf(codetmp,"%hu",con->value.uint16v);
	break;
    case NC_UINT:
	bbprintf(codetmp,"%uU",con->value.uint32v);
	break;
    case NC_INT64:
	bbprintf(codetmp,"%lldLL",con->value.int64v);
	break;
    case NC_UINT64:
	bbprintf(codetmp,"%lluLLU",con->value.uint64v);
	break;
    case NC_ECONST:
	bbprintf(codetmp,"%s",cname(con->value.enumv));
	break;
    case NC_NIL:
    case NC_STRING: { /* handle separately */
	if(con->value.stringv.len == 0 && con->value.stringv.stringv == NULL) {
            bbprintf(codetmp,"NULL");
	} else {
	    char* escaped = escapify(con->value.stringv.stringv,
				 '"',con->value.stringv.len);
	    special = poolalloc(1+2+strlen(escaped));
	    strcpy(special,"\"");
	    strcat(special,escaped);
	    strcat(special,"\"");
	}
	} break;
    case NC_OPAQUE: {
	char* p;
	int bslen;
	bslen=(4*con->value.opaquev.len);
	special = poolalloc(bslen+2+1);
	strcpy(special,"\"");
	p = con->value.opaquev.stringv;
	while(*p) {
	    strcat(special,"\\x");
	    strncat(special,p,2);	    	    
	    p += 2;	
	}
	strcat(special,"\"");
	} break;

    default: PANIC1("ncstype: bad type code: %d",con->nctype);

    }
    if(special == NULL)
        bbCatbuf(buf,codetmp);
    else
	bbCat(buf,special);
    bbFree(codetmp);
    return 1;
}
Beispiel #24
0
/* Compute type sizes and compound offsets*/
void
computesize(Symbol* tsym)
{
    int i;
    int offset = 0;
    int largealign;
    unsigned long totaldimsize;
    if(tsym->touched) return;
    tsym->touched=1;
    switch (tsym->subclass) {
        case NC_VLEN: /* actually two sizes for vlen*/
	    computesize(tsym->typ.basetype); /* first size*/
	    tsym->typ.size = ncsize(tsym->typ.typecode);
	    tsym->typ.alignment = ncaux_class_alignment(tsym->typ.typecode);
	    tsym->typ.nelems = 1; /* always a single compound datalist */
	    break;
	case NC_PRIM:
	    tsym->typ.size = ncsize(tsym->typ.typecode);
	    tsym->typ.alignment = ncaux_class_alignment(tsym->typ.typecode);
	    tsym->typ.nelems = 1;
	    break;
	case NC_OPAQUE:
	    /* size and alignment already assigned*/
	    tsym->typ.nelems = 1;
	    break;
	case NC_ENUM:
	    computesize(tsym->typ.basetype); /* first size*/
	    tsym->typ.size = tsym->typ.basetype->typ.size;
	    tsym->typ.alignment = tsym->typ.basetype->typ.alignment;
	    tsym->typ.nelems = 1;
	    break;
	case NC_COMPOUND: /* keep if all fields are primitive*/
	    /* First, compute recursively, the size and alignment of fields*/
            for(i=0;i<listlength(tsym->subnodes);i++) {
		Symbol* field = (Symbol*)listget(tsym->subnodes,i);
                ASSERT(field->subclass == NC_FIELD);
		computesize(field);
		if(i==0) tsym->typ.alignment = field->typ.alignment;
            }
            /* now compute the size of the compound based on what user specified*/
            offset = 0;
            largealign = 1;
            for(i=0;i<listlength(tsym->subnodes);i++) {
                Symbol* field = (Symbol*)listget(tsym->subnodes,i);
                /* only support 'c' alignment for now*/
                int alignment = field->typ.alignment;
                int padding = getpadding(offset,alignment);
                offset += padding;
                field->typ.offset = offset;
                offset += field->typ.size;
                if (alignment > largealign) {
                    largealign = alignment;
                }
            }
	    tsym->typ.cmpdalign = largealign; /* total structure size alignment */
            offset += (offset % largealign);
	    tsym->typ.size = offset;
	    break;
        case NC_FIELD: /* Compute size assume no unlimited dimensions*/
	    if(tsym->typ.dimset.ndims > 0) {
	        computesize(tsym->typ.basetype);
	        totaldimsize = crossproduct(&tsym->typ.dimset,0,rankfor(&tsym->typ.dimset));
	        tsym->typ.size = tsym->typ.basetype->typ.size * totaldimsize;
	        tsym->typ.alignment = tsym->typ.basetype->typ.alignment;
	        tsym->typ.nelems = 1;
	    } else {
	        tsym->typ.size = tsym->typ.basetype->typ.size;
	        tsym->typ.alignment = tsym->typ.basetype->typ.alignment;
	        tsym->typ.nelems = tsym->typ.basetype->typ.nelems;
	    }
	    break;
	default:
	    PANIC1("computesize: unexpected type class: %d",tsym->subclass);
	    break;
    }
}
Beispiel #25
0
static int
j_constant(Generator* generator, Symbol* sym, NCConstant* con, Bytebuffer* buf,...)
{
    Bytebuffer* codetmp = bbNew();
    char* special = NULL;

    switch (con->nctype) {
    case NC_CHAR:
	if(con->value.charv == '\'') 
	    bbprintf(codetmp,"'\\''");
	else
	    bbprintf(codetmp,"'%c'",con->value.charv);
	break;
    case NC_BYTE:
	bbprintf(codetmp,"%hhd",con->value.int8v);
	break;
    case NC_SHORT:
	bbprintf(codetmp,"%hd",con->value.int16v);
	break;
    case NC_INT:
	bbprintf(codetmp,"%d",con->value.int32v);
	break;
    case NC_FLOAT:
	/* Special case for nan */
	if(isnan(con->value.floatv))
	    bbprintf(codetmp,"Float.NaN");
	else
	    bbprintf(codetmp,"%f",con->value.floatv);
	break;
    case NC_DOUBLE:
	/* Special case for nan */
	if(isnan(con->value.doublev))
	    bbprintf(codetmp,"Double.NaN");
	else
	    bbprintf(codetmp,"%lf",con->value.doublev);
	break;
    case NC_UBYTE:
        bbprintf(codetmp,"%hhu",con->value.uint8v);
	break;
    case NC_USHORT:
	bbprintf(codetmp,"%hu",con->value.uint16v);
	break;
    case NC_UINT:
	bbprintf(codetmp,"%uU",con->value.uint32v);
	break;
    case NC_INT64:
	bbprintf(codetmp,"%lldLL",con->value.int64v);
	break;
    case NC_UINT64:
	bbprintf(codetmp,"%lluLLU",con->value.uint64v);
	break;
    case NC_STRING: { /* handle separately */
	char* escaped = escapify(con->value.stringv.stringv,
				 '"',con->value.stringv.len);
	special = poolalloc(1+2+strlen(escaped));
	strcpy(special,"\"");
	strcat(special,escaped);
	strcat(special,"\"");
	} break;

    default: PANIC1("ncstype: bad type code: %d",con->nctype);

    }
    if(special == NULL)
        bbCatbuf(buf,codetmp);
    else
	bbCat(buf,special);
    bbFree(codetmp);
    return 1;
}
Beispiel #26
0
Symbol*
locate(Symbol* refsym)
{
    Symbol* sym = NULL;
    switch (refsym->objectclass) {
    case NC_DIM:
	if(refsym->is_prefixed) {
	    /* locate exact dimension specified*/
	    sym = lookup(NC_DIM,refsym);
	} else { /* Search for matching dimension in all parent groups*/
	    Symbol* parent = lookupgroup(refsym->prefix);/*get group for refsym*/
	    while(parent != NULL) {
		/* search this parent for matching name and type*/
		sym = lookupingroup(NC_DIM,refsym->name,parent);
		if(sym != NULL) break;
		parent = parent->container;
	    }
	}
	break;
    case NC_TYPE:
	if(refsym->is_prefixed) {
	    /* locate exact type specified*/
	    sym = lookup(NC_TYPE,refsym);
	} else {
	    Symbol* parent;
	    int i; /* Search for matching type in all groups (except...)*/
	    /* Short circuit test for primitive types*/
	    for(i=NC_NAT;i<=NC_STRING;i++) {
		Symbol* prim = basetypefor(i);
		if(prim == NULL) continue;
	        if(strcmp(refsym->name,prim->name)==0) {
		    sym = prim;
		    break;
		}
	    }
	    if(sym == NULL) {
	        /* Added 5/26/09: look in parent hierarchy first */
	        parent = lookupgroup(refsym->prefix);/*get group for refsym*/
	        while(parent != NULL) {
		    /* search this parent for matching name and type*/
		    sym = lookupingroup(NC_TYPE,refsym->name,parent);
		    if(sym != NULL) break;
		    parent = parent->container;
		}
	    }
	    if(sym == NULL) {
	        sym = uniquetreelocate(refsym,rootgroup); /* want unique */
	    }
	}
	break;
    case NC_VAR:
	if(refsym->is_prefixed) {
	    /* locate exact variable specified*/
	    sym = lookup(NC_VAR,refsym);
	} else {
	    Symbol* parent = lookupgroup(refsym->prefix);/*get group for refsym*/
   	    /* search this parent for matching name and type*/
	    sym = lookupingroup(NC_VAR,refsym->name,parent);
	}
        break;
    case NC_GRP:
	if(refsym->is_prefixed) {
	    /* locate exact group specified*/
	    sym = lookup(NC_GRP,refsym);
	} else {
 	    Symbol* parent = lookupgroup(refsym->prefix);/*get group for refsym*/
   	    /* search this parent for matching name and type*/
	    sym = lookupingroup(NC_GRP,refsym->name,parent);
	}
	break;

    default: PANIC1("locate: bad refsym type: %d",refsym->objectclass);
    }
    if(debug > 1) {
	char* ncname;
	if(refsym->objectclass == NC_TYPE)
	    ncname = ncclassname(refsym->subclass);
	else
	    ncname = ncclassname(refsym->objectclass);
	fdebug("locate: %s: %s -> %s\n",
		ncname,fullname(refsym),(sym?fullname(sym):"NULL"));
    }
    return sym;
}
Beispiel #27
0
NCerror
dapcvtattrval3(nc_type etype, void* dst, NClist* src)
{
    int i,ok;
    NCerror  ncstat = NC_NOERR;
    unsigned int memsize = nctypesizeof(etype);
    unsigned int nvalues = nclistlength(src);
    char* dstmem = (char*)dst;

    for(i=0;i<nvalues;i++) {
	char* s = (char*)nclistget(src,i);
	ok = 0;
	switch (etype) {
	case NC_BYTE: {
	    unsigned char* p = (unsigned char*)dstmem;
	    ok = sscanf(s,"%hhu",p);
	    } break;
	case NC_CHAR: {
	    signed char* p = (signed char*)dstmem;
	    ok = sscanf(s,"%c",p);
	    } break;
	case NC_SHORT: {
	    short* p = (short*)dstmem;
	    ok = sscanf(s,"%hd",p);
	    } break;
	case NC_INT: {
	    int* p = (int*)dstmem;
	    ok = sscanf(s,"%d",p);
	    } break;
	case NC_FLOAT: {
	    float* p = (float*)dstmem;
	    ok = sscanf(s,"%g",p);
	    } break;
	case NC_DOUBLE: {
	    double* p = (double*)dstmem;
	    ok = sscanf(s,"%lg",p);
	    } break;
	case NC_UBYTE: {
	    unsigned char* p = (unsigned char*)dstmem;
	    ok = sscanf(s,"%hhu",p);
	    } break;
	case NC_USHORT: {
	    unsigned short* p = (unsigned short*)dstmem;
	    ok = sscanf(s,"%hu",p);
	    } break;
	case NC_UINT: {
	    unsigned int* p = (unsigned int*)dstmem;
	    ok = sscanf(s,"%u",p);
	    } break;
	case NC_INT64: {
	    long long* p = (long long*)dstmem;
	    ok = sscanf(s,"%lld",p);
	    } break;
	case NC_UINT64: {
	    unsigned long long* p = (unsigned long long*)dstmem;
	    ok = sscanf(s,"%llu",p);
	    } break;
	case NC_STRING: case NC_URL: {
	    char** p = (char**)dstmem;
	    *p = nulldup(s);
	    ok = 1;
	    } break;
	default:
   	    PANIC1("unexpected nc_type: %d",(int)etype);
	}
	if(ok != 1) {ncstat = NC_EINVAL; goto done;}
	dstmem += memsize;
    }
done:
    return THROW(ncstat);
}
Beispiel #28
0
static int
bin_constant(Generator* generator, Symbol* sym, NCConstant* con, Bytebuffer* buf,...)
{
    if(con->nctype != NC_ECONST) {
        alignbuffer(con,buf);
    }
    switch (con->nctype) {
    case NC_OPAQUE: {
        unsigned char* bytes = NULL;
        size_t len;
	/* Assume the opaque string has been normalized */
        bytes=makebytestring(con->value.opaquev.stringv,&len);
        bbAppendn(buf,(void*)bytes,len);
	efree(bytes);
    } break;
    case NC_CHAR:
        bbAppendn(buf,&con->value.charv,sizeof(con->value.charv));
        break;
    case NC_BYTE:
        bbAppendn(buf,(void*)&con->value.int8v,sizeof(con->value.int8v));
        break;
    case NC_SHORT:
        bbAppendn(buf,(void*)&con->value.int16v,sizeof(con->value.int16v));
        break;
    case NC_INT:
        bbAppendn(buf,(void*)&con->value.int32v,sizeof(con->value.int32v));
        break;
    case NC_FLOAT:
        bbAppendn(buf,(void*)&con->value.floatv,sizeof(con->value.floatv));
        break;
    case NC_DOUBLE:
        bbAppendn(buf,(void*)&con->value.doublev,sizeof(con->value.doublev));
        break;
    case NC_UBYTE:
        bbAppendn(buf,(void*)&con->value.uint8v,sizeof(con->value.uint8v));
        break;
    case NC_USHORT:
        bbAppendn(buf,(void*)&con->value.uint16v,sizeof(con->value.uint16v));
        break;
    case NC_UINT:
        bbAppendn(buf,(void*)&con->value.uint32v,sizeof(con->value.uint32v));
        break;
    case NC_INT64: {
        union SI64 { char ch[8]; long long i64;} si64;
        si64.i64 = con->value.int64v;
        bbAppendn(buf,(void*)si64.ch,sizeof(si64.ch));
        } break;
    case NC_UINT64: {
        union SU64 { char ch[8]; unsigned long long i64;} su64;
        su64.i64 = con->value.uint64v;
        bbAppendn(buf,(void*)su64.ch,sizeof(su64.ch));
        } break;
    case NC_NIL:
    case NC_STRING: {
        int len = (size_t)con->value.stringv.len;
	if(len == 0 && con->value.stringv.stringv == NULL) {
	    char* nil = NULL;
            bbAppendn(buf,(void*)&nil,sizeof(nil));
	} else {
            char* ptr = (char*)ecalloc(len+1);
	    memcpy(ptr,con->value.stringv.stringv,len);
	    ptr[len] = '\0';
            bbAppendn(buf,(void*)&ptr,sizeof(ptr));
	    ptr = NULL;
        }
	} break;

    default: PANIC1("bin_constant: unexpected type: %d",con->nctype);
    }
    return 1;
}
Beispiel #29
0
static NCerror
buildcdftreer(NCDAPCOMMON* nccomm, OCddsnode ocnode, CDFnode* container,
                CDFtree* tree, CDFnode** cdfnodep)
{
    size_t i,ocrank,ocnsubnodes;
    OCtype octype;
    OCtype ocatomtype;
    char* ocname = NULL;
    NCerror ncerr = NC_NOERR;
    CDFnode* cdfnode = NULL;

    oc_dds_class(nccomm->oc.conn,ocnode,&octype);
    if(octype == OC_Atomic)
	oc_dds_atomictype(nccomm->oc.conn,ocnode,&ocatomtype);
    else
	ocatomtype = OC_NAT;
    oc_dds_name(nccomm->oc.conn,ocnode,&ocname);
    oc_dds_rank(nccomm->oc.conn,ocnode,&ocrank);
    oc_dds_nsubnodes(nccomm->oc.conn,ocnode,&ocnsubnodes);

#ifdef DEBUG1
    if(ocatomtype == OC_NAT)
	fprintf(stderr,"buildcdftree: connect: %s %s\n",oc_typetostring(octype),ocname);
    else
	fprintf(stderr,"buildcdftree: connect: %s %s\n",oc_typetostring(ocatomtype),ocname);
#endif

    switch (octype) {
    case OC_Dataset:
	cdfnode = makecdfnode(nccomm,ocname,octype,ocnode,container);
	nclistpush(tree->nodes,(void*)cdfnode);
	tree->root = cdfnode;
	cdfnode->tree = tree;
	break;

    case OC_Grid:
    case OC_Structure:
    case OC_Sequence:
	cdfnode = makecdfnode(nccomm,ocname,octype,ocnode,container);
	nclistpush(tree->nodes,(void*)cdfnode);
#if 0
	if(tree->root == NULL) {
	    tree->root = cdfnode;
	    cdfnode->tree = tree;
	}
#endif
	break;

    case OC_Atomic:
	cdfnode = makecdfnode(nccomm,ocname,octype,ocnode,container);
	nclistpush(tree->nodes,(void*)cdfnode);
#if 0
	if(tree->root == NULL) {
	    tree->root = cdfnode;
	    cdfnode->tree = tree;
	}
#endif
	break;

    case OC_Dimension:
    default: PANIC1("buildcdftree: unexpect OC node type: %d",(int)octype);

    }
    /* Avoid a rare but perhaps possible null-dereference
       of cdfnode. Not sure what error to throw, so using
       NC_EDAP: generic DAP error. */
    if(!cdfnode) {
      return NC_EDAP;
    }

#if 0
    /* cross link */
    assert(tree->root != NULL);
    cdfnode->root = tree->root;
#endif

    if(ocrank > 0) defdimensions(ocnode,cdfnode,nccomm,tree);
    for(i=0;i<ocnsubnodes;i++) {
	OCddsnode ocsubnode;
	CDFnode* subnode;
	oc_dds_ithfield(nccomm->oc.conn,ocnode,i,&ocsubnode);
	ncerr = buildcdftreer(nccomm,ocsubnode,cdfnode,tree,&subnode);
	if(ncerr) {
	  if(ocname) free(ocname);
	  return ncerr;
	}
	nclistpush(cdfnode->subnodes,(void*)subnode);
    }
    nullfree(ocname);
    if(cdfnodep) *cdfnodep = cdfnode;
    return ncerr;
}
Beispiel #30
0
static void
dumpdataprim(NCConstant* ci, Bytebuffer* buf)
{
    char tmp[64];
    ASSERT(isprimplus(ci->nctype) || ci->nctype == NC_FILLVALUE);
    switch (ci->nctype) {
    case NC_CHAR: {
	bbCat(buf,"'");
	escapifychar(ci->value.charv,tmp,'\'');
	bbCat(buf,tmp);
	bbCat(buf,"'");
	} break;
    case NC_BYTE:
	sprintf(tmp,"%hhd",ci->value.int8v);
	bbCat(buf,tmp);
	break;
    case NC_SHORT:
	sprintf(tmp,"%hd",ci->value.int16v);
	bbCat(buf,tmp);
	break;
    case NC_INT:
	sprintf(tmp,"%d",ci->value.int32v);
	bbCat(buf,tmp);
	break;
    case NC_FLOAT:
	sprintf(tmp,"%g",ci->value.floatv);
	bbCat(buf,tmp);
	break;
    case NC_DOUBLE:
	sprintf(tmp,"%lg",ci->value.doublev);
	bbCat(buf,tmp);
	break;
    case NC_UBYTE:
	sprintf(tmp,"%hhu",ci->value.int8v);
	bbCat(buf,tmp);
	break;
    case NC_USHORT:
	sprintf(tmp,"%hu",ci->value.uint16v);
	bbCat(buf,tmp);
	break;
    case NC_UINT:
	sprintf(tmp,"%u",ci->value.uint32v);
	bbCat(buf,tmp);
	break;
    case NC_INT64:
	sprintf(tmp,"%lld",ci->value.int64v);
	bbCat(buf,tmp);
	break;
    case NC_UINT64:
	sprintf(tmp,"%llu",ci->value.uint64v);
	bbCat(buf,tmp);
	break;
    case NC_ECONST:
	sprintf(tmp,"%s",ci->value.enumv->fqn);
	bbCat(buf,tmp);
	break;
    case NC_STRING:
	bbCat(buf,"\"");
	bbCat(buf,ci->value.stringv.stringv);
	bbCat(buf,"\"");
	break;
    case NC_OPAQUE:
	bbCat(buf,"0x");
	bbCat(buf,ci->value.opaquev.stringv);
	break;
    case NC_FILLVALUE:
	bbCat(buf,"_");
	break;
    default: PANIC1("dumpdataprim: bad type code:%d",ci->nctype);
    }
}