bug-gnu-utils
[Top][All Lists]
Advanced

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

Re: [gettext] changequote considered harmful


From: Bruno Haible
Subject: Re: [gettext] changequote considered harmful
Date: Tue, 2 Aug 2005 12:58:32 +0200
User-agent: KMail/1.5

Stepan Kasal wrote:
> You spoke about mixing different syntaxes.  Well that's an important feature
> of macro languages:  literal text is intermixed with macro calls.
> 
> On one side, this simplicity is one of the most appealing properties of
> macro languages.
> 
> OTOH, this means you inevitably get into situation where some text/code is
> screwed ^H^H^H^H^H^H^H^Hexpanded even though it was meant as literal 
> text/code.
>
> To fix this problem, you have to mark the literal text with \begin{verbatim}
> \end{verbatim} or some such.

The desirable way to mix C or sh syntax and a macro language - for me as
someone who has to maintain some of these macros - is so that
  1) A valid C or sh snippet without specific macro invocations is
     valid inside the macro, and does not change its meaning.
     Brackets count as normal C or sh syntax here, since they are frequent
     in C and sh.
  2) There is a way to insert macro invocation in C or sh snippets,
     either directly by writing    MACRONAME(ARGS)   or with some similar
     syntax.
  3) There is normally no need to switch into a TeX {verbatim} or XML CDATA
     section, because 1) is usually enough.

This is my goal. I will accept patches that go in this direction.


About the first part of your patch:

> --- gettext-runtime/m4/gettext.m4       27 Jul 2005 11:27:55 -0000      1.37
> +++ gettext-runtime/m4/gettext.m4       28 Jul 2005 12:09:07 -0000
> @@ -130,13 +130,11 @@
>          AC_CACHE_CHECK([for GNU gettext in libc], gt_cv_func_gnugettext_libc,
>           [AC_TRY_LINK([#include <libintl.h>
>  ]ifelse([$2], [need-formatstring-macros],
> -[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
> +[[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
>  #define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1)
>  #endif
> -changequote(,)dnl
>  typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
> -changequote([,])dnl
> -], [])[extern int _nl_msg_cat_cntr;
> +]], [])[extern int _nl_msg_cat_cntr;
>  extern int *_nl_domain_bindings;],
>              [bindtextdomain ("", "");
>  return * gettext ("")]ifelse([$2], [need-ngettext], [ + * ngettext ("", "", 
> 0)], [])[ + _nl_msg_cat_cntr + *_nl_domain_bindings],

This patch works, and satisfies goals 1 and 2 better than the previous
code that uses changequote. Namely, suppose I want to use a macro

   AC_DEFUN([AM_TYPEDEF], [typedef])

instead of writing 'typedef' literally, then by writing as the AC_TRY_LINK
argument

[...
changequote(,)dnl
AM_TYPEDEF int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
changequote([,])dnl
...]

or

[[...
AM_TYPEDEF int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
...]]

I always get the undesired result

AM_TYPEDEF int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];

By writing

[...
changequote(,)dnl
AM_TYPEDEF int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
changequote([,])dnl
...]

or

[...
changequote(<<,>>)dnl
>>AM_TYPEDEF<< int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
changequote([,])dnl
...]

I get a stack overflow ("ERROR: Recursion limit of 1024 exceeded").

Whereas

[[...
]AM_TYPEDEF[ int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
...]]

or

[[...
]]AM_TYPEDEF[[ int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
...]]

produce the desired

typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];

So I'm applying this part. Thanks.


About the second part of your patch:

> @@ -515,15 +509,15 @@
>    else
>      dnl Found it, now check the version.
>      AC_MSG_CHECKING([version of bison])
> -changequote(<<,>>)dnl
> +    [
>      ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* 
> \([0-9]*\.[0-9.]*\).*$/\1/p'`
>      case $ac_prog_version in
>        '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
>        1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*)
> -changequote([,])dnl
>           ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
>        *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;
>      esac
> +    ]
>      AC_MSG_RESULT([$ac_prog_version])
>    fi
>    if test $ac_verc_fail = yes; then

This has two problems that the original changequote code doesn't have:
Goal 2 not satisfied:
  - dnl comments are not recognized; instead they are sent out to the
    'configure' file, where they are misplaced.
  - Macro invocations are not recognized but sent to the 'configure' file
    as well.
The use of the brackets here thus resembles the aforementioned verbatim
mode, which I don't find usually desirable. In these areas, I want the
macro processor only to preserve brackets, not dnl comments and macro
invocations.

The style that fulfills goals 1 and 2 here is like this:

  [...
    # Found it, now check the version.
    ]AC_MSG_CHECKING([version of bison])[
    ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* 
\([0-9]*\.[0-9.]*\).*$/\1/p'`
    case $ac_prog_version in
      '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
      1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*)
         ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
      *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;
    esac
    ]AC_MSG_RESULT([$ac_prog_version])[
  ...]

I.e. put braces around everything, but unbrace the macro invocations and
don't put dnl comments. Unfortunately as long as autoconf does not recommend
this style, other people will not like this style; therefore I cannot really
use this style yet.

          Bruno





reply via email to

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