[Top][All Lists]

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

making complex statements i18n friendly

From: Ben Pfaff
Subject: making complex statements i18n friendly
Date: Sat, 03 Nov 2007 13:33:15 -0700
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1 (gnu/linux)

In GNU PSPP, I like to use detailed error messages that make it
clear what has gone wrong.  Unfortunately, sometimes this
interacts badly with i18n.

Here is one example.  As you can see, it is attempting to ensure
that a file cannot be opened for more than one purpose and, if
this is attempted, give error messages that say exactly how the
different purposes are being mixed:

      if (strcmp (lock->type, type))
          if (access == FH_ACC_READ)
            msg (SE, _("Can't read from %s as a %s because it is "
                       "already being read as a %s."),
                 fh_get_name (h), gettext (type), gettext (lock->type));
            msg (SE, _("Can't write to %s as a %s because it is "
                       "already being written as a %s."),
                 fh_get_name (h), gettext (type), gettext (lock->type));
          return NULL;
      else if (exclusive || lock->exclusive)
          msg (SE, _("Can't re-open %s as a %s."), 
               fh_get_name (h), gettext (type));
          return NULL;

As John Darrington pointed out, this won't work out so well in
some languages.  The easiest solution would be to change the
error messages to be more generic, e.g. "Can't treat %s as two
different kinds of files," but this would make the actual problem
less apparent to the user.

It probably is not practical to write out a separate message for
each pairing of (current type, attempted type), because that
would be a pretty large set of messages.  It would also force a
central registry of types of files, which doesn't make me happy.

Here is another example:

      const char *allowed[3];
      int allowed_cnt;
      char *s;

      allowed_cnt = 0;
      if (command->states & S_INITIAL)
        allowed[allowed_cnt++] = _("before the active file has been defined");
      else if (command->states & S_DATA)
        allowed[allowed_cnt++] = _("after the active file has been defined");
      if (command->states & S_INPUT_PROGRAM)
        allowed[allowed_cnt++] = _("inside INPUT PROGRAM");
      if (command->states & S_FILE_TYPE)
        allowed[allowed_cnt++] = _("inside FILE TYPE");

      if (allowed_cnt == 1)
        s = xstrdup (allowed[0]);
      else if (allowed_cnt == 2)
        s = xasprintf (_("%s or %s"), allowed[0], allowed[1]);
      else if (allowed_cnt == 3)
        s = xasprintf (_("%s, %s, or %s"), allowed[0], allowed[1], allowed[2]);
        NOT_REACHED ();

      msg (SE, _("%s is allowed only %s."), command->name, s);

      free (s);

In this case there are 14 possible error messages, which is a bit
many to write out explicitly.  Again, I could simply make the
error message something like "%s is not allowed in this state,"
but that doesn't help the user nearly as much as saying exactly
where the command may be placed.

I would not mind suggestions for how to handle these specific
cases, but more than that I am after general principles on how to
handle these and similar cases.  Ideas?


"Let others praise ancient times; I am glad I was born in these."
--Ovid (43 BC-18 AD)

reply via email to

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