static OCerror
ocextractdds(OCstate* state, OCtree* tree)
{
    OCerror stat = OC_NOERR;
    size_t ddslen, bod, bodfound;
#ifdef OC_DISK_STORAGE
    /* Read until we find the separator (or EOF)*/
    ocbytesclear(state->packet);
    rewind(tree->data.file);
    do {
	char chunk[128];
	size_t count;
	/* read chunks of the file until we find the separator*/
        count = fread(chunk,1,sizeof(chunk),tree->data.file);
	if(count <= 0) break; /* EOF;*/
        ocbytesappendn(state->packet,chunk,count);
	bodfound = findbod(state->packet,&bod,&ddslen);
    } while(!bodfound);
#else /*!OC_DISK_STORAGE*/
    /* Read until we find the separator (or EOF)*/
    bodfound = findbod(state->packet,&bod,&ddslen);
#endif
    if(!bodfound) {/* No BOD; pretend */
	bod = tree->data.bod;
	ddslen = tree->data.datasize;
    }
    tree->data.bod = bod;
    tree->data.ddslen = ddslen;
    /* copy out the dds */
    if(ddslen > 0) {
        tree->text = (char*)ocmalloc(ddslen+1);
        memcpy((void*)tree->text,(void*)ocbytescontents(state->packet),ddslen);
        tree->text[ddslen] = '\0';
    } else
	tree->text = NULL;
#ifdef OC_DISK_STORAGE
    /* reset the position of the tmp file*/
    fseek(tree->data.file,tree->data.bod,SEEK_SET);
#else
    /* If the data part is not on an 8 byte boundary, make it so */
    if(tree->data.bod % 8 != 0) {
        unsigned long count = tree->data.datasize - tree->data.bod;
	char* dst = ocbytescontents(state->packet);
	char* src = dst + tree->data.bod;
	int i;
	/* memcpy((void*)dst,(void*)src,count); overlap*/
	for(i=0;i<count;i++) dst[i] = src[i]; /* avoid memcpy overlap */
	tree->data.datasize = count;
	tree->data.bod = 0;
	tree->data.ddslen = 0;
    }
#endif
    if(tree->text == NULL) stat = OC_EDATADDS;
    return THROW(stat);
}
Esempio n. 2
0
static OCerror
ocextractddsinfile(OCstate* state, OCtree* tree, OCflags flags)
{
    OCerror stat = OC_NOERR;
    size_t ddslen, bod, bodfound;

    /* Read until we find the separator (or EOF)*/
    ocbytesclear(state->packet);
    rewind(tree->data.file);
    bodfound = 0;
    do {
        char chunk[1024];
	size_t count;
	/* read chunks of the file until we find the separator*/
        count = fread(chunk,1,sizeof(chunk),tree->data.file);
	if(count <= 0) break; /* EOF;*/
        ocbytesappendn(state->packet,chunk,count);
	bodfound = ocfindbod(state->packet,&bod,&ddslen);
    } while(!bodfound);
    if(!bodfound) {/* No BOD; pretend */
	bod = tree->data.bod;
	ddslen = tree->data.datasize;
#ifdef OCDEBUG
fprintf(stderr,"missing bod: ddslen=%lu bod=%lu\n",
(unsigned long)ddslen,(unsigned long)bod);
#endif
    }
    tree->data.bod = bod;
    tree->data.ddslen = ddslen;
    /* copy out the dds */
    if(ddslen > 0) {
        tree->text = (char*)ocmalloc(ddslen+1);
        memcpy((void*)tree->text,(void*)ocbytescontents(state->packet),ddslen);
        tree->text[ddslen] = '\0';
    } else
	tree->text = NULL;
    /* reset the position of the tmp file*/
    if(fseek(tree->data.file,(long)tree->data.bod,SEEK_SET) < 0
       || tree->text == NULL)
	stat = OC_EDATADDS;
    return OCTHROW(stat);
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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);
}
Esempio n. 6
0
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);
}
Esempio n. 7
0
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.  */
}