grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Fix gettext quotation in util/grub.d


From: Colin Watson
Subject: [PATCH] Fix gettext quotation in util/grub.d
Date: Tue, 21 Dec 2010 12:31:23 +0000
User-agent: Mutt/1.5.18 (2008-05-17)

http://bugs.debian.org/605615

This happens when the system shell is bash rather than dash.  The behaviour
of printf when the format string contains the character sequence \' is
unspecified.

Adding an extra layer of quotation and making sure that everything that uses
it goes through printf (so that that extra layer is consistently removed) is
easy.  I added a gettext_printf function to help with this, which is briefer
and involves fewer nested layers of open-coded quotation.

The tricky bit is making sure that xgettext understands what's going on!
Adding --keyword=gettext_printf is obvious, but I noticed along the way
that we weren't setting c-format flags so that translations were checked
for the right number of %s entries and the like.  I tried adding
--flag=gettext_quoted:1:c-format --flag=gettext_printf:1:c-format, but
it turns out that xgettext refuses to include c-format flags for strings
it extracted from a shell file.  Whoops.  Since we already had a
modified version of po/Makefile.in.in, I changed it a bit further to fix
things up with sed.

Finally, xgettext refuses to extract strings from here-documents (which
I think is probably a bug, and if I can manage to write a reduced test
case for it I'll report it to the gettext maintainers).  Thus, I
extracted translatable strings from here-documents and used a temporary
variable for them instead.

2010-12-21  Colin Watson  <address@hidden>

        * util/grub-mkconfig_lib.in (gettext_quoted): Add clarifying
        comment.  Add an extra layer of quotation, requiring the output of
        this function to be used in a printf format string.
        (gettext_printf): New function.
        * util/grub.d/10_hurd.in: Use gettext_printf where appropriate.
        Extract translatable strings from here-documents and use a temporary
        variable instead, so that xgettext can find them.
        * util/grub.d/10_kfreebsd.in: Likewise.
        * util/grub.d/10_linux.in: Likewise.
        * util/grub.d/20_linux_xen.in: Likewise.

        * po/grub.d.sed: New file.
        * po/Makefile.in.in ($(DOMAIN).pot-update): Extract gettext_printf
        arguments.  Set c-format flags on all strings extracted from
        util/grub.d/ (xgettext refuses to include these itself for strings
        it extracted from a shell file, but these really are c-format).

=== modified file 'po/Makefile.in.in'
--- po/Makefile.in.in   2010-09-20 23:09:23 +0000
+++ po/Makefile.in.in   2010-12-21 12:05:05 +0000
@@ -173,7 +173,8 @@ $(DOMAIN).pot-update: $(POTFILES) $(srcd
              --files-from=$(srcdir)/POTFILES-shell.in \
              --copyright-holder='$(COPYRIGHT_HOLDER)' \
              --msgid-bugs-address="$$msgid_bugs_address" \
-             --join-existing --language=Shell --keyword=gettext_quoted \
+             --join-existing --language=Shell \
+             --keyword=gettext_quoted --keyword=gettext_printf \
            ;; \
          *) \
            $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \
@@ -183,10 +184,13 @@ $(DOMAIN).pot-update: $(POTFILES) $(srcd
              --package-name="address@hidden@" \
              --package-version='@VERSION@' \
              --msgid-bugs-address="$$msgid_bugs_address" \
-             --join-existing --language=Shell --keyword=gettext_quoted \
+             --join-existing --language=Shell \
+             --keyword=gettext_quoted --keyword=gettext_printf \
            ;; \
        esac
        test ! -f $(DOMAIN).po || { \
+         sed -f grub.d.sed < $(DOMAIN).po > $(DOMAIN).1po && \
+         mv $(DOMAIN).1po $(DOMAIN).po; \
          if test -f $(srcdir)/$(DOMAIN).pot; then \
            sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > 
$(DOMAIN).1po && \
            sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \

=== added file 'po/grub.d.sed'
--- po/grub.d.sed       1970-01-01 00:00:00 +0000
+++ po/grub.d.sed       2010-12-21 12:02:27 +0000
@@ -0,0 +1,2 @@
+/^#: util\/grub\.d\//a\
+#, c-format

=== modified file 'util/grub-mkconfig_lib.in'
--- util/grub-mkconfig_lib.in   2010-09-15 12:46:53 +0000
+++ util/grub-mkconfig_lib.in   2010-12-21 12:13:33 +0000
@@ -187,8 +187,20 @@ version_find_latest ()
   echo "$a"
 }
 
+# One layer of quotation is eaten by "", the second by sed, and the third by
+# printf; so this turns ' into \'.  Note that you must use the output of
+# this function in a printf format string.
 gettext_quoted () {
-  $gettext "$@" | sed "s/'/'\\\\''/g"
+  $gettext "$@" | sed "s/'/'\\\\\\\\''/g"
+}
+
+# Run the first argument through gettext_quoted, and then pass that and all
+# remaining arguments to printf.  This is a useful abbreviation and tends to
+# be easier to type.
+gettext_printf () {
+  local format="$1"
+  shift
+  printf "$(gettext_quoted "$format")" "$@"
 }
 
 uses_abstraction () {

=== modified file 'util/grub.d/10_hurd.in'
--- util/grub.d/10_hurd.in      2010-11-01 11:49:40 +0000
+++ util/grub.d/10_hurd.in      2010-12-21 11:45:56 +0000
@@ -81,14 +81,16 @@ do
 menuentry "${OS} ${KERNEL}" ${CLASS} {
 EOF
   prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/"
+  message="$(gettext_printf "Loading GNU Mach ...")"
   cat << EOF
-       echo            '$(gettext_quoted "Loading GNU Mach ...")'
+       echo            '$message'
        multiboot       ${kernel} root=device:${GRUB_DEVICE#/dev/}
 EOF
   save_default_entry | sed -e "s/^/\t/"
   prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/"
+  message="$(gettext_printf "Loading the Hurd ...")"
   cat << EOF
-       echo            '$(gettext_quoted "Loading the Hurd ...")'
+       echo            '$message'
        module          /hurd/${hurd_fs}.static ${hurd_fs} --readonly \\
                        --multiboot-command-line='\${kernel-command-line}' \\
                        --host-priv-port='\${host-port}' \\
@@ -103,13 +105,15 @@ EOF
 menuentry "${OS} ${KERNEL} (recovery mode)" ${CLASS} {
 EOF
   prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/"
+  message="$(gettext_printf "Loading GNU Mach ...")"
   cat << EOF
-       echo            '$(gettext_quoted "Loading GNU Mach ...")'
+       echo            '$message'
        multiboot       ${kernel} root=device:${GRUB_DEVICE#/dev/} -s
 EOF
   prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/"
+  message="$(gettext_printf "Loading the Hurd ...")"
   cat << EOF
-       echo            '$(gettext_quoted "Loading the Hurd ...")'
+       echo            '$message'
        module          /hurd/${hurd_fs}.static ${hurd_fs} \\
                        --multiboot-command-line='\${kernel-command-line}' \\
                        --host-priv-port='\${host-port}' \\

=== modified file 'util/grub.d/10_kfreebsd.in'
--- util/grub.d/10_kfreebsd.in  2010-11-01 11:49:40 +0000
+++ util/grub.d/10_kfreebsd.in  2010-12-21 11:46:13 +0000
@@ -84,8 +84,9 @@ kfreebsd_entry ()
   fi
 
   printf '%s\n' "${prepare_boot_cache}"
+  message="$(gettext_printf "Loading kernel of FreeBSD %s ..." ${version})"
   cat << EOF
-       echo                    '$(printf "$(gettext_quoted "Loading kernel of 
FreeBSD %s ...")" ${version})'
+       echo                    '$message'
        kfreebsd                ${rel_dirname}/${basename} ${args}
 EOF
 

=== modified file 'util/grub.d/10_linux.in'
--- util/grub.d/10_linux.in     2010-11-01 11:49:40 +0000
+++ util/grub.d/10_linux.in     2010-12-21 11:43:50 +0000
@@ -94,13 +94,15 @@ EOF
     prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | 
sed -e "s/^/\t/")"
   fi
   printf '%s\n' "${prepare_boot_cache}"
+  message="$(gettext_printf "Loading Linux %s ..." ${version})"
   cat << EOF
-       echo    '$(printf "$(gettext_quoted "Loading Linux %s ...")" 
${version})'
+       echo    '$message'
        linux   ${rel_dirname}/${basename} 
root=${linux_root_device_thisversion} ro ${args}
 EOF
   if test -n "${initrd}" ; then
+    message="$(gettext_printf "Loading initial ramdisk ...")"
     cat << EOF
-       echo    '$(gettext_quoted "Loading initial ramdisk ...")'
+       echo    '$message'
        initrd  ${rel_dirname}/${initrd}
 EOF
   fi

=== modified file 'util/grub.d/20_linux_xen.in'
--- util/grub.d/20_linux_xen.in 2010-11-01 11:49:40 +0000
+++ util/grub.d/20_linux_xen.in 2010-12-21 11:46:36 +0000
@@ -73,14 +73,16 @@ linux_entry ()
     prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | 
sed -e "s/^/\t/")"
   fi
   printf '%s\n' "${prepare_boot_cache}"
+  message="$(gettext_printf "Loading Linux %s ..." ${version})"
   cat << EOF
-       echo    '$(printf "$(gettext_quoted "Loading Linux %s ...")" 
${version})'
+       echo    '$message'
        multiboot       ${rel_xen_dirname}/${xen_basename} placeholder 
${xen_args}
        module  ${rel_dirname}/${basename} placeholder 
root=${linux_root_device_thisversion} ro ${args}
 EOF
   if test -n "${initrd}" ; then
+    message="$(gettext_printf "Loading initial ramdisk ...")"
     cat << EOF
-       echo    '$(gettext_quoted "Loading initial ramdisk ...")'
+       echo    '$message'
        module  ${rel_dirname}/${initrd}
 EOF
   fi

-- 
Colin Watson                                       address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]