Add YEAR token, and integer ops -- equal, greater, less, etc.

This commit is contained in:
Ron Pedde 2003-12-07 06:36:06 +00:00
parent 47dd724c35
commit e35cf88e50
4 changed files with 110 additions and 31 deletions

View File

@ -30,12 +30,11 @@ artist { yylval.ival=ARTIST; return(ARTIST); }
album { yylval.ival=ALBUM; return(ALBUM); } album { yylval.ival=ALBUM; return(ALBUM); }
genre { yylval.ival=GENRE; return(GENRE); } genre { yylval.ival=GENRE; return(GENRE); }
is | year { yylval.ival=YEAR; return(YEAR); }
= { yylval.ival=IS; return(IS); }
includes | is { yylval.ival=IS; return(IS); }
=~ | includes { yylval.ival=INCLUDES; return(INCLUDES); }
~= { yylval.ival=INCLUDES; return(INCLUDES); } = { yylval.ival=EQUALS; return(EQUALS); }
or | or |
\|\| { yylval.ival=OR; return(OR); } \|\| { yylval.ival=OR; return(OR); }
@ -46,12 +45,18 @@ and |
not | not |
! { yylval.ival=1; return(NOT); } ! { yylval.ival=1; return(NOT); }
\<= { yylval.ival=LESSEQUAL; return(LESSEQUAL); }
\< { yylval.ival=LESS; return(LESS); }
\>= { yylval.ival=GREATEREQUAL; return(GREATEREQUAL); }
\> { yylval.ival=GREATER; return(GREATER); }
{qstring} { yylval.cval=strdup(yytext+1); {qstring} { yylval.cval=strdup(yytext+1);
if(yylval.cval[strlen(yylval.cval)-1] == '"'); if(yylval.cval[strlen(yylval.cval)-1] == '"');
yylval.cval[strlen(yylval.cval)-1] = '\0'; yylval.cval[strlen(yylval.cval)-1] = '\0';
return(ID); } return(ID); }
[0-9]+ { yylval.ival=atoi(yytext); return(NUM); }
. { return yytext[0]; } . { return yytext[0]; }
%% %%

View File

