Working toward single smart playlist/query parser
This commit is contained in:
parent
32add9e77c
commit
43afe26932
|
@ -5,13 +5,11 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "err.h"
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err_debuglevel = 9;
|
|
||||||
|
|
||||||
printf("Reading %s\n",argv[1]);
|
printf("Reading %s\n",argv[1]);
|
||||||
|
|
||||||
if((err=conf_read(argv[1])) != CONF_E_SUCCESS) {
|
if((err=conf_read(argv[1])) != CONF_E_SUCCESS) {
|
||||||
|
|
|
@ -184,7 +184,35 @@ typedef struct tag_fieldlookup {
|
||||||
char *name;
|
char *name;
|
||||||
} FIELDLOOKUP;
|
} FIELDLOOKUP;
|
||||||
|
|
||||||
FIELDLOOKUP sp_fields[] = {
|
/* normal terminators, in-string terminators, escapes */
|
||||||
|
char *sp_terminators[2][3] = {
|
||||||
|
{ " \t\n\r\"<>=()|&!", "\"","\"" },
|
||||||
|
{ "()'+: -,", "')", "\\*'" }
|
||||||
|
};
|
||||||
|
|
||||||
|
FIELDLOOKUP sp_symbols_0[] = {
|
||||||
|
{ T_OR, "||" },
|
||||||
|
{ T_AND, "&&" },
|
||||||
|
{ T_EQUAL, "=" },
|
||||||
|
{ T_LESSEQUAL, "<=" },
|
||||||
|
{ T_LESS, "<" },
|
||||||
|
{ T_GREATEREQUAL, ">=" },
|
||||||
|
{ T_GREATER, ">" },
|
||||||
|
{ T_OPENPAREN, "(" },
|
||||||
|
{ T_CLOSEPAREN, ")" },
|
||||||
|
{ T_NOT, "!" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
FIELDLOOKUP sp_symbols_1[] = {
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
FIELDLOOKUP *sp_symbols[2] = {
|
||||||
|
sp_symbols_0, sp_symbols_1
|
||||||
|
};
|
||||||
|
|
||||||
|
FIELDLOOKUP sp_fields_0[] = {
|
||||||
{ T_INT_FIELD, "id" },
|
{ T_INT_FIELD, "id" },
|
||||||
{ T_STRING_FIELD, "path" },
|
{ T_STRING_FIELD, "path" },
|
||||||
{ T_STRING_FIELD, "fname" },
|
{ T_STRING_FIELD, "fname" },
|
||||||
|
@ -245,11 +273,20 @@ FIELDLOOKUP sp_fields[] = {
|
||||||
{ T_ENDSWITH, "endswith" },
|
{ T_ENDSWITH, "endswith" },
|
||||||
|
|
||||||
/* end */
|
/* end */
|
||||||
{ 0, NULL },
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
FIELDLOOKUP sp_fields_1[] = {
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
FIELDLOOKUP *sp_fields[2] = {
|
||||||
|
sp_fields_0, sp_fields_1
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct tag_parsetree {
|
typedef struct tag_parsetree {
|
||||||
int in_string;
|
int in_string;
|
||||||
|
int token_list;
|
||||||
char *term;
|
char *term;
|
||||||
char *current;
|
char *current;
|
||||||
SP_TOKEN token;
|
SP_TOKEN token;
|
||||||
|
@ -371,11 +408,12 @@ int sp_scan(PARSETREE tree) {
|
||||||
char *terminator=NULL;
|
char *terminator=NULL;
|
||||||
char *tail;
|
char *tail;
|
||||||
int advance=0;
|
int advance=0;
|
||||||
FIELDLOOKUP *pfield=sp_fields;
|
FIELDLOOKUP *pfield=sp_fields[tree->token_list];
|
||||||
int len;
|
int len;
|
||||||
int found;
|
int found;
|
||||||
int numval;
|
int numval;
|
||||||
time_t tval;
|
time_t tval;
|
||||||
|
int found_symbol;
|
||||||
|
|
||||||
if(tree->token.token_id & 0x2000) {
|
if(tree->token.token_id & 0x2000) {
|
||||||
if(tree->token.data.cvalue)
|
if(tree->token.data.cvalue)
|
||||||
|
@ -404,84 +442,40 @@ int sp_scan(PARSETREE tree) {
|
||||||
tree->token_pos, *(tree->current));
|
tree->token_pos, *(tree->current));
|
||||||
|
|
||||||
/* check singletons */
|
/* check singletons */
|
||||||
|
found_symbol=0;
|
||||||
|
|
||||||
if(!tree->in_string) {
|
if(!tree->in_string) {
|
||||||
switch(*(tree->current)) {
|
pfield=sp_symbols[tree->token_list];
|
||||||
case '|':
|
while((pfield->name) && (!found_symbol)) {
|
||||||
if((*(tree->current + 1) == '|')) {
|
if(!strncmp(pfield->name,tree->current,strlen(pfield->name))) {
|
||||||
advance = 2;
|
/* that's a match */
|
||||||
tree->token.token_id = T_OR;
|
tree->current += strlen(pfield->name);
|
||||||
|
tree->token.token_id = pfield->type;
|
||||||
|
found_symbol = 1;
|
||||||
}
|
}
|
||||||
break;
|
pfield++;
|
||||||
|
|
||||||
case '&':
|
|
||||||
if((*(tree->current + 1) == '&')) {
|
|
||||||
advance = 2;
|
|
||||||
tree->token.token_id = T_AND;
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case '=':
|
|
||||||
advance=1;
|
|
||||||
tree->token.token_id = T_EQUAL;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '<':
|
|
||||||
if((*(tree->current + 1)) == '=') {
|
|
||||||
advance = 2;
|
|
||||||
tree->token.token_id = T_LESSEQUAL;
|
|
||||||
} else {
|
|
||||||
advance = 1;
|
|
||||||
tree->token.token_id = T_LESS;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '>':
|
|
||||||
if((*(tree->current + 1)) == '=') {
|
|
||||||
advance = 2;
|
|
||||||
tree->token.token_id = T_GREATEREQUAL;
|
|
||||||
} else {
|
|
||||||
advance = 1;
|
|
||||||
tree->token.token_id = T_GREATER;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '(':
|
|
||||||
advance=1;
|
|
||||||
tree->token.token_id = T_OPENPAREN;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ')':
|
|
||||||
advance=1;
|
|
||||||
tree->token.token_id = T_CLOSEPAREN;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '!':
|
|
||||||
advance=1;
|
|
||||||
tree->token.token_id = T_NOT;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
if((!found_symbol) && (*tree->current == '"')) {
|
||||||
|
tree->current++;
|
||||||
if(*tree->current == '"') {
|
|
||||||
advance = 1;
|
|
||||||
tree->in_string = !tree->in_string;
|
tree->in_string = !tree->in_string;
|
||||||
tree->token.token_id = T_QUOTE;
|
tree->token.token_id = T_QUOTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(advance) { /* singleton */
|
if(!found_symbol) { /* either a keyword token or a quoted string */
|
||||||
tree->current += advance;
|
|
||||||
} else { /* either a keyword token or a quoted string */
|
|
||||||
DPRINTF(E_SPAM,L_PARSE,"keyword or string!\n");
|
DPRINTF(E_SPAM,L_PARSE,"keyword or string!\n");
|
||||||
|
|
||||||
/* walk to a terminator */
|
/* walk to a terminator */
|
||||||
tail = tree->current;
|
tail = tree->current;
|
||||||
|
|
||||||
terminator = " \t\n\r\"<>=()|&!";
|
/* out-of-string terminator */
|
||||||
if(tree->in_string) {
|
terminator = sp_terminators[tree->token_list][0];
|
||||||
terminator="\"";
|
if(tree->in_string) { /* in-string terminator */
|
||||||
|
terminator=sp_terminators[tree->token_list][1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: escaped characters */
|
||||||
while((*tail) && (!strchr(terminator,*tail))) {
|
while((*tail) && (!strchr(terminator,*tail))) {
|
||||||
tail++;
|
tail++;
|
||||||
}
|
}
|
||||||
|
@ -491,7 +485,7 @@ int sp_scan(PARSETREE tree) {
|
||||||
|
|
||||||
if(!tree->in_string) {
|
if(!tree->in_string) {
|
||||||
/* find it in the token list */
|
/* find it in the token list */
|
||||||
pfield=sp_fields;
|
pfield=sp_fields[tree->token_list];
|
||||||
DPRINTF(E_SPAM,L_PARSE,"Len is %d\n",len);
|
DPRINTF(E_SPAM,L_PARSE,"Len is %d\n",len);
|
||||||
while(pfield->name) {
|
while(pfield->name) {
|
||||||
if(strlen(pfield->name) == len) {
|
if(strlen(pfield->name) == len) {
|
||||||
|
@ -567,6 +561,9 @@ PARSETREE sp_init(void) {
|
||||||
DPRINTF(E_FATAL,L_PARSE,"Alloc error\n");
|
DPRINTF(E_FATAL,L_PARSE,"Alloc error\n");
|
||||||
|
|
||||||
memset(ptree,0,sizeof(PARSESTRUCT));
|
memset(ptree,0,sizeof(PARSESTRUCT));
|
||||||
|
|
||||||
|
/* this sets the default token list as well (0) */
|
||||||
|
|
||||||
return ptree;
|
return ptree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue