(file) Return to lexer.c CVS log (file) (dir) Up to [OMI] / omi / wql

  1 mike  1.1 /*
  2           **==============================================================================
  3           **
  4           ** Open Management Infrastructure (OMI)
  5           **
  6           ** Copyright (c) Microsoft Corporation
  7           ** 
  8           ** Licensed under the Apache License, Version 2.0 (the "License"); you may not 
  9           ** use this file except in compliance with the License. You may obtain a copy 
 10           ** of the License at 
 11           **
 12           **     http://www.apache.org/licenses/LICENSE-2.0 
 13           **
 14           ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15           ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
 16           ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
 17           ** MERCHANTABLITY OR NON-INFRINGEMENT. 
 18           **
 19           ** See the Apache 2 License for the specific language governing permissions 
 20           ** and limitations under the License.
 21           **
 22 mike  1.1 **==============================================================================
 23           */
 24           
 25           #include "wql.h"
 26           #include <ctype.h>
 27           #include <base/strings.h>
 28           #include "state.h"
 29           #include "wqlyacc.h"
 30           
 31           extern void* wqlmalloc(size_t size);
 32           extern MI_Char* wqlstrdup(const MI_Char* str);
 33           
 34           int wqllex()
 35           {
 36               const MI_Char* p = wqlstate.ptr;
 37           
 38               /* Skip whitespace */
 39               while (*p && isspace(*p))
 40                   p++;
 41           
 42               /* Return on end-of-file */
 43 mike  1.1     if (*p == '\0')
 44               {
 45                   wqlstate.ptr = p;
 46                   return 0;
 47               }
 48           
 49               /* Recognize identifier */
 50               if (isalpha(*p) || *p == '_')
 51               {
 52                   const MI_Char* start = p++;
 53                   size_t n;
 54           
 55                   while (isalnum(*p) || *p == '_')
 56                       p++;
 57           
 58                   wqlstate.ptr = p;
 59           
 60                   if (Zncasecmp(start, MI_T("select"), 6) == 0)
 61                       return WQL_SELECT;
 62                   else if (Zncasecmp(start, MI_T("from"), 4) == 0)
 63                       return WQL_FROM;
 64 mike  1.1         else if (Zncasecmp(start, MI_T("where"), 5) == 0)
 65                       return WQL_WHERE;
 66                   else if (Zncasecmp(start, MI_T("not"), 3) == 0)
 67                       return WQL_NOT;
 68                   else if (Zncasecmp(start, MI_T("and"), 3) == 0)
 69                       return WQL_AND;
 70                   else if (Zncasecmp(start, MI_T("or"), 2) == 0)
 71                       return WQL_OR;
 72                   else if (Zncasecmp(start, MI_T("null"), 2) == 0)
 73                       return WQL_NULL;
 74                   else if (Zncasecmp(start, MI_T("true"), 4) == 0)
 75                   {
 76                       wqllval.boolean = 1;
 77                       return WQL_BOOLEAN;
 78                   }
 79                   else if (Zncasecmp(start, MI_T("false"), 5) == 0)
 80                   {
 81                       wqllval.boolean = 0;
 82                       return WQL_BOOLEAN;
 83                   }
 84           
 85 mike  1.1         n = p - start;
 86                   wqllval.string = (MI_Char*)wqlmalloc(n + 1);
 87           
 88                   if (!wqllval.string)
 89                       return -1;
 90           
 91                   memcpy(wqllval.string, start, n);
 92                   wqllval.string[n] = '\0';
 93           
 94                   return WQL_IDENTIFIER;
 95               }
 96           
 97               /* Recognize number (integer or double) */
 98               if (*p == '+' || *p == '-' || isdigit(*p))
 99               {
100                   const MI_Char* start = p++;
101           
102                   while (isdigit(*p))
103                       p++;
104           
105                   if (*p == '.')
106 mike  1.1         {
107                       MI_Char* end;
108                       wqllval.real = Ztod(start, &end);
109                       p = end;
110                       wqlstate.ptr = p;
111                       return WQL_REAL;
112                   }
113                   else
114                   {
115                       MI_Char* end;
116                       wqllval.integer = Ztoll(start, &end, 10);
117                       p = end;
118                       wqlstate.ptr = p;
119                       return WQL_INTEGER;
120                   }
121               }
122           
123               /* Recognize string literal */
124               if (*p == '"')
125               {
126                   const MI_Char* start = ++p;
127 mike  1.1         size_t n = 0;
128                   MI_Char* q;
129           
130                   /* Determine the length of the string */
131                   while (*p && *p != '"')
132                   {
133                       if (*p == '\\')
134                       {
135                           if (*++p == '\0')
136                               return -1;
137                       }
138           
139                       p++;
140                       n++;
141                   }
142           
143                   /* Allocate new string */
144                   {
145                       q = wqlmalloc(n + 1);
146           
147                       if (!q)
148 mike  1.1                 return -1;
149           
150                       wqllval.string = q;
151                   }
152           
153                   /* Convert string */
154                   for (p = start; *p && *p != '"'; )
155                   {
156                       if (*p == '\\')
157                       {
158                           p++;
159                           switch (*p)
160                           {
161                               case '\0':
162                                   return -1;
163                               case 'n':
164                                   *q++ = '\n';
165                                   break;
166                               case 'r':
167                                   *q++ = '\r';
168                                   break;
169 mike  1.1                     case 'f':
170                                   *q++ = '\r';
171                                   break;
172                               case '"':
173                                   *q++ = '"';
174                                   break;
175                               case '\\':
176                                   *q++ = '\\';
177                                   break;
178                               default:
179                                   *q++ = *p;
180                           }
181                           p++;
182                       }
183                       else
184                           *q++ = *p++;
185                   }
186           
187                   /* String literal must be terminated */
188                   if (*p++ != '"')
189                       return -1;
190 mike  1.1 
191                   /* Null terminate string */
192                   *q = '\0';
193                   wqlstate.ptr = p;
194                   return WQL_STRING;
195               }
196           
197               /* WQL_EQ */
198               if (p[0] == '=')
199               {
200                   wqlstate.ptr = p + 1;
201                   return WQL_EQ;
202               }
203           
204               /* WQL_NE */
205               if ((p[0] == '<' && p[1] == '>') || (p[0] == '!' && p[1] == '='))
206               {
207                   wqlstate.ptr = p + 2;
208                   return WQL_NE;
209               }
210           
211 mike  1.1     /* WQL_LE */
212               if (p[0] == '<' && p[1] == '=')
213               {
214                   wqlstate.ptr = p + 2;
215                   return WQL_LE;
216               }
217           
218               /* WQL_LT */
219               if (p[0] == '<')
220               {
221                   wqlstate.ptr = p + 1;
222                   return WQL_LT;
223               }
224           
225               /* WQL_GE */
226               if (p[0] == '>' && p[1] == '=')
227               {
228                   wqlstate.ptr = p + 2;
229                   return WQL_GE;
230               }
231           
232 mike  1.1     /* WQL_GT */
233               if (p[0] == '>')
234               {
235                   wqlstate.ptr = p + 1;
236                   return WQL_GT;
237               }
238           
239               /* Match single characters */
240               if (*p == '*' || *p == '(' || *p == ')' || *p == ',')
241               {
242                   wqlstate.ptr = p + 1;
243                   return *p;
244               }
245           
246               /* Unrecognized tokens */
247               return WQL_ERROR;
248           }

ViewCVS 0.9.2