@ -7,7 +7,7 @@
/* Forwards */ /* Forwards */
extern PL_NODE *pl_newpredicate(int tag, int op, char *value); extern PL_NODE *pl_newpredicate(int tag, int op, char *value, int type);
extern PL_NODE *pl_newexpr(PL_NODE *arg1, int op, PL_NODE *arg2); extern PL_NODE *pl_newexpr(PL_NODE *arg1, int op, PL_NODE *arg2);
extern int pl_addplaylist(char *name, PL_NODE *root); extern int pl_addplaylist(char *name, PL_NODE *root);
@ -29,6 +29,11 @@ int pl_number=2;
%token <ival> ALBUM %token <ival> ALBUM
%token <ival> GENRE %token <ival> GENRE
%token <ival> EQUALS
%token <ival> LESS
%token <ival> LESSEQUAL
%token <ival> GREATER
%token <ival> GREATEREQUAL
%token <ival> IS %token <ival> IS
%token <ival> INCLUDES %token <ival> INCLUDES
@ -37,12 +42,16 @@ int pl_number=2;
%token <ival> NOT %token <ival> NOT
%token <cval> ID %token <cval> ID
%token <ival> NUM
%token <ival> YEAR
%type <plval> expression %type <plval> expression
%type <plval> predicate %type <plval> predicate
%type <ival> idtag %type <ival> strtag
%type <ival> boolarg %type <ival> inttag
%type <cval> value %type <ival> strbool
%type <ival> intbool
%type <ival> playlist %type <ival> playlist
%% %%
@ -60,25 +69,34 @@ expression: expression AND expression { $$=pl_newexpr($1,$2,$3); }
| predicate | predicate
; ;
predicate: idtag boolarg value { $$=pl_newpredicate($1, $2, $3); } predicate: strtag strbool ID { $$=pl_newpredicate($1, $2, $3, T_STR); }
| inttag intbool NUM { $$=pl_newpredicate($1, $2, $3, T_INT); }
;
idtag: ARTIST inttag: YEAR
;
intbool: EQUALS { $$ = $1; }
| LESS { $$ = $1; }
| LESSEQUAL { $$ = $1; }
| GREATER { $$ = $1; }
| GREATEREQUAL { $$ = $1; }
| NOT intbool { $$ = $2 | 0x80000000; }
;
strtag: ARTIST
| ALBUM | ALBUM
| GENRE | GENRE
; ;
boolarg: IS { $$=$1; } strbool: IS { $$=$1; }
| INCLUDES { $$=$1; } | INCLUDES { $$=$1; }
| NOT boolarg { $$=$2 | 0x80000000; } | NOT strbool { $$=$2 | 0x80000000; }
; ;
value: ID
;
%% %%
PL_NODE *pl_newpredicate(int tag, int op, char *value) { PL_NODE *pl_newpredicate(int tag, int op, char *value, int type) {
PL_NODE *pnew; PL_NODE *pnew;
pnew=(PL_NODE*)malloc(sizeof(PL_NODE)); pnew=(PL_NODE*)malloc(sizeof(PL_NODE));
@ -86,6 +104,7 @@ PL_NODE *pl_newpredicate(int tag, int op, char *value) {
return NULL; return NULL;
pnew->op=op; pnew->op=op;
pnew->type=type;
pnew->arg1.ival=tag; pnew->arg1.ival=tag;
pnew->arg2.cval=value; pnew->arg2.cval=value;
return pnew; return pnew;

View File

@ -73,6 +73,9 @@ void pl_dump_node(PL_NODE *pnode, int indent) {
case GENRE: case GENRE:
printf("GENRE "); printf("GENRE ");
break; break;
case YEAR:
printf("YEAR ");
break;
default: default:
printf ("<unknown tag> "); printf ("<unknown tag> ");
break; break;
@ -89,12 +92,37 @@ void pl_dump_node(PL_NODE *pnode, int indent) {
case INCLUDES: case INCLUDES:
printf("%s",not? "DOES NOT INCLUDE " : "INCLUDES "); printf("%s",not? "DOES NOT INCLUDE " : "INCLUDES ");
break; break;
case EQUALS:
printf("EQUALS ");
break;
case LESS:
printf("< ");
break;
case LESSEQUAL:
printf("<= ");
break;
case GREATER:
printf("> ");
break;
case GREATEREQUAL:
printf(">= ");
break;
default: default:
printf("<unknown boolop> "); printf("<unknown boolop> ");
break; break;
} }
printf("%s\n",pnode->arg2.cval); switch(pnode->type) {
case T_STR:
printf("%s\n",pnode->arg2.cval);
break;
case T_INT:
printf("%d\n",pnode->arg2.ival);
break;
default:
printf("<unknown type>\n");
break;
}
return; return;
} }
@ -161,7 +189,8 @@ void pl_eval(MP3FILE *pmp3) {
int pl_eval_node(MP3FILE *pmp3, PL_NODE *pnode) { int pl_eval_node(MP3FILE *pmp3, PL_NODE *pnode) {
int r_arg,r_arg2; int r_arg,r_arg2;
int argtypec; int argtypec;
char *argc; char *cval;
int ival;
int boolarg; int boolarg;
int not=0; int not=0;
int retval=0; int retval=0;
@ -183,16 +212,16 @@ int pl_eval_node(MP3FILE *pmp3, PL_NODE *pnode) {
/* Not an AND/OR node, so let's eval */ /* Not an AND/OR node, so let's eval */
switch(pnode->arg1.ival) { switch(pnode->arg1.ival) {
case ALBUM: case ALBUM:
argtypec=1; cval=pmp3->album;
argc=pmp3->album;
break; break;
case ARTIST: case ARTIST:
argtypec=1; cval=pmp3->artist;
argc=pmp3->artist;
break; break;
case GENRE: case GENRE:
argtypec=1; cval=pmp3->genre;
argc=pmp3->genre; break;
case YEAR:
ival=pmp3->year;
break; break;
} }
@ -200,24 +229,45 @@ int pl_eval_node(MP3FILE *pmp3, PL_NODE *pnode) {
if(pnode->op & 0x80000000) if(pnode->op & 0x80000000)
not=1; not=1;
if(argtypec) { if(pnode->type==T_STR) {
if(!argc) if(!cval)
return not; cval = "";
DPRINTF(ERR_DEBUG,"Matching %s to %s\n",argc,pnode->arg2.cval); DPRINTF(ERR_DEBUG,"Matching %s to %s\n",argc,pnode->arg2.cval);
switch(boolarg) { switch(boolarg) {
case IS: case IS:
r_arg=strcasecmp(argc,pnode->arg2.cval); r_arg=strcasecmp(cval,pnode->arg2.cval);
retval = not ? r_arg : !r_arg; retval = not ? r_arg : !r_arg;
break; break;
case INCLUDES: case INCLUDES:
r_arg=strcasestr(argc,pnode->arg2.cval); r_arg=strcasestr(cval,pnode->arg2.cval);
retval = not ? !r_arg : r_arg; retval = not ? !r_arg : r_arg;
break; break;
} }
} }
if(pnode->type==T_INT) {
switch(boolarg) {
case EQUALS:
r_arg=(ival == pnode->arg2.ival);
break;
case GREATER:
r_arg=(ival > pnode->arg2.ival);
break;
case GREATEREQUAL:
r_arg=(ival >= pnode->arg2.ival);
break;
case LESS:
r_arg=(ival < pnode->arg2.ival);
break;
case LESSEQUAL:
r_arg=(ival <= pnode->arg2.ival);
break;
}
return not? !r_arg : r_arg;
}
/* can't get here */ /* can't get here */
DPRINTF(ERR_DEBUG,"Returning %d\n",retval); DPRINTF(ERR_DEBUG,"Returning %d\n",retval);
return retval; return retval;

View File

@ -8,14 +8,19 @@
#include "mp3-scanner.h" #include "mp3-scanner.h"
#define T_INT 0
#define T_STR 1
typedef struct tag_pl_node { typedef struct tag_pl_node {
int op; int op;
int type;
union { union {
int ival; int ival;
struct tag_pl_node *plval; struct tag_pl_node *plval;
} arg1; } arg1;
union { union {
char *cval; char *cval;
int ival;
struct tag_pl_node *plval; struct tag_pl_node *plval;
} arg2; } arg2;
} PL_NODE; } PL_NODE;