source: XIOS3/trunk/extern/src_netcdf4/dcelex.c @ 2471

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

Add improved nectdf internal library src

YM

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