diff --git a/apps/misc.c b/apps/misc.c index d7a64b3..481dc2a 100644 --- a/apps/misc.c +++ b/apps/misc.c @@ -27,9 +27,7 @@ #ifdef __PCTOOL__ #include #include -#ifdef WPSEDITOR -#include "string.h" -#endif +#include #else #include "sprintf.h" #include "appevents.h" @@ -765,26 +763,6 @@ char* strrsplt(char* str, int c) return s; } -/* Test file existence, using dircache of possible */ -bool file_exists(const char *file) -{ - int fd; - - if (!file || strlen(file) <= 0) - return false; - -#ifdef HAVE_DIRCACHE - if (dircache_is_enabled()) - return (dircache_get_entry_ptr(file) != NULL); -#endif - - fd = open(file, O_RDONLY); - if (fd < 0) - return false; - close(fd); - return true; -} - bool dir_exists(const char *path) { DIR* d = opendir(path); @@ -838,6 +816,26 @@ char* skip_whitespace(char* const str) return s; } +/* Test file existence, using dircache of possible */ +bool file_exists(const char *file) +{ + int fd; + + if (!file || strlen(file) <= 0) + return false; + +#ifdef HAVE_DIRCACHE + if (dircache_is_enabled()) + return (dircache_get_entry_ptr(file) != NULL); +#endif + + fd = open(file, O_RDONLY); + if (fd < 0) + return false; + close(fd); + return true; +} + /* Format time into buf. * * buf - buffer to format to. diff --git a/apps/tagcache.c b/apps/tagcache.c old mode 100644 new mode 100755 index 2b2881a..4c68b5b --- a/apps/tagcache.c +++ b/apps/tagcache.c @@ -86,7 +86,7 @@ #ifdef __PCTOOL__ #define yield() do { } while(0) -#define sim_sleep(timeout) do { } while(0) +#define sleep(timeout) do { } while(0) #define do_timed_yield() do { } while(0) #endif @@ -260,6 +260,13 @@ static int processed_dir_count; static volatile int write_lock; static volatile int read_lock; +#ifdef __PCTOOL__ +#define DB_BIG_ENDIAN 1 +#define DB_LITTLE_ENDIAN 2 + +static int database_endian = 0; +#endif + static bool delete_entry(long idx_id); const char* tagcache_tag_to_str(int tag) @@ -362,30 +369,47 @@ static int open_master_fd(struct master_header *hdr, bool write) return fd; } - tc_stat.econ = false; - - /* Check the header. */ - rc = read(fd, hdr, sizeof(struct master_header)); - if (hdr->tch.magic == TAGCACHE_MAGIC && rc == sizeof(struct master_header)) +#ifdef __PCTOOL__ + if (database_endian == 0) { - /* Success. */ - return fd; - } +#endif + tc_stat.econ = false; - /* Trying to read again, this time with endianess correction enabled. */ - lseek(fd, 0, SEEK_SET); + /* Check the header. */ + rc = read(fd, hdr, sizeof(struct master_header)); + if (hdr->tch.magic == TAGCACHE_MAGIC && rc == sizeof(struct master_header)) + { + /* Success. */ + return fd; + } + + /* Trying to read again, this time with endianess correction enabled. */ + lseek(fd, 0, SEEK_SET); - rc = ecread(fd, hdr, 1, master_header_ec, true); - if (hdr->tch.magic != TAGCACHE_MAGIC || rc != sizeof(struct master_header)) + rc = ecread(fd, hdr, 1, master_header_ec, true); + if (hdr->tch.magic != TAGCACHE_MAGIC || rc != sizeof(struct master_header)) + { + logf("header error"); + tc_stat.ready = false; + close(fd); + return -2; + } + + tc_stat.econ = true; +#ifdef __PCTOOL__ + } + else { - logf("header error"); - tc_stat.ready = false; - close(fd); - return -2; + rc = ecread(fd, hdr, 1, master_header_ec, tc_stat.econ); + if (hdr->tch.magic != TAGCACHE_MAGIC || rc != sizeof(struct master_header)) + { + logf("header error"); + tc_stat.ready = false; + close(fd); + return -2; + } } - - tc_stat.econ = true; - +#endif return fd; } @@ -1152,7 +1176,7 @@ static void remove_files(void) tc_stat.ready = false; tc_stat.ramcache = false; - tc_stat.econ = false; + //tc_stat.econ = false; remove(TAGCACHE_FILE_MASTER); for (i = 0; i < TAG_COUNT; i++) { @@ -1164,6 +1188,13 @@ static void remove_files(void) } } +#ifdef __PCTOOL__ +void tagcache_remove_database(void) +{ + remove_files(); + remove(TAGCACHE_FILE_TEMP); +} +#endif static bool check_all_headers(void) { @@ -3018,6 +3049,7 @@ static bool modify_numeric_entry(int masterfd, int idx_id, int tag, long data) return write_index(masterfd, idx_id, &idx); } +#endif #if 0 bool tagcache_modify_numeric_entry(struct tagcache_search *tcs, @@ -3035,6 +3067,7 @@ bool tagcache_modify_numeric_entry(struct tagcache_search *tcs, } #endif +#ifndef __PCTOOL__ #define COMMAND_QUEUE_IS_EMPTY (command_queue_ridx == command_queue_widx) static bool command_queue_is_full(void) @@ -3160,7 +3193,6 @@ void tagcache_update_numeric(int idx_id, int tag, long data) { queue_command(CMD_UPDATE_NUMERIC, idx_id, tag, data); } -#endif /* !__PCTOOL__ */ long tagcache_get_serial(void) { @@ -3171,6 +3203,7 @@ long tagcache_get_commitid(void) { return current_tcmh.commitid; } +#endif /* !__PCTOOL__ */ static bool write_tag(int fd, const char *tagstr, const char *datastr) { @@ -4209,9 +4242,9 @@ void tagcache_build(const char *path) } filenametag_fd = open_tag_fd(&header, tag_filename, false); - +#ifndef __PCTOOL__ cpu_boost(true); - +#endif logf("Scanning files..."); /* Scan for new files. */ memset(&header, 0, sizeof(struct tagcache_header)); @@ -4238,7 +4271,9 @@ void tagcache_build(const char *path) if (!ret) { logf("Aborted."); +#ifndef __PCTOOL__ cpu_boost(false); +#endif return ; } @@ -4264,7 +4299,9 @@ void tagcache_build(const char *path) } #endif +#ifndef __PCTOOL__ cpu_boost(false); +#endif } #ifdef HAVE_TC_RAMCACHE @@ -4273,7 +4310,9 @@ static void load_ramcache(void) if (!hdr) return ; +#ifndef __PCTOOL__ cpu_boost(true); +#endif /* At first we should load the cache (if exists). */ tc_stat.ramcache = load_tagcache(); @@ -4286,7 +4325,9 @@ static void load_ramcache(void) hdr = NULL; } +#ifndef __PCTOOL__ cpu_boost(false); +#endif } void tagcache_unload_ramcache(void) @@ -4493,8 +4534,17 @@ bool tagcache_is_ramcache(void) #endif /* !__PCTOOL__ */ - +#ifdef __PCTOOL__ +/* + * endian + * 0: The database is made by the same endian as of database_idx.tcd. + * 1: The endian of the database is made as big endian. + * 2: The endian of the database is made as little endian. + */ +void tagcache_init(int endian) +#else void tagcache_init(void) +#endif { memset(&tc_stat, 0, sizeof(struct tagcache_stat)); memset(¤t_tcmh, 0, sizeof(struct master_header)); @@ -4510,6 +4560,12 @@ void tagcache_init(void) IF_COP(, CPU)); #else tc_stat.initialized = true; + database_endian = endian; +#ifdef ROCKBOX_BIG_ENDIAN + tc_stat.econ = !(endian == DB_BIG_ENDIAN); +#else + tc_stat.econ = !(endian == DB_LITTLE_ENDIAN); +#endif allocate_tempbuf(); commit(); free_tempbuf(); diff --git a/apps/tagcache.h b/apps/tagcache.h old mode 100644 new mode 100755 index e995784..17b8b96 --- a/apps/tagcache.h +++ b/apps/tagcache.h @@ -179,6 +179,7 @@ void tagcache_build(const char *path); #ifdef __PCTOOL__ void tagcache_reverse_scan(void); +void tagcache_remove_database(void); #endif const char* tagcache_tag_to_str(int tag); @@ -222,7 +223,11 @@ bool tagcache_is_ramcache(void); bool tagcache_fill_tags(struct mp3entry *id3, const char *filename); void tagcache_unload_ramcache(void); #endif +#ifdef __PCTOOL__ +void tagcache_init(int endian); +#else void tagcache_init(void); +#endif bool tagcache_is_initialized(void); bool tagcache_is_usable(void); void tagcache_start_scan(void); diff --git a/firmware/common/unicode.c b/firmware/common/unicode.c index 61989e5..062576d 100644 --- a/firmware/common/unicode.c +++ b/firmware/common/unicode.c @@ -40,7 +40,7 @@ static int default_codepage = 0; static int loaded_cp_table = 0; -#ifdef HAVE_LCD_BITMAP +#if defined(HAVE_LCD_BITMAP) || defined(__PCTOOL__) #define MAX_CP_TABLE_SIZE 32768 #define NUM_TABLES 5 @@ -194,7 +194,7 @@ unsigned char* iso_decode(const unsigned char *iso, unsigned char *utf8, case ISO_8859_9: /* Turkish */ case ISO_8859_2: /* Latin Extended */ case WIN_1250: /* Central European */ -#ifdef HAVE_LCD_BITMAP +#if defined(HAVE_LCD_BITMAP) || defined(__PCTOOL__) case ISO_8859_8: /* Hebrew */ case ISO_8859_11: /* Thai */ case WIN_1256: /* Arabic */ @@ -203,7 +203,7 @@ unsigned char* iso_decode(const unsigned char *iso, unsigned char *utf8, ucs = codepage_table[tmp]; break; -#ifdef HAVE_LCD_BITMAP +#if defined(HAVE_LCD_BITMAP) || defined(__PCTOOL__) case SJIS: /* Japanese */ if (*iso > 0xA0 && *iso < 0xE0) { tmp = *iso++ | (0xA100 - 0x8000); diff --git a/firmware/export/system.h b/firmware/export/system.h index b44600d..af1dcf2 100644 --- a/firmware/export/system.h +++ b/firmware/export/system.h @@ -228,9 +228,9 @@ enum { MAXMEMGUARD }; -#ifndef SIMULATOR +#if !defined(SIMULATOR) && !defined(__PCTOOL__) #include "system-target.h" -#else /* SIMULATOR */ +#else /* SIMULATOR and __PCTOOL__ */ static inline uint16_t swap16(uint16_t value) /* @@ -264,7 +264,7 @@ static inline uint32_t swap_odd_even32(uint32_t value) return (t >> 8) | ((t ^ value) << 8); } -#endif /* !SIMULATOR */ +#endif /* !SIMULATOR and __PCTOOL__ */ /* Declare this as HIGHEST_IRQ_LEVEL if they don't differ */ #ifndef DISABLE_INTERRUPTS diff --git a/firmware/export/thread.h b/firmware/export/thread.h index 7fe128d..bd8f4ae 100644 --- a/firmware/export/thread.h +++ b/firmware/export/thread.h @@ -78,7 +78,7 @@ #define DEFAULT_STACK_SIZE 0x400 /* Bytes */ -#ifndef SIMULATOR +#if !defined(SIMULATOR) && !defined(__PCTOOL__) /* Need to keep structures inside the header file because debug_menu * needs them. */ #ifdef CPU_COLDFIRE @@ -122,7 +122,7 @@ struct regs void *s; /* Semaphore for blocking and wakeup */ void (*start)(void); /* Start function */ }; -#endif /* !SIMULATOR */ +#endif /* !SIMULATOR and __PCTOOL__ */ /* NOTE: The use of the word "queue" may also refer to a linked list of threads being maintained that are normally dealt with in FIFO order diff --git a/firmware/include/_ansi.h b/firmware/include/_ansi.h index 0002816..52c16e5 100644 --- a/firmware/include/_ansi.h +++ b/firmware/include/_ansi.h @@ -9,8 +9,8 @@ "comment out" the non-ANSI parts of the ANSI header files (non-ANSI header files aren't affected). */ -#ifndef _ANSIDECL_H_ -#define _ANSIDECL_H_ +#ifndef _ANSI_DECL_H_ +#define _ANSI_DECL_H_ /* First try to figure out whether we really are in an ANSI C environment. */ /* FIXME: This probably needs some work. Perhaps sys/config.h can be @@ -75,4 +75,4 @@ #define ATTRIBUTE_PRINTF(fmt, arg1) _ATTRIBUTE( ( format( printf, fmt, arg1 ) ) ) #define ATTRIBUTE_SCANF(fmt, arg1) _ATTRIBUTE( ( format( scanf, fmt, arg1 ) ) ) -#endif /* _ANSIDECL_H_ */ +#endif /* _ANSI_DECL_H_ */ diff --git a/firmware/include/dir_uncached.h b/firmware/include/dir_uncached.h index e198833..9c5302f 100644 --- a/firmware/include/dir_uncached.h +++ b/firmware/include/dir_uncached.h @@ -32,7 +32,7 @@ #define ATTR_ARCHIVE 0x20 #define ATTR_VOLUME 0x40 /* this is a volume, not a real directory */ -#ifdef SIMULATOR +#if defined(SIMULATOR) || defined(__PCTOOL__) #define dirent_uncached sim_dirent #define DIR_UNCACHED SIM_DIR #define opendir_uncached sim_opendir @@ -57,7 +57,7 @@ struct dirent_uncached { #include "fat.h" typedef struct { -#ifndef SIMULATOR +#if !defined(SIMULATOR) && !defined(__PCTOOL__) bool busy; long startcluster; struct fat_dir fatdir; diff --git a/firmware/include/file.h b/firmware/include/file.h index 9a9548f..f46f51c 100644 --- a/firmware/include/file.h +++ b/firmware/include/file.h @@ -48,7 +48,7 @@ #define O_TRUNC 0x10 #endif -#if defined(SIMULATOR) && !defined(PLUGIN) && !defined(CODEC) +#if (defined(SIMULATOR) && !defined(PLUGIN) && !defined(CODEC)) || defined(__PCTOOL__) #define open(x,y) sim_open(x,y) #define creat(x) sim_creat(x) #define remove(x) sim_remove(x) diff --git a/firmware/include/rbunicode.h b/firmware/include/rbunicode.h index 39fe253..6322816 100644 --- a/firmware/include/rbunicode.h +++ b/firmware/include/rbunicode.h @@ -35,7 +35,7 @@ #define MASK 0xC0 /* 11000000 */ #define COMP 0x80 /* 10x */ -#ifdef HAVE_LCD_BITMAP +#if defined(HAVE_LCD_BITMAP) || defined(__PCTOOL__) enum codepages { ISO_8859_1 = 0, ISO_8859_7, ISO_8859_8, WIN_1251, diff --git a/firmware/include/stdio.h b/firmware/include/stdio.h index 968bd59..6c315ef 100644 --- a/firmware/include/stdio.h +++ b/firmware/include/stdio.h @@ -45,4 +45,8 @@ int vfprintf(FILE *stream, const char *format, __VALIST ap); #endif #endif +#ifdef __PCTOOL__ +extern int printf(const char *format, __VALIST ap); +#endif + #endif /* _STDIO_H_ */ diff --git a/tools/database/Makefile b/tools/database/Makefile index 2c20bb7..65ed0c6 100644 --- a/tools/database/Makefile +++ b/tools/database/Makefile @@ -1,42 +1,144 @@ +# __________ __ ___. +# Open \______ \ ____ ____ | | _\_ |__ _______ ___ +# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +# \/ \/ \/ \/ \/ +# $Id$ +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# ifndef V -SILENT = @ +SILENT:=@ endif -INCLUDE = -I../../firmware/export \ - -I../../apps -I../../uisimulator/sdl -I/usr/include/SDL -FIRMINC = -I../../firmware/include -fno-builtin -DEFINES = -D__PCTOOL__ -DHAVE_TAGCACHE -DSIMULATOR -DCONFIG_CODEC=1 \ - -DROCKBOX_LITTLE_ENDIAN -DROCKBOX_DIR=\".rockbox\" -DROCKBOX_HAS_LOGF \ - -DCONFIG_CODEC=1 -CFLAGS = -g $(INCLUDE) $(DEFINES) -Wno-pointer-sign +CC:=gcc +MAKE:=make +RM:=rm +AR:=ar -SRC = database.o tagcache.o replaygain.o \ - metadata.o metadata_common.o mp3data.o \ - a52.o mp3.o adx.o mp4.o aiff.o mpc.o ape.o ogg.o \ - asap.o sid.o asf.o spc.o flac.o vorbis.o wave.o \ - mod.o wavpack.o monkeys.o \ - logf.o unicode.o ctype.o structec.o crc32.o io.o misc.o +ifneq "$(MAKECMDGOALS)" "clean" + VERSION:=$(shell ../../tools/version.sh ../../) + BUILDDATE:=$(shell date -u +'-DYEAR=%Y -DMONTH=%m -DDAY=%d') +endif + +GCC_VER := $(shell $(CC) -dumpversion | sed -e 's/\..*//') + +GCCOPTS := -O -W -Wall -fno-builtin +DEBUG := -g +DEFINES := -D__PCTOOL__ -DHAVE_TAGCACHE -DCONFIG_CODEC=1 -DROCKBOX_DIR=\".\" +INCLUDES := -I../../apps -I../../apps/metadata -I../../firmware/export +FIRMINC := -I../../firmware/include +LIBS := -lsdb + +EXTRA_DEFINES := -DROCKBOX_HAS_LOGF + +ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN) + ifneq "$(GCC_VER)" "4" + GCCOPTS += -mno-cygwin + endif +else + ifneq ($(findstring MINGW,$(shell uname)),MINGW) + LIBS += -ldl + endif +endif +ifeq "$(GCC_VER)" "4" + GCCOPTS += -Wno-pointer-sign +endif + +ifdef ROCKBOX_BUILD_ENDIAN + DEFINES += -D$(ROCKBOX_BUILD_ENDIAN) +else + # checked the endian of the build environment. + # It is necessary to install perl. + # Please execute make after exporting ROCKBOX_BUILD_ENDIAN=ROCKBOX_BIG_ENDIAN + # or ROCKBOX_BUILD_ENDIAN=ROCKBOX_LITTLE_ENDIAN when you make the database tool + # in the environment in which perl is not installed. + ENDIAN := $(shell perl -e 'unpack("I*", "\x12\x34\x56\x78")') + ifeq "$(ENDIAN)" "0x12345678" + DEFINES += -DROCKBOX_BIG_ENDIAN + else + DEFINES += -DROCKBOX_LITTLE_ENDIAN + endif +endif + +APP_CFLAGS := $(GCCOPTS) $(DEBUG) -DAPP_VERSION=\"$(VERSION)\" $(BUILDDATE) -I. -L. +SIM_CFLAGS := $(GCCOPTS) $(DEBUG) $(DEFINES) $(EXTRA_DEFINES) $(INCLUDES) +LIB_CFLAGS := $(GCCOPTS) $(DEBUG) $(DEFINES) $(EXTRA_DEFINES) $(INCLUDES) $(FIRMINC) -OBJ = $(SRC:.c=.o) +.PHONY: all clean +all: database -# source code search path -VPATH = ../../apps ../../apps/metadata ../../firmware/common ../../firmware/ \ - ../../uisimulator/common +APP_SRCS := database.c +SIM_SRCS := ../../uisimulator/common/io.c +LIB_SRCS := ../../firmware/common/crc32.c \ +../../firmware/common/ctype.c \ +../../firmware/common/errno.c \ +../../firmware/common/strcasestr.c \ +../../firmware/common/structec.c \ +../../firmware/common/unicode.c \ +../../apps/metadata.c \ +../../apps/misc.c \ +../../apps/mp3data.c \ +../../apps/replaygain.c \ +../../apps/tagcache.c -TARGET= database +# append metadata files +LIB_SRCS += $(wildcard ../../apps/metadata/*.c) + +ifneq "$(filter -DROCKBOX_HAS_LOGF,$(EXTRA_DEFINES))" "" + LIB_SRCS += ../../firmware/logf.c +endif + +APP_OBJS := $(patsubst %.c,%.o, $(notdir $(APP_SRCS))) +SIM_OBJS := $(patsubst %.c,%.o, $(notdir $(SIM_SRCS))) +LIB_OBJS := $(patsubst %.c,%.o, $(notdir $(LIB_SRCS))) + +DEPFILE = database.d + +$(DEPFILE): $(SRCS) + $(SILENT)(for each in $(APP_SRCS); do \ + obj=`echo $$each | sed -e 's/\.c/.o/' -e 's/^.*\///'`; \ + $(CC) -MG -MM -MT "$$obj" $(APP_CFLAGS) $$each 2>/dev/null; \ + done) >> $(DEPFILE) + $(SILENT)(for each in $(SIM_SRCS); do \ + obj=`echo $$each | sed -e 's/\.c/.o/' -e 's/^.*\///'`; \ + $(CC) -MG -MM -MT "$$obj" $(SIM_CFLAGS) $$each 2>/dev/null; \ + done) >> $(DEPFILE) + $(SILENT)(for each in $(LIB_SRCS); do \ + obj=`echo $$each | sed -e 's/\.c/.o/' -e 's/^.*\///'`; \ + $(CC) -MG -MM -MT "$$obj" $(LIB_CFLAGS) $$each 2>/dev/null; \ + done) >> $(DEPFILE) -all: $(TARGET) -%.o : ../../uisimulator/common/%.c +database: libsdb.a $(APP_OBJS) + @echo LD database + $(SILENT)$(CC) $(APP_CFLAGS) -o $@ $(APP_OBJS) $(LIBS) + +libsdb.a: $(SIM_OBJS) $(LIB_OBJS) + @echo AR libsdb.a + $(SILENT)$(AR) ruv $@ $+ > /dev/null 2>&1 + +$(APP_OBJS):%.o: $(shell grep %.c $(APP_SRCS)) @echo CC $( ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 Yoshihisa Uchida + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ #include -#include "tagcache.h" +#include +#include +#include "database.h" -int main(int argc, char **argv) +const char *sim_root_dir = NULL; +const char *sim_rockbox_dir = NULL; + +#define DEFAULT_ROCKBOX_DIRECTORY "/.rockbox" + +#define DB_MODE_CREATE_STR "create" +#define DB_MODE_UPDATE_STR "update" +#define DB_MODE_APPEND_STR "append" + +enum {DB_MODE_CREATE, DB_MODE_UPDATE, DB_MODE_APPEND}; + +enum {DB_ENDIAN_MASTER_FILE, DB_BIG_ENDIAN, DB_LITTLE_ENDIAN}; + +const unsigned char *usage_messages[] = { - tagcache_init(); - tagcache_build("."); - tagcache_reverse_scan(); - - return 0; -} + "Usage: database -r|--root-path -m|--mode \n", + " [-d|--rockbox-directory ] [-s|--song-directory ]\n", + " [-c|--codepage ]\n", + " [-b|--big-endian][-l|--little-endian]\n", + " [-h|--help][-V|--version]\n", + "\n", + "Options\n", + " -r|--root-path \n", + " Rockbox root path.\n", + " -m|--mode \n", + " create: build database newly.\n", + " update: update database.\n", + " append: append non registered files.\n", + " -d|--rockbox-directory \n", + " Rockbox directory.\n", + " -s|--song-directory \n", + " song storage directory.\n", + " -c|--codepage \n", + " metadata codepage\n", + " -b|--big-endian\n", + " the database build as big endian\n", + " -l|--little-endian\n", + " the database build as little endian\n", + " -h|--help\n", + " show this help message and exit.\n", + " -V|--version\n", + " show version information and exit.\n", + NULL, +}; -/* stub to avoid including all of apps/misc.c */ -bool file_exists(const char *file) +static void show_usage(void) { - if (!stat(file)) - return true; - return false; + int i; + + for (i = 0; usage_messages[i] != NULL; i++) + fprintf(stderr, usage_messages[i]); + return; } -/* stubs to avoid including thread-sdl.c */ -#include "kernel.h" -void mutex_init(struct mutex *m) +static void show_version(void) { - (void)m; -} + fprintf(stdout, "database tool version %s\n", APP_VERSION); + fprintf(stdout, "Copyright (C) 2009 The Rockbox Team., Yoshihisa Uchida\n"); + fprintf(stdout, "Released under the GNU General Public License v2+\n"); + return; +} -void mutex_lock(struct mutex *m) +static void show_errmsg(const char *msg) { - (void)m; -} + fprintf(stderr, "error: %s\n", msg); + return; +} -void mutex_unlock(struct mutex *m) +static int get_codepage(const char *cp) { - (void)m; -} + int code; + const char *name; -void thread_sdl_thread_lock(void *me) -{ - (void)me; -} + for (code = 0; ; code++) + { + name = get_codepage_name(code); + if (strcmp(name, "unknown") == 0) + break; + if (strcmp(cp, name) == 0) + return code; + } + + return -1; +} -void * thread_sdl_thread_unlock(void) +int main(int argc, char **argv) { - return (void*)1; -} - + int idx = 0; + int mode = -1; + char rootdir[MAX_PATH] = "\0"; + char rockboxdir[MAX_PATH] = DEFAULT_ROCKBOX_DIRECTORY; + char songdir[MAX_PATH] = "/"; + int cp = 0; /* ISO-8859-1 */ + int endian = DB_ENDIAN_MASTER_FILE; /* endian is decide by database_idx.tcd */ + + for (idx = 1; idx < argc; idx++) + { + if ((strcmp(argv[idx],"-h")==0) || (strcmp(argv[idx],"--help")==0)) + { + show_usage(); + return 0; + } + else if ((strcmp(argv[idx],"-V")==0) || (strcmp(argv[idx],"--version")==0)) + { + show_version(); + return 0; + } + else if ((strcmp(argv[idx],"-r")==0) || (strcmp(argv[idx],"--root-path")==0)) + { + if ((idx == argc-1) || (argv[idx+1][0] == '-')) + { + show_usage(); + return 1; + } + idx++; + + if (strlen(argv[idx]) >= MAX_PATH) + { + show_errmsg("root path is too long."); + return 1; + } + strcpy(rootdir, argv[idx]); + } + else if ((strcmp(argv[idx],"-d")==0) || (strcmp(argv[idx],"--rockbox-directory")==0)) + { + if ((idx == argc-1) || (argv[idx+1][0] == '-')) + { + show_usage(); + return 1; + } + idx++; + + if (strlen(argv[idx]) >= MAX_PATH) + { + show_errmsg("Rockbox directory is too long."); + return 1; + } + strcpy(rockboxdir, "/"); + strcat(rockboxdir, argv[idx]); + } + else if ((strcmp(argv[idx],"-s")==0) || (strcmp(argv[idx],"--song-directory")==0)) + { + if ((idx == argc-1) || (argv[idx+1][0] == '-')) + { + show_usage(); + return 1; + } + idx++; + + if (strlen(argv[idx]) >= MAX_PATH) + { + show_errmsg("song store directory is too long."); + return 1; + } + strcpy(songdir, argv[idx]); + } + else if ((strcmp(argv[idx],"-m")==0) || (strcmp(argv[idx],"--mode")==0)) + { + if (idx == argc-1) + { + show_usage(); + return 1; + } + idx++; + if (strcmp(argv[idx],DB_MODE_CREATE_STR)==0) + mode = DB_MODE_CREATE; + else if (strcmp(argv[idx],DB_MODE_UPDATE_STR)==0) + mode = DB_MODE_UPDATE; + else if (strcmp(argv[idx],DB_MODE_APPEND_STR)==0) + mode = DB_MODE_APPEND; + else + { + show_errmsg("--mode is invalid."); + return 1; + } + } + else if ((strcmp(argv[idx], "-c")==0) || (strcmp(argv[idx], "--codepage")==0)) + { + if (idx == argc-1) + { + show_usage(); + return 1; + } + idx++; + cp = get_codepage(argv[idx]); + if (cp < 0) + { + show_errmsg("codepage is invalid."); + return 1; + } + } + else if ((strcmp(argv[idx], "-b")==0) || (strcmp(argv[idx], "--big-endian")==0)) + { + endian = DB_BIG_ENDIAN; + } + else if ((strcmp(argv[idx], "-l")==0) || (strcmp(argv[idx], "--little-endian")==0)) + { + endian = DB_LITTLE_ENDIAN; + } + else + { + show_usage(); + return 1; + } + } + + if (rootdir[0] == '\0' || mode < 0) + { + show_usage(); + return 1; + } + + sim_root_dir = rootdir; + sim_rockbox_dir = rockboxdir; + + set_codepage(cp); + + tagcache_init(endian); + + if (mode == DB_MODE_CREATE) + { + tagcache_remove_database(); + tagcache_build(songdir); + } + else if (mode == DB_MODE_UPDATE) + { + tagcache_build(songdir); + tagcache_reverse_scan(); + } + else if (mode == DB_MODE_APPEND) + { + tagcache_build(songdir); + } + + return 0; +} diff --git a/uisimulator/common/io.c b/uisimulator/common/io.c index d87e331..375ef87 100644 --- a/uisimulator/common/io.c +++ b/uisimulator/common/io.c @@ -50,14 +50,16 @@ #define MAX_OPEN_FILES 11 #include +#ifndef __PCTOOL__ #include #include #include "thread.h" #include "kernel.h" +#include "thread-sdl.h" +#endif #include "debug.h" #include "config.h" #include "ata.h" /* for IF_MV2 et al. */ -#include "thread-sdl.h" /* Windows (and potentially other OSes) distinguish binary and text files. @@ -147,6 +149,12 @@ void dircache_rename(const char *oldname, const char *newname); #define SIMULATOR_DEFAULT_ROOT "simdisk" extern const char *sim_root_dir; +#ifdef __PCTOOL__ +#define PCTOOL_DEFAULT_ROOT "./" +#define PCTOOL_DEFAULT_ROCKBOX_DIR "/.rockbox" +extern const char *sim_rockbox_dir; +#endif + static int num_openfiles = 0; struct sim_dirent { @@ -201,7 +209,9 @@ enum struct sim_io { +#ifndef __PCTOOL__ struct mutex sim_mutex; /* Rockbox mutex */ +#endif int cmd; /* The command to perform */ int ready; /* I/O ready flag - 1= ready */ int fd; /* The file to read/write */ @@ -214,22 +224,29 @@ static struct sim_io io; int ata_init(void) { +#ifndef __PCTOOL__ /* Initialize the rockbox kernel objects on a rockbox thread */ mutex_init(&io.sim_mutex); +#endif io.accum = 0; return 1; } +#ifndef __PCTOOL__ int ata_spinup_time(void) { return HZ; } +#endif static ssize_t io_trigger_and_wait(int cmd) { +#ifndef __PCTOOL__ void *mythread = NULL; - ssize_t result; +#endif + ssize_t result = 0; +#ifndef __PCTOOL__ if (io.count > IO_YIELD_THRESHOLD || (io.accum += io.count) >= IO_YIELD_THRESHOLD) { @@ -237,6 +254,7 @@ static ssize_t io_trigger_and_wait(int cmd) io.accum = 0; mythread = thread_sdl_thread_unlock(); } +#endif switch (cmd) { @@ -247,21 +265,21 @@ static ssize_t io_trigger_and_wait(int cmd) result = write(io.fd, io.buf, io.count); break; } - +#ifndef __PCTOOL__ /* Regain our status as current */ if (mythread != NULL) { thread_sdl_thread_lock(mythread); } - +#endif return result; } -#ifndef __PCTOOL__ static const char *get_sim_pathname(const char *name) { static char buffer[MAX_PATH]; /* sufficiently big */ +#ifndef __PCTOOL__ if(name[0] == '/') { snprintf(buffer, sizeof(buffer), "%s%s", @@ -270,10 +288,22 @@ static const char *get_sim_pathname(const char *name) } fprintf(stderr, "WARNING, bad file name lacks slash: %s\n", name); return name; -} #else -#define get_sim_pathname(name) name + if(name[0] == '/') + { + snprintf(buffer, sizeof(buffer), "%s%s", + sim_root_dir != NULL ? sim_root_dir : PCTOOL_DEFAULT_ROOT, name); + } + else + { + snprintf(buffer, sizeof(buffer), "%s%s/%s", + sim_root_dir != NULL ? sim_root_dir : PCTOOL_DEFAULT_ROOT, + sim_rockbox_dir != NULL ? sim_rockbox_dir : PCTOOL_DEFAULT_ROCKBOX_DIR, + name); + } + return buffer; #endif +} MYDIR *sim_opendir(const char *name) { @@ -366,35 +396,35 @@ int sim_creat(const char *name) ssize_t sim_read(int fd, void *buf, size_t count) { ssize_t result; - +#ifndef __PCTOOL__ mutex_lock(&io.sim_mutex); - +#endif /* Setup parameters */ io.fd = fd; io.buf = buf; io.count = count; result = io_trigger_and_wait(IO_READ); - +#ifndef __PCTOOL__ mutex_unlock(&io.sim_mutex); - +#endif return result; } ssize_t sim_write(int fd, const void *buf, size_t count) { ssize_t result; - +#ifndef __PCTOOL__ mutex_lock(&io.sim_mutex); - +#endif io.fd = fd; io.buf = (void*)buf; io.count = count; result = io_trigger_and_wait(IO_WRITE); - +#ifndef __PCTOOL__ mutex_unlock(&io.sim_mutex); - +#endif return result; } diff --git a/tools/database/database.h b/tools/database/database.h new file mode 100644 index 0000000..e0550fb --- /dev/null +++ b/tools/database/database.h @@ -0,0 +1,40 @@ +/**************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 Yoshihisa Uchida + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include +#include + +/* implemented by firmware/common/unicode.c */ +extern const char* get_codepage_name(int cp); +extern void set_codepage(int cp); + +/* implemented by apps/tagcache.c */ +extern void tagcache_build(const char *path); +extern void tagcache_init(int endian); +extern void tagcache_remove_database(void); +extern void tagcache_reverse_scan(void); + +#ifndef MAX_PATH +#ifdef PATH_MAX /* for Cygwin without -mno-cygwin */ +#define MAX_PATH PATH_MAX +#else +#error MAX_PATH and PATH_MAX not defined +#endif +#endif diff --git a/tools/database/readme.txt b/tools/database/readme.txt new file mode 100644 index 0000000..a5a84c6 --- /dev/null +++ b/tools/database/readme.txt @@ -0,0 +1,152 @@ + __________ __ ___. + Open \______ \ ____ ____ | | _\_ |__ _______ ___ + Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + \/ \/ \/ \/ \/ +$Id$ + +Copyright (C) 2009 Yoshihisa Uchida + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + KIND, either express or implied. + +========================================================================== +database tool + Create the song database (database_*.tcd) application. + + +================================================= +Usage +================================================= +database -r|--root-path + -m|--mode + [-d|--rockbox-directory ] + [-s|--song-directory ] + [-c|--codepage ] + [-b|--big-endian] + [-l|--little-endian] + [-h|--help] + [-V|--version] + +-r|--root-path + set Rockbox root directory. + + When the database tool is used on Windows, the drive letter is written + Windows style (such as "C:/path/of/root"). + + Song database (database_*.tcd) are build for + / directory. + + When using database tool on MinGW+MSYS shell, it should be set not + /foo but //foo. + +-m|--mode + create: build database newly. + + update: Files not registered in the database are added to the database. + And deleted files are deleted from the database. + + append: Files not registered in the database are added to the database. + But deleted files are not deleted from the database. + +-d|--rockbox-directory + set Rockbox directory. + If this option is not given, then Rockbox directory is ".rockbox". + + //codepages/*.cp + should exist. + +-s|--song-directory + set song storage directory. + If begins with a "/", then it looks for the song file + from /. + If does not begin with a "/", then it looks for the song + file from //. + + If this option is not given, then = "/". + + When using database tool on MinGW+MSYS shell, it should be set not + /foo but //foo. + +-c|--codepage + set metadata codepage. + If this option is not given, then metadata codepage is "ISO-8859-1". + When the player is the codepage not supported, "ISO-8859-1" is selected. + + codepage list + option value codepage + ----------------------------------------------- + ISO-8859-1 Latin1 (ISO-8859-1) + ISO-8859-2 Latin Extended (ISO-8859-2) + ISO-8859-7 Greek (ISO-8859-7) + ISO-8859-8 Hebrew (ISO-8859-8) + ISO-8859-9 Turkish (ISO-8859-9) + ISO-8859-11 Thai (ISO-8859-11) + CP1250 Central European (CP1250) + CP1251 Cyrillic (CP1251) + CP1256 Arabic (CP1256) + SJIS Japanese (SJIS) + GB-2312 Simple Chinese (GB2312) + KSX-1001 Korean (KSX1001) + BIG-5 Traditional Chinese (BIG5) + UTF-8 Unicode (UTF-8) + +-b|--big-endian + The endian of the database is made as big endian. + +-l|--little-endian + The endian of the database is made as little endian. + + When neither -b nor -l are given, the endian of the database is + the same as database_idx.tcd. + If database_idx.tcd doesn't exist, it is the same endian as the + execution environment. + +-h|--help + show help message and exit. + +-V|--version + show version information and exit. + +================================================= +Requirement +================================================= +OS + 1) Windows + - Cygwin + When the database tool is built by using gcc 3.X.X on Cygwin, + to execute the songdb, cygwin1.dll is not needed. + But if it is built by using gcc 4.X.X, cygwin1.dll is needed. + + - MinGW + It is necessary to install msys. + + 2) Linux + + Other OS do not checked. + +When the database tool does not use the SDL library, then the SDL library +may not be installed. + +================================================= +Build +================================================= +1) edit Makefile (gcc options) +2) make + +When the build environment does not install perl, +please execute export ROCKBOX_BUILD_ENDIAN=ROCKBOX_BIG_ENDIAN or +export ROCKBOX_BUILD_ENDIAN=ROCKBOX_LITTLE_ENDIAN +after executing make. + +================================================= +TODO +================================================= +1) The folder of song database can be freely set. +2) Fix build warning.