{"thread":{"id":"27298","subject":"[PATCH 0/4] i18n: Add shell script translation infrastructure","startedAt":"2011-05-08T12:10:55Z","lastAt":"2011-05-09T07:52:09Z","messageCount":13,"participants":["Ævar Arnfjörð Bjarmason","Sverre Rabbelier","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"167368","messageId":"1304856659-10672-1-git-send-email-avarab@gmail.com","threadId":"27298","inReplyTo":null,"subject":"[PATCH 0/4] i18n: Add shell script translation infrastructure","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2011-05-08T12:10:55Z","receivedAt":"2011-05-08T12:10:55Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"As threatened this is the updated shell script translation\ninfrastructure that I'm submitting now that 1.7.5 has been out for a\nbit.\n\nThis adds skeleton no-op functions to git-sh-i18n.sh analogous to the\ngettext.c skeleton functions for C, adds *.sh scripts to the \"pot\"\ntarget for message extraction, and updates the git-sh-i18n--envsubst\ntests to use the new test_i18ncmp function.\n\nÆvar Arnfjörð Bjarmason (4):\n  git-sh-i18n--envsubst: our own envsubst(1) for eval_gettext()\n  git-sh-i18n.sh: add no-op gettext() and eval_gettext() wrappers\n  git-sh-i18n.sh: add GIT_GETTEXT_POISON support\n  Makefile: add xgettext target for *.sh files\n\n .gitignore                              |    3 +\n Documentation/git-sh-i18n--envsubst.txt |   36 +++\n Documentation/git-sh-i18n.txt           |   57 ++++\n Makefile                                |    8 +-\n git-sh-i18n.sh                          |   29 ++\n sh-i18n--envsubst.c                     |  444 +++++++++++++++++++++++++++++++\n t/t0201-gettext-fallbacks.sh            |   51 ++++\n 7 files changed, 627 insertions(+), 1 deletions(-)\n create mode 100644 Documentation/git-sh-i18n--envsubst.txt\n create mode 100644 Documentation/git-sh-i18n.txt\n create mode 100644 git-sh-i18n.sh\n create mode 100644 sh-i18n--envsubst.c\n create mode 100755 t/t0201-gettext-fallbacks.sh\n\n-- \n1.7.4.4\n"},{"id":"167369","messageId":"1304856659-10672-2-git-send-email-avarab@gmail.com","threadId":"27298","inReplyTo":"1304856659-10672-1-git-send-email-avarab@gmail.com","subject":"[PATCH 1/4] git-sh-i18n--envsubst: our own envsubst(1) for eval_gettext()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2011-05-08T12:10:56Z","receivedAt":"2011-05-08T12:10:56Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Add a git-sh-i18n--envsubst program which is a stripped-down version\nof the GNU envsubst(1) program that comes with GNU gettext for use in\nthe eval_gettext() fallback, instead of using a clever (but broken)\nprintf + eval + printf trick.\n\nIn a previous incarnation of the gettext series I implemented the\neval_gettext() fallback like this:\n\n    eval_gettext() {\n        gettext_out=$(gettext \"$1\")\n        gettext_eval=\"printf '%s' \\\"$gettext_out\\\"\"\n        printf \"%s\" \"`eval \\\"$gettext_eval\\\"`\"\n    }\n\nThis was clever, but would incorrectly handle cases where the variable\nbeing interpolated contained spaces. E.g.:\n\n    cmd=\"git foo\"; eval_gettext \"command: \\$cmd\"\n\nWould emit \"command: gitfoo\", instead of the correct \"command: git\nfoo\". This happened with a message in git-am.sh that used the $cmdline\nvariable. An alternate version suggested by Junio is able to handle\nthis case:\n\n   eval_gettext() {\n           gettext_out=$(gettext \"$1\") &&\n           gettext_eval=\"printf '%s' \\\"$gettext_out\\\"\" &&\n           gettext_cmd=$(eval \"$gettext_eval\") &&\n           printf \"%s\" \"$gettext_cmd\"\n   }\n\nBut it strips out double-quotes when they're included in the message\nbeing passed to eval_gettext. E.g. the message in git-am.sh:\n\n    \"When you have resolved this problem run \\\"$cmdline --resolved\\\".\"\n\nWill be emitted as:\n\n    When you have resolved this problem run git am --resolved.\n\nInstead of the correct:\n\n    When you have resolved this problem run \"git am --resolved\".\n\nTo work around this, and to improve our variable expansion behavior\n(eval has security issues) I've imported a stripped-down version of\ngettext's envsubst(1) program. With it eval_gettext() is implemented\nlike this:\n\n    eval_gettext() {\n        printf \"%s\" \"$1\" | (\n            export PATH $(git sh-i18n--envsubst --variables \"$1\");\n            git sh-i18n--envsubst \"$1\"\n        )\n    }\n\nThese are the modifications I made to envsubst.c as I turned it into\nsh-i18n--envsubst.c:\n\n * Added our git-compat-util.h header for xrealloc() and friends.\n\n * Removed inclusion of gettext-specific headers.\n\n * Removed most of main() and replaced it with my own. The modified\n   version only does option parsing for --variables. That's all it\n   needs.\n\n * Modified error() invocations to use our error() instead of\n   error(3).\n\n * Replaced the gettext XNMALLOC(n, size) macro with just\n   xmalloc(n). Since XNMALLOC() only allocated char's.\n\n * Removed the string_list_destroy function. It's redundant (also in\n   the upstream code).\n\n * Replaced the use of stdbool.h (a C99 header) by doing the following\n   replacements on the code:\n\n    * s/bool/unsigned short int/g\n    * s/true/1/g\n    * s/false/0/g\n\nReported-by: Johannes Sixt <j.sixt@viscovery.net>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n .gitignore                              |    2 +\n Documentation/git-sh-i18n--envsubst.txt |   36 +++\n Makefile                                |    1 +\n sh-i18n--envsubst.c                     |  444 +++++++++++++++++++++++++++++++\n t/t0201-gettext-fallbacks.sh            |   51 ++++\n 5 files changed, 534 insertions(+), 0 deletions(-)\n create mode 100644 Documentation/git-sh-i18n--envsubst.txt\n create mode 100644 sh-i18n--envsubst.c\n create mode 100755 t/t0201-gettext-fallbacks.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex 711fce7..1ccf797 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -127,6 +127,8 @@\n /git-rm\n /git-send-email\n /git-send-pack\n+/git-sh-i18n\n+/git-sh-i18n--envsubst\n /git-sh-setup\n /git-shell\n /git-shortlog\ndiff --git a/Documentation/git-sh-i18n--envsubst.txt b/Documentation/git-sh-i18n--envsubst.txt\nnew file mode 100644\nindex 0000000..e146a2c\n--- /dev/null\n+++ b/Documentation/git-sh-i18n--envsubst.txt\n@@ -0,0 +1,36 @@\n+git-sh-i18n--envsubst(1)\n+========================\n+\n+NAME\n+----\n+git-sh-i18n--envsubst - Git's own envsubst(1) for i18n fallbacks\n+\n+DESCRIPTION\n+-----------\n+\n+This is not a command the end user would want to run.  Ever.\n+This documentation is meant for people who are studying the\n+plumbing scripts and/or are writing new ones.\n+\n+git-sh-i18n--envsubst is Git's stripped-down copy of the GNU\n+`envsubst(1)` program that comes with the GNU gettext\n+package. It's used internally by linkgit:git-sh-i18n[1] to\n+provide the `eval_gettext` fallback on Solaris and systems\n+that don't have a gettext implementation.\n+\n+No promises are made about the interface, or that this\n+program won't disappear without warning in the next version\n+of Git. Don't use it.\n+\n+Author\n+------\n+Written by Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n+\n+Documentation\n+--------------\n+Documentation by Ævar Arnfjörð Bjarmason and the git-list\n+<git@vger.kernel.org>.\n+\n+GIT\n+---\n+Part of the linkgit:git[1] suite\ndiff --git a/Makefile b/Makefile\nindex ef57c1c..87c83cb 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -414,6 +414,7 @@ PROGRAM_OBJS += shell.o\n PROGRAM_OBJS += show-index.o\n PROGRAM_OBJS += upload-pack.o\n PROGRAM_OBJS += http-backend.o\n+PROGRAM_OBJS += sh-i18n--envsubst.o\n \n PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS))\n \ndiff --git a/sh-i18n--envsubst.c b/sh-i18n--envsubst.c\nnew file mode 100644\nindex 0000000..8db71b1\n--- /dev/null\n+++ b/sh-i18n--envsubst.c\n@@ -0,0 +1,444 @@\n+/*\n+ * sh-i18n--envsubst.c - a stripped-down version of gettext's envsubst(1)\n+ *\n+ * Copyright (C) 2010 Ævar Arnfjörð Bjarmason\n+ *\n+ * This is a modified version of\n+ * 67d0871a8c:gettext-runtime/src/envsubst.c from the gettext.git\n+ * repository. It has been stripped down to only implement the\n+ * envsubst(1) features that we need in the git-sh-i18n fallbacks.\n+ *\n+ * The \"Close standard error\" part in main() is from\n+ * 8dac033df0:gnulib-local/lib/closeout.c. The copyright notices for\n+ * both files are reproduced immediately below.\n+ */\n+\n+#include \"git-compat-util.h\"\n+\n+/* Substitution of environment variables in shell format strings.\n+   Copyright (C) 2003-2007 Free Software Foundation, Inc.\n+   Written by Bruno Haible <bruno@clisp.org>, 2003.\n+\n+   This program is free software; you can redistribute it and/or modify\n+   it under the terms of the GNU General Public License as published by\n+   the Free Software Foundation; either version 2, or (at your option)\n+   any later version.\n+\n+   This program is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+   GNU General Public License for more details.\n+\n+   You should have received a copy of the GNU General Public License\n+   along with this program; if not, write to the Free Software Foundation,\n+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */\n+\n+/* closeout.c - close standard output and standard error\n+   Copyright (C) 1998-2007 Free Software Foundation, Inc.\n+\n+   This program is free software; you can redistribute it and/or modify\n+   it under the terms of the GNU General Public License as published by\n+   the Free Software Foundation; either version 2, or (at your option)\n+   any later version.\n+\n+   This program is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+   GNU General Public License for more details.\n+\n+   You should have received a copy of the GNU General Public License\n+   along with this program; if not, write to the Free Software Foundation,\n+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */\n+\n+#include <errno.h>\n+#include <getopt.h>\n+#include <stdio.h>\n+#include <stdlib.h>\n+#include <string.h>\n+\n+/* If true, substitution shall be performed on all variables.  */\n+static unsigned short int all_variables;\n+\n+/* Forward declaration of local functions.  */\n+static void print_variables (const char *string);\n+static void note_variables (const char *string);\n+static void subst_from_stdin (void);\n+\n+int\n+main (int argc, char *argv[])\n+{\n+  /* Default values for command line options.  */\n+  unsigned short int show_variables = 0;\n+\n+  switch (argc)\n+\t{\n+\tcase 1:\n+\t  error (\"we won't substitute all variables on stdin for you\");\n+\t  /*\n+\t  all_variables = 1;\n+      subst_from_stdin ();\n+\t  */\n+\tcase 2:\n+\t  /* echo '$foo and $bar' | git sh-i18n--envsubst --variables '$foo and $bar' */\n+\t  all_variables = 0;\n+\t  note_variables (argv[1]);\n+      subst_from_stdin ();\n+\t  break;\n+\tcase 3:\n+\t  /* git sh-i18n--envsubst --variables '$foo and $bar' */\n+\t  if (strcmp(argv[1], \"--variables\"))\n+\t\terror (\"first argument must be --variables when two are given\");\n+\t  show_variables = 1;\n+      print_variables (argv[2]);\n+\t  break;\n+\tdefault:\n+\t  error (\"too many arguments\");\n+\t  break;\n+\t}\n+\n+  /* Close standard error.  This is simpler than fwriteerror_no_ebadf, because\n+     upon failure we don't need an errno - all we can do at this point is to\n+     set an exit status.  */\n+  errno = 0;\n+  if (ferror (stderr) || fflush (stderr))\n+    { \n+      fclose (stderr);\n+      exit (EXIT_FAILURE);\n+    }\n+  if (fclose (stderr) && errno != EBADF)\n+    exit (EXIT_FAILURE);\n+\n+  exit (EXIT_SUCCESS);\n+}\n+\n+/* Parse the string and invoke the callback each time a $VARIABLE or\n+   ${VARIABLE} construct is seen, where VARIABLE is a nonempty sequence\n+   of ASCII alphanumeric/underscore characters, starting with an ASCII\n+   alphabetic/underscore character.\n+   We allow only ASCII characters, to avoid dependencies w.r.t. the current\n+   encoding: While \"${\\xe0}\" looks like a variable access in ISO-8859-1\n+   encoding, it doesn't look like one in the BIG5, BIG5-HKSCS, GBK, GB18030,\n+   SHIFT_JIS, JOHAB encodings, because \\xe0\\x7d is a single character in these\n+   encodings.  */\n+static void\n+find_variables (const char *string,\n+\t\tvoid (*callback) (const char *var_ptr, size_t var_len))\n+{\n+  for (; *string != '\\0';)\n+    if (*string++ == '$')\n+      {\n+\tconst char *variable_start;\n+\tconst char *variable_end;\n+\tunsigned short int valid;\n+\tchar c;\n+\n+\tif (*string == '{')\n+\t  string++;\n+\n+\tvariable_start = string;\n+\tc = *string;\n+\tif ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_')\n+\t  {\n+\t    do\n+\t      c = *++string;\n+\t    while ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')\n+\t\t   || (c >= '0' && c <= '9') || c == '_');\n+\t    variable_end = string;\n+\n+\t    if (variable_start[-1] == '{')\n+\t      {\n+\t\tif (*string == '}')\n+\t\t  {\n+\t\t    string++;\n+\t\t    valid = 1;\n+\t\t  }\n+\t\telse\n+\t\t  valid = 0;\n+\t      }\n+\t    else\n+\t      valid = 1;\n+\n+\t    if (valid)\n+\t      callback (variable_start, variable_end - variable_start);\n+\t  }\n+      }\n+}\n+\n+\n+/* Print a variable to stdout, followed by a newline.  */\n+static void\n+print_variable (const char *var_ptr, size_t var_len)\n+{\n+  fwrite (var_ptr, var_len, 1, stdout);\n+  putchar ('\\n');\n+}\n+\n+/* Print the variables contained in STRING to stdout, each one followed by a\n+   newline.  */\n+static void\n+print_variables (const char *string)\n+{\n+  find_variables (string, &print_variable);\n+}\n+\n+\n+/* Type describing list of immutable strings,\n+   implemented using a dynamic array.  */\n+typedef struct string_list_ty string_list_ty;\n+struct string_list_ty\n+{\n+  const char **item;\n+  size_t nitems;\n+  size_t nitems_max;\n+};\n+\n+/* Initialize an empty list of strings.  */\n+static inline void\n+string_list_init (string_list_ty *slp)\n+{\n+  slp->item = NULL;\n+  slp->nitems = 0;\n+  slp->nitems_max = 0;\n+}\n+\n+/* Append a single string to the end of a list of strings.  */\n+static inline void\n+string_list_append (string_list_ty *slp, const char *s)\n+{\n+  /* Grow the list.  */\n+  if (slp->nitems >= slp->nitems_max)\n+    {\n+      size_t nbytes;\n+\n+      slp->nitems_max = slp->nitems_max * 2 + 4;\n+      nbytes = slp->nitems_max * sizeof (slp->item[0]);\n+      slp->item = (const char **) xrealloc (slp->item, nbytes);\n+    }\n+\n+  /* Add the string to the end of the list.  */\n+  slp->item[slp->nitems++] = s;\n+}\n+\n+/* Compare two strings given by reference.  */\n+static int\n+cmp_string (const void *pstr1, const void *pstr2)\n+{\n+  const char *str1 = *(const char **)pstr1;\n+  const char *str2 = *(const char **)pstr2;\n+\n+  return strcmp (str1, str2);\n+}\n+\n+/* Sort a list of strings.  */\n+static inline void\n+string_list_sort (string_list_ty *slp)\n+{\n+  if (slp->nitems > 0)\n+    qsort (slp->item, slp->nitems, sizeof (slp->item[0]), cmp_string);\n+}\n+\n+/* Test whether a string list contains a given string.  */\n+static inline int\n+string_list_member (const string_list_ty *slp, const char *s)\n+{\n+  size_t j;\n+\n+  for (j = 0; j < slp->nitems; ++j)\n+    if (strcmp (slp->item[j], s) == 0)\n+      return 1;\n+  return 0;\n+}\n+\n+/* Test whether a sorted string list contains a given string.  */\n+static int\n+sorted_string_list_member (const string_list_ty *slp, const char *s)\n+{\n+  size_t j1, j2;\n+\n+  j1 = 0;\n+  j2 = slp->nitems;\n+  if (j2 > 0)\n+    {\n+      /* Binary search.  */\n+      while (j2 - j1 > 1)\n+\t{\n+\t  /* Here we know that if s is in the list, it is at an index j\n+\t     with j1 <= j < j2.  */\n+\t  size_t j = (j1 + j2) >> 1;\n+\t  int result = strcmp (slp->item[j], s);\n+\n+\t  if (result > 0)\n+\t    j2 = j;\n+\t  else if (result == 0)\n+\t    return 1;\n+\t  else\n+\t    j1 = j + 1;\n+\t}\n+      if (j2 > j1)\n+\tif (strcmp (slp->item[j1], s) == 0)\n+\t  return 1;\n+    }\n+  return 0;\n+}\n+\n+\n+/* Set of variables on which to perform substitution.\n+   Used only if !all_variables.  */\n+static string_list_ty variables_set;\n+\n+/* Adds a variable to variables_set.  */\n+static void\n+note_variable (const char *var_ptr, size_t var_len)\n+{\n+  char *string = xmalloc (var_len + 1);\n+  memcpy (string, var_ptr, var_len);\n+  string[var_len] = '\\0';\n+\n+  string_list_append (&variables_set, string);\n+}\n+\n+/* Stores the variables occurring in the string in variables_set.  */\n+static void\n+note_variables (const char *string)\n+{\n+  string_list_init (&variables_set);\n+  find_variables (string, &note_variable);\n+  string_list_sort (&variables_set);\n+}\n+\n+\n+static int\n+do_getc ()\n+{\n+  int c = getc (stdin);\n+\n+  if (c == EOF)\n+    {\n+      if (ferror (stdin))\n+\terror (\"error while reading standard input\");\n+    }\n+\n+  return c;\n+}\n+\n+static inline void\n+do_ungetc (int c)\n+{\n+  if (c != EOF)\n+    ungetc (c, stdin);\n+}\n+\n+/* Copies stdin to stdout, performing substitutions.  */\n+static void\n+subst_from_stdin ()\n+{\n+  static char *buffer;\n+  static size_t bufmax;\n+  static size_t buflen;\n+  int c;\n+\n+  for (;;)\n+    {\n+      c = do_getc ();\n+      if (c == EOF)\n+\tbreak;\n+      /* Look for $VARIABLE or ${VARIABLE}.  */\n+      if (c == '$')\n+\t{\n+\t  unsigned short int opening_brace = 0;\n+\t  unsigned short int closing_brace = 0;\n+\n+\t  c = do_getc ();\n+\t  if (c == '{')\n+\t    {\n+\t      opening_brace = 1;\n+\t      c = do_getc ();\n+\t    }\n+\t  if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_')\n+\t    {\n+\t      unsigned short int valid;\n+\n+\t      /* Accumulate the VARIABLE in buffer.  */\n+\t      buflen = 0;\n+\t      do\n+\t\t{\n+\t\t  if (buflen >= bufmax)\n+\t\t    {\n+\t\t      bufmax = 2 * bufmax + 10;\n+\t\t      buffer = xrealloc (buffer, bufmax);\n+\t\t    }\n+\t\t  buffer[buflen++] = c;\n+\n+\t\t  c = do_getc ();\n+\t\t}\n+\t      while ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')\n+\t\t     || (c >= '0' && c <= '9') || c == '_');\n+\n+\t      if (opening_brace)\n+\t\t{\n+\t\t  if (c == '}')\n+\t\t    {\n+\t\t      closing_brace = 1;\n+\t\t      valid = 1;\n+\t\t    }\n+\t\t  else\n+\t\t    {\n+\t\t      valid = 0;\n+\t\t      do_ungetc (c);\n+\t\t    }\n+\t\t}\n+\t      else\n+\t\t{\n+\t\t  valid = 1;\n+\t\t  do_ungetc (c);\n+\t\t}\n+\n+\t      if (valid)\n+\t\t{\n+\t\t  /* Terminate the variable in the buffer.  */\n+\t\t  if (buflen >= bufmax)\n+\t\t    {\n+\t\t      bufmax = 2 * bufmax + 10;\n+\t\t      buffer = xrealloc (buffer, bufmax);\n+\t\t    }\n+\t\t  buffer[buflen] = '\\0';\n+\n+\t\t  /* Test whether the variable shall be substituted.  */\n+\t\t  if (!all_variables\n+\t\t      && !sorted_string_list_member (&variables_set, buffer))\n+\t\t    valid = 0;\n+\t\t}\n+\n+\t      if (valid)\n+\t\t{\n+\t\t  /* Substitute the variable's value from the environment.  */\n+\t\t  const char *env_value = getenv (buffer);\n+\n+\t\t  if (env_value != NULL)\n+\t\t    fputs (env_value, stdout);\n+\t\t}\n+\t      else\n+\t\t{\n+\t\t  /* Perform no substitution at all.  Since the buffered input\n+\t\t     contains no other '$' than at the start, we can just\n+\t\t     output all the buffered contents.  */\n+\t\t  putchar ('$');\n+\t\t  if (opening_brace)\n+\t\t    putchar ('{');\n+\t\t  fwrite (buffer, buflen, 1, stdout);\n+\t\t  if (closing_brace)\n+\t\t    putchar ('}');\n+\t\t}\n+\t    }\n+\t  else\n+\t    {\n+\t      do_ungetc (c);\n+\t      putchar ('$');\n+\t      if (opening_brace)\n+\t\tputchar ('{');\n+\t    }\n+\t}\n+      else\n+\tputchar (c);\n+    }\n+}\ndiff --git a/t/t0201-gettext-fallbacks.sh b/t/t0201-gettext-fallbacks.sh\nnew file mode 100755\nindex 0000000..54d98b9\n--- /dev/null\n+++ b/t/t0201-gettext-fallbacks.sh\n@@ -0,0 +1,51 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2010 Ævar Arnfjörð Bjarmason\n+#\n+\n+test_description='Gettext Shell fallbacks'\n+\n+. ./test-lib.sh\n+. \"$GIT_BUILD_DIR\"/git-sh-i18n\n+\n+test_expect_success 'gettext: our gettext() fallback has pass-through semantics' '\n+    printf \"test\" >expect &&\n+    gettext \"test\" >actual &&\n+    test_i18ncmp expect actual &&\n+    printf \"test more words\" >expect &&\n+    gettext \"test more words\" >actual &&\n+    test_i18ncmp expect actual\n+'\n+\n+test_expect_success 'eval_gettext: our eval_gettext() fallback has pass-through semantics' '\n+    printf \"test\" >expect &&\n+    eval_gettext \"test\" >actual &&\n+    test_i18ncmp expect actual &&\n+    printf \"test more words\" >expect &&\n+    eval_gettext \"test more words\" >actual &&\n+    test_i18ncmp expect actual\n+'\n+\n+test_expect_success 'eval_gettext: our eval_gettext() fallback can interpolate variables' '\n+    printf \"test YesPlease\" >expect &&\n+    GIT_INTERNAL_GETTEXT_TEST_FALLBACKS=YesPlease eval_gettext \"test \\$GIT_INTERNAL_GETTEXT_TEST_FALLBACKS\" >actual &&\n+    test_i18ncmp expect actual\n+'\n+\n+test_expect_success 'eval_gettext: our eval_gettext() fallback can interpolate variables with spaces' '\n+    cmdline=\"git am\" &&\n+    export cmdline;\n+    printf \"When you have resolved this problem run git am --resolved.\" >expect &&\n+    eval_gettext \"When you have resolved this problem run \\$cmdline --resolved.\" >actual\n+    test_i18ncmp expect actual\n+'\n+\n+test_expect_success 'eval_gettext: our eval_gettext() fallback can interpolate variables with spaces and quotes' '\n+    cmdline=\"git am\" &&\n+    export cmdline;\n+    printf \"When you have resolved this problem run \\\"git am --resolved\\\".\" >expect &&\n+    eval_gettext \"When you have resolved this problem run \\\"\\$cmdline --resolved\\\".\" >actual\n+    test_i18ncmp expect actual\n+'\n+\n+test_done\n-- \n1.7.4.4\n"},{"id":"167370","messageId":"1304856659-10672-3-git-send-email-avarab@gmail.com","threadId":"27298","inReplyTo":"1304856659-10672-1-git-send-email-avarab@gmail.com","subject":"[PATCH 2/4] git-sh-i18n.sh: add no-op gettext() and eval_gettext() wrappers","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2011-05-08T12:10:57Z","receivedAt":"2011-05-08T12:10:57Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Add a no-op wrapper library for Git's shell scripts. To split up the\ngettext series I'm first submitting patches to gettextize the source\ntree before I add any of the Makefile and Shell library changes needed\nto actually use them.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n .gitignore                    |    1 +\n Documentation/git-sh-i18n.txt |   57 +++++++++++++++++++++++++++++++++++++++++\n Makefile                      |    1 +\n git-sh-i18n.sh                |   17 ++++++++++++\n 4 files changed, 76 insertions(+), 0 deletions(-)\n create mode 100644 Documentation/git-sh-i18n.txt\n create mode 100644 git-sh-i18n.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex 1ccf797..4bdb839 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -130,6 +130,7 @@\n /git-sh-i18n\n /git-sh-i18n--envsubst\n /git-sh-setup\n+/git-sh-i18n\n /git-shell\n /git-shortlog\n /git-show\ndiff --git a/Documentation/git-sh-i18n.txt b/Documentation/git-sh-i18n.txt\nnew file mode 100644\nindex 0000000..b41b3af\n--- /dev/null\n+++ b/Documentation/git-sh-i18n.txt\n@@ -0,0 +1,57 @@\n+git-sh-i18n(1)\n+==============\n+\n+NAME\n+----\n+git-sh-i18n - Git's i18n setup code for shell scripts\n+\n+SYNOPSIS\n+--------\n+'. \"$(git --exec-path)/git-sh-i18n\"'\n+\n+DESCRIPTION\n+-----------\n+\n+This is not a command the end user would want to run.  Ever.\n+This documentation is meant for people who are studying the\n+Porcelain-ish scripts and/or are writing new ones.\n+\n+The 'git sh-i18n scriptlet is designed to be sourced (using\n+`.`) by Git's porcelain programs implemented in shell\n+script. It provides wrappers for the GNU `gettext` and\n+`eval_gettext` functions accessible through the `gettext.sh`\n+script, and provides pass-through fallbacks on systems\n+without GNU gettext.\n+\n+FUNCTIONS\n+---------\n+\n+gettext::\n+\tOn GNU systems this will be the `gettext` function from\n+\t`gettext.sh`, on Solaris it`ll be the `gettext(1)`\n+\tcommand.\n+\n+\tIf neither of those implementations are available a\n+\tdummy fall-through function is provided.\n+    \n+eval_gettext::\n+\tOn GNU systems this will be the `eval_gettext` function\n+\tfrom `gettext.sh`, on Solaris we provide an\n+\t`eval_gettext` using the\n+\tlinkgit:git-sh-i18n--envsubst[1] helper.\n+\n+\tIf neither of those implementations are available a\n+\tdummy fall-through function is provided.\n+\n+Author\n+------\n+Written by Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n+\n+Documentation\n+--------------\n+Documentation by Ævar Arnfjörð Bjarmason and the git-list\n+<git@vger.kernel.org>.\n+\n+GIT\n+---\n+Part of the linkgit:git[1] suite\ndiff --git a/Makefile b/Makefile\nindex 87c83cb..83889f3 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -381,6 +381,7 @@ SCRIPT_LIB += git-rebase--am\n SCRIPT_LIB += git-rebase--interactive\n SCRIPT_LIB += git-rebase--merge\n SCRIPT_LIB += git-sh-setup\n+SCRIPT_LIB += git-sh-i18n\n \n SCRIPT_PERL += git-add--interactive.perl\n SCRIPT_PERL += git-difftool.perl\ndiff --git a/git-sh-i18n.sh b/git-sh-i18n.sh\nnew file mode 100644\nindex 0000000..ea05e16\n--- /dev/null\n+++ b/git-sh-i18n.sh\n@@ -0,0 +1,17 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2010 Ævar Arnfjörð Bjarmason\n+#\n+# This is a skeleton no-op implementation of gettext for Git. It'll be\n+# replaced by something that uses gettext.sh in a future patch series.\n+\n+gettext () {\n+\tprintf \"%s\" \"$1\"\n+}\n+\n+eval_gettext () {\n+\tprintf \"%s\" \"$1\" | (\n+\t\texport PATH $(git sh-i18n--envsubst --variables \"$1\");\n+\t\tgit sh-i18n--envsubst \"$1\"\n+\t)\n+}\n-- \n1.7.4.4\n"},{"id":"167371","messageId":"1304856659-10672-4-git-send-email-avarab@gmail.com","threadId":"27298","inReplyTo":"1304856659-10672-1-git-send-email-avarab@gmail.com","subject":"[PATCH 3/4] git-sh-i18n.sh: add GIT_GETTEXT_POISON support","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2011-05-08T12:10:58Z","receivedAt":"2011-05-08T12:10:58Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change git-sh-i18n.sh to support the GIT_GETTEXT_POISON environment\nvariable like gettext.c does, this ensures that tests that use\ngit-sh-i18n.sh will fail under GETTEXT_POISON=YesPlease if they rely\non Git's C locale messages without declaring that they do.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n git-sh-i18n.sh |   30 +++++++++++++++++++++---------\n 1 files changed, 21 insertions(+), 9 deletions(-)\n\ndiff --git a/git-sh-i18n.sh b/git-sh-i18n.sh\nindex ea05e16..32ca59d 100644\n--- a/git-sh-i18n.sh\n+++ b/git-sh-i18n.sh\n@@ -5,13 +5,25 @@\n # This is a skeleton no-op implementation of gettext for Git. It'll be\n # replaced by something that uses gettext.sh in a future patch series.\n \n-gettext () {\n-\tprintf \"%s\" \"$1\"\n-}\n+if test -z \"$GIT_GETTEXT_POISON\"\n+then\n+\tgettext () {\n+\t\tprintf \"%s\" \"$1\"\n+\t}\n+\n+\teval_gettext () {\n+\t\tprintf \"%s\" \"$1\" | (\n+\t\t\texport PATH $(git sh-i18n--envsubst --variables \"$1\");\n+\t\t\tgit sh-i18n--envsubst \"$1\"\n+\t\t)\n+\t}\n+else\n+\tgettext () {\n+\t\tprintf \"%s\" \"# GETTEXT POISON #\"\n+\t}\n+\n+\teval_gettext () {\n+\t\tprintf \"%s\" \"# GETTEXT POISON #\"\n+\t}\n+fi\n \n-eval_gettext () {\n-\tprintf \"%s\" \"$1\" | (\n-\t\texport PATH $(git sh-i18n--envsubst --variables \"$1\");\n-\t\tgit sh-i18n--envsubst \"$1\"\n-\t)\n-}\n-- \n1.7.4.4\n"},{"id":"167372","messageId":"1304856659-10672-5-git-send-email-avarab@gmail.com","threadId":"27298","inReplyTo":"1304856659-10672-1-git-send-email-avarab@gmail.com","subject":"[PATCH 4/4] Makefile: add xgettext target for *.sh files","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2011-05-08T12:10:59Z","receivedAt":"2011-05-08T12:10:59Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change the \"pot\" target to also extract strings from our $(SCRIPT_SH)\nfiles with xgettext(1).\n\nNote that due to Jonathan Nieder's trick of doing \"mv $@+ $@\" at the\nend of the target the \"pot\" target will now warn:\n\n    $ make pot\n        XGETTEXT po/git.pot\n    po/git.pot+: warning: Charset \"CHARSET\" is not a portable encoding name.\n                          Message conversion to user's charset might not work.\n\nThis warnings is emitted because xgettext is writing into a non-*.pot\nfile, it's harmless however. The content that's written out is\nequivalent to what it would be if we were writing directly into an\nexisting POT file with --join-existing.\n\nAs part of this change I've eliminated the && chain between xgettext\ncalls, this is incompatible with $(QUIET_XGETTEXT), if the && is left\nin it'll emit:\n\n    /bin/sh: @echo: not found\n\nSince it's redundant (the Makefile will stop if there's an error) I've\nremoved it altogether.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile |    6 +++++-\n 1 files changed, 5 insertions(+), 1 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 83889f3..10252d5 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2065,10 +2065,14 @@ XGETTEXT_FLAGS = \\\n \t--from-code=UTF-8\n XGETTEXT_FLAGS_C = $(XGETTEXT_FLAGS) --language=C \\\n \t--keyword=_ --keyword=N_ --keyword=\"Q_:1,2\"\n+XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell\n LOCALIZED_C := $(C_OBJ:o=c)\n+LOCALIZED_SH := $(SCRIPT_SH)\n \n po/git.pot: $(LOCALIZED_C)\n-\t$(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ $(XGETTEXT_FLAGS_C) $(LOCALIZED_C) && \\\n+\t$(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ $(XGETTEXT_FLAGS_C) $(LOCALIZED_C)\n+\t$(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ --join-existing $(XGETTEXT_FLAGS_SH) \\\n+\t\t$(LOCALIZED_SH)\n \tmv $@+ $@\n \n pot: po/git.pot\n-- \n1.7.4.4\n"},{"id":"167431","messageId":"BANLkTi=nTSf0CQWs-ODxw=P+eX=Dc7Yf-Q@mail.gmail.com","threadId":"27298","inReplyTo":"1304856659-10672-1-git-send-email-avarab@gmail.com","subject":"Re: [PATCH 0/4] i18n: Add shell script translation infrastructure","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2011-05-08T17:03:39Z","receivedAt":"2011-05-08T17:03:39Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Sun, May 8, 2011 at 14:10, Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:\n> This adds skeleton no-op functions to git-sh-i18n.sh analogous to the\n> gettext.c skeleton functions for C, adds *.sh scripts to the \"pot\"\n> target for message extraction, and updates the git-sh-i18n--envsubst\n> tests to use the new test_i18ncmp function.\n\nI seem to remember there were some concerns about performance with a\nprevious version of this series. Have you done any before/after\ntimings on, say, the git test suite? Or am I remembering incorrectly?\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"167432","messageId":"7v1v09un8y.fsf@alter.siamese.dyndns.org","threadId":"27298","inReplyTo":"1304856659-10672-2-git-send-email-avarab@gmail.com","subject":"Re: [PATCH 1/4] git-sh-i18n--envsubst: our own envsubst(1) for eval_gettext()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-05-08T17:15:57Z","receivedAt":"2011-05-08T17:15:57Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> Add a git-sh-i18n--envsubst program which is a stripped-down version\n> of the GNU envsubst(1) program that comes with GNU gettext for use in\n> the eval_gettext() fallback\n\nOk up to this point.\n\n> ... instead of using a clever (but broken)\n> printf + eval + printf trick.\n>\n> In a previous incarnation of the gettext series I implemented the\n> eval_gettext() fallback like this:\n> ...\n> This was clever, but ...\n> ... \n> To work around this, and to improve our variable expansion behavior\n> (eval has security issues) I've imported a stripped-down version of\n> gettext's envsubst(1) program.\n\nI do not think the lengthy history of failed experiments above is worth\nexplaining. If you really want to say something to justify a new helper, I\nthink it is sufficient to just explain that it is unsolvable in shell. I\ntried that in the first 9-line paragraph in:\n\n  http://thread.gmane.org/gmane.comp.version-control.git/170703/focus=170770\n\nIn other words, \"we tried X that didn't work and we tried Y that didn't\neither, we cannot think of any better solution, so we are doing something\nelse\" is not a good justificiation for doing that \"something else\".\n\n\"Anything based on shell is an unpractical solution for this and that\nreasons, so we use this instead\" explains that the earlier failures were\nnot because we did not try hard enough.  Unlike \"tried X and Y but didn't\nwork\", dismissing \"anything based on shell\" as a whole class with clear\nexplanation why it would not work would prevent people from pursuing that\ndead-end approach.  It also avoids giving quibbling people an excuse to\nargue against importing envsubst implementation saying \"you didn't try\nhard enough\".\n\n> With it eval_gettext() is implemented\n> like this:\n> ...\n> Reported-by: Johannes Sixt <j.sixt@viscovery.net>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n\nOk.\n\n> diff --git a/Documentation/git-sh-i18n--envsubst.txt b/Documentation/git-sh-i18n--envsubst.txt\n> new file mode 100644\n> index 0000000..e146a2c\n> --- /dev/null\n> +++ b/Documentation/git-sh-i18n--envsubst.txt\n> @@ -0,0 +1,36 @@\n> ...\n> +Author\n> +------\n> +Written by Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> +\n> +Documentation\n> +--------------\n> +Documentation by Ævar Arnfjörð Bjarmason and the git-list\n> +<git@vger.kernel.org>.\n\nI do not think we do these individual credits these days in the doc.\n"},{"id":"167451","messageId":"BANLkTikSvU4haNpRmPq8o2P0yB1Y3t0Ahg@mail.gmail.com","threadId":"27298","inReplyTo":"7v1v09un8y.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 1/4] git-sh-i18n--envsubst: our own envsubst(1) for eval_gettext()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2011-05-08T21:33:46Z","receivedAt":"2011-05-08T21:33:46Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Sun, May 8, 2011 at 19:15, Junio C Hamano <gitster@pobox.com> wrote:\n> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n>\n>> Add a git-sh-i18n--envsubst program which is a stripped-down version\n>> of the GNU envsubst(1) program that comes with GNU gettext for use in\n>> the eval_gettext() fallback\n>\n> Ok up to this point.\n>\n>> ... instead of using a clever (but broken)\n>> printf + eval + printf trick.\n>>\n>> In a previous incarnation of the gettext series I implemented the\n>> eval_gettext() fallback like this:\n>> ...\n>> This was clever, but ...\n>> ...\n>> To work around this, and to improve our variable expansion behavior\n>> (eval has security issues) I've imported a stripped-down version of\n>> gettext's envsubst(1) program.\n>\n> I do not think the lengthy history of failed experiments above is worth\n> explaining. If you really want to say something to justify a new helper, I\n> think it is sufficient to just explain that it is unsolvable in shell. I\n> tried that in the first 9-line paragraph in:\n>\n>  http://thread.gmane.org/gmane.comp.version-control.git/170703/focus=170770\n>\n> In other words, \"we tried X that didn't work and we tried Y that didn't\n> either, we cannot think of any better solution, so we are doing something\n> else\" is not a good justificiation for doing that \"something else\".\n>\n> \"Anything based on shell is an unpractical solution for this and that\n> reasons, so we use this instead\" explains that the earlier failures were\n> not because we did not try hard enough.  Unlike \"tried X and Y but didn't\n> work\", dismissing \"anything based on shell\" as a whole class with clear\n> explanation why it would not work would prevent people from pursuing that\n> dead-end approach.  It also avoids giving quibbling people an excuse to\n> argue against importing envsubst implementation saying \"you didn't try\n> hard enough\".\n\nI included the failed experiments because I know for sure that those\ndon't work, but I'm not sure that this is impossible in shell, and it\nmight be possible in some non-POSIX shell (which we could optionally\ntake advantage of on certain platforms in the future).\n\nSo having the failed examples that we know don't work is valuable for\nanyone digging into this in the future.\n\nOr are we sure that this can't work in POSIX (or non-POSIX shells)?\n\n>> With it eval_gettext() is implemented\n>> like this:\n>> ...\n>> Reported-by: Johannes Sixt <j.sixt@viscovery.net>\n>> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n>\n> Ok.\n>\n>> diff --git a/Documentation/git-sh-i18n--envsubst.txt b/Documentation/git-sh-i18n--envsubst.txt\n>> new file mode 100644\n>> index 0000000..e146a2c\n>> --- /dev/null\n>> +++ b/Documentation/git-sh-i18n--envsubst.txt\n>> @@ -0,0 +1,36 @@\n>> ...\n>> +Author\n>> +------\n>> +Written by Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n>> +\n>> +Documentation\n>> +--------------\n>> +Documentation by Ævar Arnfjörð Bjarmason and the git-list\n>> +<git@vger.kernel.org>.\n>\n> I do not think we do these individual credits these days in the doc.\n\nI wrote this when that was the convention, but evidently we've changed\nthat since then.\n\nI'll remove it in the next iteration.\n"},{"id":"167452","messageId":"BANLkTikmj_urw389ad0r86OR+26AvXTVzg@mail.gmail.com","threadId":"27298","inReplyTo":"BANLkTi=nTSf0CQWs-ODxw=P+eX=Dc7Yf-Q@mail.gmail.com","subject":"Re: [PATCH 0/4] i18n: Add shell script translation infrastructure","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2011-05-08T21:38:02Z","receivedAt":"2011-05-08T21:38:02Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Sun, May 8, 2011 at 19:03, Sverre Rabbelier <srabbelier@gmail.com> wrote:\n> Heya,\n>\n> On Sun, May 8, 2011 at 14:10, Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:\n>> This adds skeleton no-op functions to git-sh-i18n.sh analogous to the\n>> gettext.c skeleton functions for C, adds *.sh scripts to the \"pot\"\n>> target for message extraction, and updates the git-sh-i18n--envsubst\n>> tests to use the new test_i18ncmp function.\n>\n> I seem to remember there were some concerns about performance with a\n> previous version of this series. Have you done any before/after\n> timings on, say, the git test suite? Or am I remembering incorrectly?\n\nWhen I benchmark this on my (Linux) system it runs at 0% difference\nbetween the current test suite and the one with this series.\n\nThe concern was about Windows, where forks are more expensive, so\ne.g. every time we shell out to sed/awk/perl/grep or\ngit-sh-i18n--envsubst we incur a larger speed hit than on Unix\nsystems.\n"},{"id":"167455","messageId":"BANLkTinnv=hm80h=9P80t=3QvwS-BQ7D=A@mail.gmail.com","threadId":"27298","inReplyTo":"BANLkTikmj_urw389ad0r86OR+26AvXTVzg@mail.gmail.com","subject":"Re: [PATCH 0/4] i18n: Add shell script translation infrastructure","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2011-05-08T21:45:24Z","receivedAt":"2011-05-08T21:45:24Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\n[+msysgit people]\n\nOn Sun, May 8, 2011 at 23:38, Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:\n> On Sun, May 8, 2011 at 19:03, Sverre Rabbelier <srabbelier@gmail.com> wrote:\n>> On Sun, May 8, 2011 at 14:10, Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:\n>>> This adds skeleton no-op functions to git-sh-i18n.sh analogous to the\n>>> gettext.c skeleton functions for C, adds *.sh scripts to the \"pot\"\n>>> target for message extraction, and updates the git-sh-i18n--envsubst\n>>> tests to use the new test_i18ncmp function.\n>>\n>> I seem to remember there were some concerns about performance with a\n>> previous version of this series. Have you done any before/after\n>> timings on, say, the git test suite? Or am I remembering incorrectly?\n>\n> When I benchmark this on my (Linux) system it runs at 0% difference\n> between the current test suite and the one with this series.\n>\n> The concern was about Windows, where forks are more expensive, so\n> e.g. every time we shell out to sed/awk/perl/grep or\n> git-sh-i18n--envsubst we incur a larger speed hit than on Unix\n> systems.\n\nPerhaps one of the windows devs can benchmark this then? Ævar, where\ndo you have a pullable version of this series? Your github fork has\nquite a few branches.\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"167456","messageId":"BANLkTinOkM+MTwq46mvPs1G5fQmGvxknrg@mail.gmail.com","threadId":"27298","inReplyTo":"BANLkTinnv=hm80h=9P80t=3QvwS-BQ7D=A@mail.gmail.com","subject":"Re: [PATCH 0/4] i18n: Add shell script translation infrastructure","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2011-05-08T21:52:01Z","receivedAt":"2011-05-08T21:52:01Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Sun, May 8, 2011 at 23:45, Sverre Rabbelier <srabbelier@gmail.com> wrote:\n> Heya,\n>\n> [+msysgit people]\n>\n> On Sun, May 8, 2011 at 23:38, Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:\n>> On Sun, May 8, 2011 at 19:03, Sverre Rabbelier <srabbelier@gmail.com> wrote:\n>>> On Sun, May 8, 2011 at 14:10, Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:\n>>>> This adds skeleton no-op functions to git-sh-i18n.sh analogous to the\n>>>> gettext.c skeleton functions for C, adds *.sh scripts to the \"pot\"\n>>>> target for message extraction, and updates the git-sh-i18n--envsubst\n>>>> tests to use the new test_i18ncmp function.\n>>>\n>>> I seem to remember there were some concerns about performance with a\n>>> previous version of this series. Have you done any before/after\n>>> timings on, say, the git test suite? Or am I remembering incorrectly?\n>>\n>> When I benchmark this on my (Linux) system it runs at 0% difference\n>> between the current test suite and the one with this series.\n>>\n>> The concern was about Windows, where forks are more expensive, so\n>> e.g. every time we shell out to sed/awk/perl/grep or\n>> git-sh-i18n--envsubst we incur a larger speed hit than on Unix\n>> systems.\n>\n> Perhaps one of the windows devs can benchmark this then? Ævar, where\n> do you have a pullable version of this series? Your github fork has\n> quite a few branches.\n\nIt's ab/i18n-sh-only in git://github.com/avar/git.git\n\nThere was some discussion about this a while ago, not sure what came\nout of that, but there were some msysgit patches involved IIRC.\n"},{"id":"167457","messageId":"7vsjsor29t.fsf@alter.siamese.dyndns.org","threadId":"27298","inReplyTo":"BANLkTikSvU4haNpRmPq8o2P0yB1Y3t0Ahg@mail.gmail.com","subject":"Re: [PATCH 1/4] git-sh-i18n--envsubst: our own envsubst(1) for eval_gettext()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-05-09T03:17:18Z","receivedAt":"2011-05-09T03:17:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n> Or are we sure that this can't work in POSIX (or non-POSIX shells)?\n\nYou need to implement the same logic to tokenize enough to understand the\nexpansion the shell does inside dq.  Yes, shell is general programming\nlanguage and you can theoretically implement it, but would the result be a\npractical solution?  I doubt it.\n"},{"id":"167470","messageId":"BANLkTino5PpXY8eD+T3Ki+2Xn1MLjZojTQ@mail.gmail.com","threadId":"27298","inReplyTo":"7vsjsor29t.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 1/4] git-sh-i18n--envsubst: our own envsubst(1) for eval_gettext()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2011-05-09T07:52:09Z","receivedAt":"2011-05-09T07:52:09Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Mon, May 9, 2011 at 05:17, Junio C Hamano <gitster@pobox.com> wrote:\n> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n>\n>> Or are we sure that this can't work in POSIX (or non-POSIX shells)?\n>\n> You need to implement the same logic to tokenize enough to understand the\n> expansion the shell does inside dq.  Yes, shell is general programming\n> language and you can theoretically implement it, but would the result be a\n> practical solution?  I doubt it.\n\nI'll write a better commit message and re-send this soon (after some\nother comments have trickled in).\n"}]}