enum word_type
{
t_string, /* constant string */
+ t_assignment, /* variable assignment */
t_other, /* other string */
t_separator, /* command separator: semicolon or newline */
t_redirect, /* redirection: one of < > >| << <<- >> <> <& >& */
{
int c;
bool all_unquoted_digits;
+ bool all_unquoted_name_characters;
do
{
wp->token = XMALLOC (struct token);
init_token (wp->token);
wp->line_number_at_start = line_number;
+ /* True while all characters in the token seen so far are digits. */
all_unquoted_digits = true;
+ /* True while all characters in the token seen so far form a "name":
+ all characters are unquoted underscores, digits, or alphabetics from the
+ portable character set, and the first character is not a digit. Cf.
+ <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_235>
+ */
+ all_unquoted_name_characters = true;
for (;; c = phase2_getc ())
{
all_unquoted_digits = all_unquoted_digits && (c >= '0' && c <= '9');
+ if (all_unquoted_name_characters && wp->token->charcount > 0 && c == '=')
+ {
+ wp->type = t_assignment;
+ continue;
+ }
+
+ all_unquoted_name_characters =
+ all_unquoted_name_characters
+ && ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_'
+ || (wp->token->charcount > 0 && c >= '0' && c <= '9'));
+
if (c == '$')
{
int c2;
{
/* This is the function position. */
arg = 0;
- if (inner.type == t_string)
+ if (inner.type == t_assignment)
+ {
+ /* An assignment just set an environment variable.
+ Ignore it. */
+ }
+ else if (inner.type == t_string)
{
char *function_name = string_of_word (&inner);
- void *keyword_value;
- if (hash_find_entry (&keywords,
- function_name, strlen (function_name),
- &keyword_value)
- == 0)
- shapes = (const struct callshapes *) keyword_value;
-
- argparser = arglist_parser_alloc (mlp, shapes);
-
- context_iter =
- flag_context_list_iterator (
- flag_context_list_table_lookup (
- flag_context_list_table,
- function_name, strlen (function_name)));
+ if (strcmp (function_name, "env") == 0)
+ {
+ /* The 'env' command just introduces more assignments.
+ Ignore it. */
+ }
+ else
+ {
+ void *keyword_value;
+
+ if (hash_find_entry (&keywords,
+ function_name,
+ strlen (function_name),
+ &keyword_value)
+ == 0)
+ shapes = (const struct callshapes *) keyword_value;
+
+ argparser = arglist_parser_alloc (mlp, shapes);
+
+ context_iter =
+ flag_context_list_iterator (
+ flag_context_list_table_lookup (
+ flag_context_list_table,
+ function_name, strlen (function_name)));
+ }
free (function_name);
}
--- /dev/null
+#!/bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test of Shell support: assignment syntax.
+
+cat <<\EOF > xg-sh-7.sh
+gettext 'immediate invocation'
+foo=bar gettext 'invocation with 1 environment variable'
+foo=bar FOO=baz gettext 'invocation with 2 environment variables'
+env gettext 'invocation with env'
+env foo=bar gettext 'invocation with env and 1 environment variable'
+env foo=bar FOO=baz gettext 'invocation with env and 2 environment variables'
+'foo'=bar gettext 'invocation after a non-assignment 1'
+"foo"=bar gettext 'invocation after a non-assignment 2'
+fo\o=bar gettext 'invocation after a non-assignment 3'
+foo'='bar gettext 'invocation after a non-assignment 4'
+foo"="bar gettext 'invocation after a non-assignment 5'
+foo\=bar gettext 'invocation after a non-assignment 6'
+7=bar gettext 'invocation after a non-assignment 7'
+océ=bar gettext 'invocation after a non-assignment 8'
+f0oO_=bar gettext 'invocation with a mixed environment variable'
+EOF
+
+: ${XGETTEXT=xgettext}
+${XGETTEXT} --omit-header --no-location -d xg-sh-7.tmp xg-sh-7.sh || Exit 1
+LC_ALL=C tr -d '\r' < xg-sh-7.tmp.po > xg-sh-7.po || Exit 1
+
+cat <<\EOF > xg-sh-7.ok
+msgid "immediate invocation"
+msgstr ""
+
+msgid "invocation with 1 environment variable"
+msgstr ""
+
+msgid "invocation with 2 environment variables"
+msgstr ""
+
+msgid "invocation with env"
+msgstr ""
+
+msgid "invocation with env and 1 environment variable"
+msgstr ""
+
+msgid "invocation with env and 2 environment variables"
+msgstr ""
+
+msgid "invocation with a mixed environment variable"
+msgstr ""
+EOF
+
+: ${DIFF=diff}
+${DIFF} xg-sh-7.ok xg-sh-7.po
+result=$?
+
+exit $result