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

Diff for /omi/wql/wql.c between version 1.2 and 1.3

version 1.2, 2015/04/20 18:10:35 version 1.3, 2015/04/20 18:20:37
Line 23 
Line 23 
 */ */
  
 #include "wql.h" #include "wql.h"
   #include <ctype.h>
  
 #ifndef _MSC_VER #ifndef _MSC_VER
 #include <pthread.h> #include <pthread.h>
Line 31 
Line 32 
 #include <stdlib.h> #include <stdlib.h>
 #include <stdio.h> #include <stdio.h>
 #include <string.h> #include <string.h>
 #include <base/strings.h>  #include <pal/strings.h>
 #include <base/classdecl.h> #include <base/classdecl.h>
 #include <base/helpers.h> #include <base/helpers.h>
 #include <base/io.h>  #include <pal/format.h>
 #include "wqlyacc.h" #include "wqlyacc.h"
 #include "state.h" #include "state.h"
   #include "like.h"
  
 extern int wqlparse(); extern int wqlparse();
   extern void WQL_ResetParser();
  
 WQL_State wqlstate; WQL_State wqlstate;
  
 #ifndef _MSC_VER  #ifdef _MSC_VER
   /* TODO: Fix this otherwise we are not thread safe */
   static void _Lock() {  }
   static void _Unlock() {  }
   #else
 static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER;
 static void _Lock() { pthread_mutex_lock(&_mutex); } static void _Lock() { pthread_mutex_lock(&_mutex); }
 static void _Unlock() { pthread_mutex_unlock(&_mutex); } static void _Unlock() { pthread_mutex_unlock(&_mutex); }
