=== added file 'ChangeLog.gettext'
--- ChangeLog.gettext 1970-01-01 00:00:00 +0000
+++ ChangeLog.gettext 2009-11-22 12:40:27 +0000
@@ -0,0 +1,18 @@
+YYYY-MM-DD Carles Pina i Estany
+
+ * conf/common.rmk: Add grub-gettext_lib target and updates
+ lib_DATA and CLEANFILES. Adds gettext.mod SOURCES, CFLAGS,
+ LDFLAGS.
+ * gettext/gettext.c: New file. (Reads mo files).
+ * include/grub/file.h (grub_file_pread): New prototype.
+ * include/grub/i18n.h (_): New prototype.
+ * include/grub/misc.h (grub_gettext_dummy, grub_gettext): New
+ prototypes.
+ * kern/misc.c (grub_gettext_dummy): New function.
+ * menu/menu_text.c: Include .
+ * menu/menu_text.c (print_timeout): Gettexttize string.
+ * menu/menu_text.c (print_message): Gettexttize string.
+ * po/POTFILES: Add `normal/menu_text.c'.
+ * po/ca.po: Add new translations.
+ * util/grub.d/00_header.in: Define locale_dir and lang. insmod
+ gettext module and defines locale_dir and lang in grub.cfg.
=== modified file 'conf/common.rmk'
--- conf/common.rmk 2009-11-18 23:05:59 +0000
+++ conf/common.rmk 2009-11-22 12:02:01 +0000
@@ -163,6 +163,12 @@
lib_SCRIPTS += 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 $@
@@ -610,6 +616,12 @@
bufio_mod_CFLAGS = $(COMMON_CFLAGS)
bufio_mod_LDFLAGS = $(COMMON_LDFLAGS)
+# For gettext.mod.
+pkglib_MODULES += gettext.mod
+gettext_mod_SOURCES = gettext/gettext.c
+gettext_mod_CFLAGS = $(COMMON_CFLAGS)
+gettext_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
# Misc.
pkglib_MODULES += xnu_uuid.mod
=== added directory 'gettext'
=== added file 'gettext/gettext.c'
--- gettext/gettext.c 1970-01-01 00:00:00 +0000
+++ gettext/gettext.c 2009-11-22 16:56:18 +0000
@@ -0,0 +1,293 @@
+/* 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 .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*
+ .mo file information from:
+ http://www.gnu.org/software/autoconf/manual/gettext/MO-Files.html .
+*/
+
+
+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
+
+#define MO_MAGIC_NUMBER 0x950412de
+
+static grub_ssize_t
+grub_gettext_pread (grub_file_t file, void *buf, grub_size_t len,
+ grub_off_t offset)
+{
+ if (grub_file_seek (file, offset) == (grub_off_t) - 1)
+ {
+ return -1;
+ }
+ return grub_file_read (file, buf, len);
+}
+
+static grub_uint32_t
+grub_gettext_get_info (int offset)
+{
+ grub_uint32_t value;
+
+ grub_gettext_pread (fd_mo, (char *) &value, 4, offset);
+
+ value = grub_cpu_to_le32 (value);
+ return value;
+}
+
+static void
+grub_gettext_getstring_from_offset (grub_uint32_t offset,
+ grub_uint32_t length, char *translation)
+{
+ grub_gettext_pread (fd_mo, translation, length, offset);
+ translation[length] = '\0';
+}
+
+static char *
+grub_gettext_gettranslation_from_position (int position)
+{
+ int offsettranslation;
+ int internal_position;
+ grub_uint32_t length, offset;
+ char *translation;
+
+ offsettranslation = grub_gettext_get_info (GETTEXT_OFFSET_TRANSLATION);
+
+ internal_position = offsettranslation + position * 8;
+
+ grub_gettext_pread (fd_mo, (char *) &length, 4, internal_position);
+ length = grub_cpu_to_le32 (length);
+
+ grub_gettext_pread (fd_mo, (char *) &offset, 4, internal_position + 4);
+ offset = grub_cpu_to_le32 (offset);
+
+ translation = grub_malloc (length + 1);
+ grub_gettext_getstring_from_offset (offset, length, translation);
+
+ return translation;
+}
+
+static char *
+grub_gettext_getstring_from_position (int position)
+{
+ int internal_position;
+ int length, offset;
+ char *original;
+
+ /* Get position for string i. */
+ internal_position = grub_gettext_offsetoriginal + (position * 8);
+
+ /* Get the length of the string i. */
+ grub_gettext_pread (fd_mo, (char *) &length, 4, internal_position);
+
+ /* Get the offset of the string i. */
+ grub_gettext_pread (fd_mo, (char *) &offset, 4, internal_position + 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_from_position (current);
+
+ /* Search by bisection. */
+ 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_from_position (current);
+ }
+ current = (max + min) / 2;
+ }
+
+ ret = grub_malloc (grub_strlen (orig) + 1);
+ grub_strcpy (ret, orig);
+ return ret;
+}
+
+/* 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_gzfile_open (filename, 1);
+ grub_errno = GRUB_ERR_NONE;
+
+ if (!fd_mo)
+ {
+ grub_dprintf ("gettext", "Cannot read %s", filename);
+ return 0;
+ }
+
+ magic = grub_gettext_get_info (GETTEXT_MAGIC_NUMBER);
+
+ if (magic != MO_MAGIC_NUMBER)
+ {
+ 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;
+ }
+
+ return fd_mo;
+}
+
+static void
+grub_gettext_init_ext (const char *lang)
+{
+ char *mo_file;
+ char *locale_dir;
+
+ locale_dir = grub_env_get ("locale_dir");
+ if (locale_dir == NULL)
+ {
+ grub_printf ("locale_dir variable is not setted up.");
+ return;
+ }
+
+ fd_mo = NULL;
+
+ /* mo_file e.g.: /boot/grub/locale/ca.mo */
+
+ mo_file =
+ grub_malloc (grub_strlen (locale_dir) + grub_strlen ("/") +
+ grub_strlen (lang) + grub_strlen (".mo") + 1);
+
+ /* Warning: if changing some paths in the below line, change the grub_malloc
+ contents below. */
+
+ grub_sprintf (mo_file, "%s/%s.mo", locale_dir, lang);
+
+ fd_mo = grub_mofile_open (mo_file);
+
+ /* Will try adding .gz as well. */
+ if (fd_mo == NULL)
+ {
+ grub_sprintf (mo_file, "%s.gz", mo_file);
+ fd_mo = grub_mofile_open (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);
+
+ /* 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;
+}
=== modified file 'include/grub/i18n.h'
--- include/grub/i18n.h 2009-11-17 09:52:08 +0000
+++ include/grub/i18n.h 2009-11-21 23:52:17 +0000
@@ -24,7 +24,7 @@
# include
# define _(str) gettext(str)
#else
-# define _(str) str
+# define _(str) grub_gettext(str)
#endif
#endif /* GRUB_I18N_H */
=== modified file 'include/grub/misc.h'
--- include/grub/misc.h 2009-10-28 22:55:27 +0000
+++ include/grub/misc.h 2009-11-22 12:34:50 +0000
@@ -1,7 +1,7 @@
/* misc.h - prototypes for misc functions */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2008 Free Software Foundation, Inc.
+ * Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2008,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
@@ -191,6 +191,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);
+
#ifdef NEED_ENABLE_EXECUTE_STACK
void EXPORT_FUNC(__enable_execute_stack) (void *addr);
#endif
=== modified file 'kern/misc.c'
--- kern/misc.c 2009-11-01 23:03:09 +0000
+++ kern/misc.c 2009-11-21 23:55:37 +0000
@@ -30,6 +30,8 @@
return (grub_isspace (c) || c == ',' || c == ';' || c == '|' || c == '&');
}
+const char* (*grub_gettext) (const char *s) = grub_gettext_dummy;
+
void *
grub_memmove (void *dest, const void *src, grub_size_t n)
{
@@ -984,6 +986,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)
=== modified file 'normal/menu_text.c'
--- normal/menu_text.c 2009-05-02 19:49:34 +0000
+++ normal/menu_text.c 2009-11-22 11:44:20 +0000
@@ -25,6 +25,7 @@
#include
#include
#include
+#include
/* Time to delay after displaying an error message about a default/fallback
entry failing to boot. */
@@ -93,8 +94,8 @@
}
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 ("\
Press enter to boot the selected OS, \'e\' to edit the\n\
@@ -266,7 +267,7 @@
{
/* NOTE: Do not remove the trailing space characters.
They are required to clear the line. */
- char *msg = " The highlighted entry will be booted automatically in %ds. ";
+ const 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);
=== modified file 'po/POTFILES'
--- po/POTFILES 2009-11-18 23:20:22 +0000
+++ po/POTFILES 2009-11-22 11:45:38 +0000
@@ -10,3 +10,5 @@
util/mkisofs/rock.c
util/mkisofs/tree.c
util/mkisofs/write.c
+
+normal/menu_text.c
=== modified file 'po/ca.po'
--- po/ca.po 2009-11-18 23:20:22 +0000
+++ po/ca.po 2009-11-22 16:59:12 +0000
@@ -6,7 +6,7 @@
msgstr ""
"Project-Id-Version: GNU GRUB\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-11-19 00:16+0100\n"
+"POT-Creation-Date: 2009-11-22 11:45+0000\n"
"PO-Revision-Date: 2009-11-17 12:26+0100\n"
"Last-Translator: Robert Millan \n"
"Language-Team: None \n"
@@ -63,7 +63,7 @@
#: util/i386/pc/grub-mkimage.c:321 util/i386/pc/grub-setup.c:587
#, c-format
msgid "Try ``%s --help'' for more information.\n"
-msgstr "Proveu «%s --help» per a obtenir més informació.\n"
+msgstr "Proveu ë%s --helpû per a obtenir més informació.\n"
#: util/i386/pc/grub-mkimage.c:323
#, c-format
@@ -882,6 +882,20 @@
msgid "Path table size(bytes): %d\n"
msgstr ""
+#: normal/menu_text.c:97
+#, 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 a seleccionar l'entrada.\n"
+
+#: normal/menu_text.c:270
+#, c-format
+msgid " The highlighted entry will be booted automatically in %ds. "
+msgstr " L' entrada seleccionada sera arrancada automaticament en %ds. "
+
#: util/grub.d/10_kfreebsd.in:40
msgid "%s, with kFreeBSD %s"
msgstr ""
=== modified file 'util/grub.d/00_header.in'
--- util/grub.d/00_header.in 2009-08-25 19:42:56 +0000
+++ util/grub.d/00_header.in 2009-11-21 23:53:44 +0000
@@ -22,6 +22,8 @@
address@hidden@
address@hidden@
grub_prefix=`echo /boot/grub | sed ${transform}`
+locale_dir=`echo /boot/grub/locale | sed ${transform}`
+grub_lang=`echo $LANG | cut -d _ -f 1`
. ${libdir}/grub/grub-mkconfig_lib
@@ -100,6 +102,15 @@
;;
esac
+# Gettext variables and module
+if [ "x${LANG}" != "xC" ] ; then
+ cat << EOF
+set locale_dir=${locale_dir}
+set lang=${grub_lang}
+insmod gettext
+EOF
+fi
+
if [ "x${GRUB_HIDDEN_TIMEOUT}" != "x" ] ; then
if [ "x${GRUB_HIDDEN_TIMEOUT_QUIET}" = "xtrue" ] ; then
verbose=