From: Vladimir Serbinenko Date: Mon, 28 Oct 2013 15:49:58 +0000 (+0100) Subject: Supporting infrastructure for brltty X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e79b5f26781997557c9cbf512bf57af4ff89ba40;p=thirdparty%2Fgrub.git Supporting infrastructure for brltty --- diff --git a/.gitignore b/.gitignore index e7251ff4f..01984b351 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,7 @@ aclocal.m4 ahci_test ascii.bitmaps -ascii.h +asciifont.h autom4te.cache build_env.mk .bzrignore diff --git a/Makefile.am b/Makefile.am index 724c6bb10..7cd4f806e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -61,7 +61,7 @@ grub_fstest_init.c: grub_fstest_init.lst $(top_srcdir)/geninit.sh CLEANFILES += grub_fstest_init.c if COND_HAVE_FONT_SOURCE -pkgdata_DATA += unicode.pf2 ascii.pf2 euro.pf2 ascii.h widthspec.h +pkgdata_DATA += unicode.pf2 ascii.pf2 euro.pf2 asciifont.h widthspec.h endif starfield_theme_files = $(srcdir)/themes/starfield/blob_w.png $(srcdir)/themes/starfield/boot_menu_c.png $(srcdir)/themes/starfield/boot_menu_e.png $(srcdir)/themes/starfield/boot_menu_ne.png $(srcdir)/themes/starfield/boot_menu_n.png $(srcdir)/themes/starfield/boot_menu_nw.png $(srcdir)/themes/starfield/boot_menu_se.png $(srcdir)/themes/starfield/boot_menu_s.png $(srcdir)/themes/starfield/boot_menu_sw.png $(srcdir)/themes/starfield/boot_menu_w.png $(srcdir)/themes/starfield/slider_c.png $(srcdir)/themes/starfield/slider_n.png $(srcdir)/themes/starfield/slider_s.png $(srcdir)/themes/starfield/starfield.png $(srcdir)/themes/starfield/terminal_box_c.png $(srcdir)/themes/starfield/terminal_box_e.png $(srcdir)/themes/starfield/terminal_box_ne.png $(srcdir)/themes/starfield/terminal_box_n.png $(srcdir)/themes/starfield/terminal_box_nw.png $(srcdir)/themes/starfield/terminal_box_se.png $(srcdir)/themes/starfield/terminal_box_s.png $(srcdir)/themes/starfield/terminal_box_sw.png $(srcdir)/themes/starfield/terminal_box_w.png $(srcdir)/themes/starfield/theme.txt $(srcdir)/themes/starfield/README $(srcdir)/themes/starfield/COPYING.CC-BY-SA-3.0 diff --git a/autogen.sh b/autogen.sh index 10fe68fb9..aaa069137 100755 --- a/autogen.sh +++ b/autogen.sh @@ -5,7 +5,7 @@ set -e export LC_COLLATE=C unset LC_ALL -find . -iname '*.[ch]' ! -ipath './grub-core/lib/libgcrypt-grub/*' ! -ipath './build-aux/*' ! -ipath './grub-core/lib/libgcrypt/src/misc.c' ! -ipath './grub-core/lib/libgcrypt/src/global.c' ! -ipath './grub-core/lib/libgcrypt/src/secmem.c' ! -ipath './util/grub-gen-widthspec.c' ! -ipath './util/grub-gen-asciih.c' |sort > po/POTFILES.in +find . -iname '*.[ch]' ! -ipath '*/grub-core/braille/brltty/*' ! -ipath './grub-core/lib/libgcrypt-grub/*' ! -ipath './build-aux/*' ! -ipath './grub-core/lib/libgcrypt/src/misc.c' ! -ipath './grub-core/lib/libgcrypt/src/global.c' ! -ipath './grub-core/lib/libgcrypt/src/secmem.c' ! -ipath './util/grub-gen-widthspec.c' ! -ipath './util/grub-gen-asciih.c' |sort > po/POTFILES.in find util -iname '*.in' ! -name Makefile.in |sort > po/POTFILES-shell.in autogen --version >/dev/null || exit 1 diff --git a/conf/Makefile.common b/conf/Makefile.common index 3877b0b93..e2f845977 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -110,8 +110,11 @@ starfielddir = $(pkgdatadir)/themes/starfield CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -Wno-conversion -Wno-old-style-definition -Wno-unsafe-loop-optimizations CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/gnulib -I$(top_srcdir)/grub-core/gnulib +CFLAGS_BRAILLE = -Wno-strict-prototypes -Wno-missing-field-initializers -Wno-unused-parameter -Wno-shadow -Wno-sign-compare +CPPFLAGS_BRAILLE = -I$(top_srcdir)/grub-core/braille/brltty_wrap -I$(top_srcdir)/grub-core/braille/brltty/Programs -I$(top_srcdir)/grub-core/braille/brltty -Wno-sign-compare -DPACKAGE_REVISION=\"\" -include $(top_srcdir)/grub-core/braille/config.h + CFLAGS_POSIX = -fno-builtin -CPPFLAGS_POSIX = -I$(top_srcdir)/grub-core/lib/posix_wrap +CPPFLAGS_POSIX = -I$(top_srcdir)/grub-core/lib/posix_wrap/include CFLAGS_GCRY = -Wno-error -Wno-missing-field-initializers -Wno-redundant-decls $(CFLAGS_POSIX) CPPFLAGS_GCRY = -I$(top_srcdir)/grub-core/lib/libgcrypt_wrap $(CPPFLAGS_POSIX) -D_GCRYPT_IN_LIBGCRYPT=1 -I$(top_srcdir)/include/grub/gcrypt diff --git a/config.h.in b/config.h.in index efc9c4ca0..6ba79acf0 100644 --- a/config.h.in +++ b/config.h.in @@ -60,6 +60,14 @@ #define RE_ENABLE_I18N 1 +#define _GL_UNUSED __attribute__ ((unused)) +#define HAVE_VPRINTF 1 +#define HAVE_DECL_STRERROR 1 +#define HAVE_INLINE 1 +#define HAVE_MBRTOWC 1 + +#define ENABLE_NLS 1 + #define _GNU_SOURCE 1 #endif diff --git a/configure.ac b/configure.ac index b430135b5..209173a6c 100644 --- a/configure.ac +++ b/configure.ac @@ -85,6 +85,7 @@ HOST_CPPFLAGS="$HOST_CPPFLAGS -DLOCALEDIR=\\\"\$(localedir)\\\"" TARGET_CPPFLAGS="$TARGET_CPPFLAGS -Wall -W" TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_srcdir)/include" TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_builddir)/include" +TARGET_CPPFLAGS="$TARGET_CPPFLAGS -Dfloat=__float__bug__ -Ddouble=__double__bug__ -DGRUB_RUNTIME=1" case "$target_cpu" in i[[3456]]86) target_cpu=i386 ;; @@ -851,9 +852,9 @@ if test "x$target_cpu" = xi386; then fi if test "$platform" != emu; then -AC_CACHE_CHECK([whether -nostdinc -isystem works], [grub_cv_cc_isystem], [ +AC_CACHE_CHECK([whether -nostdinc -ffreestanding -isystem works], [grub_cv_cc_isystem], [ SAVED_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$TARGET_CPPFLAGS -nostdinc -isystem `$TARGET_CC -print-file-name=include`" + CPPFLAGS="$TARGET_CPPFLAGS -nostdinc -ffreestanding -isystem `$TARGET_CC -print-file-name=include`" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include int va_arg_func (int fixed, va_list args);]], [[]])], @@ -863,7 +864,7 @@ int va_arg_func (int fixed, va_list args);]], [[]])], ]) if test x"$grub_cv_cc_isystem" = xyes ; then - TARGET_CPPFLAGS="$TARGET_CPPFLAGS -nostdinc -isystem `$TARGET_CC -print-file-name=include`" + TARGET_CPPFLAGS="$TARGET_CPPFLAGS -nostdinc -ffreestanding -isystem `$TARGET_CC -print-file-name=include`" fi fi diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 036113b20..f45e90e58 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -406,7 +406,7 @@ image = { common = lib/xzembed/xz_dec_lzma2.c; common = lib/xzembed/xz_dec_stream.c; - cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -DGRUB_EMBED_DECOMPRESSOR=1'; + cppflags = '$(CPPFLAGS_POSIX) -I$(srcdir)/lib/xzembed -DGRUB_EMBED_DECOMPRESSOR=1'; objcopyflags = '-O binary'; mips_ldflags = '-static-libgcc -Wl,-Ttext,$(TARGET_DECOMPRESSOR_LINK_ADDR)'; @@ -577,10 +577,18 @@ module = { }; library = { - name = libgnulib.a; + name = libregexp.a; common = gnulib/regex.c; cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)'; - cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)'; + cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB) -DGRUB_POSIX_GETTEXT_DOMAIN=\"grub\"'; +}; + +module = { + name = getopt; + common = gnulib/getopt.c; + common = gnulib/getopt1.c; + cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)'; + cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB) -DGRUB_POSIX_GETTEXT_DOMAIN=\"grub\"'; }; module = { @@ -1202,7 +1210,7 @@ module = { common = fs/btrfs.c; common = lib/crc.c; cflags = '$(CFLAGS_POSIX) -Wno-undef'; - cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H'; + cppflags = '$(CPPFLAGS_POSIX) -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H'; }; module = { @@ -1344,7 +1352,7 @@ module = { name = squash4; common = fs/squash4.c; cflags = '$(CFLAGS_POSIX) -Wno-undef'; - cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H'; + cppflags = '$(CPPFLAGS_POSIX) -I$(srcdir)/lib/xzembed -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H'; }; module = { @@ -2019,7 +2027,7 @@ module = { common = lib/xzembed/xz_dec_bcj.c; common = lib/xzembed/xz_dec_lzma2.c; common = lib/xzembed/xz_dec_stream.c; - cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed'; + cppflags = '$(CPPFLAGS_POSIX) -I$(srcdir)/lib/xzembed'; cflags='-Wno-unreachable-code'; }; @@ -2028,7 +2036,7 @@ module = { common = io/lzopio.c; common = lib/minilzo/minilzo.c; cflags = '$(CFLAGS_POSIX) -Wno-undef -Wno-redundant-decls -Wno-error'; - cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H'; + cppflags = '$(CPPFLAGS_POSIX) -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H'; }; module = { @@ -2055,6 +2063,87 @@ module = { enable = x86; }; +module = { + name = braille_baum; + common = braille/brltty/Drivers/Braille/Baum/braille.c; + cflags = '$(CFLAGS_POSIX) $(CFLAGS_BRAILLE)'; + cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_BRAILLE) -DDRIVER_NAME=Baum -DDRIVER_CODE=1 -DDRIVER_COMMENT=\"\" -DDRIVER_VERSION=\"\" -DDRIVER_DEVELOPERS=\"\" -DGRUB_POSIX_GETTEXT_DOMAIN=\"brltty\"'; +}; + +module = { + name = braille_core; + common = braille/brltty/Programs/atb_compile.c; + common = braille/brltty/Programs/atb_translate.c; + common = braille/brltty/Programs/brl.c; + common = braille/brltty/Programs/brltty.c; + common = braille/brltty/Programs/bluetooth_none.c; + common = braille/brltty/Programs/bluetooth.c; + common = braille/brltty/Programs/clipboard.c; + common = braille/brltty/Programs/config.c; + common = braille/brltty/Programs/ctb_translate.c; + common = braille/brltty/Programs/dataarea.c; + common = braille/brltty/Programs/device.c; + common = braille/brltty/Programs/driver.c; + common = braille/brltty/Programs/drivers.c; + common = braille/brltty/Programs/menu.c; + common = braille/brltty/Programs/parse.c; + common = braille/brltty/Programs/queue.c; + common = braille/brltty/Programs/routing.c; + common = braille/brltty/Programs/scancodes.c; + common = braille/brltty/Programs/scr_frozen.c; + common = braille/brltty/Programs/ses.c; + common = braille/brltty/Programs/scr.c; + common = braille/brltty/Programs/ttb_translate.c; + common = braille/brltty/Programs/tunes.c; + common = braille/brltty/Programs/usb.c; + common = braille/brltty/Programs/usb_serial.c; + common = braille/brltty/Programs/usb_hid.c; + + common = braille/brltty/Programs/async.c; + common = braille/brltty/Programs/auth.c; + common = braille/brltty/Programs/charset.c; + common = braille/brltty/Programs/charset_grub.c; + common = braille/brltty/Programs/cmd.c; + common = braille/brltty/Programs/ctb_compile.c; + common = braille/brltty/Programs/datafile.c; + common = braille/brltty/Programs/file.c; + common = braille/brltty/Programs/hostcmd.c; + common = braille/brltty/Programs/hostcmd_none.c; + common = braille/brltty/Programs/io_misc.c; + common = braille/brltty/Programs/kbd.c; + common = braille/brltty/Programs/kbd_none.c; + common = braille/brltty/Programs/ktb_compile.c; + common = braille/brltty/Programs/ktb_translate.c; + common = braille/brltty/Programs/ktb_list.c; + common = braille/brltty/Programs/ktb_keyboard.c; + common = braille/brltty/Programs/lock.c; + common = braille/brltty/Programs/log.c; + common = braille/brltty/Programs/main.c; +/* common = braille/brltty/Programs/mount.c; */ + common = braille/brltty/Programs/options.c; + common = braille/brltty/Programs/prefs.c; + common = braille/brltty/Programs/program.c; + common = braille/brltty/Programs/scr_base.c; + common = braille/brltty/Programs/scr_help.c; + common = braille/brltty/Programs/scr_main.c; + common = braille/brltty/Programs/scr_menu.c; +/* common = braille/brltty/Programs/scr_real.c; */ +/* common = braille/brltty/Programs/serial.c; */ + common = braille/brltty/Programs/status.c; + common = braille/brltty/Programs/sys_grub.c; + common = braille/brltty/Programs/timing.c; + common = braille/brltty/Programs/touch.c; + common = braille/brltty/Programs/ttb_compile.c; + common = braille/brltty/Programs/ttb_native.c; + common = braille/brltty/Programs/unicode.c; + +/* common = braille/brltty_wrap/charset.c; */ + common = braille/brltty_wrap/usb.c; + common = braille/brltty_wrap/serial.c; + cflags = '$(CFLAGS_POSIX) $(CFLAGS_BRAILLE)'; + cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_BRAILLE) -DGRUB_POSIX_GETTEXT_DOMAIN=\"brltty\"'; +}; + module = { name = priority_queue; common = lib/priority_queue.c; @@ -2132,6 +2221,24 @@ module = { enable = i386; }; +module = { + name = posix; + common = lib/posix_wrap/errno.c; + common = lib/posix_wrap/stdio.c; + common = lib/posix_wrap/string.c; + common = lib/posix_wrap/time.c; +}; + +module = { + name = bsearch; + common = lib/bsearch.c; +}; + +module = { + name = qsort; + common = lib/qsort.c; +}; + module = { name = testspeed; common = commands/testspeed.c; diff --git a/grub-core/commands/help.c b/grub-core/commands/help.c index f0be89baa..a04489daa 100644 --- a/grub-core/commands/help.c +++ b/grub-core/commands/help.c @@ -45,8 +45,8 @@ grub_cmd_help (grub_extcmd_context_t ctxt __attribute__ ((unused)), int argc, struct grub_term_output *term; const char *summary_translated = _(cmd->summary); char *command_help; - grub_uint32_t *unicode_command_help; - grub_uint32_t *unicode_last_position; + grub_wchar_t *unicode_command_help; + grub_wchar_t *unicode_last_position; command_help = grub_xasprintf ("%s %s", cmd->name, summary_translated); if (!command_help) @@ -58,7 +58,7 @@ grub_cmd_help (grub_extcmd_context_t ctxt __attribute__ ((unused)), int argc, FOR_ACTIVE_TERM_OUTPUTS(term) { unsigned stringwidth; - grub_uint32_t *unicode_last_screen_position; + grub_wchar_t *unicode_last_screen_position; unicode_last_screen_position = unicode_command_help; diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c index 259251d76..8e70185a1 100644 --- a/grub-core/gettext/gettext.c +++ b/grub-core/gettext/gettext.c @@ -34,8 +34,6 @@ GRUB_MOD_LICENSE ("GPLv3+"); http://www.gnu.org/software/autoconf/manual/gettext/MO-Files.html . */ -static struct grub_gettext_context main_context, secondary_context; - static const char *(*grub_gettext_original) (const char *s); struct grub_gettext_msg @@ -69,6 +67,21 @@ struct grub_gettext_context struct grub_gettext_msg *grub_gettext_msg_list; }; +const char *const domains[] = + { + "grub", + "bison-runtime", + "brltty" + }; +enum + { + CONTEXT_GRUB, + CONTEXT_BISON, + CONTEXT_BRLTTY, + CONTEXT_CNT + }; +static struct grub_gettext_context main_context[ARRAY_SIZE (domains)], secondary_context; + #define MO_MAGIC_NUMBER 0x950412de static grub_err_t @@ -244,6 +257,21 @@ grub_gettext_translate_real (struct grub_gettext_context *ctx, return NULL; } +const char * +grub_dgettext (const char *domainname, const char *msgid) +{ + unsigned i; + const char *ret = msgid; + COMPILE_TIME_ASSERT (ARRAY_SIZE (domains) == CONTEXT_CNT); + for (i = 0; i < ARRAY_SIZE (domains); i++) + if (grub_strcmp (domainname, domains[i]) == 0) + { + ret = grub_gettext_translate_real (&main_context[i], msgid); + break; + } + return ret; +} + static const char * grub_gettext_translate (const char *orig) { @@ -251,7 +279,7 @@ grub_gettext_translate (const char *orig) if (orig[0] == 0) return orig; - ret = grub_gettext_translate_real (&main_context, orig); + ret = grub_gettext_translate_real (&main_context[CONTEXT_GRUB], orig); if (ret) return ret; ret = grub_gettext_translate_real (&secondary_context, orig); @@ -343,14 +371,18 @@ grub_mofile_open (struct grub_gettext_context *ctx, to fd_mo anyway ... */ static grub_err_t grub_mofile_open_lang (struct grub_gettext_context *ctx, - const char *part1, const char *part2, const char *locale) + const char *part1, const char *part2, + const char *domain, const char *locale) { char *mo_file; grub_err_t err; /* mo_file e.g.: /boot/grub/locale/ca.mo */ - mo_file = grub_xasprintf ("%s%s/%s.mo", part1, part2, locale); + if (domain) + mo_file = grub_xasprintf ("%s%s/%s/%s.mo", part1, part2, domain, locale); + else + mo_file = grub_xasprintf ("%s%s/%s.mo", part1, part2, locale); if (!mo_file) return grub_errno; @@ -385,7 +417,8 @@ grub_mofile_open_lang (struct grub_gettext_context *ctx, static grub_err_t grub_gettext_init_ext (struct grub_gettext_context *ctx, const char *locale, - const char *locale_dir, const char *prefix) + const char *locale_dir, const char *prefix, + const char *domain) { const char *part1, *part2; grub_err_t err; @@ -406,7 +439,7 @@ grub_gettext_init_ext (struct grub_gettext_context *ctx, if (!part1 || part1[0] == 0) return 0; - err = grub_mofile_open_lang (ctx, part1, part2, locale); + err = grub_mofile_open_lang (ctx, part1, part2, domain, locale); /* ll_CC didn't work, so try ll. */ if (err) @@ -418,7 +451,7 @@ grub_gettext_init_ext (struct grub_gettext_context *ctx, { *underscore = '\0'; grub_errno = GRUB_ERR_NONE; - err = grub_mofile_open_lang (ctx, part1, part2, lang); + err = grub_mofile_open_lang (ctx, part1, part2, domain, lang); } grub_free (lang); @@ -431,13 +464,20 @@ grub_gettext_env_write_lang (struct grub_env_var *var __attribute__ ((unused)), const char *val) { grub_err_t err; - err = grub_gettext_init_ext (&main_context, val, grub_env_get ("locale_dir"), - grub_env_get ("prefix")); - if (err) - grub_print_error (); + unsigned i; + COMPILE_TIME_ASSERT (ARRAY_SIZE (domains) == CONTEXT_CNT); + for (i = 0; i < ARRAY_SIZE (domains); i++) + { + err = grub_gettext_init_ext (&main_context[i], val, + grub_env_get ("locale_dir"), + grub_env_get ("prefix"), + domains[i]); + if (err) + grub_print_error (); + } err = grub_gettext_init_ext (&secondary_context, val, - grub_env_get ("secondary_locale_dir"), 0); + grub_env_get ("secondary_locale_dir"), 0, 0); if (err) grub_print_error (); @@ -448,11 +488,16 @@ void grub_gettext_reread_prefix (const char *val) { grub_err_t err; - err = grub_gettext_init_ext (&main_context, grub_env_get ("lang"), - grub_env_get ("locale_dir"), - val); - if (err) - grub_print_error (); + unsigned i; + COMPILE_TIME_ASSERT (ARRAY_SIZE (domains) == CONTEXT_CNT); + for (i = 0; i < ARRAY_SIZE (domains); i++) + { + err = grub_gettext_init_ext (&main_context[i], grub_env_get ("lang"), + grub_env_get ("locale_dir"), + val, domains[i]); + if (err) + grub_print_error (); + } } static char * @@ -460,10 +505,15 @@ read_main (struct grub_env_var *var __attribute__ ((unused)), const char *val) { grub_err_t err; - err = grub_gettext_init_ext (&main_context, grub_env_get ("lang"), val, - grub_env_get ("prefix")); - if (err) - grub_print_error (); + unsigned i; + COMPILE_TIME_ASSERT (ARRAY_SIZE (domains) == CONTEXT_CNT); + for (i = 0; i < ARRAY_SIZE (domains); i++) + { + err = grub_gettext_init_ext (&main_context[i], grub_env_get ("lang"), val, + grub_env_get ("prefix"), domains[i]); + if (err) + grub_print_error (); + } return grub_strdup (val); } @@ -473,7 +523,7 @@ read_secondary (struct grub_env_var *var { grub_err_t err; err = grub_gettext_init_ext (&secondary_context, grub_env_get ("lang"), val, - 0); + 0, 0); if (err) grub_print_error (); @@ -500,12 +550,19 @@ GRUB_MOD_INIT (gettext) lang = grub_env_get ("lang"); - err = grub_gettext_init_ext (&main_context, lang, grub_env_get ("locale_dir"), - grub_env_get ("prefix")); - if (err) - grub_print_error (); + unsigned i; + COMPILE_TIME_ASSERT (ARRAY_SIZE (domains) == CONTEXT_CNT); + for (i = 0; i < ARRAY_SIZE (domains); i++) + { + grub_err_t err; + err = grub_gettext_init_ext (&main_context[i], lang, + grub_env_get ("locale_dir"), + grub_env_get ("prefix"), domains[i]); + if (err) + grub_print_error (); + } err = grub_gettext_init_ext (&secondary_context, lang, - grub_env_get ("secondary_locale_dir"), 0); + grub_env_get ("secondary_locale_dir"), 0, 0); if (err) grub_print_error (); @@ -531,7 +588,10 @@ GRUB_MOD_INIT (gettext) GRUB_MOD_FINI (gettext) { - grub_gettext_delete_list (&main_context); + unsigned i; + COMPILE_TIME_ASSERT (ARRAY_SIZE (domains) == CONTEXT_CNT); + for (i = 0; i < ARRAY_SIZE (domains); i++) + grub_gettext_delete_list (&main_context[i]); grub_gettext_delete_list (&secondary_context); grub_gettext = grub_gettext_original; diff --git a/grub-core/gfxmenu/font.c b/grub-core/gfxmenu/font.c index 64d52670b..b76f61f1e 100644 --- a/grub-core/gfxmenu/font.c +++ b/grub-core/gfxmenu/font.c @@ -42,7 +42,7 @@ grub_font_draw_string (const char *str, grub_font_t font, int left_x, int baseline_y) { int x; - grub_uint32_t *logical; + grub_wchar_t *logical; grub_ssize_t logical_len, visual_len; struct grub_unicode_glyph *visual, *ptr; @@ -83,9 +83,9 @@ int grub_font_get_string_width (grub_font_t font, const char *str) { int width = 0; - grub_uint32_t *ptr; + grub_wchar_t *ptr; grub_ssize_t logical_len; - grub_uint32_t *logical; + grub_wchar_t *logical; logical_len = grub_utf8_to_ucs4_alloc (str, &logical, 0); if (logical_len < 0) diff --git a/grub-core/gnulib/regex.h b/grub-core/gnulib/regex.h index 854c6edaf..a38f19298 100644 --- a/grub-core/gnulib/regex.h +++ b/grub-core/gnulib/regex.h @@ -622,13 +622,7 @@ extern int re_exec (const char *); 'configure' might #define 'restrict' to those words, so pick a different name. */ #ifndef _Restrict_ -# if 199901L <= __STDC_VERSION__ -# define _Restrict_ restrict -# elif 2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__) -# define _Restrict_ __restrict -# else -# define _Restrict_ -# endif +# define _Restrict_ __restrict #endif /* gcc 3.1 and up support the [restrict] syntax. Don't trust sys/cdefs.h's definition of __restrict_arr, though, as it diff --git a/grub-core/io/xzio.c b/grub-core/io/xzio.c index bcce24290..5abdda4b2 100644 --- a/grub-core/io/xzio.c +++ b/grub-core/io/xzio.c @@ -74,15 +74,15 @@ static grub_ssize_t read_vli (grub_file_t file, grub_uint64_t *num) { grub_uint8_t buf[VLI_MAX_DIGITS]; - grub_ssize_t read; + grub_ssize_t to_read; grub_size_t dec; - read = grub_file_read (file, buf, VLI_MAX_DIGITS); - if (read < 0) + to_read = grub_file_read (file, buf, VLI_MAX_DIGITS); + if (to_read < 0) return -1; - dec = decode_vli (buf, read, num); - grub_file_seek (file, file->offset - (read - dec)); + dec = decode_vli (buf, to_read, num); + grub_file_seek (file, file->offset - (to_read - dec)); return dec; } diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 6c086adda..3f656d7fb 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -77,16 +77,6 @@ grub_dl_remove (grub_dl_t mod) -struct grub_symbol -{ - struct grub_symbol *next; - const char *name; - void *addr; - int isfunc; - grub_dl_t mod; /* The module to which this symbol belongs. */ -}; -typedef struct grub_symbol *grub_symbol_t; - /* The size of the symbol table. */ #define GRUB_SYMTAB_SIZE 509 @@ -119,6 +109,18 @@ grub_dl_resolve_symbol (const char *name) return 0; } +grub_symbol_t +grub_get_symbol (const char *name, grub_dl_t mod) +{ + grub_symbol_t sym; + + for (sym = grub_symtab[grub_symbol_hash (name)]; sym; sym = sym->next) + if (grub_strcmp (sym->name, name) == 0 && sym->mod == mod) + return sym; + + return 0; +} + /* Register a symbol with the name NAME and the address ADDR. */ grub_err_t grub_dl_register_symbol (const char *name, void *addr, int isfunc, diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index d8de0bb09..d6d69a36b 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -645,6 +645,54 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list a count++; } + void write_wide (grub_uint32_t code) + { + int shift; + unsigned mask; + + if (code <= 0x7f) + { + shift = 0; + mask = 0; + } + else if (code <= 0x7ff) + { + shift = 6; + mask = 0xc0; + } + else if (code <= 0xffff) + { + shift = 12; + mask = 0xe0; + } + else if (code <= 0x1fffff) + { + shift = 18; + mask = 0xf0; + } + else if (code <= 0x3ffffff) + { + shift = 24; + mask = 0xf8; + } + else if (code <= 0x7fffffff) + { + shift = 30; + mask = 0xfc; + } + else + { + code = '?'; + shift = 0; + mask = 0; + } + + write_char (mask | (code >> shift)); + + for (shift -= 6; shift >= 0; shift -= 6) + write_char (0x80 | (0x3f & (code >> shift))); + } + void write_str (const char *s) { while (*s) diff --git a/grub-core/lib/bsearch.c b/grub-core/lib/bsearch.c new file mode 100644 index 000000000..e324ad5ee --- /dev/null +++ b/grub-core/lib/bsearch.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +void * +grub_bsearch (const void *key, const void *base, grub_size_t nmemb, + grub_size_t size, int (*compar)(const void *, const void *)) +{ + grub_size_t cur = 0; + int i; + const void *el; + int cmp; + for (i = 0; (1U << i) < nmemb; i++); + for (i--; i; i--) + { + if ((cur | (1U << i)) >= nmemb) + continue; + el = (const char *) base + size * (cur | (1 << i)); + cmp = compar (el, key); + if (cmp < 0) + cur |= (1 << i); + if (cmp == 0) + return (void *) el; + } + el = (const char *) base + size * (cur | (1 << i)); + cmp = compar (el, key); + if (cmp == 0) + return (void *) el; + return NULL; +} diff --git a/grub-core/lib/posix_wrap/errno.c b/grub-core/lib/posix_wrap/errno.c new file mode 100644 index 000000000..61960ab16 --- /dev/null +++ b/grub-core/lib/posix_wrap/errno.c @@ -0,0 +1,26 @@ +#include +#include +#include + +grub_err_t grub_posix_errno; + +static const char *posix_errmsg[] = + { + [GRUB_ERR_NONE] = "success", + [GRUB_ERR_BAD_NUMBER] = N_("unrecognized number"), + [GRUB_ERR_OUT_OF_MEMORY] = N_("out of memory"), + [GRUB_ERR_AGAIN] = "waiting", + /* FIXME: Disambiguate this. */ + [GRUB_ERR_IO] = "I/O error", + [GRUB_ERR_POSIX_EROFS] = "no FS writing support", + [GRUB_ERR_ACCESS_DENIED] = N_("access denied"), + [GRUB_ERR_BAD_ARGUMENT] = "invalid argument" + }; + +const char * +grub_posix_strerror (grub_err_t err) +{ + if (err < ARRAY_SIZE (posix_errmsg) && posix_errmsg[err]) + return _(posix_errmsg[err]); + return grub_errmsg; +} diff --git a/grub-core/lib/posix_wrap/errno.h b/grub-core/lib/posix_wrap/errno.h index 9031722e2..b40203df1 100644 --- a/grub-core/lib/posix_wrap/errno.h +++ b/grub-core/lib/posix_wrap/errno.h @@ -20,9 +20,27 @@ #define GRUB_POSIX_ERRNO_H 1 #include +#include -#define errno grub_errno +#define errno grub_posix_errno #define EINVAL GRUB_ERR_BAD_NUMBER #define ENOMEM GRUB_ERR_OUT_OF_MEMORY +#define EAGAIN GRUB_ERR_AGAIN + /* FIXME: Disambiguate this. */ +#define ENODEV GRUB_ERR_IO +#define ENOSYS GRUB_ERR_IO +#define ENOENT GRUB_ERR_IO +#define EIO GRUB_ERR_IO +#define EROFS GRUB_ERR_POSIX_EROFS +#define EINTR GRUB_ERR_AGAIN +#define EACCES GRUB_ERR_ACCESS_DENIED +#define ERANGE GRUB_ERR_BAD_ARGUMENT +#define EEXIST GRUB_ERR_POSIX_EEXIST + +static inline const char * +strerror (grub_err_t err) +{ + return grub_posix_strerror (err); +} #endif diff --git a/grub-core/lib/posix_wrap/include/fcntl.h b/grub-core/lib/posix_wrap/include/fcntl.h new file mode 100644 index 000000000..c6a7456c1 --- /dev/null +++ b/grub-core/lib/posix_wrap/include/fcntl.h @@ -0,0 +1,31 @@ +#ifndef GRUB_POSIX_FCNTL_H +#define GRUB_POSIX_FCNTL_H 1 + +#include + +#define O_RDONLY 1 +#define O_RDWR 3 +#define O_CREAT 4 +#define S_IRUSR 0 +#define S_IWUSR 0 + +static inline int +open (const char *pathname, int flags, ...) +{ + struct grub_posix_file *f; + if (flags != O_RDONLY) + return -1; + f = grub_posix_fopen (pathname, "r"); + if (!f) + return -1; + return f->fileno; +} + +static inline int +close (int fd) +{ + return grub_posix_close (fd); +} + + +#endif diff --git a/grub-core/lib/posix_wrap/include/getopt.h b/grub-core/lib/posix_wrap/include/getopt.h new file mode 100644 index 000000000..30a6c32e2 --- /dev/null +++ b/grub-core/lib/posix_wrap/include/getopt.h @@ -0,0 +1,33 @@ +#ifndef GRUB_GETOPT_H +#define GRUB_GETOPT_H 1 + +struct option { + const char *name; + int has_arg; + int *flag; + int val; +}; + +enum + { + no_argument, + required_argument, + optional_argument + }; +extern char *optarg; +extern int optind, opterr, optopt; + +#define __getopt_argv_const const + +int getopt(int argc, char * const argv[], + const char *optstring); + +int getopt_long(int argc, char * const argv[], + const char *optstring, + const struct option *longopts, int *longindex); + +int getopt_long_only(int argc, char * const argv[], + const char *optstring, + const struct option *longopts, int *longindex); + +#endif diff --git a/grub-core/lib/posix_wrap/include/libintl.h b/grub-core/lib/posix_wrap/include/libintl.h new file mode 100644 index 000000000..843ffebe6 --- /dev/null +++ b/grub-core/lib/posix_wrap/include/libintl.h @@ -0,0 +1,32 @@ +#ifndef GRUB_POSIX_LIBINTL_H +#define GRUB_POSIX_LIBINTL_H 1 + +#include + +/* FIXME: sloppy. */ +#define setlocale(x,y) 0 +#define bindtextdomain(x,y) +#define textdomain(x) + +#ifdef GRUB_POSIX_GETTEXT_DOMAIN +static inline const char * +gettext (const char *str) +{ + return grub_dgettext (GRUB_POSIX_GETTEXT_DOMAIN, str); +} +#endif + +static inline const char * +dgettext (const char *dom, const char *str) +{ + return grub_dgettext (dom, str); +} + +/* Not really implemented, just declarations. */ +char * dcgettext (const char * domainname, const char * msgid, + int category); +char * dcngettext (const char * domainname, + const char * msgid, const char * msgid_plural, + unsigned long int n, int category); + +#endif diff --git a/grub-core/lib/posix_wrap/include/strings.h b/grub-core/lib/posix_wrap/include/strings.h new file mode 100644 index 000000000..b66438d50 --- /dev/null +++ b/grub-core/lib/posix_wrap/include/strings.h @@ -0,0 +1,10 @@ + +static inline int +ffs (int i) +{ + unsigned j; + for (j = 0; j < sizeof (i) * 8; j++) + if (i & (1 << j)) + return j + 1; + return 0; +} diff --git a/grub-core/lib/posix_wrap/include/sys/time.h b/grub-core/lib/posix_wrap/include/sys/time.h new file mode 100644 index 000000000..56f111fc1 --- /dev/null +++ b/grub-core/lib/posix_wrap/include/sys/time.h @@ -0,0 +1,77 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2011 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 . + */ + +#ifndef GRUB_POSIX_SYS_TIME_H +#define GRUB_POSIX_SYS_TIME_H 1 + +#include +#include + +struct timeval +{ + grub_time_t tv_sec; + long int tv_usec; +}; + +typedef grub_time_t time_t; + +static inline time_t +time (time_t *t) +{ + return grub_posix_time (t); +} + +extern struct tm grub_posix_tm_result; + +static inline struct tm * +localtime_r (const time_t *timep, struct tm *result) +{ + grub_unixtime2datetime (*timep, &result->tm); + return result; +} + +static inline struct tm * +localtime (const time_t *timep) +{ + return localtime_r (timep, &grub_posix_tm_result); +} + +#define tm_hour tm.hour +#define tm_min tm.minute + +static inline grub_size_t +strftime (char *s, grub_size_t max, const char *format, + const struct tm *tm) +{ + return grub_strftime (s, max, format, &tm->tm); +} + +struct timezone; + +static inline int +gettimeofday_fake (struct timeval *tv, struct timezone *tz) +{ + grub_uint64_t ms = grub_get_time_ms (); + grub_uint64_t t; + tv->tv_sec = grub_divmod64 (ms, 1000, &t); + tv->tv_usec = t * 1000; + return 0; +} + + +#endif diff --git a/grub-core/lib/posix_wrap/include/syslog.h b/grub-core/lib/posix_wrap/include/syslog.h new file mode 100644 index 000000000..0bafe2158 --- /dev/null +++ b/grub-core/lib/posix_wrap/include/syslog.h @@ -0,0 +1,25 @@ + +enum + { + LOG_DAEMON = (3<<3) + }; + +enum + { + LOG_PID = 0x01 + }; + +enum + { + LOG_CRIT, + LOG_ERR, + LOG_WARNING, + LOG_NOTICE, + LOG_INFO, + LOG_DEBUG, + }; + +#define syslog(prio, fmt, args...) grub_dprintf ("syslog", fmt, ##args) + +#define openlog(x,y,z) +#define closelog() diff --git a/grub-core/lib/posix_wrap/include/time.h b/grub-core/lib/posix_wrap/include/time.h new file mode 100644 index 000000000..18a03a58e --- /dev/null +++ b/grub-core/lib/posix_wrap/include/time.h @@ -0,0 +1 @@ +#include diff --git a/grub-core/lib/posix_wrap/stdio.c b/grub-core/lib/posix_wrap/stdio.c new file mode 100644 index 000000000..4477971ad --- /dev/null +++ b/grub-core/lib/posix_wrap/stdio.c @@ -0,0 +1,246 @@ +#include +#include +#include +#include +#include +#include + +static grub_size_t current_fileno = 16; +static grub_size_t fileno_allocated = 0; +static const grub_size_t min_fileno = 16; +static struct grub_posix_file **files = 0; + +struct grub_posix_file * +grub_posix_fopen (const char *path, const char *mode) +{ + struct grub_posix_file *ret; + if (grub_strcmp (mode, "r") != 0) + { + grub_posix_errno = GRUB_ERR_POSIX_EROFS; + return NULL; + } + ret = grub_zalloc (sizeof (*ret)); + if (!ret) + goto fail; + if (current_fileno >= fileno_allocated) + { + struct grub_posix_file **n; + n = grub_realloc (files, sizeof (files[0]) * 2 * fileno_allocated); + if (!n) + goto fail; + fileno_allocated *= 2; + files = n; + } + ret->file = grub_file_open (path); + if (!ret->file) + goto fail; + ret->fileno = current_fileno; + files[current_fileno] = ret; + return ret; + fail: + grub_posix_errno = grub_errno; + grub_errno = 0; + grub_free (ret); + return NULL; +} + +int +grub_posix_fclose (struct grub_posix_file *fp) +{ + if (fp == grub_posix_stdin || fp == grub_posix_stdout + || fp == grub_posix_stderr) + return 0; + grub_file_close (fp->file); + files[fp->fileno] = 0; + return 0; +} + +int +grub_posix_feof (struct grub_posix_file *fp) +{ + if (fp == grub_posix_stdin || fp == grub_posix_stdout + || fp == grub_posix_stderr) + return 0; + if (fp->file->offset == fp->file->size) + return 1; + return 0; +} + +grub_size_t +grub_posix_fread (void *ptr0, grub_size_t size, grub_size_t nmemb, + struct grub_posix_file *stream) +{ + grub_ssize_t st; + if (stream == grub_posix_stdout || stream == grub_posix_stderr) + { + stream->was_error = 1; + return 0; + } + if (stream == grub_posix_stdin) + { + grub_uint8_t *ptr; + for (ptr = ptr0; ptr < (grub_uint8_t *) ptr0 + size * nmemb; ptr++) + { + int key; + key = grub_getkey (); + if (key == (GRUB_TERM_CTRL | 'd') || key == (GRUB_TERM_CTRL | 'D')) + break; + *ptr = key; + } + st = ptr - (grub_uint8_t *) ptr0; + } + else + st = grub_file_read (ptr0, stream, size * nmemb); + if (st < 0) + { + stream->was_error = 1; + grub_posix_errno = grub_errno; + grub_errno = 0; + return 0; + } + return st / size; +} + +static struct grub_posix_file * +get_file (int fd) +{ + if (fd == grub_posix_stdin_fileno) + return grub_posix_stdin; + if (fd == grub_posix_stdout_fileno) + return grub_posix_stdout; + if (fd == grub_posix_stderr_fileno) + return grub_posix_stderr; + if ((grub_size_t) fd < min_fileno || (grub_size_t) fd >= current_fileno + || files[(grub_size_t) fd] == 0) + return NULL; + return files[(grub_size_t) fd]; +} + +grub_ssize_t +grub_posix_read (int fd, void *buf, grub_size_t count) +{ + grub_ssize_t st; + struct grub_posix_file *file; + file = get_file (fd); + if (file == NULL) + return -1; + return grub_posix_fread (buf, 1, count, file); +} + +char * +grub_posix_fgets (char *ptr0, int size, struct grub_posix_file *stream) +{ + if (stream == grub_posix_stdout || stream == grub_posix_stderr) + return 0; + if (size <= 0) + return 0; + if (stream == grub_posix_stdin) + { + char *ptr; + for (ptr = ptr0; ptr < ptr0 + size - 1; ) + { + int key; + key = grub_getkey (); + if (key == (GRUB_TERM_CTRL | 'd') || key == (GRUB_TERM_CTRL | 'D')) + break; + *ptr = key; + ptr++; + if (key == '\n') + break; + } + *ptr = 0; + return ptr0; + } + else + { + grub_ssize_t st; + grub_off_t off = grub_file_tell (stream->file); + char *ptr; + st = grub_file_read (stream->file, ptr0, size - 1); + if (st < 0) + { + stream->was_error = 1; + grub_posix_errno = grub_errno; + grub_errno = 0; + return 0; + } + ptr = grub_strchr (ptr0, '\n'); + if (ptr) + { + ptr[1] = 0; + grub_file_seek (stream->file, off + ptr - ptr0 + 1); + return ptr0; + } + ptr0[size - 1] = 0; + return ptr0; + } +} + +grub_ssize_t +grub_posix_write_console (const void *buf, grub_size_t count) +{ + char *tmp; + tmp = grub_malloc (count + 1); + if (!tmp) + { + grub_posix_errno = grub_errno; + grub_errno = 0; + return -1; + } + grub_memcpy (tmp, buf, count); + tmp[count] = 0; + grub_xputs (tmp); + grub_free (tmp); + return count; +} + +grub_off_t +grub_posix_seek (int fd, grub_off_t offset, int whence) +{ + struct grub_posix_file *file; + grub_off_t ret, newpos; + if (fd == grub_posix_stdin_fileno || fd == grub_posix_stdout_fileno + || fd == grub_posix_stderr_fileno) + return -1; + file = get_file (fd); + if (file == NULL) + return -1; + switch (whence) + { + case GRUB_POSIX_SEEK_SET: + newpos = offset; + break; + case GRUB_POSIX_SEEK_CUR: + newpos = file->file->offset + offset; + break; + case GRUB_POSIX_SEEK_END: + newpos = grub_file_size (file->file) - offset; + break; + default: + return -1; + } + ret = grub_file_seek (file->file, newpos); + grub_posix_errno = grub_errno; + grub_errno = 0; + return ret; +} + +int +grub_posix_close (int fd) +{ + struct grub_posix_file *file; + file = get_file (fd); + if (file == NULL) + return -1; + return grub_posix_fclose (file); +} + +grub_off_t +grub_posix_get_file_size (int fd) +{ + struct grub_posix_file *file; + file = get_file (fd); + if (file == NULL) + return 0; + return file->file->size; +} diff --git a/grub-core/lib/posix_wrap/stdio.h b/grub-core/lib/posix_wrap/stdio.h index d5a8b7503..0e54526f6 100644 --- a/grub-core/lib/posix_wrap/stdio.h +++ b/grub-core/lib/posix_wrap/stdio.h @@ -21,9 +21,15 @@ #include #include -#include +#include +#include +#include -typedef struct grub_file FILE; +typedef struct grub_posix_file FILE; + +#define stdin grub_posix_stdin +#define stdout grub_posix_stdout +#define stderr grub_posix_stderr #define EOF -1 @@ -40,4 +46,187 @@ snprintf (char *str, grub_size_t n, const char *fmt, ...) return ret; } +static inline int +vsnprintf (char *str, grub_size_t n, const char *fmt, va_list args) +{ + return grub_vsnprintf (str, n, fmt, args); +} + +static inline int +printf (const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start (ap, fmt); + ret = grub_printf (fmt, ap); + va_end (ap); + + grub_posix_errno = grub_errno; + grub_errno = 0; + + return ret; +} + +static inline int +fputs (const char *s, FILE *stream) +{ + if (stream != stdout && stream != stderr) + { + grub_posix_errno = GRUB_ERR_POSIX_EROFS; + return -1; + } + grub_xputs (s); + return 1; +} + +static inline int +puts (const char *s) +{ + grub_puts (s); + return 1; +} + +static inline int +fputc (int c, FILE *stream) +{ + char tmp[2] = {c, 0}; + if (stream != stdout && stream != stderr) + { + grub_posix_errno = GRUB_ERR_POSIX_EROFS; + return -1; + } + grub_xputs (tmp); + return (unsigned char) c; +} + +static inline int +putc (int c, FILE *stream) +{ + return fputc (c, stream); +} + +static inline int +fflush (FILE *stream) +{ + if (stream != stdout && stream != stderr) + { + grub_posix_errno = GRUB_ERR_POSIX_EROFS; + return -1; + } + grub_refresh (); + return 0; +} + +static inline int +vfprintf (FILE *stream, const char *fmt, va_list ap) +{ + int ret; + + if (stream != stdout && stream != stderr) + { + grub_posix_errno = GRUB_ERR_POSIX_EROFS; + return -1; + } + + ret = grub_printf (fmt, ap); + + grub_posix_errno = grub_errno; + grub_errno = 0; + + return ret; +} + +static inline int +fprintf (FILE *stream, const char *fmt, ...) +{ + va_list ap; + int ret; + + if (stream != stdout && stream != stderr) + { + grub_posix_errno = GRUB_ERR_POSIX_EROFS; + return -1; + } + + va_start (ap, fmt); + ret = grub_printf (fmt, ap); + va_end (ap); + + grub_posix_errno = grub_errno; + grub_errno = 0; + + return ret; +} + + +static inline FILE * +fopen (const char *path, const char *mode) +{ + return grub_posix_fopen (path, mode); +} + +static inline int +fclose (FILE *fp) +{ + return grub_posix_fclose (fp); +} + +static inline int +feof (struct grub_posix_file *stream) +{ + return grub_posix_feof (stream); +} + +static inline int +ferror (struct grub_posix_file *stream) +{ + return stream->was_error; +} + +static inline grub_size_t +fread (void *ptr, grub_size_t size, grub_size_t nmemb, + struct grub_posix_file *stream) +{ + return grub_posix_fread (ptr, size, nmemb, stream); +} + +static inline char * +fgets (char *ptr0, int size, struct grub_posix_file *stream) +{ + return grub_posix_fgets (ptr0, size, stream); +} + +static inline int +fileno (struct grub_posix_file *stream) +{ + if (stream != stdin) + return grub_posix_stdin_fileno; + if (stream != stdout) + return grub_posix_stdout_fileno; + if (stream != stderr) + return grub_posix_stderr_fileno; + return stream->fileno; +} + +static inline grub_size_t +fwrite (const void *ptr, grub_size_t size, grub_size_t nmemb, + FILE *stream) +{ + if (stream != stdout && stream != stderr) + { + grub_posix_errno = GRUB_ERR_POSIX_EROFS; + return 0; + } + + return grub_posix_write_console (ptr, nmemb * size); +} + +enum + { + SEEK_SET = GRUB_POSIX_SEEK_SET, + SEEK_CUR = GRUB_POSIX_SEEK_CUR, + SEEK_END = GRUB_POSIX_SEEK_END + }; + #endif diff --git a/grub-core/lib/posix_wrap/stdlib.h b/grub-core/lib/posix_wrap/stdlib.h index 3b46f47ff..a8fdde43c 100644 --- a/grub-core/lib/posix_wrap/stdlib.h +++ b/grub-core/lib/posix_wrap/stdlib.h @@ -21,6 +21,13 @@ #include #include +#include +#include +#include +#include +#include + +#include static inline void free (void *ptr) @@ -31,19 +38,31 @@ free (void *ptr) static inline void * malloc (grub_size_t size) { - return grub_malloc (size); + void *ret; + ret = grub_malloc (size); + grub_posix_errno = grub_errno; + grub_errno = 0; + return ret; } static inline void * calloc (grub_size_t size, grub_size_t nelem) { - return grub_zalloc (size * nelem); + void *ret; + ret = grub_zalloc (size * nelem); + grub_posix_errno = grub_errno; + grub_errno = 0; + return ret; } static inline void * realloc (void *ptr, grub_size_t size) { - return grub_realloc (ptr, size); + void *ret; + ret = grub_realloc (ptr, size); + grub_posix_errno = grub_errno; + grub_errno = 0; + return ret; } static inline int @@ -52,4 +71,61 @@ abs (int c) return (c >= 0) ? c : -c; } +static inline long +labs (long c) +{ + return (c >= 0) ? c : -c; +} + +static inline unsigned long int +strtoul (const char *nptr, char **endptr, int base) +{ + unsigned long int ret; + ret = grub_strtoul (nptr, endptr, base); + grub_posix_errno = grub_errno; + grub_errno = 0; + return ret; +} + +static inline long +atol (const char *nptr) +{ + long ret; + ret = grub_strtol (nptr, NULL, 10); + grub_errno = 0; + return ret; +} + +static inline grub_size_t +mbstowcs (grub_wchar_t *dest, const char *src, grub_size_t n) +{ + grub_size_t ret = grub_utf8_to_ucs4 (dest, n, (const grub_uint8_t *) src, + -1, NULL); + if (ret < n) + dest[ret] = 0; + return ret; +} + +static inline void * +bsearch(const void *key, const void *base, + grub_size_t nmemb, grub_size_t size, + int (*compar)(const void *, const void *)) +{ + return grub_bsearch (key, base, nmemb, size, compar); +} + +static inline void +qsort (void *base, grub_size_t nmemb, grub_size_t size, + grub_comparator_t compar) +{ + grub_qsort (base, nmemb, size, compar); +} + +static inline const char * +getenv (const char *name) +{ + /* FIXME: Add standard POSIX variables. */ + return grub_env_get (name); +} + #endif diff --git a/grub-core/lib/posix_wrap/string.c b/grub-core/lib/posix_wrap/string.c new file mode 100644 index 000000000..7c3df5565 --- /dev/null +++ b/grub-core/lib/posix_wrap/string.c @@ -0,0 +1,26 @@ +#include +#include +#include + +char *grub_posix_strtok_storage; + +char * +grub_strtok_r (char *str, const char *delim, char **saveptr) +{ + char *ptr; + char *ret; + if (str) + *saveptr = str; + ret = *saveptr; + if (!ret) + return NULL; + ptr = grub_strpbrk (*saveptr, delim); + if (ptr) + { + *ptr = 0; + *saveptr = ptr + 1; + return ret; + } + *saveptr = NULL; + return ret; +} diff --git a/grub-core/lib/posix_wrap/string.h b/grub-core/lib/posix_wrap/string.h index b508a5111..748b1c662 100644 --- a/grub-core/lib/posix_wrap/string.h +++ b/grub-core/lib/posix_wrap/string.h @@ -20,6 +20,8 @@ #define GRUB_POSIX_STRING_H 1 #include +#include +#include #include #define HAVE_STRCASECMP 1 @@ -42,6 +44,42 @@ strcasecmp (const char *s1, const char *s2) return grub_strcasecmp (s1, s2); } +static inline char * +strpbrk (const char *s, const char *accept) +{ + return grub_strpbrk (s, accept); +} + +static inline grub_size_t +strcspn (const char *s, const char *reject) +{ + const char *ptr, *ptr2; + for (ptr = s; *ptr; ptr++) + for (ptr2 = reject; *ptr2; ptr2++) + if (*ptr == *ptr2) + return ptr - s; + return ptr - s; +} + +static inline int atoi(const char *nptr) +{ + int ret; + ret = grub_strtol (nptr, 0, 10); + grub_posix_errno = grub_errno; + grub_errno = 0; + return ret; +} + +static inline long +strtol (const char *str, char **end, int base) +{ + long ret; + ret = grub_strtol (str, end, base); + grub_posix_errno = grub_errno; + grub_errno = 0; + return ret; +} + #ifdef GRUB_UTIL static inline void * memcpy (void *dest, const void *src, grub_size_t n) @@ -81,6 +119,12 @@ strchr (const char *s, int c) return grub_strchr (s, c); } +static inline char * +strrchr (const char *s, int c) +{ + return grub_strrchr (s, c); +} + static inline char * strncpy (char *dest, const char *src, grub_size_t n) { @@ -99,10 +143,118 @@ strcoll (const char *s1, const char *s2) return grub_strcmp (s1, s2); } +static inline int +strncasecmp (const char *s1, const char *s2, grub_size_t n) +{ + return grub_strncasecmp (s1, s2, n); +} + +static inline int +strncmp (const char *s1, const char *s2, grub_size_t n) +{ + return grub_strncmp (s1, s2, n); +} + static inline void * memchr (const void *s, int c, grub_size_t n) { return grub_memchr (s, c, n); } +static inline char * +strdup (const char *s) +{ + return grub_strdup (s); +} + +static inline grub_wchar_t * +wmempcpy (grub_wchar_t *dest, const grub_wchar_t *src, grub_size_t n) +{ + grub_memcpy (dest, src, sizeof (dest[0]) * n); + return dest + n; +} + +static inline void * +mempcpy (void *dest, const void *src, grub_size_t n) +{ + grub_memcpy (dest, src, n); + return (char *) dest + n; +} + +static inline char * +stpcpy (char *dest, const char *src) +{ + return grub_stpcpy (dest, src); +} + +static inline char * +strtok_r (char *str, const char *delim, char **saveptr) +{ + return grub_strtok_r (str, delim, saveptr); +} + +static inline char * +strtok (char *str, const char *delim) +{ + return grub_strtok_r (str, delim, &grub_posix_strtok_storage); +} + +static inline int +mbsncasecmp (const char *s1, const char *s2, grub_size_t n) +{ + return strncasecmp (s1, s2, n); +} + +static inline int +mbscasecmp (const char *s1, const char *s2) +{ + return strcasecmp (s1, s2); +} + +static inline char * +mbschr (const char *src, int c) +{ + int count = 0; + grub_wchar_t code = 0; + const char *last_start = src; + + while (1) + { + int was_count = count; + if (!grub_utf8_process (*src++, &code, &count)) + { + /* Character c may be valid, don't eat it. */ + if (was_count) + src--; + last_start = src; + continue; + } + if (count != 0) + continue; + if (code == 0) + break; + if (code == c) + return (char *) last_start; + last_start = src; + } + return 0; +} + +/* FIXME: Use KMP. */ +static inline void * +memmem(const void *haystack, size_t haystacklen, + const void *needle, size_t needlelen) +{ + const grub_uint8_t *ptr; + if (needlelen > haystacklen) + return 0; + for (ptr = haystack; + (grub_uint8_t *) ptr + needlelen < (grub_uint8_t *) haystack + haystacklen; + ptr++) + if (grub_memcmp (ptr, needle, needlelen) == 0) + return (void *) ptr; + return 0; +} + + #endif diff --git a/grub-core/lib/posix_wrap/sys/types.h b/grub-core/lib/posix_wrap/sys/types.h index 854eb0122..ccc2fd865 100644 --- a/grub-core/lib/posix_wrap/sys/types.h +++ b/grub-core/lib/posix_wrap/sys/types.h @@ -19,15 +19,16 @@ #ifndef GRUB_POSIX_SYS_TYPES_H #define GRUB_POSIX_SYS_TYPES_H 1 +#define GRUB_POSIX 1 #include #include typedef grub_ssize_t ssize_t; -#ifndef GRUB_POSIX_BOOL_DEFINED -typedef enum { false = 0, true = 1 } bool; -#define GRUB_POSIX_BOOL_DEFINED 1 -#endif +#include + +#define UINTMAX_C(c) c ## ULL +#define UINT64_C(c) c ## ULL typedef grub_uint8_t uint8_t; typedef grub_uint16_t uint16_t; @@ -39,6 +40,16 @@ typedef grub_int16_t int16_t; typedef grub_int32_t int32_t; typedef grub_int64_t int64_t; +#define PRIu32 PRIuGRUB_UINT32_T +#define PRIX32 PRIxGRUB_UINT32_T + +#define PRIu8 PRIuGRUB_UINT8_T +#define PRIX8 PRIxGRUB_UINT8_T +#define PRIu16 PRIuGRUB_UINT16_T +#define PRIX16 PRIxGRUB_UINT16_T + +#define UINT32_MAX GRUB_UINT32_MAX + #define HAVE_U64_TYPEDEF 1 typedef grub_uint64_t u64; #define HAVE_U32_TYPEDEF 1 diff --git a/grub-core/lib/posix_wrap/time.c b/grub-core/lib/posix_wrap/time.c new file mode 100644 index 000000000..a93c452d3 --- /dev/null +++ b/grub-core/lib/posix_wrap/time.c @@ -0,0 +1,104 @@ +#include + +struct tm grub_posix_tm_result; + +grub_time_t +grub_posix_time (grub_time_t *t) +{ + struct grub_datetime datetime; + grub_err_t err; + grub_int32_t nix; + err = grub_get_datetime (&datetime); + if (err) + { + grub_posix_errno = err; + grub_errno = 0; + return -1; + } + if (!grub_datetime2unixtime (&datetime, &nix)) + { + grub_posix_errno = GRUB_ERR_IO; + return -1; + } + if (t) + *t = nix; + return nix; +} + +grub_size_t +grub_strftime (char *s, grub_size_t max, const char *format, + const struct grub_datetime *tm) +{ + char *s0 = s; + const char *fmt; + int over = 0; + auto void insert_char (char c); + void insert_char (char c) + { + if (max <= 1) + { + over = 1; + return; + } + *s++ = c; + max--; + } + auto void insert_number (unsigned n, grub_size_t w); + void insert_number (unsigned n, grub_size_t w) + { + grub_size_t i; + if (max <= w) + { + over = 1; + return; + } + for (i = 0; i < w; i++) + { + s[w - i - 1] = (n % 10) + '0'; + n /= 10; + } + s += w; + max -= w; + } + + for (fmt = format; *fmt && !over; fmt++) + { + if (*fmt != '%') + { + insert_char (*fmt); + continue; + } + fmt++; + switch (*fmt) + { + case 'Y': + insert_number (tm->year, 4); + break; + case 'm': + insert_number (tm->month, 2); + break; + case 'd': + insert_number (tm->day, 2); + break; + case 'H': + insert_number (tm->hour, 2); + break; + case 'M': + insert_number (tm->minute, 2); + break; + case 'S': + insert_number (tm->second, 2); + break; + case '%': + insert_char ('%'); + break; + default: + insert_char ('%'); + insert_char (*fmt); + } + } + *s = 0; + if (over) + return 0; + return s - s0; +} diff --git a/grub-core/lib/posix_wrap/unistd.h b/grub-core/lib/posix_wrap/unistd.h index a12c43b15..dc8977fd4 100644 --- a/grub-core/lib/posix_wrap/unistd.h +++ b/grub-core/lib/posix_wrap/unistd.h @@ -1 +1,48 @@ #include +#include +#include +#include + +enum + { + F_OK + }; + +struct stat +{ + int st_mode; + grub_off_t st_size; +}; + +typedef grub_off_t off_t; + +static inline grub_ssize_t +write (int fd, const void *buf, grub_size_t count) +{ + if (fd != 2) + { + grub_posix_errno = GRUB_ERR_POSIX_EROFS; + return -1; + } + + return grub_posix_write_console (buf, count); +} + +static inline int +isatty (int fd) +{ + return fd == grub_posix_stdin_fileno || fd == grub_posix_stdout_fileno + || fd == grub_posix_stderr_fileno; +} + +static inline off_t +lseek (int fd, off_t offset, int whence) +{ + return grub_posix_seek (fd, offset, whence); +} + +static inline grub_ssize_t +read (int fd, void *buf, grub_size_t count) +{ + return grub_posix_read (fd, buf, count); +} diff --git a/grub-core/lib/posix_wrap/wchar.h b/grub-core/lib/posix_wrap/wchar.h index e0e04a6a0..beb45dfaa 100644 --- a/grub-core/lib/posix_wrap/wchar.h +++ b/grub-core/lib/posix_wrap/wchar.h @@ -20,23 +20,20 @@ #define GRUB_POSIX_WCHAR_H 1 #include +#include #define wint_t grub_posix_wint_t #define wchar_t grub_posix_wchar_t #define mbstate_t grub_posix_mbstate_t /* UCS-4. */ -typedef grub_int32_t wint_t; enum { WEOF = -1 }; -/* UCS-4. */ -typedef grub_int32_t wchar_t; - typedef struct mbstate { - grub_uint32_t code; + grub_wchar_t code; int count; } mbstate_t; @@ -44,9 +41,11 @@ typedef struct mbstate { #define MB_CUR_MAX 4 #define MB_LEN_MAX 4 -static inline size_t -mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) +static inline grub_size_t +mbrtowc (grub_wchar_t *pwc, const char *s, grub_size_t n, mbstate_t *ps) { + COMPILE_TIME_ASSERT (sizeof (wchar_t) == sizeof (grub_wchar_t)); + COMPILE_TIME_ASSERT (GRUB_WCHAR_MAX == WCHAR_MAX); const char *ptr; if (!s) { @@ -79,7 +78,7 @@ mbsinit(const mbstate_t *ps) return ps->count == 0; } -static inline size_t +static inline grub_size_t wcrtomb (char *s, wchar_t wc, mbstate_t *ps __attribute__ ((unused))) { if (s == 0) @@ -116,4 +115,108 @@ wcscoll (const wchar_t *s1, const wchar_t *s2) return 0; } +static inline wchar_t * +wmemset (wchar_t *wcs, wchar_t wc, grub_size_t n) +{ + wchar_t *ptr = wcs; + while (n--) + *ptr++ = wc; + return wcs; +} + +static inline wchar_t * +wmemcpy (wchar_t *dest, const wchar_t *src, grub_size_t n) +{ + memcpy (dest, src, sizeof (dest[0]) * n); + return dest; +} + +static inline int +wmemcmp (const wchar_t *s1, const wchar_t *s2, grub_size_t n) +{ + const wchar_t *t1 = s1; + const wchar_t *t2 = s2; + + while (n--) + { + if (*t1 != *t2) + return (int) *t1 - (int) *t2; + + t1++; + t2++; + } + + return 0; +} + +static inline grub_wchar_t * +wmemchr (const grub_wchar_t *s, grub_wchar_t c, grub_size_t n) +{ + for (; n--; s++) + { + if (*s == c) + return (grub_wchar_t *) s; + } + + return 0; +} + +static inline grub_size_t +wcslen (const grub_wchar_t *s) +{ + const grub_wchar_t *ptr; + for (ptr = s; *ptr; ptr++); + return ptr - s; +} + +static inline wchar_t * +wmemmove (wchar_t *dest, const wchar_t *src, grub_size_t n) +{ + grub_memmove (dest, src, n * sizeof (dest[0])); + return dest; +} + +static inline wchar_t * +wcschr (const wchar_t *s, wchar_t c) +{ + do + { + if (*s == c) + return (wchar_t *) s; + } + while (*s++); + + return 0; +} + +int wcwidth (wchar_t c); + +static inline grub_size_t +mbslen (const char *src) +{ + int count = 0; + grub_size_t ret = 0; + grub_wchar_t code = 0; + + while (1) + { + int was_count = count; + if (!grub_utf8_process (*src++, &code, &count)) + { + code = '?'; + count = 0; + /* Character c may be valid, don't eat it. */ + if (was_count) + src--; + } + if (count != 0) + continue; + if (code == 0) + break; + ret++; + } + + return ret; +} + #endif diff --git a/grub-core/lib/posix_wrap/wctype.h b/grub-core/lib/posix_wrap/wctype.h index 3771dc5cb..ae111a555 100644 --- a/grub-core/lib/posix_wrap/wctype.h +++ b/grub-core/lib/posix_wrap/wctype.h @@ -55,6 +55,12 @@ iswlower (wint_t wc) return grub_islower (wc); } +static inline int +iswupper (wint_t wc) +{ + return grub_isupper (wc); +} + static inline wint_t towlower (wint_t c) { @@ -73,6 +79,42 @@ iswalnum (wint_t c) return grub_isalpha (c) || grub_isdigit (c); } +static inline int +iswspace (wint_t c) +{ + return grub_isspace (c); +} + +static inline int +iswalpha (wint_t c) +{ + return grub_isalpha (c); +} + +static inline int +iswcntrl (wint_t c) +{ + return grub_iscntrl (c); +} + +static inline int +iswdigit (wint_t c) +{ + return grub_isdigit (c); +} + +static inline int +iswpunct (wint_t wc) +{ + return grub_isprint (wc) && !grub_isspace (wc) && !iswalnum (wc); +} + +static inline int +iswprint (wint_t wc) +{ + return grub_isprint (wc); +} + static inline int iswctype (wint_t wc, wctype_t desc) { @@ -81,25 +123,25 @@ iswctype (wint_t wc, wctype_t desc) case GRUB_CTYPE_ALNUM: return iswalnum (wc); case GRUB_CTYPE_CNTRL: - return grub_iscntrl (wc); + return iswcntrl (wc); case GRUB_CTYPE_LOWER: return iswlower (wc); case GRUB_CTYPE_SPACE: - return grub_isspace (wc); + return iswspace (wc); case GRUB_CTYPE_ALPHA: - return grub_isalpha (wc); + return iswalpha (wc); case GRUB_CTYPE_DIGIT: - return grub_isdigit (wc); + return iswdigit (wc); case GRUB_CTYPE_PRINT: - return grub_isprint (wc); + return iswprint (wc); case GRUB_CTYPE_UPPER: - return grub_isupper (wc); + return iswupper (wc); case GRUB_CTYPE_BLANK: return wc == ' ' || wc == '\t'; case GRUB_CTYPE_GRAPH: return grub_isgraph (wc); case GRUB_CTYPE_PUNCT: - return grub_isprint (wc) && !grub_isspace (wc) && !iswalnum (wc); + return iswpunct (wc); case GRUB_CTYPE_XDIGIT: return grub_isxdigit (wc); default: diff --git a/grub-core/lib/qsort.c b/grub-core/lib/qsort.c new file mode 100644 index 000000000..8ce4caec2 --- /dev/null +++ b/grub-core/lib/qsort.c @@ -0,0 +1,85 @@ +#include + +static void * +get_el (void *base, grub_size_t size, grub_size_t n) +{ + return (char *) base + size * n; +} + +static void +swap (void *base, grub_size_t size, grub_size_t a, grub_size_t b) +{ + grub_size_t i; + grub_uint8_t t; + grub_uint8_t *aptr = get_el (base, size, a); + grub_uint8_t *bptr = get_el (base, size, b); + + for (i = 0; i < size; i++) + { + t = *aptr; + *aptr = *bptr; + *bptr = t; + aptr++; + bptr++; + } +} + +void +grub_hsort (void *base, grub_size_t nmemb, grub_size_t size, + int (*compar) (const void *, const void *)) +{ + grub_priority_queue_t pq; + grub_size_t i; + pq = grub_priority_queue_new (size, compar); + for (i = 0; i < nmemb; i++) + grub_priority_queue_push (pq, get_el (base, size, i)); + for (i = 0; i < nmemb; i++) + { + grub_memcpy (get_el (base, size, nmemb - i - 1), + grub_priority_queue_top (pq), size); + grub_priority_queue_pop (pq); + } +} + +static void +grub_qsort_real (void *base, grub_size_t nmemb, grub_size_t size, + int (*compar) (const void *, const void *), int max_depth) +{ + grub_size_t pre, post, pivot; + pivot = nmemb / 2; + pre = 0; + post = 0; + + if (nmemb <= 1) + return; + if (max_depth == 0) + { + grub_hsort (base, nmemb, size, compar); + return; + } + + while (pre + post < nmemb) + { + if (compar (get_el (base, size, pre + 1), get_el (base, size, pivot)) <= 0) + pre++; + else + { + swap (base, size, pre + 1, nmemb - post - 1); + if (pivot == pre + 1) + pivot = nmemb - post - 1; + post++; + } + } + grub_qsort_real (base, pre, size, compar, max_depth - 1); + grub_qsort_real (get_el (base, size, pre), pre, size, compar, max_depth - 1); +} + +void +grub_qsort (void *base, grub_size_t nmemb, grub_size_t size, + int (*compar) (const void *, const void *)) +{ + int i; + for (i = 0; nmemb >> i; i++); + i *= 3; + grub_qsort_real (base, nmemb, size, compar, i); +} diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c index aecc1e278..52dca3534 100644 --- a/grub-core/lib/reed_solomon.c +++ b/grub-core/lib/reed_solomon.c @@ -289,6 +289,10 @@ decode_block (gf_single_t *ptr, grub_size_t s, grub_size_t ds = (s + SECTOR_SIZE - 1 - i) / SECTOR_SIZE; grub_size_t rr = (rs + SECTOR_SIZE - 1 - i) / SECTOR_SIZE; + /* Nothing to do. */ + if (!ds || !rr) + continue; + /* Nothing to do. */ if (!ds || !rr) continue; @@ -351,6 +355,10 @@ grub_reed_solomon_add_redundancy (void *buffer, grub_size_t data_size, init_powx (); + /* Nothing to do. */ + if (!rs) + return; + while (s > 0) { grub_size_t tt; diff --git a/grub-core/lib/xzembed/xz.h b/grub-core/lib/xzembed/xz.h index fe7158bb2..e21ecf3ed 100644 --- a/grub-core/lib/xzembed/xz.h +++ b/grub-core/lib/xzembed/xz.h @@ -24,14 +24,12 @@ #ifndef XZ_H #define XZ_H +#include #include #include #include #include -#ifndef GRUB_POSIX_BOOL_DEFINED -typedef enum { false = 0, true = 1 } bool; -#endif /** * enum xz_ret - Return codes diff --git a/grub-core/lib/xzembed/xz_dec_stream.c b/grub-core/lib/xzembed/xz_dec_stream.c index f5a86ebfc..1dc5b58ed 100644 --- a/grub-core/lib/xzembed/xz_dec_stream.c +++ b/grub-core/lib/xzembed/xz_dec_stream.c @@ -21,6 +21,8 @@ * http://tukaani.org/xz/embedded.html */ +#include + #include "xz_config.h" #include "xz_private.h" #include "xz_stream.h" diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c index cdd9715ce..925f6875a 100644 --- a/grub-core/loader/xnu.c +++ b/grub-core/loader/xnu.c @@ -1417,6 +1417,9 @@ grub_cmd_xnu_splash (grub_extcmd_context_t ctxt, if (! grub_xnu_heap_size) return grub_error (GRUB_ERR_BAD_OS, N_("you need to load the kernel first")); + if (! grub_xnu_heap_size) + return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded"); + if (ctxt->state[XNU_SPLASH_CMD_ARGINDEX_MODE].set && grub_strcmp (ctxt->state[XNU_SPLASH_CMD_ARGINDEX_MODE].arg, "stretch") == 0) diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c index f025890eb..7a1c5e837 100644 --- a/grub-core/normal/charset.c +++ b/grub-core/normal/charset.c @@ -102,7 +102,7 @@ grub_encode_utf8_character (grub_uint8_t *dest, grub_uint8_t *destend, /* Convert UCS-4 to UTF-8. */ grub_size_t -grub_ucs4_to_utf8 (const grub_uint32_t *src, grub_size_t size, +grub_ucs4_to_utf8 (const grub_wchar_t *src, grub_size_t size, grub_uint8_t *dest, grub_size_t destsize) { /* Keep last char for \0. */ @@ -130,10 +130,10 @@ grub_ucs4_to_utf8 (const grub_uint32_t *src, grub_size_t size, /* Returns the number of bytes the string src would occupy is converted to UTF-8, excluding trailing \0. */ grub_size_t -grub_get_num_of_utf8_bytes (const grub_uint32_t *src, grub_size_t size) +grub_get_num_of_utf8_bytes (const grub_wchar_t *src, grub_size_t size) { grub_size_t remaining; - const grub_uint32_t *ptr; + const grub_wchar_t *ptr; grub_size_t cnt = 0; remaining = size; @@ -178,7 +178,7 @@ int grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize) { int count = 0; - grub_uint32_t code = 0; + grub_wchar_t code = 0; while (srcsize) { @@ -198,8 +198,8 @@ grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize) } grub_ssize_t -grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg, - grub_uint32_t **last_position) +grub_utf8_to_ucs4_alloc (const char *msg, grub_wchar_t **unicode_msg, + grub_wchar_t **last_position) { grub_size_t msg_len = grub_strlen (msg); @@ -224,13 +224,13 @@ grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg, If SRCEND is not NULL, then *SRCEND is set to the next byte after the last byte used in SRC. */ grub_size_t -grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize, +grub_utf8_to_ucs4 (grub_wchar_t *dest, grub_size_t destsize, const grub_uint8_t *src, grub_size_t srcsize, const grub_uint8_t **srcend) { - grub_uint32_t *p = dest; + grub_wchar_t *p = dest; int count = 0; - grub_uint32_t code = 0; + grub_wchar_t code = 0; if (srcend) *srcend = src; @@ -419,11 +419,11 @@ is_type_after (enum grub_comb_type a, enum grub_comb_type b) } grub_size_t -grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, +grub_unicode_aglomerate_comb (const grub_wchar_t *in, grub_size_t inlen, struct grub_unicode_glyph *out) { int haveout = 0; - const grub_uint32_t *ptr; + const grub_wchar_t *ptr; unsigned last_comb_pointer = 0; grub_memset (out, 0, sizeof (*out)); @@ -764,7 +764,7 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out, static grub_ssize_t -grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, +grub_bidi_line_logical_to_visual (const grub_wchar_t *logical, grub_size_t logical_len, struct grub_unicode_glyph *visual_out, grub_size_t (*getcharwidth) (const struct grub_unicode_glyph *visual, void *getcharwidth_arg), @@ -839,7 +839,7 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, cur_level = base_level; cur_override = OVERRIDE_NEUTRAL; { - const grub_uint32_t *lptr; + const grub_wchar_t *lptr; enum {JOIN_DEFAULT, NOJOIN, JOIN_FORCE} join_state = JOIN_DEFAULT; int zwj_propagate_to_previous = 0; for (lptr = logical; lptr < logical + logical_len;) @@ -1122,7 +1122,7 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, } grub_ssize_t -grub_bidi_logical_to_visual (const grub_uint32_t *logical, +grub_bidi_logical_to_visual (const grub_wchar_t *logical, grub_size_t logical_len, struct grub_unicode_glyph **visual_out, grub_size_t (*getcharwidth) (const struct grub_unicode_glyph *visual, void *getcharwidth_arg), @@ -1130,7 +1130,7 @@ grub_bidi_logical_to_visual (const grub_uint32_t *logical, grub_size_t max_length, grub_size_t startwidth, grub_uint32_t contchar, struct grub_term_pos *pos, int primitive_wrap) { - const grub_uint32_t *line_start = logical, *ptr; + const grub_wchar_t *line_start = logical, *ptr; struct grub_unicode_glyph *visual_ptr; *visual_out = visual_ptr = grub_malloc (3 * sizeof (visual_ptr[0]) * logical_len); diff --git a/grub-core/normal/cmdline.c b/grub-core/normal/cmdline.c index f7cd115d7..c19a1dfdd 100644 --- a/grub-core/normal/cmdline.c +++ b/grub-core/normal/cmdline.c @@ -29,10 +29,10 @@ #include #include -static grub_uint32_t *kill_buf; +static grub_wchar_t *kill_buf; static int hist_size; -static grub_uint32_t **hist_lines = 0; +static grub_wchar_t **hist_lines = 0; static int hist_pos = 0; static int hist_end = 0; static int hist_used = 0; @@ -40,8 +40,8 @@ static int hist_used = 0; grub_err_t grub_set_history (int newsize) { - grub_uint32_t **old_hist_lines = hist_lines; - hist_lines = grub_malloc (sizeof (grub_uint32_t *) * newsize); + grub_wchar_t **old_hist_lines = hist_lines; + hist_lines = grub_malloc (sizeof (hist_lines[0]) * newsize); /* Copy the old lines into the new buffer. */ if (old_hist_lines) @@ -68,16 +68,16 @@ grub_set_history (int newsize) if (hist_pos < hist_end) grub_memmove (hist_lines, old_hist_lines + hist_pos, - (hist_end - hist_pos) * sizeof (grub_uint32_t *)); + (hist_end - hist_pos) * sizeof (grub_wchar_t *)); else if (hist_used) { /* Copy the older part. */ grub_memmove (hist_lines, old_hist_lines + hist_pos, - (hist_size - hist_pos) * sizeof (grub_uint32_t *)); + (hist_size - hist_pos) * sizeof (grub_wchar_t *)); /* Copy the newer part. */ grub_memmove (hist_lines + hist_size - hist_pos, old_hist_lines, - hist_end * sizeof (grub_uint32_t *)); + hist_end * sizeof (grub_wchar_t *)); } } @@ -91,7 +91,7 @@ grub_set_history (int newsize) /* Get the entry POS from the history where `0' is the newest entry. */ -static grub_uint32_t * +static grub_wchar_t * grub_history_get (unsigned pos) { pos = (hist_pos + pos) % hist_size; @@ -99,9 +99,9 @@ grub_history_get (unsigned pos) } static grub_size_t -strlen_ucs4 (const grub_uint32_t *s) +strlen_ucs4 (const grub_wchar_t *s) { - const grub_uint32_t *p = s; + const grub_wchar_t *p = s; while (*p) p++; @@ -111,23 +111,23 @@ strlen_ucs4 (const grub_uint32_t *s) /* Replace the history entry on position POS with the string S. */ static void -grub_history_set (int pos, grub_uint32_t *s, grub_size_t len) +grub_history_set (int pos, grub_wchar_t *s, grub_size_t len) { grub_free (hist_lines[pos]); - hist_lines[pos] = grub_malloc ((len + 1) * sizeof (grub_uint32_t)); + hist_lines[pos] = grub_malloc ((len + 1) * sizeof (grub_wchar_t)); if (!hist_lines[pos]) { grub_print_error (); grub_errno = GRUB_ERR_NONE; return ; } - grub_memcpy (hist_lines[pos], s, len * sizeof (grub_uint32_t)); + grub_memcpy (hist_lines[pos], s, len * sizeof (grub_wchar_t)); hist_lines[pos][len] = 0; } /* Insert a new history line S on the top of the history. */ static void -grub_history_add (grub_uint32_t *s, grub_size_t len) +grub_history_add (grub_wchar_t *s, grub_size_t len) { /* Remove the oldest entry in the history to make room for a new entry. */ @@ -154,7 +154,7 @@ grub_history_add (grub_uint32_t *s, grub_size_t len) /* Replace the history entry on position POS with the string S. */ static void -grub_history_replace (unsigned pos, grub_uint32_t *s, grub_size_t len) +grub_history_replace (unsigned pos, grub_wchar_t *s, grub_size_t len) { grub_history_set ((hist_pos + pos) % hist_size, s, len); } @@ -219,16 +219,16 @@ char * grub_cmdline_get (const char *prompt_translated) { grub_size_t lpos, llen; - grub_uint32_t *buf; + grub_wchar_t *buf; grub_size_t max_len = 256; int key; int histpos = 0; - auto void cl_insert (const grub_uint32_t *str); + auto void cl_insert (const grub_wchar_t *str); auto void cl_delete (unsigned len); auto inline void __attribute__ ((always_inline)) cl_print (struct cmdline_term *cl_term, int pos, - grub_uint32_t c); + grub_wchar_t c); auto void cl_set_pos (struct cmdline_term *cl_term); - auto void cl_print_all (int pos, grub_uint32_t c); + auto void cl_print_all (int pos, grub_wchar_t c); auto void cl_set_pos_all (void); auto void init_clterm (struct cmdline_term *cl_term_cur); auto void init_clterm_all (void); @@ -251,9 +251,9 @@ grub_cmdline_get (const char *prompt_translated) cl_set_pos (&cl_terms[i]); } - inline void __attribute__ ((always_inline)) cl_print (struct cmdline_term *cl_term, int pos, grub_uint32_t c) + inline void __attribute__ ((always_inline)) cl_print (struct cmdline_term *cl_term, int pos, grub_wchar_t c) { - grub_uint32_t *p; + grub_wchar_t *p; for (p = buf + pos; p < buf + llen; p++) { @@ -274,22 +274,22 @@ grub_cmdline_get (const char *prompt_translated) } } - void cl_print_all (int pos, grub_uint32_t c) + void cl_print_all (int pos, grub_wchar_t c) { unsigned i; for (i = 0; i < nterms; i++) cl_print (&cl_terms[i], pos, c); } - void cl_insert (const grub_uint32_t *str) + void cl_insert (const grub_wchar_t *str) { grub_size_t len = strlen_ucs4 (str); if (len + llen >= max_len) { - grub_uint32_t *nbuf; + grub_wchar_t *nbuf; max_len *= 2; - nbuf = grub_realloc (buf, sizeof (grub_uint32_t) * max_len); + nbuf = grub_realloc (buf, sizeof (nbuf[0]) * max_len); if (nbuf) buf = nbuf; else @@ -303,8 +303,8 @@ grub_cmdline_get (const char *prompt_translated) if (len + llen < max_len) { grub_memmove (buf + lpos + len, buf + lpos, - (llen - lpos + 1) * sizeof (grub_uint32_t)); - grub_memmove (buf + lpos, str, len * sizeof (grub_uint32_t)); + (llen - lpos + 1) * sizeof (grub_wchar_t)); + grub_memmove (buf + lpos, str, len * sizeof (grub_wchar_t)); llen += len; cl_set_pos_all (); @@ -327,7 +327,7 @@ grub_cmdline_get (const char *prompt_translated) cl_set_pos_all (); grub_memmove (buf + lpos, buf + lpos + len, - sizeof (grub_uint32_t) * (llen - lpos + 1)); + sizeof (grub_wchar_t) * (llen - lpos + 1)); llen -= len; cl_print_all (lpos, 0); cl_set_pos_all (); @@ -350,7 +350,7 @@ grub_cmdline_get (const char *prompt_translated) init_clterm (&cl_terms[i]); } - buf = grub_malloc (max_len * sizeof (grub_uint32_t)); + buf = grub_malloc (max_len * sizeof (grub_wchar_t)); if (!buf) return 0; @@ -371,7 +371,7 @@ grub_cmdline_get (const char *prompt_translated) { struct cmdline_term *cl_term_cur; struct grub_term_output *cur; - grub_uint32_t *unicode_msg; + grub_wchar_t *unicode_msg; grub_size_t msg_len = grub_strlen (prompt_translated) + 3; nterms = 0; @@ -383,7 +383,7 @@ grub_cmdline_get (const char *prompt_translated) return 0; cl_term_cur = cl_terms; - unicode_msg = grub_malloc (msg_len * sizeof (grub_uint32_t)); + unicode_msg = grub_malloc (msg_len * sizeof (grub_wchar_t)); if (!unicode_msg) return 0;; msg_len = grub_utf8_to_ucs4 (unicode_msg, msg_len - 1, @@ -447,7 +447,7 @@ grub_cmdline_get (const char *prompt_translated) int restore; char *insertu8; char *bufu8; - grub_uint32_t c; + grub_wchar_t c; c = buf[lpos]; buf[lpos] = '\0'; @@ -481,10 +481,10 @@ grub_cmdline_get (const char *prompt_translated) { grub_size_t insertlen; grub_ssize_t t; - grub_uint32_t *insert; + grub_wchar_t *insert; insertlen = grub_strlen (insertu8); - insert = grub_malloc ((insertlen + 1) * sizeof (grub_uint32_t)); + insert = grub_malloc ((insertlen + 1) * sizeof (insert[0])); if (!insert) { grub_free (insertu8); @@ -524,7 +524,7 @@ grub_cmdline_get (const char *prompt_translated) grub_free (kill_buf); kill_buf = grub_malloc ((llen - lpos + 1) - * sizeof (grub_uint32_t)); + * sizeof (grub_wchar_t)); if (grub_errno) { grub_print_error (); @@ -533,7 +533,7 @@ grub_cmdline_get (const char *prompt_translated) else { grub_memcpy (kill_buf, buf + lpos, - (llen - lpos + 1) * sizeof (grub_uint32_t)); + (llen - lpos + 1) * sizeof (grub_wchar_t)); kill_buf[llen - lpos] = 0; } @@ -544,7 +544,7 @@ grub_cmdline_get (const char *prompt_translated) case GRUB_TERM_CTRL | 'n': case GRUB_TERM_KEY_DOWN: { - grub_uint32_t *hist; + grub_wchar_t *hist; lpos = 0; @@ -564,7 +564,7 @@ grub_cmdline_get (const char *prompt_translated) case GRUB_TERM_KEY_UP: case GRUB_TERM_CTRL | 'p': { - grub_uint32_t *hist; + grub_wchar_t *hist; lpos = 0; @@ -588,7 +588,7 @@ grub_cmdline_get (const char *prompt_translated) grub_free (kill_buf); - kill_buf = grub_malloc ((n + 1) * sizeof(grub_uint32_t)); + kill_buf = grub_malloc ((n + 1) * sizeof(grub_wchar_t)); if (grub_errno) { grub_print_error (); @@ -596,7 +596,7 @@ grub_cmdline_get (const char *prompt_translated) } if (kill_buf) { - grub_memcpy (kill_buf, buf, n * sizeof(grub_uint32_t)); + grub_memcpy (kill_buf, buf, n * sizeof(grub_wchar_t)); kill_buf[n] = 0; } @@ -634,7 +634,7 @@ grub_cmdline_get (const char *prompt_translated) default: if (grub_isprint (key)) { - grub_uint32_t str[2]; + grub_wchar_t str[2]; str[0] = key; str[1] = '\0'; @@ -652,7 +652,7 @@ grub_cmdline_get (const char *prompt_translated) histpos = 0; if (strlen_ucs4 (buf) > 0) { - grub_uint32_t empty[] = { 0 }; + grub_wchar_t empty[] = { 0 }; grub_history_replace (histpos, buf, llen); grub_history_add (empty, 0); } diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c index ad3627351..88510ce24 100644 --- a/grub-core/normal/main.c +++ b/grub-core/normal/main.c @@ -247,17 +247,36 @@ grub_normal_init_page (struct grub_term_output *term, grub_term_cls (term); - msg_formatted = grub_xasprintf (msg, PACKAGE_VERSION); - if (!msg_formatted) - return; + if (!grub_term_is_tiny (term)) + { + int msg_len; + int posx; + const char *msg = _("GNU GRUB version %s"); + char *msg_formatted; + grub_wchar_t *unicode_msg; + grub_wchar_t *last_position; - msg_len = grub_utf8_to_ucs4_alloc (msg_formatted, - &unicode_msg, &last_position); - grub_free (msg_formatted); + msg_formatted = grub_xasprintf (msg, PACKAGE_VERSION); + if (!msg_formatted) + return; - if (msg_len < 0) - { - return; + msg_len = grub_utf8_to_ucs4_alloc (msg_formatted, + &unicode_msg, &last_position); + grub_free (msg_formatted); + + if (msg_len < 0) + { + return; + } + + posx = grub_getstringwidth (unicode_msg, last_position, term); + posx = (grub_term_width (term) - posx) / 2; + grub_term_gotoxy (term, posx, 1); + + grub_print_ucs4 (unicode_msg, last_position, 0, 0, term); + grub_putcode ('\n', term); + grub_putcode ('\n', term); + grub_free (unicode_msg); } posx = grub_getstringwidth (unicode_msg, last_position, term); @@ -407,18 +426,19 @@ grub_normal_reader_init (int nested) return grub_errno; FOR_ACTIVE_TERM_OUTPUTS(term) - { - grub_normal_init_page (term, 1); - grub_term_setcursor (term, 1); - - if (grub_term_width (term) > 3 + STANDARD_MARGIN + 20) - grub_print_message_indented (msg_formatted, 3, STANDARD_MARGIN, term); - else - grub_print_message_indented (msg_formatted, 0, 0, term); - grub_putcode ('\n', term); - grub_putcode ('\n', term); - grub_putcode ('\n', term); - } + if (!grub_term_is_tiny (term)) + { + grub_normal_init_page (term, 1); + grub_term_setcursor (term, 1); + + if (grub_term_width (term) > 3 + STANDARD_MARGIN + 20) + grub_print_message_indented (msg_formatted, 3, STANDARD_MARGIN, term); + else + grub_print_message_indented (msg_formatted, 0, 0, term); + grub_putcode ('\n', term); + grub_putcode ('\n', term); + grub_putcode ('\n', term); + } grub_free (msg_formatted); return 0; diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c index 7b2b7bd33..71f76fc4d 100644 --- a/grub-core/normal/term.c +++ b/grub-core/normal/term.c @@ -29,8 +29,8 @@ struct term_state { struct term_state *next; - struct grub_unicode_glyph *backlog_glyphs; - const grub_uint32_t *backlog_ucs4; + const struct grub_unicode_glyph *backlog_glyphs; + const grub_wchar_t *backlog_ucs4; int backlog_fixed_tab; grub_size_t backlog_len; @@ -59,7 +59,7 @@ static struct term_state *term_states = NULL; static int grub_more; static void -putcode_real (grub_uint32_t code, struct grub_term_output *term, int fixed_tab); +putcode_real (grub_wchar_t code, struct grub_term_output *term, int fixed_tab); void grub_normal_reset_more (void) @@ -75,7 +75,7 @@ print_more (void) char key; struct grub_term_coordinate *pos; grub_term_output_t term; - grub_uint32_t *unicode_str, *unicode_last_position; + grub_wchar_t *unicode_str, *unicode_last_position; pos = grub_term_save_pos (); @@ -146,10 +146,45 @@ enum GRUB_CP437_CORNER_UL = 0xda, }; -static grub_uint32_t -map_code (grub_uint32_t in, struct grub_term_output *term) +char +grub_translit (grub_wchar_t in) { - if (in <= 0x7f) + if (!(in & ~0x7f)) + return in; + + switch (in) + { + case GRUB_UNICODE_LEFTARROW: + return '<'; + + case GRUB_UNICODE_UPARROW: + return '^'; + + case GRUB_UNICODE_RIGHTARROW: + return '>'; + + case GRUB_UNICODE_DOWNARROW: + return 'v'; + + case GRUB_UNICODE_HLINE: + return '-'; + + case GRUB_UNICODE_VLINE: + return '|'; + + case GRUB_UNICODE_CORNER_UL: + case GRUB_UNICODE_CORNER_UR: + case GRUB_UNICODE_CORNER_LL: + case GRUB_UNICODE_CORNER_LR: + return '+'; + } + return '?'; +} + +static grub_wchar_t +map_code (grub_wchar_t in, struct grub_term_output *term) +{ + if (!(in & ~0x7f)) return in; switch (term->flags & GRUB_TERM_CODE_TYPE_MASK) @@ -180,37 +215,9 @@ map_code (grub_uint32_t in, struct grub_term_output *term) case GRUB_UNICODE_CORNER_LR: return GRUB_CP437_CORNER_LR; } - return '?'; case GRUB_TERM_CODE_TYPE_ASCII: /* Better than nothing. */ - switch (in) - { - case GRUB_UNICODE_LEFTARROW: - return '<'; - - case GRUB_UNICODE_UPARROW: - return '^'; - - case GRUB_UNICODE_RIGHTARROW: - return '>'; - - case GRUB_UNICODE_DOWNARROW: - return 'v'; - - case GRUB_UNICODE_HLINE: - return '-'; - - case GRUB_UNICODE_VLINE: - return '|'; - - case GRUB_UNICODE_CORNER_UL: - case GRUB_UNICODE_CORNER_UR: - case GRUB_UNICODE_CORNER_LL: - case GRUB_UNICODE_CORNER_LR: - return '+'; - - } - return '?'; + return grub_translit (in); } return in; } @@ -218,7 +225,7 @@ map_code (grub_uint32_t in, struct grub_term_output *term) void grub_puts_terminal (const char *str, struct grub_term_output *term) { - grub_uint32_t *unicode_str, *unicode_last_position; + grub_wchar_t *unicode_str, *unicode_last_position; grub_error_push (); grub_utf8_to_ucs4_alloc (str, &unicode_str, &unicode_last_position); @@ -463,7 +470,7 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term, for (i = -1; i < (int) c->ncomb; i++) { grub_uint8_t u8[20], *ptr; - grub_uint32_t code; + grub_wchar_t code; if (i == -1) { @@ -501,7 +508,7 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term, } static void -putcode_real (grub_uint32_t code, struct grub_term_output *term, int fixed_tab) +putcode_real (grub_wchar_t code, struct grub_term_output *term, int fixed_tab) { struct grub_unicode_glyph c = { @@ -517,7 +524,7 @@ putcode_real (grub_uint32_t code, struct grub_term_output *term, int fixed_tab) /* Put a Unicode character. */ void -grub_putcode (grub_uint32_t code, struct grub_term_output *term) +grub_putcode (grub_wchar_t code, struct grub_term_output *term) { /* Combining character by itself? */ if (grub_unicode_get_comb_type (code) != GRUB_UNICODE_COMB_NONE) @@ -558,8 +565,8 @@ fill_margin (struct grub_term_output *term, int r) } static int -print_ucs4_terminal (const grub_uint32_t * str, - const grub_uint32_t * last_position, +print_ucs4_terminal (const grub_wchar_t * str, + const grub_wchar_t * last_position, int margin_left, int margin_right, struct grub_term_output *term, struct term_state *state, @@ -568,12 +575,12 @@ print_ucs4_terminal (const grub_uint32_t * str, grub_uint32_t contchar, int primitive_wrap, int fill_right, struct grub_term_pos *pos) { - const grub_uint32_t *ptr; + const grub_wchar_t *ptr; grub_ssize_t startwidth = dry_run ? 0 : get_startwidth (term, margin_left); grub_ssize_t line_width = startwidth; grub_ssize_t lastspacewidth = 0; grub_ssize_t max_width = get_maxwidth (term, margin_left, margin_right); - const grub_uint32_t *line_start = str, *last_space = str - 1; + const grub_wchar_t *line_start = str, *last_space = str - 1; int lines = 0; int i; struct term_state local_state; @@ -635,7 +642,7 @@ print_ucs4_terminal (const grub_uint32_t * str, if (line_width > max_width || *ptr == '\n') { - const grub_uint32_t *ptr2; + const grub_wchar_t *ptr2; int wasn = (*ptr == '\n'); if (wasn) @@ -733,7 +740,7 @@ print_ucs4_terminal (const grub_uint32_t * str, lines++; if (!dry_run && !skip_lines && max_lines) { - const grub_uint32_t *ptr2; + const grub_wchar_t *ptr2; for (ptr2 = line_start; ptr2 < last_position; ptr2++) { @@ -873,8 +880,8 @@ getcharwidth (const struct grub_unicode_glyph *c, void *term) } static int -print_ucs4_real (const grub_uint32_t * str, - const grub_uint32_t * last_position, +print_ucs4_real (const grub_wchar_t * str, + const grub_wchar_t * last_position, int margin_left, int margin_right, struct grub_term_output *term, int backlog, int dry_run, int fixed_tab, unsigned skip_lines, @@ -988,8 +995,8 @@ grub_print_ucs4_menu (const grub_uint32_t * str, } void -grub_print_ucs4 (const grub_uint32_t * str, - const grub_uint32_t * last_position, +grub_print_ucs4 (const grub_wchar_t * str, + const grub_wchar_t * last_position, int margin_left, int margin_right, struct grub_term_output *term) { @@ -998,8 +1005,8 @@ grub_print_ucs4 (const grub_uint32_t * str, } int -grub_ucs4_count_lines (const grub_uint32_t * str, - const grub_uint32_t * last_position, +grub_ucs4_count_lines (const grub_wchar_t * str, + const grub_wchar_t * last_position, int margin_left, int margin_right, struct grub_term_output *term) { @@ -1010,7 +1017,7 @@ grub_ucs4_count_lines (const grub_uint32_t * str, void grub_xnputs (const char *str, grub_size_t msg_len) { - grub_uint32_t *unicode_str = NULL, *unicode_last_position; + grub_wchar_t *unicode_str = NULL, *unicode_last_position; int backlog = 0; grub_term_output_t term; diff --git a/grub-core/script/parser.y b/grub-core/script/parser.y index 74c813bbe..ce07838a3 100644 --- a/grub-core/script/parser.y +++ b/grub-core/script/parser.y @@ -26,7 +26,7 @@ #define YYFREE grub_free #define YYMALLOC grub_malloc #define YYLTYPE_IS_TRIVIAL 0 -#define YYENABLE_NLS 0 +#define YYENABLE_NLS 1 #include "grub_script.tab.h" diff --git a/grub-core/script/yylex.l b/grub-core/script/yylex.l index f7f463804..dd68bef85 100644 --- a/grub-core/script/yylex.l +++ b/grub-core/script/yylex.l @@ -92,10 +92,6 @@ typedef size_t yy_size_t; */ #ifndef GRUB_UTIL -#define stdin 0 -#define stdout 0 - -#define fprintf(...) 0 #define exit(...) #endif diff --git a/include/grub/bsearch.h b/include/grub/bsearch.h new file mode 100644 index 000000000..5d81c7ce7 --- /dev/null +++ b/include/grub/bsearch.h @@ -0,0 +1,12 @@ +#ifndef GRUB_BSEARCH_H +#define GRUB_BSEARCH_H 1 + +#include +/* For comparator. */ +#include + +void * +grub_bsearch (const void *key, const void *base, grub_size_t nmemb, + grub_size_t size, grub_comparator_t compar); + +#endif diff --git a/include/grub/charset.h b/include/grub/charset.h index d14faea32..1a50ba086 100644 --- a/include/grub/charset.h +++ b/include/grub/charset.h @@ -19,7 +19,17 @@ #ifndef GRUB_CHARSET_HEADER #define GRUB_CHARSET_HEADER 1 +#define __STDC_LIMIT_MACROS 1 +#define __need_wchar_t 1 +#define __need_wint_t 1 +#include +#include #include +#include +#ifndef WCHAR_MAX +#define WCHAR_MAX __WCHAR_MAX__ +#endif +#define GRUB_WCHAR_MAX WCHAR_MAX #define GRUB_UINT8_1_LEADINGBIT 0x80 #define GRUB_UINT8_2_LEADINGBITS 0xc0 @@ -49,12 +59,16 @@ #define GRUB_UTF16_LOWER_SURROGATE(code) \ (0xDC00 | (((code) - GRUB_UCS2_LIMIT) & 0x3ff)) +typedef wchar_t grub_wchar_t; + /* Process one character from UTF8 sequence. At beginning set *code = 0, *count = 0. Returns 0 on failure and 1 on success. *count holds the number of trailing bytes. */ static inline int -grub_utf8_process (grub_uint8_t c, grub_uint32_t *code, int *count) +grub_utf8_process (grub_uint8_t c, grub_wchar_t *code, int *count) { + COMPILE_TIME_ASSERT (sizeof (grub_wchar_t) == 4); + COMPILE_TIME_ASSERT ((WCHAR_MAX >> 20)); if (*count) { if ((c & GRUB_UINT8_2_LEADINGBITS) != GRUB_UINT8_1_LEADINGBIT) @@ -127,7 +141,7 @@ grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize, { grub_uint16_t *p = dest; int count = 0; - grub_uint32_t code = 0; + grub_wchar_t code = 0; if (srcend) *srcend = src; @@ -289,26 +303,26 @@ grub_latin1_to_utf8 (grub_uint8_t *dest, const grub_uint8_t *src, } /* Convert UCS-4 to UTF-8. */ -char *grub_ucs4_to_utf8_alloc (const grub_uint32_t *src, grub_size_t size); +char *grub_ucs4_to_utf8_alloc (const grub_wchar_t *src, grub_size_t size); int grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize); grub_ssize_t grub_utf8_to_ucs4_alloc (const char *msg, - grub_uint32_t **unicode_msg, - grub_uint32_t **last_position); + grub_wchar_t **unicode_msg, + grub_wchar_t **last_position); /* Returns the number of bytes the string src would occupy is converted to UTF-8, excluding \0. */ grub_size_t -grub_get_num_of_utf8_bytes (const grub_uint32_t *src, grub_size_t size); +grub_get_num_of_utf8_bytes (const grub_wchar_t *src, grub_size_t size); /* Converts UCS-4 to UTF-8. Returns the number of bytes effectively written excluding the trailing \0. */ grub_size_t -grub_ucs4_to_utf8 (const grub_uint32_t *src, grub_size_t size, +grub_ucs4_to_utf8 (const grub_wchar_t *src, grub_size_t size, grub_uint8_t *dest, grub_size_t destsize); -grub_size_t grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize, +grub_size_t grub_utf8_to_ucs4 (grub_wchar_t *dest, grub_size_t destsize, const grub_uint8_t *src, grub_size_t srcsize, const grub_uint8_t **srcend); /* Returns -2 if not enough space, -1 on invalid character. */ @@ -316,6 +330,8 @@ grub_ssize_t grub_encode_utf8_character (grub_uint8_t *dest, grub_uint8_t *destend, grub_uint32_t code); +char +grub_translit (grub_wchar_t in); const grub_uint32_t * grub_unicode_get_comb_start (const grub_uint32_t *str, const grub_uint32_t *cur); diff --git a/include/grub/crypto.h b/include/grub/crypto.h index 9d16df1de..d3ffdeb9a 100644 --- a/include/grub/crypto.h +++ b/include/grub/crypto.h @@ -27,6 +27,7 @@ #include #include #include +#include typedef enum { diff --git a/include/grub/datetime.h b/include/grub/datetime.h index fef281404..38f2fabc9 100644 --- a/include/grub/datetime.h +++ b/include/grub/datetime.h @@ -51,6 +51,8 @@ const char *grub_get_weekday_name (struct grub_datetime *datetime); void grub_unixtime2datetime (grub_int32_t nix, struct grub_datetime *datetime); +typedef grub_int64_t grub_time_t; + static inline int grub_datetime2unixtime (const struct grub_datetime *datetime, grub_int32_t *nix) { @@ -130,4 +132,8 @@ grub_err_t grub_set_datetime_cmos (struct grub_datetime *datetime); #endif +grub_size_t +grub_strftime (char *s, grub_size_t max, const char *format, + const struct grub_datetime *tm); + #endif /* ! KERNEL_DATETIME_HEADER */ diff --git a/include/grub/dl.h b/include/grub/dl.h index 3dc88c75c..7fea6a519 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -234,6 +234,19 @@ grub_err_t grub_dl_register_symbol (const char *name, void *addr, grub_err_t grub_arch_dl_check_header (void *ehdr); grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr); +struct grub_symbol +{ + struct grub_symbol *next; + const char *name; + void *addr; + int isfunc; + grub_dl_t mod; /* The module to which this symbol belongs. */ +}; +typedef struct grub_symbol *grub_symbol_t; + +grub_symbol_t +EXPORT_FUNC(grub_get_symbol) (const char *name, grub_dl_t mod); + #if defined (_mips) #define GRUB_LINKER_HAVE_INIT 1 void grub_arch_dl_init_linker (void); diff --git a/include/grub/err.h b/include/grub/err.h index 9896fccf9..c97b992a7 100644 --- a/include/grub/err.h +++ b/include/grub/err.h @@ -71,7 +71,9 @@ typedef enum GRUB_ERR_NET_PACKET_TOO_BIG, GRUB_ERR_NET_NO_DOMAIN, GRUB_ERR_EOF, - GRUB_ERR_BAD_SIGNATURE + GRUB_ERR_BAD_SIGNATURE, + GRUB_ERR_POSIX_EROFS, + GRUB_ERR_POSIX_EEXIST } grub_err_t; diff --git a/include/grub/i18n.h b/include/grub/i18n.h index a91d73346..fd11e0035 100644 --- a/include/grub/i18n.h +++ b/include/grub/i18n.h @@ -26,6 +26,8 @@ #if (defined(ENABLE_NLS) && ENABLE_NLS) || !defined (GRUB_UTIL) extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s); +const char * +grub_dgettext (const char *domainname, const char *msgid); # ifdef GRUB_UTIL diff --git a/include/grub/libgcc.h b/include/grub/libgcc.h index d101db473..84c58d215 100644 --- a/include/grub/libgcc.h +++ b/include/grub/libgcc.h @@ -20,6 +20,9 @@ #ifndef __STDC_VERSION__ #define __STDC_VERSION__ 0 #endif + +#undef _GL_UNUSED + #include /* On x86 these functions aren't really needed. Save some space. */ diff --git a/include/grub/menu_text.h b/include/grub/menu_text.h new file mode 100644 index 000000000..83d9b3bcb --- /dev/null +++ b/include/grub/menu_text.h @@ -0,0 +1,122 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 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 . + */ + +#ifndef GRUB_MENU_TEXT_HEADER +#define GRUB_MENU_TEXT_HEADER 1 + +#define GRUB_ + +/* The number of columns/lines between messages/borders/etc. */ +static inline int +grub_term_margin (struct grub_term_output *term) +{ + if (grub_term_is_tiny (term)) + return 0; + return 1; +} + +/* The number of lines of "GRUB version..." at the top. */ +static inline int +grub_term_info_height (struct grub_term_output *term) +{ + if (grub_term_is_tiny (term)) + return 0; + return 1; +} + +static inline int +grub_term_left_border_x (struct grub_term_output *term) +{ + if (grub_term_is_tiny (term)) + return 0; + return 1; +} + +/* margin + info_height + margin. */ +static inline int +grub_term_top_border_y (struct grub_term_output *term) +{ + if (grub_term_is_tiny (term)) + return 0; + return 3; +} + +/* margin + info_height + margin + margin. */ +static inline int +grub_term_first_entry_y (struct grub_term_output *term) +{ + if (grub_term_is_tiny (term)) + return 0; + return 4; +} + +/* The width of the border. */ +static inline unsigned +grub_term_border_width (struct grub_term_output *term) +{ + if (grub_term_height (term) == 1) + return grub_term_width (term) - 2; + if (grub_term_is_tiny (term)) + return grub_term_width (term) - 1; + + /* - 3 * margin - scroll. */ + return grub_term_width (term) - 3; +} + +/* The height of the border. */ +static inline unsigned +grub_term_border_height (struct grub_term_output *term) +{ + if (grub_term_is_tiny (term)) + return grub_term_height (term); + return grub_term_height (term) - 3 - 8; +} + +/* The number of entries shown at a time. */ +static inline int +grub_term_num_entries (struct grub_term_output *term) +{ + if (grub_term_is_tiny (term)) + return grub_term_height (term); + + return grub_term_border_height (term) - 2; +} + +/* The max column number of an entry. The last "-1" is for a + continuation marker. */ +static inline int +grub_term_entry_width (struct grub_term_output *term) +{ + if (grub_term_height (term) == 1) + return grub_term_width (term) - 2; + + if (grub_term_is_tiny (term)) + return grub_term_width (term) - 1; + + return grub_term_border_width (term) - 2 - 2 - 1; +} + +static inline int +grub_term_cursor_x (struct grub_term_output *term) +{ + if (grub_term_is_tiny (term)) + return grub_term_border_width (term); + return (1 + grub_term_border_width (term) - 1 - 1); +} + +#endif diff --git a/include/grub/misc.h b/include/grub/misc.h index ed672fdf4..2be2af224 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -59,7 +59,9 @@ #define ALIGN_UP_OVERHEAD(addr, align) ((-(addr)) & ((typeof (addr)) (align) - 1)) #define ALIGN_DOWN(addr, align) \ ((addr) & ~((typeof (addr)) align - 1)) +#ifndef GRUB_POSIX #define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0])) +#endif #define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; } #define grub_dprintf(condition, fmt, args...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, fmt, ## args) @@ -455,6 +457,17 @@ grub_error_load (const struct grub_error_saved *save) grub_errno = save->grub_errno; } +static inline char * +grub_strpbrk (const char *s, const char *accept) +{ + const char *ptr, *ptr2; + for (ptr = s; *ptr; ptr++) + for (ptr2 = accept; *ptr2; ptr2++) + if (*ptr == *ptr2) + return (char *) ptr; + return 0; +} + #if BOOT_TIME_STATS struct grub_boot_time { diff --git a/include/grub/normal.h b/include/grub/normal.h index c4ab193b3..ea096b283 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -27,6 +27,7 @@ #include #include #include +#include /* The standard left and right margin for some messages. */ #define STANDARD_MARGIN 6 @@ -87,25 +88,25 @@ int grub_parse_color_name_pair (grub_uint8_t *ret, const char *name); /* Defined in `menu_text.c'. */ void grub_wait_after_message (void); void -grub_print_ucs4 (const grub_uint32_t * str, - const grub_uint32_t * last_position, +grub_print_ucs4 (const grub_wchar_t * str, + const grub_wchar_t * last_position, int margin_left, int margin_right, struct grub_term_output *term); void -grub_print_ucs4_menu (const grub_uint32_t * str, - const grub_uint32_t * last_position, +grub_print_ucs4_menu (const grub_wchar_t * str, + const grub_wchar_t * last_position, int margin_left, int margin_right, struct grub_term_output *term, - int skip_lines, int max_lines, grub_uint32_t contchar, + int skip_lines, int max_lines, grub_wchar_t contchar, struct grub_term_pos *pos); int -grub_ucs4_count_lines (const grub_uint32_t * str, - const grub_uint32_t * last_position, +grub_ucs4_count_lines (const grub_wchar_t * str, + const grub_wchar_t * last_position, int margin_left, int margin_right, struct grub_term_output *term); -grub_size_t grub_getstringwidth (grub_uint32_t * str, - const grub_uint32_t * last_position, +grub_size_t grub_getstringwidth (grub_wchar_t * str, + const grub_wchar_t * last_position, struct grub_term_output *term); void grub_print_message_indented (const char *msg, int margin_left, int margin_right, diff --git a/include/grub/posix.h b/include/grub/posix.h new file mode 100644 index 000000000..b17254edf --- /dev/null +++ b/include/grub/posix.h @@ -0,0 +1,86 @@ + +#ifndef GRUB_POSIX_H +#define GRUB_POSIX_H 1 + +#include +#include +#include +#include + +struct grub_posix_file +{ + grub_file_t file; + int fileno; + int was_error; +}; + +struct grub_posix_file * +grub_posix_fopen (const char *path, const char *mode); + +int +grub_posix_fclose (struct grub_posix_file *fp); + +int +grub_posix_feof (struct grub_posix_file *stream); + +grub_size_t +grub_posix_fread (void *ptr, grub_size_t size, grub_size_t nmemb, + struct grub_posix_file *stream); + +extern grub_err_t grub_posix_errno; + +grub_ssize_t +grub_posix_write_console (const void *buf, grub_size_t count); + +char * +grub_posix_fgets (char *ptr0, int size, struct grub_posix_file *stream); + +grub_time_t +grub_posix_time (grub_time_t *t); + +#define grub_posix_stdin ((struct grub_posix_file *) 1) +#define grub_posix_stdout ((struct grub_posix_file *) 2) +#define grub_posix_stderr ((struct grub_posix_file *) 3) + +#define grub_posix_stdin_fileno 0 +#define grub_posix_stdout_fileno 1 +#define grub_posix_stderr_fileno 2 + +struct tm +{ + struct grub_datetime tm; +}; + +const char * +grub_posix_strerror (grub_err_t err); + +extern char *grub_posix_strtok_storage; + +char * +grub_strtok_r (char *str, const char *delim, char **saveptr); + +grub_off_t +grub_posix_seek (int fd, grub_off_t offset, int whence); + +grub_off_t +grub_posix_get_file_size (int fd); + +int +grub_posix_close (int fd); +grub_ssize_t +grub_posix_read (int fd, void *buf, grub_size_t count); + +enum + { + GRUB_POSIX_SEEK_SET, + GRUB_POSIX_SEEK_CUR, + GRUB_POSIX_SEEK_END + }; + +struct grub_posix_atexit +{ + struct grub_posix_atexit *next; + void (*function) (void); +}; + +#endif diff --git a/include/grub/serial.h b/include/grub/serial.h index 20840d04b..987b08317 100644 --- a/include/grub/serial.h +++ b/include/grub/serial.h @@ -77,6 +77,11 @@ struct grub_serial_port struct grub_serial_driver *driver; struct grub_serial_config config; int configured; + enum + { + GRUB_SERIAL_PORT_TYPE_GENERIC, + GRUB_SERIAL_PORT_TYPE_TERMINAL + } port_type; int broken; /* This should be void *data but since serial is useful as an early console diff --git a/include/grub/sort.h b/include/grub/sort.h new file mode 100644 index 000000000..ffcf841c5 --- /dev/null +++ b/include/grub/sort.h @@ -0,0 +1,15 @@ +#ifndef GRUB_SORT_H +#define GRUB_SORT_H 1 + +#include +/* For comparator. */ +#include + +void +grub_hsort (void *base, grub_size_t nmemb, grub_size_t size, + grub_comparator_t compar); +void +grub_qsort (void *base, grub_size_t nmemb, grub_size_t size, + grub_comparator_t compar); + +#endif diff --git a/include/grub/term.h b/include/grub/term.h index e2110f390..dcbaf4451 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -323,7 +323,7 @@ grub_term_unregister_output (grub_term_output_t term) #define FOR_ACTIVE_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs)) #define FOR_DISABLED_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs_disabled)) -void grub_putcode (grub_uint32_t code, struct grub_term_output *term); +void grub_putcode (grub_wchar_t code, struct grub_term_output *term); int EXPORT_FUNC(grub_getkey) (void); int EXPORT_FUNC(grub_getkey_noblock) (void); void grub_cls (void); @@ -348,6 +348,11 @@ grub_term_getxy (struct grub_term_output *term) return term->getxy (term); } +static inline unsigned grub_term_is_tiny (struct grub_term_output *term) +{ + return grub_term_height (term) < 5; +} + static inline void grub_term_refresh (struct grub_term_output *term) { diff --git a/include/grub/types.h b/include/grub/types.h index 8c737aa6f..25ab3b4d6 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -124,6 +124,9 @@ typedef grub_int32_t grub_ssize_t; # define PRIdGRUB_SSIZE "d" #endif +#define PRIxGRUB_UINT8_T "x" +#define PRIxGRUB_UINT16_T "x" + #define GRUB_UCHAR_MAX 0xFF #define GRUB_USHRT_MAX 65535 #define GRUB_SHRT_MAX 0x7fff diff --git a/include/grub/unicode.h b/include/grub/unicode.h index 17b6ca684..3000d84cc 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -22,6 +22,7 @@ #include #include #include +#include struct grub_unicode_bidi_pair { @@ -250,7 +251,7 @@ struct grub_term_pos }; grub_ssize_t -grub_bidi_logical_to_visual (const grub_uint32_t *logical, +grub_bidi_logical_to_visual (const grub_wchar_t *logical, grub_size_t logical_len, struct grub_unicode_glyph **visual_out, grub_size_t (*getcharwidth) (const struct grub_unicode_glyph *visual, void *getcharwidth_arg), @@ -263,7 +264,7 @@ grub_bidi_logical_to_visual (const grub_uint32_t *logical, enum grub_comb_type grub_unicode_get_comb_type (grub_uint32_t c); grub_size_t -grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, +grub_unicode_aglomerate_comb (const grub_wchar_t *in, grub_size_t inlen, struct grub_unicode_glyph *out); static inline const struct grub_unicode_combining * diff --git a/util/grub-install.in b/util/grub-install.in index 7cd089bfd..f3ab2d15f 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -498,6 +498,16 @@ if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] || [ "$ done fi +# Copy gettext files +for domain in grub bison-runtime brltty; do + mkdir -p "${grubdir}"/locale/$domain + for dir in "${localedir}"/*; do + if test -f "$dir/LC_MESSAGES/$domain.mo"; then + cp -f "$dir/LC_MESSAGES/$domain.mo" "${grubdir}/locale/$domain/${dir##*/}.mo" + fi + done +done + if ! is_path_readable_by_grub "${grubdir}"; then gettext_printf "Path \`%s' is not readable by GRUB on boot. Installation is impossible. Aborting.\n" "${grubdir}" 1>&2 exit 1