[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: gettext patch (beta)
From: |
Carles Pina i Estany |
Subject: |
Re: gettext patch (beta) |
Date: |
Sat, 24 Jan 2009 16:09:33 +0100 |
User-agent: |
Mutt/1.5.18 (2008-05-17) |
Sorry, a new mistake has been removed
If someone wants to test:
a) msgfmt po/ca.po -o /usr/share/locale/ca/LC_MESSAGES/grub.mo
b) edit /boot/grub/grub.cfg and change lang=C by lang=ca
Thanks,
On Jan/24/2009, Carles Pina i Estany wrote:
>
> New version (same ChangeLog), fixing some warning messages, mistake in
> 00_header, etc.
>
> On Jan/21/2009, Carles Pina i Estany wrote:
> >
> > Hello,
> >
> > I have been working with the gettext patch (and Robert gave me a hand,
> > thanks)
> >
> > Take this version as a RFC and call for help (see at the bottom, it
> > includes beer invitation in Fosdem).
> >
> > ChangeLog:
> > -------------------
> > YYYY-MM-DD Carles Pina i Estany <address@hidden>
> >
> > * Makefile.in: Add uptrans target to help to update .pot file
> > * conf/common.rmk: Add grub-gettext_lib target, dependency and
> > SOURCES, CFLAGS, LDFLAGS
> > * kern/misc.c: Define grub_gettext symbol and add implement
> > grub_gettext_dummy function
> > * po/TODO: Temporary file with instructions of what Makefile.in
> > will do
> > * po/ca.po: Catalan translation stub
> > * include/grub/misc.h: Define macro _(char *s). Declare
> > grub_gettext_dummy and grub_gettext
> > * gettext/gettext.c: New file with gettext implementation
> > * normal/menu.c (print_message): add _( ) to some strings
> > * util/grub.d/10_linux.in: include grub-gettext_lib file.
> > For the Linux menuentry, call eval_gettext
> > * util/grub.d/00_header.in: add locale_prefix and gettext
> > locale detection and setting up the access to the mo directory
> > * util/grub-mkconfig_lib.in: add get_locale_lang
> > * util/grub-gettext_lib.in: new file
> > -------------------
> >
> > How to test and see something:
> > -Apply the patch
> >
> > -In po/ execute msgfmt ca.po -o ca.mo
> >
> > -Copy ca.mo to /usr/share/locale/ca/LC_MESSAGES/grub.mo
> >
> > -Compile and install the patched Grub
> >
> > -Maybe the new 00_header will detect your language and add the
> > configuration (this has not been tested)
> >
> > -In Grub2 console you should:
> > set lang=ca
> > set locale_prefix=/usr/share/locale
> > insmod gettext
> > (ESC)
> >
> > Then the lines under the menu box will appear in Catalan.
> >
> > The gettext module has a hook to the lang variable, if you change lang to
> > a new value, it will reload the file. Ops! And I didn't do any hook for
> > locale_prefix, I will do it but by the moment you can rmmod gettext
> > and insmod again
> >
> > CALL FOR HELP:
> > I need to write the Makefile.in (see po/TODO :-( ). I'm not used or
> > familiar to write Makefiles :-( if someone wants to help it would
> > speed up the process quite much. It needs only to merge the files with
> > the new .pot, compile (msgfmt), and install to the correct directory.
> >
> > I exactly know what has to do, so if someone knows about
> > installation/Makefiles and doesn't know about gettext it's not a
> > problem, contact me. Else I will try to implement soon.
> >
> > I would even invite to a couple of beers in Fosdem if someone does
> > this part :-)
> >
> > TODO:
> > -the Makefile.in
> > -and more testing about 00_header with gettext detection.
> > -Add _("") for mainly all strings (I would do in a separate patch)
> > -I have seen that Grub2 is not printing correctly the accents,
> > could be a problem in gettext or in some other layer
> >
> > --
> > Carles Pina i Estany GPG id: 0x17756391
> > http://pinux.info
>
> > Index: Makefile.in
> > ===================================================================
> > --- Makefile.in (revision 1952)
> > +++ Makefile.in (working copy)
> > @@ -170,6 +170,16 @@
> > endif
> > endif
> >
> > +#TODO: define on the header?
> > +SHELLSDIR = $(srcdir)/util/grub.d
> > +uptrans:
> > + #TODO: only one xgettext for everything
> > + xgettext -k_ -LC -o - `find "$(srcdir)/" -name '*.c'` -o po/grub.pot
> > +
> > + #TODO: in which variable we have all shell scripts?
> > + xgettext -k_ -Lshell -o - $(SHELLSDIR)/00_header.in
> > $(SHELLSDIR)/10_freebsd.in $(SHELLSDIR)/10_hurd.in $(SHELLSDIR)/10_linux.in
> > $(SHELLSDIR)/10_windows.in $(SHELLSDIR)/30_os-prober.in
> > $(SHELLSDIR)/40_custom.in -o po/grub.pot
> > +
> > +
> > # Used for building modules externally
> > pkglib_BUILDDIR += build_env.mk
> > build_env.mk: Makefile
> > Index: conf/common.rmk
> > ===================================================================
> > --- conf/common.rmk (revision 1952)
> > +++ conf/common.rmk (working copy)
> > @@ -142,6 +142,12 @@
> > lib_DATA += update-grub_lib
> > CLEANFILES += update-grub_lib
> >
> > +grub-gettext_lib: util/grub-gettext_lib.in config.status
> > + ./config.status --file=$@:$<
> > + chmod +x $@
> > +lib_DATA += grub-gettext_lib
> > +CLEANFILES += grub-gettext_lib
> > +
> > %: util/grub.d/%.in config.status
> > ./config.status --file=$@:$<
> > chmod +x $@
> > @@ -329,7 +335,7 @@
> > cmp.mod cat.mod help.mod search.mod
> > \
> > loopback.mod fs_uuid.mod configfile.mod echo.mod \
> > terminfo.mod test.mod blocklist.mod hexdump.mod \
> > - read.mod sleep.mod loadenv.mod crc.mod
> > + read.mod sleep.mod loadenv.mod crc.mod gettext.mod
> >
> > # For hello.mod.
> > hello_mod_SOURCES = hello/hello.c
> > @@ -492,3 +498,10 @@
> > bufio_mod_SOURCES = io/bufio.c
> > bufio_mod_CFLAGS = $(COMMON_CFLAGS)
> > bufio_mod_LDFLAGS = $(COMMON_LDFLAGS)
> > +
> > +# For gettext.mod.
> > +gettext_mod_SOURCES = gettext/gettext.c
> > +gettext_mod_CFLAGS = $(COMMON_CFLAGS)
> > +gettext_mod_LDFLAGS = $(COMMON_LDFLAGS)
> > +
> > +
> > Index: conf/common.mk
> > ===================================================================
> > --- conf/common.mk (revision 1952)
> > +++ conf/common.mk (working copy)
> > @@ -567,6 +567,12 @@
> > lib_DATA += update-grub_lib
> > CLEANFILES += update-grub_lib
> >
> > +grub-gettext_lib: util/grub-gettext_lib.in config.status
> > + ./config.status --file=$@:$<
> > + chmod +x $@
> > +lib_DATA += grub-gettext_lib
> > +CLEANFILES += grub-gettext_lib
> > +
> > %: util/grub.d/%.in config.status
> > ./config.status --file=$@:$<
> > chmod +x $@
> > @@ -2366,7 +2372,7 @@
> > cmp.mod cat.mod help.mod search.mod
> > \
> > loopback.mod fs_uuid.mod configfile.mod echo.mod \
> > terminfo.mod test.mod blocklist.mod hexdump.mod \
> > - read.mod sleep.mod loadenv.mod crc.mod
> > + read.mod sleep.mod loadenv.mod crc.mod gettext.mod
> >
> > # For hello.mod.
> > hello_mod_SOURCES = hello/hello.c
> > @@ -4236,3 +4242,62 @@
> >
> > bufio_mod_CFLAGS = $(COMMON_CFLAGS)
> > bufio_mod_LDFLAGS = $(COMMON_LDFLAGS)
> > +
> > +# For gettext.mod.
> > +gettext_mod_SOURCES = gettext/gettext.c
> > +CLEANFILES += gettext.mod mod-gettext.o mod-gettext.c pre-gettext.o
> > gettext_mod-gettext_gettext.o und-gettext.lst
> > +ifneq ($(gettext_mod_EXPORTS),no)
> > +CLEANFILES += def-gettext.lst
> > +DEFSYMFILES += def-gettext.lst
> > +endif
> > +MOSTLYCLEANFILES += gettext_mod-gettext_gettext.d
> > +UNDSYMFILES += und-gettext.lst
> > +
> > +gettext.mod: pre-gettext.o mod-gettext.o $(TARGET_OBJ2ELF)
> > + -rm -f $@
> > + $(TARGET_CC) $(gettext_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS)
> > -Wl,-r,-d -o $@ pre-gettext.o mod-gettext.o
> > + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f
> > $@; exit 1); fi
> > + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K
> > _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
> > +
> > +pre-gettext.o: $(gettext_mod_DEPENDENCIES) gettext_mod-gettext_gettext.o
> > + -rm -f $@
> > + $(TARGET_CC) $(gettext_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@
> > gettext_mod-gettext_gettext.o
> > +
> > +mod-gettext.o: mod-gettext.c
> > + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gettext_mod_CFLAGS)
> > -c -o $@ $<
> > +
> > +mod-gettext.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
> > + sh $(srcdir)/genmodsrc.sh 'gettext' $< > $@ || (rm -f $@; exit 1)
> > +
> > +ifneq ($(gettext_mod_EXPORTS),no)
> > +def-gettext.lst: pre-gettext.o
> > + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 gettext/' > $@
> > +endif
> > +
> > +und-gettext.lst: pre-gettext.o
> > + echo 'gettext' > $@
> > + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@
> > +
> > +gettext_mod-gettext_gettext.o: gettext/gettext.c
> > $(gettext/gettext.c_DEPENDENCIES)
> > + $(TARGET_CC) -Igettext -I$(srcdir)/gettext $(TARGET_CPPFLAGS)
> > $(TARGET_CFLAGS) $(gettext_mod_CFLAGS) -MD -c -o $@ $<
> > +-include gettext_mod-gettext_gettext.d
> > +
> > +CLEANFILES += cmd-gettext_mod-gettext_gettext.lst
> > fs-gettext_mod-gettext_gettext.lst partmap-gettext_mod-gettext_gettext.lst
> > +COMMANDFILES += cmd-gettext_mod-gettext_gettext.lst
> > +FSFILES += fs-gettext_mod-gettext_gettext.lst
> > +PARTMAPFILES += partmap-gettext_mod-gettext_gettext.lst
> > +
> > +cmd-gettext_mod-gettext_gettext.lst: gettext/gettext.c
> > $(gettext/gettext.c_DEPENDENCIES) gencmdlist.sh
> > + set -e; $(TARGET_CC) -Igettext -I$(srcdir)/gettext
> > $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gettext_mod_CFLAGS) -E $< | sh
> > $(srcdir)/gencmdlist.sh gettext > $@ || (rm -f $@; exit 1)
> > +
> > +fs-gettext_mod-gettext_gettext.lst: gettext/gettext.c
> > $(gettext/gettext.c_DEPENDENCIES) genfslist.sh
> > + set -e; $(TARGET_CC) -Igettext -I$(srcdir)/gettext
> > $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gettext_mod_CFLAGS) -E $< | sh
> > $(srcdir)/genfslist.sh gettext > $@ || (rm -f $@; exit 1)
> > +
> > +partmap-gettext_mod-gettext_gettext.lst: gettext/gettext.c
> > $(gettext/gettext.c_DEPENDENCIES) genpartmaplist.sh
> > + set -e; $(TARGET_CC) -Igettext -I$(srcdir)/gettext
> > $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gettext_mod_CFLAGS) -E $< | sh
> > $(srcdir)/genpartmaplist.sh gettext > $@ || (rm -f $@; exit 1)
> > +
> > +
> > +gettext_mod_CFLAGS = $(COMMON_CFLAGS)
> > +gettext_mod_LDFLAGS = $(COMMON_LDFLAGS)
> > +
> > +
> > Index: kern/misc.c
> > ===================================================================
> > --- kern/misc.c (revision 1952)
> > +++ kern/misc.c (working copy)
> > @@ -24,6 +24,8 @@
> > #include <grub/term.h>
> > #include <grub/env.h>
> >
> > +char* (*grub_gettext) (const char *s) = grub_gettext_dummy;
> > +
> > void *
> > grub_memmove (void *dest, const void *src, grub_size_t n)
> > {
> > @@ -1036,6 +1038,13 @@
> > return p - dest;
> > }
> >
> > +/* grub_gettext_dummy is not translating anything. */
> > +char *
> > +grub_gettext_dummy (const char *s)
> > +{
> > + return s;
> > +}
> > +
> > /* Abort GRUB. This function does not return. */
> > void
> > grub_abort (void)
> > Index: po/ca.po
> > ===================================================================
> > --- po/ca.po (revision 0)
> > +++ po/ca.po (revision 0)
> > @@ -0,0 +1,39 @@
> > +# SOME DESCRIPTIVE TITLE.
> > +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
> > +# This file is distributed under the same license as the PACKAGE package.
> > +# FIRST AUTHOR <address@hidden>, YEAR.
> > +#
> > +#, fuzzy
> > +msgid ""
> > +msgstr ""
> > +"Project-Id-Version: PACKAGE VERSION\n"
> > +"Report-Msgid-Bugs-To: \n"
> > +"POT-Creation-Date: 2009-01-21 21:14+0100\n"
> > +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
> > +"Last-Translator: FULL NAME <address@hidden>\n"
> > +"Language-Team: LANGUAGE <address@hidden>\n"
> > +"MIME-Version: 1.0\n"
> > +"Content-Type: text/plain; charset=CHARSET\n"
> > +"Content-Transfer-Encoding: 8bit\n"
> > +
> > +#: normal/menu.c:90
> > +#, c-format
> > +msgid ""
> > +"\n"
> > +" Use the %C and %C keys to select which entry is highlighted.\n"
> > +msgstr ""
> > +"\n"
> > +" Utilitzeu les tecles %C i %C per seleccionar l'entrada.\n"
> > +
> > +#: normal/menu.c:93
> > +msgid ""
> > +" Press enter to boot the selected OS, 'e' to edit the\n"
> > +" commands before booting or 'c' for a command-line."
> > +msgstr ""
> > +" Presioneu retorn per arrancar el SO seleccionat, 'e' editar\n"
> > +" les comandes abans d'arrancar, 'c' per línia d'ordres."
> > +
> > +#: util/grub.d/10_linux.in:148
> > +#, sh-format
> > +msgid "${OS}, linux ${version} (single-user mode)"
> > +msgstr "${OS}, linux ${version} (mode mono-usuari)"
> > Index: po/TODO
> > ===================================================================
> > --- po/TODO (revision 0)
> > +++ po/TODO (revision 0)
> > @@ -0,0 +1,5 @@
> > +Prepare a Makefile.in to:
> > +
> > +-Compile all .po to .mo (msgfmt $LANG.po -o $LANG.mo)
> > +-Copy to /usr/share/locale/$LANG/LC_MESSAGES/grub.mo (or
> > /usr/local/share/locale/$LANG/LC_MESSAGES/..., so $prefix...)
> > +-Check that grub-gettext_lib.in is correct
> > Index: include/grub/misc.h
> > ===================================================================
> > --- include/grub/misc.h (revision 1952)
> > +++ include/grub/misc.h (working copy)
> > @@ -31,6 +31,8 @@
> > /* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */
> > #define grub_memcpy(d,s,n) grub_memmove ((d), (s), (n))
> >
> > +#define _(s) grub_gettext(s)
> > +
> > void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t
> > n);
> > char *EXPORT_FUNC(grub_strcpy) (char *dest, const char *src);
> > char *EXPORT_FUNC(grub_strncpy) (char *dest, const char *src, int c);
> > @@ -84,6 +86,9 @@
> > grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
> > grub_uint32_t d, grub_uint32_t *r);
> >
> > +char *EXPORT_FUNC(grub_gettext_dummy) (const char *s);
> > +extern char *(*EXPORT_VAR(grub_gettext)) (const char *s);// =
> > grub_gettext_dummy;
> > +
> > #ifdef NEED_ENABLE_EXECUTE_STACK
> > void EXPORT_FUNC(__enable_execute_stack) (void *addr);
> > #endif
> > Index: gettext/gettext.c
> > ===================================================================
> > --- gettext/gettext.c (revision 0)
> > +++ gettext/gettext.c (revision 0)
> > @@ -0,0 +1,299 @@
> > +/* gettext.c - gettext module */
> > +/*
> > + * GRUB -- GRand Unified Bootloader
> > + * Copyright (C) 2009 Free Software Foundation, Inc.
> > + *
> > + * GRUB 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 3 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * GRUB is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > + * GNU General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> > + */
> > +
> > +#include <grub/types.h>
> > +#include <grub/misc.h>
> > +#include <grub/mm.h>
> > +#include <grub/err.h>
> > +#include <grub/dl.h>
> > +#include <grub/normal.h>
> > +#include <grub/file.h>
> > +#include <grub/kernel.h>
> > +
> > +/*
> > + .mo file information from:
> > + http://www.gnu.org/software/autoconf/manual/gettext/MO-Files.html .
> > +*/
> > +
> > +
> > +static grub_file_t grub_mofile_open (const char *name);
> > +static grub_file_t fd_mo;
> > +
> > +static int grub_gettext_offsetoriginal;
> > +static int grub_gettext_max;
> > +
> > +static char* (*grub_gettext_original) (const char *s);
> > +
> > +#define GETTEXT_MAGIC_NUMBER 0
> > +#define GETTEXT_FILE_FORMAT 4
> > +#define GETTEXT_NUMBER_OF_STRINGS 8
> > +#define GETTEXT_OFFSET_ORIGINAL 12
> > +#define GETTEXT_OFFSET_TRANSLATION 16
> > +
> > +static int
> > +grub_gettext_get_info (int offset)
> > +{
> > + int buf;
> > +
> > + grub_file_seek (fd_mo, offset);
> > + grub_file_read (fd_mo, (char*) &buf, 4);
> > + return buf;
> > +}
> > +
> > +static void
> > +grub_gettext_getstring_from_offset (int offset, int length, char
> > *translation)
> > +{
> > + grub_file_seek (fd_mo,offset);
> > + grub_file_read (fd_mo,translation,length);
> > + translation[length] = '\0';
> > +}
> > +
> > +static char*
> > +grub_gettext_gettranslation_number (int i)
> > +{
> > + int offsettranslation;
> > + int position;
> > + int length, offset;
> > + char *translation;
> > +
> > + offsettranslation = grub_gettext_get_info (GETTEXT_OFFSET_TRANSLATION);
> > +
> > + position=offsettranslation+i*8;
> > +
> > + grub_file_seek (fd_mo, position);
> > + grub_file_read (fd_mo, (char*) &length, 4);
> > +
> > + grub_file_seek (fd_mo, position + 4),
> > + grub_file_read (fd_mo, (char*) &offset, 4);
> > +
> > + translation = grub_malloc(length + 1);
> > + grub_gettext_getstring_from_offset (offset, length, translation);
> > +
> > + return translation;
> > +}
> > +
> > +static char*
> > +grub_gettext_getstring_num (int num)
> > +{
> > + int position;
> > + int length, offset;
> > + char *original;
> > +
> > + /* Get position for string i. */
> > + position = grub_gettext_offsetoriginal + (num * 8);
> > +
> > + /* Get the length of the string i. */
> > + grub_file_seek (fd_mo, position);
> > + grub_file_read (fd_mo, (char *) &length, 4);
> > +
> > + /* Get the offset of the string i. */
> > + grub_file_seek (fd_mo, position + 4);
> > + grub_file_read (fd_mo, (char *) &offset, 4);
> > +
> > + /* Get the string i. */
> > + original = grub_malloc (length + 1);
> > + grub_gettext_getstring_from_offset (offset, length, original);
> > +
> > + return original;
> > +}
> > +
> > +static char*
> > +grub_gettext_translate (char *orig)
> > +{
> > + char *current_string;
> > + char *ret;
> > +
> > + int min,max,current;
> > +
> > + if (fd_mo == 0)
> > + return orig;
> > +
> > + min = 0;
> > + max = grub_gettext_max;
> > +
> > + current = (max + min) / 2;
> > +
> > + while (current != min && current != max)
> > + {
> > + current_string = grub_gettext_getstring_num (current);
> > + /* grub_printf("Current: %s\n",current_string); */
> > +
> > + /* Search by bissection. */
> > + if (grub_strcmp (current_string, orig) < 0)
> > + {
> > + grub_free(current_string);
> > + min=current;
> > + }
> > + else if (grub_strcmp (current_string, orig) > 0)
> > + {
> > + grub_free(current_string);
> > + max=current;
> > + }
> > + else if (grub_strcmp (current_string, orig) == 0)
> > + {
> > + grub_free(current_string);
> > + return grub_gettext_gettranslation_number (current);
> > + }
> > + current = (max+min)/2;
> > + }
> > +
> > + ret = grub_malloc(grub_strlen(orig) + 1);
> > + grub_strcpy(ret,orig);
> > + return ret;
> > +}
> > +
> > +// XXX: Return a real grub_err_t or static void
> > +static grub_err_t
> > +grub_cmd_translate (struct grub_arg_list *state __attribute__ ((unused)),
> > + int argc __attribute__ ((unused)),
> > + char **args __attribute__ ((unused)))
> > +{
> > + if (argc != 1)
> > + return grub_error (GRUB_ERR_BAD_ARGUMENT, "text to translate
> > required");
> > +
> > + char *translation;
> > +
> > + translation = grub_gettext_translate(args[0]);
> > + grub_printf("%s\n",translation);
> > + //grub_printf("grub__: %d\n",grub__);
> > +
> > + return 0;
> > +}
> > +
> > +/* This is similar to grub_gzfile_open. */
> > +static grub_file_t
> > +grub_mofile_open (const char *filename)
> > +{
> > + int unsigned magic;
> > + int version;
> > +
> > + /* Using fd_mo and not another variable because
> > + it's needed for grub_gettext_get_info. */
> > +
> > + fd_mo = grub_file_open (filename);
> > + if (! fd_mo)
> > + {
> > + grub_error (GRUB_ERR_FILE_READ_ERROR, "Cannot read %s",filename);
> > + return 0;
> > + }
> > +
> > + magic = grub_gettext_get_info (GETTEXT_MAGIC_NUMBER);
> > +
> > + if (magic != 0x950412de)
> > + {
> > + grub_error (GRUB_ERR_BAD_FILE_TYPE, "mo: invalid mo file: %s",
> > filename);
> > + grub_file_close (fd_mo);
> > + fd_mo = 0;
> > + return 0;
> > + }
> > +
> > + version = grub_gettext_get_info (GETTEXT_FILE_FORMAT);
> > +
> > + if (version != 0)
> > + {
> > + grub_error (GRUB_ERR_BAD_FILE_TYPE, "mo: invalid mo version in file:
> > %s", filename);
> > + fd_mo = 0;
> > + return 0;
> > + }
> > +
> > + /*
> > + Do we want .mo.gz files? Then, the code:
> > + file = grub_gzio_open (io, 0); // 0: transparent
> > + if (! file)
> > + {
> > + grub_printf("Problems opening the file\n");
> > + grub_file_close (io);
> > + return 0;
> > + }
> > + */
> > +
> > + return fd_mo;
> > +}
> > +
> > +static void
> > +grub_gettext_init_ext (const char *lang)
> > +{
> > + char *mo_file;
> > + char *locale_prefix;
> > +
> > + locale_prefix = grub_env_get ("locale_prefix");
> > +
> > + fd_mo = 0;
> > +
> > + // mo_file e.g.: /usr/share/locale/ca/LC_MESSAGES/grub.mo
> > +
> > + mo_file = grub_malloc (grub_strlen (locale_prefix) + sizeof ("/") +
> > grub_strlen (lang) + sizeof ("/LC_MESSAGES/grub.mo"));
> > +
> > + if (! mo_file)
> > + return;
> > +
> > + grub_sprintf (mo_file, "%s/%s/LC_MESSAGES/grub.mo", locale_prefix, lang);
> > + /* XXX: lang is written by the user, need to sanitaze the input? */
> > +
> > + fd_mo = grub_mofile_open(mo_file);
> > + grub_free (mo_file);
> > +
> > + if (fd_mo)
> > + {
> > + grub_gettext_offsetoriginal =
> > grub_gettext_get_info(GETTEXT_OFFSET_ORIGINAL);
> > + grub_gettext_max = grub_gettext_get_info(GETTEXT_NUMBER_OF_STRINGS);
> > +
> > + grub_gettext_original = grub_gettext;
> > + grub_gettext = grub_gettext_translate;
> > + }
> > +}
> > +
> > +static char*
> > +grub_gettext_env_write_lang (struct grub_env_var *var __attribute__
> > ((unused)),
> > + const char *val)
> > +{
> > + grub_gettext_init_ext (val);
> > +
> > + return grub_strdup (val);
> > +}
> > +
> > +GRUB_MOD_INIT(gettext)
> > +{
> > + (void)mod; /* To stop warning. */
> > +
> > + const char *lang;
> > +
> > + lang = grub_env_get ("lang");
> > +
> > + grub_gettext_init_ext (lang);
> > +
> > + /* Testing:
> > + grub_register_command ("_", grub_cmd_translate, GRUB_COMMAND_FLAG_BOTH,
> > + "_", "internalization support trans", 0);
> > + */
> > +
> > + /* Reload .mo file information if lang changes. */
> > + grub_register_variable_hook ("lang", NULL, grub_gettext_env_write_lang);
> > +
> > + /* Preserve hooks after context changes. */
> > + grub_env_export ("lang");
> > +}
> > +
> > +GRUB_MOD_FINI(gettext)
> > +{
> > + if (fd_mo != 0)
> > + grub_file_close(fd_mo);
> > +
> > + grub_gettext = grub_gettext_original;
> > +}
> > Index: normal/menu.c
> > ===================================================================
> > --- normal/menu.c (revision 1952)
> > +++ normal/menu.c (working copy)
> > @@ -87,17 +87,16 @@
> > }
> > else
> > {
> > - grub_printf ("\n\
> > - Use the %C and %C keys to select which entry is highlighted.\n",
> > + grub_printf (_("\n\
> > + Use the %C and %C keys to select which entry is highlighted.\n"),
> > (grub_uint32_t) GRUB_TERM_DISP_UP, (grub_uint32_t)
> > GRUB_TERM_DISP_DOWN);
> > - grub_printf ("\
> > + grub_printf (_("\
> > Press enter to boot the selected OS, \'e\' to edit the\n\
> > - commands before booting or \'c\' for a command-line.");
> > + commands before booting or \'c\' for a command-line."));
> > if (nested)
> > grub_printf ("\n\
> > ESC to return previous menu.");
> > }
> > -
> > }
> >
> > static grub_menu_entry_t
> > @@ -317,7 +316,7 @@
> > They are required to clear the line. */
> > char *msg = " The highlighted entry will be booted automatically in
> > %ds. ";
> > char *msg_end = grub_strchr (msg, '%');
> > -
> > +
> > grub_gotoxy (second_stage ? (msg_end - msg) : 0, GRUB_TERM_HEIGHT - 3);
> > grub_printf (second_stage ? msg_end : msg, timeout);
> > grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset);
> > Index: util/grub.d/10_linux.in
> > ===================================================================
> > --- util/grub.d/10_linux.in (revision 1952)
> > +++ util/grub.d/10_linux.in (working copy)
> > @@ -20,6 +20,7 @@
> > address@hidden@
> > address@hidden@
> > . ${libdir}/grub/grub-mkconfig_lib
> > +. ${libdir}/grub/grub-gettext_lib
> >
> > if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
> > OS=GNU/Linux
> > @@ -139,7 +140,7 @@
> > EOF
> >
> > cat << EOF
> > -menuentry "${OS}, linux ${version} (single-user mode)" {
> > +menuentry "$(eval_gettext '${OS}, linux ${version} (single-user mode)')" {
> > EOF
> > prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/"
> > cat << EOF
> > Index: util/grub.d/00_header.in
> > ===================================================================
> > --- util/grub.d/00_header.in (revision 1952)
> > +++ util/grub.d/00_header.in (working copy)
> > @@ -22,6 +22,7 @@
> > address@hidden@
> > address@hidden@
> > grub_prefix=`echo /boot/grub | sed ${transform}`
> > +locale_prefix="/usr/share/locale" # TODO: dynamic with exec_prefix ?
> >
> > . ${libdir}/grub/grub-mkconfig_lib
> >
> > @@ -112,3 +113,17 @@
> > EOF
> > ;;
> > esac
> > +
> > +if test -e ${grub_prefix}/gettext.mod ; then
> > + # Make the locales accesible
> > + prepare_grub_to_access_device `${grub_probe} --target=device
> > ${locale_prefix}`
> > + lang=`get_locale_lang`
> > + cat << EOF
> > +if `make_system_path_relative_to_its_root ${locale_prefix}` ; then
> > + set locale_prefix=${locale_prefix}
> > + set lang=${lang}
> > + insmod gettext
> > +EOF
> > +else
> > + echo "gettext module is not available"
> > +fi
> > Index: util/grub-mkconfig_lib.in
> > ===================================================================
> > --- util/grub-mkconfig_lib.in (revision 1952)
> > +++ util/grub-mkconfig_lib.in (working copy)
> > @@ -176,3 +176,14 @@
> > fi
> > return 0
> > }
> > +
> > +get_locale_lang ()
> > +{
> > + lang="`echo ${LANG} | cut -d _ -f 1`"
> > + if [ "x${lang}" = "x" ] ; then
> > + return 1
> > + else
> > + echo "${lang}"
> > + return 0
> > + fi
> > +}
> > Index: util/grub-gettext_lib.in
> > ===================================================================
> > --- util/grub-gettext_lib.in (revision 0)
> > +++ util/grub-gettext_lib.in (revision 0)
> > @@ -0,0 +1,23 @@
> > +# Configuration of grub-gettext
> > +# Copyright (C) 2009 Free Software Foundation, Inc.
> > +#
> > +# GRUB 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 3 of the License, or
> > +# (at your option) any later version.
> > +#
> > +# GRUB is distributed in the hope that it will be useful,
> > +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > +# GNU General Public License for more details.
> > +#
> > +# You should have received a copy of the GNU General Public License
> > +# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> > +
> > address@hidden@
> > address@hidden@
> > address@hidden@
> > +
> > address@hidden@/share/locale
> > +TEXTDOMAIN=grub
> > +. gettext.sh
> >
> > Property changes on: util/grub-gettext_lib.in
> > ___________________________________________________________________
> > Added: svn:mergeinfo
> >
>
> > _______________________________________________
> > Grub-devel mailing list
> > address@hidden
> > http://lists.gnu.org/mailman/listinfo/grub-devel
>
> --
> Carles Pina i Estany GPG id: 0x17756391
> http://pinux.info
> Index: Makefile.in
> ===================================================================
> --- Makefile.in (revision 1954)
> +++ Makefile.in (working copy)
> @@ -112,6 +112,7 @@
> PKGDATA = $(pkgdata_DATA) $(pkgdata_SRCDIR)
> PROGRAMS = $(bin_UTILITIES) $(sbin_UTILITIES)
> SCRIPTS = $(bin_SCRIPTS) $(sbin_SCRIPTS) $(grub-mkconfig_SCRIPTS)
> +GRUBD = $(srcdir)/util/grub.d
>
> CLEANFILES =
> MOSTLYCLEANFILES =
> @@ -170,6 +171,11 @@
> endif
> endif
>
> +uptrans:
> + xgettext -k_ -LC -o - `find "$(srcdir)/" -name '*.c'` -o po/grub.pot
> + xgettext -k_ -Lshell -o - $(GRUBD)/* -j -o po/grub.pot
> +
> +
> # Used for building modules externally
> pkglib_BUILDDIR += build_env.mk
> build_env.mk: Makefile
> Index: conf/common.rmk
> ===================================================================
> --- conf/common.rmk (revision 1954)
> +++ conf/common.rmk (working copy)
> @@ -142,6 +142,12 @@
> lib_DATA += update-grub_lib
> CLEANFILES += update-grub_lib
>
> +grub-gettext_lib: util/grub-gettext_lib.in config.status
> + ./config.status --file=$@:$<
> + chmod +x $@
> +lib_DATA += grub-gettext_lib
> +CLEANFILES += grub-gettext_lib
> +
> %: util/grub.d/%.in config.status
> ./config.status --file=$@:$<
> chmod +x $@
> @@ -329,7 +335,7 @@
> cmp.mod cat.mod help.mod search.mod
> \
> loopback.mod fs_uuid.mod configfile.mod echo.mod \
> terminfo.mod test.mod blocklist.mod hexdump.mod \
> - read.mod sleep.mod loadenv.mod crc.mod
> + read.mod sleep.mod loadenv.mod crc.mod gettext.mod
>
> # For hello.mod.
> hello_mod_SOURCES = hello/hello.c
> @@ -492,3 +498,10 @@
> bufio_mod_SOURCES = io/bufio.c
> bufio_mod_CFLAGS = $(COMMON_CFLAGS)
> bufio_mod_LDFLAGS = $(COMMON_LDFLAGS)
> +
> +# For gettext.mod.
> +gettext_mod_SOURCES = gettext/gettext.c
> +gettext_mod_CFLAGS = $(COMMON_CFLAGS)
> +gettext_mod_LDFLAGS = $(COMMON_LDFLAGS)
> +
> +
> Index: conf/common.mk
> ===================================================================
> --- conf/common.mk (revision 1954)
> +++ conf/common.mk (working copy)
> @@ -567,6 +567,12 @@
> lib_DATA += update-grub_lib
> CLEANFILES += update-grub_lib
>
> +grub-gettext_lib: util/grub-gettext_lib.in config.status
> + ./config.status --file=$@:$<
> + chmod +x $@
> +lib_DATA += grub-gettext_lib
> +CLEANFILES += grub-gettext_lib
> +
> %: util/grub.d/%.in config.status
> ./config.status --file=$@:$<
> chmod +x $@
> @@ -2366,7 +2372,7 @@
> cmp.mod cat.mod help.mod search.mod
> \
> loopback.mod fs_uuid.mod configfile.mod echo.mod \
> terminfo.mod test.mod blocklist.mod hexdump.mod \
> - read.mod sleep.mod loadenv.mod crc.mod
> + read.mod sleep.mod loadenv.mod crc.mod gettext.mod
>
> # For hello.mod.
> hello_mod_SOURCES = hello/hello.c
> @@ -4236,3 +4242,62 @@
>
> bufio_mod_CFLAGS = $(COMMON_CFLAGS)
> bufio_mod_LDFLAGS = $(COMMON_LDFLAGS)
> +
> +# For gettext.mod.
> +gettext_mod_SOURCES = gettext/gettext.c
> +CLEANFILES += gettext.mod mod-gettext.o mod-gettext.c pre-gettext.o
> gettext_mod-gettext_gettext.o und-gettext.lst
> +ifneq ($(gettext_mod_EXPORTS),no)
> +CLEANFILES += def-gettext.lst
> +DEFSYMFILES += def-gettext.lst
> +endif
> +MOSTLYCLEANFILES += gettext_mod-gettext_gettext.d
> +UNDSYMFILES += und-gettext.lst
> +
> +gettext.mod: pre-gettext.o mod-gettext.o $(TARGET_OBJ2ELF)
> + -rm -f $@
> + $(TARGET_CC) $(gettext_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS)
> -Wl,-r,-d -o $@ pre-gettext.o mod-gettext.o
> + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f
> $@; exit 1); fi
> + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K
> _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
> +
> +pre-gettext.o: $(gettext_mod_DEPENDENCIES) gettext_mod-gettext_gettext.o
> + -rm -f $@
> + $(TARGET_CC) $(gettext_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@
> gettext_mod-gettext_gettext.o
> +
> +mod-gettext.o: mod-gettext.c
> + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gettext_mod_CFLAGS)
> -c -o $@ $<
> +
> +mod-gettext.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
> + sh $(srcdir)/genmodsrc.sh 'gettext' $< > $@ || (rm -f $@; exit 1)
> +
> +ifneq ($(gettext_mod_EXPORTS),no)
> +def-gettext.lst: pre-gettext.o
> + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 gettext/' > $@
> +endif
> +
> +und-gettext.lst: pre-gettext.o
> + echo 'gettext' > $@
> + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@
> +
> +gettext_mod-gettext_gettext.o: gettext/gettext.c
> $(gettext/gettext.c_DEPENDENCIES)
> + $(TARGET_CC) -Igettext -I$(srcdir)/gettext $(TARGET_CPPFLAGS)
> $(TARGET_CFLAGS) $(gettext_mod_CFLAGS) -MD -c -o $@ $<
> +-include gettext_mod-gettext_gettext.d
> +
> +CLEANFILES += cmd-gettext_mod-gettext_gettext.lst
> fs-gettext_mod-gettext_gettext.lst partmap-gettext_mod-gettext_gettext.lst
> +COMMANDFILES += cmd-gettext_mod-gettext_gettext.lst
> +FSFILES += fs-gettext_mod-gettext_gettext.lst
> +PARTMAPFILES += partmap-gettext_mod-gettext_gettext.lst
> +
> +cmd-gettext_mod-gettext_gettext.lst: gettext/gettext.c
> $(gettext/gettext.c_DEPENDENCIES) gencmdlist.sh
> + set -e; $(TARGET_CC) -Igettext -I$(srcdir)/gettext
> $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gettext_mod_CFLAGS) -E $< | sh
> $(srcdir)/gencmdlist.sh gettext > $@ || (rm -f $@; exit 1)
> +
> +fs-gettext_mod-gettext_gettext.lst: gettext/gettext.c
> $(gettext/gettext.c_DEPENDENCIES) genfslist.sh
> + set -e; $(TARGET_CC) -Igettext -I$(srcdir)/gettext
> $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gettext_mod_CFLAGS) -E $< | sh
> $(srcdir)/genfslist.sh gettext > $@ || (rm -f $@; exit 1)
> +
> +partmap-gettext_mod-gettext_gettext.lst: gettext/gettext.c
> $(gettext/gettext.c_DEPENDENCIES) genpartmaplist.sh
> + set -e; $(TARGET_CC) -Igettext -I$(srcdir)/gettext
> $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gettext_mod_CFLAGS) -E $< | sh
> $(srcdir)/genpartmaplist.sh gettext > $@ || (rm -f $@; exit 1)
> +
> +
> +gettext_mod_CFLAGS = $(COMMON_CFLAGS)
> +gettext_mod_LDFLAGS = $(COMMON_LDFLAGS)
> +
> +
> Index: kern/misc.c
> ===================================================================
> --- kern/misc.c (revision 1954)
> +++ kern/misc.c (working copy)
> @@ -24,6 +24,8 @@
> #include <grub/term.h>
> #include <grub/env.h>
>
> +const char* (*grub_gettext) (const char *s) = grub_gettext_dummy;
> +
> void *
> grub_memmove (void *dest, const void *src, grub_size_t n)
> {
> @@ -1044,6 +1046,13 @@
> return p - dest;
> }
>
> +/* grub_gettext_dummy is not translating anything. */
> +const char *
> +grub_gettext_dummy (const char *s)
> +{
> + return s;
> +}
> +
> /* Abort GRUB. This function does not return. */
> void
> grub_abort (void)
> Index: po/ca.po
> ===================================================================
> --- po/ca.po (revision 0)
> +++ po/ca.po (revision 0)
> @@ -0,0 +1,39 @@
> +# SOME DESCRIPTIVE TITLE.
> +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
> +# This file is distributed under the same license as the PACKAGE package.
> +# FIRST AUTHOR <address@hidden>, YEAR.
> +#
> +#, fuzzy
> +msgid ""
> +msgstr ""
> +"Project-Id-Version: PACKAGE VERSION\n"
> +"Report-Msgid-Bugs-To: \n"
> +"POT-Creation-Date: 2009-01-21 21:14+0100\n"
> +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
> +"Last-Translator: FULL NAME <address@hidden>\n"
> +"Language-Team: LANGUAGE <address@hidden>\n"
> +"MIME-Version: 1.0\n"
> +"Content-Type: text/plain; charset=CHARSET\n"
> +"Content-Transfer-Encoding: 8bit\n"
> +
> +#: normal/menu.c:90
> +#, c-format
> +msgid ""
> +"\n"
> +" Use the %C and %C keys to select which entry is highlighted.\n"
> +msgstr ""
> +"\n"
> +" Utilitzeu les tecles %C i %C per seleccionar l'entrada.\n"
> +
> +#: normal/menu.c:93
> +msgid ""
> +" Press enter to boot the selected OS, 'e' to edit the\n"
> +" commands before booting or 'c' for a command-line."
> +msgstr ""
> +" Presioneu retorn per arrancar el SO seleccionat, 'e' editar\n"
> +" les comandes abans d'arrancar, 'c' per línia d'ordres."
> +
> +#: util/grub.d/10_linux.in:148
> +#, sh-format
> +msgid "${OS}, linux ${version} (single-user mode)"
> +msgstr "${OS}, linux ${version} (mode mono-usuari)"
> Index: po/TODO
> ===================================================================
> --- po/TODO (revision 0)
> +++ po/TODO (revision 0)
> @@ -0,0 +1,5 @@
> +Prepare a Makefile.in to:
> +
> +-Compile all .po to .mo (msgfmt $LANG.po -o $LANG.mo)
> +-Copy to /usr/share/locale/$LANG/LC_MESSAGES/grub.mo (or
> /usr/local/share/locale/$LANG/LC_MESSAGES/..., so $prefix...)
> +-Check that grub-gettext_lib.in is correct
> Index: include/grub/misc.h
> ===================================================================
> --- include/grub/misc.h (revision 1954)
> +++ include/grub/misc.h (working copy)
> @@ -31,6 +31,8 @@
> /* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */
> #define grub_memcpy(d,s,n) grub_memmove ((d), (s), (n))
>
> +#define _(s) grub_gettext(s)
> +
> void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n);
> char *EXPORT_FUNC(grub_strcpy) (char *dest, const char *src);
> char *EXPORT_FUNC(grub_strncpy) (char *dest, const char *src, int c);
> @@ -84,6 +86,9 @@
> grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
> grub_uint32_t d, grub_uint32_t *r);
>
> +const char *EXPORT_FUNC(grub_gettext_dummy) (const char *s);
> +extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s);// =
> grub_gettext_dummy;
> +
> #ifdef NEED_ENABLE_EXECUTE_STACK
> void EXPORT_FUNC(__enable_execute_stack) (void *addr);
> #endif
> Index: gettext/gettext.c
> ===================================================================
> --- gettext/gettext.c (revision 0)
> +++ gettext/gettext.c (revision 0)
> @@ -0,0 +1,300 @@
> +/* gettext.c - gettext module */
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2009 Free Software Foundation, Inc.
> + *
> + * GRUB 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 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <grub/types.h>
> +#include <grub/misc.h>
> +#include <grub/mm.h>
> +#include <grub/err.h>
> +#include <grub/dl.h>
> +#include <grub/normal.h>
> +#include <grub/file.h>
> +#include <grub/kernel.h>
> +
> +/*
> + .mo file information from:
> + http://www.gnu.org/software/autoconf/manual/gettext/MO-Files.html .
> +*/
> +
> +
> +static grub_file_t grub_mofile_open (const char *name);
> +static grub_file_t fd_mo;
> +
> +static int grub_gettext_offsetoriginal;
> +static int grub_gettext_max;
> +
> +static const char* (*grub_gettext_original) (const char *s);
> +
> +#define GETTEXT_MAGIC_NUMBER 0
> +#define GETTEXT_FILE_FORMAT 4
> +#define GETTEXT_NUMBER_OF_STRINGS 8
> +#define GETTEXT_OFFSET_ORIGINAL 12
> +#define GETTEXT_OFFSET_TRANSLATION 16
> +
> +static int
> +grub_gettext_get_info (int offset)
> +{
> + int buf;
> +
> + grub_file_seek (fd_mo, offset);
> + grub_file_read (fd_mo, (char*) &buf, 4);
> + return buf;
> +}
> +
> +static void
> +grub_gettext_getstring_from_offset (int offset, int length, char
> *translation)
> +{
> + grub_file_seek (fd_mo,offset);
> + grub_file_read (fd_mo,translation,length);
> + translation[length] = '\0';
> +}
> +
> +static char*
> +grub_gettext_gettranslation_number (int i)
> +{
> + int offsettranslation;
> + int position;
> + int length, offset;
> + char *translation;
> +
> + offsettranslation = grub_gettext_get_info (GETTEXT_OFFSET_TRANSLATION);
> +
> + position=offsettranslation+i*8;
> +
> + grub_file_seek (fd_mo, position);
> + grub_file_read (fd_mo, (char*) &length, 4);
> +
> + grub_file_seek (fd_mo, position + 4),
> + grub_file_read (fd_mo, (char*) &offset, 4);
> +
> + translation = grub_malloc(length + 1);
> + grub_gettext_getstring_from_offset (offset, length, translation);
> +
> + return translation;
> +}
> +
> +static char*
> +grub_gettext_getstring_num (int num)
> +{
> + int position;
> + int length, offset;
> + char *original;
> +
> + /* Get position for string i. */
> + position = grub_gettext_offsetoriginal + (num * 8);
> +
> + /* Get the length of the string i. */
> + grub_file_seek (fd_mo, position);
> + grub_file_read (fd_mo, (char *) &length, 4);
> +
> + /* Get the offset of the string i. */
> + grub_file_seek (fd_mo, position + 4);
> + grub_file_read (fd_mo, (char *) &offset, 4);
> +
> + /* Get the string i. */
> + original = grub_malloc (length + 1);
> + grub_gettext_getstring_from_offset (offset, length, original);
> +
> + return original;
> +}
> +
> +static const char*
> +grub_gettext_translate (const char *orig)
> +{
> + char *current_string;
> + char *ret;
> +
> + int min,max,current;
> +
> + if (fd_mo == 0)
> + return orig;
> +
> + min = 0;
> + max = grub_gettext_max;
> +
> + current = (max + min) / 2;
> +
> + while (current != min && current != max)
> + {
> + current_string = grub_gettext_getstring_num (current);
> + /* grub_printf("Current: %s\n",current_string); */
> +
> + /* Search by bissection. */
> + if (grub_strcmp (current_string, orig) < 0)
> + {
> + grub_free(current_string);
> + min=current;
> + }
> + else if (grub_strcmp (current_string, orig) > 0)
> + {
> + grub_free(current_string);
> + max=current;
> + }
> + else if (grub_strcmp (current_string, orig) == 0)
> + {
> + grub_free(current_string);
> + return grub_gettext_gettranslation_number (current);
> + }
> + current = (max+min)/2;
> + }
> +
> + ret = grub_malloc(grub_strlen(orig) + 1);
> + grub_strcpy(ret,orig);
> + return ret;
> +}
> +
> +// XXX: Return a real grub_err_t or static void
> +/*static grub_err_t
> +grub_cmd_translate (struct grub_arg_list *state __attribute__ ((unused)),
> + int argc __attribute__ ((unused)),
> + char **args __attribute__ ((unused)))
> +{
> + if (argc != 1)
> + return grub_error (GRUB_ERR_BAD_ARGUMENT, "text to translate required");
> +
> + char *translation;
> +
> + translation = grub_gettext_translate(args[0]);
> + grub_printf("%s\n",translation);
> + //grub_printf("grub__: %d\n",grub__);
> +
> + return 0;
> +}
> +*/
> +
> +/* This is similar to grub_gzfile_open. */
> +static grub_file_t
> +grub_mofile_open (const char *filename)
> +{
> + int unsigned magic;
> + int version;
> +
> + /* Using fd_mo and not another variable because
> + it's needed for grub_gettext_get_info. */
> +
> + fd_mo = grub_file_open (filename);
> + if (! fd_mo)
> + {
> + grub_error (GRUB_ERR_FILE_READ_ERROR, "Cannot read %s",filename);
> + return 0;
> + }
> +
> + magic = grub_gettext_get_info (GETTEXT_MAGIC_NUMBER);
> +
> + if (magic != 0x950412de)
> + {
> + grub_error (GRUB_ERR_BAD_FILE_TYPE, "mo: invalid mo file: %s",
> filename);
> + grub_file_close (fd_mo);
> + fd_mo = 0;
> + return 0;
> + }
> +
> + version = grub_gettext_get_info (GETTEXT_FILE_FORMAT);
> +
> + if (version != 0)
> + {
> + grub_error (GRUB_ERR_BAD_FILE_TYPE, "mo: invalid mo version in file:
> %s", filename);
> + fd_mo = 0;
> + return 0;
> + }
> +
> + /*
> + Do we want .mo.gz files? Then, the code:
> + file = grub_gzio_open (io, 0); // 0: transparent
> + if (! file)
> + {
> + grub_printf("Problems opening the file\n");
> + grub_file_close (io);
> + return 0;
> + }
> + */
> +
> + return fd_mo;
> +}
> +
> +static void
> +grub_gettext_init_ext (const char *lang)
> +{
> + char *mo_file;
> + char *locale_prefix;
> +
> + locale_prefix = grub_env_get ("locale_prefix");
> +
> + fd_mo = 0;
> +
> + // mo_file e.g.: /usr/share/locale/ca/LC_MESSAGES/grub.mo
> +
> + mo_file = grub_malloc (grub_strlen (locale_prefix) + sizeof ("/") +
> grub_strlen (lang) + sizeof ("/LC_MESSAGES/grub.mo"));
> +
> + if (! mo_file)
> + return;
> +
> + grub_sprintf (mo_file, "%s/%s/LC_MESSAGES/grub.mo", locale_prefix, lang);
> + /* XXX: lang is written by the user, need to sanitaze the input? */
> +
> + fd_mo = grub_mofile_open(mo_file);
> + grub_free (mo_file);
> +
> + if (fd_mo)
> + {
> + grub_gettext_offsetoriginal =
> grub_gettext_get_info(GETTEXT_OFFSET_ORIGINAL);
> + grub_gettext_max = grub_gettext_get_info(GETTEXT_NUMBER_OF_STRINGS);
> +
> + grub_gettext_original = grub_gettext;
> + grub_gettext = grub_gettext_translate;
> + }
> +}
> +
> +static char*
> +grub_gettext_env_write_lang (struct grub_env_var *var __attribute__
> ((unused)),
> + const char *val)
> +{
> + grub_gettext_init_ext (val);
> +
> + return grub_strdup (val);
> +}
> +
> +GRUB_MOD_INIT(gettext)
> +{
> + (void)mod; /* To stop warning. */
> +
> + const char *lang;
> +
> + lang = grub_env_get ("lang");
> +
> + grub_gettext_init_ext (lang);
> +
> + /* Testing:
> + grub_register_command ("_", grub_cmd_translate, GRUB_COMMAND_FLAG_BOTH,
> + "_", "internalization support trans", 0);
> + */
> +
> + /* Reload .mo file information if lang changes. */
> + grub_register_variable_hook ("lang", NULL, grub_gettext_env_write_lang);
> +
> + /* Preserve hooks after context changes. */
> + grub_env_export ("lang");
> +}
> +
> +GRUB_MOD_FINI(gettext)
> +{
> + if (fd_mo != 0)
> + grub_file_close(fd_mo);
> +
> + grub_gettext = grub_gettext_original;
> +}
> Index: normal/menu.c
> ===================================================================
> --- normal/menu.c (revision 1954)
> +++ normal/menu.c (working copy)
> @@ -87,12 +87,12 @@
> }
> else
> {
> - grub_printf ("\n\
> - Use the %C and %C keys to select which entry is highlighted.\n",
> + grub_printf (_("\n\
> + Use the %C and %C keys to select which entry is highlighted.\n"),
> (grub_uint32_t) GRUB_TERM_DISP_UP, (grub_uint32_t)
> GRUB_TERM_DISP_DOWN);
> - grub_printf ("\
> + grub_printf (_("\
> Press enter to boot the selected OS, \'e\' to edit the\n\
> - commands before booting or \'c\' for a command-line.");
> + commands before booting or \'c\' for a command-line."));
> if (nested)
> grub_printf ("\n\
> ESC to return previous menu.");
> Index: util/grub.d/10_linux.in
> ===================================================================
> --- util/grub.d/10_linux.in (revision 1954)
> +++ util/grub.d/10_linux.in (working copy)
> @@ -20,6 +20,7 @@
> address@hidden@
> address@hidden@
> . ${libdir}/grub/grub-mkconfig_lib
> +. ${libdir}/grub/grub-gettext_lib
>
> if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
> OS=GNU/Linux
> @@ -139,7 +140,7 @@
> EOF
>
> cat << EOF
> -menuentry "${OS}, linux ${version} (single-user mode)" {
> +menuentry "$(eval_gettext '${OS}, linux ${version} (single-user mode)')" {
> EOF
> prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/"
> cat << EOF
> Index: util/grub.d/00_header.in
> ===================================================================
> --- util/grub.d/00_header.in (revision 1954)
> +++ util/grub.d/00_header.in (working copy)
> @@ -22,6 +22,7 @@
> address@hidden@
> address@hidden@
> grub_prefix=`echo /boot/grub | sed ${transform}`
> +locale_prefix="/usr/share/locale" # TODO: dynamic with exec_prefix ?
>
> . ${libdir}/grub/grub-mkconfig_lib
>
> @@ -112,3 +113,18 @@
> EOF
> ;;
> esac
> +
> +if test -e ${grub_prefix}/gettext.mod ; then
> + # Make the locales accesible
> + prepare_grub_to_access_device `${grub_probe} --target=device
> ${locale_prefix}`
> + lang=`get_locale_lang`
> + cat << EOF
> +if `make_system_path_relative_to_its_root ${locale_prefix}` ; then
> + set locale_prefix=${locale_prefix}
> + set lang=${lang}
> + insmod gettext
> +fi
> +EOF
> +else
> + echo "gettext module is not available"
> +fi
> Index: util/grub-mkconfig_lib.in
> ===================================================================
> --- util/grub-mkconfig_lib.in (revision 1954)
> +++ util/grub-mkconfig_lib.in (working copy)
> @@ -176,3 +176,14 @@
> fi
> return 0
> }
> +
> +get_locale_lang ()
> +{
> + lang="`echo ${LANG} | cut -d _ -f 1`"
> + if [ "x${lang}" = "x" ] ; then
> + return 1
> + else
> + echo "${lang}"
> + return 0
> + fi
> +}
> Index: util/grub-gettext_lib.in
> ===================================================================
> --- util/grub-gettext_lib.in (revision 0)
> +++ util/grub-gettext_lib.in (revision 0)
> @@ -0,0 +1,23 @@
> +# Configuration of grub-gettext
> +# Copyright (C) 2009 Free Software Foundation, Inc.
> +#
> +# GRUB 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 3 of the License, or
> +# (at your option) any later version.
> +#
> +# GRUB is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> +
> address@hidden@
> address@hidden@
> address@hidden@
> +
> address@hidden@/share/locale
> +TEXTDOMAIN=grub
> +. gettext.sh
>
> Property changes on: util/grub-gettext_lib.in
> ___________________________________________________________________
> Added: svn:mergeinfo
>
> _______________________________________________
> Grub-devel mailing list
> address@hidden
> http://lists.gnu.org/mailman/listinfo/grub-devel
--
Carles Pina i Estany GPG id: 0x17756391
http://pinux.info
Re: gettext patch (beta), Carles Pina i Estany, 2009/01/24
- Re: gettext patch (beta),
Carles Pina i Estany <=