Line 53 
Line 60 
     return Batch_Get(wqlstate.wql->batch, size);     return Batch_Get(wqlstate.wql->batch, size);
 } }
  
 MI_Char* wqlstrdup(const MI_Char * str)  ZChar* wqlstrdup(const ZChar * str)
 { {
     return Batch_Zdup(wqlstate.wql->batch, str);      return Batch_Tcsdup(wqlstate.wql->batch, str);
 } }
  
 WQL* WQL_Parse(const MI_Char* text, Batch* batch)  WQL* WQL_Parse(
       const ZChar* text,
       Batch* batch,
       WQL_Dialect dialect)
 { {
     WQL* self = NULL;     WQL* self = NULL;
     int deleteBatch;     int deleteBatch;
Line 69 
Line 79 
     /* Create batch if none */     /* Create batch if none */
     if (!batch)     if (!batch)
     {     {
         batch = Batch_New(64);          batch = Batch_New(BATCH_MAX_PAGES);
  
         if (!batch)         if (!batch)
         {         {
Line 98 
Line 108 
         }         }
     }     }
  
       /* Set the dialect */
       self->dialect = dialect;
   
     /* Initialize WQL object */     /* Initialize WQL object */
     self->batch = batch;     self->batch = batch;
     self->deleteBatch = deleteBatch;     self->deleteBatch = deleteBatch;
     self->text = Batch_Zdup(batch, text);      self->text = Batch_Tcsdup(batch, text);
   
       if (!self->text)
       {
           if (deleteBatch)
               Batch_Delete(batch);
   
           _Unlock();
           return NULL;
       }
  
     /* Initialize global parser state */     /* Initialize global parser state */
     memset(&wqlstate, 0, sizeof(WQL_State));     memset(&wqlstate, 0, sizeof(WQL_State));
     wqlstate.text = self->text;     wqlstate.text = self->text;
     wqlstate.size = (int)Zlen(text);      wqlstate.size = (int)Tcslen(text);
     wqlstate.wql = self;     wqlstate.wql = self;
     wqlstate.ptr = text;     wqlstate.ptr = text;
  
     /* Parse the text */     /* Parse the text */
     wqlparse();     wqlparse();
  
       /* Reset global parser states */
       WQL_ResetParser();
   
     /* Get return status */     /* Get return status */
     if (wqlstate.status != 0)     if (wqlstate.status != 0)
     {     {
Line 140 
Line 165 
     /* Create batch if none */     /* Create batch if none */
     if (!batch)     if (!batch)
     {     {
         batch = Batch_New(64);          batch = Batch_New(BATCH_MAX_PAGES);
  
         if (!batch)         if (!batch)
             return NULL;             return NULL;
Line 166 
Line 191 
     {     {
         for (i = 0; i < self->nproperties; i++)         for (i = 0; i < self->nproperties; i++)
         {         {
             result->properties[i] = Batch_Zdup(batch, self->properties[i]);              result->properties[i] = Batch_Tcsdup(batch, self->properties[i]);
  
             if (!result->properties[i])             if (!result->properties[i])
                 goto failed;                 goto failed;
Line 178 
Line 203 
     /* Clone classname */     /* Clone classname */
     if (self->className)     if (self->className)
     {     {
         result->className = Batch_Zdup(batch, self->className);          result->className = Batch_Tcsdup(batch, self->className);
  
         if (!result->className)         if (!result->className)
             goto failed;             goto failed;
Line 196 
Line 221 
                 if (self->symbols[i].value.string)                 if (self->symbols[i].value.string)
                 {                 {
                     result->symbols[i].value.string =                     result->symbols[i].value.string =
                         Batch_Zdup(batch, self->symbols[i].value.string);                          Batch_Tcsdup(batch, self->symbols[i].value.string);
  
                     if (!result->symbols[i].value.string)                     if (!result->symbols[i].value.string)
                         goto failed;                         goto failed;
Line 210 
Line 235 
     /* Clone text */     /* Clone text */
     if (self->text)     if (self->text)
     {     {
         result->text = Batch_Zdup(batch, self->text);          result->text = Batch_Tcsdup(batch, self->text);
  
         if (!result->text)         if (!result->text)
             goto failed;             goto failed;
Line 241 
Line 266 
  
 MI_Boolean WQL_ContainsProperty( MI_Boolean WQL_ContainsProperty(
     const WQL* wql,     const WQL* wql,
     const MI_Char* propertyName)      const ZChar* propertyName)
 { {
     size_t i;     size_t i;
  
Line 250 
Line 275 
  
     for (i = 0; i < wql->nproperties; i++)     for (i = 0; i < wql->nproperties; i++)
     {     {
         if (Zcasecmp(propertyName, wql->properties[i]) == 0)          if (Tcscmp(propertyName, wql->properties[i]) == 0)
             return MI_TRUE;             return MI_TRUE;
     }     }
  
Line 259 
Line 284 
 } }
  
 int _ValidateLookup( int _ValidateLookup(
     const MI_Char* name,      const ZChar* name,
       const ZChar* embeddedClassName,
       const ZChar* embeddedPropertyName,
     WQL_Symbol* symbol,     WQL_Symbol* symbol,
     Batch* batch,     Batch* batch,
     void* data)     void* data)
Line 267 
Line 294 
     const MI_ClassDecl* cd = (const MI_ClassDecl*)data;     const MI_ClassDecl* cd = (const MI_ClassDecl*)data;
     const MI_PropertyDecl* pd;     const MI_PropertyDecl* pd;
  
   #if 0
       printf("_ValidateLookup(): {%s}{%s}{%s}\n",
           name, embeddedClassName, embeddedPropertyName);
   #endif
   
     MI_UNUSED(batch);     MI_UNUSED(batch);
  
     /* Check for null parameters */     /* Check for null parameters */
     if (!name || !symbol || !data)     if (!name || !symbol || !data)
         return -1;         return -1;
  
       /* Handle ISA operation */
       if (name && embeddedClassName && !embeddedPropertyName)
       {
           symbol->type = WQL_TYPE_BOOLEAN;
           symbol->value.boolean = MI_TRUE;
           return 0;
       }
   
     /* Lookup the property with this name */     /* Lookup the property with this name */
     {     {
         pd = ClassDecl_FindPropertyDecl(cd, name);         pd = ClassDecl_FindPropertyDecl(cd, name);
Line 310 
Line 350 
             symbol->type = WQL_TYPE_STRING;             symbol->type = WQL_TYPE_STRING;
             symbol->value.string = MI_T("");             symbol->value.string = MI_T("");
             return 0;             return 0;
           case MI_INSTANCE:
               /* Use WQL_TYPE_ANY since the type of the embedded instance property
                * cannot be deterined.
                */
               symbol->type = WQL_TYPE_ANY;
               return 0;
         default:         default:
             break;             break;
     }     }
Line 333 
Line 379 
      * property-literal mismatches.      * property-literal mismatches.
      */      */
     if (WQL_Eval(self, _ValidateLookup, (void*)cd) == -1)     if (WQL_Eval(self, _ValidateLookup, (void*)cd) == -1)
       {
           return -1;
       }
   
       return 0;
   }
   
   static int _FixupTypeAux(WQL_Symbol* sym, WQL_Type type)
   {
       if (sym->type != WQL_TYPE_STRING)
           return -1;
   
       if (type == WQL_TYPE_REAL)
       {
           ZChar* end = NULL;
           sym->value.real = Tcstod(sym->value.string, &end);
   
           if (end == sym->value.string)
               return -1;
   
           if (*end != '\0')
               return -1;
   
           sym->type = WQL_TYPE_REAL;
           return 0;
       }
       else if (type == WQL_TYPE_INTEGER)
       {
           ZChar* end = NULL;
           sym->value.integer = Tcstoll(sym->value.string, &end, 10);
   
           if (end == sym->value.string)
               return -1;
   
           if (*end != '\0')
               return -1;
   
           sym->type = WQL_TYPE_INTEGER;
           return 0;
       }
       else if (type == WQL_TYPE_BOOLEAN)
       {
           if (Tcscasecmp(sym->value.string, PAL_T("true")) == 0)
               sym->value.boolean = 1;
           else if (Tcscasecmp(sym->value.string, PAL_T("false")) == 0)
               sym->value.boolean = 0;
           else
         return -1;         return -1;
  
           sym->type = WQL_TYPE_BOOLEAN;
     return 0;     return 0;
 } }
  
       return -1;
   }
   
   /*
    * If the types of the two symbols are incompatible, then if either symbol
    * is a string, attempt to convert it to the type of the other symbol. For
    * example, the string will be converted to a real, integer, or boolean.
    */
   static int _FixupType(WQL_Symbol* lhs, WQL_Symbol* rhs)
   {
       if (lhs->type == rhs->type)
           return 0;
   
       if (lhs->type == WQL_TYPE_STRING)
       {
           return _FixupTypeAux(lhs, rhs->type);
       }
       else if (rhs->type == WQL_TYPE_STRING)
       {
           return _FixupTypeAux(rhs, lhs->type);
       }
   
       return -1;
   }
   
   /*
   **-----------------------------------------------------------------------------
   ** @brief   See if a string matches a template string
   **
   ** @param   [in] s1 - one string
   ** @param   [in] s1 - another string
   **
   ** @returns 0 for a match, > 0 for s1 > s2; < 0 for s1 < s2
   **-----------------------------------------------------------------------------
   */
   
 static int _Compare(const WQL_Symbol* s1, const WQL_Symbol* s2) static int _Compare(const WQL_Symbol* s1, const WQL_Symbol* s2)
 { {
     switch (s1->type)     switch (s1->type)
Line 366 
Line 496 
         }         }
         case WQL_TYPE_STRING:         case WQL_TYPE_STRING:
         {         {
             return Zcmp(s1->value.string, s2->value.string);              return Tcscasecmp(s1->value.string, s2->value.string);
         }         }
         default:         default:
             return -1;             return -1;
     }     }
 } }
  
   static int _CompareLike(const WQL_Symbol* s1, const WQL_Symbol* s2)
   {
       const ZChar* pattern;
       const ZChar* string;
   
       if (s1->type != WQL_TYPE_STRING || s2->type != WQL_TYPE_STRING)
           return -1;
   
       string = s1->value.string;
       pattern = s2->value.string;
   
       if (WQL_MatchLike(pattern, string, '\0'))
           return 0;
       else
           return -1;
   }
   
 extern int WQL_Eval( extern int WQL_Eval(
     const WQL* wql,     const WQL* wql,
     WQL_Lookup lookup,     WQL_Lookup lookup,
Line 395 
Line 542 
         const WQL_Symbol* sym = &wql->symbols[i];         const WQL_Symbol* sym = &wql->symbols[i];
         WQL_Type type = sym->type;         WQL_Type type = sym->type;
  
           if (nsymbols >= WQL_MAX_SYMBOLS)
               return -1;
   
         switch (type)         switch (type)
         {         {
             case WQL_TYPE_AND:             case WQL_TYPE_AND:
Line 409 
Line 559 
                     WQL_Symbol s;                     WQL_Symbol s;
                     int f;                     int f;
  
                       memset(&s, '\0', sizeof(s));
   
                     if (s1.type != WQL_TYPE_BOOLEAN)                     if (s1.type != WQL_TYPE_BOOLEAN)
                         return -1;                         return -1;
                     if (s2.type != WQL_TYPE_BOOLEAN)                     if (s2.type != WQL_TYPE_BOOLEAN)
Line 431 
Line 583 
             {             {
                 if (nsymbols < 1)                 if (nsymbols < 1)
                     return -1;                     return -1;
   
                 {                 {
                     WQL_Symbol s1 = symbols[--nsymbols];                     WQL_Symbol s1 = symbols[--nsymbols];
                     WQL_Symbol s;                     WQL_Symbol s;
  
                       memset(&s, '\0', sizeof(s));
   
                     if (s1.type != WQL_TYPE_BOOLEAN)                     if (s1.type != WQL_TYPE_BOOLEAN)
                         return -1;                         return -1;
  
Line 452 
Line 605 
             case WQL_TYPE_LE:             case WQL_TYPE_LE:
             case WQL_TYPE_GT:             case WQL_TYPE_GT:
             case WQL_TYPE_GE:             case WQL_TYPE_GE:
               case WQL_TYPE_LIKE:
             {             {
                 if (nsymbols < 2)                 if (nsymbols < 2)
                     return -1;                     return -1;
   
                 {                 {
                     WQL_Symbol s2 = symbols[--nsymbols];                     WQL_Symbol s2 = symbols[--nsymbols];
                     WQL_Symbol s1 = symbols[--nsymbols];                     WQL_Symbol s1 = symbols[--nsymbols];
Line 463 
Line 616 
                     int r;                     int r;
                     int f;                     int f;
  
                       memset(&s, '\0', sizeof(s));
   
                       /* This type only returned by _ValidateLookup() */
                       if (s2.type == WQL_TYPE_ANY || s1.type == WQL_TYPE_ANY)
                       {
                           return 0;
                       }
   
                     /* If either operand is null */                     /* If either operand is null */
                     if (s1.type == WQL_TYPE_NULL || s2.type == WQL_TYPE_NULL)                     if (s1.type == WQL_TYPE_NULL || s2.type == WQL_TYPE_NULL)
                     {                     {
Line 470 
Line 631 
                         int bothNull =                         int bothNull =
                             (s1.type==WQL_TYPE_NULL && s2.type==WQL_TYPE_NULL);                             (s1.type==WQL_TYPE_NULL && s2.type==WQL_TYPE_NULL);
  
                         if (type == WQL_TYPE_EQ)                          if (type == WQL_TYPE_EQ || type == WQL_TYPE_LIKE)
                         {                         {
                             s.type = WQL_TYPE_BOOLEAN;                             s.type = WQL_TYPE_BOOLEAN;
                             s.value.boolean = bothNull ? 1 : 0;                             s.value.boolean = bothNull ? 1 : 0;
Line 489 
Line 650 
                     }                     }
                     else                     else
                     {                     {
                         /* Reject type mismatch */  
                         if (s1.type != s2.type)                          if (type == WQL_TYPE_LIKE)
                               r = _CompareLike(&s1, &s2);
                           else
                           {
                               WQL_Symbol lhs = s1;
                               WQL_Symbol rhs = s2;
   
                               if (lhs.type != rhs.type)
                               {
                                   if (_FixupType(&lhs, &rhs) != 0)
                             return -1;                             return -1;
                               }
  
                         r = _Compare(&s1, &s2);                              r = _Compare(&lhs, &rhs);
                           }
  
                         switch (type)                         switch (type)
                         {                         {
                             case WQL_TYPE_EQ:                             case WQL_TYPE_EQ:
                               case WQL_TYPE_LIKE:
                                 f = (r == 0);                                 f = (r == 0);
                                 break;                                 break;
                             case WQL_TYPE_NE:                             case WQL_TYPE_NE:
Line 533 
Line 706 
  
                 memset(&tmp, 0, sizeof(WQL_Symbol));                 memset(&tmp, 0, sizeof(WQL_Symbol));
  
                 if ((*lookup)(sym->value.string, &tmp, wql->batch, data) != 0)                  if ((*lookup)(
                       sym->value.string,
                       sym->value.embeddedClassName,
                       sym->value.embeddedPropertyName,
                       &tmp,
                       wql->batch,
                       data) != 0)
                   {
                     return -1;                     return -1;
                   }
  
                 if (tmp.type != WQL_TYPE_BOOLEAN &&                 if (tmp.type != WQL_TYPE_BOOLEAN &&
                     tmp.type != WQL_TYPE_INTEGER &&                     tmp.type != WQL_TYPE_INTEGER &&
                     tmp.type != WQL_TYPE_REAL &&                     tmp.type != WQL_TYPE_REAL &&
                     tmp.type != WQL_TYPE_STRING &&                     tmp.type != WQL_TYPE_STRING &&
                     tmp.type != WQL_TYPE_NULL)                      tmp.type != WQL_TYPE_NULL &&
                       tmp.type != WQL_TYPE_ANY)
                 {                 {
                     return -1;                     return -1;
                 }                 }
   
                 symbols[nsymbols++] = tmp;                 symbols[nsymbols++] = tmp;
                 break;                 break;
             }             }
Line 553 
Line 734 
             case WQL_TYPE_REAL:             case WQL_TYPE_REAL:
             case WQL_TYPE_STRING:             case WQL_TYPE_STRING:
             case WQL_TYPE_NULL:             case WQL_TYPE_NULL:
               case WQL_TYPE_ANY:
                 symbols[nsymbols++] = *sym;                 symbols[nsymbols++] = *sym;
                 break;                 break;
   
               case WQL_TYPE_ISA:
               {
                   WQL_Symbol s2;
                   WQL_Symbol s1;
   
                   if (nsymbols < 2)
                       return -1;
   
                   s2 = symbols[--nsymbols];
                   s1 = symbols[--nsymbols];
   
                   if (s1.type != WQL_TYPE_STRING)
                       return -1;
   
                   if (s2.type != WQL_TYPE_STRING)
                       return -1;
   
                   /* Ask lookup() to perform ISA operation */
                   {
                       WQL_Symbol tmp = s2;
   
                       if ((*lookup)(
                           s1.value.string, /* Embedded property name */
                           s2.value.string, /* Embedded class name */
                           NULL,
                           &tmp,
                           wql->batch,
                           data) != 0)
                       {
                           return -1;
                       }
   
                       symbols[nsymbols++] = tmp;
                   }
                   break;
               }
         }         }
     }     }
  
Line 562 
Line 781 
     if (nsymbols != 1)     if (nsymbols != 1)
         return -1;         return -1;
  
       /* There should be exactly 1 symbol left on stack */
     /* Final token on stack should be boolean */     /* Final token on stack should be boolean */
     if (symbols[0].type != WQL_TYPE_BOOLEAN)     if (symbols[0].type != WQL_TYPE_BOOLEAN)
         return -1;         return -1;
Line 574 
Line 794 
 } }
  
 int WQL_LookupInstanceProperty( int WQL_LookupInstanceProperty(
     const MI_Char* name,      const ZChar* name,
       const ZChar* embeddedClassName,
       const ZChar* embeddedPropertyName,
     WQL_Symbol* symbol,     WQL_Symbol* symbol,
     Batch* batch,     Batch* batch,
     void* data)     void* data)
Line 585 
Line 807 
     MI_Type type;     MI_Type type;
     MI_Uint32 flags;     MI_Uint32 flags;
  
   #if 0
       printf("WQL_LookupInstanceProperty{%s}{%s}{%s}\n",
           name, embeddedClassName, embeddedPropertyName);
   #endif
   
     /* Check for null parameters */     /* Check for null parameters */
     if (!name || !symbol || !data)     if (!name || !symbol || !data)
         return -1;         return -1;
Line 596 
Line 823 
     if (r != MI_RESULT_OK)     if (r != MI_RESULT_OK)
         return -1;         return -1;
  
       /* Handle ISA opeartion and ISA check for gets on embedded properties:
        * For example: SourceInstance.CIM_StorageVolume.OperationalStatus
        */
       if (embeddedClassName)
       {
           const MI_ClassDecl* cd;
           MI_Boolean isa = MI_FALSE;
   
           if (type != MI_INSTANCE || !value.instance)
               return -1;
   
           /* Perform ISA check */
   
           for (cd = value.instance->classDecl; cd; cd = cd->superClassDecl)
           {
               if (Tcscmp(cd->name, embeddedClassName) == 0)
               {
                   isa = MI_TRUE;
                   break;
               }
           }
   
           /* If lookup was called just to perform an ISA check */
   
           if (!embeddedPropertyName)
           {
               symbol->type = WQL_TYPE_BOOLEAN;
               symbol->value.boolean = isa;
               return 0;
           }
   
           /* If lookup was called to get an embedded intance property */
   
           if (embeddedPropertyName && !isa)
           {
               /* Class was wrong type */
               return -1;
           }
       }
   
       /* Handle get embedded instance property */
   
       if (embeddedPropertyName)
       {
           if (type != MI_INSTANCE || !value.instance)
               return -1;
   
           r = __MI_Instance_GetElement(
               value.instance,
               embeddedPropertyName,
               &value,
               &type,
               &flags, 0);
   
           if (r != MI_RESULT_OK)
               return -1;
       }
   
     /* Handle null case */     /* Handle null case */
     if (flags & MI_FLAG_NULL)     if (flags & MI_FLAG_NULL)
     {     {
Line 676 
Line 961 
         }         }
         case MI_DATETIME:         case MI_DATETIME:
         {         {
             MI_Char buf[26];              ZChar buf[26];
             DatetimeToStr(&value.datetime, buf);             DatetimeToStr(&value.datetime, buf);
             symbol->type = WQL_TYPE_STRING;             symbol->type = WQL_TYPE_STRING;
             symbol->value.string = Batch_Zdup(batch, buf);              symbol->value.string = Batch_Tcsdup(batch, buf);
               if (!symbol->value.string)
                   return -1;
               else
             return 0;             return 0;
         }         }
         case MI_STRING:         case MI_STRING:
         {         {
             symbol->type = WQL_TYPE_STRING;             symbol->type = WQL_TYPE_STRING;
             symbol->value.string = Batch_Zdup(batch, value.string);              symbol->value.string = Batch_Tcsdup(batch, value.string);
               if (!symbol->value.string)
                   return -1;
               else
             return 0;             return 0;
         }         }
  


Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

ViewCVS 0.9.2