bug-coreutils
[Top][All Lists]
Advanced

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

Re: tr '[:upper:]' '[:lower:]' -- misaligned construct


From: Jim Meyering
Subject: Re: tr '[:upper:]' '[:lower:]' -- misaligned construct
Date: Sat, 05 Jan 2008 10:01:58 +0100

Gerald Pfeifer <address@hidden> wrote:
> I've been using  tr '[:upper:]' '[:lower:]'  for a while, but with
> version 6.9.90 (and 6.9.91) I know get the following hard error:
>
>   address@hidden:~> echo 'AbCd' | tr '[:lower:]' '[:upper:]'
>   ABCD
>
>   address@hidden:~> echo 'AbCd' | tr '[:upper:]' '[:lower:]'
>   tr: misaligned [:upper:] and/or [:lower:] construct
>
> That machine is running in an ISO-8859 locale on openSUSE 11.0 FACTORY:
>
>   address@hidden:~> set | egrep '^(LANG|LC)'
>   LANG=en_US.iso-8859-1
>   LC_COLLATE=C
>
> I searched Google, the mailing list archives, and checked the ChangeLog
> in git but didn't find any matching information.  Earlier versions as
> well as FreeBSD 6.2 tr and Solaris 9 tr process both invocations above
> as expected.
>
> To exclude any problems caused by the alpha status of openSUSE FACTORY
> I also downloaded coreutils-6.9.91 and built it (./configure ; make)
> on an openSUSE 10.3 machine.  The result is the same.

Hi Gerald,

Thank you for the bug report.

That locale definition has 3 more upper-case letters than lower-case,
and GNU tr's implementation has always required that the
lists of upper- and lower- case characters -- defined by
the isupper and islower functions -- have the same length.

I'll look into removing that requirement.

Here's a program to demonstrate:

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <locale.h>
int
main ()
{
  int n_upper = 0;
  int n_lower = 0;
  int i;

  setlocale (LC_ALL, "");

  for (i = 0; i < 256; i++)
    {
      printf ("%d %c: %s %s\n",
              i, i, islower (i) ? "  U" : "", isupper (i) ? "L" : "");
      if (isupper (i))
        ++n_upper;
      if (islower (i))
        ++n_lower;
    }
  return !(n_lower == n_upper);
}

$ gcc -O -W -Wall char-class-check.c
$ LC_ALL=en_US ./a.out|grep -c ':  L'
56
$ LC_ALL=en_US ./a.out|grep -c ':   U'
59




reply via email to

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