source: XIOS/trunk/extern/src_netcdf4/dceparse.c @ 409

Last change on this file since 409 was 409, checked in by ymipsl, 11 years ago

Add improved nectdf internal library src

YM

  • Property svn:eol-style set to native
File size: 9.0 KB
Line 
1/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc.
2   See the COPYRIGHT file for more information. */
3
4/* Parser actions for constraint expressions */
5
6/* Since oc does not use the constraint parser,
7   they functions all just abort if called.
8*/
9
10#include "config.h"
11#include <stdlib.h>
12#include <stdio.h>
13#include <string.h>
14#include <assert.h>
15
16#include "netcdf.h"
17
18#include "nclist.h"
19#include "ncbytes.h"
20#include "dceconstraints.h"
21#include "dceparselex.h"
22
23static Object collectlist(Object list0, Object decl);
24
25void
26projections(DCEparsestate* state, Object list0)
27{
28    NClist* list = (NClist*)list0;
29    if(list != NULL) {
30        nclistfree(state->constraint->projections);
31        state->constraint->projections = list;
32    }
33#ifdef DEBUG
34fprintf(stderr,"        ce.projections: %s\n",
35        dcetostring((DCEnode*)state->constraint->projections));
36#endif
37}
38
39void
40selections(DCEparsestate* state, Object list0)
41{
42    NClist* list = (NClist*)list0;
43    if(list != NULL) {
44        nclistfree(state->constraint->selections);
45        state->constraint->selections = list;
46    }
47#ifdef DEBUG
48fprintf(stderr,"        ce.selections: %s\n",
49        dcetostring((DCEnode*)state->constraint->selections));
50#endif
51}
52
53
54Object
55projectionlist(DCEparsestate* state, Object list0, Object decl)
56{
57    return collectlist(list0,decl);
58}
59
60Object
61projection(DCEparsestate* state, Object varorfcn)
62{
63    DCEprojection* p = (DCEprojection*)dcecreate(CES_PROJECT);
64    CEsort tag = *(CEsort*)varorfcn;
65    if(tag == CES_FCN)
66        p->fcn = varorfcn;
67    else
68        p->var = varorfcn;
69    p->discrim = tag;
70#ifdef DEBUG
71fprintf(stderr,"        ce.projection: %s\n",
72        dcetostring((DCEnode*)p));
73#endif
74    return p;
75}
76
77Object
78segmentlist(DCEparsestate* state, Object var0, Object decl)
79{
80    /* watch out: this is non-standard */
81    NClist* list;
82    DCEvar* v = (DCEvar*)var0;
83    if(v==NULL) v = (DCEvar*)dcecreate(CES_VAR);
84    list = v->segments;
85    if(list == NULL) list = nclistnew();
86    nclistpush(list,(ncelem)decl);
87    v->segments = list;
88    return v;
89}
90
91Object
92segment(DCEparsestate* state, Object name, Object slices0)
93{
94    int i;
95    DCEsegment* segment = (DCEsegment*)dcecreate(CES_SEGMENT);
96    NClist* slices = (NClist*)slices0;
97    segment->name = strdup((char*)name);
98    if(slices != NULL && nclistlength(slices) > 0) {
99        segment->rank = nclistlength(slices);
100        segment->slicesdefined = 1; /* but not declsizes */
101        for(i=0;i<nclistlength(slices);i++) {
102            DCEslice* slice = (DCEslice*)nclistget(slices,i);
103            segment->slices[i] = *slice;
104            free(slice);
105        }
106        nclistfree(slices);
107    } else
108        segment->slicesdefined = 0;
109#ifdef DEBUG
110fprintf(stderr,"        ce.segment: %s\n",
111        dumpsegment(segment));
112#endif
113    return segment;
114}
115
116
117Object
118rangelist(DCEparsestate* state, Object list0, Object decl)
119{
120    return collectlist(list0,decl);
121}
122
123Object
124range(DCEparsestate* state, Object sfirst, Object sstride, Object slast)
125{
126    DCEslice* slice = (DCEslice*)dcecreate(CES_SLICE);
127    unsigned long first,stride,last;
128
129    /* Note: that incoming arguments are strings; we must convert to size_t;
130       but we do know they are legal integers or NULL */
131    sscanf((char*)sfirst,"%lu",&first); /* always defined */
132    if(slast != NULL)
133        sscanf((char*)slast,"%lu",&last);
134    else
135        last = first;
136    if(sstride != NULL)
137        sscanf((char*)sstride,"%lu",&stride);
138    else
139        stride = 1; /* default */
140
141    if(stride == 0)
142        dceerror(state,"Illegal index for range stride");
143    if(last < first)
144        dceerror(state,"Illegal index for range last index");
145    slice->first  = first;
146    slice->stride = stride;
147    slice->stop   = last + 1;
148    slice->length  = slice->stop - slice->first;
149    slice->count  = slice->length / slice->stride;
150#ifdef DEBUG
151fprintf(stderr,"        ce.slice: %s\n",
152        dumpslice(slice));
153#endif
154    return slice;
155}
156
157Object
158range1(DCEparsestate* state, Object rangenumber)
159{
160    int range = -1;
161    sscanf((char*)rangenumber,"%u",&range);
162    if(range < 0) {
163        dceerror(state,"Illegal range index");
164    }
165    return rangenumber;
166}
167
168Object
169clauselist(DCEparsestate* state, Object list0, Object decl)
170{
171    return collectlist(list0,decl);
172}
173
174Object
175sel_clause(DCEparsestate* state, int selcase,
176           Object lhs, Object relop0, Object values)
177{
178    DCEselection* sel = (DCEselection*)dcecreate(CES_SELECT);
179    sel->operator = (CEsort)relop0;
180    sel->lhs = (DCEvalue*)lhs;
181    if(selcase == 2) {/*singleton value*/
182        sel->rhs = nclistnew();
183        nclistpush(sel->rhs,(ncelem)values);
184    } else
185        sel->rhs = (NClist*)values;
186    return sel;
187}
188
189Object
190indexpath(DCEparsestate* state, Object list0, Object index)
191{
192    return collectlist(list0,index);
193}
194
195Object
196array_indices(DCEparsestate* state, Object list0, Object indexno)
197{
198    DCEslice* slice;
199    long long start = -1;
200    NClist* list = (NClist*)list0;
201    if(list == NULL) list = nclistnew();
202    sscanf((char*)indexno,"%lld",&start);
203    if(start < 0) {
204        dceerror(state,"Illegal array index");
205        start = 1;
206    }   
207    slice = (DCEslice*)dcecreate(CES_SLICE);
208    slice->first = start;
209    slice->stride = 1;
210    slice->count = 1;
211    slice->length = 1;
212    slice->stop = start+1;
213    nclistpush(list,(ncelem)slice);
214    return list;
215}
216
217Object
218indexer(DCEparsestate* state, Object name, Object indices)
219{
220    int i;
221    NClist* list = (NClist*)indices;
222    DCEsegment* seg = (DCEsegment*)dcecreate(CES_SEGMENT);
223    seg->name = strdup((char*)name);
224    for(i=0;i<nclistlength(list);i++) {   
225        DCEslice* slice = (DCEslice*)nclistget(list,i);
226        seg->slices[i] = *slice;
227        free(slice);
228    }
229    nclistfree(indices);
230    return seg;   
231}
232
233Object
234function(DCEparsestate* state, Object fcnname, Object args)
235{
236    DCEfcn* fcn = (DCEfcn*)dcecreate(CES_FCN);
237    fcn->name = nulldup((char*)fcnname);
238    fcn->args = args;
239    return fcn;
240}
241
242Object
243arg_list(DCEparsestate* state, Object list0, Object decl)
244{
245    return collectlist(list0,decl);
246}
247
248
249Object
250value_list(DCEparsestate* state, Object list0, Object decl)
251{
252    return collectlist(list0,decl);
253}
254
255Object
256value(DCEparsestate* state, Object val)
257{
258    DCEvalue* ncvalue = (DCEvalue*)dcecreate(CES_VALUE);
259    CEsort tag = *(CEsort*)val;
260    switch (tag) {
261    case CES_VAR: ncvalue->var = (DCEvar*)val; break;
262    case CES_FCN: ncvalue->fcn = (DCEfcn*)val; break;
263    case CES_CONST: ncvalue->constant = (DCEconstant*)val; break;
264    default: abort(); break;
265    }
266    ncvalue->discrim = tag;
267    return ncvalue;
268}
269
270Object
271var(DCEparsestate* state, Object indexpath)
272{
273    DCEvar* v = (DCEvar*)dcecreate(CES_VAR);
274    v->segments = (NClist*)indexpath;       
275    return v;
276}
277
278Object
279constant(DCEparsestate* state, Object val, int tag)
280{
281    DCEconstant* con = (DCEconstant*)dcecreate(CES_CONST);
282    char* text = (char*)val;
283    char* endpoint = NULL;
284    switch (tag) {
285    case SCAN_STRINGCONST:
286        con->discrim = CES_STR;
287        con->text = nulldup(text);
288        break;
289    case SCAN_NUMBERCONST:
290        con->intvalue = strtoll(text,&endpoint,10);
291        if(*text != '\0' && *endpoint == '\0') {
292            con->discrim = CES_INT;
293        } else {
294            con->floatvalue = strtod(text,&endpoint);
295            if(*text != '\0' && *endpoint == '\0')
296                con->discrim = CES_FLOAT;
297            else abort();
298        }
299        break;
300    default: abort(); break;
301    }
302    return con;
303}
304
305static Object
306collectlist(Object list0, Object decl)
307{
308    NClist* list = (NClist*)list0;
309    if(list == NULL) list = nclistnew();
310    nclistpush(list,(ncelem)decl);
311    return list;
312}
313
314Object
315makeselectiontag(CEsort tag)
316{
317    return (Object) tag;
318}
319
320int
321dceerror(DCEparsestate* state, char* msg)
322{
323    strcpy(state->errorbuf,msg);
324    state->errorcode=1;
325    return 0;
326}
327
328static void
329dce_parse_cleanup(DCEparsestate* state)
330{
331    dcelexcleanup(&state->lexstate); /* will free */
332}
333
334static DCEparsestate*
335ce_parse_init(char* input, DCEconstraint* constraint)
336{
337    DCEparsestate* state = NULL;
338    if(input==NULL) {
339        dceerror(state,"ce_parse_init: no input buffer");
340    } else {
341        state = (DCEparsestate*)calloc(1,sizeof(DCEparsestate));
342        if(state==NULL) return (DCEparsestate*)NULL;
343        state->errorbuf[0] = '\0';
344        state->errorcode = 0;
345        dcelexinit(input,&state->lexstate);
346        state->constraint = constraint;
347    }
348    return state;
349}
350
351#ifdef PARSEDEBUG
352extern int dcedebug;
353#endif
354
355/* Wrapper for ceparse */
356int
357dapceparse(char* input, DCEconstraint* constraint, char** errmsgp)
358{
359    DCEparsestate* state;
360    int errcode = 0;
361
362#ifdef PARSEDEBUG
363dcedebug = 1;
364#endif
365
366    if(input != NULL) {
367#ifdef DEBUG
368fprintf(stderr,"dceeparse: input=%s\n",input);
369#endif
370        state = ce_parse_init(input,constraint);
371        if(dceparse(state) == 0) {
372#ifdef DEBUG
373if(nclistlength(constraint->projections) > 0)
374fprintf(stderr,"dceeparse: projections=%s\n",
375        dcetostring((DCEnode*)constraint->projections));
376#endif
377#ifdef DEBUG
378if(nclistlength(constraint->selections)  > 0)
379fprintf(stderr,"dceeparse: selections=%s\n",
380        dumpselections(constraint->selections));
381#endif
382        } else {
383            if(errmsgp) *errmsgp = nulldup(state->errorbuf);
384        }
385        errcode = state->errorcode;
386        dce_parse_cleanup(state);
387    }
388    return errcode;
389}
390
391#ifdef PARSEDEBUG
392Object
393debugobject(Object o)
394{
395    return o;
396}
397#endif
Note: See TracBrowser for help on using the repository browser.