wbemprox: Add support for parsing ASSOCIATORS OF queries.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
7e14df06f1
commit
d83b71ebfd
|
@ -30,17 +30,17 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
|
WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
|
||||||
|
|
||||||
HRESULT create_view( const struct property *proplist, const WCHAR *class,
|
HRESULT create_view( const WCHAR *path, const struct keyword *keywordlist, const WCHAR *class,
|
||||||
const struct expr *cond, struct view **ret )
|
const struct property *proplist, const struct expr *cond, struct view **ret )
|
||||||
{
|
{
|
||||||
struct view *view = heap_alloc( sizeof(struct view) );
|
struct view *view = heap_alloc_zero( sizeof(*view) );
|
||||||
|
|
||||||
if (!view) return E_OUTOFMEMORY;
|
if (!view) return E_OUTOFMEMORY;
|
||||||
view->proplist = proplist;
|
view->path = path;
|
||||||
view->table = grab_table( class );
|
view->keywordlist = keywordlist;
|
||||||
view->cond = cond;
|
view->proplist = proplist;
|
||||||
view->result = NULL;
|
view->table = grab_table( class );
|
||||||
view->count = 0;
|
view->cond = cond;
|
||||||
*ret = view;
|
*ret = view;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -357,7 +357,7 @@ struct table *grab_table( const WCHAR *name )
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY( table, table_list, struct table, entry )
|
LIST_FOR_EACH_ENTRY( table, table_list, struct table, entry )
|
||||||
{
|
{
|
||||||
if (!strcmpiW( table->name, name ))
|
if (name && !strcmpiW( table->name, name ))
|
||||||
{
|
{
|
||||||
TRACE("returning %p\n", table);
|
TRACE("returning %p\n", table);
|
||||||
return addref_table( table );
|
return addref_table( table );
|
||||||
|
|
|
@ -156,14 +156,37 @@ static void test_select( IWbemServices *services )
|
||||||
static void test_associators( IWbemServices *services )
|
static void test_associators( IWbemServices *services )
|
||||||
{
|
{
|
||||||
static const WCHAR query1[] =
|
static const WCHAR query1[] =
|
||||||
{'A','S','S','O','C','I','A','T','O','R','S',' ','O','F',' ','{','W','i','n','3','2','_',
|
{'A','S','S','O','C','I','A','T','O','R','S',' ',' ','O','F','{','W','i','n','3','2','_',
|
||||||
'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','D','=','"','C',':','"','}',0};
|
'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','D','=','"','C',':','"','}',0};
|
||||||
static const WCHAR query2[] =
|
static const WCHAR query2[] =
|
||||||
{'A','S','S','O','C','I','A','T','O','R','S',' ','O','F',' ','{','W','i','n','3','2','_',
|
{'A','S','S','O','C','I','A','T','O','R','S',' ','O','F',' ','{','W','i','n','3','2','_',
|
||||||
'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','D','=','"','C',':','"','}',' ',
|
'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','D','=','"','C',':','"','}',' ',
|
||||||
'W','H','E','R','E',' ','A','s','s','o','c','C','l','a','s','s',' ','=',' ','W','i','n','3','2','_',
|
'W','H','E','R','E',' ','A','s','s','o','c','C','l','a','s','s','=','W','i','n','3','2','_',
|
||||||
'L','o','g','i','c','a','l','D','i','s','k','T','o','P','a','r','t','i','t','i','o','n',0};
|
'L','o','g','i','c','a','l','D','i','s','k','T','o','P','a','r','t','i','t','i','o','n',0};
|
||||||
static const WCHAR *test[] = { query1, query2 };
|
static const WCHAR query3[] =
|
||||||
|
{'A','S','S','O','C','I','A','T','O','R','S',' ',' ','O','F',' ','{','W','i','n','3','2','_',
|
||||||
|
'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','D','}',0};
|
||||||
|
static const WCHAR query4[] =
|
||||||
|
{'A','S','S','O','C','I','A','T','O','R','S',' ',' ','O','F',' ','{','W','i','n','3','2','_',
|
||||||
|
'D','i','s','k','D','r','i','v','e','.','D','e','v','i','c','e','I','D','=',
|
||||||
|
'\'','\\','\\','.','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','0','\'','}',0};
|
||||||
|
static const WCHAR query5[] =
|
||||||
|
{'A','S','S','O','C','I','A','T','O','R','S',' ','O','F',' ','{','W','i','n','3','2','_',
|
||||||
|
'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','D','=','"','C',':','"','}',' ',
|
||||||
|
'W','H','E','R','E',' ','A','s','s','o','c','C','l','a','s','s','=','W','i','n','3','2','_',
|
||||||
|
'L','o','g','i','c','a','l','D','i','s','k','T','o','P','a','r','t','i','t','i','o','n',' ',
|
||||||
|
'C','l','a','s','s','D','e','f','s','O','n','l','y',0};
|
||||||
|
static const WCHAR query6[] =
|
||||||
|
{'A','S','S','O','C','I','A','T','O','R','S',' ','O','F',' ','{','W','i','n','3','2','_',
|
||||||
|
'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','D','=','"','C',':','"','}',' ',
|
||||||
|
'W','H','E','R','E',' ','C','l','a','s','s','D','e','f','s','O','n','l','y',0};
|
||||||
|
static const WCHAR query7[] =
|
||||||
|
{'A','S','S','O','C','I','A','T','O','R','S',' ','O','F',' ','{','W','i','n','3','2','_',
|
||||||
|
'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','D','=','"','C',':','"','}',' ',
|
||||||
|
'W','H','E','R','E',' ','C','l','a','s','s','D','e','f','s','O','n','l','y',' ',
|
||||||
|
'A','s','s','o','c','C','l','a','s','s',' ','=',' ','W','i','n','3','2','_',
|
||||||
|
'L','o','g','i','c','a','l','D','i','s','k','T','o','P','a','r','t','i','t','i','o','n',0};
|
||||||
|
static const WCHAR *test[] = { query1, query2, query3, query4, query5, query6, query7 };
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
IEnumWbemClassObject *result;
|
IEnumWbemClassObject *result;
|
||||||
UINT i;
|
UINT i;
|
||||||
|
@ -171,7 +194,7 @@ static void test_associators( IWbemServices *services )
|
||||||
for (i = 0; i < ARRAY_SIZE( test ); i++)
|
for (i = 0; i < ARRAY_SIZE( test ); i++)
|
||||||
{
|
{
|
||||||
hr = exec_query( services, test[i], &result );
|
hr = exec_query( services, test[i], &result );
|
||||||
todo_wine ok( hr == S_OK, "query %u failed: %08x\n", i, hr );
|
ok( hr == S_OK, "query %u failed: %08x\n", i, hr );
|
||||||
if (result) IEnumWbemClassObject_Release( result );
|
if (result) IEnumWbemClassObject_Release( result );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,8 +148,17 @@ struct record
|
||||||
struct table *table;
|
struct table *table;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct keyword
|
||||||
|
{
|
||||||
|
const WCHAR *name;
|
||||||
|
const WCHAR *value;
|
||||||
|
const struct keyword *next;
|
||||||
|
};
|
||||||
|
|
||||||
struct view
|
struct view
|
||||||
{
|
{
|
||||||
|
const WCHAR *path; /* ASSOCIATORS OF query */
|
||||||
|
const struct keyword *keywordlist;
|
||||||
const struct property *proplist;
|
const struct property *proplist;
|
||||||
struct table *table;
|
struct table *table;
|
||||||
const struct expr *cond;
|
const struct expr *cond;
|
||||||
|
@ -170,8 +179,8 @@ struct query *addref_query( struct query * ) DECLSPEC_HIDDEN;
|
||||||
void release_query( struct query *query ) DECLSPEC_HIDDEN;
|
void release_query( struct query *query ) DECLSPEC_HIDDEN;
|
||||||
HRESULT exec_query( const WCHAR *, IEnumWbemClassObject ** ) DECLSPEC_HIDDEN;
|
HRESULT exec_query( const WCHAR *, IEnumWbemClassObject ** ) DECLSPEC_HIDDEN;
|
||||||
HRESULT parse_query( const WCHAR *, struct view **, struct list * ) DECLSPEC_HIDDEN;
|
HRESULT parse_query( const WCHAR *, struct view **, struct list * ) DECLSPEC_HIDDEN;
|
||||||
HRESULT create_view( const struct property *, const WCHAR *, const struct expr *,
|
HRESULT create_view( const WCHAR *, const struct keyword *, const WCHAR *, const struct property *,
|
||||||
struct view ** ) DECLSPEC_HIDDEN;
|
const struct expr *, struct view ** ) DECLSPEC_HIDDEN;
|
||||||
void destroy_view( struct view * ) DECLSPEC_HIDDEN;
|
void destroy_view( struct view * ) DECLSPEC_HIDDEN;
|
||||||
HRESULT execute_view( struct view * ) DECLSPEC_HIDDEN;
|
HRESULT execute_view( struct view * ) DECLSPEC_HIDDEN;
|
||||||
void init_table_list( void ) DECLSPEC_HIDDEN;
|
void init_table_list( void ) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -67,6 +67,18 @@ static struct property *alloc_property( struct parser *parser, const WCHAR *clas
|
||||||
return prop;
|
return prop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct keyword *alloc_keyword( struct parser *parser, const WCHAR *name, const WCHAR *value )
|
||||||
|
{
|
||||||
|
struct keyword *keyword = alloc_mem( parser, sizeof(*keyword) );
|
||||||
|
if (keyword)
|
||||||
|
{
|
||||||
|
keyword->name = name;
|
||||||
|
keyword->value = value;
|
||||||
|
keyword->next = NULL;
|
||||||
|
}
|
||||||
|
return keyword;
|
||||||
|
}
|
||||||
|
|
||||||
static WCHAR *get_string( struct parser *parser, const struct string *str )
|
static WCHAR *get_string( struct parser *parser, const struct string *str )
|
||||||
{
|
{
|
||||||
const WCHAR *p = str->data;
|
const WCHAR *p = str->data;
|
||||||
|
@ -87,6 +99,18 @@ static WCHAR *get_string( struct parser *parser, const struct string *str )
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static WCHAR *get_path( struct parser *parser, const struct string *str )
|
||||||
|
{
|
||||||
|
const WCHAR *p = str->data;
|
||||||
|
int len = str->len;
|
||||||
|
WCHAR *ret;
|
||||||
|
|
||||||
|
if (!(ret = alloc_mem( parser, (len + 1) * sizeof(WCHAR) ))) return NULL;
|
||||||
|
memcpy( ret, p, len * sizeof(WCHAR) );
|
||||||
|
ret[len] = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int get_int( struct parser *parser )
|
static int get_int( struct parser *parser )
|
||||||
{
|
{
|
||||||
const WCHAR *p = &parser->cmd[parser->idx];
|
const WCHAR *p = &parser->cmd[parser->idx];
|
||||||
|
@ -195,28 +219,92 @@ static int wql_lex( void *val, struct parser *parser );
|
||||||
struct string str;
|
struct string str;
|
||||||
WCHAR *string;
|
WCHAR *string;
|
||||||
struct property *proplist;
|
struct property *proplist;
|
||||||
|
struct keyword *keywordlist;
|
||||||
struct view *view;
|
struct view *view;
|
||||||
struct expr *expr;
|
struct expr *expr;
|
||||||
int integer;
|
int integer;
|
||||||
}
|
}
|
||||||
|
|
||||||
%token TK_SELECT TK_FROM TK_STAR TK_COMMA TK_DOT TK_IS TK_LP TK_RP TK_NULL TK_FALSE TK_TRUE
|
%token TK_SELECT TK_FROM TK_STAR TK_COMMA TK_DOT TK_IS TK_LP TK_RP TK_NULL TK_FALSE TK_TRUE
|
||||||
%token TK_INTEGER TK_WHERE TK_SPACE TK_MINUS TK_ILLEGAL TK_BY
|
%token TK_INTEGER TK_WHERE TK_SPACE TK_MINUS TK_ILLEGAL TK_BY TK_ASSOCIATORS TK_OF
|
||||||
%token <str> TK_STRING TK_ID
|
%token <str> TK_STRING TK_ID TK_PATH
|
||||||
|
|
||||||
%type <string> id
|
%type <string> id path
|
||||||
%type <proplist> prop proplist
|
%type <proplist> prop proplist
|
||||||
%type <view> select
|
%type <keywordlist> keyword keywordlist
|
||||||
|
%type <view> query select associatorsof
|
||||||
%type <expr> expr prop_val const_val string_val
|
%type <expr> expr prop_val const_val string_val
|
||||||
%type <integer> number
|
%type <integer> number
|
||||||
|
|
||||||
%left TK_OR
|
%left TK_OR TK_AND TK_NOT TK_EQ TK_NE TK_LT TK_GT TK_LE TK_GE TK_LIKE
|
||||||
%left TK_AND
|
|
||||||
%left TK_NOT
|
|
||||||
%left TK_EQ TK_NE TK_LT TK_GT TK_LE TK_GE TK_LIKE
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
query:
|
||||||
|
select
|
||||||
|
|
|
||||||
|
associatorsof
|
||||||
|
;
|
||||||
|
|
||||||
|
path:
|
||||||
|
TK_PATH
|
||||||
|
{
|
||||||
|
$$ = get_path( ctx, &$1 );
|
||||||
|
if (!$$)
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
keyword:
|
||||||
|
id
|
||||||
|
{
|
||||||
|
$$ = alloc_keyword( ctx, $1, NULL );
|
||||||
|
if (!$$)
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
| id TK_EQ id
|
||||||
|
{
|
||||||
|
$$ = alloc_keyword( ctx, $1, $3 );
|
||||||
|
if (!$$)
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
keywordlist:
|
||||||
|
keyword
|
||||||
|
| keyword keywordlist
|
||||||
|
{
|
||||||
|
$1->next = $2;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
associatorsof:
|
||||||
|
TK_ASSOCIATORS TK_OF path
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
struct parser *parser = ctx;
|
||||||
|
struct view *view;
|
||||||
|
|
||||||
|
hr = create_view( $3, NULL, NULL, NULL, NULL, &view );
|
||||||
|
if (hr != S_OK)
|
||||||
|
YYABORT;
|
||||||
|
|
||||||
|
PARSER_BUBBLE_UP_VIEW( parser, $$, view );
|
||||||
|
}
|
||||||
|
| TK_ASSOCIATORS TK_OF path TK_WHERE keywordlist
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
struct parser *parser = ctx;
|
||||||
|
struct view *view;
|
||||||
|
|
||||||
|
hr = create_view( $3, $5, NULL, NULL, NULL, &view );
|
||||||
|
if (hr != S_OK)
|
||||||
|
YYABORT;
|
||||||
|
|
||||||
|
PARSER_BUBBLE_UP_VIEW( parser, $$, view );
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
select:
|
select:
|
||||||
TK_SELECT TK_FROM id
|
TK_SELECT TK_FROM id
|
||||||
{
|
{
|
||||||
|
@ -224,7 +312,7 @@ select:
|
||||||
struct parser *parser = ctx;
|
struct parser *parser = ctx;
|
||||||
struct view *view;
|
struct view *view;
|
||||||
|
|
||||||
hr = create_view( NULL, $3, NULL, &view );
|
hr = create_view( NULL, NULL, $3, NULL, NULL, &view );
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
YYABORT;
|
YYABORT;
|
||||||
|
|
||||||
|
@ -236,7 +324,7 @@ select:
|
||||||
struct parser *parser = ctx;
|
struct parser *parser = ctx;
|
||||||
struct view *view;
|
struct view *view;
|
||||||
|
|
||||||
hr = create_view( $2, $4, NULL, &view );
|
hr = create_view( NULL, NULL, $4, $2, NULL, &view );
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
YYABORT;
|
YYABORT;
|
||||||
|
|
||||||
|
@ -248,7 +336,7 @@ select:
|
||||||
struct parser *parser = ctx;
|
struct parser *parser = ctx;
|
||||||
struct view *view;
|
struct view *view;
|
||||||
|
|
||||||
hr = create_view( $2, $4, $6, &view );
|
hr = create_view( NULL, NULL, $4, $2, $6, &view );
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
YYABORT;
|
YYABORT;
|
||||||
|
|
||||||
|
@ -535,16 +623,18 @@ static const char id_char[] =
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct keyword
|
struct wql_keyword
|
||||||
{
|
{
|
||||||
const WCHAR *name;
|
const WCHAR *name;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
int type;
|
int type;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_TOKEN_LEN 6
|
#define MIN_TOKEN_LEN 2
|
||||||
|
#define MAX_TOKEN_LEN 11
|
||||||
|
|
||||||
static const WCHAR andW[] = {'A','N','D'};
|
static const WCHAR andW[] = {'A','N','D'};
|
||||||
|
static const WCHAR associatorsW[] = {'A','S','S','O','C','I','A','T','O','R','S'};
|
||||||
static const WCHAR byW[] = {'B','Y'};
|
static const WCHAR byW[] = {'B','Y'};
|
||||||
static const WCHAR falseW[] = {'F','A','L','S','E'};
|
static const WCHAR falseW[] = {'F','A','L','S','E'};
|
||||||
static const WCHAR fromW[] = {'F','R','O','M'};
|
static const WCHAR fromW[] = {'F','R','O','M'};
|
||||||
|
@ -552,30 +642,33 @@ static const WCHAR isW[] = {'I','S'};
|
||||||
static const WCHAR likeW[] = {'L','I','K','E'};
|
static const WCHAR likeW[] = {'L','I','K','E'};
|
||||||
static const WCHAR notW[] = {'N','O','T'};
|
static const WCHAR notW[] = {'N','O','T'};
|
||||||
static const WCHAR nullW[] = {'N','U','L','L'};
|
static const WCHAR nullW[] = {'N','U','L','L'};
|
||||||
|
static const WCHAR ofW[] = {'O','F'};
|
||||||
static const WCHAR orW[] = {'O','R'};
|
static const WCHAR orW[] = {'O','R'};
|
||||||
static const WCHAR selectW[] = {'S','E','L','E','C','T'};
|
static const WCHAR selectW[] = {'S','E','L','E','C','T'};
|
||||||
static const WCHAR trueW[] = {'T','R','U','E'};
|
static const WCHAR trueW[] = {'T','R','U','E'};
|
||||||
static const WCHAR whereW[] = {'W','H','E','R','E'};
|
static const WCHAR whereW[] = {'W','H','E','R','E'};
|
||||||
|
|
||||||
static const struct keyword keyword_table[] =
|
static const struct wql_keyword keyword_table[] =
|
||||||
{
|
{
|
||||||
{ andW, ARRAY_SIZE(andW), TK_AND },
|
{ andW, ARRAY_SIZE(andW), TK_AND },
|
||||||
{ byW, ARRAY_SIZE(byW), TK_BY },
|
{ associatorsW, ARRAY_SIZE(associatorsW), TK_ASSOCIATORS },
|
||||||
{ falseW, ARRAY_SIZE(falseW), TK_FALSE },
|
{ byW, ARRAY_SIZE(byW), TK_BY },
|
||||||
{ fromW, ARRAY_SIZE(fromW), TK_FROM },
|
{ falseW, ARRAY_SIZE(falseW), TK_FALSE },
|
||||||
{ isW, ARRAY_SIZE(isW), TK_IS },
|
{ fromW, ARRAY_SIZE(fromW), TK_FROM },
|
||||||
{ likeW, ARRAY_SIZE(likeW), TK_LIKE },
|
{ isW, ARRAY_SIZE(isW), TK_IS },
|
||||||
{ notW, ARRAY_SIZE(notW), TK_NOT },
|
{ likeW, ARRAY_SIZE(likeW), TK_LIKE },
|
||||||
{ nullW, ARRAY_SIZE(nullW), TK_NULL },
|
{ notW, ARRAY_SIZE(notW), TK_NOT },
|
||||||
{ orW, ARRAY_SIZE(orW), TK_OR },
|
{ nullW, ARRAY_SIZE(nullW), TK_NULL },
|
||||||
{ selectW, ARRAY_SIZE(selectW), TK_SELECT },
|
{ ofW, ARRAY_SIZE(ofW), TK_OF },
|
||||||
{ trueW, ARRAY_SIZE(trueW), TK_TRUE },
|
{ orW, ARRAY_SIZE(orW), TK_OR },
|
||||||
{ whereW, ARRAY_SIZE(whereW), TK_WHERE }
|
{ selectW, ARRAY_SIZE(selectW), TK_SELECT },
|
||||||
|
{ trueW, ARRAY_SIZE(trueW), TK_TRUE },
|
||||||
|
{ whereW, ARRAY_SIZE(whereW), TK_WHERE }
|
||||||
};
|
};
|
||||||
|
|
||||||
static int cmp_keyword( const void *arg1, const void *arg2 )
|
static int cmp_keyword( const void *arg1, const void *arg2 )
|
||||||
{
|
{
|
||||||
const struct keyword *key1 = arg1, *key2 = arg2;
|
const struct wql_keyword *key1 = arg1, *key2 = arg2;
|
||||||
int len = min( key1->len, key2->len );
|
int len = min( key1->len, key2->len );
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -587,14 +680,14 @@ static int cmp_keyword( const void *arg1, const void *arg2 )
|
||||||
|
|
||||||
static int keyword_type( const WCHAR *str, unsigned int len )
|
static int keyword_type( const WCHAR *str, unsigned int len )
|
||||||
{
|
{
|
||||||
struct keyword key, *ret;
|
struct wql_keyword key, *ret;
|
||||||
|
|
||||||
if (len > MAX_TOKEN_LEN) return TK_ID;
|
if (len < MIN_TOKEN_LEN || len > MAX_TOKEN_LEN) return TK_ID;
|
||||||
|
|
||||||
key.name = str;
|
key.name = str;
|
||||||
key.len = len;
|
key.len = len;
|
||||||
key.type = 0;
|
key.type = 0;
|
||||||
ret = bsearch( &key, keyword_table, ARRAY_SIZE(keyword_table), sizeof(struct keyword), cmp_keyword );
|
ret = bsearch( &key, keyword_table, ARRAY_SIZE(keyword_table), sizeof(struct wql_keyword), cmp_keyword );
|
||||||
if (ret) return ret->type;
|
if (ret) return ret->type;
|
||||||
return TK_ID;
|
return TK_ID;
|
||||||
}
|
}
|
||||||
|
@ -622,6 +715,15 @@ static int get_token( const WCHAR *s, int *token )
|
||||||
case ')':
|
case ')':
|
||||||
*token = TK_RP;
|
*token = TK_RP;
|
||||||
return 1;
|
return 1;
|
||||||
|
case '{':
|
||||||
|
for (i = 1; s[i] && s[i] != '}'; i++) {}
|
||||||
|
if (s[i] != '}')
|
||||||
|
{
|
||||||
|
*token = TK_ILLEGAL;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
*token = TK_PATH;
|
||||||
|
return i + 1;
|
||||||
case '*':
|
case '*':
|
||||||
*token = TK_STAR;
|
*token = TK_STAR;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
Loading…
Reference in New Issue