netcdf-c/ncgen/cdata.c

218 lines
5.0 KiB
C
Raw Normal View History

2010-06-03 21:24:43 +08:00
/*********************************************************************
* Copyright 2009, UCAR/Unidata
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
*********************************************************************/
#include "includes.h"
#include "nc_iter.h"
2010-06-03 21:24:43 +08:00
#ifdef ENABLE_C
#include <math.h>
static int c_uid = 0;
static int
c_charconstant(Generator* generator, Bytebuffer* codebuf, ...)
2010-06-03 21:24:43 +08:00
{
/* Escapes and quoting will be handled in genc_write */
/* Just transfer charbuf to codebuf */
Bytebuffer* charbuf;
va_list ap;
vastart(ap,codebuf);
charbuf = va_arg(ap, Bytebuffer*);
va_end(ap);
bbNull(charbuf);
bbCatbuf(codebuf,charbuf);
return 1;
2010-06-03 21:24:43 +08:00
}
static int
c_constant(Generator* generator, NCConstant* con, Bytebuffer* buf,...)
2010-06-03 21:24:43 +08:00
{
Bytebuffer* codetmp = bbNew();
char* special = NULL;
2010-06-03 21:24:43 +08:00
switch (con->nctype) {
case NC_CHAR:
if(con->value.charv == '\'')
bbprintf(codetmp,"'\\''");
else
bbprintf(codetmp,"'%s'",cescapifychar(con->value.charv,'\''));
break;
2010-06-03 21:24:43 +08:00
case NC_BYTE:
bbprintf(codetmp,"%hhd",con->value.int8v);
2010-06-03 21:24:43 +08:00
break;
case NC_SHORT:
bbprintf(codetmp,"%hd",con->value.int16v);
2010-06-03 21:24:43 +08:00
break;
case NC_INT:
bbprintf(codetmp,"%d",con->value.int32v);
2010-06-03 21:24:43 +08:00
break;
case NC_FLOAT:
/* Special case for nanf */
if(isnan(con->value.floatv))
bbprintf(codetmp,"nanf");
else
bbprintf(codetmp,"%f",con->value.floatv);
2010-06-03 21:24:43 +08:00
break;
case NC_DOUBLE:
/* Special case for nan */
if(isnan(con->value.doublev))
bbprintf(codetmp,"nan");
else
bbprintf(codetmp,"%lf",con->value.doublev);
2010-06-03 21:24:43 +08:00
break;
case NC_UBYTE:
2015-11-20 04:44:07 +08:00
bbprintf(codetmp,"%hhuU",con->value.uint8v);
2010-06-03 21:24:43 +08:00
break;
case NC_USHORT:
2015-11-20 04:44:07 +08:00
bbprintf(codetmp,"%huU",con->value.uint16v);
2010-06-03 21:24:43 +08:00
break;
case NC_UINT:
bbprintf(codetmp,"%uU",con->value.uint32v);
2010-06-03 21:24:43 +08:00
break;
case NC_INT64:
bbprintf(codetmp,"%lldLL",con->value.int64v);
2010-06-03 21:24:43 +08:00
break;
case NC_UINT64:
2015-11-20 04:44:07 +08:00
bbprintf(codetmp,"%lluULL",con->value.uint64v);
2010-06-03 21:24:43 +08:00
break;
case NC_ECONST:
bbprintf(codetmp,"%s",cname(con->value.enumv));
2010-06-03 21:24:43 +08:00
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;
2010-06-03 21:24:43 +08:00
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;
2010-06-03 21:24:43 +08:00
while(*p) {
strcat(special,"\\x");
strncat(special,p,2);
2010-06-03 21:24:43 +08:00
p += 2;
}
strcat(special,"\"");
2010-06-03 21:24:43 +08:00
} break;
default: PANIC1("ncstype: bad type code: %d",con->nctype);
2010-06-03 21:24:43 +08:00
}
if(special == NULL)
bbCatbuf(buf,codetmp);
else
bbCat(buf,special);
2010-06-03 21:24:43 +08:00
bbFree(codetmp);
return 1;
}
static int
c_listbegin(Generator* generator, ListClass lc, size_t size, Bytebuffer* codebuf, int* uidp, ...)
{
if(uidp) *uidp = ++c_uid;
switch (lc) {
case LISTVLEN:
case LISTATTR:
case LISTDATA:
break;
case LISTFIELDARRAY:
case LISTCOMPOUND:
bbAppend(codebuf,'{');
break;
}
return 1;
}
static int
c_list(Generator* generator, ListClass lc, int uid, size_t count, Bytebuffer* codebuf, ...)
{
switch (lc) {
case LISTVLEN:
case LISTATTR:
if(count > 0) bbCat(codebuf,", ");
break;
case LISTDATA:
case LISTCOMPOUND:
case LISTFIELDARRAY:
bbAppend(codebuf,' ');
break;
}
return 1;
}
static int
c_listend(Generator* generator, ListClass lc, int uid, size_t count, Bytebuffer* buf, ...)
{
switch (lc) {
case LISTCOMPOUND:
case LISTFIELDARRAY:
bbAppend(buf,'}');
break;
case LISTDATA:
case LISTVLEN:
case LISTATTR:
break;
}
return 1;
2010-06-03 21:24:43 +08:00
}
static int
c_vlendecl(Generator* generator, Bytebuffer* codebuf, Symbol* tsym, int uid, size_t count, ...)
{
/* Build a bytebuffer to capture the vlen decl */
List* declstack = (List*)generator->state;
Bytebuffer* decl = bbNew();
Bytebuffer* vlenbuf;
va_list ap;
vastart(ap,count);
vlenbuf = va_arg(ap, Bytebuffer*);
va_end(ap);
bbprintf0(decl,"static const %s vlen_%u[] = {",
ctypename(tsym->typ.basetype),
uid);
commify(vlenbuf);
bbCatbuf(decl,vlenbuf);
bbCat(decl,"} ;");
listpush(declstack,(void*)decl);
/* Now generate the reference to buffer */
bbprintf(codebuf,"{%u,(void*)vlen_%u}",count,uid);
return 1;
}
static int
c_vlenstring(Generator* generator, Bytebuffer* vlenmem, int* uidp, size_t* countp,...)
{
if(uidp) *uidp = ++c_uid;
if(countp) *countp = bbLength(vlenmem);
return 1;
}
/* Define the single static bin data generator */
static Generator c_generator_singleton = {
NULL,
c_charconstant,
c_constant,
c_listbegin,
c_list,
c_listend,
c_vlendecl,
c_vlenstring
};
Generator* c_generator = &c_generator_singleton;
2010-06-03 21:24:43 +08:00
#endif /*ENABLE_C*/