From ec2737b2c24ac442d2b9fcf0f0222becb456d8ce Mon Sep 17 00:00:00 2001 From: Tom Ross Date: Sun, 18 Oct 2009 00:56:42 +0000 Subject: Change the .lng files to contain strings from multiple users. Still hard-coded to only output the core strings for now. Should be the majority of the core changes needed for translatable plugins. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23241 a1c6a512-1295-4272-9138-f99709370657 --- apps/filetree.c | 2 +- apps/lang/lang.make | 7 ++++- apps/language.c | 78 ++++++++++++++++++++++++++++++++--------------------- apps/language.h | 7 ++++- apps/main.c | 6 +++-- apps/settings.c | 2 +- 6 files changed, 66 insertions(+), 36 deletions(-) (limited to 'apps') diff --git a/apps/filetree.c b/apps/filetree.c index 8fbc39fa67..3468051b55 100644 --- a/apps/filetree.c +++ b/apps/filetree.c @@ -526,7 +526,7 @@ int ft_enter(struct tree_context* c) case FILE_ATTR_LNG: splash(0, ID2P(LANG_WAIT)); - if(!lang_load(buf)) { + if(!lang_core_load(buf)) { set_file(buf, (char *)global_settings.lang_file, MAX_FILENAME); talk_init(); /* use voice of same language */ diff --git a/apps/lang/lang.make b/apps/lang/lang.make index e32f084a29..f7366c9225 100644 --- a/apps/lang/lang.make +++ b/apps/lang/lang.make @@ -18,9 +18,14 @@ CLEANOBJS += $(BUILDDIR)/lang/max_language_size.h $(BUILDDIR)/lang/lang* # Therefore we create it here. #DUMMY := $(shell mkdir -p $(BUILDDIR)/apps/lang) +# Calculate the maximum language size. Currently based on the file size +# of the largest lng file. Subtract 10 due to HEADER_SIZE and +# SUBHEADER_SIZE. +# TODO: In the future generate this file within genlang or another script +# in order to only calculate the maximum size based on the core strings. $(BUILDDIR)/lang/max_language_size.h: $(LANGOBJ) $(call PRINTS,Create $(notdir $@)) - $(SILENT)echo "#define MAX_LANGUAGE_SIZE `ls -ln $(BUILDDIR)/apps/lang/* | awk '{print $$5}' | sort -n | tail -1`" > $@ + $(SILENT)echo "#define MAX_LANGUAGE_SIZE `ls -ln $(BUILDDIR)/apps/lang/* | awk '{print $$5-10}' | sort -n | tail -1`" > $@ $(BUILDDIR)/lang/lang_core.o: $(APPSDIR)/lang/$(LANGUAGE).lang $(BUILDDIR)/apps/features $(SILENT)for f in `cat $(BUILDDIR)/apps/features`; do feat="$$feat:$$f" ; done; \ diff --git a/apps/language.c b/apps/language.c index fe9ad5e97d..70549e194d 100644 --- a/apps/language.c +++ b/apps/language.c @@ -37,10 +37,11 @@ /* These defines must match the initial bytes in the binary lang file */ /* See tools/genlang (TODO: Use common include for both) */ #define LANGUAGE_COOKIE 0x1a -#define LANGUAGE_VERSION 0x05 +#define LANGUAGE_VERSION 0x06 #define LANGUAGE_FLAG_RTL 0x01 #define HEADER_SIZE 4 +#define SUBHEADER_SIZE 6 static unsigned char language_buffer[MAX_LANGUAGE_SIZE]; static unsigned char lang_options = 0; @@ -54,52 +55,62 @@ void lang_init(const unsigned char *builtin, unsigned char **dest, int count) } } -int lang_load(const char *filename) +int lang_load(const char *filename, const unsigned char *builtin, + unsigned char **dest, unsigned char *buffer, + unsigned int user_num, int max_lang_size, + unsigned int max_id) { - int fsize; + int lang_size; int fd = open(filename, O_RDONLY); int retcode=0; unsigned char lang_header[HEADER_SIZE]; + unsigned char sub_header[SUBHEADER_SIZE]; + unsigned int id, num_strings, foffset; + if(fd < 0) return 1; - fsize = filesize(fd) - HEADER_SIZE; - if(fsize <= MAX_LANGUAGE_SIZE) { - read(fd, lang_header, HEADER_SIZE); - if((lang_header[0] == LANGUAGE_COOKIE) && - (lang_header[1] == LANGUAGE_VERSION) && - (lang_header[2] == TARGET_ID)) { - read(fd, language_buffer, MAX_LANGUAGE_SIZE); - unsigned char *ptr = language_buffer; - int id; + read(fd, lang_header, HEADER_SIZE); + if((lang_header[0] == LANGUAGE_COOKIE) && + (lang_header[1] == LANGUAGE_VERSION) && + (lang_header[2] == TARGET_ID)) { + /* jump to the proper entry in the table of subheaders */ + lseek(fd, user_num * SUBHEADER_SIZE, SEEK_CUR); + read(fd, sub_header, SUBHEADER_SIZE); + /* read in information about the requested lang */ + num_strings = (sub_header[0]<<8) | sub_header[1]; + lang_size = (sub_header[2]<<8) | sub_header[3]; + foffset = (sub_header[4]<<8) | sub_header[5]; + if(lang_size <= max_lang_size) { /* initialize with builtin */ - lang_init(language_builtin, language_strings, - LANG_LAST_INDEX_IN_ARRAY); + lang_init(builtin, dest, num_strings); + lseek(fd, foffset, SEEK_SET); + read(fd, buffer, lang_size); - while(fsize>3) { - id = (ptr[0]<<8) | ptr[1]; /* get two-byte id */ - ptr+=2; /* pass the id */ - if(id < LANG_LAST_INDEX_IN_ARRAY) { + while(lang_size>3) { + id = ((buffer[0]<<8) | buffer[1]); /* get two-byte id */ + buffer += 2; /* pass the id */ + if(id < max_id) { #if 0 - DEBUGF("%2x New: %30s ", id, ptr); - DEBUGF("Replaces: %s\n", language_strings[id]); + DEBUGF("%2x New: %30s ", id, buffer); + DEBUGF("Replaces: %s\n", dest[id]); #endif - language_strings[id] = ptr; /* point to this string */ - } - while(*ptr) { /* pass the string */ - fsize--; - ptr++; + dest[id] = buffer; /* point to this string */ } - fsize-=3; /* the id and the terminating zero */ - ptr++; /* pass the terminating zero-byte */ + while(*buffer) { /* pass the string */ + lang_size--; + buffer++; + } + lang_size-=3; /* the id and the terminating zero */ + buffer++; /* pass the terminating zero-byte */ } } else { - DEBUGF("Illegal language file\n"); + DEBUGF("Language %s too large: %d\n", filename, lang_size); retcode = 2; } } else { - DEBUGF("Language %s too large: %d\n", filename, fsize); + DEBUGF("Illegal language file\n"); retcode = 3; } close(fd); @@ -107,10 +118,17 @@ int lang_load(const char *filename) return retcode; } +int lang_core_load(const char *filename) +{ + return lang_load(filename, core_language_builtin, language_strings, + language_buffer, 0, MAX_LANGUAGE_SIZE, + LANG_LAST_INDEX_IN_ARRAY); +} + int lang_english_to_id(const char *english) { int i; - unsigned char *ptr = (unsigned char *) language_builtin; + unsigned char *ptr = (unsigned char *) core_language_builtin; for (i = 0; i < LANG_LAST_INDEX_IN_ARRAY; i++) { if (!strcmp(ptr, english)) diff --git a/apps/language.h b/apps/language.h index 4cfe2b22ce..cbfa7e2c1d 100644 --- a/apps/language.h +++ b/apps/language.h @@ -25,7 +25,12 @@ void lang_init(const unsigned char *builtin, unsigned char **dest, int count); /* load a given language file */ -int lang_load(const char *filename); +int lang_core_load(const char *filename); + +int lang_load(const char *filename, const unsigned char *builtin, + unsigned char **dest, unsigned char *buffer, + unsigned int user_num, int max_lang_size, + unsigned int max_id); /* get the ID of an english string so it can be localised */ int lang_english_to_id(const char *english); diff --git a/apps/main.c b/apps/main.c index 3c93b4fea4..ec4829189b 100644 --- a/apps/main.c +++ b/apps/main.c @@ -308,7 +308,8 @@ static void init(void) button_init(); backlight_init(); sim_tasks_init(); - lang_init(language_builtin, language_strings, LANG_LAST_INDEX_IN_ARRAY); + lang_init(core_language_builtin, language_strings, + LANG_LAST_INDEX_IN_ARRAY); #ifdef DEBUG debug_init(); #endif @@ -399,7 +400,8 @@ static void init(void) font_init(); show_logo(); - lang_init(language_builtin, language_strings, LANG_LAST_INDEX_IN_ARRAY); + lang_init(core_language_builtin, language_strings, + LANG_LAST_INDEX_IN_ARRAY); #ifdef DEBUG debug_init(); diff --git a/apps/settings.c b/apps/settings.c index 2a5e31824f..6cbd559f94 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -900,7 +900,7 @@ void settings_apply(bool read_disk) if ( global_settings.lang_file[0]) { snprintf(buf, sizeof buf, LANG_DIR "/%s.lng", global_settings.lang_file); - lang_load(buf); + lang_core_load(buf); talk_init(); /* use voice of same language */ } -- cgit v1.2.3