mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-13 16:03:23 -05:00
parser still not quite working on both queries and smart playlists
This commit is contained in:
parent
43afe26932
commit
2b6b8cd208
@ -4,7 +4,12 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define os_opensyslog()
|
||||||
|
#define os_syslog(a,b)
|
||||||
|
#define os_closesyslog()
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
|
#include "err.h"
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# $Id$
|
# $Id$
|
||||||
CC=gcc
|
CC=gcc
|
||||||
CFLAGS := $(CFLAGS) -g -DHAVE_CONFIG_H -I. -I..
|
CFLAGS := $(CFLAGS) -g -DHAVE_CONFIG_H -I. -I.. -DERR_LEAN
|
||||||
LDFLAGS := $(LDFLAGS)
|
LDFLAGS := $(LDFLAGS)
|
||||||
TARGET = conf
|
TARGET = conf
|
||||||
OBJECTS=config-driver.o conf.o ll.o err.o
|
OBJECTS=config-driver.o conf.o ll.o err.o
|
||||||
|
16
src/err.c
16
src/err.c
@ -41,7 +41,9 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "err.h"
|
#include "err.h"
|
||||||
#include "os.h"
|
#ifndef ERR_LEAN
|
||||||
|
# include "os.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static int err_debuglevel=0; /**< current debuglevel, set from command line with -d */
|
static int err_debuglevel=0; /**< current debuglevel, set from command line with -d */
|
||||||
static int err_logdestination=LOGDEST_STDERR; /**< current log destination */
|
static int err_logdestination=LOGDEST_STDERR; /**< current log destination */
|
||||||
@ -64,13 +66,13 @@ static int _err_unlock(void);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a printf-style formatted message to the log destination.
|
* Write a printf-style formatted message to the log destination.
|
||||||
* This can be stderr, syslog/eventviewer, or a logfile, as determined by
|
* This can be stderr, syslog/eventviewer, or a logfile, as determined by
|
||||||
* err_setdest(). Note that this function should not be directly
|
* err_setdest(). Note that this function should not be directly
|
||||||
* used, rather it should be used via the #DPRINTF macro.
|
* used, rather it should be used via the #DPRINTF macro.
|
||||||
*
|
*
|
||||||
* \param level Level at which to log \ref log_levels
|
* \param level Level at which to log \ref log_levels
|
||||||
* \param cat the category to log \ref log_categories
|
* \param cat the category to log \ref log_categories
|
||||||
* \param fmt printf-style
|
* \param fmt printf-style
|
||||||
*/
|
*/
|
||||||
void err_log(int level, unsigned int cat, char *fmt, ...)
|
void err_log(int level, unsigned int cat, char *fmt, ...)
|
||||||
{
|
{
|
||||||
@ -91,7 +93,7 @@ void err_log(int level, unsigned int cat, char *fmt, ...)
|
|||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
|
vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
_err_lock(); /* atomic file writes */
|
_err_lock(); /* atomic file writes */
|
||||||
|
|
||||||
if((!level) && (err_logdestination != LOGDEST_STDERR)) {
|
if((!level) && (err_logdestination != LOGDEST_STDERR)) {
|
||||||
@ -127,7 +129,7 @@ void err_log(int level, unsigned int cat, char *fmt, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* simple get/set interface to debuglevel to avoid global
|
* simple get/set interface to debuglevel to avoid global
|
||||||
*/
|
*/
|
||||||
void err_setlevel(int level) {
|
void err_setlevel(int level) {
|
||||||
err_debuglevel = level;
|
err_debuglevel = level;
|
||||||
@ -176,7 +178,7 @@ void err_setdest(char *cvalue, int destination) {
|
|||||||
* through the err_categorylist and sets the bitfields for the
|
* through the err_categorylist and sets the bitfields for the
|
||||||
* requested log modules.
|
* requested log modules.
|
||||||
*
|
*
|
||||||
* \param list comma separated list of modules to debug.
|
* \param list comma separated list of modules to debug.
|
||||||
*/
|
*/
|
||||||
extern int err_setdebugmask(char *list) {
|
extern int err_setdebugmask(char *list) {
|
||||||
unsigned int rack;
|
unsigned int rack;
|
||||||
@ -193,7 +195,7 @@ extern int err_setdebugmask(char *list) {
|
|||||||
if(token) {
|
if(token) {
|
||||||
rack=1;
|
rack=1;
|
||||||
index=0;
|
index=0;
|
||||||
while((err_categorylist[index]) &&
|
while((err_categorylist[index]) &&
|
||||||
(strcasecmp(err_categorylist[index],token))) {
|
(strcasecmp(err_categorylist[index],token))) {
|
||||||
rack <<= 1;
|
rack <<= 1;
|
||||||
index++;
|
index++;
|
||||||
|
@ -74,4 +74,10 @@ extern int err_setdebugmask(char *list);
|
|||||||
|
|
||||||
#define DPRINTF err_log
|
#define DPRINTF err_log
|
||||||
|
|
||||||
|
#ifdef ERR_LEAN
|
||||||
|
# define os_syslog(a,b)
|
||||||
|
# define os_opensyslog(a)
|
||||||
|
# define os_closesyslog(a)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __ERR_H__ */
|
#endif /* __ERR_H__ */
|
||||||
|
@ -22,7 +22,7 @@ int main(int argc, char *argv[]) {
|
|||||||
while((option = getopt(argc, argv, "d:")) != -1) {
|
while((option = getopt(argc, argv, "d:")) != -1) {
|
||||||
switch(option) {
|
switch(option) {
|
||||||
case 'd':
|
case 'd':
|
||||||
err_debuglevel = atoi(optarg);
|
err_setlevel(atoi(optarg));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,"Error: unknown option (%c)\n\n",option);
|
fprintf(stderr,"Error: unknown option (%c)\n\n",option);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
CC=gcc
|
CC=gcc
|
||||||
CFLAGS := $(CFLAGS) -g -I/sw/include -DHAVE_CONFIG_H -I. -I.. -Wall
|
CFLAGS := $(CFLAGS) -g -I/sw/include -DHAVE_CONFIG_H -I. -I.. -Wall -DERR_LEAN
|
||||||
TARGET=parser
|
TARGET=parser
|
||||||
OBJECTS=parser-driver.o smart-parser.o err.o
|
OBJECTS=parser-driver.o smart-parser.o err.o
|
||||||
|
|
||||||
|
@ -56,6 +56,11 @@ typedef struct tag_sp_node {
|
|||||||
#define SP_OPTYPE_INT 2
|
#define SP_OPTYPE_INT 2
|
||||||
#define SP_OPTYPE_DATE 3
|
#define SP_OPTYPE_DATE 3
|
||||||
|
|
||||||
|
#define SP_HINT_NONE 0
|
||||||
|
#define SP_HINT_STRING 1
|
||||||
|
#define SP_HINT_INT 2
|
||||||
|
#define SP_HINT_DATE 3
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define T_ID 0x00
|
#define T_ID 0x00
|
||||||
#define T_PATH 0x01
|
#define T_PATH 0x01
|
||||||
@ -184,10 +189,10 @@ typedef struct tag_fieldlookup {
|
|||||||
char *name;
|
char *name;
|
||||||
} FIELDLOOKUP;
|
} FIELDLOOKUP;
|
||||||
|
|
||||||
/* normal terminators, in-string terminators, escapes */
|
/* normal terminators, in-string terminators, escapes, quotes */
|
||||||
char *sp_terminators[2][3] = {
|
char *sp_terminators[2][4] = {
|
||||||
{ " \t\n\r\"<>=()|&!", "\"","\"" },
|
{ " \t\n\r\"<>=()|&!", "\"","\"","\"" },
|
||||||
{ "()'+: -,", "')", "\\*'" }
|
{ "()'+: -,", "')", "\\*'","" }
|
||||||
};
|
};
|
||||||
|
|
||||||
FIELDLOOKUP sp_symbols_0[] = {
|
FIELDLOOKUP sp_symbols_0[] = {
|
||||||
@ -404,16 +409,16 @@ time_t sp_isdate(char *string) {
|
|||||||
* @param tree current working parse tree.
|
* @param tree current working parse tree.
|
||||||
* @returns next token (token, not the value)
|
* @returns next token (token, not the value)
|
||||||
*/
|
*/
|
||||||
int sp_scan(PARSETREE tree) {
|
int sp_scan(PARSETREE tree, int hint) {
|
||||||
char *terminator=NULL;
|
char *terminator=NULL;
|
||||||
char *tail;
|
char *tail;
|
||||||
int advance=0;
|
|
||||||
FIELDLOOKUP *pfield=sp_fields[tree->token_list];
|
FIELDLOOKUP *pfield=sp_fields[tree->token_list];
|
||||||
int len;
|
int len;
|
||||||
int found;
|
int found;
|
||||||
int numval;
|
int numval;
|
||||||
|
int is_qstr;
|
||||||
time_t tval;
|
time_t tval;
|
||||||
int found_symbol;
|
char *qstr;
|
||||||
|
|
||||||
if(tree->token.token_id & 0x2000) {
|
if(tree->token.token_id & 0x2000) {
|
||||||
if(tree->token.data.cvalue)
|
if(tree->token.data.cvalue)
|
||||||
@ -441,100 +446,122 @@ int sp_scan(PARSETREE tree) {
|
|||||||
DPRINTF(E_SPAM,L_PARSE,"Current offset: %d, char: %c\n",
|
DPRINTF(E_SPAM,L_PARSE,"Current offset: %d, char: %c\n",
|
||||||
tree->token_pos, *(tree->current));
|
tree->token_pos, *(tree->current));
|
||||||
|
|
||||||
/* check singletons */
|
if(hint == SP_HINT_STRING) {
|
||||||
found_symbol=0;
|
terminator=sp_terminators[tree->token_list][1];
|
||||||
|
tree->in_string = 1;
|
||||||
|
} else {
|
||||||
|
terminator = sp_terminators[tree->token_list][0];
|
||||||
|
tree->in_string = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check symbols */
|
||||||
if(!tree->in_string) {
|
if(!tree->in_string) {
|
||||||
pfield=sp_symbols[tree->token_list];
|
pfield=sp_symbols[tree->token_list];
|
||||||
while((pfield->name) && (!found_symbol)) {
|
while(pfield->name) {
|
||||||
if(!strncmp(pfield->name,tree->current,strlen(pfield->name))) {
|
if(!strncmp(pfield->name,tree->current,strlen(pfield->name))) {
|
||||||
/* that's a match */
|
/* that's a match */
|
||||||
tree->current += strlen(pfield->name);
|
tree->current += strlen(pfield->name);
|
||||||
tree->token.token_id = pfield->type;
|
tree->token.token_id = pfield->type;
|
||||||
found_symbol = 1;
|
return pfield->type;
|
||||||
}
|
}
|
||||||
pfield++;
|
pfield++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((!found_symbol) && (*tree->current == '"')) {
|
qstr = sp_terminators[tree->token_list][3];
|
||||||
tree->current++;
|
is_qstr = (strstr(qstr,tree->current) != NULL);
|
||||||
tree->in_string = !tree->in_string;
|
if(strlen(qstr)) { /* strings ARE quoted */
|
||||||
tree->token.token_id = T_QUOTE;
|
if(hint == SP_HINT_STRING) { /* MUST be a quote */
|
||||||
|
if(!is_qstr)
|
||||||
|
return T_ERROR;
|
||||||
|
} else {
|
||||||
|
tree->in_string = 1; /* guess we're in a string */
|
||||||
|
tree->current++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!found_symbol) { /* 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;
|
||||||
|
|
||||||
/* out-of-string terminator */
|
/* FIXME: escaped characters */
|
||||||
terminator = sp_terminators[tree->token_list][0];
|
while((*tail) && (!strchr(terminator,*tail))) {
|
||||||
if(tree->in_string) { /* in-string terminator */
|
tail++;
|
||||||
terminator=sp_terminators[tree->token_list][1];
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: escaped characters */
|
found=0;
|
||||||
while((*tail) && (!strchr(terminator,*tail))) {
|
len = (int) (tail - tree->current);
|
||||||
tail++;
|
|
||||||
}
|
|
||||||
|
|
||||||
found=0;
|
if(!tree->in_string) {
|
||||||
len = (int) (tail - tree->current);
|
/* find it in the token list */
|
||||||
|
pfield=sp_fields[tree->token_list];
|
||||||
if(!tree->in_string) {
|
DPRINTF(E_SPAM,L_PARSE,"Len is %d\n",len);
|
||||||
/* find it in the token list */
|
while(pfield->name) {
|
||||||
pfield=sp_fields[tree->token_list];
|
if(strlen(pfield->name) == len) {
|
||||||
DPRINTF(E_SPAM,L_PARSE,"Len is %d\n",len);
|
if(strncasecmp(pfield->name,tree->current,len) == 0) {
|
||||||
while(pfield->name) {
|
DPRINTF(E_DBG,L_PARSE,"%*s Returning token %04x (%s)\n",
|
||||||
if(strlen(pfield->name) == len) {
|
tree->level," ", tree->token.token_id,
|
||||||
if(strncasecmp(pfield->name,tree->current,len) == 0) {
|
pfield->name);
|
||||||
found=1;
|
found=1;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pfield++;
|
|
||||||
}
|
}
|
||||||
|
pfield++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(found) {
|
if(found) {
|
||||||
tree->token.token_id = pfield->type;
|
tree->token.token_id = pfield->type;
|
||||||
} else {
|
} else {
|
||||||
tree->token.token_id = T_STRING;
|
tree->token.token_id = T_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tree->token.token_id & 0x2000) {
|
||||||
|
tree->token.data.cvalue = malloc(len + 1);
|
||||||
|
if(!tree->token.data.cvalue) {
|
||||||
|
/* fail on malloc error */
|
||||||
|
DPRINTF(E_FATAL,L_PARSE,"Malloc error.\n");
|
||||||
}
|
}
|
||||||
|
strncpy(tree->token.data.cvalue,tree->current,len);
|
||||||
|
tree->token.data.cvalue[len] = '\x0';
|
||||||
|
}
|
||||||
|
|
||||||
if(tree->token.token_id & 0x2000) {
|
if((hint == SP_HINT_NONE) || (hint == SP_HINT_INT)) {
|
||||||
tree->token.data.cvalue = malloc(len + 1);
|
/* check for numeric? */
|
||||||
if(!tree->token.data.cvalue) {
|
|
||||||
/* fail on malloc error */
|
|
||||||
DPRINTF(E_FATAL,L_PARSE,"Malloc error.\n");
|
|
||||||
}
|
|
||||||
strncpy(tree->token.data.cvalue,tree->current,len);
|
|
||||||
tree->token.data.cvalue[len] = '\x0';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for numberic? */
|
|
||||||
if(tree->token.token_id == T_STRING &&
|
if(tree->token.token_id == T_STRING &&
|
||||||
(!tree->in_string) &&
|
(!tree->in_string) &&
|
||||||
sp_isnumber(tree->token.data.cvalue)) {
|
sp_isnumber(tree->token.data.cvalue)) {
|
||||||
/* woops! */
|
/* woops! */
|
||||||
numval = atoi(tree->token.data.cvalue);
|
numval = atoi(tree->token.data.cvalue);
|
||||||
free(tree->token.data.cvalue);
|
free(tree->token.data.cvalue);
|
||||||
tree->token.data.ivalue = numval;
|
tree->token.data.ivalue = numval;
|
||||||
tree->token.token_id = T_NUMBER;
|
tree->token.token_id = T_NUMBER;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if((hint == SP_HINT_NONE) || (hint == SP_HINT_DATE)) {
|
||||||
if(tree->token.token_id == T_STRING &&
|
if(tree->token.token_id == T_STRING &&
|
||||||
(!tree->in_string) &&
|
(!tree->in_string) &&
|
||||||
(tval=sp_isdate(tree->token.data.cvalue))) {
|
(tval=sp_isdate(tree->token.data.cvalue))) {
|
||||||
free(tree->token.data.cvalue);
|
free(tree->token.data.cvalue);
|
||||||
tree->token.data.tvalue = tval;
|
tree->token.data.tvalue = tval;
|
||||||
tree->token.token_id = T_DATE;
|
tree->token.token_id = T_DATE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tree->current=tail;
|
||||||
|
|
||||||
tree->current=tail;
|
/* if we are in_string, and we have quoted strings, ensure we
|
||||||
|
* have a quote */
|
||||||
|
|
||||||
|
is_qstr = (strstr(qstr,tree->current) != NULL);
|
||||||
|
if((!found) && strlen(qstr) && (!is_qstr) && (tree->in_string)) {
|
||||||
|
DPRINTF(E_INF,L_PARSE,"Missing closing quotes\n");
|
||||||
|
if(tree->token.token_id & 0x2000) {
|
||||||
|
free(tree->token.data.cvalue);
|
||||||
|
}
|
||||||
|
tree->token.token_id = T_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF(E_DBG,L_PARSE,"%*s Returning token %04x\n",tree->level," ",
|
DPRINTF(E_DBG,L_PARSE,"%*s Returning token %04x\n",tree->level," ",
|
||||||
@ -595,7 +622,7 @@ int sp_parse(PARSETREE tree, char *term) {
|
|||||||
if(tree->tree)
|
if(tree->tree)
|
||||||
sp_free_node(tree->tree);
|
sp_free_node(tree->tree);
|
||||||
|
|
||||||
sp_scan(tree);
|
sp_scan(tree,SP_HINT_NONE);
|
||||||
tree->tree = sp_parse_phrase(tree);
|
tree->tree = sp_parse_phrase(tree);
|
||||||
|
|
||||||
if(tree->tree) {
|
if(tree->tree) {
|
||||||
@ -662,7 +689,7 @@ SP_NODE *sp_parse_aexpr(PARSETREE tree) {
|
|||||||
pnew->op_type = SP_OPTYPE_ANDOR;
|
pnew->op_type = SP_OPTYPE_ANDOR;
|
||||||
|
|
||||||
pnew->left.node = expr;
|
pnew->left.node = expr;
|
||||||
sp_scan(tree);
|
sp_scan(tree,SP_HINT_NONE);
|
||||||
pnew->right.node = sp_parse_expr(tree);
|
pnew->right.node = sp_parse_expr(tree);
|
||||||
|
|
||||||
if(!pnew->right.node) {
|
if(!pnew->right.node) {
|
||||||
@ -704,7 +731,7 @@ SP_NODE *sp_parse_oexpr(PARSETREE tree) {
|
|||||||
pnew->op_type = SP_OPTYPE_ANDOR;
|
pnew->op_type = SP_OPTYPE_ANDOR;
|
||||||
|
|
||||||
pnew->left.node = expr;
|
pnew->left.node = expr;
|
||||||
sp_scan(tree);
|
sp_scan(tree,SP_HINT_NONE);
|
||||||
pnew->right.node = sp_parse_aexpr(tree);
|
pnew->right.node = sp_parse_aexpr(tree);
|
||||||
|
|
||||||
if(!pnew->right.node) {
|
if(!pnew->right.node) {
|
||||||
@ -733,10 +760,10 @@ SP_NODE *sp_parse_expr(PARSETREE tree) {
|
|||||||
sp_enter_exit(tree,"sp_parse_expr",1,NULL);
|
sp_enter_exit(tree,"sp_parse_expr",1,NULL);
|
||||||
|
|
||||||
if(tree->token.token_id == T_OPENPAREN) {
|
if(tree->token.token_id == T_OPENPAREN) {
|
||||||
sp_scan(tree);
|
sp_scan(tree,SP_HINT_NONE);
|
||||||
expr = sp_parse_oexpr(tree);
|
expr = sp_parse_oexpr(tree);
|
||||||
if((expr) && (tree->token.token_id == T_CLOSEPAREN)) {
|
if((expr) && (tree->token.token_id == T_CLOSEPAREN)) {
|
||||||
sp_scan(tree);
|
sp_scan(tree,SP_HINT_NONE);
|
||||||
} else {
|
} else {
|
||||||
/* Error: expecting close paren */
|
/* Error: expecting close paren */
|
||||||
sp_set_error(tree,SP_E_CLOSE);
|
sp_set_error(tree,SP_E_CLOSE);
|
||||||
@ -807,11 +834,11 @@ SP_NODE *sp_parse_criterion(PARSETREE tree) {
|
|||||||
memset(pnew,0x00,sizeof(SP_NODE));
|
memset(pnew,0x00,sizeof(SP_NODE));
|
||||||
pnew->left.field = strdup(tree->token.data.cvalue);
|
pnew->left.field = strdup(tree->token.data.cvalue);
|
||||||
|
|
||||||
sp_scan(tree); /* scan past the string field we know is there */
|
sp_scan(tree,SP_HINT_NONE);/* scan past the string field we know is there */
|
||||||
|
|
||||||
if(tree->token.token_id == T_NOT) {
|
if(tree->token.token_id == T_NOT) {
|
||||||
pnew->not_flag=1;
|
pnew->not_flag=1;
|
||||||
sp_scan(tree);
|
sp_scan(tree,SP_HINT_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(tree->token.token_id) {
|
switch(tree->token.token_id) {
|
||||||
@ -830,28 +857,17 @@ SP_NODE *sp_parse_criterion(PARSETREE tree) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(result) {
|
if(result) {
|
||||||
sp_scan(tree);
|
sp_scan(tree,SP_HINT_NONE);
|
||||||
/* should be sitting on quote literal string quote */
|
/* should be sitting on string literal */
|
||||||
|
if(tree->token.token_id == T_STRING) {
|
||||||
if(tree->token.token_id == T_QUOTE) {
|
result = 1;
|
||||||
sp_scan(tree);
|
pnew->right.cvalue=strdup(tree->token.data.cvalue);
|
||||||
if(tree->token.token_id == T_STRING) {
|
sp_scan(tree,SP_HINT_NONE);
|
||||||
pnew->right.cvalue=strdup(tree->token.data.cvalue);
|
|
||||||
sp_scan(tree);
|
|
||||||
if(tree->token.token_id == T_QUOTE) {
|
|
||||||
result=1;
|
|
||||||
sp_scan(tree);
|
|
||||||
} else {
|
|
||||||
sp_set_error(tree,SP_E_CLOSEQUOTE);
|
|
||||||
DPRINTF(E_SPAM,L_PARSE,"Expecting closign quote\n");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sp_set_error(tree,SP_E_STRING);
|
|
||||||
DPRINTF(E_SPAM,L_PARSE,"Expecting literal string\n");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
sp_set_error(tree,SP_E_OPENQUOTE);
|
sp_set_error(tree,SP_E_OPENQUOTE);
|
||||||
DPRINTF(E_SPAM,L_PARSE,"Expecting opening quote\n");
|
DPRINTF(E_SPAM,L_PARSE,"Expecting string, got %04X\n",
|
||||||
|
tree->token.token_id);
|
||||||
|
result = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -883,11 +899,11 @@ SP_NODE *sp_parse_criterion(PARSETREE tree) {
|
|||||||
memset(pnew,0x00,sizeof(SP_NODE));
|
memset(pnew,0x00,sizeof(SP_NODE));
|
||||||
pnew->left.field = strdup(tree->token.data.cvalue);
|
pnew->left.field = strdup(tree->token.data.cvalue);
|
||||||
|
|
||||||
sp_scan(tree); /* scan past the int field we know is there */
|
sp_scan(tree,SP_HINT_NONE); /* scan past the int field we know is there */
|
||||||
|
|
||||||
if(tree->token.token_id == T_NOT) {
|
if(tree->token.token_id == T_NOT) {
|
||||||
pnew->not_flag=1;
|
pnew->not_flag=1;
|
||||||
sp_scan(tree);
|
sp_scan(tree,SP_HINT_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(tree->token.token_id) {
|
switch(tree->token.token_id) {
|
||||||
@ -909,12 +925,12 @@ SP_NODE *sp_parse_criterion(PARSETREE tree) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(result) {
|
if(result) {
|
||||||
sp_scan(tree);
|
sp_scan(tree,SP_HINT_NONE);
|
||||||
/* should be sitting on a literal string */
|
/* should be sitting on a literal string */
|
||||||
if(tree->token.token_id == T_NUMBER) {
|
if(tree->token.token_id == T_NUMBER) {
|
||||||
result = 1;
|
result = 1;
|
||||||
pnew->right.ivalue=tree->token.data.ivalue;
|
pnew->right.ivalue=tree->token.data.ivalue;
|
||||||
sp_scan(tree);
|
sp_scan(tree,SP_HINT_NONE);
|
||||||
} else {
|
} else {
|
||||||
/* Error: Expecting number */
|
/* Error: Expecting number */
|
||||||
sp_set_error(tree,SP_E_NUMBER);
|
sp_set_error(tree,SP_E_NUMBER);
|
||||||
@ -953,11 +969,11 @@ SP_NODE *sp_parse_date_criterion(PARSETREE tree) {
|
|||||||
memset(pnew,0x00,sizeof(SP_NODE));
|
memset(pnew,0x00,sizeof(SP_NODE));
|
||||||
pnew->left.field = strdup(tree->token.data.cvalue);
|
pnew->left.field = strdup(tree->token.data.cvalue);
|
||||||
|
|
||||||
sp_scan(tree); /* scan past the date field we know is there */
|
sp_scan(tree,SP_HINT_NONE); /* scan past the date field we know is there */
|
||||||
|
|
||||||
if(tree->token.token_id == T_NOT) {
|
if(tree->token.token_id == T_NOT) {
|
||||||
pnew->not_flag=1;
|
pnew->not_flag=1;
|
||||||
sp_scan(tree);
|
sp_scan(tree,SP_HINT_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(tree->token.token_id) {
|
switch(tree->token.token_id) {
|
||||||
@ -988,7 +1004,7 @@ SP_NODE *sp_parse_date_criterion(PARSETREE tree) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(result) {
|
if(result) {
|
||||||
sp_scan(tree);
|
sp_scan(tree,SP_HINT_NONE);
|
||||||
/* should be sitting on a date */
|
/* should be sitting on a date */
|
||||||
if((pnew->right.tvalue = sp_parse_date(tree))) {
|
if((pnew->right.tvalue = sp_parse_date(tree))) {
|
||||||
result=1;
|
result=1;
|
||||||
@ -1030,11 +1046,11 @@ time_t sp_parse_date(PARSETREE tree) {
|
|||||||
switch(tree->token.token_id) {
|
switch(tree->token.token_id) {
|
||||||
case T_TODAY:
|
case T_TODAY:
|
||||||
result = time(NULL);
|
result = time(NULL);
|
||||||
sp_scan(tree);
|
sp_scan(tree,SP_HINT_NONE);
|
||||||
break;
|
break;
|
||||||
case T_DATE:
|
case T_DATE:
|
||||||
result = tree->token.data.tvalue;
|
result = tree->token.data.tvalue;
|
||||||
sp_scan(tree);
|
sp_scan(tree,SP_HINT_NONE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1052,7 +1068,7 @@ time_t sp_parse_date(PARSETREE tree) {
|
|||||||
if(tree->token.token_id == T_AFTER)
|
if(tree->token.token_id == T_AFTER)
|
||||||
before = 0;
|
before = 0;
|
||||||
|
|
||||||
sp_scan(tree);
|
sp_scan(tree,SP_HINT_NONE);
|
||||||
result = sp_parse_date(tree);
|
result = sp_parse_date(tree);
|
||||||
if(result) {
|
if(result) {
|
||||||
if(before) {
|
if(before) {
|
||||||
@ -1087,23 +1103,23 @@ time_t sp_parse_date_interval(PARSETREE tree) {
|
|||||||
sp_set_error(tree,SP_E_NUMBER);
|
sp_set_error(tree,SP_E_NUMBER);
|
||||||
} else {
|
} else {
|
||||||
count = tree->token.data.ivalue;
|
count = tree->token.data.ivalue;
|
||||||
sp_scan(tree);
|
sp_scan(tree,SP_HINT_NONE);
|
||||||
switch(tree->token.token_id) {
|
switch(tree->token.token_id) {
|
||||||
case T_DAY:
|
case T_DAY:
|
||||||
result = count * 3600 * 24;
|
result = count * 3600 * 24;
|
||||||
sp_scan(tree);
|
sp_scan(tree,SP_HINT_NONE);
|
||||||
break;
|
break;
|
||||||
case T_WEEK:
|
case T_WEEK:
|
||||||
result = count * 3600 * 24 * 7;
|
result = count * 3600 * 24 * 7;
|
||||||
sp_scan(tree);
|
sp_scan(tree,SP_HINT_NONE);
|
||||||
break;
|
break;
|
||||||
case T_MONTH:
|
case T_MONTH:
|
||||||
result = count * 3600 * 24 * 30;
|
result = count * 3600 * 24 * 30;
|
||||||
sp_scan(tree);
|
sp_scan(tree,SP_HINT_NONE);
|
||||||
break;
|
break;
|
||||||
case T_YEAR:
|
case T_YEAR:
|
||||||
result = count * 3600 * 24 * 365;
|
result = count * 3600 * 24 * 365;
|
||||||
sp_scan(tree);
|
sp_scan(tree,SP_HINT_NONE);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
result=0;
|
result=0;
|
||||||
|
Loading…
Reference in New Issue
Block a user