1/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc.
2   See the COPYRIGHT file for more information. */
3
4#define URLDECODE
5
6#include "config.h"
7#include <stdlib.h>
8#include <stdio.h>
9#include <string.h>
10#include <assert.h>
11
12#include "netcdf.h"
13
14#include "nclist.h"
15#include "ncbytes.h"
16#include "ncuri.h"
17#include "dceconstraints.h"
18#include "dceparselex.h"
19
20/* Forward */
21static void dumptoken(DCElexstatelexstate);
22static int tohex(int c);
23static void ceaddyytext(DCElexstatelex, int c);
24
25/****************************************************/
26/* Define 1 and > 1st legal characters */
27static char* wordchars1 =
28  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-+_/%\\";
29static char* wordcharsn =
30  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-+_/%\\";
31
32/* Number characters */
33static char* numchars1="+-0123456789";
34static char* numcharsn="Ee.+-0123456789";
35
36/**************************************************/
37
38int
39dcelex(YYSTYPElvalpDCEparsestatestate)
40{
41    DCElexstatelexstate = state->lexstate;
42    int token;
43    int c;
44    int len;
45    char* p=NULL;
46    token = 0;
47    ncbytesclear(lexstate->yytext);
48    ncbytesnull(lexstate->yytext);
49    p=lexstate->next;
50    while(token == 0 && (c=*p)) {
51 if(c <= ' ' || c >= '\177') {p++; continue;}
52 if(c == '"') {
53     int more = 1;
54     ceaddyytext(lexstate,c);
55     /* We have a SCAN_STRINGCONST */
56     while(more && (c=*(++p))) {
57 switch (c) {
58 case '"': p++; more=0; break;
59 case '\\':
60     c=*(++p);
61     switch (c) {
62     case 'r': c = '\r'; break;
63     case 'n': c = '\n'; break;
64     case 'f': c = '\f'; break;
65     case 't': c = '\t'; break;
66     case 'x': {
67 int d1,d2;
68 c = '?';
69 ++p;
70         d1 = tohex(*p++);
71 if(d1 < 0) {
72     dceerror(state,"Illegal \\xDD in SCAN_STRING");
73 } else {
74     d2 = tohex(*p++);
75     if(d2 < 0) {
76         dceerror(state,"Illegal \\xDD in SCAN_STRING");
77     } else {
78 c=(((unsigned int)d1)<<4) | (unsigned int)d2;
79     }
80 }
81     } break;
82     default: break;
83     }
84     break;
85 default: break;
86 }
87 ceaddyytext(lexstate,c);
88     }
89     token=SCAN_STRINGCONST;
90 } else if(strchr(numchars1,c) != NULL) {
91     /* we might have a SCAN_NUMBERCONST */
92     int isnumber = 0;
93     char* yytext;
94     char* endpoint;
95     ceaddyytext(lexstate,c);
96     for(p++;(c=*p);p++) {
97 if(strchr(numcharsn,c) == NULL) break;
98         ceaddyytext(lexstate,c);
99     }
100     /* See if this is a number */
101     ncbytesnull(lexstate->yytext);
102     yytext = ncbytescontents(lexstate->yytext);
103     (void)strtoll(yytext,&endpoint,10);
104     if(*yytext != '\0' && *endpoint == '\0')
105         isnumber = 1;
106     else {
107         (void)strtod(yytext,&endpoint);
108         if(*yytext != '\0' && *endpoint == '\0')
109             isnumber = 1; /* maybe */
110     }
111     /* A number followed by an id char is assumed to just be
112        a funny id */
113     if(isnumber && (*p == '\0' || strchr(wordcharsn,*p) == NULL))  {
114         token = SCAN_NUMBERCONST;
115     } else {
116 /* Now, if the funny word has a "." in it,
117    we have to back up to that dot */
118 char* dotpoint = strchr(yytext,'.');
119 if(dotpoint != NULL) {
120     p = dotpoint;
121     *dotpoint = '\0';
122 }
123 token = SCAN_WORD;
124     }
125 } else if(strchr(wordchars1,c) != NULL) {
126     /* we have a SCAN_WORD */
127     ceaddyytext(lexstate,c);
128     for(p++;(c=*p);p++) {
129 if(strchr(wordcharsn,c) == NULL) break;
130         ceaddyytext(lexstate,c);
131     }
132     token=SCAN_WORD;
133 } else {
134     /* we have a single char token */
135     token = c;
136     ceaddyytext(lexstate,c);
137     p++;
138 }
139    }
140    lexstate->next = p;
141    len = ncbyteslength(lexstate->yytext);
142    if(len > MAX_TOKEN_LENGTHlen = MAX_TOKEN_LENGTH;
143    strncpy(lexstate->lasttokentext,ncbytescontents(lexstate->yytext),len);
144    lexstate->lasttokentext[len] = '\0';
145    lexstate->lasttoken = token;
146    if(dcedebugdumptoken(lexstate);
147
148    /*Put return value onto Bison stack*/
149
150    if(ncbyteslength(lexstate->yytext) == 0)
151        *lvalp = NULL;
152    else {
153        *lvalp = ncbytesdup(lexstate->yytext);
154 nclistpush(lexstate->reclaim,(void*)*lvalp);
155    }
156
157    return token;
158}
159
160static void
161ceaddyytext(DCElexstatelex, int c)
162{
163    ncbytesappend(lex->yytext,(char)c);
164}
165
166static int
167tohex(int c)
168{
169    if(c >= 'a' && c <= 'f') return (c - 'a') + 0xa;
170    if(c >= 'A' && c <= 'F') return (c - 'A') + 0xa;
171    if(c >= '0' && c <= '9') return (c - '0');
172    return -1;
173}
174
175static void
176dumptoken(DCElexstatelexstate)
177{
178    switch (lexstate->lasttoken) {
179    case SCAN_STRINGCONST:
180        fprintf(stderr,"TOKEN = |\"%s\"|\n",lexstate->lasttokentext);
181 break;
182    case SCAN_WORD:
183    case SCAN_NUMBERCONST:
184    default:
185        fprintf(stderr,"TOKEN = |%s|\n",lexstate->lasttokentext);
186 break;
187    }
188}
189
190void
191dcelexinit(char* inputDCElexstate** lexstatep)
192{
193    DCElexstatelexstate = (DCElexstate*)malloc(sizeof(DCElexstate));
194
195    /* If lexstatep is NULL,
196       we want to free lexstate and
197       return to avoid a memory leak. */
198    if(lexstatep) {
199      *lexstatep = lexstate;
200    } else {
201      if(lexstate) free(lexstate);
202      return;
203    }
204
205    if(lexstate == NULL) return;
206    memset((void*)lexstate,0,sizeof(DCElexstate));
207
208
209
210#ifdef URLDECODE
211    lexstate->input = ncuridecode(input);
212#else
213    lexstate->input = strdup(input);
214#endif
215    lexstate->next = lexstate->input;
216    lexstate->yytext = ncbytesnew();
217    lexstate->reclaim = nclistnew();
218}
219
220void
221dcelexcleanup(DCElexstate** lexstatep)
222{
223    DCElexstatelexstate = *lexstatep;
224    if(lexstate == NULL) return;
225    if(lexstate->input != NULL) free(lexstate->input);
226    if(lexstate->reclaim != NULL) {
227 while(nclistlength(lexstate->reclaim) > 0) {
228     char* word = (char*)nclistpop(lexstate->reclaim);
229     if(word) free(word);
230 }
231 nclistfree(lexstate->reclaim);
232    }
233    ncbytesfree(lexstate->yytext);
234    free(lexstate);
235    *lexstatep = NULL;
236}


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