/* Insert new client param (name,value); return value = 1 => not already defined 0 => param already defined (no change) */ int ocparaminsert(OClist* params, const char* clientparam, const char* value) { int i; if(params == NULL || clientparam == NULL) return 0; for(i=0;i<oclistlength(params);i+=2) { char* name = (char*)oclistget(params,i); if(strcmp(clientparam,name)==0) return 0; } /* not found, append */ oclistpush(params,(ocelem)nulldup(clientparam)); oclistpush(params,(ocelem)nulldup(value)); return 1; }
/* Create an ocnode and capture in the state->ocnode list */ static OCnode* newocnode(char* name, OCtype octype, DAPparsestate* state) { OCnode* node = ocnode_new(name,octype,state->root); oclistpush(state->ocnodes,(void*)node); return node; }
/* Collect the set of nodes ending in "node"*/ void collectpathtonode(OCnode* node, OClist* path) { if(node == NULL) return; collectpathtonode(node->container,path); oclistpush(path,(ocelem)node); }
static int mergedas1(OCnode* dds, OCnode* das) { int i,j; int stat = OC_NOERR; if(dds->attributes == NULL) dds->attributes = oclistnew(); /* assign the simple attributes in the das set to this dds node*/ for(i=0;i<oclistlength(das->subnodes);i++) { OCnode* attnode = (OCnode*)oclistget(das->subnodes,i); if(attnode->octype == OC_Attribute) { Attribute* att = makeattribute(attnode->name, attnode->etype, attnode->att.values); oclistpush(dds->attributes,(ocelem)att); } } /* Try to merge any enclosed sets with subnodes of dds*/ for(i=0;i<oclistlength(das->subnodes);i++) { OCnode* dasnode = (OCnode*)oclistget(das->subnodes,i); int match = 0; if(dasnode->octype == OC_Attribute) continue; /* already dealt with above*/ for(j=0;j<oclistlength(dds->subnodes) && !match;j++) { OCnode* ddsnode = (OCnode*)oclistget(dds->subnodes,j); if(strcmp(dasnode->name,ddsnode->name) == 0) { match = 1; stat = mergedas1(ddsnode,dasnode); if(stat != OC_NOERR) break; } } if(!match) {marklostattribute(dasnode);} } return THROW(stat); }
/* Dap identifiers will come to use encoded, so we must decode them; It turns out that we can use ocuridecode because dap specifies %xx encoding. */ char* dapdecode(DAPlexstate* lexstate, char* name) { char* decoded; decoded = ocuridecode(name); oclistpush(lexstate->reclaim,(ocelem)decoded); return decoded; }
static OCobject ocassign(void* object) { #ifdef TRACK fprintf(stderr,"assign: %lu\n",(unsigned long)object); fflush(stderr); #endif oclistpush(ocmap,(ocelem)object); return (OCobject)object; }
Object dap_arraydecls(DAPparsestate* state, Object arraydecls, Object arraydecl) { OClist* alist = (OClist*)arraydecls; if(alist == NULL) alist = oclistnew(); else oclistpush(alist,(void*)arraydecl); return alist; }
Object dap_attrvalue(DAPparsestate* state, Object valuelist, Object value, Object etype) { OClist* alist = (OClist*)valuelist; if(alist == NULL) alist = oclistnew(); /* Watch out for null values */ if(value == NULL) value = ""; oclistpush(alist,(void*)strdup(value)); return alist; }
char* dapdecode(DAPlexstate* lexstate, char* name) { char* decoded = NULL; #ifdef DECODE_IDENTIFIERS decoded = ocuridecode(name); #else decoded = ocuridecodeonly(name,decodelist); #endif oclistpush(lexstate->reclaim,(void*)decoded); return decoded; }
static void ocassignall(OClist* list) { unsigned int i; if(list != NULL) for(i=0;i<oclistlength(list);i++) { void* object = (void*)oclistget(list,i); #ifdef TRACK fprintf(stderr,"assign: %lu\n",(unsigned long)object); fflush(stderr); #endif oclistpush(ocmap,(ocelem)object); } }
void makedimlist(OClist* path, OClist* dims) { unsigned int i,j; for(i=0;i<oclistlength(path);i++) { OCnode* node = (OCnode*)oclistget(path,i); unsigned int rank = node->array.rank; for(j=0;j<rank;j++) { OCnode* dim = (OCnode*)oclistget(node->array.dimensions,j); oclistpush(dims,(void*)dim); } } }
static int mergedas1(OCnode* dds, OCnode* das) { unsigned int i; int stat = OC_NOERR; if(das == NULL) return OC_NOERR; /* nothing to do */ if(dds->attributes == NULL) dds->attributes = oclistnew(); /* assign the simple attributes in the das set to this dds node*/ for(i=0;i<oclistlength(das->subnodes);i++) { OCnode* attnode = (OCnode*)oclistget(das->subnodes,i); if(attnode->octype == OC_Attribute) { OCattribute* att = makeattribute(attnode->name, attnode->etype, attnode->att.values); oclistpush(dds->attributes,(ocelem)att); } } return THROW(stat); }
Object dap_attrlist(DAPparsestate* state, Object attrlist, Object attrtuple) { OClist* alist = (OClist*)attrlist; if(alist == NULL) alist = oclistnew(); else { char* dupname; if(attrtuple != NULL) {/* NULL=>alias encountered, ignore */ oclistpush(alist,(void*)attrtuple); if((dupname=scopeduplicates(alist))!=NULL) { dap_parse_error(state,"Duplicate attribute names in same scope: %s",dupname); /* Remove this attribute */ oclistpop(alist); state->error = OC_ENAMEINUSE; /* semantic error */ } } } return alist; }
int ocddsdasmerge(OCstate* state, OCnode* ddsroot, OCnode* dasroot) { int i,j; int stat = OC_NOERR; OClist* globals = oclistnew(); if(dasroot == NULL) return THROW(stat); /* Start by looking for global attributes*/ for(i=0;i<oclistlength(dasroot->subnodes);i++) { OCnode* node = (OCnode*)oclistget(dasroot->subnodes,i); if(node->att.isglobal) { for(j=0;j<oclistlength(node->subnodes);j++) { OCnode* attnode = (OCnode*)oclistget(node->subnodes,j); Attribute* att = makeattribute(attnode->name, attnode->etype, attnode->att.values); oclistpush(globals,(ocelem)att); } } } ddsroot->attributes = globals; /* Now try to match subnode names with attribute set names*/ for(i=0;i<oclistlength(dasroot->subnodes);i++) { OCnode* das = (OCnode*)oclistget(dasroot->subnodes,i); int match = 0; if(das->att.isglobal) continue; if(das->octype == OC_Attributeset) { for(j=0;j<oclistlength(ddsroot->subnodes) && !match;j++) { OCnode* dds = (OCnode*)oclistget(ddsroot->subnodes,j); if(strcmp(das->name,dds->name) == 0) { match = 1; stat = mergedas1(dds,das); if(stat != OC_NOERR) break; } } } if(!match) {marklostattribute(das);} } if(stat == OC_NOERR) ddsroot->attributed = 1; return THROW(stat); }
int daplex(YYSTYPE* lvalp, DAPparsestate* state) { DAPlexstate* lexstate = state->lexstate; int token; int c; unsigned int i; char* p; char* tmp; YYSTYPE lval = NULL; token = 0; ocbytesclear(lexstate->yytext); /* invariant: p always points to current char */ for(p=lexstate->next; token==0&&(c=*p); p++) { if(c == '\n') { lexstate->lineno++; } else if(c <= ' ' || c == '\177') { /* whitespace: ignore */ } else if(c == '#') { /* single line comment */ while((c=*(++p))) { if(c == '\n') break; } } else if(strchr(lexstate->worddelims,c) != NULL) { /* don't put in lexstate->yytext to avoid memory leak */ token = c; } else if(c == '"') { int more = 1; /* We have a string token; will be reported as WORD_STRING */ while(more && (c=*(++p))) { if(c == '"') { more = 0; continue; } #ifdef DAP2ENCODE if(c == '\\') { /* Resolve spec ambiguity about handling of \c: 1. !KEEPSLASH: convert \c to c for any character c 2. KEEPSLASH: convert \c to \c for any character c; that is, keep the backslash. It is clear that the problem being addressed was \". But it is unclear what to to do about \n: convert to Ascii LF or leave as \n. This code will leave as \n and assume higher levels of code will address the issue. */ #ifdef KEEPSLASH dapaddyytext(lexstate,c); #endif c=*(++p); if(c == '\0') more = 0; } #else /*Non-standard*/ switch (c) { case '\\': c=*(++p); switch (c) { case 'r': c = '\r'; break; case 'n': c = '\n'; break; case 'f': c = '\f'; break; case 't': c = '\t'; break; case 'x': { int d1,d2; c = '?'; ++p; d1 = tohex(*p++); if(d1 < 0) { daperror(state,"Illegal \\xDD in TOKEN_STRING"); } else { d2 = tohex(*p++); if(d2 < 0) { daperror(state,"Illegal \\xDD in TOKEN_STRING"); } else { c=(((unsigned int)d1)<<4) | (unsigned int)d2; } } } break; default: break; } break; default: break; } #endif /*!DAP2ENCODE*/ if(more) dapaddyytext(lexstate,c); } token=WORD_STRING; } else if(strchr(lexstate->wordchars1,c) != NULL) { int isdatamark = 0; /* we have a WORD_WORD */ dapaddyytext(lexstate,c); while((c=*(++p))) { #ifdef URLCVT if(c == '%' && p[1] != 0 && p[2] != 0 && strchr(hexdigits,p[1]) != NULL && strchr(hexdigits,p[2]) != NULL) { int d1,d2; d1 = tohex(p[1]); d2 = tohex(p[2]); if(d1 >= 0 || d2 >= 0) { c=(((unsigned int)d1)<<4) | (unsigned int)d2; p+=2; } } else { if(strchr(lexstate->wordcharsn,c) == NULL) { p--; break; } } dapaddyytext(lexstate,c); #else if(strchr(lexstate->wordcharsn,c) == NULL) { p--; break; } dapaddyytext(lexstate,c); #endif } /* Special check for Data: */ tmp = ocbytescontents(lexstate->yytext); if(strcmp(tmp,"Data")==0 && *p == ':') { dapaddyytext(lexstate,*p); p++; if(p[0] == '\n') { token = SCAN_DATA; isdatamark = 1; p++; } else if(p[0] == '\r' && p[1] == '\n') { token = SCAN_DATA; isdatamark = 1; p+=2; } } if(!isdatamark) { /* check for keyword */ token=WORD_WORD; /* assume */ for(i=0;; i++) { if(keywords[i] == NULL) break; if(strcasecmp(keywords[i],tmp)==0) { token=keytokens[i]; break; } } } } else { /* illegal */ } } lexstate->next = p; strncpy(lexstate->lasttokentext,ocbytescontents(lexstate->yytext),MAX_TOKEN_LENGTH); lexstate->lasttoken = token; if(ocdebug >= 2) dumptoken(lexstate); /*Put return value onto Bison stack*/ if(ocbyteslength(lexstate->yytext) == 0) lval = NULL; else { lval = ocbytesdup(lexstate->yytext); oclistpush(lexstate->reclaim,(void*)lval); } if(lvalp) *lvalp = lval; return token; /* Return the type of the token. */ }
OCerror ocfetch(OCstate* state, const char* constraint, OCdxd kind, OCnode** rootp) { OCtree* tree = NULL; OCnode* root = NULL; OCerror stat = OC_NOERR; tree = (OCtree*)ocmalloc(sizeof(OCtree)); MEMCHECK(tree,OC_ENOMEM); memset((void*)tree,0,sizeof(OCtree)); tree->dxdclass = kind; tree->state = state; tree->constraint = constraintescape(constraint); if(tree->constraint == NULL) tree->constraint = nulldup(constraint); ocbytesclear(state->packet); switch (kind) { case OCDAS: stat = readDAS(state,tree); if(stat == OC_NOERR) { tree->text = ocbytesdup(state->packet); if(tree->text == NULL) stat = OC_EDAS; } break; case OCDDS: stat = readDDS(state,tree); if(stat == OC_NOERR) { tree->text = ocbytesdup(state->packet); if(tree->text == NULL) stat = OC_EDDS; } break; case OCDATADDS: #ifdef OC_DISK_STORAGE /* Create the datadds file immediately so that DRNO can reference it*/ /* Make the tmp file*/ stat = createtempfile(state,tree); if(stat) {THROWCHK(stat); goto unwind;} stat = readDATADDS(state,tree); if(stat == OC_NOERR) { /* Separate the DDS from data and return the dds; will modify packet */ stat = ocextractdds(state,tree); } #else stat = readDATADDS(state,tree); if(stat == OC_NOERR) { /* Separate the DDS from data*/ stat = ocextractdds(state,tree); tree->data.xdrdata = ocbytesdup(state->packet); } #endif break; } if(stat != OC_NOERR) { /* Obtain any http code */ state->error.httpcode = ocfetchhttpcode(state->curl); if(state->error.httpcode >= 400) { oc_log(LOGWARN,"oc_open: Could not read url; http error = %l",state->error.httpcode); } else { oc_log(LOGWARN,"oc_open: Could not read url"); } return THROW(stat); } tree->nodes = NULL; stat = DAPparse(state,tree,tree->text); /* Check and report on an error return from the server */ if(stat == OC_EDAPSVC && state->error.code != NULL) { oc_log(LOGERR,"oc_open: server error retrieving url: code=%s message=\"%s\"", state->error.code, (state->error.message?state->error.message:"")); } if(stat) {THROWCHK(stat); goto unwind;} root = tree->root; /* make sure */ tree->root = root; root->tree = tree; /* Verify the parse */ switch (kind) { case OCDAS: if(root->octype != OC_Attributeset) {THROWCHK(stat=OC_EDAS); goto unwind;} break; case OCDDS: if(root->octype != OC_Dataset) {THROWCHK(stat=OC_EDDS); goto unwind;} break; case OCDATADDS: if(root->octype != OC_Dataset) {THROWCHK(stat=OC_EDATADDS); goto unwind;} /* Modify the tree kind */ tree->dxdclass = OCDATADDS; break; default: return OC_EINVAL; } if(kind != OCDAS) { /* Process ocnodes to fix various semantic issues*/ computeocsemantics(tree->nodes); } /* Process ocnodes to compute name info*/ computeocfullnames(tree->root); if(kind != OCDAS) { /* Process ocnodes to compute sizes when uniform in size*/ ocsetsize(tree->root); } if(kind == OCDATADDS) { tree->data.xdrs = (XDR*)ocmalloc(sizeof(XDR)); MEMCHECK(tree->data.xdrs,OC_ENOMEM); #ifdef OC_DISK_STORAGE ocxdrstdio_create(tree->data.xdrs,tree->data.file,XDR_DECODE); #else xdrmem_create(tree->data.xdrs,tree->data.xdrdata,tree->data.datasize,XDR_DECODE); #endif if(!xdr_setpos(tree->data.xdrs,tree->data.bod)) return xdrerror(); } #ifdef OC_DISK_STORAGE if(ocdebug == 0 && tree->data.filename != NULL) { unlink(tree->data.filename); } #endif /* Put root into the state->trees list */ oclistpush(state->trees,(ocelem)root); if(rootp) *rootp = root; return stat; unwind: ocfreetree(tree); return THROW(stat); }
static int occompile1(OCstate* state, OCnode* xnode, OCmemdata** memdatap, XDR* xdrs) { unsigned int i,j,xdrcount; int stat = OC_NOERR; size_t nelements; OCmemdata* memdata = NULL; OCmemdata* structdata = NULL; OClist* records = NULL; OCerror ocstat = OC_NOERR; OCmemdata** pmem = NULL; /* Allocate the space for this memdata chunk */ switch (xnode->octype) { case OC_Dataset: case OC_Grid: case OC_Structure: { if(xnode->array.rank == 0) { ocstat = occompilefields(state,xnode,&memdata,xdrs); if(ocstat != OC_NOERR) goto fail; } else { /* rank > 0 */ /* Compute the actual index count after projections */ nelements = totaldimsize(xnode); if(nelements == 0) return THROW(OC_ENODATA); memdata = makememdata(xnode->octype,OC_NAT,nelements); MEMCHECK(memdata,OC_ENOMEM); memdata->mode = Dimmode; pmem = (OCmemdata**)&memdata->data; /* Consume the leading count field */ if(!xdr_u_int(xdrs,&xdrcount)) {stat = OC_EXDR; goto fail;} /* validate the datadds dimensions */ if(xdrcount != nelements) {stat=OC_EINVALCOORDS; goto fail;} for(i=0;i<nelements;i++) { ocstat = occompilefields(state,xnode,&structdata,xdrs); if(ocstat != OC_NOERR) { if(ocstat != OC_ENODATA) goto fail; structdata = NULL; /* Leave a hole for this element */ } pmem[i] = structdata; structdata = NULL; } } } break; case OC_Sequence:{ /* Since we do not know the # records beforehand, use a oclist to collect the record instances. Query: this stores by recor (where e.g. original ocapi stores by column). How hard would it be to make the storage choice conditional on some user defined flag? */ records = oclistnew(); for(;;) { /* pick up the sequence record begin marker*/ char tmp[sizeof(unsigned int)]; /* extract the tag byte*/ if(!xdr_opaque(xdrs,tmp,sizeof(tmp))) {stat = OC_EXDR; goto fail;} if(tmp[0] == StartOfoclist) { /* Walk each member field*/ ocstat = occompilefields(state,xnode,&structdata,xdrs); if(ocstat != OC_NOERR) goto fail; oclistpush(records,(ocelem)structdata); structdata = NULL; } else if(tmp[0] == EndOfoclist) { break; /* we are done with the this sequence instance*/ } else { oc_log(LOGERR,"missing/invalid begin/end record marker\n"); stat = OC_EINVALCOORDS; goto fail; } } /* Convert the list to a proper OCmemdata */ nelements = oclistlength(records); memdata = makememdata(xnode->octype,OC_NAT,nelements); MEMCHECK(memdata,OC_ENOMEM); memdata->mode = Recordmode; pmem = (OCmemdata**)&memdata->data; for(j=0;j<nelements;j++) { OCmemdata* record = (OCmemdata*)oclistget(records,j); pmem[j] = record; } oclistfree(records); records = NULL; } break; case OC_Primitive: ocstat = occompileprim(state,xnode,&memdata,xdrs); if(ocstat != OC_NOERR) goto fail; break; default: OCPANIC1("ocmap: encountered unexpected node type: %x",xnode->octype); break; } /*ok:*/ if(memdatap) *memdatap = memdata; return THROW(ocstat); fail: if(records != NULL) for(i=0;i<oclistlength(records);i++) freeocmemdata((OCmemdata*)oclistget(records,i)); freeocmemdata(memdata); freeocmemdata(structdata); return THROW(ocstat); }
OCerror ocfetch(OCstate* state, const char* constraint, OCdxd kind, OCflags flags, OCnode** rootp) { OCtree* tree = NULL; OCnode* root = NULL; OCerror stat = OC_NOERR; tree = (OCtree*)ocmalloc(sizeof(OCtree)); MEMCHECK(tree,OC_ENOMEM); memset((void*)tree,0,sizeof(OCtree)); tree->dxdclass = kind; tree->state = state; tree->constraint = constraintescape(constraint); if(tree->constraint == NULL) tree->constraint = nulldup(constraint); /* Set per-fetch curl properties */ #if 0 /* temporarily make per-link */ if((stat=ocset_flags_perfetch(state))!= OC_NOERR) goto fail; #endif ocbytesclear(state->packet); switch (kind) { case OCDAS: stat = readDAS(state,tree); if(stat == OC_NOERR) { tree->text = ocbytesdup(state->packet); if(tree->text == NULL) stat = OC_EDAS; } break; case OCDDS: stat = readDDS(state,tree); if(stat == OC_NOERR) { tree->text = ocbytesdup(state->packet); if(tree->text == NULL) stat = OC_EDDS; } break; case OCDATADDS: if((flags & OCONDISK) != 0) {/* store in file */ /* Create the datadds file immediately so that DRNO can reference it*/ /* Make the tmp file*/ stat = createtempfile(state,tree); if(stat) {OCTHROWCHK(stat); goto fail;} stat = readDATADDS(state,tree,flags); if(stat == OC_NOERR) { /* Separate the DDS from data and return the dds; will modify packet */ stat = ocextractddsinfile(state,tree,flags); } } else { /*inmemory*/ stat = readDATADDS(state,tree,flags); if(stat == OC_NOERR) { /* Separate the DDS from data and return the dds; will modify packet */ stat = ocextractddsinmemory(state,tree,flags); } } break; default: break; }/*switch*/ /* Obtain any http code */ state->error.httpcode = ocfetchhttpcode(state->curl); if(stat != OC_NOERR) { if(state->error.httpcode >= 400) { oclog(OCLOGWARN,"oc_open: Could not read url; http error = %l",state->error.httpcode); } else { oclog(OCLOGWARN,"oc_open: Could not read url"); } goto fail; } tree->nodes = NULL; stat = DAPparse(state,tree,tree->text); /* Check and report on an error return from the server */ if(stat == OC_EDAPSVC && state->error.code != NULL) { oclog(OCLOGERR,"oc_open: server error retrieving url: code=%s message=\"%s\"", state->error.code, (state->error.message?state->error.message:"")); } if(stat) {OCTHROWCHK(stat); goto fail;} root = tree->root; /* make sure */ tree->root = root; root->tree = tree; /* Verify the parse */ switch (kind) { case OCDAS: if(root->octype != OC_Attributeset) {OCTHROWCHK(stat=OC_EDAS); goto fail;} break; case OCDDS: if(root->octype != OC_Dataset) {OCTHROWCHK(stat=OC_EDDS); goto fail;} break; case OCDATADDS: if(root->octype != OC_Dataset) {OCTHROWCHK(stat=OC_EDATADDS); goto fail;} /* Modify the tree kind */ tree->dxdclass = OCDATADDS; break; default: return OC_EINVAL; } if(kind != OCDAS) { /* Process ocnodes to mark those that are cacheable */ ocmarkcacheable(state,root); /* Process ocnodes to handle various semantic issues*/ occomputesemantics(tree->nodes); } /* Process ocnodes to compute name info*/ occomputefullnames(tree->root); if(kind == OCDATADDS) { if((flags & OCONDISK) != 0) { tree->data.xdrs = xxdr_filecreate(tree->data.file,tree->data.bod); } else { #ifdef OCDEBUG fprintf(stderr,"ocfetch.datadds.memory: datasize=%lu bod=%lu\n", (unsigned long)tree->data.datasize,(unsigned long)tree->data.bod); #endif /* Switch to zero based memory */ tree->data.xdrs = xxdr_memcreate(tree->data.memory,tree->data.datasize,tree->data.bod); } MEMCHECK(tree->data.xdrs,OC_ENOMEM); /* Do a quick check to see if server returned an ERROR {} at the beginning of the data */ if(dataError(tree->data.xdrs,state)) { stat = OC_EDATADDS; oclog(OCLOGERR,"oc_open: server error retrieving url: code=%s message=\"%s\"", state->error.code, (state->error.message?state->error.message:"")); goto fail; } /* Compile the data into a more accessible format */ stat = occompile(state,tree->root); if(stat != OC_NOERR) goto fail; } /* Put root into the state->trees list */ oclistpush(state->trees,(void*)root); if(rootp) *rootp = root; return stat; fail: if(root != NULL) ocroot_free(root); else if(tree != NULL) octree_free(tree); return OCTHROW(stat); }
int daplex(YYSTYPE* lvalp, DAPparsestate* state) { DAPlexstate* lexstate = state->lexstate; int token; int c; unsigned int i; char* p=lexstate->next; char* tmp; token = 0; ocbytesclear(lexstate->yytext); /* invariant: p always points to current char */ for(p=lexstate->next;token==0&&(c=*p);p++) { if(c == '\n') { lexstate->lineno++; } else if(c <= ' ' || c == '\177') { /* whitespace: ignore */ } else if(c == '#') { /* single line comment */ while((c=*(++p))) {if(c == '\n') break;} } else if(strchr(lexstate->worddelims,c) != NULL) { /* don't put in lexstate->yytext to avoid memory leak */ token = c; } else if(c == '"') { int more = 1; /* We have a string token; will be reported as SCAN_WORD */ while(more && (c=*(++p))) { #ifdef NONSTDCVT switch (c) { case '"': more=0; break; case '\\': c=*(++p); switch (c) { case 'r': c = '\r'; break; case 'n': c = '\n'; break; case 'f': c = '\f'; break; case 't': c = '\t'; break; case 'x': { int d1,d2; c = '?'; ++p; d1 = tohex(*p++); if(d1 < 0) { daperror(state,"Illegal \\xDD in TOKEN_STRING"); } else { d2 = tohex(*p++); if(d2 < 0) { daperror(state,"Illegal \\xDD in TOKEN_STRING"); } else { c=(((unsigned int)d1)<<4) | (unsigned int)d2; } } } break; default: break; } break; default: break; } #else /*!NONSTDCVT*/ if(c == '"') more = 0; else if(c == '\\') { c=*(++p); if(c == '\0') more = false; if(c != '"') {c = '\\'; --p;} } #endif /*!NONSTDCVT*/ if(more) dapaddyytext(lexstate,c); } token=SCAN_WORD; } else if(strchr(lexstate->wordchars1,c) != NULL) { /* we have a SCAN_WORD */ dapaddyytext(lexstate,c); while((c=*(++p))) { #ifdef URLCVT if(c == '%' && p[1] != 0 && p[2] != 0 && strchr(hexdigits,p[1]) != NULL && strchr(hexdigits,p[2]) != NULL) { #ifdef WRONG /* Should not unescape %xx occurrences */ int d1,d2; d1 = tohex(p[1]); d2 = tohex(p[2]); if(d1 >= 0 || d2 >= 0) { c=(((unsigned int)d1)<<4) | (unsigned int)d2; p+=2; } #endif } else { if(strchr(lexstate->wordcharsn,c) == NULL) {p--; break;} } dapaddyytext(lexstate,c); #else if(strchr(lexstate->wordcharsn,c) == NULL) {p--; break;} dapaddyytext(lexstate,c); #endif } /* Special check for Data: */ tmp = ocbytescontents(lexstate->yytext); if(strcmp(tmp,"Data")==0 && *p == ':') { dapaddyytext(lexstate,*p); p++; token = SCAN_DATA; } else { /* check for keyword */ token=SCAN_WORD; /* assume */ for(i=0;;i++) { if(keywords[i] == NULL) break; if(strcasecmp(keywords[i],tmp)==0) { token=keytokens[i]; break; } } } } else { /* illegal */ } } lexstate->next = p; strncpy(lexstate->lasttokentext,ocbytescontents(lexstate->yytext),MAX_TOKEN_LENGTH); lexstate->lasttoken = token; if(ocdebug >= 2) dumptoken(lexstate); /*Put return value onto Bison stack*/ if(ocbyteslength(lexstate->yytext) == 0) *lvalp = NULL; else { *lvalp = ocbytesdup(lexstate->yytext); oclistpush(lexstate->reclaim,(ocelem)*lvalp); } return token; /* Return the type of the token. */ }
OCerror ocfetchf(OCstate* state, const char* constraint, OCdxd kind, OCflags flags, OCnode** rootp) { OCtree* tree = NULL; OCnode* root = NULL; OCerror stat = OC_NOERR; tree = (OCtree*)ocmalloc(sizeof(OCtree)); MEMCHECK(tree,OC_ENOMEM); memset((void*)tree,0,sizeof(OCtree)); tree->dxdclass = kind; tree->state = state; tree->constraint = constraintescape(constraint); if(tree->constraint == NULL) tree->constraint = nulldup(constraint); /* Set curl properties: pwd, flags, proxies, ssl */ if((stat=ocset_user_password(state))!= OC_NOERR) goto fail; if((stat=ocset_curl_flags(state)) != OC_NOERR) goto fail; if((stat=ocset_proxy(state)) != OC_NOERR) goto fail; if((stat=ocset_ssl(state)) != OC_NOERR) goto fail; ocbytesclear(state->packet); switch (kind) { case OCDAS: stat = readDAS(state,tree); if(stat == OC_NOERR) { tree->text = ocbytesdup(state->packet); if(tree->text == NULL) stat = OC_EDAS; } break; case OCDDS: stat = readDDS(state,tree); if(stat == OC_NOERR) { tree->text = ocbytesdup(state->packet); if(tree->text == NULL) stat = OC_EDDS; } break; case OCDATADDS: if((flags & OCINMEMORY) == 0) {/* store in file */ /* Create the datadds file immediately so that DRNO can reference it*/ /* Make the tmp file*/ stat = createtempfile(state,tree); if(stat) {OCTHROWCHK(stat); goto unwind;} stat = readDATADDS(state,tree,flags); if(stat == OC_NOERR) { /* Separate the DDS from data and return the dds; will modify packet */ stat = ocextractddsinfile(state,tree,flags); } } else { /*inmemory*/ stat = readDATADDS(state,tree,flags); if(stat == OC_NOERR) { /* Separate the DDS from data and return the dds; will modify packet */ stat = ocextractddsinmemory(state,tree,flags); } } break; }/*switch*/ if(stat != OC_NOERR) { /* Obtain any http code */ state->error.httpcode = ocfetchhttpcode(state->curl); if(state->error.httpcode >= 400) { oc_log(LOGWARN,"oc_open: Could not read url; http error = %l",state->error.httpcode); } else { oc_log(LOGWARN,"oc_open: Could not read url"); } return OCTHROW(stat); } tree->nodes = NULL; stat = DAPparse(state,tree,tree->text); /* Check and report on an error return from the server */ if(stat == OC_EDAPSVC && state->error.code != NULL) { oc_log(LOGERR,"oc_open: server error retrieving url: code=%s message=\"%s\"", state->error.code, (state->error.message?state->error.message:"")); } if(stat) {OCTHROWCHK(stat); goto unwind;} root = tree->root; /* make sure */ tree->root = root; root->tree = tree; /* Verify the parse */ switch (kind) { case OCDAS: if(root->octype != OC_Attributeset) {OCTHROWCHK(stat=OC_EDAS); goto unwind;} break; case OCDDS: if(root->octype != OC_Dataset) {OCTHROWCHK(stat=OC_EDDS); goto unwind;} break; case OCDATADDS: if(root->octype != OC_Dataset) {OCTHROWCHK(stat=OC_EDATADDS); goto unwind;} /* Modify the tree kind */ tree->dxdclass = OCDATADDS; break; default: return OC_EINVAL; } if(kind != OCDAS) { /* Process ocnodes to assign offsets and sizes where possible */ occomputeskipdata(state,root); /* Process ocnodes to mark those that are cacheable */ ocmarkcacheable(state,root); /* Process ocnodes to handle various semantic issues*/ occomputesemantics(tree->nodes); } /* Process ocnodes to compute name info*/ occomputefullnames(tree->root); if(kind == OCDATADDS) { if((flags & OCINMEMORY) == 0) { tree->data.xdrs = xxdr_filecreate(tree->data.file,tree->data.bod); } else { /* Switch to zero based memory */ tree->data.xdrs = xxdr_memcreate(tree->data.memory,tree->data.datasize,tree->data.bod); } MEMCHECK(tree->data.xdrs,OC_ENOMEM); } /* Put root into the state->trees list */ oclistpush(state->trees,(ocelem)root); if(rootp) *rootp = root; return stat; unwind: ocfreetree(tree); fail: return OCTHROW(stat); }
int ocddsdasmerge(OCstate* state, OCnode* dasroot, OCnode* ddsroot) { OClist* dasglobals = oclistnew(); OClist* dasnodes = oclistnew(); OClist* varnodes = oclistnew(); OClist* ddsnodes; unsigned int i,j; if(dasroot->tree == NULL || dasroot->tree->dxdclass != OCDAS) return THROW(OC_EINVAL); if(ddsroot->tree == NULL || (ddsroot->tree->dxdclass != OCDDS && ddsroot->tree->dxdclass != OCDATADDS)) return THROW(OC_EINVAL); ddsnodes = ddsroot->tree->nodes; /* 1. collect all the relevant DAS nodes; namely those that contain at least one attribute value. Simultaneously look for potential ambiguities if found; complain but continue: result are indeterminate. also collect globals separately*/ for(i=0;i<oclistlength(dasroot->tree->nodes);i++) { OCnode* das = (OCnode*)oclistget(dasroot->tree->nodes,i); int hasattributes = 0; if(das->octype == OC_Attribute) continue; /* ignore these for now*/ if(das->name == NULL || das->att.isglobal) { oclistpush(dasglobals,(ocelem)das); continue; } for(j=0;j<oclistlength(das->subnodes);j++) { OCnode* subnode = (OCnode*)oclistget(das->subnodes,j); if(subnode->octype == OC_Attribute) {hasattributes = 1; break;} } if(hasattributes) { /* Look for previously collected nodes with same name*/ for(j=0;j<oclistlength(dasnodes);j++) { OCnode* das2 = (OCnode*)oclistget(dasnodes,j); if(das->name == NULL || das2->name == NULL) continue; if(strcmp(das->name,das2->name)==0) { oc_log(LOGWARN,"oc_mergedas: potentially ambiguous DAS name: %s",das->name); } } oclistpush(dasnodes,(ocelem)das); } } /* 2. collect all the leaf DDS nodes (of type OC_Primitive)*/ for(i=0;i<oclistlength(ddsnodes);i++) { OCnode* dds = (OCnode*)oclistget(ddsnodes,i); if(dds->octype == OC_Primitive) oclistpush(varnodes,(ocelem)dds); } /* 3. For each das node, locate matching DDS node(s) and attach attributes to the DDS node(s). Match means: 1. DAS->fullname :: DDS->fullname 2. DAS->name :: DDS->fullname (support DAS names with embedded '.' 3. DAS->name :: DDS->name */ for(i=0;i<oclistlength(dasnodes);i++) { OCnode* das = (OCnode*)oclistget(dasnodes,i); for(j=0;j<oclistlength(varnodes);j++) { OCnode* dds = (OCnode*)oclistget(varnodes,j); if(strcmp(das->fullname,dds->fullname)==0 || strcmp(das->name,dds->fullname)==0 || strcmp(das->name,dds->name)==0) { mergedas1(dds,das); /* remove from dasnodes list*/ oclistset(dasnodes,i,(ocelem)NULL); } } } /* 4. If there are attributes left, then complain about them being lost.*/ for(i=0;i<oclistlength(dasnodes);i++) { OCnode* das = (OCnode*)oclistget(dasnodes,i); if(das != NULL) marklostattribute(das); } /* 5. Assign globals*/ for(i=0;i<oclistlength(dasglobals);i++) { OCnode* das = (OCnode*)oclistget(dasglobals,i); mergedas1(ddsroot,das); } /* cleanup*/ oclistfree(dasglobals); oclistfree(dasnodes); oclistfree(varnodes); return THROW(OC_NOERR); }