1/*********************************************************************
2 *   Copyright 2009, UCAR/Unidata
3 *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
4 *********************************************************************/
5
6#include "includes.h"
7#include "nc_iter.h"
8
9#ifdef ENABLE_C
10
11#include <math.h>
12
13static int c_uid = 0;
14
15static int
16c_charconstant(GeneratorgeneratorSymbolsymBytebuffercodebuf, ...)
17{
18    /* Escapes and quoting will be handled in genc_write */
19    /* Just transfer charbuf to codebuf */
20    Bytebuffercharbuf;
21    va_list ap;
22    vastart(ap,codebuf);
23    charbuf = va_arg(apBytebuffer*);
24    va_end(ap);
25    bbNull(charbuf);
26    bbCatbuf(codebuf,charbuf);
27    return 1;
28}
29
30static int
31c_constant(GeneratorgeneratorSymbolsymNCConstantconBytebufferbuf,...)
32{
33    Bytebuffercodetmp = bbNew();
34    char* special = NULL;
35
36    switch (con->nctype) {
37    case NC_CHAR:
38 if(con->value.charv == '\'')
39     bbprintf(codetmp,"'\\''");
40 else
41     bbprintf(codetmp,"'%s'",cescapifychar(con->value.charv,'\''));
42 break;
43    case NC_BYTE:
44 bbprintf(codetmp,"%hhd",con->value.int8v);
45 break;
46    case NC_SHORT:
47 bbprintf(codetmp,"%hd",con->value.int16v);
48 break;
49    case NC_INT:
50 bbprintf(codetmp,"%d",con->value.int32v);
51 break;
52    case NC_FLOAT:
53 /* Special case for nanf */
54 if(isnan(con->value.floatv))
55     bbprintf(codetmp,"nanf");
56 else
57     bbprintf(codetmp,"%f",con->value.floatv);
58 break;
59    case NC_DOUBLE:
60 /* Special case for nan */
61 if(isnan(con->value.doublev))
62     bbprintf(codetmp,"nan");
63 else
64     bbprintf(codetmp,"%lf",con->value.doublev);
65 break;
66    case NC_UBYTE:
67        bbprintf(codetmp,"%hhuU",con->value.uint8v);
68 break;
69    case NC_USHORT:
70 bbprintf(codetmp,"%huU",con->value.uint16v);
71 break;
72    case NC_UINT:
73 bbprintf(codetmp,"%uU",con->value.uint32v);
74 break;
75    case NC_INT64:
76 bbprintf(codetmp,"%lldLL",con->value.int64v);
77 break;
78    case NC_UINT64:
79 bbprintf(codetmp,"%lluULL",con->value.uint64v);
80 break;
81    case NC_ECONST:
82 bbprintf(codetmp,"%s",cname(con->value.enumv));
83 break;
84    case NC_NIL:
85    case NC_STRING: { /* handle separately */
86 if(con->value.stringv.len == 0 && con->value.stringv.stringv == NULL) {
87            bbprintf(codetmp,"NULL");
88 } else {
89     char* escaped = escapify(con->value.stringv.stringv,
90  '"',con->value.stringv.len);
91     special = poolalloc(1+2+strlen(escaped));
92     strcpy(special,"\"");
93     strcat(special,escaped);
94     strcat(special,"\"");
95 }
96 } break;
97    case NC_OPAQUE: {
98 char* p;
99 int bslen;
100 bslen=(4*con->value.opaquev.len);
101 special = poolalloc(bslen+2+1);
102 strcpy(special,"\"");
103 p = con->value.opaquev.stringv;
104 while(*p) {
105     strcat(special,"\\x");
106     strncat(special,p,2);     
107     p += 2;
108 }
109 strcat(special,"\"");
110 } break;
111
112    default: PANIC1("ncstype: bad type code: %d",con->nctype);
113
114    }
115    if(special == NULL)
116        bbCatbuf(buf,codetmp);
117    else
118 bbCat(buf,special);
119    bbFree(codetmp);
120    return 1;
121}
122
123static int
124c_listbegin(GeneratorgeneratorSymbolsym, void* liststateListClass lc, size_t sizeBytebuffercodebuf, int* uidp, ...)
125{
126    if(uidp) *uidp = ++c_uid;
127    switch (lc) {
128    case LISTVLEN:
129    case LISTATTR:
130    case LISTDATA:
131 break;
132    case LISTFIELDARRAY:
133    case LISTCOMPOUND:
134        bbAppend(codebuf,'{');
135 break;
136    }
137    return 1;
138}
139
140static int
141c_list(GeneratorgeneratorSymbolsym, void* liststateListClass lc, int uid, size_t countBytebuffercodebuf, ...)
142{
143    switch (lc) {
144    case LISTVLEN:
145    case LISTATTR:
146        if(count > 0) bbCat(codebuf,", ");
147 break;
148    case LISTDATA:
149    case LISTCOMPOUND:
150    case LISTFIELDARRAY:
151        bbAppend(codebuf,' ');
152 break;
153    }
154    return 1;
155}
156
157static int
158c_listend(GeneratorgeneratorSymbolsym, void* liststateListClass lc, int uid, size_t countBytebufferbuf, ...)
159{
160    switch (lc) {
161    case LISTCOMPOUND:
162    case LISTFIELDARRAY:
163 bbAppend(buf,'}');
164 break;
165    case LISTDATA:
166    case LISTVLEN:
167    case LISTATTR:
168 break;
169    }
170    return 1;
171}
172
173static int
174c_vlendecl(GeneratorgeneratorSymboltsymBytebuffercodebuf, int uid, size_t count, ...)
175{
176    /* Build a bytebuffer to capture the vlen decl */
177    Listdeclstack = (List*)generator->globalstate;
178    Bytebufferdecl = bbNew();
179    Bytebuffervlenbuf;
180    va_list ap;
181    vastart(ap,count);
182    vlenbuf = va_arg(apBytebuffer*);
183    va_end(ap);
184    bbprintf0(decl,"static const %s vlen_%u[] = {",
185         ctypename(tsym->typ.basetype),
186                uid);
187    commify(vlenbuf);
188    bbCatbuf(decl,vlenbuf);
189    bbCat(decl,"} ;");
190    listpush(declstack,(void*)decl);
191    /* Now generate the reference to buffer */
192    bbprintf(codebuf,"{%u,(void*)vlen_%u}",count,uid);
193    return 1;
194}
195
196static int
197c_vlenstring(GeneratorgeneratorSymbolsymBytebuffervlenmem, int* uidp, size_t* countp,...)
198{
199    if(uidp) *uidp = ++c_uid;
200    if(countp) *countp = bbLength(vlenmem);
201    return 1;
202}
203
204/* Define the single static bin data generator  */
205static Generator c_generator_singleton = {
206    NULL,
207    c_charconstant,
208    c_constant,
209    c_listbegin,
210    c_list,
211    c_listend,
212    c_vlendecl,
213    c_vlenstring
214};
215Generatorc_generator = &c_generator_singleton;
216
217#endif /*ENABLE_C*/


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed