Thread (1 message) 1 message, 1 author, 2016-06-15

Re: [PATCH/RFC 1/2] git-sh-i18n--envsubst: our own envsubst(1) for eval_gettext()

From: Ævar Arnfjörð Bjarmason <hidden>
Date: 2016-06-15 22:50:58

On Thu, Mar 3, 2011 at 01:14, Junio C Hamano [off-list ref] wrote:
Ævar Arnfjörð Bjarmason  [off-list ref] writes:
quoted
In a previous incarnation of the gettext series I implemented the
eval_gettext() fallback like this:

    eval_gettext() {
        gettext_out=$(gettext "$1")
        gettext_eval="printf '%s' \"$gettext_out\""
        printf "%s" "`eval \"$gettext_eval\"`"
    }

This was clever, but would incorrectly handle cases where the variable
being interpolated contained spaces. E.g.:

    cmd="git foo"; eval_gettext "command: \$cmd"

Would emit "command: gitfoo", instead of the correct "command: git
foo".
Hmm, are you sure you got your quoting right?

   $ cat >1.sh <<\EOF
   #!/bin/sh
   gettext () {
           case "$1" in
           'command: $cmd') echo 'dcomman: $cmd' ;;
           *) echo "GETTEXT POISON" ;;
           esac
   }

   eval_gettext() {
           gettext_out=$(gettext "$1") &&
           gettext_eval="printf '%s' \"$gettext_out\"" &&
           gettext_cmd=$(eval "$gettext_eval") &&
           printf "%s" "$gettext_cmd"
   }

   cmd="git foo"
   eval_gettext "command: \$cmd"
   EOF
   $ sh -x 1.sh
   + cmd='git foo'
   + eval_gettext 'command: $cmd'
   ++ gettext 'command: $cmd'
   ++ case "$1" in
   ++ echo 'dcomman: $cmd'
   + gettext_out='dcomman: $cmd'
   + gettext_eval='printf '\''%s'\'' "dcomman: $cmd"'
   ++ eval 'printf '\''%s'\'' "dcomman: $cmd"'
   +++ printf %s 'dcomman: git foo'
   + gettext_cmd='dcomman: git foo'
   + printf %s 'dcomman: git foo'
   dcomman: git foo

Am I grossly missing something from what you are trying to do here?
(CC-ing the list again, so there's a record of this in the mail
archive).

Your eval_gettext() is better, but it still fails in cases where the
string contains "'s. E.g.:

    test_expect_success C_LOCALE_OUTPUT 'eval_gettext: our
eval_gettext() fallback can interpolate variables with spaces in them'
'
        cmdline="git am" &&
        export cmdline;
        printf "When you have resolved this problem run \"git am
--resolved\"." >expect &&
        eval_gettext "When you have resolved this problem run
\"\$cmdline --resolved\"." >actual
        test_cmp expect actual
    '

If this were just:

    test_expect_success C_LOCALE_OUTPUT 'eval_gettext: our
eval_gettext() fallback can interpolate variables with spaces in them'
'
        cmdline="git am" &&
        export cmdline;
        printf "When you have resolved this problem run git am
--resolved." >expect &&
        eval_gettext "When you have resolved this problem run
\$cmdline --resolved." >actual
        test_cmp expect actual
    '

Your version would work.

Maybe there's some portable version of doing this that works with
variables with spaces mixed with quotes. But unless someone can point
it out I'll submit a series with git-sh-i18n--envsubst and tests
demonstrating why it's needed soon.q
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help