mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 10:37:38 -04:00
1) Delete unused files from old database and old gui files 2) Remove unneccesary includes of the old database header 3) Delete the deprecated databox plugin
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11715 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
e22649929f
commit
ed15e2994d
16 changed files with 0 additions and 1920 deletions
|
@ -48,7 +48,6 @@
|
||||||
#include "powermgmt.h"
|
#include "powermgmt.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "database.h"
|
|
||||||
#include "splash.h"
|
#include "splash.h"
|
||||||
#include "general.h"
|
#include "general.h"
|
||||||
|
|
||||||
|
|
530
apps/database.c
530
apps/database.c
|
@ -1,530 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* __________ __ ___.
|
|
||||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
||||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
||||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
||||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
||||||
* \/ \/ \/ \/ \/
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* Copyright (C) 2005 by Michiel van der Kolk
|
|
||||||
*
|
|
||||||
* All files in this archive are subject to the GNU General Public License.
|
|
||||||
* See the file COPYING in the source tree root for full license agreement.
|
|
||||||
*
|
|
||||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
||||||
* KIND, either express or implied.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "file.h"
|
|
||||||
#include "screens.h"
|
|
||||||
#include "kernel.h"
|
|
||||||
#include "tree.h"
|
|
||||||
#include "lcd.h"
|
|
||||||
#include "font.h"
|
|
||||||
#include "settings.h"
|
|
||||||
#include "icons.h"
|
|
||||||
#include "status.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "button.h"
|
|
||||||
#include "menu.h"
|
|
||||||
#include "main_menu.h"
|
|
||||||
#include "mpeg.h"
|
|
||||||
#include "misc.h"
|
|
||||||
#include "ata.h"
|
|
||||||
#include "filetypes.h"
|
|
||||||
#include "applimits.h"
|
|
||||||
#include "icons.h"
|
|
||||||
#include "lang.h"
|
|
||||||
#include "keyboard.h"
|
|
||||||
#include "database.h"
|
|
||||||
#include "autoconf.h"
|
|
||||||
#include "splash.h"
|
|
||||||
|
|
||||||
#if CONFIG_CODEC == SWCODEC
|
|
||||||
#include "playback.h"
|
|
||||||
#else
|
|
||||||
#include "mpeg.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "logf.h"
|
|
||||||
|
|
||||||
/* internal functions */
|
|
||||||
void writetagdbheader(void);
|
|
||||||
void writefentry(struct mp3entry *id);
|
|
||||||
void getfentrybyoffset(struct mp3entry *id,int offset);
|
|
||||||
void update_fentryoffsets(int start, int end);
|
|
||||||
void writerundbheader(void);
|
|
||||||
void getrundbentrybyoffset(struct mp3entry *id,int offset);
|
|
||||||
void writerundbentry(struct mp3entry *id);
|
|
||||||
int getfentrybyfilename(struct mp3entry *id);
|
|
||||||
void clearfileentryinfo(struct mp3entry *id);
|
|
||||||
void clearruntimeinfo(struct mp3entry *id);
|
|
||||||
int findrundbentry(struct mp3entry *id);
|
|
||||||
|
|
||||||
int getfentrybyhash(int hash);
|
|
||||||
int deletefentry(char *fname);
|
|
||||||
int tagdb_shiftdown(int targetoffset, int startingoffset, int bytes);
|
|
||||||
int tagdb_shiftup(int targetoffset, int startingoffset, int bytes);
|
|
||||||
|
|
||||||
static char sbuf[MAX_PATH];
|
|
||||||
|
|
||||||
int tagdb_fd = -1;
|
|
||||||
int tagdb_initialized = 0;
|
|
||||||
struct tagdb_header tagdbheader;
|
|
||||||
|
|
||||||
int tagdb_init(void)
|
|
||||||
{
|
|
||||||
unsigned char* ptr = (unsigned char*)&tagdbheader.version;
|
|
||||||
#ifdef ROCKBOX_LITTLE_ENDIAN
|
|
||||||
int i, *p;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
tagdb_fd = open(ROCKBOX_DIR "/rockbox.tagdb", O_RDWR);
|
|
||||||
if (tagdb_fd < 0) {
|
|
||||||
DEBUGF("Failed opening database\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
read(tagdb_fd, &tagdbheader, 68);
|
|
||||||
|
|
||||||
if (ptr[0] != 'R' ||
|
|
||||||
ptr[1] != 'D' ||
|
|
||||||
ptr[2] != 'B')
|
|
||||||
{
|
|
||||||
gui_syncsplash(HZ, true,
|
|
||||||
(unsigned char *)"Not a rockbox ID3 database!");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#ifdef ROCKBOX_LITTLE_ENDIAN
|
|
||||||
p=(int *)&tagdbheader;
|
|
||||||
for(i=0;i<17;i++) {
|
|
||||||
*p=BE32(*p);
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if ( (tagdbheader.version&0xFF) != TAGDB_VERSION)
|
|
||||||
{
|
|
||||||
gui_syncsplash(HZ, true,
|
|
||||||
(unsigned char *)"Unsupported database version %d!",
|
|
||||||
tagdbheader.version&0xFF);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tagdbheader.songstart > tagdbheader.filestart ||
|
|
||||||
tagdbheader.albumstart > tagdbheader.songstart ||
|
|
||||||
tagdbheader.artiststart > tagdbheader.albumstart)
|
|
||||||
{
|
|
||||||
gui_syncsplash(HZ, true, (unsigned char *)"Corrupt ID3 database!");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
tagdb_initialized = 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tagdb_shutdown(void)
|
|
||||||
{
|
|
||||||
if (tagdb_fd >= 0)
|
|
||||||
close(tagdb_fd);
|
|
||||||
tagdb_initialized = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NOTE: All these functions below are yet untested. */
|
|
||||||
|
|
||||||
/*** TagDatabase code ***/
|
|
||||||
|
|
||||||
void writetagdbheader(void)
|
|
||||||
{
|
|
||||||
lseek(tagdb_fd,0,SEEK_SET);
|
|
||||||
write(tagdb_fd, &tagdbheader, 68);
|
|
||||||
fsync(tagdb_fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
void writefentry(struct mp3entry *id)
|
|
||||||
{ long temp;
|
|
||||||
if(!id->fileentryoffset)
|
|
||||||
return;
|
|
||||||
lseek(tagdb_fd,id->fileentryoffset,SEEK_SET);
|
|
||||||
write(tagdb_fd,id->path,tagdbheader.filelen);
|
|
||||||
temp=id->filehash;
|
|
||||||
write(tagdb_fd,&temp,4);
|
|
||||||
temp=id->songentryoffset;
|
|
||||||
write(tagdb_fd,&temp,4);
|
|
||||||
temp=id->rundbentryoffset;
|
|
||||||
write(tagdb_fd,&temp,4);
|
|
||||||
}
|
|
||||||
|
|
||||||
void getfentrybyoffset(struct mp3entry *id,int offset)
|
|
||||||
{
|
|
||||||
clearfileentryinfo(id);
|
|
||||||
lseek(tagdb_fd,offset,SEEK_SET);
|
|
||||||
read(tagdb_fd,sbuf,tagdbheader.filelen);
|
|
||||||
id->fileentryoffset=offset;
|
|
||||||
read(tagdb_fd,&id->filehash,4);
|
|
||||||
read(tagdb_fd,&id->songentryoffset,4);
|
|
||||||
read(tagdb_fd,&id->rundbentryoffset,4);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define getfentrybyrecord(_y_,_x_) getfentrybyoffset(_y_,FILERECORD2OFFSET(_x_))
|
|
||||||
|
|
||||||
int getfentrybyfilename(struct mp3entry *id)
|
|
||||||
{
|
|
||||||
int min=0;
|
|
||||||
int max=tagdbheader.filecount;
|
|
||||||
while(min<max) {
|
|
||||||
int mid=(min+max)/2;
|
|
||||||
int compare;
|
|
||||||
getfentrybyrecord(id,mid);
|
|
||||||
compare=strcasecmp(id->path,sbuf);
|
|
||||||
if(compare==0)
|
|
||||||
return 1;
|
|
||||||
else if(compare<0)
|
|
||||||
max=mid;
|
|
||||||
else
|
|
||||||
min=mid+1;
|
|
||||||
}
|
|
||||||
clearfileentryinfo(id);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
int getfentrybyhash(int hash)
|
|
||||||
{
|
|
||||||
int min=0;
|
|
||||||
for(min=0;min<tagdbheader.filecount;min++) {
|
|
||||||
getfentrybyrecord(min);
|
|
||||||
if(hash==fe.hash)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int deletefentry(char *fname)
|
|
||||||
{
|
|
||||||
if(!getfentrybyfilename(fname))
|
|
||||||
return 0;
|
|
||||||
int restrecord = currentferecord+1;
|
|
||||||
if(currentferecord!=tagdbheader.filecount) /* file is not last entry */
|
|
||||||
tagdb_shiftdown(FILERECORD2OFFSET(currentferecord),
|
|
||||||
FILERECORD2OFFSET(restrecord),
|
|
||||||
(tagdbheader.filecount-restrecord)*FILEENTRY_SIZE);
|
|
||||||
ftruncate(tagdb_fd,lseek(tagdb_fd,0,SEEK_END)-FILEENTRY_SIZE);
|
|
||||||
tagdbheader.filecount--;
|
|
||||||
update_fentryoffsets(restrecord,tagdbheader.filecount);
|
|
||||||
writetagdbheader();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void update_fentryoffsets(int start, int end)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for(i=start;i<end;i++) {
|
|
||||||
getfentrybyrecord(i);
|
|
||||||
if(fe.songentry!=-1) {
|
|
||||||
int p;
|
|
||||||
lseek(tagdb_fd,fe.songentry+tagdbheader.songlen+8,SEEK_SET);
|
|
||||||
read(tagdb_fd,&p,sizeof(int));
|
|
||||||
if(p!=currentfeoffset) {
|
|
||||||
p=currentfeoffset;
|
|
||||||
lseek(tagdb_fd,fe.songentry+tagdbheader.songlen+8,SEEK_SET);
|
|
||||||
write(tagdb_fd,&p,sizeof(int));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(fe.rundbentry!=-1) {
|
|
||||||
gui_syncsplash(HZ*2,true, "o.o.. found a rundbentry? o.o; didn't update "
|
|
||||||
"it, update the code o.o;");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int tagdb_shiftdown(int targetoffset, int startingoffset, int bytes)
|
|
||||||
{
|
|
||||||
int amount;
|
|
||||||
if(targetoffset>=startingoffset) {
|
|
||||||
gui_syncsplash(HZ*2,true,"Woah. no beeping way. (tagdb_shiftdown)");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
lseek(tagdb_fd,startingoffset,SEEK_SET);
|
|
||||||
while((amount=read(tagdb_fd,sbuf,(bytes > 1024) ? 1024 : bytes))) {
|
|
||||||
int written;
|
|
||||||
startingoffset+=amount;
|
|
||||||
lseek(tagdb_fd,targetoffset,SEEK_SET);
|
|
||||||
written=write(tagdb_fd,sbuf,amount);
|
|
||||||
targetoffset+=written;
|
|
||||||
if(amount!=written) {
|
|
||||||
gui_syncsplash(HZ*2,true,"Something went very wrong. expect database "
|
|
||||||
"corruption. (tagdb_shiftdown)");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
lseek(tagdb_fd,startingoffset,SEEK_SET);
|
|
||||||
bytes-=amount;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tagdb_shiftup(int targetoffset, int startingoffset, int bytes)
|
|
||||||
{
|
|
||||||
int amount,amount2;
|
|
||||||
int readpos,writepos,filelen;
|
|
||||||
if(targetoffset<=startingoffset) {
|
|
||||||
gui_syncsplash(HZ*2,true,"Um. no. (tagdb_shiftup)");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
filelen=lseek(tagdb_fd,0,SEEK_END);
|
|
||||||
readpos=startingoffset+bytes;
|
|
||||||
do {
|
|
||||||
amount=bytes>1024 ? 1024 : bytes;
|
|
||||||
readpos-=amount;
|
|
||||||
writepos=readpos+targetoffset-startingoffset;
|
|
||||||
lseek(tagdb_fd,readpos,SEEK_SET);
|
|
||||||
amount2=read(tagdb_fd,sbuf,amount);
|
|
||||||
if(amount2!=amount) {
|
|
||||||
gui_syncsplash(HZ*2,true,"Something went very wrong. expect database "
|
|
||||||
"corruption. (tagdb_shiftup)");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
lseek(tagdb_fd,writepos,SEEK_SET);
|
|
||||||
amount=write(tagdb_fd,sbuf,amount2);
|
|
||||||
if(amount2!=amount) {
|
|
||||||
gui_syncsplash(HZ*2,true,"Something went very wrong. expect database "
|
|
||||||
"corruption. (tagdb_shiftup)");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
bytes-=amount;
|
|
||||||
} while (amount>0);
|
|
||||||
if(bytes==0)
|
|
||||||
return 1;
|
|
||||||
else {
|
|
||||||
gui_syncsplash(HZ*2,true,"Something went wrong, >.>;; (tagdb_shiftup)");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*** end TagDatabase code ***/
|
|
||||||
|
|
||||||
int rundb_fd = -1;
|
|
||||||
int rundb_initialized = 0;
|
|
||||||
struct rundb_header rundbheader;
|
|
||||||
|
|
||||||
static long rundbsize;
|
|
||||||
|
|
||||||
/*** RuntimeDatabase code ***/
|
|
||||||
|
|
||||||
void rundb_unbuffer_track(struct mp3entry *id, bool last_track) {
|
|
||||||
writeruntimeinfo(id);
|
|
||||||
if(last_track) {
|
|
||||||
fsync(rundb_fd);
|
|
||||||
fsync(tagdb_fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void rundb_track_change(struct mp3entry *id) {
|
|
||||||
id->playcount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rundb_buffer_track(struct mp3entry *id, bool last_track) {
|
|
||||||
loadruntimeinfo(id);
|
|
||||||
if(last_track) {
|
|
||||||
fsync(rundb_fd);
|
|
||||||
fsync(tagdb_fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int rundb_init(void)
|
|
||||||
{
|
|
||||||
unsigned char* ptr = (unsigned char*)&rundbheader.version;
|
|
||||||
#ifdef ROCKBOX_LITTLE_ENDIAN
|
|
||||||
int i, *p;
|
|
||||||
#endif
|
|
||||||
if(!tagdb_initialized) /* forget it.*/
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if(!global_settings.runtimedb) /* user doesn't care */
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
rundb_fd = open(ROCKBOX_DIR "/rockbox.rundb", O_CREAT|O_RDWR);
|
|
||||||
if (rundb_fd < 0) {
|
|
||||||
DEBUGF("Failed opening database\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if(read(rundb_fd, &rundbheader, 8)!=8) {
|
|
||||||
ptr[0]=ptr[1]='R';
|
|
||||||
ptr[2]='D';
|
|
||||||
ptr[3]=0x1;
|
|
||||||
rundbheader.entrycount=0;
|
|
||||||
writerundbheader();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ptr[0] != 'R' ||
|
|
||||||
ptr[1] != 'R' ||
|
|
||||||
ptr[2] != 'D')
|
|
||||||
{
|
|
||||||
gui_syncsplash(HZ, true,
|
|
||||||
(unsigned char *)"Not a rockbox runtime database!");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#ifdef ROCKBOX_LITTLE_ENDIAN
|
|
||||||
p=(int *)&rundbheader;
|
|
||||||
for(i=0;i<2;i++) {
|
|
||||||
*p=BE32(*p);
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if ( (rundbheader.version&0xFF) != RUNDB_VERSION)
|
|
||||||
{
|
|
||||||
gui_syncsplash(HZ, true, (unsigned char *)
|
|
||||||
"Unsupported runtime database version %d!",
|
|
||||||
rundbheader.version&0xFF);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
rundb_initialized = 1;
|
|
||||||
audio_set_track_buffer_event(&rundb_buffer_track);
|
|
||||||
audio_set_track_changed_event(&rundb_track_change);
|
|
||||||
audio_set_track_unbuffer_event(&rundb_unbuffer_track);
|
|
||||||
logf("rundb inited.");
|
|
||||||
|
|
||||||
rundbsize=lseek(rundb_fd,0,SEEK_END);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rundb_shutdown(void)
|
|
||||||
{
|
|
||||||
if (rundb_fd >= 0)
|
|
||||||
close(rundb_fd);
|
|
||||||
rundb_initialized = 0;
|
|
||||||
audio_set_track_buffer_event(NULL);
|
|
||||||
audio_set_track_unbuffer_event(NULL);
|
|
||||||
audio_set_track_changed_event(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void writerundbheader(void)
|
|
||||||
{
|
|
||||||
lseek(rundb_fd,0,SEEK_SET);
|
|
||||||
write(rundb_fd, &rundbheader, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define getrundbentrybyrecord(_y_,_x_) getrundbentrybyoffset(_y_,8+_x_*20)
|
|
||||||
|
|
||||||
void getrundbentrybyoffset(struct mp3entry *id,int offset) {
|
|
||||||
lseek(rundb_fd,offset+4,SEEK_SET); // skip fileentry offset
|
|
||||||
id->rundbentryoffset=offset;
|
|
||||||
read(rundb_fd,&id->rundbhash,4);
|
|
||||||
read(rundb_fd,&id->rating,2);
|
|
||||||
read(rundb_fd,&id->voladjust,2);
|
|
||||||
read(rundb_fd,&id->playcount,4);
|
|
||||||
read(rundb_fd,&id->lastplayed,4);
|
|
||||||
#ifdef ROCKBOX_LITTLE_ENDIAN
|
|
||||||
id->rundbhash=BE32(id->rundbhash);
|
|
||||||
id->rating=BE16(id->rating);
|
|
||||||
id->voladjust=BE16(id->voladjust);
|
|
||||||
id->playcount=BE32(id->playcount);
|
|
||||||
id->lastplayed=BE32(id->lastplayed);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int getrundbentrybyhash(struct mp3entry *id)
|
|
||||||
{
|
|
||||||
int min=0;
|
|
||||||
for(min=0;min<rundbheader.entrycount;min++) {
|
|
||||||
getrundbentrybyrecord(id,min);
|
|
||||||
if(id->filehash==id->rundbhash)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
clearruntimeinfo(id);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void writerundbentry(struct mp3entry *id)
|
|
||||||
{
|
|
||||||
if(id->rundbhash==0) /* 0 = invalid rundb info. */
|
|
||||||
return;
|
|
||||||
lseek(rundb_fd,id->rundbentryoffset,SEEK_SET);
|
|
||||||
write(rundb_fd,&id->fileentryoffset,4);
|
|
||||||
write(rundb_fd,&id->rundbhash,4);
|
|
||||||
write(rundb_fd,&id->rating,2);
|
|
||||||
write(rundb_fd,&id->voladjust,2);
|
|
||||||
write(rundb_fd,&id->playcount,4);
|
|
||||||
write(rundb_fd,&id->lastplayed,4);
|
|
||||||
}
|
|
||||||
|
|
||||||
void writeruntimeinfo(struct mp3entry *id) {
|
|
||||||
logf("rundb write");
|
|
||||||
if(!id->rundbhash)
|
|
||||||
addrundbentry(id);
|
|
||||||
else
|
|
||||||
writerundbentry(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clearfileentryinfo(struct mp3entry *id) {
|
|
||||||
id->fileentryoffset=0;
|
|
||||||
id->filehash=0;
|
|
||||||
id->songentryoffset=0;
|
|
||||||
id->rundbentryoffset=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clearruntimeinfo(struct mp3entry *id) {
|
|
||||||
id->rundbhash=0;
|
|
||||||
id->rating=0;
|
|
||||||
id->voladjust=0;
|
|
||||||
id->playcount=0;
|
|
||||||
id->lastplayed=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void loadruntimeinfo(struct mp3entry *id)
|
|
||||||
{
|
|
||||||
logf("rundb load");
|
|
||||||
clearruntimeinfo(id);
|
|
||||||
clearfileentryinfo(id);
|
|
||||||
if(!getfentrybyfilename(id)) {
|
|
||||||
logf("tagdb fail: %s",id->path);
|
|
||||||
return; /* file is not in tagdatabase, could not load. */
|
|
||||||
}
|
|
||||||
if(id->rundbentryoffset!=-1 && id->rundbentryoffset<rundbsize) {
|
|
||||||
logf("load rundbentry: 0x%x", id->rundbentryoffset);
|
|
||||||
getrundbentrybyoffset(id, id->rundbentryoffset);
|
|
||||||
if(id->filehash != id->rundbhash) {
|
|
||||||
logf("Rundb: Hash mismatch. trying to repair entry.",
|
|
||||||
id->filehash, id->rundbhash);
|
|
||||||
findrundbentry(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#ifdef ROCKBOX_HAS_LOGF
|
|
||||||
if(!findrundbentry(id))
|
|
||||||
logf("rundb:no entry and not found.");
|
|
||||||
#else
|
|
||||||
findrundbentry(id);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int findrundbentry(struct mp3entry *id) {
|
|
||||||
if(getrundbentrybyhash(id)) {
|
|
||||||
logf("Found existing rundb entry: 0x%x",id->rundbentryoffset);
|
|
||||||
writefentry(id);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
clearruntimeinfo(id);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void addrundbentry(struct mp3entry *id)
|
|
||||||
{
|
|
||||||
/* first search for an entry with an equal hash. */
|
|
||||||
/* if(findrundbentry(id))
|
|
||||||
return; disabled cause this SHOULD have been checked at the buffer event.. */
|
|
||||||
rundbheader.entrycount++;
|
|
||||||
writerundbheader();
|
|
||||||
id->rundbentryoffset=lseek(rundb_fd,0,SEEK_END);
|
|
||||||
logf("Add rundb entry: 0x%x hash: 0x%x",id->rundbentryoffset,id->filehash);
|
|
||||||
id->rundbhash=id->filehash;
|
|
||||||
writefentry(id);
|
|
||||||
writerundbentry(id);
|
|
||||||
rundbsize=lseek(rundb_fd,0,SEEK_END);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** end RuntimeDatabase code ***/
|
|
|
@ -1,89 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* __________ __ ___.
|
|
||||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
||||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
||||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
||||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
||||||
* \/ \/ \/ \/ \/
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* Copyright (C) 2005 by Michiel van der Kolk
|
|
||||||
*
|
|
||||||
* All files in this archive are subject to the GNU General Public License.
|
|
||||||
* See the file COPYING in the source tree root for full license agreement.
|
|
||||||
*
|
|
||||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
||||||
* KIND, either express or implied.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
#ifndef DATABASE_H
|
|
||||||
#define DATABASE_H
|
|
||||||
|
|
||||||
#ifdef ROCKBOX_LITTLE_ENDIAN
|
|
||||||
#define BE32(_x_) (((_x_ & 0xff000000) >> 24) | \
|
|
||||||
((_x_ & 0x00ff0000) >> 8) | \
|
|
||||||
((_x_ & 0x0000ff00) << 8) | \
|
|
||||||
((_x_ & 0x000000ff) << 24))
|
|
||||||
#define BE16(_x_) ( ((_x_&0xFF00) >> 8)|((_x_&0xFF)<<8))
|
|
||||||
#else
|
|
||||||
#define BE32(_x_) _x_
|
|
||||||
#define BE16(_x_) _x_
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SONGENTRY_SIZE (tagdbheader.songlen+12+tagdbheader.genrelen+12)
|
|
||||||
#define FILEENTRY_SIZE (tagdbheader.filelen+12)
|
|
||||||
#define ALBUMENTRY_SIZE (tagdbheader.albumlen+4+tagdbheader.songarraylen*4)
|
|
||||||
#define ARTISTENTRY_SIZE (tagdbheader.artistlen+tagdbheader.albumarraylen*4)
|
|
||||||
|
|
||||||
#define FILERECORD2OFFSET(_x_) (tagdbheader.filestart + _x_ * FILEENTRY_SIZE)
|
|
||||||
|
|
||||||
extern int tagdb_initialized;
|
|
||||||
|
|
||||||
struct tagdb_header {
|
|
||||||
int version;
|
|
||||||
int artiststart;
|
|
||||||
int albumstart;
|
|
||||||
int songstart;
|
|
||||||
int filestart;
|
|
||||||
int artistcount;
|
|
||||||
int albumcount;
|
|
||||||
int songcount;
|
|
||||||
int filecount;
|
|
||||||
int artistlen;
|
|
||||||
int albumlen;
|
|
||||||
int songlen;
|
|
||||||
int genrelen;
|
|
||||||
int filelen;
|
|
||||||
int songarraylen;
|
|
||||||
int albumarraylen;
|
|
||||||
int rundbdirty;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct tagdb_header tagdbheader;
|
|
||||||
extern int tagdb_fd;
|
|
||||||
|
|
||||||
int tagdb_init(void);
|
|
||||||
void tagdb_shutdown(void);
|
|
||||||
|
|
||||||
#define TAGDB_VERSION 3
|
|
||||||
|
|
||||||
extern int rundb_fd, rundb_initialized;
|
|
||||||
extern struct rundb_header rundbheader;
|
|
||||||
|
|
||||||
struct rundb_header {
|
|
||||||
int version;
|
|
||||||
int entrycount;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
extern struct rundb_header rundbheader;
|
|
||||||
|
|
||||||
#define RUNDB_VERSION 1
|
|
||||||
|
|
||||||
void tagdb_shutdown(void);
|
|
||||||
void addrundbentry(struct mp3entry *id);
|
|
||||||
void loadruntimeinfo(struct mp3entry *id);
|
|
||||||
void writeruntimeinfo(struct mp3entry *id);
|
|
||||||
int rundb_init(void);
|
|
||||||
void rundb_shutdown(void);
|
|
||||||
#endif
|
|
|
@ -1,109 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* __________ __ ___.
|
|
||||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
||||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
||||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
||||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
||||||
* \/ \/ \/ \/ \/
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* Copyright (C) 2005 by Kevin Ferrare
|
|
||||||
*
|
|
||||||
* All files in this archive are subject to the GNU General Public License.
|
|
||||||
* See the file COPYING in the source tree root for full license agreement.
|
|
||||||
*
|
|
||||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
||||||
* KIND, either express or implied.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include "select.h"
|
|
||||||
|
|
||||||
#include "lang.h"
|
|
||||||
#include "textarea.h"
|
|
||||||
#include "screen_access.h"
|
|
||||||
#include "kernel.h"
|
|
||||||
#include "action.h"
|
|
||||||
|
|
||||||
|
|
||||||
void gui_select_init_numeric(struct gui_select * select,
|
|
||||||
const char * title,
|
|
||||||
int init_value,
|
|
||||||
int min_value,
|
|
||||||
int max_value,
|
|
||||||
int step,
|
|
||||||
const char * unit,
|
|
||||||
option_formatter *formatter)
|
|
||||||
{
|
|
||||||
select->canceled=false;
|
|
||||||
select->validated=false;
|
|
||||||
option_select_init_numeric(&select->options, title, init_value,
|
|
||||||
min_value, max_value, step, unit, formatter);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gui_select_init_items(struct gui_select * select,
|
|
||||||
const char * title,
|
|
||||||
int selected,
|
|
||||||
const struct opt_items * items,
|
|
||||||
int nb_items)
|
|
||||||
{
|
|
||||||
select->canceled=false;
|
|
||||||
select->validated=false;
|
|
||||||
option_select_init_items(&select->options, title, selected, items, nb_items);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gui_select_draw(struct gui_select * select, struct screen * display)
|
|
||||||
{
|
|
||||||
char buffer[30];
|
|
||||||
const char * selected=option_select_get_text(&(select->options), buffer,
|
|
||||||
sizeof buffer);
|
|
||||||
#ifdef HAVE_LCD_BITMAP
|
|
||||||
screen_set_xmargin(display, 0);
|
|
||||||
#endif
|
|
||||||
gui_textarea_clear(display);
|
|
||||||
display->puts_scroll(0, 0, (unsigned char *)select->options.title);
|
|
||||||
|
|
||||||
if(select->canceled)
|
|
||||||
display->puts_scroll(0, 0, str(LANG_MENU_SETTING_CANCEL));
|
|
||||||
display->puts_scroll(0, 1, (unsigned char *)selected);
|
|
||||||
gui_textarea_update(display);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gui_syncselect_draw(struct gui_select * select)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
FOR_NB_SCREENS(i)
|
|
||||||
gui_select_draw(select, &(screens[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool gui_syncselect_do_button(struct gui_select * select, int button)
|
|
||||||
{
|
|
||||||
switch(button)
|
|
||||||
{
|
|
||||||
case ACTION_SETTINGS_INCREPEAT:
|
|
||||||
select->options.limit_loop = true;
|
|
||||||
case ACTION_SETTINGS_INC:
|
|
||||||
option_select_next(&select->options);
|
|
||||||
return(true);
|
|
||||||
|
|
||||||
case ACTION_SETTINGS_DECREPEAT:
|
|
||||||
select->options.limit_loop = true;
|
|
||||||
case ACTION_SETTINGS_DEC:
|
|
||||||
option_select_prev(&select->options);
|
|
||||||
return(true);
|
|
||||||
|
|
||||||
case ACTION_STD_OK:
|
|
||||||
case ACTION_STD_PREV: /*NOTE: this is in CONTEXT_SETTINGS ! */
|
|
||||||
select->validated=true;
|
|
||||||
return(false);
|
|
||||||
|
|
||||||
case ACTION_STD_CANCEL:
|
|
||||||
select->canceled = true;
|
|
||||||
gui_syncselect_draw(select);
|
|
||||||
sleep(HZ/2);
|
|
||||||
action_signalscreenchange();
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,87 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* __________ __ ___.
|
|
||||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
||||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
||||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
||||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
||||||
* \/ \/ \/ \/ \/
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* Copyright (C) 2005 by Kevin Ferrare
|
|
||||||
*
|
|
||||||
* All files in this archive are subject to the GNU General Public License.
|
|
||||||
* See the file COPYING in the source tree root for full license agreement.
|
|
||||||
*
|
|
||||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
||||||
* KIND, either express or implied.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _GUI_SELECT_H_
|
|
||||||
#define _GUI_SELECT_H_
|
|
||||||
#include "screen_access.h"
|
|
||||||
#include "settings.h"
|
|
||||||
#include "option_select.h"
|
|
||||||
|
|
||||||
struct gui_select
|
|
||||||
{
|
|
||||||
bool canceled;
|
|
||||||
bool validated;
|
|
||||||
struct option_select options;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initializes a select that let's you choose between several numeric values
|
|
||||||
* - title : the title of the select
|
|
||||||
* - init_value : the initial value the number will be
|
|
||||||
* - min_value, max_value : bounds to the value
|
|
||||||
* - step : the ammount you want to add / withdraw to the initial number
|
|
||||||
* each time a key is pressed
|
|
||||||
* - unit : the unit in which the value is (ex "s", "bytes", ...)
|
|
||||||
* - formatter : a callback function that generates a string
|
|
||||||
* from the number it gets
|
|
||||||
*/
|
|
||||||
extern void gui_select_init_numeric(struct gui_select * select,
|
|
||||||
const char * title,
|
|
||||||
int init_value,
|
|
||||||
int min_value,
|
|
||||||
int max_value,
|
|
||||||
int step,
|
|
||||||
const char * unit,
|
|
||||||
option_formatter *formatter);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initializes a select that let's you choose between options in a list
|
|
||||||
* - title : the title of the select
|
|
||||||
* - selected : the initially selected item
|
|
||||||
* - items : the list of items, defined in settings.h
|
|
||||||
* - nb_items : the number of items in the 'items' list
|
|
||||||
*/
|
|
||||||
extern void gui_select_init_items(struct gui_select * select,
|
|
||||||
const char * title,
|
|
||||||
int selected,
|
|
||||||
const struct opt_items * items,
|
|
||||||
int nb_items
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Draws the select on the given screen
|
|
||||||
* - select : the select struct
|
|
||||||
* - display : the display on which you want to output
|
|
||||||
*/
|
|
||||||
extern void gui_select_draw(struct gui_select * select, struct screen * display);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Draws the select on all the screens
|
|
||||||
* - select : the select struct
|
|
||||||
*/
|
|
||||||
extern void gui_syncselect_draw(struct gui_select * select);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Handles key events for a synced (drawn on all screens) select
|
|
||||||
* - select : the select struct
|
|
||||||
*/
|
|
||||||
extern bool gui_syncselect_do_button(struct gui_select * select, int button);
|
|
||||||
|
|
||||||
#endif /* _GUI_SELECT_H_ */
|
|
|
@ -59,7 +59,6 @@
|
||||||
#include "talk.h"
|
#include "talk.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "database.h"
|
|
||||||
#include "dircache.h"
|
#include "dircache.h"
|
||||||
#ifdef HAVE_TAGCACHE
|
#ifdef HAVE_TAGCACHE
|
||||||
#include "tagcache.h"
|
#include "tagcache.h"
|
||||||
|
|
|
@ -58,7 +58,6 @@
|
||||||
#endif
|
#endif
|
||||||
#include "main_menu.h"
|
#include "main_menu.h"
|
||||||
#include "sound_menu.h"
|
#include "sound_menu.h"
|
||||||
#include "database.h"
|
|
||||||
#if CONFIG_CODEC == SWCODEC
|
#if CONFIG_CODEC == SWCODEC
|
||||||
#include "eq_menu.h"
|
#include "eq_menu.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#ifndef IRIVER_IFP7XX_SERIES
|
#ifndef IRIVER_IFP7XX_SERIES
|
||||||
|
|
||||||
/* For all targets */
|
/* For all targets */
|
||||||
databox
|
|
||||||
|
|
||||||
/* For various targets... */
|
/* For various targets... */
|
||||||
#if (CONFIG_KEYPAD == RECORDER_PAD) || \
|
#if (CONFIG_KEYPAD == RECORDER_PAD) || \
|
||||||
|
|
|
@ -1,105 +0,0 @@
|
||||||
# __________ __ ___.
|
|
||||||
# Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
||||||
# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
||||||
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
||||||
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
||||||
# \/ \/ \/ \/ \/
|
|
||||||
# $Id$
|
|
||||||
#
|
|
||||||
|
|
||||||
INCLUDES = -I$(APPSDIR) -I.. -I. $(TARGET_INC) -I$(FIRMDIR)/include -I$(FIRMDIR)/export \
|
|
||||||
-I$(FIRMDIR)/common -I$(FIRMDIR)/drivers -I$(OUTDIR) -I$(BUILDDIR)
|
|
||||||
CFLAGS = $(INCLUDES) $(GCCOPTS) -O3 $(TARGET) $(EXTRA_DEFINES) \
|
|
||||||
-DTARGET_ID=$(TARGET_ID) -DMEM=${MEMORYSIZE} -DPLUGIN
|
|
||||||
|
|
||||||
ifdef APPEXTRA
|
|
||||||
INCLUDES += $(patsubst %,-I$(APPSDIR)/%,$(subst :, ,$(APPEXTRA)))
|
|
||||||
endif
|
|
||||||
|
|
||||||
LINKFILE := $(OBJDIR)/link.lds
|
|
||||||
DEPFILE = $(OBJDIR)/dep-databox
|
|
||||||
SRC = databox.c editparser.c edittoken.c
|
|
||||||
|
|
||||||
SOURCES = $(SRC)
|
|
||||||
OBJS := $(SRC:%.c=$(OBJDIR)/%.o)
|
|
||||||
DIRS = .
|
|
||||||
|
|
||||||
LDS := ../plugin.lds
|
|
||||||
OUTPUT = $(OUTDIR)/databox.rock
|
|
||||||
|
|
||||||
all: $(OUTPUT)
|
|
||||||
|
|
||||||
ifndef SIMVER
|
|
||||||
$(OBJDIR)/databox.elf: $(OBJS) $(LINKFILE)
|
|
||||||
$(call PRINTS,LD $(@F))$(CC) $(GCCOPTS) -O -nostdlib -o $@ $(OBJS) -L$(BUILDDIR) -lplugin -lgcc \
|
|
||||||
-T$(LINKFILE) -Wl,-Map,$(OBJDIR)/databox.map
|
|
||||||
|
|
||||||
$(OUTPUT): $(OBJDIR)/databox.elf
|
|
||||||
$(call PRINTS,OBJCOPY $(@F))$(OC) -O binary $< $@
|
|
||||||
else
|
|
||||||
|
|
||||||
ifeq ($(SIMVER), x11)
|
|
||||||
###################################################
|
|
||||||
# This is the X11 simulator version
|
|
||||||
|
|
||||||
$(OUTPUT): $(OBJS)
|
|
||||||
$(call PRINTS,LD $(@F))$(CC) $(CFLAGS) $(SHARED_FLAG) $(OBJS) -L$(BUILDDIR) -lplugin -o $@
|
|
||||||
ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN)
|
|
||||||
# 'x' must be kept or you'll have "Win32 error 5"
|
|
||||||
# $ fgrep 5 /usr/include/w32api/winerror.h | head -1
|
|
||||||
# #define ERROR_ACCESS_DENIED 5L
|
|
||||||
else
|
|
||||||
@chmod -x $@
|
|
||||||
endif
|
|
||||||
|
|
||||||
else # end of x11-simulator
|
|
||||||
ifeq ($(SIMVER), sdl)
|
|
||||||
###################################################
|
|
||||||
# This is the SDL simulator version
|
|
||||||
|
|
||||||
$(OUTPUT): $(OBJS)
|
|
||||||
$(call PRINTS,LD $(@F))$(CC) $(CFLAGS) $(SHARED_FLAG) $(OBJS) -L$(BUILDDIR) -lplugin -o $@
|
|
||||||
ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN)
|
|
||||||
# 'x' must be kept or you'll have "Win32 error 5"
|
|
||||||
# $ fgrep 5 /usr/include/w32api/winerror.h | head -1
|
|
||||||
# #define ERROR_ACCESS_DENIED 5L
|
|
||||||
else
|
|
||||||
@chmod -x $@
|
|
||||||
endif
|
|
||||||
|
|
||||||
else # end of sdl-simulator
|
|
||||||
###################################################
|
|
||||||
# This is the win32 simulator version
|
|
||||||
DLLTOOLFLAGS = --export-all
|
|
||||||
DLLWRAPFLAGS = -s --entry _DllMain@12 --target=i386-mingw32 -mno-cygwin
|
|
||||||
|
|
||||||
$(OUTPUT): $(OBJS)
|
|
||||||
$(call PRINTS,DLL $(@F))$(DLLTOOL) $(DLLTOOLFLAGS) -z $(OBJDIR)/$*.def $(OBJS)
|
|
||||||
$(SILENT)$(DLLWRAP) $(DLLWRAPFLAGS) --def $(OBJDIR)/$*.def $(OBJS) \
|
|
||||||
$(BUILDDIR)/libplugin.a -o $@
|
|
||||||
ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN)
|
|
||||||
# 'x' must be kept or you'll have "Win32 error 5"
|
|
||||||
# $ fgrep 5 /usr/include/w32api/winerror.h | head -1
|
|
||||||
# #define ERROR_ACCESS_DENIED 5L
|
|
||||||
else
|
|
||||||
@chmod -x $@
|
|
||||||
endif
|
|
||||||
endif # end of win32-simulator
|
|
||||||
endif
|
|
||||||
endif # end of simulator section
|
|
||||||
|
|
||||||
|
|
||||||
include $(TOOLSDIR)/make.inc
|
|
||||||
|
|
||||||
# MEMORYSIZE should be passed on to this makefile with the chosen memory size
|
|
||||||
# given in number of MB
|
|
||||||
$(LINKFILE): $(LDS)
|
|
||||||
$(call PRINTS,build $(@F))cat $< | $(CC) -DMEMORYSIZE=$(MEMORYSIZE) $(INCLUDES) $(TARGET) \
|
|
||||||
$(DEFINES) -E -P - >$@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(call PRINTS,cleaning databox)rm -rf $(OBJDIR)/databox
|
|
||||||
$(SILENT)rm -f $(OBJDIR)/databox.* $(DEPFILE)
|
|
||||||
|
|
||||||
-include $(DEPFILE)
|
|
||||||
|
|
|
@ -1,395 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* __________ __ ___.
|
|
||||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
||||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
||||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
||||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
||||||
* \/ \/ \/ \/ \/
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* Copyright (C) 2002 Björn Stenberg
|
|
||||||
*
|
|
||||||
* All files in this archive are subject to the GNU General Public License.
|
|
||||||
* See the file COPYING in the source tree root for full license agreement.
|
|
||||||
*
|
|
||||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
||||||
* KIND, either express or implied.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
#include "databox.h"
|
|
||||||
|
|
||||||
PLUGIN_HEADER
|
|
||||||
|
|
||||||
/* variable button definitions */
|
|
||||||
#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
|
|
||||||
(CONFIG_KEYPAD == IRIVER_H300_PAD)
|
|
||||||
#define DBX_SELECT BUTTON_SELECT
|
|
||||||
#define DBX_STOP BUTTON_OFF
|
|
||||||
#elif CONFIG_KEYPAD == RECORDER_PAD
|
|
||||||
#define DBX_SELECT BUTTON_PLAY
|
|
||||||
#define DBX_STOP BUTTON_OFF
|
|
||||||
#elif CONFIG_KEYPAD == ONDIO_PAD
|
|
||||||
#define DBX_SELECT BUTTON_MENU
|
|
||||||
#define DBX_STOP BUTTON_OFF
|
|
||||||
#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
|
|
||||||
(CONFIG_KEYPAD == IPOD_3G_PAD)
|
|
||||||
#define DBX_SELECT BUTTON_SELECT
|
|
||||||
#define DBX_STOP BUTTON_MENU
|
|
||||||
#elif CONFIG_KEYPAD == PLAYER_PAD
|
|
||||||
#define DBX_SELECT BUTTON_PLAY
|
|
||||||
#define DBX_STOP BUTTON_STOP
|
|
||||||
#elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
|
|
||||||
#define DBX_SELECT BUTTON_SELECT
|
|
||||||
#define DBX_STOP BUTTON_PLAY
|
|
||||||
#elif CONFIG_KEYPAD == IAUDIO_X5_PAD
|
|
||||||
#define DBX_SELECT BUTTON_SELECT
|
|
||||||
#define DBX_STOP BUTTON_PLAY
|
|
||||||
#elif CONFIG_KEYPAD == GIGABEAT_PAD
|
|
||||||
#define DBX_SELECT BUTTON_SELECT
|
|
||||||
#define DBX_STOP BUTTON_A
|
|
||||||
#elif CONFIG_KEYPAD == IRIVER_H10_PAD
|
|
||||||
#define DBX_SELECT BUTTON_REW
|
|
||||||
#define DBX_STOP BUTTON_PLAY
|
|
||||||
#elif CONFIG_KEYPAD == SANSA_E200_PAD
|
|
||||||
#define DBX_SELECT BUTTON_SELECT
|
|
||||||
#define DBX_STOP BUTTON_POWER
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAX_TOKENS 70
|
|
||||||
|
|
||||||
/* here is a global api struct pointer. while not strictly necessary,
|
|
||||||
it's nice not to have to pass the api pointer in all function calls
|
|
||||||
in the plugin */
|
|
||||||
struct plugin_api* rb;
|
|
||||||
struct token tokenbuf[MAX_TOKENS];
|
|
||||||
|
|
||||||
struct print printing;
|
|
||||||
struct editor editor;
|
|
||||||
struct editing editing;
|
|
||||||
|
|
||||||
extern int acceptedmask;
|
|
||||||
|
|
||||||
void databox_init(void) {
|
|
||||||
#ifdef HAVE_LCD_BITMAP
|
|
||||||
printing.fontfixed = rb->font_get(FONT_SYSFIXED);
|
|
||||||
rb->lcd_setfont(FONT_SYSFIXED);
|
|
||||||
printing.font_w = printing.fontfixed->maxwidth;
|
|
||||||
printing.font_h = printing.fontfixed->height;
|
|
||||||
#endif
|
|
||||||
printing.line=0;
|
|
||||||
printing.position=0;
|
|
||||||
editor.editingmode = INVALID_MARK;
|
|
||||||
editor.token = tokenbuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_LCD_BITMAP
|
|
||||||
void print(char *word, int invert) {
|
|
||||||
int strlen=rb->strlen(word), newpos=printing.position+strlen+1;
|
|
||||||
if(newpos*printing.font_w>LCD_WIDTH) {
|
|
||||||
printing.line++;
|
|
||||||
printing.position=0;
|
|
||||||
newpos=printing.position+strlen+1;
|
|
||||||
}
|
|
||||||
/* Fixme: the display code needs to keep the current item visible instead of
|
|
||||||
* just displaying the first items. */
|
|
||||||
if (printing.font_h*printing.line >= LCD_HEIGHT)
|
|
||||||
return;
|
|
||||||
rb->lcd_putsxy(printing.font_w*printing.position,printing.font_h*printing.line,word);
|
|
||||||
if(invert) {
|
|
||||||
rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
|
|
||||||
rb->lcd_fillrect(printing.font_w*printing.position,printing.font_h*printing.line,printing.font_w*strlen,printing.font_h);
|
|
||||||
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
||||||
}
|
|
||||||
rb->lcd_update_rect(printing.font_w*printing.position,printing.font_h*printing.line,printing.font_w*strlen,printing.font_h);
|
|
||||||
printing.position=newpos;
|
|
||||||
}
|
|
||||||
#else /* HAVE_LCD_CHARCELLS */
|
|
||||||
#define MARKER_LEFT 0x81
|
|
||||||
#define MARKER_RIGHT 0x82
|
|
||||||
void print(char *word, int invert) {
|
|
||||||
int strlen = rb->strlen(word);
|
|
||||||
int newpos = printing.position + strlen + (invert ? 3 : 1);
|
|
||||||
if (newpos > 11) {
|
|
||||||
printing.line++;
|
|
||||||
printing.position = 0;
|
|
||||||
newpos = printing.position + strlen + (invert ? 3 : 1);
|
|
||||||
}
|
|
||||||
/* Fixme: the display code needs to keep the current item visible instead of
|
|
||||||
* just displaying the first items. */
|
|
||||||
if (printing.line >= 2)
|
|
||||||
return;
|
|
||||||
if (invert) {
|
|
||||||
rb->lcd_putc(printing.position, printing.line, MARKER_LEFT);
|
|
||||||
rb->lcd_puts(printing.position + 1, printing.line, word);
|
|
||||||
rb->lcd_putc(printing.position + strlen + 1, printing.line, MARKER_RIGHT);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
rb->lcd_puts(printing.position, printing.line, word);
|
|
||||||
printing.position = newpos;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void displaytstream(struct token *token) {
|
|
||||||
int index=0;
|
|
||||||
while(token[index].kind!=TOKEN_EOF||index==editor.currentindex) {
|
|
||||||
if(editing.selecting&&index==editor.currentindex) {
|
|
||||||
print(tokentypetostring(editing.selection_candidates[editing.currentselection]),1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
print(tokentostring(&token[index]),index==editor.currentindex ? 1 : 0);
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void buildchoices(int mask) {
|
|
||||||
int i;
|
|
||||||
for(i=0;i<20;i++)
|
|
||||||
editing.selection_candidates[i]=-1;
|
|
||||||
i=0;
|
|
||||||
if(editing.selecting&&
|
|
||||||
editing.old_token.kind!=TOKEN_EOF &&
|
|
||||||
editing.old_token.kind!=TOKEN_INVALID) {
|
|
||||||
editing.selection_candidates[i++]=TOKEN_EDIT;
|
|
||||||
}
|
|
||||||
if((mask&ACCEPT_EOF)&&editor.valid)
|
|
||||||
editing.selection_candidates[i++]=TOKEN_EOF;
|
|
||||||
if(mask&ACCEPT_NOT)
|
|
||||||
editing.selection_candidates[i++]=TOKEN_NOT;
|
|
||||||
if(mask&ACCEPT_BOOLOP) {
|
|
||||||
editing.selection_candidates[i++]=TOKEN_AND;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_OR;
|
|
||||||
}
|
|
||||||
if(mask&ACCEPT_NUMOP) {
|
|
||||||
editing.selection_candidates[i++]=TOKEN_GT;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_GTE;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_LT;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_LTE;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_NE;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_EQ;
|
|
||||||
}
|
|
||||||
if(mask&ACCEPT_STROP) {
|
|
||||||
editing.selection_candidates[i++]=TOKEN_CONTAINS;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_EQUALS;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_STARTSWITH;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_ENDSWITH;
|
|
||||||
}
|
|
||||||
if(mask&ACCEPT_LPAREN) {
|
|
||||||
editing.selection_candidates[i++]=TOKEN_LPAREN;
|
|
||||||
}
|
|
||||||
if(mask&ACCEPT_RPAREN) {
|
|
||||||
editing.selection_candidates[i++]=TOKEN_RPAREN;
|
|
||||||
}
|
|
||||||
if(mask&ACCEPT_NUMARG) {
|
|
||||||
editing.selection_candidates[i++]=TOKEN_NUM;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_YEAR;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_RATING;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_PLAYCOUNT;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_AUTORATING;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_TRACKNUM;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_PLAYTIME;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_SAMPLERATE;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_BITRATE;
|
|
||||||
}
|
|
||||||
if(mask&ACCEPT_STRARG) {
|
|
||||||
editing.selection_candidates[i++]=TOKEN_STRING;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_TITLE;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_ARTIST;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_ALBUM;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_GENRE;
|
|
||||||
editing.selection_candidates[i++]=TOKEN_FILENAME;
|
|
||||||
}
|
|
||||||
editing.selectionmax=i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns tokencount or 0 if error */
|
|
||||||
int readtstream(char *filename,struct token *token,int max) {
|
|
||||||
int tokencount=0;
|
|
||||||
int filelen,i;
|
|
||||||
int fd;
|
|
||||||
rb->memset(token,0,max*sizeof(struct token));
|
|
||||||
fd=rb->open(filename,O_RDONLY);
|
|
||||||
if(fd>=0) {
|
|
||||||
filelen=rb->filesize(fd);
|
|
||||||
if(filelen>0) {
|
|
||||||
if(filelen % sizeof(struct token)) {
|
|
||||||
rb->splash(HZ*2,true,"Filesize not a multiple of sizeof(struct token)");
|
|
||||||
rb->close(fd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
tokencount=(filelen/sizeof(struct token))-1;
|
|
||||||
for(i=0;i<tokencount&&i<max;i++) {
|
|
||||||
rb->read(fd,&token[i],sizeof(struct token));
|
|
||||||
token[i].intvalue=BE32(token[i].intvalue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rb->close(fd);
|
|
||||||
}
|
|
||||||
return tokencount;
|
|
||||||
}
|
|
||||||
|
|
||||||
int writetstream(char *filename,struct token *token) {
|
|
||||||
int fd,i;
|
|
||||||
fd=rb->open(filename,O_WRONLY|O_CREAT|O_TRUNC);
|
|
||||||
if(fd<0)
|
|
||||||
return 0;
|
|
||||||
i=0;
|
|
||||||
while(token[i].kind!=TOKEN_EOF) {
|
|
||||||
token[i].intvalue=BE32(token[i].intvalue);
|
|
||||||
rb->write(fd,&token[i++],sizeof(struct token));
|
|
||||||
}
|
|
||||||
token[i].intvalue=BE32(token[i].intvalue);
|
|
||||||
rb->write(fd,&token[i++],sizeof(struct token));
|
|
||||||
rb->close(fd);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this is the plugin entry point */
|
|
||||||
enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
|
||||||
{
|
|
||||||
int button,done=0,abort=0;
|
|
||||||
char filename[100],buf[100];
|
|
||||||
/* if you don't use the parameter, you can do like
|
|
||||||
this to avoid the compiler warning about it */
|
|
||||||
(void)parameter;
|
|
||||||
|
|
||||||
/* if you are using a global api pointer, don't forget to copy it!
|
|
||||||
otherwise you will get lovely "I04: IllInstr" errors... :-) */
|
|
||||||
rb = api;
|
|
||||||
|
|
||||||
/* now go ahead and have fun! */
|
|
||||||
rb->splash(HZ*2, true, "Databox! Enter filename ^.^");
|
|
||||||
databox_init();
|
|
||||||
filename[0] = '\0';
|
|
||||||
if(rb->kbd_input(filename, sizeof filename)) {
|
|
||||||
rb->splash(HZ*2, true, "Cancelled...");
|
|
||||||
return PLUGIN_OK;
|
|
||||||
}
|
|
||||||
/* add / in front if omitted */
|
|
||||||
if(filename[0]!='/') {
|
|
||||||
rb->strncpy(buf+1,filename,sizeof(filename)-1);
|
|
||||||
buf[0]='/';
|
|
||||||
rb->strcpy(filename,buf);
|
|
||||||
}
|
|
||||||
/* add extension if omitted */
|
|
||||||
if(rb->strncasecmp(filename+rb->strlen(filename)-4,".rsp",4)) {
|
|
||||||
rb->strcat(filename,".rsp");
|
|
||||||
}
|
|
||||||
editor.currentindex=editor.tokencount
|
|
||||||
=readtstream(filename,editor.token,MAX_TOKENS);
|
|
||||||
editing.currentselection=0;
|
|
||||||
editing.selecting=0;
|
|
||||||
if(editor.currentindex==0) {
|
|
||||||
editor.valid=check_tokenstream(editor.token,editor.editingmode);
|
|
||||||
check_accepted(editor.token,editor.currentindex);
|
|
||||||
editing.selecting=1;
|
|
||||||
buildchoices(acceptedmask);
|
|
||||||
rb->memset(&editing.old_token,0,sizeof(struct token));
|
|
||||||
}
|
|
||||||
do {
|
|
||||||
#ifdef HAVE_LCD_BITMAP
|
|
||||||
rb->lcd_setfont(FONT_SYSFIXED);
|
|
||||||
#endif
|
|
||||||
rb->lcd_clear_display();
|
|
||||||
printing.line=0;
|
|
||||||
printing.position=0;
|
|
||||||
displaytstream(editor.token);
|
|
||||||
editor.valid=check_tokenstream(editor.token,editor.editingmode);
|
|
||||||
check_accepted(editor.token,editor.currentindex);
|
|
||||||
#ifdef HAVE_LCD_BITMAP
|
|
||||||
rb->lcd_update();
|
|
||||||
#endif
|
|
||||||
button = rb->button_get(true);
|
|
||||||
switch (button) {
|
|
||||||
case BUTTON_LEFT:
|
|
||||||
#ifdef BUTTON_DOWN
|
|
||||||
case BUTTON_DOWN:
|
|
||||||
#endif
|
|
||||||
if (editing.selecting)
|
|
||||||
editing.currentselection = (editing.currentselection +
|
|
||||||
editing.selectionmax-1) % editing.selectionmax;
|
|
||||||
else
|
|
||||||
editor.currentindex = (editor.currentindex + editor.tokencount)
|
|
||||||
% (editor.tokencount+1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BUTTON_RIGHT:
|
|
||||||
#ifdef BUTTON_UP
|
|
||||||
case BUTTON_UP:
|
|
||||||
#endif
|
|
||||||
if (editing.selecting)
|
|
||||||
editing.currentselection = (editing.currentselection+1)
|
|
||||||
% editing.selectionmax;
|
|
||||||
else
|
|
||||||
editor.currentindex = (editor.currentindex+1)
|
|
||||||
% (editor.tokencount+1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DBX_SELECT:
|
|
||||||
if(editing.selecting) {
|
|
||||||
buildtoken(editing.selection_candidates[editing.currentselection],
|
|
||||||
&editor.token[editor.currentindex]);
|
|
||||||
editing.selecting=0;
|
|
||||||
if(editor.token[editor.currentindex].kind==TOKEN_EOF)
|
|
||||||
done=1;
|
|
||||||
else if(editor.currentindex==editor.tokencount) {
|
|
||||||
editor.tokencount++;
|
|
||||||
editor.currentindex++;
|
|
||||||
editor.valid=check_tokenstream(editor.token,editor.editingmode);
|
|
||||||
check_accepted(editor.token,editor.currentindex);
|
|
||||||
editing.selecting=1;
|
|
||||||
editing.currentselection=0;
|
|
||||||
buildchoices(acceptedmask);
|
|
||||||
rb->memcpy(&editing.old_token,&editor.token[editor.currentindex],
|
|
||||||
sizeof(struct token));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
editing.selecting=1;
|
|
||||||
editing.currentselection=0;
|
|
||||||
buildchoices(acceptedmask);
|
|
||||||
rb->memcpy(&editing.old_token,&editor.token[editor.currentindex],
|
|
||||||
sizeof(struct token));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DBX_STOP:
|
|
||||||
if(editing.selecting) {
|
|
||||||
rb->memcpy(&editor.token[editor.currentindex],&editing.old_token,
|
|
||||||
sizeof(struct token));
|
|
||||||
editing.selecting=0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
abort=1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (rb->default_event_handler(button) == SYS_USB_CONNECTED) {
|
|
||||||
#ifdef HAVE_LCD_BITMAP
|
|
||||||
rb->lcd_setfont(FONT_UI);
|
|
||||||
#endif
|
|
||||||
return PLUGIN_USB_CONNECTED;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (!done&&!abort);
|
|
||||||
#ifdef HAVE_LCD_BITMAP
|
|
||||||
rb->lcd_setfont(FONT_UI);
|
|
||||||
#endif
|
|
||||||
if(abort)
|
|
||||||
return PLUGIN_OK;
|
|
||||||
|
|
||||||
if(editor.valid&&editor.tokencount>0) {
|
|
||||||
if(writetstream(filename,editor.token)) {
|
|
||||||
rb->splash(HZ*2,true,"Wrote file succesfully ^.^");
|
|
||||||
return PLUGIN_OK;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rb->splash(HZ*2,true,"Error while writing file :(");
|
|
||||||
return PLUGIN_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rb->splash(HZ*2,true,"Search query invalid, not saving.");
|
|
||||||
return PLUGIN_OK;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* __________ __ ___.
|
|
||||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
||||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
||||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
||||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
||||||
* \/ \/ \/ \/ \/
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* Copyright (C) 2005 by Michiel van der Kolk
|
|
||||||
*
|
|
||||||
* All files in this archive are subject to the GNU General Public License.
|
|
||||||
* See the file COPYING in the source tree root for full license agreement.
|
|
||||||
*
|
|
||||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
||||||
* KIND, either express or implied.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
#ifndef DATABOX_H
|
|
||||||
#define DATABOX_H
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <plugin.h>
|
|
||||||
#include <database.h>
|
|
||||||
|
|
||||||
#include "edittoken.h"
|
|
||||||
#include "editparser.h"
|
|
||||||
|
|
||||||
extern struct plugin_api* rb;
|
|
||||||
|
|
||||||
struct print {
|
|
||||||
#ifdef HAVE_LCD_BITMAP
|
|
||||||
struct font *fontfixed;
|
|
||||||
int font_w,font_h;
|
|
||||||
#endif
|
|
||||||
int line;
|
|
||||||
int position;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct editor {
|
|
||||||
struct token *token; /* tokenstream */
|
|
||||||
int currentindex; /* index of the token to change.(+1, 1=0 2=1 3=2 etc.) */
|
|
||||||
int tokencount; /* total amount of tokens */
|
|
||||||
int editingmode; /* defined in databox.h */
|
|
||||||
int valid; /* is the current tokenstream valid ? */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct editing {
|
|
||||||
int selection_candidates[30]; /* possible options for this selecting */
|
|
||||||
struct token old_token; /* only set when selecting, stores old token */
|
|
||||||
int currentselection; /* current selection index */
|
|
||||||
int selectionmax;
|
|
||||||
int selecting; /* boolean */
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct print printing;
|
|
||||||
extern struct editor editor;
|
|
||||||
extern struct editing editing;
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,205 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* __________ __ ___.
|
|
||||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
||||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
||||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
||||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
||||||
* \/ \/ \/ \/ \/
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* Copyright (C) 2005 by Michiel van der Kolk
|
|
||||||
*
|
|
||||||
* All files in this archive are subject to the GNU General Public License.
|
|
||||||
* See the file COPYING in the source tree root for full license agreement.
|
|
||||||
*
|
|
||||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
||||||
* KIND, either express or implied.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
#include "databox.h"
|
|
||||||
#include "edittoken.h"
|
|
||||||
#include "editparser.h"
|
|
||||||
|
|
||||||
struct token *currenttoken,*lasttoken,*tokenstream;
|
|
||||||
int currentindex;
|
|
||||||
int lparencount,acceptedmask;
|
|
||||||
int tokensleft;
|
|
||||||
int invalid;
|
|
||||||
int invalid_mode;
|
|
||||||
|
|
||||||
void check_accepted(struct token *tstream, int count) {
|
|
||||||
parse_stream(tstream,count+1,INVALID_EXPERT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void parse_stream(struct token *tstream, int count, int inv_mode) {
|
|
||||||
invalid_mode=inv_mode;
|
|
||||||
acceptedmask=0;
|
|
||||||
lparencount=0;
|
|
||||||
tokensleft=count;
|
|
||||||
currentindex=0;
|
|
||||||
invalid=0;
|
|
||||||
tokenstream=tstream;
|
|
||||||
currenttoken=&tokenstream[currentindex];
|
|
||||||
parseMExpr();
|
|
||||||
}
|
|
||||||
|
|
||||||
int check_tokenstream(struct token *tstream, int inv_mode) {
|
|
||||||
int inval=0;
|
|
||||||
int i;
|
|
||||||
parse_stream(tstream,-1,inv_mode);
|
|
||||||
inval=invalid;
|
|
||||||
while( (inv_mode==INVALID_STRIP||inv_mode==INVALID_MARK) && invalid)
|
|
||||||
parse_stream(tstream,-1,inv_mode);
|
|
||||||
i=0;
|
|
||||||
while(tstream[i].kind!=TOKEN_EOF)
|
|
||||||
if(tstream[i++].kind==TOKEN_INVALID) {
|
|
||||||
inval=1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return inval==0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void parse_accept_rparen(void) {
|
|
||||||
if(!tokensleft) return;
|
|
||||||
if(lparencount) {
|
|
||||||
acceptedmask|=ACCEPT_RPAREN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void parse_accept(int bitmask) {
|
|
||||||
if(!tokensleft) return;
|
|
||||||
acceptedmask|=bitmask;
|
|
||||||
if(lparencount) {
|
|
||||||
acceptedmask&=~ACCEPT_EOF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void parse_checktoken() {
|
|
||||||
int ok=0;
|
|
||||||
if(!tokensleft) return;
|
|
||||||
lasttoken=currenttoken;
|
|
||||||
switch(lasttoken->kind) {
|
|
||||||
case TOKEN_EOF:
|
|
||||||
ok=acceptedmask&ACCEPT_EOF;
|
|
||||||
break;
|
|
||||||
case TOKEN_NOT:
|
|
||||||
ok=acceptedmask&ACCEPT_NOT;
|
|
||||||
break;
|
|
||||||
case TOKEN_AND:
|
|
||||||
case TOKEN_OR:
|
|
||||||
ok=acceptedmask&ACCEPT_BOOLOP;
|
|
||||||
break;
|
|
||||||
case TOKEN_GT:
|
|
||||||
case TOKEN_GTE:
|
|
||||||
case TOKEN_LT:
|
|
||||||
case TOKEN_LTE:
|
|
||||||
case TOKEN_NE:
|
|
||||||
case TOKEN_EQ:
|
|
||||||
ok=acceptedmask&ACCEPT_NUMOP;
|
|
||||||
break;
|
|
||||||
case TOKEN_EQUALS:
|
|
||||||
case TOKEN_CONTAINS:
|
|
||||||
case TOKEN_STARTSWITH:
|
|
||||||
case TOKEN_ENDSWITH:
|
|
||||||
ok=acceptedmask&ACCEPT_STROP;
|
|
||||||
break;
|
|
||||||
case TOKEN_STRING:
|
|
||||||
case TOKEN_STRINGIDENTIFIER:
|
|
||||||
ok=acceptedmask&ACCEPT_STRARG;
|
|
||||||
break;
|
|
||||||
case TOKEN_NUM:
|
|
||||||
case TOKEN_NUMIDENTIFIER:
|
|
||||||
ok=acceptedmask&ACCEPT_NUMARG;
|
|
||||||
break;
|
|
||||||
case TOKEN_LPAREN:
|
|
||||||
ok=acceptedmask&ACCEPT_LPAREN;
|
|
||||||
if(ok) lparencount++;
|
|
||||||
break;
|
|
||||||
case TOKEN_RPAREN:
|
|
||||||
ok=acceptedmask&ACCEPT_RPAREN;
|
|
||||||
if(ok) lparencount--;
|
|
||||||
break;
|
|
||||||
case TOKEN_INVALID:
|
|
||||||
if(invalid_mode!=INVALID_STRIP)
|
|
||||||
ok=1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tokensleft--;
|
|
||||||
if(lasttoken->kind==TOKEN_EOF)
|
|
||||||
tokensleft=0;
|
|
||||||
if(!ok&&tokensleft) {
|
|
||||||
// delete token
|
|
||||||
int i=currentindex;
|
|
||||||
//printf("Syntax error. accepted: 0x%x index:%d token: %d %s\n",acceptedmask,currentindex,currenttoken->kind,tokentostring(currenttoken));
|
|
||||||
switch (invalid_mode) {
|
|
||||||
case INVALID_STRIP:
|
|
||||||
do {
|
|
||||||
rb->memcpy(currenttoken,&tokenstream[++i],sizeof(struct token));;
|
|
||||||
currenttoken=&tokenstream[i];
|
|
||||||
} while (currenttoken->kind!=TOKEN_EOF);
|
|
||||||
currenttoken=&tokenstream[currentindex];
|
|
||||||
break;
|
|
||||||
case INVALID_MARK:
|
|
||||||
currenttoken->kind=TOKEN_INVALID;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tokensleft=0;
|
|
||||||
invalid=1;
|
|
||||||
}
|
|
||||||
if(tokensleft) {
|
|
||||||
currenttoken=&tokenstream[++currentindex];
|
|
||||||
acceptedmask=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void parseCompareNum() {
|
|
||||||
parse_accept(ACCEPT_NUMOP);
|
|
||||||
parse_checktoken();
|
|
||||||
parse_accept(ACCEPT_NUMARG);
|
|
||||||
parse_checktoken();
|
|
||||||
}
|
|
||||||
|
|
||||||
void parseCompareString() {
|
|
||||||
parse_accept(ACCEPT_STROP);
|
|
||||||
parse_checktoken();
|
|
||||||
parse_accept(ACCEPT_STRARG);
|
|
||||||
parse_checktoken();
|
|
||||||
}
|
|
||||||
|
|
||||||
void parseExpr() {
|
|
||||||
if(!tokensleft) return;
|
|
||||||
parse_accept(ACCEPT_NOT|ACCEPT_LPAREN|ACCEPT_NUMARG|ACCEPT_STRARG);
|
|
||||||
parse_checktoken();
|
|
||||||
switch(lasttoken->kind) {
|
|
||||||
case TOKEN_NOT:
|
|
||||||
parseExpr();
|
|
||||||
break;
|
|
||||||
case TOKEN_LPAREN:
|
|
||||||
parseMExpr();
|
|
||||||
break;
|
|
||||||
case TOKEN_NUM:
|
|
||||||
case TOKEN_NUMIDENTIFIER:
|
|
||||||
parseCompareNum();
|
|
||||||
break;
|
|
||||||
case TOKEN_STRING:
|
|
||||||
case TOKEN_STRINGIDENTIFIER:
|
|
||||||
parseCompareString();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void parseMExpr() {
|
|
||||||
parseExpr();
|
|
||||||
parse_accept_rparen();
|
|
||||||
parse_accept(ACCEPT_BOOLOP|ACCEPT_EOF);
|
|
||||||
parse_checktoken();
|
|
||||||
while(lasttoken->kind==TOKEN_OR || lasttoken->kind == TOKEN_AND) {
|
|
||||||
parseExpr();
|
|
||||||
parse_accept_rparen();
|
|
||||||
parse_accept(ACCEPT_BOOLOP|ACCEPT_EOF);
|
|
||||||
parse_checktoken();
|
|
||||||
if(!tokensleft)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* __________ __ ___.
|
|
||||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
||||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
||||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
||||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
||||||
* \/ \/ \/ \/ \/
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* Copyright (C) 2005 by Michiel van der Kolk
|
|
||||||
*
|
|
||||||
* All files in this archive are subject to the GNU General Public License.
|
|
||||||
* See the file COPYING in the source tree root for full license agreement.
|
|
||||||
*
|
|
||||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
||||||
* KIND, either express or implied.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
extern int acceptedmask;
|
|
||||||
|
|
||||||
#define INVALID_STRIP 1
|
|
||||||
#define INVALID_MARK 2
|
|
||||||
#define INVALID_EXPERT 3
|
|
||||||
|
|
||||||
void check_accepted(struct token *tstream, int count);
|
|
||||||
void parse_stream(struct token *tstream, int count, int inv_mode);
|
|
||||||
int check_tokenstream(struct token *tstream, int inv_mode);
|
|
||||||
void parser_accept_rparen(void);
|
|
||||||
void parser_accept(int bitmask);
|
|
||||||
void parse_checktoken(void);
|
|
||||||
void parseCompareNum(void);
|
|
||||||
void parseCompareString(void);
|
|
||||||
void parseExpr(void);
|
|
||||||
void parseMExpr(void);
|
|
|
@ -1,204 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* __________ __ ___.
|
|
||||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
||||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
||||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
||||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
||||||
* \/ \/ \/ \/ \/
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* Copyright (C) 2005 by Michiel van der Kolk
|
|
||||||
*
|
|
||||||
* All files in this archive are subject to the GNU General Public License.
|
|
||||||
* See the file COPYING in the source tree root for full license agreement.
|
|
||||||
*
|
|
||||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
||||||
* KIND, either express or implied.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
#include "databox.h"
|
|
||||||
#include "edittoken.h"
|
|
||||||
|
|
||||||
char *tokentypetostring(int tokentype) {
|
|
||||||
switch(tokentype) {
|
|
||||||
case TOKEN_EOF: return "<END>";
|
|
||||||
case TOKEN_NOT: return "not";
|
|
||||||
case TOKEN_AND: return "and";
|
|
||||||
case TOKEN_OR: return "or";
|
|
||||||
case TOKEN_GT: return ">";
|
|
||||||
case TOKEN_GTE: return ">=";
|
|
||||||
case TOKEN_LT: return "<";
|
|
||||||
case TOKEN_LTE: return "<=";
|
|
||||||
case TOKEN_EQ: return "==";
|
|
||||||
case TOKEN_NE: return "!=";
|
|
||||||
case TOKEN_LPAREN: return "(";
|
|
||||||
case TOKEN_RPAREN: return ")";
|
|
||||||
case TOKEN_CONTAINS: return "contains";
|
|
||||||
case TOKEN_EQUALS: return "equals";
|
|
||||||
case TOKEN_STARTSWITH: return "starts with";
|
|
||||||
case TOKEN_ENDSWITH: return "ends with";
|
|
||||||
case TOKEN_NUM: return "<number>";
|
|
||||||
case TOKEN_NUMIDENTIFIER: return "<numberproperty>";
|
|
||||||
case TOKEN_STRING: return "<string>";
|
|
||||||
case TOKEN_STRINGIDENTIFIER: return "<stringproperty>";
|
|
||||||
case TOKEN_INVALID: return "<INVALID>";
|
|
||||||
case TOKEN_EDIT: return tokentostring(&editing.old_token);
|
|
||||||
case TOKEN_YEAR: return "year";
|
|
||||||
case TOKEN_RATING: return "rating";
|
|
||||||
case TOKEN_PLAYCOUNT: return "playcount";
|
|
||||||
case TOKEN_AUTORATING: return "autorating";
|
|
||||||
case TOKEN_TITLE: return "title";
|
|
||||||
case TOKEN_ARTIST: return "artist";
|
|
||||||
case TOKEN_ALBUM: return "album";
|
|
||||||
case TOKEN_GENRE: return "genre";
|
|
||||||
case TOKEN_FILENAME: return "filename";
|
|
||||||
case TOKEN_PLAYTIME: return "playtime";
|
|
||||||
case TOKEN_TRACKNUM: return "track number";
|
|
||||||
case TOKEN_SAMPLERATE: return "sample rate";
|
|
||||||
case TOKEN_BITRATE: return "bitrate";
|
|
||||||
}
|
|
||||||
return "tokentypeerror";
|
|
||||||
}
|
|
||||||
|
|
||||||
char *numidtostring(int numid) {
|
|
||||||
switch(numid) {
|
|
||||||
case INTVALUE_YEAR: return "<year>";
|
|
||||||
case INTVALUE_RATING: return "<rating>";
|
|
||||||
case INTVALUE_PLAYCOUNT: return "<playcount>";
|
|
||||||
case INTVALUE_AUTORATING: return "<autorating>";
|
|
||||||
case INTVALUE_PLAYTIME: return "<playtime>";
|
|
||||||
case INTVALUE_TRACKNUM: return "<track number>";
|
|
||||||
case INTVALUE_SAMPLERATE: return "<sample rate>";
|
|
||||||
case INTVALUE_BITRATE: return "<bitrate>";
|
|
||||||
}
|
|
||||||
return "numiderror";
|
|
||||||
}
|
|
||||||
|
|
||||||
char *stridtostring(int strid) {
|
|
||||||
switch(strid) {
|
|
||||||
case INTVALUE_TITLE: return "<title>";
|
|
||||||
case INTVALUE_ARTIST: return "<artist>";
|
|
||||||
case INTVALUE_ALBUM: return "<album>";
|
|
||||||
case INTVALUE_GENRE: return "<genre>";
|
|
||||||
case INTVALUE_FILENAME: return "<filename>";
|
|
||||||
}
|
|
||||||
return "striderror";
|
|
||||||
}
|
|
||||||
|
|
||||||
char bufbla[40];
|
|
||||||
|
|
||||||
void buildtoken(int tokentype,struct token *token) {
|
|
||||||
// TODO
|
|
||||||
char buf[200];
|
|
||||||
rb->memset(token,0,sizeof(struct token));
|
|
||||||
rb->memset(buf,0,200);
|
|
||||||
token->kind=tokentype;
|
|
||||||
token->intvalue=0;
|
|
||||||
switch(token->kind) {
|
|
||||||
case TOKEN_STRING:
|
|
||||||
do {
|
|
||||||
rb->splash(HZ*2,true,"Enter String.");
|
|
||||||
} while(rb->kbd_input(token->spelling, SPELLING_LENGTH));
|
|
||||||
break;
|
|
||||||
case TOKEN_YEAR:
|
|
||||||
token->kind=TOKEN_NUMIDENTIFIER;
|
|
||||||
token->intvalue=INTVALUE_YEAR;
|
|
||||||
break;
|
|
||||||
case TOKEN_RATING:
|
|
||||||
token->kind=TOKEN_NUMIDENTIFIER;
|
|
||||||
token->intvalue=INTVALUE_RATING;
|
|
||||||
break;
|
|
||||||
case TOKEN_PLAYCOUNT:
|
|
||||||
token->kind=TOKEN_NUMIDENTIFIER;
|
|
||||||
token->intvalue=INTVALUE_PLAYCOUNT;
|
|
||||||
break;
|
|
||||||
case TOKEN_AUTORATING:
|
|
||||||
token->kind=TOKEN_NUMIDENTIFIER;
|
|
||||||
token->intvalue=INTVALUE_AUTORATING;
|
|
||||||
break;
|
|
||||||
case TOKEN_TITLE:
|
|
||||||
token->kind=TOKEN_STRINGIDENTIFIER;
|
|
||||||
token->intvalue=INTVALUE_TITLE;
|
|
||||||
break;
|
|
||||||
case TOKEN_ARTIST:
|
|
||||||
token->kind=TOKEN_STRINGIDENTIFIER;
|
|
||||||
token->intvalue=INTVALUE_ARTIST;
|
|
||||||
break;
|
|
||||||
case TOKEN_ALBUM:
|
|
||||||
token->kind=TOKEN_STRINGIDENTIFIER;
|
|
||||||
token->intvalue=INTVALUE_ALBUM;
|
|
||||||
break;
|
|
||||||
case TOKEN_GENRE:
|
|
||||||
token->kind=TOKEN_STRINGIDENTIFIER;
|
|
||||||
token->intvalue=INTVALUE_GENRE;
|
|
||||||
break;
|
|
||||||
case TOKEN_FILENAME:
|
|
||||||
token->kind=TOKEN_STRINGIDENTIFIER;
|
|
||||||
token->intvalue=INTVALUE_TITLE;
|
|
||||||
break;
|
|
||||||
case TOKEN_NUM:
|
|
||||||
do {
|
|
||||||
rb->splash(HZ*2,true,"Enter Number.");
|
|
||||||
} while(rb->kbd_input(buf, 199));
|
|
||||||
token->intvalue=rb->atoi(buf);
|
|
||||||
break;
|
|
||||||
case TOKEN_EDIT:
|
|
||||||
rb->memcpy(token,&editing.old_token,sizeof(struct token));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void removetoken(struct token *token,int index) {
|
|
||||||
struct token *currenttoken;
|
|
||||||
currenttoken=&token[index];
|
|
||||||
do {
|
|
||||||
rb->memcpy(currenttoken,&token[++index],sizeof(struct token));
|
|
||||||
currenttoken=&token[index];
|
|
||||||
} while (currenttoken->kind!=TOKEN_EOF);
|
|
||||||
}
|
|
||||||
|
|
||||||
void inserttoken(struct token *token,int index,int tokentype) {
|
|
||||||
struct token *currenttoken;
|
|
||||||
int max,i;
|
|
||||||
currenttoken=&token[0];
|
|
||||||
for(i=1;currenttoken->kind!=TOKEN_EOF;i++)
|
|
||||||
currenttoken=&token[i];
|
|
||||||
max=i;
|
|
||||||
for(i=max;i>=index;i--) {
|
|
||||||
rb->memcpy(&token[i+1],&token[i],sizeof(struct token));
|
|
||||||
}
|
|
||||||
buildtoken(tokentype,&token[index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
char *tokentostring(struct token *token) {
|
|
||||||
switch(token->kind) {
|
|
||||||
case TOKEN_INVALID:
|
|
||||||
case TOKEN_EOF:
|
|
||||||
case TOKEN_NOT:
|
|
||||||
case TOKEN_AND:
|
|
||||||
case TOKEN_OR:
|
|
||||||
case TOKEN_GT:
|
|
||||||
case TOKEN_GTE:
|
|
||||||
case TOKEN_LT:
|
|
||||||
case TOKEN_LTE:
|
|
||||||
case TOKEN_EQ:
|
|
||||||
case TOKEN_NE:
|
|
||||||
case TOKEN_LPAREN:
|
|
||||||
case TOKEN_RPAREN:
|
|
||||||
case TOKEN_CONTAINS:
|
|
||||||
case TOKEN_EQUALS:
|
|
||||||
case TOKEN_STARTSWITH:
|
|
||||||
case TOKEN_ENDSWITH:
|
|
||||||
return tokentypetostring(token->kind);
|
|
||||||
case TOKEN_NUM: rb->snprintf(bufbla,40,"%d",token->intvalue);
|
|
||||||
return bufbla;
|
|
||||||
case TOKEN_NUMIDENTIFIER:
|
|
||||||
return numidtostring(token->intvalue);
|
|
||||||
case TOKEN_STRING: return token->spelling;
|
|
||||||
case TOKEN_STRINGIDENTIFIER:
|
|
||||||
return stridtostring(token->intvalue);
|
|
||||||
case TOKEN_EDIT: return tokentostring(&editing.old_token);
|
|
||||||
default: return "unknown token";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,97 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* __________ __ ___.
|
|
||||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
||||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
||||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
||||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
||||||
* \/ \/ \/ \/ \/
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* Copyright (C) 2005 by Michiel van der Kolk
|
|
||||||
*
|
|
||||||
* All files in this archive are subject to the GNU General Public License.
|
|
||||||
* See the file COPYING in the source tree root for full license agreement.
|
|
||||||
*
|
|
||||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
||||||
* KIND, either express or implied.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
#ifndef EDITTOKEN_H
|
|
||||||
#define EDITTOKEN_H
|
|
||||||
|
|
||||||
#define TOKEN_INVALID -1
|
|
||||||
#define TOKEN_EOF 0 // EOF
|
|
||||||
#define TOKEN_NOT 1 // "not"
|
|
||||||
#define TOKEN_AND 2 // "and"
|
|
||||||
#define TOKEN_OR 3 // "or"
|
|
||||||
#define TOKEN_GT 4 // '>'
|
|
||||||
#define TOKEN_GTE 5 // '>='
|
|
||||||
#define TOKEN_LT 6 // '<'
|
|
||||||
#define TOKEN_LTE 7 // '<='
|
|
||||||
#define TOKEN_EQ 8 // '=='
|
|
||||||
#define TOKEN_NE 9 // '!='
|
|
||||||
#define TOKEN_CONTAINS 10 // "contains"
|
|
||||||
#define TOKEN_EQUALS 11 // "equals"
|
|
||||||
#define TOKEN_STARTSWITH 12
|
|
||||||
#define TOKEN_ENDSWITH 13
|
|
||||||
#define TOKEN_LPAREN 14 // '('
|
|
||||||
#define TOKEN_RPAREN 15 // ')'
|
|
||||||
#define TOKEN_NUM 16 // (0..9)+
|
|
||||||
#define TOKEN_NUMIDENTIFIER 17 // year, trackid, bpm, etc.
|
|
||||||
#define TOKEN_STRING 18 // (?)+
|
|
||||||
#define TOKEN_STRINGIDENTIFIER 19 // album, artist, title, genre ...
|
|
||||||
#define TOKEN_SHUFFLE 20
|
|
||||||
#define TOKEN_PLAYTIMELIMIT 21
|
|
||||||
|
|
||||||
// pseudotokens..
|
|
||||||
#define TOKEN_YEAR 118
|
|
||||||
#define TOKEN_RATING 119
|
|
||||||
#define TOKEN_PLAYCOUNT 120
|
|
||||||
#define TOKEN_TITLE 121
|
|
||||||
#define TOKEN_ARTIST 122
|
|
||||||
#define TOKEN_ALBUM 123
|
|
||||||
#define TOKEN_GENRE 124
|
|
||||||
#define TOKEN_FILENAME 125
|
|
||||||
#define TOKEN_EDIT 126
|
|
||||||
#define TOKEN_AUTORATING 127
|
|
||||||
#define TOKEN_PLAYTIME 128
|
|
||||||
#define TOKEN_TRACKNUM 129
|
|
||||||
#define TOKEN_SAMPLERATE 130
|
|
||||||
#define TOKEN_BITRATE 131
|
|
||||||
|
|
||||||
#define ACCEPT_EOF 0x1
|
|
||||||
#define ACCEPT_BOOLOP 0x2
|
|
||||||
#define ACCEPT_NUMOP 0x4
|
|
||||||
#define ACCEPT_STROP 0x8
|
|
||||||
#define ACCEPT_LPAREN 0x10
|
|
||||||
#define ACCEPT_RPAREN 0x20
|
|
||||||
#define ACCEPT_NUMARG 0x40
|
|
||||||
#define ACCEPT_STRARG 0x80
|
|
||||||
#define ACCEPT_NOT 0x100
|
|
||||||
#define ACCEPT_DELETE 0x200
|
|
||||||
|
|
||||||
#define INTVALUE_YEAR 1
|
|
||||||
#define INTVALUE_RATING 2
|
|
||||||
#define INTVALUE_PLAYCOUNT 3
|
|
||||||
#define INTVALUE_AUTORATING 4
|
|
||||||
#define INTVALUE_PLAYTIME 5
|
|
||||||
#define INTVALUE_TRACKNUM 6
|
|
||||||
#define INTVALUE_SAMPLERATE 7
|
|
||||||
#define INTVALUE_BITRATE 8
|
|
||||||
#define INTVALUE_TITLE 14
|
|
||||||
#define INTVALUE_ARTIST 15
|
|
||||||
#define INTVALUE_ALBUM 16
|
|
||||||
#define INTVALUE_GENRE 17
|
|
||||||
#define INTVALUE_FILENAME 18
|
|
||||||
|
|
||||||
#define SPELLING_LENGTH 100
|
|
||||||
|
|
||||||
struct token {
|
|
||||||
signed char kind;
|
|
||||||
char spelling[SPELLING_LENGTH + 3];
|
|
||||||
long intvalue;
|
|
||||||
};
|
|
||||||
char *tokentypetostring(int tokentype);
|
|
||||||
char *tokentostring(struct token *token);
|
|
||||||
void buildtoken(int tokentype,struct token *token);
|
|
||||||
#endif
|
|
|
@ -46,7 +46,6 @@
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "abrepeat.h"
|
#include "abrepeat.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
#include "database.h"
|
|
||||||
#include "dir.h"
|
#include "dir.h"
|
||||||
#include "dircache.h"
|
#include "dircache.h"
|
||||||
#ifdef HAVE_TAGCACHE
|
#ifdef HAVE_TAGCACHE
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue