diff options
32 files changed, 4648 insertions, 0 deletions
diff --git a/test/locale/Makefile b/test/locale/Makefile new file mode 100644 index 000000000..0ab07f7aa --- /dev/null +++ b/test/locale/Makefile @@ -0,0 +1,31 @@ +# uClibc locale tests +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. +#	 tst_mbtowc tst_strcoll tst_strfmon tst_strxfrm    \ + +TESTS := bug-iconv-trans bug-usesetlocale collate-test dump-ctype \ +	 gen-unicode-ctype show-ucs-data tst-ctype \ +	 tst-digits tst-fmon tst-langinfo tst-leaks tst-mbswcs1 \ +	 tst-mbswcs2 tst-mbswcs3 tst-mbswcs4 tst-mbswcs5 tst-mbswcs6 \ +	 tst_nl_langinfo tst-numeric tst-rpmatch tst-setlocale \ +	 tst-sscanf tst-strfmon1 tst-trans tst-wctype tst-xlocale1 \ +	 tst-xlocale2 xfrm-test + + +# NOTE: For now disabled some tests that are known not build +TESTS_DISABLED := tst-ctype tst-fmon tst-leaks tst-rpmatch tst-strfmon1 + +ifneq ($(UCLIBC_HAS_XLOCALE),y) +TESTS_DISABLED += bug-usesetlocale tst-xlocale1 tst-xlocale2 xfrm-test tst-C-locale +endif + +include ../Test.mak + +DODIFF_rint     := 1 + +EXTRA_CFLAGS    := -D__USE_GNU -fno-builtin + +OPTS_dump-ctype = C +OPTS_tst-ctype = < tst-ctype-de_DE.ISO-8859-1.in +OPTS_tst-langinfo = < tst-langinfo.input + +EXTRA_CLEAN := C diff --git a/test/locale/bug-iconv-trans.c b/test/locale/bug-iconv-trans.c new file mode 100644 index 000000000..3886247c3 --- /dev/null +++ b/test/locale/bug-iconv-trans.c @@ -0,0 +1,68 @@ +#include <iconv.h> +#include <locale.h> +#include <stdio.h> +#include <string.h> + +int +main (void) +{ +  iconv_t cd; +  const char str[] = "ÄäÖöÜüß"; +  const char expected[] = "AEaeOEoeUEuess"; +  char *inptr = (char *) str; +  size_t inlen = strlen (str) + 1; +  char outbuf[500]; +  char *outptr = outbuf; +  size_t outlen = sizeof (outbuf); +  int result = 0; +  size_t n; + +  if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL) +    { +      puts ("setlocale failed"); +      return 1; +    } + +  cd = iconv_open ("ANSI_X3.4-1968//TRANSLIT", "ISO-8859-1"); +  if (cd == (iconv_t) -1) +    { +      puts ("iconv_open failed"); +      return 1; +    } + +  n = iconv (cd, &inptr, &inlen, &outptr, &outlen); +  if (n != 7) +    { +      if (n == (size_t) -1) +	printf ("iconv() returned error: %m\n"); +      else +	printf ("iconv() returned %Zd, expected 7\n", n); +      result = 1; +    } +  if (inlen != 0) +    { +      puts ("not all input consumed"); +      result = 1; +    } +  else if (inptr - str != strlen (str) + 1) +    { +      printf ("inptr wrong, advanced by %td\n", inptr - str); +      result = 1; +    } +  if (memcmp (outbuf, expected, sizeof (expected)) != 0) +    { +      printf ("result wrong: \"%.*s\", expected: \"%s\"\n", +	      (int) (sizeof (outbuf) - outlen), outbuf, expected); +      result = 1; +    } +  else if (outlen != sizeof (outbuf) - sizeof (expected)) +    { +      printf ("outlen wrong: %Zd, expected %Zd\n", outlen, +	      sizeof (outbuf) - 15); +      result = 1; +    } +  else +    printf ("output is \"%s\" which is OK\n", outbuf); + +  return result; +} diff --git a/test/locale/bug-usesetlocale.c b/test/locale/bug-usesetlocale.c new file mode 100644 index 000000000..0637067de --- /dev/null +++ b/test/locale/bug-usesetlocale.c @@ -0,0 +1,38 @@ +/* Test case for setlocale vs uselocale (LC_GLOBAL_LOCALE) bug.  */ + +#define _GNU_SOURCE 1 +#include <locale.h> +#include <stdio.h> +#include <ctype.h> + +static int +do_test (void) +{ +  __locale_t loc_new, loc_old; + +  int first = !!isalpha(0xE4); + +  setlocale (LC_ALL, "de_DE"); + +  int global_de = !!isalpha(0xE4); + +  loc_new = newlocale (1 << LC_ALL, "C", 0); +  loc_old = uselocale (loc_new); + +  int used_c = !!isalpha(0xE4); + +  uselocale (loc_old); + +  int used_global = !!isalpha(0xE4); + +  printf ("started %d, after setlocale %d\n", first, global_de); +  printf ("after uselocale %d, after LC_GLOBAL_LOCALE %d\n", +	  used_c, used_global); + +  freelocale (loc_new); +  return !(used_c == first && used_global == global_de); +} + + +#define TEST_FUNCTION do_test () +#include "test-skeleton.c" diff --git a/test/locale/collate-test.c b/test/locale/collate-test.c new file mode 100644 index 000000000..e8f43218f --- /dev/null +++ b/test/locale/collate-test.c @@ -0,0 +1,133 @@ +/* Test collation function using real data. +   Copyright (C) 1997, 1999, 2000, 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <ctype.h> +#include <error.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +struct lines +{ +  char *key; +  char *line; +}; + +static int xstrcoll (const void *, const void *); + +int +main (int argc, char *argv[]) +{ +  int result = 0; +  size_t nstrings, nstrings_max; +  struct lines *strings; +  char *line = NULL; +  size_t len = 0; +  size_t n; + +  if (argc < 2) +    error (1, 0, "usage: %s <random seed>", argv[0]); + +  setlocale (LC_ALL, ""); + +  nstrings_max = 100; +  nstrings = 0; +  strings = (struct lines *) malloc (nstrings_max * sizeof (struct lines)); +  if (strings == NULL) +    { +      perror (argv[0]); +      exit (1); +    } + +  while (1) +    { +      int l; +      if (getline (&line, &len, stdin) < 0) +	break; + +      if (nstrings == nstrings_max) +	{ +	  strings = (struct lines *) realloc (strings, +					      (nstrings_max *= 2) +					       * sizeof (*strings)); +	  if (strings == NULL) +	    { +	      perror (argv[0]); +	      exit (1); +	    } +	} +      strings[nstrings].line = strdup (line); +      l = strcspn (line, ":(;"); +      while (l > 0 && isspace (line[l - 1])) +	--l; +      strings[nstrings].key = strndup (line, l); +      ++nstrings; +    } +  free (line); + +  /* First shuffle.  */ +  srandom (atoi (argv[1])); +  for (n = 0; n < 10 * nstrings; ++n) +    { +      int r1, r2, r; +      size_t idx1 = random () % nstrings; +      size_t idx2 = random () % nstrings; +      struct lines tmp = strings[idx1]; +      strings[idx1] = strings[idx2]; +      strings[idx2] = tmp; + +      /* While we are at it a first little test.  */ +      r1 = strcoll (strings[idx1].key, strings[idx2].key); +      r2 = strcoll (strings[idx2].key, strings[idx1].key); +      r = r1 * r2; + +      if (r > 0 || (r == 0 && r1 != 0) || (r == 0 && r2 != 0)) +	printf ("`%s' and `%s' collate wrong: %d vs. %d\n", +		strings[idx1].key, strings[idx2].key, r1, r2); +    } + +  /* Now sort.  */ +  qsort (strings, nstrings, sizeof (struct lines), xstrcoll); + +  /* Print the result.  */ +  for (n = 0; n < nstrings; ++n) +    { +      fputs (strings[n].line, stdout); +      free (strings[n].line); +      free (strings[n].key); +    } +  free (strings); + +  return result; +} + + +static int +xstrcoll (ptr1, ptr2) +     const void *ptr1; +     const void *ptr2; +{ +  const struct lines *l1 = (const struct lines *) ptr1; +  const struct lines *l2 = (const struct lines *) ptr2; + +  return strcoll (l1->key, l2->key); +} diff --git a/test/locale/dump-ctype.c b/test/locale/dump-ctype.c new file mode 100644 index 000000000..a1f24c656 --- /dev/null +++ b/test/locale/dump-ctype.c @@ -0,0 +1,164 @@ +/* Dump the character classes and character maps of a locale to a bunch +   of individual files which can be processed with diff, sed etc. +   Copyright (C) 2000 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Bruno Haible <haible@clisp.cons.org>, 2000. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +/* Usage example: +     $ dump-ctype de_DE.UTF-8 + */ + +#include <stdio.h> +#include <stdlib.h> +#include <wctype.h> +#include <locale.h> +#include <sys/stat.h> +#include <unistd.h> +#include <errno.h> + +static const char *program_name = "dump-ctype"; +static const char *locale; + +static const char *class_names[] = +  { +    "alnum", "alpha", "blank", "cntrl", "digit", "graph", "lower", +    "print", "punct", "space", "upper", "xdigit" +  }; + +static const char *map_names[] = +  { +    "tolower", "toupper", "totitle" +  }; + +static void dump_class (const char *class_name) +{ +  wctype_t class; +  FILE *f; +  unsigned int ch; + +  class = wctype (class_name); +  if (class == (wctype_t) 0) +    { +      fprintf (stderr, "%s %s: noexistent class %s\n", program_name, +	       locale, class_name); +      return; +    } + +  f = fopen (class_name, "w"); +  if (f == NULL) +    { +      fprintf (stderr, "%s %s: cannot open file %s/%s\n", program_name, +	       locale, locale, class_name); +      exit (1); +    } + +  for (ch = 0; ch < 0x10000; ch++) +    if (iswctype (ch, class)) +      fprintf (f, "0x%04X\n", ch); + +  if (ferror (f) || fclose (f)) +    { +      fprintf (stderr, "%s %s: I/O error on file %s/%s\n", program_name, +	       locale, locale, class_name); +      exit (1); +    } +} + +static void dump_map (const char *map_name) +{ +  wctrans_t map; +  FILE *f; +  unsigned int ch; + +  map = wctrans (map_name); +  if (map == (wctrans_t) 0) +    { +      fprintf (stderr, "%s %s: noexistent map %s\n", program_name, +	       locale, map_name); +      return; +    } + +  f = fopen (map_name, "w"); +  if (f == NULL) +    { +      fprintf (stderr, "%s %s: cannot open file %s/%s\n", program_name, +	       locale, locale, map_name); +      exit (1); +    } + +  for (ch = 0; ch < 0x10000; ch++) +    if (towctrans (ch, map) != ch) +      fprintf (f, "0x%04X\t0x%04X\n", ch, towctrans (ch, map)); + +  if (ferror (f) || fclose (f)) +    { +      fprintf (stderr, "%s %s: I/O error on file %s/%s\n", program_name, +	       locale, locale, map_name); +      exit (1); +    } +} + +int +main (int argc, char *argv[]) +{ +  size_t i; + +  if (argc != 2) +    { +      fprintf (stderr, "Usage: dump-ctype locale\n"); +      exit (1); +    } +  locale = argv[1]; + +  if (setlocale (LC_ALL, locale) == NULL) +    { +      fprintf (stderr, "%s: setlocale cannot switch to locale %s\n", +	       program_name, locale); +      exit (1); +    } + +  if (mkdir (locale, 0777) < 0) +    { +      char buf[100]; +      int save_errno = errno; + +      sprintf (buf, "%s: cannot create directory %s", program_name, locale); +      errno = save_errno; +      perror (buf); +      exit (1); +    } + +  if (chdir (locale) < 0) +    { +      char buf[100]; +      int save_errno = errno; + +      sprintf (buf, "%s: cannot chdir to %s", program_name, locale); +      errno = save_errno; +      perror (buf); +      exit (1); +    } + +  for (i = 0; i < sizeof (class_names) / sizeof (class_names[0]); i++) +    dump_class (class_names[i]); + +  for (i = 0; i < sizeof (map_names) / sizeof (map_names[0]); i++) +    dump_map (map_names[i]); + +  return 0; +} diff --git a/test/locale/gen-unicode-ctype.c b/test/locale/gen-unicode-ctype.c new file mode 100644 index 000000000..849f272ed --- /dev/null +++ b/test/locale/gen-unicode-ctype.c @@ -0,0 +1,785 @@ +/* Generate a Unicode conforming LC_CTYPE category from a UnicodeData file. +   Copyright (C) 2000-2001 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Bruno Haible <haible@clisp.cons.org>, 2000. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +/* Usage example: +     $ gen-unicode /usr/local/share/Unidata/UnicodeData.txt 3.1 + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <time.h> + +/* This structure represents one line in the UnicodeData.txt file.  */ +struct unicode_attribute +{ +  const char *name;           /* Character name */ +  const char *category;       /* General category */ +  const char *combining;      /* Canonical combining classes */ +  const char *bidi;           /* Bidirectional category */ +  const char *decomposition;  /* Character decomposition mapping */ +  const char *decdigit;       /* Decimal digit value */ +  const char *digit;          /* Digit value */ +  const char *numeric;        /* Numeric value */ +  int mirrored;               /* mirrored */ +  const char *oldname;        /* Old Unicode 1.0 name */ +  const char *comment;        /* Comment */ +  unsigned int upper;         /* Uppercase mapping */ +  unsigned int lower;         /* Lowercase mapping */ +  unsigned int title;         /* Titlecase mapping */ +}; + +/* Missing fields are represented with "" for strings, and NONE for +   characters.  */ +#define NONE (~(unsigned int)0) + +/* The entire contents of the UnicodeData.txt file.  */ +struct unicode_attribute unicode_attributes [0x110000]; + +/* Stores in unicode_attributes[i] the values from the given fields.  */ +static void +fill_attribute (unsigned int i, +		const char *field1, const char *field2, +		const char *field3, const char *field4, +		const char *field5, const char *field6, +		const char *field7, const char *field8, +		const char *field9, const char *field10, +		const char *field11, const char *field12, +		const char *field13, const char *field14) +{ +  struct unicode_attribute * uni; + +  if (i >= 0x110000) +    { +      fprintf (stderr, "index too large\n"); +      exit (1); +    } +  if (strcmp (field2, "Cs") == 0) +    /* Surrogates are UTF-16 artefacts, not real characters. Ignore them.  */ +    return; +  uni = &unicode_attributes[i]; +  /* Copy the strings.  */ +  uni->name          = strdup (field1); +  uni->category      = (field2[0] == '\0' ? "" : strdup (field2)); +  uni->combining     = (field3[0] == '\0' ? "" : strdup (field3)); +  uni->bidi          = (field4[0] == '\0' ? "" : strdup (field4)); +  uni->decomposition = (field5[0] == '\0' ? "" : strdup (field5)); +  uni->decdigit      = (field6[0] == '\0' ? "" : strdup (field6)); +  uni->digit         = (field7[0] == '\0' ? "" : strdup (field7)); +  uni->numeric       = (field8[0] == '\0' ? "" : strdup (field8)); +  uni->mirrored      = (field9[0] == 'Y'); +  uni->oldname       = (field10[0] == '\0' ? "" : strdup (field10)); +  uni->comment       = (field11[0] == '\0' ? "" : strdup (field11)); +  uni->upper = (field12[0] =='\0' ? NONE : strtoul (field12, NULL, 16)); +  uni->lower = (field13[0] =='\0' ? NONE : strtoul (field13, NULL, 16)); +  uni->title = (field14[0] =='\0' ? NONE : strtoul (field14, NULL, 16)); +} + +/* Maximum length of a field in the UnicodeData.txt file.  */ +#define FIELDLEN 120 + +/* Reads the next field from STREAM.  The buffer BUFFER has size FIELDLEN. +   Reads up to (but excluding) DELIM. +   Returns 1 when a field was successfully read, otherwise 0.  */ +static int +getfield (FILE *stream, char *buffer, int delim) +{ +  int count = 0; +  int c; + +  for (; (c = getc (stream)), (c != EOF && c != delim); ) +    { +      /* The original unicode.org UnicodeData.txt file happens to have +	 CR/LF line terminators.  Silently convert to LF.  */ +      if (c == '\r') +	continue; + +      /* Put c into the buffer.  */ +      if (++count >= FIELDLEN - 1) +	{ +	  fprintf (stderr, "field too long\n"); +	  exit (1); +	} +      *buffer++ = c; +    } + +  if (c == EOF) +    return 0; + +  *buffer = '\0'; +  return 1; +} + +/* Stores in unicode_attributes[] the entire contents of the UnicodeData.txt +   file.  */ +static void +fill_attributes (const char *unicodedata_filename) +{ +  unsigned int i, j; +  FILE *stream; +  char field0[FIELDLEN]; +  char field1[FIELDLEN]; +  char field2[FIELDLEN]; +  char field3[FIELDLEN]; +  char field4[FIELDLEN]; +  char field5[FIELDLEN]; +  char field6[FIELDLEN]; +  char field7[FIELDLEN]; +  char field8[FIELDLEN]; +  char field9[FIELDLEN]; +  char field10[FIELDLEN]; +  char field11[FIELDLEN]; +  char field12[FIELDLEN]; +  char field13[FIELDLEN]; +  char field14[FIELDLEN]; +  int lineno = 0; + +  for (i = 0; i < 0x110000; i++) +    unicode_attributes[i].name = NULL; + +  stream = fopen (unicodedata_filename, "r"); +  if (stream == NULL) +    { +      fprintf (stderr, "error during fopen of '%s'\n", unicodedata_filename); +      exit (1); +    } + +  for (;;) +    { +      int n; + +      lineno++; +      n = getfield (stream, field0, ';'); +      n += getfield (stream, field1, ';'); +      n += getfield (stream, field2, ';'); +      n += getfield (stream, field3, ';'); +      n += getfield (stream, field4, ';'); +      n += getfield (stream, field5, ';'); +      n += getfield (stream, field6, ';'); +      n += getfield (stream, field7, ';'); +      n += getfield (stream, field8, ';'); +      n += getfield (stream, field9, ';'); +      n += getfield (stream, field10, ';'); +      n += getfield (stream, field11, ';'); +      n += getfield (stream, field12, ';'); +      n += getfield (stream, field13, ';'); +      n += getfield (stream, field14, '\n'); +      if (n == 0) +	break; +      if (n != 15) +	{ +	  fprintf (stderr, "short line in'%s':%d\n", +		   unicodedata_filename, lineno); +	  exit (1); +	} +      i = strtoul (field0, NULL, 16); +      if (field1[0] == '<' +	  && strlen (field1) >= 9 +	  && !strcmp (field1 + strlen(field1) - 8, ", First>")) +	{ +	  /* Deal with a range. */ +	  lineno++; +	  n = getfield (stream, field0, ';'); +	  n += getfield (stream, field1, ';'); +	  n += getfield (stream, field2, ';'); +	  n += getfield (stream, field3, ';'); +	  n += getfield (stream, field4, ';'); +	  n += getfield (stream, field5, ';'); +	  n += getfield (stream, field6, ';'); +	  n += getfield (stream, field7, ';'); +	  n += getfield (stream, field8, ';'); +	  n += getfield (stream, field9, ';'); +	  n += getfield (stream, field10, ';'); +	  n += getfield (stream, field11, ';'); +	  n += getfield (stream, field12, ';'); +	  n += getfield (stream, field13, ';'); +	  n += getfield (stream, field14, '\n'); +	  if (n != 15) +	    { +	      fprintf (stderr, "missing end range in '%s':%d\n", +		       unicodedata_filename, lineno); +	      exit (1); +	    } +	  if (!(field1[0] == '<' +		&& strlen (field1) >= 8 +		&& !strcmp (field1 + strlen (field1) - 7, ", Last>"))) +	    { +	      fprintf (stderr, "missing end range in '%s':%d\n", +		       unicodedata_filename, lineno); +	      exit (1); +	    } +	  field1[strlen (field1) - 7] = '\0'; +	  j = strtoul (field0, NULL, 16); +	  for (; i <= j; i++) +	    fill_attribute (i, field1+1, field2, field3, field4, field5, +			       field6, field7, field8, field9, field10, +			       field11, field12, field13, field14); +	} +      else +	{ +	  /* Single character line */ +	  fill_attribute (i, field1, field2, field3, field4, field5, +			     field6, field7, field8, field9, field10, +			     field11, field12, field13, field14); +	} +    } +  if (ferror (stream) || fclose (stream)) +    { +      fprintf (stderr, "error reading from '%s'\n", unicodedata_filename); +      exit (1); +    } +} + +/* Character mappings.  */ + +static unsigned int +to_upper (unsigned int ch) +{ +  if (unicode_attributes[ch].name != NULL +      && unicode_attributes[ch].upper != NONE) +    return unicode_attributes[ch].upper; +  else +    return ch; +} + +static unsigned int +to_lower (unsigned int ch) +{ +  if (unicode_attributes[ch].name != NULL +      && unicode_attributes[ch].lower != NONE) +    return unicode_attributes[ch].lower; +  else +    return ch; +} + +static unsigned int +to_title (unsigned int ch) +{ +  if (unicode_attributes[ch].name != NULL +      && unicode_attributes[ch].title != NONE) +    return unicode_attributes[ch].title; +  else +    return ch; +} + +/* Character class properties.  */ + +static bool +is_upper (unsigned int ch) +{ +  return (to_lower (ch) != ch); +} + +static bool +is_lower (unsigned int ch) +{ +  return (to_upper (ch) != ch) +	 /* <U00DF> is lowercase, but without simple to_upper mapping.  */ +	 || (ch == 0x00DF); +} + +static bool +is_alpha (unsigned int ch) +{ +  return (unicode_attributes[ch].name != NULL +	  && ((unicode_attributes[ch].category[0] == 'L' +	       /* Theppitak Karoonboonyanan <thep@links.nectec.or.th> says +		  <U0E2F>, <U0E46> should belong to is_punct.  */ +	       && (ch != 0x0E2F) && (ch != 0x0E46)) +	      /* Theppitak Karoonboonyanan <thep@links.nectec.or.th> says +		 <U0E31>, <U0E34>..<U0E3A>, <U0E47>..<U0E4E> are is_alpha.  */ +	      || (ch == 0x0E31) +	      || (ch >= 0x0E34 && ch <= 0x0E3A) +	      || (ch >= 0x0E47 && ch <= 0x0E4E) +	      /* Avoid warning for <U0345>.  */ +	      || (ch == 0x0345) +	      /* Avoid warnings for <U2160>..<U217F>.  */ +	      || (unicode_attributes[ch].category[0] == 'N' +		  && unicode_attributes[ch].category[1] == 'l') +	      /* Avoid warnings for <U24B6>..<U24E9>.  */ +	      || (unicode_attributes[ch].category[0] == 'S' +		  && unicode_attributes[ch].category[1] == 'o' +		  && strstr (unicode_attributes[ch].name, " LETTER ") +		     != NULL) +	      /* Consider all the non-ASCII digits as alphabetic. +		 ISO C 99 forbids us to have them in category "digit", +		 but we want iswalnum to return true on them.  */ +	      || (unicode_attributes[ch].category[0] == 'N' +		  && unicode_attributes[ch].category[1] == 'd' +		  && !(ch >= 0x0030 && ch <= 0x0039)))); +} + +static bool +is_digit (unsigned int ch) +{ +#if 0 +  return (unicode_attributes[ch].name != NULL +	  && unicode_attributes[ch].category[0] == 'N' +	  && unicode_attributes[ch].category[1] == 'd'); +  /* Note: U+0BE7..U+0BEF and U+1369..U+1371 are digit systems without +     a zero.  Must add <0> in front of them by hand.  */ +#else +  /* SUSV2 gives us some freedom for the "digit" category, but ISO C 99 +     takes it away: +     7.25.2.1.5: +        The iswdigit function tests for any wide character that corresponds +        to a decimal-digit character (as defined in 5.2.1). +     5.2.1: +        the 10 decimal digits 0 1 2 3 4 5 6 7 8 9 +   */ +  return (ch >= 0x0030 && ch <= 0x0039); +#endif +} + +static bool +is_outdigit (unsigned int ch) +{ +  return (ch >= 0x0030 && ch <= 0x0039); +} + +static bool +is_blank (unsigned int ch) +{ +  return (ch == 0x0009 /* '\t' */ +	  /* Category Zs without mention of "<noBreak>" */ +	  || (unicode_attributes[ch].name != NULL +	      && unicode_attributes[ch].category[0] == 'Z' +	      && unicode_attributes[ch].category[1] == 's' +	      && !strstr (unicode_attributes[ch].decomposition, "<noBreak>"))); +} + +static bool +is_space (unsigned int ch) +{ +  /* Don't make U+00A0 a space. Non-breaking space means that all programs +     should treat it like a punctuation character, not like a space. */ +  return (ch == 0x0020 /* ' ' */ +	  || ch == 0x000C /* '\f' */ +	  || ch == 0x000A /* '\n' */ +	  || ch == 0x000D /* '\r' */ +	  || ch == 0x0009 /* '\t' */ +	  || ch == 0x000B /* '\v' */ +	  /* Categories Zl, Zp, and Zs without mention of "<noBreak>" */ +	  || (unicode_attributes[ch].name != NULL +	      && unicode_attributes[ch].category[0] == 'Z' +	      && (unicode_attributes[ch].category[1] == 'l' +		  || unicode_attributes[ch].category[1] == 'p' +		  || (unicode_attributes[ch].category[1] == 's' +		      && !strstr (unicode_attributes[ch].decomposition, +				  "<noBreak>"))))); +} + +static bool +is_cntrl (unsigned int ch) +{ +  return (unicode_attributes[ch].name != NULL +	  && (!strcmp (unicode_attributes[ch].name, "<control>") +	      /* Categories Zl and Zp */ +	      || (unicode_attributes[ch].category[0] == 'Z' +		  && (unicode_attributes[ch].category[1] == 'l' +		      || unicode_attributes[ch].category[1] == 'p')))); +} + +static bool +is_xdigit (unsigned int ch) +{ +#if 0 +  return is_digit (ch) +	 || (ch >= 0x0041 && ch <= 0x0046) +	 || (ch >= 0x0061 && ch <= 0x0066); +#else +  /* SUSV2 gives us some freedom for the "xdigit" category, but ISO C 99 +     takes it away: +     7.25.2.1.12: +        The iswxdigit function tests for any wide character that corresponds +        to a hexadecimal-digit character (as defined in 6.4.4.1). +     6.4.4.1: +        hexadecimal-digit: one of 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F +   */ +  return (ch >= 0x0030 && ch <= 0x0039) +	 || (ch >= 0x0041 && ch <= 0x0046) +	 || (ch >= 0x0061 && ch <= 0x0066); +#endif +} + +static bool +is_graph (unsigned int ch) +{ +  return (unicode_attributes[ch].name != NULL +	  && strcmp (unicode_attributes[ch].name, "<control>") +	  && !is_space (ch)); +} + +static bool +is_print (unsigned int ch) +{ +  return (unicode_attributes[ch].name != NULL +	  && strcmp (unicode_attributes[ch].name, "<control>") +	  /* Categories Zl and Zp */ +	  && !(unicode_attributes[ch].name != NULL +	       && unicode_attributes[ch].category[0] == 'Z' +	       && (unicode_attributes[ch].category[1] == 'l' +		   || unicode_attributes[ch].category[1] == 'p'))); +} + +static bool +is_punct (unsigned int ch) +{ +#if 0 +  return (unicode_attributes[ch].name != NULL +	  && unicode_attributes[ch].category[0] == 'P'); +#else +  /* The traditional POSIX definition of punctuation is every graphic, +     non-alphanumeric character.  */ +  return (is_graph (ch) && !is_alpha (ch) && !is_digit (ch)); +#endif +} + +static bool +is_combining (unsigned int ch) +{ +  /* Up to Unicode 3.0.1 we took the Combining property from the PropList.txt +     file. In 3.0.1 it was identical to the union of the general categories +     "Mn", "Mc", "Me". In Unicode 3.1 this property has been dropped from the +     PropList.txt file, so we take the latter definition.  */ +  return (unicode_attributes[ch].name != NULL +	  && unicode_attributes[ch].category[0] == 'M' +	  && (unicode_attributes[ch].category[1] == 'n' +	      || unicode_attributes[ch].category[1] == 'c' +	      || unicode_attributes[ch].category[1] == 'e')); +} + +static bool +is_combining_level3 (unsigned int ch) +{ +  return is_combining (ch) +	 && !(unicode_attributes[ch].combining[0] != '\0' +	      && unicode_attributes[ch].combining[0] != '0' +	      && strtoul (unicode_attributes[ch].combining, NULL, 10) >= 200); +} + +/* Return the UCS symbol string for a Unicode character.  */ +static const char * +ucs_symbol (unsigned int i) +{ +  static char buf[11+1]; + +  sprintf (buf, (i < 0x10000 ? "<U%04X>" : "<U%08X>"), i); +  return buf; +} + +/* Return the UCS symbol range string for a Unicode characters interval.  */ +static const char * +ucs_symbol_range (unsigned int low, unsigned int high) +{ +  static char buf[24+1]; + +  strcpy (buf, ucs_symbol (low)); +  strcat (buf, ".."); +  strcat (buf, ucs_symbol (high)); +  return buf; +} + +/* Output a character class (= property) table.  */ + +static void +output_charclass (FILE *stream, const char *classname, +		  bool (*func) (unsigned int)) +{ +  char table[0x110000]; +  unsigned int i; +  bool need_semicolon; +  const int max_column = 75; +  int column; + +  for (i = 0; i < 0x110000; i++) +    table[i] = (int) func (i); + +  fprintf (stream, "%s ", classname); +  need_semicolon = false; +  column = 1000; +  for (i = 0; i < 0x110000; ) +    { +      if (!table[i]) +	i++; +      else +	{ +	  unsigned int low, high; +	  char buf[25]; + +	  low = i; +	  do +	    i++; +	  while (i < 0x110000 && table[i]); +	  high = i - 1; + +	  if (low == high) +	    strcpy (buf, ucs_symbol (low)); +	  else +	    strcpy (buf, ucs_symbol_range (low, high)); + +	  if (need_semicolon) +	    { +	      fprintf (stream, ";"); +	      column++; +	    } + +	  if (column + strlen (buf) > max_column) +	    { +	      fprintf (stream, "/\n   "); +	      column = 3; +	    } + +	  fprintf (stream, "%s", buf); +	  column += strlen (buf); +	  need_semicolon = true; +	} +    } +  fprintf (stream, "\n"); +} + +/* Output a character mapping table.  */ + +static void +output_charmap (FILE *stream, const char *mapname, +		unsigned int (*func) (unsigned int)) +{ +  char table[0x110000]; +  unsigned int i; +  bool need_semicolon; +  const int max_column = 75; +  int column; + +  for (i = 0; i < 0x110000; i++) +    table[i] = (func (i) != i); + +  fprintf (stream, "%s ", mapname); +  need_semicolon = false; +  column = 1000; +  for (i = 0; i < 0x110000; i++) +    if (table[i]) +      { +	char buf[25+1]; + +	strcpy (buf, "("); +	strcat (buf, ucs_symbol (i)); +	strcat (buf, ","); +	strcat (buf, ucs_symbol (func (i))); +	strcat (buf, ")"); + +	if (need_semicolon) +	  { +	    fprintf (stream, ";"); +	    column++; +	  } + +	if (column + strlen (buf) > max_column) +	  { +	    fprintf (stream, "/\n   "); +	    column = 3; +	  } + +	fprintf (stream, "%s", buf); +	column += strlen (buf); +	need_semicolon = true; +      } +  fprintf (stream, "\n"); +} + +/* Output the width table.  */ + +static void +output_widthmap (FILE *stream) +{ +} + +/* Output the tables to the given file.  */ + +static void +output_tables (const char *filename, const char *version) +{ +  FILE *stream; +  unsigned int ch; + +  stream = fopen (filename, "w"); +  if (stream == NULL) +    { +      fprintf (stderr, "cannot open '%s' for writing\n", filename); +      exit (1); +    } + +  fprintf (stream, "escape_char /\n"); +  fprintf (stream, "comment_char %%\n"); +  fprintf (stream, "\n"); +  fprintf (stream, "%% Generated automatically by gen-unicode-ctype for Unicode %s.\n", +	   version); +  fprintf (stream, "\n"); + +  fprintf (stream, "LC_IDENTIFICATION\n"); +  fprintf (stream, "title     \"Unicode %s FDCC-set\"\n", version); +  fprintf (stream, "source    \"UnicodeData.txt, PropList.txt\"\n"); +  fprintf (stream, "address   \"\"\n"); +  fprintf (stream, "contact   \"\"\n"); +  fprintf (stream, "email     \"bug-glibc-locales@gnu.org\"\n"); +  fprintf (stream, "tel       \"\"\n"); +  fprintf (stream, "fax       \"\"\n"); +  fprintf (stream, "language  \"\"\n"); +  fprintf (stream, "territory \"Earth\"\n"); +  fprintf (stream, "revision  \"%s\"\n", version); +  { +    time_t now; +    char date[11]; +    now = time (NULL); +    strftime (date, sizeof (date), "%Y-%m-%d", gmtime (&now)); +    fprintf (stream, "date      \"%s\"\n", date); +  } +  fprintf (stream, "category  \"unicode:2001\";LC_CTYPE\n"); +  fprintf (stream, "END LC_IDENTIFICATION\n"); +  fprintf (stream, "\n"); + +  /* Verifications. */ +  for (ch = 0; ch < 0x110000; ch++) +    { +      /* toupper restriction: "Only characters specified for the keywords +	 lower and upper shall be specified.  */ +      if (to_upper (ch) != ch && !(is_lower (ch) || is_upper (ch))) +	fprintf (stderr, +		 "%s is not upper|lower but toupper(0x%04X) = 0x%04X\n", +		 ucs_symbol (ch), ch, to_upper (ch)); + +      /* tolower restriction: "Only characters specified for the keywords +	 lower and upper shall be specified.  */ +      if (to_lower (ch) != ch && !(is_lower (ch) || is_upper (ch))) +	fprintf (stderr, +		 "%s is not upper|lower but tolower(0x%04X) = 0x%04X\n", +		 ucs_symbol (ch), ch, to_lower (ch)); + +      /* alpha restriction: "Characters classified as either upper or lower +	 shall automatically belong to this class.  */ +      if ((is_lower (ch) || is_upper (ch)) && !is_alpha (ch)) +	fprintf (stderr, "%s is upper|lower but not alpha\n", ucs_symbol (ch)); + +      /* alpha restriction: "No character specified for the keywords cntrl, +	 digit, punct or space shall be specified."  */ +      if (is_alpha (ch) && is_cntrl (ch)) +	fprintf (stderr, "%s is alpha and cntrl\n", ucs_symbol (ch)); +      if (is_alpha (ch) && is_digit (ch)) +	fprintf (stderr, "%s is alpha and digit\n", ucs_symbol (ch)); +      if (is_alpha (ch) && is_punct (ch)) +	fprintf (stderr, "%s is alpha and punct\n", ucs_symbol (ch)); +      if (is_alpha (ch) && is_space (ch)) +	fprintf (stderr, "%s is alpha and space\n", ucs_symbol (ch)); + +      /* space restriction: "No character specified for the keywords upper, +	 lower, alpha, digit, graph or xdigit shall be specified." +	 upper, lower, alpha already checked above.  */ +      if (is_space (ch) && is_digit (ch)) +	fprintf (stderr, "%s is space and digit\n", ucs_symbol (ch)); +      if (is_space (ch) && is_graph (ch)) +	fprintf (stderr, "%s is space and graph\n", ucs_symbol (ch)); +      if (is_space (ch) && is_xdigit (ch)) +	fprintf (stderr, "%s is space and xdigit\n", ucs_symbol (ch)); + +      /* cntrl restriction: "No character specified for the keywords upper, +	 lower, alpha, digit, punct, graph, print or xdigit shall be +	 specified."  upper, lower, alpha already checked above.  */ +      if (is_cntrl (ch) && is_digit (ch)) +	fprintf (stderr, "%s is cntrl and digit\n", ucs_symbol (ch)); +      if (is_cntrl (ch) && is_punct (ch)) +	fprintf (stderr, "%s is cntrl and punct\n", ucs_symbol (ch)); +      if (is_cntrl (ch) && is_graph (ch)) +	fprintf (stderr, "%s is cntrl and graph\n", ucs_symbol (ch)); +      if (is_cntrl (ch) && is_print (ch)) +	fprintf (stderr, "%s is cntrl and print\n", ucs_symbol (ch)); +      if (is_cntrl (ch) && is_xdigit (ch)) +	fprintf (stderr, "%s is cntrl and xdigit\n", ucs_symbol (ch)); + +      /* punct restriction: "No character specified for the keywords upper, +	 lower, alpha, digit, cntrl, xdigit or as the <space> character shall +	 be specified."  upper, lower, alpha, cntrl already checked above.  */ +      if (is_punct (ch) && is_digit (ch)) +	fprintf (stderr, "%s is punct and digit\n", ucs_symbol (ch)); +      if (is_punct (ch) && is_xdigit (ch)) +	fprintf (stderr, "%s is punct and xdigit\n", ucs_symbol (ch)); +      if (is_punct (ch) && (ch == 0x0020)) +	fprintf (stderr, "%s is punct\n", ucs_symbol (ch)); + +      /* graph restriction: "No character specified for the keyword cntrl +	 shall be specified."  Already checked above.  */ + +      /* print restriction: "No character specified for the keyword cntrl +	 shall be specified."  Already checked above.  */ + +      /* graph - print relation: differ only in the <space> character. +	 How is this possible if there are more than one space character?! +	 I think susv2/xbd/locale.html should speak of "space characters", +	 not "space character".  */ +      if (is_print (ch) && !(is_graph (ch) || /* ch == 0x0020 */ is_space (ch))) +	fprintf (stderr, +		 "%s is print but not graph|<space>\n", ucs_symbol (ch)); +      if (!is_print (ch) && (is_graph (ch) || ch == 0x0020)) +	fprintf (stderr, +		 "%s is graph|<space> but not print\n", ucs_symbol (ch)); +    } + +  fprintf (stream, "LC_CTYPE\n"); +  output_charclass (stream, "upper", is_upper); +  output_charclass (stream, "lower", is_lower); +  output_charclass (stream, "alpha", is_alpha); +  output_charclass (stream, "digit", is_digit); +  output_charclass (stream, "outdigit", is_outdigit); +  output_charclass (stream, "blank", is_blank); +  output_charclass (stream, "space", is_space); +  output_charclass (stream, "cntrl", is_cntrl); +  output_charclass (stream, "punct", is_punct); +  output_charclass (stream, "xdigit", is_xdigit); +  output_charclass (stream, "graph", is_graph); +  output_charclass (stream, "print", is_print); +  output_charclass (stream, "class \"combining\";", is_combining); +  output_charclass (stream, "class \"combining_level3\";", is_combining_level3); +  output_charmap (stream, "toupper", to_upper); +  output_charmap (stream, "tolower", to_lower); +  output_charmap (stream, "map \"totitle\";", to_title); +  output_widthmap (stream); +  fprintf (stream, "END LC_CTYPE\n"); + +  if (ferror (stream) || fclose (stream)) +    { +      fprintf (stderr, "error writing to '%s'\n", filename); +      exit (1); +    } +} + +int +main (int argc, char * argv[]) +{ +  if (argc != 3) +    { +      fprintf (stderr, "Usage: %s UnicodeData.txt version\n", argv[0]); +      exit (1); +    } + +  fill_attributes (argv[1]); + +  output_tables ("unicode", argv[2]); + +  return 0; +} diff --git a/test/locale/show-ucs-data.c b/test/locale/show-ucs-data.c new file mode 100644 index 000000000..9992ece42 --- /dev/null +++ b/test/locale/show-ucs-data.c @@ -0,0 +1,62 @@ +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> + +int +main (int argc, char *argv[]) +{ +  int n; +  char *line = NULL; +  size_t len = 0; + +  for (n = 1; n < argc; ++n) +    { +      FILE *fp = fopen (argv[n], "r"); +      if (fp == NULL) +	continue; + +      while (! feof (fp)) +	{ +	  ssize_t cnt = getline (&line, &len, fp); +	  char *runp; +	  if (cnt <= 0) +	    break; + +	  runp = line; +	  do +	    { +	      if (runp[0] == '<' && runp[1] == 'U' && isxdigit (runp[2]) +		  && isxdigit (runp[3]) && isxdigit (runp[4]) +		  && isxdigit (runp[5]) && runp[6] == '>') +		{ +		  unsigned int val = strtoul (runp + 2, NULL, 16); + +		  //putchar ('<'); +		  if (val < 128) +		    putchar (val); +		  else if (val < 0x800) +		    { +		      putchar (0xc0 | (val >> 6)); +		      putchar (0x80 | (val & 0x3f)); +		    } +		  else +		    { +		      putchar (0xe0 | (val >> 12)); +		      putchar (0x80 | ((val >> 6) & 0x3f)); +		      putchar (0x80 | (val & 0x3f)); +		    } +		  //putchar ('>'); +		  runp += 7; +		} +	      else +		putchar (*runp++); +	    } +	  while (runp < &line[cnt]); +	} + +      fclose (fp); +    } + +  return 0; +} diff --git a/test/locale/tst-C-locale.c b/test/locale/tst-C-locale.c new file mode 100644 index 000000000..c568cf404 --- /dev/null +++ b/test/locale/tst-C-locale.c @@ -0,0 +1,498 @@ +/* Tests of C and POSIX locale contents. +   Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2000. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <ctype.h> +#include <langinfo.h> +#include <limits.h> +#include <locale.h> +#include <stdio.h> +#include <string.h> +#include <wchar.h> +#include <wctype.h> + + +static int +run_test (const char *locname) +{ +  struct lconv *lc; +  const char *str; +  const wchar_t *wstr; +  int result = 0; +  locale_t loc; + +  /* ISO C stuff.  */ +  lc = localeconv (); +  if (lc == NULL) +    { +      printf ("localeconv failed for locale %s\n", locname); +      result = 1; +    } +  else +    { +#define STRTEST(name, exp) \ +      do								      \ +	if (strcmp (lc->name, exp) != 0)				      \ +	  {								      \ +	    printf (#name " in locale %s wrong (is \"%s\", should be \"%s\")\n",\ +		    locname, lc->name, exp);				      \ +	    result = 1;							      \ +	  }								      \ +      while (0) +      STRTEST (decimal_point, "."); +      STRTEST (thousands_sep, ""); +      STRTEST (grouping, ""); +      STRTEST (mon_decimal_point, ""); +      STRTEST (mon_thousands_sep, ""); +      STRTEST (mon_grouping, ""); +      STRTEST (positive_sign, ""); +      STRTEST (negative_sign, ""); +      STRTEST (currency_symbol, ""); +      STRTEST (int_curr_symbol, ""); + +#define CHARTEST(name, exp) \ +      do								      \ +	if (lc->name != exp)						      \ +	  {								      \ +	    printf (#name " in locale %s wrong (is %d, should be %d)\n",      \ +		    locname, lc->name, CHAR_MAX);			      \ +	    result = 1;							      \ +	  }								      \ +      while (0) +      CHARTEST (frac_digits, CHAR_MAX); +      CHARTEST (p_cs_precedes, CHAR_MAX); +      CHARTEST (n_cs_precedes, CHAR_MAX); +      CHARTEST (p_sep_by_space, CHAR_MAX); +      CHARTEST (n_sep_by_space, CHAR_MAX); +      CHARTEST (p_sign_posn, CHAR_MAX); +      CHARTEST (n_sign_posn, CHAR_MAX); +      CHARTEST (int_frac_digits, CHAR_MAX); +      CHARTEST (int_p_cs_precedes, CHAR_MAX); +      CHARTEST (int_n_cs_precedes, CHAR_MAX); +      CHARTEST (int_p_sep_by_space, CHAR_MAX); +      CHARTEST (int_n_sep_by_space, CHAR_MAX); +      CHARTEST (int_p_sign_posn, CHAR_MAX); +      CHARTEST (int_n_sign_posn, CHAR_MAX); +    } + +#undef STRTEST +#define STRTEST(name, exp) \ +  str = nl_langinfo (name);						      \ +  if (strcmp (str, exp) != 0)						      \ +    {									      \ +      printf ("nl_langinfo(" #name ") in locale %s wrong "		      \ +	      "(is \"%s\", should be \"%s\")\n", locname, str, exp);	      \ +      result = 1;							      \ +    } +#define WSTRTEST(name, exp) \ +  wstr = (wchar_t *) nl_langinfo (name);				      \ +  if (wcscmp (wstr, exp) != 0)						      \ +    {									      \ +      printf ("nl_langinfo(" #name ") in locale %s wrong "		      \ +	      "(is \"%S\", should be \"%S\")\n", locname, wstr, exp);	      \ +      result = 1;							      \ +    } + +  /* Unix stuff.  */ +  STRTEST (ABDAY_1, "Sun"); +  STRTEST (ABDAY_2, "Mon"); +  STRTEST (ABDAY_3, "Tue"); +  STRTEST (ABDAY_4, "Wed"); +  STRTEST (ABDAY_5, "Thu"); +  STRTEST (ABDAY_6, "Fri"); +  STRTEST (ABDAY_7, "Sat"); +  STRTEST (DAY_1, "Sunday"); +  STRTEST (DAY_2, "Monday"); +  STRTEST (DAY_3, "Tuesday"); +  STRTEST (DAY_4, "Wednesday"); +  STRTEST (DAY_5, "Thursday"); +  STRTEST (DAY_6, "Friday"); +  STRTEST (DAY_7, "Saturday"); +  STRTEST (ABMON_1, "Jan"); +  STRTEST (ABMON_2, "Feb"); +  STRTEST (ABMON_3, "Mar"); +  STRTEST (ABMON_4, "Apr"); +  STRTEST (ABMON_5, "May"); +  STRTEST (ABMON_6, "Jun"); +  STRTEST (ABMON_7, "Jul"); +  STRTEST (ABMON_8, "Aug"); +  STRTEST (ABMON_9, "Sep"); +  STRTEST (ABMON_10, "Oct"); +  STRTEST (ABMON_11, "Nov"); +  STRTEST (ABMON_12, "Dec"); +  STRTEST (MON_1, "January"); +  STRTEST (MON_2, "February"); +  STRTEST (MON_3, "March"); +  STRTEST (MON_4, "April"); +  STRTEST (MON_5, "May"); +  STRTEST (MON_6, "June"); +  STRTEST (MON_7, "July"); +  STRTEST (MON_8, "August"); +  STRTEST (MON_9, "September"); +  STRTEST (MON_10, "October"); +  STRTEST (MON_11, "November"); +  STRTEST (MON_12, "December"); +  STRTEST (AM_STR, "AM"); +  STRTEST (PM_STR, "PM"); +  STRTEST (D_T_FMT, "%a %b %e %H:%M:%S %Y"); +  STRTEST (D_FMT, "%m/%d/%y"); +  STRTEST (T_FMT, "%H:%M:%S"); +  STRTEST (T_FMT_AMPM, "%I:%M:%S %p"); +  STRTEST (ERA, ""); +  STRTEST (ERA_D_FMT, ""); +  STRTEST (ERA_T_FMT, ""); +  STRTEST (ERA_D_T_FMT, ""); +  STRTEST (ALT_DIGITS, ""); + +  STRTEST (RADIXCHAR, "."); +  STRTEST (THOUSEP, ""); + +  STRTEST (YESEXPR, "^[yY]"); +  STRTEST (NOEXPR, "^[nN]"); + +  /* Extensions.  */ +  WSTRTEST (_NL_WABDAY_1, L"Sun"); +  WSTRTEST (_NL_WABDAY_2, L"Mon"); +  WSTRTEST (_NL_WABDAY_3, L"Tue"); +  WSTRTEST (_NL_WABDAY_4, L"Wed"); +  WSTRTEST (_NL_WABDAY_5, L"Thu"); +  WSTRTEST (_NL_WABDAY_6, L"Fri"); +  WSTRTEST (_NL_WABDAY_7, L"Sat"); +  WSTRTEST (_NL_WDAY_1, L"Sunday"); +  WSTRTEST (_NL_WDAY_2, L"Monday"); +  WSTRTEST (_NL_WDAY_3, L"Tuesday"); +  WSTRTEST (_NL_WDAY_4, L"Wednesday"); +  WSTRTEST (_NL_WDAY_5, L"Thursday"); +  WSTRTEST (_NL_WDAY_6, L"Friday"); +  WSTRTEST (_NL_WDAY_7, L"Saturday"); +  WSTRTEST (_NL_WABMON_1, L"Jan"); +  WSTRTEST (_NL_WABMON_2, L"Feb"); +  WSTRTEST (_NL_WABMON_3, L"Mar"); +  WSTRTEST (_NL_WABMON_4, L"Apr"); +  WSTRTEST (_NL_WABMON_5, L"May"); +  WSTRTEST (_NL_WABMON_6, L"Jun"); +  WSTRTEST (_NL_WABMON_7, L"Jul"); +  WSTRTEST (_NL_WABMON_8, L"Aug"); +  WSTRTEST (_NL_WABMON_9, L"Sep"); +  WSTRTEST (_NL_WABMON_10, L"Oct"); +  WSTRTEST (_NL_WABMON_11, L"Nov"); +  WSTRTEST (_NL_WABMON_12, L"Dec"); +  WSTRTEST (_NL_WMON_1, L"January"); +  WSTRTEST (_NL_WMON_2, L"February"); +  WSTRTEST (_NL_WMON_3, L"March"); +  WSTRTEST (_NL_WMON_4, L"April"); +  WSTRTEST (_NL_WMON_5, L"May"); +  WSTRTEST (_NL_WMON_6, L"June"); +  WSTRTEST (_NL_WMON_7, L"July"); +  WSTRTEST (_NL_WMON_8, L"August"); +  WSTRTEST (_NL_WMON_9, L"September"); +  WSTRTEST (_NL_WMON_10, L"October"); +  WSTRTEST (_NL_WMON_11, L"November"); +  WSTRTEST (_NL_WMON_12, L"December"); +  WSTRTEST (_NL_WAM_STR, L"AM"); +  WSTRTEST (_NL_WPM_STR, L"PM"); +  WSTRTEST (_NL_WD_T_FMT, L"%a %b %e %H:%M:%S %Y"); +  WSTRTEST (_NL_WD_FMT, L"%m/%d/%y"); +  WSTRTEST (_NL_WT_FMT, L"%H:%M:%S"); +  WSTRTEST (_NL_WT_FMT_AMPM, L"%I:%M:%S %p"); +  WSTRTEST (_NL_WERA_D_FMT, L""); +  WSTRTEST (_NL_WERA_T_FMT, L""); +  WSTRTEST (_NL_WERA_D_T_FMT, L""); +  WSTRTEST (_NL_WALT_DIGITS, L""); + +  STRTEST (_DATE_FMT, "%a %b %e %H:%M:%S %Z %Y"); +  WSTRTEST (_NL_W_DATE_FMT, L"%a %b %e %H:%M:%S %Z %Y"); + +  STRTEST (INT_CURR_SYMBOL, ""); +  STRTEST (CURRENCY_SYMBOL, ""); +  STRTEST (MON_DECIMAL_POINT, ""); +  STRTEST (MON_THOUSANDS_SEP, ""); +  STRTEST (MON_GROUPING, ""); +  STRTEST (POSITIVE_SIGN, ""); +  STRTEST (NEGATIVE_SIGN, ""); +  STRTEST (GROUPING, ""); + +  STRTEST (YESSTR, ""); +  STRTEST (NOSTR, ""); + +  /* Test the new locale mechanisms.  */ +  loc = newlocale (LC_ALL_MASK, locname, NULL); +  if (loc == NULL) +    { +      printf ("cannot create locale object for locale %s\n", locname); +      result = 1; +    } +  else +    { +      int c; + +#undef STRTEST +#define STRTEST(name, exp) \ +      str = nl_langinfo_l (name, loc);				      \ +      if (strcmp (str, exp) != 0)					      \ +	{								      \ +	  printf ("nl_langinfo_l(" #name ") in locale %s wrong "	      \ +		  "(is \"%s\", should be \"%s\")\n", locname, str, exp);      \ +	  result = 1;							      \ +	} +#undef WSTRTEST +#define WSTRTEST(name, exp) \ +      wstr = (wchar_t *) nl_langinfo_l (name, loc);			      \ +      if (wcscmp (wstr, exp) != 0)					      \ +	{								      \ +	  printf ("nl_langinfo_l(" #name ") in locale %s wrong "	      \ +		  "(is \"%S\", should be \"%S\")\n", locname, wstr, exp);     \ +	  result = 1;							      \ +	} + +      /* Unix stuff.  */ +      STRTEST (ABDAY_1, "Sun"); +      STRTEST (ABDAY_2, "Mon"); +      STRTEST (ABDAY_3, "Tue"); +      STRTEST (ABDAY_4, "Wed"); +      STRTEST (ABDAY_5, "Thu"); +      STRTEST (ABDAY_6, "Fri"); +      STRTEST (ABDAY_7, "Sat"); +      STRTEST (DAY_1, "Sunday"); +      STRTEST (DAY_2, "Monday"); +      STRTEST (DAY_3, "Tuesday"); +      STRTEST (DAY_4, "Wednesday"); +      STRTEST (DAY_5, "Thursday"); +      STRTEST (DAY_6, "Friday"); +      STRTEST (DAY_7, "Saturday"); +      STRTEST (ABMON_1, "Jan"); +      STRTEST (ABMON_2, "Feb"); +      STRTEST (ABMON_3, "Mar"); +      STRTEST (ABMON_4, "Apr"); +      STRTEST (ABMON_5, "May"); +      STRTEST (ABMON_6, "Jun"); +      STRTEST (ABMON_7, "Jul"); +      STRTEST (ABMON_8, "Aug"); +      STRTEST (ABMON_9, "Sep"); +      STRTEST (ABMON_10, "Oct"); +      STRTEST (ABMON_11, "Nov"); +      STRTEST (ABMON_12, "Dec"); +      STRTEST (MON_1, "January"); +      STRTEST (MON_2, "February"); +      STRTEST (MON_3, "March"); +      STRTEST (MON_4, "April"); +      STRTEST (MON_5, "May"); +      STRTEST (MON_6, "June"); +      STRTEST (MON_7, "July"); +      STRTEST (MON_8, "August"); +      STRTEST (MON_9, "September"); +      STRTEST (MON_10, "October"); +      STRTEST (MON_11, "November"); +      STRTEST (MON_12, "December"); +      STRTEST (AM_STR, "AM"); +      STRTEST (PM_STR, "PM"); +      STRTEST (D_T_FMT, "%a %b %e %H:%M:%S %Y"); +      STRTEST (D_FMT, "%m/%d/%y"); +      STRTEST (T_FMT, "%H:%M:%S"); +      STRTEST (T_FMT_AMPM, "%I:%M:%S %p"); +      STRTEST (ERA, ""); +      STRTEST (ERA_D_FMT, ""); +      STRTEST (ERA_T_FMT, ""); +      STRTEST (ERA_D_T_FMT, ""); +      STRTEST (ALT_DIGITS, ""); + +      STRTEST (RADIXCHAR, "."); +      STRTEST (THOUSEP, ""); + +      STRTEST (YESEXPR, "^[yY]"); +      STRTEST (NOEXPR, "^[nN]"); + +      /* Extensions.  */ +      WSTRTEST (_NL_WABDAY_1, L"Sun"); +      WSTRTEST (_NL_WABDAY_2, L"Mon"); +      WSTRTEST (_NL_WABDAY_3, L"Tue"); +      WSTRTEST (_NL_WABDAY_4, L"Wed"); +      WSTRTEST (_NL_WABDAY_5, L"Thu"); +      WSTRTEST (_NL_WABDAY_6, L"Fri"); +      WSTRTEST (_NL_WABDAY_7, L"Sat"); +      WSTRTEST (_NL_WDAY_1, L"Sunday"); +      WSTRTEST (_NL_WDAY_2, L"Monday"); +      WSTRTEST (_NL_WDAY_3, L"Tuesday"); +      WSTRTEST (_NL_WDAY_4, L"Wednesday"); +      WSTRTEST (_NL_WDAY_5, L"Thursday"); +      WSTRTEST (_NL_WDAY_6, L"Friday"); +      WSTRTEST (_NL_WDAY_7, L"Saturday"); +      WSTRTEST (_NL_WABMON_1, L"Jan"); +      WSTRTEST (_NL_WABMON_2, L"Feb"); +      WSTRTEST (_NL_WABMON_3, L"Mar"); +      WSTRTEST (_NL_WABMON_4, L"Apr"); +      WSTRTEST (_NL_WABMON_5, L"May"); +      WSTRTEST (_NL_WABMON_6, L"Jun"); +      WSTRTEST (_NL_WABMON_7, L"Jul"); +      WSTRTEST (_NL_WABMON_8, L"Aug"); +      WSTRTEST (_NL_WABMON_9, L"Sep"); +      WSTRTEST (_NL_WABMON_10, L"Oct"); +      WSTRTEST (_NL_WABMON_11, L"Nov"); +      WSTRTEST (_NL_WABMON_12, L"Dec"); +      WSTRTEST (_NL_WMON_1, L"January"); +      WSTRTEST (_NL_WMON_2, L"February"); +      WSTRTEST (_NL_WMON_3, L"March"); +      WSTRTEST (_NL_WMON_4, L"April"); +      WSTRTEST (_NL_WMON_5, L"May"); +      WSTRTEST (_NL_WMON_6, L"June"); +      WSTRTEST (_NL_WMON_7, L"July"); +      WSTRTEST (_NL_WMON_8, L"August"); +      WSTRTEST (_NL_WMON_9, L"September"); +      WSTRTEST (_NL_WMON_10, L"October"); +      WSTRTEST (_NL_WMON_11, L"November"); +      WSTRTEST (_NL_WMON_12, L"December"); +      WSTRTEST (_NL_WAM_STR, L"AM"); +      WSTRTEST (_NL_WPM_STR, L"PM"); +      WSTRTEST (_NL_WD_T_FMT, L"%a %b %e %H:%M:%S %Y"); +      WSTRTEST (_NL_WD_FMT, L"%m/%d/%y"); +      WSTRTEST (_NL_WT_FMT, L"%H:%M:%S"); +      WSTRTEST (_NL_WT_FMT_AMPM, L"%I:%M:%S %p"); +      WSTRTEST (_NL_WERA_D_FMT, L""); +      WSTRTEST (_NL_WERA_T_FMT, L""); +      WSTRTEST (_NL_WERA_D_T_FMT, L""); +      WSTRTEST (_NL_WALT_DIGITS, L""); + +      STRTEST (_DATE_FMT, "%a %b %e %H:%M:%S %Z %Y"); +      WSTRTEST (_NL_W_DATE_FMT, L"%a %b %e %H:%M:%S %Z %Y"); + +      STRTEST (INT_CURR_SYMBOL, ""); +      STRTEST (CURRENCY_SYMBOL, ""); +      STRTEST (MON_DECIMAL_POINT, ""); +      STRTEST (MON_THOUSANDS_SEP, ""); +      STRTEST (MON_GROUPING, ""); +      STRTEST (POSITIVE_SIGN, ""); +      STRTEST (NEGATIVE_SIGN, ""); +      STRTEST (GROUPING, ""); + +      STRTEST (YESSTR, ""); +      STRTEST (NOSTR, ""); + +      /* Character class tests.  */ +      for (c = 0; c < 128; ++c) +	{ +#define CLASSTEST(name) \ +	  if (is##name (c) != is##name##_l (c, loc))			      \ +	    {								      \ +	      printf ("is%s('\\%o') != is%s_l('\\%o')\n",		      \ +		      #name, c, #name, c);				      \ +	      result = 1;						      \ +	    } +	  CLASSTEST (alnum); +	  CLASSTEST (alpha); +	  CLASSTEST (blank); +	  CLASSTEST (cntrl); +	  CLASSTEST (digit); +	  CLASSTEST (lower); +	  CLASSTEST (graph); +	  CLASSTEST (print); +	  CLASSTEST (punct); +	  CLASSTEST (space); +	  CLASSTEST (upper); +	  CLASSTEST (xdigit); + +	  /* Character mapping tests.  */ +#define MAPTEST(name) \ +	  if (to##name (c) != to##name##_l (c, loc))			      \ +	    {								      \ +	      printf ("to%s('\\%o') != to%s_l('\\%o'): '\\%o' vs '\\%o'\n", \ +		      #name, c, #name, c,				      \ +		      to##name (c), to##name##_l (c, loc));		      \ +	      result = 1;						      \ +	    } +	  MAPTEST (lower); +	  MAPTEST (upper); +	} + +      /* Character class tests, this time for wide characters.  Note that +	 this only works because we know that the internal encoding is +	 UCS4.  */ +      for (c = 0; c < 128; ++c) +	{ +#undef CLASSTEST +#define CLASSTEST(name) \ +	  if (isw##name (c) != isw##name##_l (c, loc))		      \ +	    {								      \ +	      printf ("isw%s('\\%o') != isw%s_l('\\%o')\n",		      \ +		      #name, c, #name, c);				      \ +	      result = 1;						      \ +	    } +	  CLASSTEST (alnum); +	  CLASSTEST (alpha); +	  CLASSTEST (blank); +	  CLASSTEST (cntrl); +	  CLASSTEST (digit); +	  CLASSTEST (lower); +	  CLASSTEST (graph); +	  CLASSTEST (print); +	  CLASSTEST (punct); +	  CLASSTEST (space); +	  CLASSTEST (upper); +	  CLASSTEST (xdigit); + +	  /* Character mapping tests.  Note that +	     this only works because we know that the internal encoding is +	     UCS4.  */ +#undef MAPTEST +#define MAPTEST(name) \ +	  if (tow##name (c) != tow##name##_l (c, loc))		      \ +	    {								      \ +	      printf ("tow%s('\\%o') != tow%s_l('\\%o'): '\\%o' vs '\\%o'\n",\ +		      #name, c, #name, c,				      \ +		      tow##name (c), tow##name##_l (c, loc));		      \ +	      result = 1;						      \ +	    } +	  MAPTEST (lower); +	  MAPTEST (upper); +	} + +      freelocale (loc); +    } + +  return result; +} + + +static int +do_test (void) +{ +  int result; + +  /* First use the name "C".  */ +  if (setlocale (LC_ALL, "C") == NULL) +    { +      puts ("cannot set C locale"); +      result = 1; +    } +  else +    result = run_test ("C"); + +  /* Then the name "POSIX".  */ +  if (setlocale (LC_ALL, "POSIX") == NULL) +    { +      puts ("cannot set POSIX locale"); +      result = 1; +    } +  else +    result |= run_test ("POSIX"); + +  return result; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/test/locale/tst-ctype-de_DE.ISO-8859-1.in b/test/locale/tst-ctype-de_DE.ISO-8859-1.in new file mode 100644 index 000000000..f71d76cc2 --- /dev/null +++ b/test/locale/tst-ctype-de_DE.ISO-8859-1.in @@ -0,0 +1,56 @@ +lower    ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ +        000000000000000000000100000000000000000000000000 +lower   ÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ +        000000000000000111111111111111111111111011111111 +upper    ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ +        000000000000000000000000000000001111111111111111 +upper   ÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ +        111111101111111000000000000000000000000000000000 +alpha    ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ +        000000000010000000000100001000001111111111111111 +alpha   ÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ +        111111101111111111111111111111111111111011111111 +digit    ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ +        000000000000000000000000000000000000000000000000 +digit   ÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ +        000000000000000000000000000000000000000000000000 +xdigit   ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ +        000000000000000000000000000000000000000000000000 +xdigit  ÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ +        000000000000000000000000000000000000000000000000 +space    ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ +        000000000000000000000000000000000000000000000000 +space   ÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ +        000000000000000000000000000000000000000000000000 +print    ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ +        111111111111111111111111111111111111111111111111 +print   ÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ +        111111111111111111111111111111111111111111111111 +graph    ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ +        111111111111111111111111111111111111111111111111 +graph   ÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ +        111111111111111111111111111111111111111111111111 +blank    ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ +        000000000000000000000000000000000000000000000000 +blank   ÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ +        000000000000000000000000000000000000000000000000 +cntrl    ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ +        000000000000000000000000000000000000000000000000 +cntrl   ÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ +        000000000000000000000000000000000000000000000000 +punct    ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ +        111111111101111111111011110111110000000000000000 +punct   ÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ +        000000010000000000000000000000000000000100000000 +alnum    ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ +        000000000010000000000100001000001111111111111111 +alnum   ÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ +        111111101111111111111111111111111111111011111111 +tolower  ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ +         ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿àáâãäåæçèéêëìíîï +tolower ÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ +        ðñòóôõö×øùúûüýþßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ +toupper  ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ +         ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ +toupper ÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ +        ÐÑÒÓÔÕÖרÙÚÛÜÝÞßÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ÷ØÙÚÛÜÝÞÿ diff --git a/test/locale/tst-ctype.c b/test/locale/tst-ctype.c new file mode 100644 index 000000000..c03c2dab3 --- /dev/null +++ b/test/locale/tst-ctype.c @@ -0,0 +1,447 @@ +/* Copyright (C) 2000,02, 05 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@gnu.org>, 2000. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <ctype.h> +#include <locale.h> +#include <langinfo.h> +#include <stdio.h> +#include <string.h> + + +static const char lower[] = "abcdefghijklmnopqrstuvwxyz"; +static const char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +static const char digits[] = "0123456789"; +static const char cntrl[] = "\ +\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\ +\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f "; + + +static struct classes +{ +  const char *name; +  int mask; +} classes[] = +{ +#define ENTRY(name) { #name, _IS##name } +  ENTRY (upper), +  ENTRY (lower), +  ENTRY (alpha), +  ENTRY (digit), +  ENTRY (xdigit), +  ENTRY (space), +  ENTRY (print), +  ENTRY (graph), +  ENTRY (blank), +  ENTRY (cntrl), +  ENTRY (punct), +  ENTRY (alnum) +}; +#define nclasses (sizeof (classes) / sizeof (classes[0])) + + +#define FAIL(str, args...) \ +  {									      \ +    printf ("      " str "\n", ##args);					      \ +    ++errors;								      \ +  } + + +int +main (void) +{ +  const char *cp; +  const char *cp2; +  int errors = 0; +  char *inpline = NULL; +  size_t inplinelen = 0; +  char *resline = NULL; +  size_t reslinelen = 0; +  size_t n; + +  setlocale (LC_ALL, ""); + +  printf ("Testing the ctype data of the `%s' locale\n", +	  setlocale (LC_CTYPE, NULL)); + +#if 0 +  /* Just for debugging.  */ + +  /* Contents of the class array.  */ +  printf ("\ +upper = %04x  lower = %04x  alpha = %04x  digit = %04x  xdigit = %04x\n\ +space = %04x  print = %04x  graph = %04x  blank = %04x  cntrl  = %04x\n\ +punct = %04x  alnum = %04x\n", +	  _ISupper, _ISlower, _ISalpha, _ISdigit, _ISxdigit, +	  _ISspace, _ISprint, _ISgraph, _ISblank, _IScntrl, +	  _ISpunct, _ISalnum); + +  while (n < 256) +    { +      if (n % 8 == 0) +	printf ("%02x: ", n); +      printf ("%04x%s", __ctype_b[n], (n + 1) % 8 == 0 ? "\n" : " "); +      ++n; +    } +#endif + +  puts ("  Test of ASCII character range\n    special NUL byte handling"); +  if (isupper ('\0')) +    FAIL ("isupper ('\\0') is true"); +  if (islower ('\0')) +    FAIL ("islower ('\\0') is true"); +  if (isalpha ('\0')) +    FAIL ("isalpha ('\\0') is true"); +  if (isdigit ('\0')) +    FAIL ("isdigit ('\\0') is true"); +  if (isxdigit ('\0')) +    FAIL ("isxdigit ('\\0') is true"); +  if (isspace ('\0')) +    FAIL ("isspace ('\\0') is true"); +  if (isprint ('\0')) +    FAIL ("isprint ('\\0') is true"); +  if (isgraph ('\0')) +    FAIL ("isgraph ('\\0') is true"); +  if (isblank ('\0')) +    FAIL ("isblank ('\\0') is true"); +  if (! iscntrl ('\0')) +    FAIL ("iscntrl ('\\0') not true"); +  if (ispunct ('\0')) +    FAIL ("ispunct ('\\0') is true"); +  if (isalnum ('\0')) +    FAIL ("isalnum ('\\0') is true"); + +  puts ("    islower()"); +  for (cp = lower; *cp != '\0'; ++cp) +    if (! islower (*cp)) +      FAIL ("islower ('%c') not true", *cp); +  for (cp = upper; *cp != '\0'; ++cp) +    if (islower (*cp)) +      FAIL ("islower ('%c') is true", *cp); +  for (cp = digits; *cp != '\0'; ++cp) +    if (islower (*cp)) +      FAIL ("islower ('%c') is true", *cp); +  for (cp = cntrl; *cp != '\0'; ++cp) +    if (islower (*cp)) +      FAIL ("islower ('\\x%02x') is true", *cp); + +  puts ("    isupper()"); +  for (cp = lower; *cp != '\0'; ++cp) +    if (isupper (*cp)) +      FAIL ("isupper ('%c') is true", *cp); +  for (cp = upper; *cp != '\0'; ++cp) +    if (! isupper (*cp)) +      FAIL ("isupper ('%c') not true", *cp); +  for (cp = digits; *cp != '\0'; ++cp) +    if (isupper (*cp)) +      FAIL ("isupper ('%c') is true", *cp); +  for (cp = cntrl; *cp != '\0'; ++cp) +    if (isupper (*cp)) +      FAIL ("isupper ('\\x%02x') is true", *cp); + +  puts ("    isalpha()"); +  for (cp = lower; *cp != '\0'; ++cp) +    if (! isalpha (*cp)) +      FAIL ("isalpha ('%c') not true", *cp); +  for (cp = upper; *cp != '\0'; ++cp) +    if (! isalpha (*cp)) +      FAIL ("isalpha ('%c') not true", *cp); +  for (cp = digits; *cp != '\0'; ++cp) +    if (isalpha (*cp)) +      FAIL ("isalpha ('%c') is true", *cp); +  for (cp = cntrl; *cp != '\0'; ++cp) +    if (isalpha (*cp)) +      FAIL ("isalpha ('\\x%02x') is true", *cp); + +  puts ("    isdigit()"); +  for (cp = lower; *cp != '\0'; ++cp) +    if (isdigit (*cp)) +      FAIL ("isdigit ('%c') is true", *cp); +  for (cp = upper; *cp != '\0'; ++cp) +    if (isdigit (*cp)) +      FAIL ("isdigit ('%c') is true", *cp); +  for (cp = digits; *cp != '\0'; ++cp) +    if (! isdigit (*cp)) +      FAIL ("isdigit ('%c') not true", *cp); +  for (cp = cntrl; *cp != '\0'; ++cp) +    if (isdigit (*cp)) +      FAIL ("isdigit ('\\x%02x') is true", *cp); + +  puts ("    isxdigit()"); +  for (cp = lower; *cp != '\0'; ++cp) +    if ((! isxdigit (*cp) && cp - lower < 6) +	|| (isxdigit (*cp) && cp - lower >= 6)) +      FAIL ("isxdigit ('%c') %s true", *cp, cp - upper < 6 ? "not" : "is"); +  for (cp = upper; *cp != '\0'; ++cp) +    if ((! isxdigit (*cp) && cp - upper < 6) +	|| (isxdigit (*cp) && cp - upper >= 6)) +      FAIL ("isxdigit ('%c') %s true", *cp, cp - upper < 6 ? "not" : "is"); +  for (cp = digits; *cp != '\0'; ++cp) +    if (! isxdigit (*cp)) +      FAIL ("isxdigit ('%c') not true", *cp); +  for (cp = cntrl; *cp != '\0'; ++cp) +    if (isxdigit (*cp)) +      FAIL ("isxdigit ('\\x%02x') is true", *cp); + +  puts ("    isspace()"); +  for (cp = lower; *cp != '\0'; ++cp) +    if (isspace (*cp)) +      FAIL ("isspace ('%c') is true", *cp); +  for (cp = upper; *cp != '\0'; ++cp) +    if (isspace (*cp)) +      FAIL ("isspace ('%c') is true", *cp); +  for (cp = digits; *cp != '\0'; ++cp) +    if (isspace (*cp)) +      FAIL ("isspace ('%c') is true", *cp); +  for (cp = cntrl; *cp != '\0'; ++cp) +    if ((isspace (*cp) && ((*cp < '\x09' || *cp > '\x0d') && *cp != ' ')) +	|| (! isspace (*cp) +	    && ((*cp >= '\x09' && *cp <= '\x0d') || *cp == ' '))) +      FAIL ("isspace ('\\x%02x') %s true", *cp, +	    (*cp < '\x09' || *cp > '\x0d') ? "is" : "not"); + +  puts ("    isprint()"); +  for (cp = lower; *cp != '\0'; ++cp) +    if (! isprint (*cp)) +      FAIL ("isprint ('%c') not true", *cp); +  for (cp = upper; *cp != '\0'; ++cp) +    if (! isprint (*cp)) +      FAIL ("isprint ('%c') not true", *cp); +  for (cp = digits; *cp != '\0'; ++cp) +    if (! isprint (*cp)) +      FAIL ("isprint ('%c') not true", *cp); +  for (cp = cntrl; *cp != '\0'; ++cp) +    if ((isprint (*cp) && *cp != ' ') +	|| (! isprint (*cp) && *cp == ' ')) +      FAIL ("isprint ('\\x%02x') is true", *cp); + +  puts ("    isgraph()"); +  for (cp = lower; *cp != '\0'; ++cp) +    if (! isgraph (*cp)) +      FAIL ("isgraph ('%c') not true", *cp); +  for (cp = upper; *cp != '\0'; ++cp) +    if (! isgraph (*cp)) +      FAIL ("isgraph ('%c') not true", *cp); +  for (cp = digits; *cp != '\0'; ++cp) +    if (! isgraph (*cp)) +      FAIL ("isgraph ('%c') not true", *cp); +  for (cp = cntrl; *cp != '\0'; ++cp) +    if (isgraph (*cp)) +      FAIL ("isgraph ('\\x%02x') is true", *cp); + +  puts ("    isblank()"); +  for (cp = lower; *cp != '\0'; ++cp) +    if (isblank (*cp)) +      FAIL ("isblank ('%c') is true", *cp); +  for (cp = upper; *cp != '\0'; ++cp) +    if (isblank (*cp)) +      FAIL ("isblank ('%c') is true", *cp); +  for (cp = digits; *cp != '\0'; ++cp) +    if (isblank (*cp)) +      FAIL ("isblank ('%c') is true", *cp); +  for (cp = cntrl; *cp != '\0'; ++cp) +    if ((isblank (*cp) && *cp != '\x09' && *cp != ' ') +	|| (! isblank (*cp) && (*cp == '\x09' || *cp == ' '))) +      FAIL ("isblank ('\\x%02x') %s true", *cp, *cp != '\x09' ? "is" : "not"); + +  puts ("    iscntrl()"); +  for (cp = lower; *cp != '\0'; ++cp) +    if (iscntrl (*cp)) +      FAIL ("iscntrl ('%c') is true", *cp); +  for (cp = upper; *cp != '\0'; ++cp) +    if (iscntrl (*cp)) +      FAIL ("iscntrl ('%c') is true", *cp); +  for (cp = digits; *cp != '\0'; ++cp) +    if (iscntrl (*cp)) +      FAIL ("iscntrl ('%c') is true", *cp); +  for (cp = cntrl; *cp != '\0'; ++cp) +    if ((iscntrl (*cp) && *cp == ' ') +	|| (! iscntrl (*cp) && *cp != ' ')) +      FAIL ("iscntrl ('\\x%02x') not true", *cp); + +  puts ("    ispunct()"); +  for (cp = lower; *cp != '\0'; ++cp) +    if (ispunct (*cp)) +      FAIL ("ispunct ('%c') is true", *cp); +  for (cp = upper; *cp != '\0'; ++cp) +    if (ispunct (*cp)) +      FAIL ("ispunct ('%c') is true", *cp); +  for (cp = digits; *cp != '\0'; ++cp) +    if (ispunct (*cp)) +      FAIL ("ispunct ('%c') is true", *cp); +  for (cp = cntrl; *cp != '\0'; ++cp) +    if (ispunct (*cp)) +      FAIL ("ispunct ('\\x%02x') is true", *cp); + +  puts ("    isalnum()"); +  for (cp = lower; *cp != '\0'; ++cp) +    if (! isalnum (*cp)) +      FAIL ("isalnum ('%c') not true", *cp); +  for (cp = upper; *cp != '\0'; ++cp) +    if (! isalnum (*cp)) +      FAIL ("isalnum ('%c') not true", *cp); +  for (cp = digits; *cp != '\0'; ++cp) +    if (! isalnum (*cp)) +      FAIL ("isalnum ('%c') not true", *cp); +  for (cp = cntrl; *cp != '\0'; ++cp) +    if (isalnum (*cp)) +      FAIL ("isalnum ('\\x%02x') is true", *cp); + + +  puts ("    tolower()"); +  for (cp = lower; *cp != '\0'; ++cp) +    if (tolower (*cp) != *cp) +      FAIL ("tolower ('%c') != '%c'", *cp, *cp); +  for (cp = upper, cp2 = lower; *cp != '\0'; ++cp, ++cp2) +    if (tolower (*cp) != *cp2) +      FAIL ("tolower ('%c') != '%c'", *cp, *cp2); +  for (cp = digits; *cp != '\0'; ++cp) +    if (tolower (*cp) != *cp) +      FAIL ("tolower ('%c') != '%c'", *cp, *cp); +  for (cp = cntrl; *cp != '\0'; ++cp) +    if (tolower (*cp) != *cp) +      FAIL ("tolower ('\\x%02x') != '\\x%02x'", *cp, *cp); + +  puts ("    toupper()"); +  for (cp = lower, cp2 = upper; *cp != '\0'; ++cp, ++cp2) +    if (toupper (*cp) != *cp2) +      FAIL ("toupper ('%c') != '%c'", *cp, *cp2); +  for (cp = upper; *cp != '\0'; ++cp) +    if (toupper (*cp) != *cp) +      FAIL ("toupper ('%c') != '%c'", *cp, *cp); +  for (cp = digits; *cp != '\0'; ++cp) +    if (toupper (*cp) != *cp) +      FAIL ("toupper ('%c') != '%c'", *cp, *cp); +  for (cp = cntrl; *cp != '\0'; ++cp) +    if (toupper (*cp) != *cp) +      FAIL ("toupper ('\\x%02x') != '\\x%02x'", *cp, *cp); + + +  /* Now some locale specific tests.  */ +  while (! feof (stdin)) +    { +      unsigned char *inp; +      unsigned char *resp; + +      if (getline (&inpline, &inplinelen, stdin) <= 0 +	  || getline (&resline, &reslinelen, stdin) <= 0) +	break; + +      inp = (unsigned char *) strchr (inpline, '\n'); +      if (inp != NULL) +	*inp = '\0'; +      resp = (unsigned char *) strchr (resline, '\n'); +      if (resp != NULL) +	*resp = '\0'; + +      inp = (unsigned char *) inpline; +      while (*inp != ' ' && *inp != '\t' && *inp && *inp != '\n' +	     && *inp != '\0') +	++inp; + +      if (*inp == '\0') +	{ +	  printf ("line \"%s\" is without content\n", inpline); +	  continue; +	} +      *inp++ = '\0'; +      while (*inp == ' ' || *inp == '\t') +	++inp; + +      /* Try all classes.  */ +      for (n = 0; n < nclasses; ++n) +	if (strcmp (inpline, classes[n].name) == 0) +	  break; + +      resp = (unsigned char *) resline; +      while (*resp == ' ' || *resp == '\t') +	++resp; + +      if (strlen ((char *) inp) != strlen ((char *) resp)) +	{ +	  printf ("lines \"%.20s\"... and \"%.20s\" have not the same length\n", +		  inp, resp); +	  continue; +	} + +      if (n < nclasses) +	{ +	  if (strspn ((char *) resp, "01") != strlen ((char *) resp)) +	    { +	      printf ("result string \"%s\" malformed\n", resp); +	      continue; +	    } + +	  printf ("  Locale-specific tests for `%s'\n", inpline); + +	  while (*inp != '\0' && *inp != '\n') +	    { +	      if (((__ctype_b[(unsigned int) *inp] & classes[n].mask) != 0) +		  != (*resp != '0')) +		{ +		  printf ("    is%s('%c' = '\\x%02x') %s true\n", inpline, +			  *inp, *inp, *resp == '1' ? "not" : "is"); +		  ++errors; +		} +	      ++inp; +	      ++resp; +	    } +	} +      else if (strcmp (inpline, "tolower") == 0) +	{ +	  while (*inp != '\0') +	    { +	      if (tolower (*inp) != *resp) +		{ +		  printf ("    tolower('%c' = '\\x%02x') != '%c'\n", +			  *inp, *inp, *resp); +		  ++errors; +		} +	      ++inp; +	      ++resp; +	    } +	} +      else if (strcmp (inpline, "toupper") == 0) +	{ +	  while (*inp != '\0') +	    { +	      if (toupper (*inp) != *resp) +		{ +		  printf ("    toupper('%c' = '\\x%02x') != '%c'\n", +			  *inp, *inp, *resp); +		  ++errors; +		} +	      ++inp; +	      ++resp; +	    } +	} +      else +	printf ("\"%s\": unknown class or map\n", inpline); +    } + + +  if (errors != 0) +    { +      printf ("  %d error%s for `%s' locale\n\n\n", errors, +	      errors == 1 ? "" : "s", setlocale (LC_ALL, NULL)); +      return 1; +    } + +  printf ("  No errors for `%s' locale\n\n\n", setlocale (LC_ALL, NULL)); +  return 0; +} diff --git a/test/locale/tst-digits.c b/test/locale/tst-digits.c new file mode 100644 index 000000000..8414a4b51 --- /dev/null +++ b/test/locale/tst-digits.c @@ -0,0 +1,249 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@gnu.org>, 2000. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <ctype.h> +#include <langinfo.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <wchar.h> +#include <wctype.h> +#include <sys/types.h> + + +#define ZERO  "\xe2\x82\x80" +#define ONE   "\xe2\x82\x81" +#define TWO   "\xe2\x82\x82" +#define THREE "\xe2\x82\x83" +#define FOUR  "\xe2\x82\x84" +#define FIVE  "\xe2\x82\x85" +#define SIX   "\xe2\x82\x86" +#define SEVEN "\xe2\x82\x87" +#define EIGHT "\xe2\x82\x88" +#define NINE  "\xe2\x82\x89" + +static struct printf_int_test +{ +  int n; +  const char *format; +  const char *expected; +} printf_int_tests[] = +{ +  {       0, "%I'10d", "       " ZERO }, +  {       1, "%I'10d", "       " ONE }, +  {       2, "%I'10d", "       " TWO }, +  {       3, "%I'10d", "       " THREE }, +  {       4, "%I'10d", "       " FOUR }, +  {       5, "%I'10d", "       " FIVE }, +  {       6, "%I'10d", "       " SIX }, +  {       7, "%I'10d", "       " SEVEN }, +  {       8, "%I'10d", "       " EIGHT }, +  {       9, "%I'10d", "       " NINE }, +  {      11, "%I'10d", "    " ONE ONE }, +  {      12, "%I'10d", "    " ONE TWO }, +  {     123, "%I10d",  " " ONE TWO THREE }, +  {     123, "%I'10d", " " ONE TWO THREE }, +  {    1234, "%I10d",  ONE TWO THREE FOUR }, +  {    1234, "%I'10d", ONE "," TWO THREE FOUR }, +  {   12345, "%I'10d", ONE TWO "," THREE FOUR FIVE }, +  {  123456, "%I'10d", ONE TWO THREE "," FOUR FIVE SIX }, +  { 1234567, "%I'10d", ONE "," TWO THREE FOUR "," FIVE SIX SEVEN } +}; +#define nprintf_int_tests \ +  (sizeof (printf_int_tests) / sizeof (printf_int_tests[0])) + +#define WZERO  L"\x2080" +#define WONE   L"\x2081" +#define WTWO   L"\x2082" +#define WTHREE L"\x2083" +#define WFOUR  L"\x2084" +#define WFIVE  L"\x2085" +#define WSIX   L"\x2086" +#define WSEVEN L"\x2087" +#define WEIGHT L"\x2088" +#define WNINE  L"\x2089" + +static struct wprintf_int_test +{ +  int n; +  const wchar_t *format; +  const wchar_t *expected; +} wprintf_int_tests[] = +{ +  {       0, L"%I'10d", L"         " WZERO }, +  {       1, L"%I'10d", L"         " WONE }, +  {       2, L"%I'10d", L"         " WTWO }, +  {       3, L"%I'10d", L"         " WTHREE }, +  {       4, L"%I'10d", L"         " WFOUR }, +  {       5, L"%I'10d", L"         " WFIVE }, +  {       6, L"%I'10d", L"         " WSIX }, +  {       7, L"%I'10d", L"         " WSEVEN }, +  {       8, L"%I'10d", L"         " WEIGHT }, +  {       9, L"%I'10d", L"         " WNINE }, +  {      11, L"%I'10d", L"        " WONE WONE }, +  {      12, L"%I'10d", L"        " WONE WTWO }, +  {     123, L"%I10d",  L"       " WONE WTWO WTHREE }, +  {     123, L"%I'10d", L"       " WONE WTWO WTHREE }, +  {    1234, L"%I10d",  L"      " WONE WTWO WTHREE WFOUR }, +  {    1234, L"%I'10d", L"     " WONE L"," WTWO WTHREE WFOUR }, +  {   12345, L"%I'10d", L"    " WONE WTWO L"," WTHREE WFOUR WFIVE }, +  {  123456, L"%I'10d", L"   " WONE WTWO WTHREE L"," WFOUR WFIVE WSIX }, +  { 1234567, L"%I'10d", L" " WONE L"," WTWO WTHREE WFOUR L"," WFIVE WSIX WSEVEN } +}; +#define nwprintf_int_tests \ +  (sizeof (wprintf_int_tests) / sizeof (wprintf_int_tests[0])) + + +int +main (void) +{ +  int cnt; +  int failures; +  int status; + +  if (setlocale (LC_ALL, "test7") == NULL) +    { +      puts ("cannot set locale `test7'"); +      exit (1); +    } +  printf ("CODESET = \"%s\"\n", nl_langinfo (CODESET)); + +  /* First: printf tests.  */ +  failures = 0; +  for (cnt = 0; cnt < (int) nprintf_int_tests; ++cnt) +    { +      char buf[100]; +      ssize_t n; + +      n = snprintf (buf, sizeof buf, printf_int_tests[cnt].format, +		    printf_int_tests[cnt].n); + +      printf ("%3d: got \"%s\", expected \"%s\"", +	      cnt, buf, printf_int_tests[cnt].expected); + +      if (n != (ssize_t) strlen (printf_int_tests[cnt].expected) +	  || strcmp (buf, printf_int_tests[cnt].expected) != 0) +	{ +	  puts ("  -> FAILED"); +	  ++failures; +	} +      else +	puts ("  -> OK"); +    } + +  printf ("%d failures in printf tests\n", failures); +  status = failures != 0; + +  /* wprintf tests.  */ +  failures = 0; +  for (cnt = 0; cnt < (int) nwprintf_int_tests; ++cnt) +    { +      wchar_t buf[100]; +      ssize_t n; + +      n = swprintf (buf, sizeof buf / sizeof (buf[0]), +		    wprintf_int_tests[cnt].format, +		    wprintf_int_tests[cnt].n); + +      printf ("%3d: got \"%ls\", expected \"%ls\"", +	      cnt, buf, wprintf_int_tests[cnt].expected); + +      if (n != (ssize_t) wcslen (wprintf_int_tests[cnt].expected) +	  || wcscmp (buf, wprintf_int_tests[cnt].expected) != 0) +	{ +	  puts ("  -> FAILED"); +	  ++failures; +	} +      else +	puts ("  -> OK"); +    } + +  printf ("%d failures in wprintf tests\n", failures); +  status = failures != 0; + +  /* ctype tests.  This makes sure that the multibyte chracter digit +     representations are not handle in this table.  */ +  failures = 0; +  for (cnt = 0; cnt < 256; ++cnt) +    if (cnt >= '0' && cnt <= '9') +      { +	if (! isdigit (cnt)) +	  { +	    printf ("isdigit ('%c') == 0\n", cnt); +	    ++failures; +	  } +      } +    else +      { +	if (isdigit (cnt)) +	  { +	    printf ("isdigit (%d) != 0\n", cnt); +	    ++failures; +	  } +      } + +  printf ("%d failures in ctype tests\n", failures); +  status = failures != 0; + +  /* wctype tests.  This makes sure the second set of digits is also +     recorded.  */ +  failures = 0; +  for (cnt = 0; cnt < 256; ++cnt) +    if (cnt >= '0' && cnt <= '9') +      { +	if (! iswdigit (cnt)) +	  { +	    printf ("iswdigit (L'%c') == 0\n", cnt); +	    ++failures; +	  } +      } +    else +      { +	if (iswdigit (cnt)) +	  { +	    printf ("iswdigit (%d) != 0\n", cnt); +	    ++failures; +	  } +      } + +  for (cnt = 0x2070; cnt < 0x2090; ++cnt) +    if (cnt >= 0x2080 && cnt <= 0x2089) +      { +	if (! iswdigit (cnt)) +	  { +	    printf ("iswdigit (U%04X) == 0\n", cnt); +	    ++failures; +	  } +      } +    else +      { +	if (iswdigit (cnt)) +	  { +	    printf ("iswdigit (U%04X) != 0\n", cnt); +	    ++failures; +	  } +      } + +  printf ("%d failures in wctype tests\n", failures); +  status = failures != 0; + +  return status; +} diff --git a/test/locale/tst-fmon.c b/test/locale/tst-fmon.c new file mode 100644 index 000000000..11093ce6c --- /dev/null +++ b/test/locale/tst-fmon.c @@ -0,0 +1,68 @@ +/* Testing the implementation of strfmon(3). +   Copyright (C) 1996, 1997, 2000, 2003, 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jochen Hein <jochen.hein@delphi.central.de>, 1997. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <stdio.h> +#include <locale.h> +#include <monetary.h> +#include <string.h> +#include <stdlib.h> + +/* +  test-strfmon gets called with three parameters: +   - the locale +   - the format-string to be used +   - the actual number to be formatted +   - the expected string +   If the test passes, test-strfmon terminates with returncode 0, +   otherwise with 1 +*/ +#define EXIT_SUCCESS 0 +#define EXIT_FAILURE 1 +#define EXIT_SETLOCALE 2 +#define EXIT_STRFMON 3 + +int +main (int argc, char *argv[]) +{ +  char *s = malloc (201); + +  if (setlocale (LC_MONETARY, argv[1]) == NULL) +    { +      fprintf (stderr, "setlocale(LC_MONETARY, \"%s\"): %m\n", argv[1]); +      exit (EXIT_SETLOCALE); +    } + +  if (strfmon (s, 200, argv[2], (double) atof (argv[3])) == -1) +    { +      perror ("strfmon"); +      exit (EXIT_STRFMON); +    } + +  if (strcmp (s, argv[4]) != 0) +    { +      printf ("\ +Locale: \"%s\" Format: \"%s\" Value: \"%s\" Received: \"%s\" Expected: \"%s\" => %s\n", +	      argv[1], argv[2], argv[3], s, argv[4], +	      strcmp (s, argv[4]) != 0 ? "false" : "correct"); +      exit (EXIT_FAILURE); +    } + +  return EXIT_SUCCESS; +} diff --git a/test/locale/tst-langinfo.c b/test/locale/tst-langinfo.c new file mode 100644 index 000000000..e95f0da53 --- /dev/null +++ b/test/locale/tst-langinfo.c @@ -0,0 +1,284 @@ +/* Test program for nl_langinfo() function. +   Copyright (C) 2000 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@cygnus.com>. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <langinfo.h> +#include <locale.h> +#include <stdio.h> +#include <string.h> + + +struct map +{ +  const char *str; +  int val; +} map[] = +{ +#define VAL(name) { #name, name } +  VAL (ABDAY_1), +  VAL (ABDAY_2), +  VAL (ABDAY_3), +  VAL (ABDAY_4), +  VAL (ABDAY_5), +  VAL (ABDAY_6), +  VAL (ABDAY_7), +  VAL (ABMON_1), +  VAL (ABMON_10), +  VAL (ABMON_11), +  VAL (ABMON_12), +  VAL (ABMON_2), +  VAL (ABMON_3), +  VAL (ABMON_4), +  VAL (ABMON_5), +  VAL (ABMON_6), +  VAL (ABMON_7), +  VAL (ABMON_8), +  VAL (ABMON_9), +  VAL (ALT_DIGITS), +  VAL (AM_STR), +  VAL (CRNCYSTR), +  VAL (CURRENCY_SYMBOL), +  VAL (DAY_1), +  VAL (DAY_2), +  VAL (DAY_3), +  VAL (DAY_4), +  VAL (DAY_5), +  VAL (DAY_6), +  VAL (DAY_7), +  VAL (DECIMAL_POINT), +  VAL (D_FMT), +  VAL (D_T_FMT), +  VAL (ERA), +  VAL (ERA_D_FMT), +  VAL (ERA_D_T_FMT), +  VAL (ERA_T_FMT), +  VAL (ERA_YEAR), +  VAL (FRAC_DIGITS), +  VAL (GROUPING), +  VAL (INT_CURR_SYMBOL), +  VAL (INT_FRAC_DIGITS), +  VAL (MON_1), +  VAL (MON_10), +  VAL (MON_11), +  VAL (MON_12), +  VAL (MON_2), +  VAL (MON_3), +  VAL (MON_4), +  VAL (MON_5), +  VAL (MON_6), +  VAL (MON_7), +  VAL (MON_8), +  VAL (MON_9), +  VAL (MON_DECIMAL_POINT), +  VAL (MON_GROUPING), +  VAL (MON_THOUSANDS_SEP), +  VAL (NEGATIVE_SIGN), +  VAL (NOEXPR), +  VAL (NOSTR), +  VAL (N_CS_PRECEDES), +  VAL (N_SEP_BY_SPACE), +  VAL (N_SIGN_POSN), +  VAL (PM_STR), +  VAL (POSITIVE_SIGN), +  VAL (P_CS_PRECEDES), +  VAL (P_SEP_BY_SPACE), +  VAL (P_SIGN_POSN), +  VAL (RADIXCHAR), +  VAL (THOUSANDS_SEP), +  VAL (THOUSEP), +  VAL (T_FMT), +  VAL (T_FMT_AMPM), +  VAL (YESEXPR), +  VAL (YESSTR) +}; + + +static int +map_paramstr (const char *str) +{ +  int low = 0; +  int high = sizeof (map) / sizeof (map[0]); + +  while (low < high) +    { +      int med = (low + high) / 2; +      int cmpres; + +      cmpres = strcmp (str, map[med].str); +      if (cmpres == 0) +	return map[med].val; +      else if (cmpres > 0) +	low = med + 1; +      else +	high = med; +    } + +  return -1; +} + + +#ifdef DEBUG +# define REASON(str) printf ("\"%s\" ignored: %s\n", buf, str) +#else +# define REASON(str) +#endif + +int +main (void) +{ +  int result = 0; + +  while (! feof (stdin)) +    { +      char buf[1000]; +      char *rp; +      char *locale; +      char *paramstr; +      char *expected; +      char *actual; +      int param; + +      if (fgets (buf, sizeof (buf), stdin) == NULL) +	break; + +      /* Split the fields.   There are three is them: +	 1. locale +	 2. langinfo() parameter +	 3. expected result; this can be a string with white space etc. +      */ +      rp = buf; +      while (*rp == ' ' || *rp == '\t') +	++rp; + +      if  (*rp == '#') +	{ +	  /* It's a comment line.  Ignore it.  */ +	  REASON ("comment"); +	  continue; +	} +      locale = rp; + +      while (*rp != '\0' && *rp != ' ' && *rp != '\t' && *rp != '\n') +	++rp; +      if (*rp == '\0' || *rp == '\n') +	{ +	  /* Incomplete line.  */ +	  REASON ("incomplete line"); +	  continue; +	} +      *rp++ = '\0'; + +      while (*rp == ' ' || *rp == '\t') +	++rp; +      paramstr = rp; + +      while (*rp != '\0' && *rp != ' ' && *rp != '\t' && *rp != '\n') +	++rp; +      if (*rp == '\0' || *rp == '\n') +	{ +	  /* Incomplete line.  */ +	  REASON ("incomplete line"); +	  continue; +	} +      *rp++ = '\0'; + +      while (*rp == ' ' || *rp == '\t') +	++rp; + +      if (*rp == '"') +	{ +	  char *wp; + +	  expected = wp = ++rp; +	  while (*rp != '"' && *rp != '\n' && *rp != '\0') +	    { +	      if (*rp == '\\') +		{ +		  ++rp; +		  if (*rp == '\0') +		    break; +		  if (*rp >= '0' && *rp <= '9') +		    { +		      int val = *rp - '0'; +		      if (rp[1] >= '0' && rp[1] <= '9') +			{ +			  ++rp; +			  val *= 10; +			  val += *rp - '0'; +			  if (rp[1] >= '0' && rp[1] <= '9') +			    { +			      ++rp; +			      val *= 10; +			      val += *rp - '0'; +			    } +			} +		      *rp = val; +		    } +		} +	      *wp++ = *rp++; +	    } + +	  if (*rp != '"') +	    { +	      REASON ("missing '\"'"); +	      continue; +	    } + +	  *wp = '\0'; +	} +      else +	{ +	  expected = rp; +	  while (*rp != '\0' && *rp != '\n') +	    ++rp; +	  *rp = '\0'; +	} + +      param = map_paramstr (paramstr); +      if (param == -1) +	{ +	  /* Invalid parameter.  */ +	  REASON ("invalid parameter"); +	  continue; +	} + +      /* Set the locale and check whether it worked.  */ +      printf ("LC_ALL=%s nl_langinfo(%s)", locale, paramstr); +      setlocale (LC_ALL, locale); +      if (strcmp (locale, setlocale (LC_ALL, NULL)) != 0) +	{ +	  puts (": failed to set locale"); +	  result = 1; +	  continue; +	} + +      actual = nl_langinfo (param); +      printf (" = \"%s\", ", actual); + +      if (strcmp (actual, expected) == 0) +	puts ("OK"); +      else +	{ +	  printf ("FAILED (expected: %s)\n", expected); +	  result = 1; +	} +    } + +  return result; +} diff --git a/test/locale/tst-langinfo.input b/test/locale/tst-langinfo.input new file mode 100644 index 000000000..0a05ab862 --- /dev/null +++ b/test/locale/tst-langinfo.input @@ -0,0 +1,303 @@ +#! /bin/sh +# Input file for tst-langinfo. +# Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc. +# This file is part of the GNU C Library. +# + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +# Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with the GNU C Library; if not, write to the Free +# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +# 02111-1307 USA. + + +# Run the test program. +# Only decimal numerical escape sequences allowed in strings. +C                    ABDAY_1     Sun +C                    ABDAY_2     Mon +C                    ABDAY_3     Tue +C                    ABDAY_4     Wed +C                    ABDAY_5     Thu +C                    ABDAY_6     Fri +C                    ABDAY_7     Sat +C                    DAY_1       Sunday +C                    DAY_2       Monday +C                    DAY_3       Tuesday +C                    DAY_4       Wednesday +C                    DAY_5       Thursday +C                    DAY_6       Friday +C                    DAY_7       Saturday +C                    ABMON_1     Jan +C                    ABMON_2     Feb +C                    ABMON_3     Mar +C                    ABMON_4     Apr +C                    ABMON_5     May +C                    ABMON_6     Jun +C                    ABMON_7     Jul +C                    ABMON_8     Aug +C                    ABMON_9     Sep +C                    ABMON_10    Oct +C                    ABMON_11    Nov +C                    ABMON_12    Dec +C                    MON_1       January +C                    MON_2       February +C                    MON_3       March +C                    MON_4       April +C                    MON_5       May +C                    MON_6       June +C                    MON_7       July +C                    MON_8       August +C                    MON_9       September +C                    MON_10      October +C                    MON_11      November +C                    MON_12      December +C                    AM_STR      AM +C                    PM_STR      PM +C                    D_T_FMT     "%a %b %e %H:%M:%S %Y" +C                    D_FMT       "%m/%d/%y" +C                    T_FMT       "%H:%M:%S" +C                    T_FMT_AMPM  "%I:%M:%S %p" +C                    ABDAY_1     Sun +C                    ABDAY_2     Mon +C                    ABDAY_3     Tue +C                    ABDAY_4     Wed +C                    ABDAY_5     Thu +C                    ABDAY_6     Fri +C                    ABDAY_7     Sat +C                    DAY_1       Sunday +C                    DAY_2       Monday +C                    DAY_3       Tuesday +C                    DAY_4       Wednesday +C                    DAY_5       Thursday +C                    DAY_6       Friday +C                    DAY_7       Saturday +C                    RADIXCHAR   . +C                    THOUSEP     "" +C                    YESEXPR     ^[yY] +C                    NOEXPR      ^[nN] +en_US.ISO-8859-1     ABMON_1     Jan +en_US.ISO-8859-1     ABMON_2     Feb +en_US.ISO-8859-1     ABMON_3     Mar +en_US.ISO-8859-1     ABMON_4     Apr +en_US.ISO-8859-1     ABMON_5     May +en_US.ISO-8859-1     ABMON_6     Jun +en_US.ISO-8859-1     ABMON_7     Jul +en_US.ISO-8859-1     ABMON_8     Aug +en_US.ISO-8859-1     ABMON_9     Sep +en_US.ISO-8859-1     ABMON_10    Oct +en_US.ISO-8859-1     ABMON_11    Nov +en_US.ISO-8859-1     ABMON_12    Dec +en_US.ISO-8859-1     MON_1       January +en_US.ISO-8859-1     MON_2       February +en_US.ISO-8859-1     MON_3       March +en_US.ISO-8859-1     MON_4       April +en_US.ISO-8859-1     MON_5       May +en_US.ISO-8859-1     MON_6       June +en_US.ISO-8859-1     MON_7       July +en_US.ISO-8859-1     MON_8       August +en_US.ISO-8859-1     MON_9       September +en_US.ISO-8859-1     MON_10      October +en_US.ISO-8859-1     MON_11      November +en_US.ISO-8859-1     MON_12      December +en_US.ISO-8859-1     AM_STR      AM +en_US.ISO-8859-1     PM_STR      PM +en_US.ISO-8859-1     D_T_FMT     "%a %d %b %Y %r %Z" +en_US.ISO-8859-1     D_FMT       "%m/%d/%Y" +en_US.ISO-8859-1     T_FMT       "%r" +en_US.ISO-8859-1     T_FMT_AMPM  "%I:%M:%S %p" +en_US.ISO-8859-1     RADIXCHAR   . +en_US.ISO-8859-1     THOUSEP     , +en_US.ISO-8859-1     YESEXPR     ^[yY].* +en_US.ISO-8859-1     NOEXPR      ^[nN].* +de_DE.ISO-8859-1     ABDAY_1     So +de_DE.ISO-8859-1     ABDAY_2     Mo +de_DE.ISO-8859-1     ABDAY_3     Di +de_DE.ISO-8859-1     ABDAY_4     Mi +de_DE.ISO-8859-1     ABDAY_5     Do +de_DE.ISO-8859-1     ABDAY_6     Fr +de_DE.ISO-8859-1     ABDAY_7     Sa +de_DE.ISO-8859-1     DAY_1       Sonntag +de_DE.ISO-8859-1     DAY_2       Montag +de_DE.ISO-8859-1     DAY_3       Dienstag +de_DE.ISO-8859-1     DAY_4       Mittwoch +de_DE.ISO-8859-1     DAY_5       Donnerstag +de_DE.ISO-8859-1     DAY_6       Freitag +de_DE.ISO-8859-1     DAY_7       Samstag +de_DE.ISO-8859-1     ABMON_1     Jan +de_DE.ISO-8859-1     ABMON_2     Feb +de_DE.ISO-8859-1     ABMON_3     Mär +de_DE.ISO-8859-1     ABMON_4     Apr +de_DE.ISO-8859-1     ABMON_5     Mai +de_DE.ISO-8859-1     ABMON_6     Jun +de_DE.ISO-8859-1     ABMON_7     Jul +de_DE.ISO-8859-1     ABMON_8     Aug +de_DE.ISO-8859-1     ABMON_9     Sep +de_DE.ISO-8859-1     ABMON_10    Okt +de_DE.ISO-8859-1     ABMON_11    Nov +de_DE.ISO-8859-1     ABMON_12    Dez +de_DE.ISO-8859-1     MON_1       Januar +de_DE.ISO-8859-1     MON_2       Februar +de_DE.ISO-8859-1     MON_3       März +de_DE.ISO-8859-1     MON_4       April +de_DE.ISO-8859-1     MON_5       Mai +de_DE.ISO-8859-1     MON_6       Juni +de_DE.ISO-8859-1     MON_7       Juli +de_DE.ISO-8859-1     MON_8       August +de_DE.ISO-8859-1     MON_9       September +de_DE.ISO-8859-1     MON_10      Oktober +de_DE.ISO-8859-1     MON_11      November +de_DE.ISO-8859-1     MON_12      Dezember +de_DE.ISO-8859-1     D_T_FMT     "%a %d %b %Y %T %Z" +de_DE.ISO-8859-1     D_FMT       "%d.%m.%Y" +de_DE.ISO-8859-1     T_FMT       "%T" +de_DE.ISO-8859-1     RADIXCHAR   , +de_DE.ISO-8859-1     THOUSEP     . +de_DE.ISO-8859-1     YESEXPR     ^[jJyY].* +de_DE.ISO-8859-1     NOEXPR      ^[nN].* +de_DE.UTF-8          ABDAY_1     So +de_DE.UTF-8          ABDAY_2     Mo +de_DE.UTF-8          ABDAY_3     Di +de_DE.UTF-8          ABDAY_4     Mi +de_DE.UTF-8          ABDAY_5     Do +de_DE.UTF-8          ABDAY_6     Fr +de_DE.UTF-8          ABDAY_7     Sa +de_DE.UTF-8          DAY_1       Sonntag +de_DE.UTF-8          DAY_2       Montag +de_DE.UTF-8          DAY_3       Dienstag +de_DE.UTF-8          DAY_4       Mittwoch +de_DE.UTF-8          DAY_5       Donnerstag +de_DE.UTF-8          DAY_6       Freitag +de_DE.UTF-8          DAY_7       Samstag +de_DE.UTF-8          ABMON_1     Jan +de_DE.UTF-8          ABMON_2     Feb +de_DE.UTF-8          ABMON_3     Mär +de_DE.UTF-8          ABMON_4     Apr +de_DE.UTF-8          ABMON_5     Mai +de_DE.UTF-8          ABMON_6     Jun +de_DE.UTF-8          ABMON_7     Jul +de_DE.UTF-8          ABMON_8     Aug +de_DE.UTF-8          ABMON_9     Sep +de_DE.UTF-8          ABMON_10    Okt +de_DE.UTF-8          ABMON_11    Nov +de_DE.UTF-8          ABMON_12    Dez +de_DE.UTF-8          MON_1       Januar +de_DE.UTF-8          MON_2       Februar +de_DE.UTF-8          MON_3       März +de_DE.UTF-8          MON_4       April +de_DE.UTF-8          MON_5       Mai +de_DE.UTF-8          MON_6       Juni +de_DE.UTF-8          MON_7       Juli +de_DE.UTF-8          MON_8       August +de_DE.UTF-8          MON_9       September +de_DE.UTF-8          MON_10      Oktober +de_DE.UTF-8          MON_11      November +de_DE.UTF-8          MON_12      Dezember +de_DE.UTF-8          D_T_FMT     "%a %d %b %Y %T %Z" +de_DE.UTF-8          D_FMT       "%d.%m.%Y" +de_DE.UTF-8          T_FMT       "%T" +de_DE.UTF-8          RADIXCHAR   , +de_DE.UTF-8          THOUSEP     . +de_DE.UTF-8          YESEXPR     ^[jJyY].* +de_DE.UTF-8          NOEXPR      ^[nN].* +fr_FR.ISO-8859-1     ABDAY_1     dim +fr_FR.ISO-8859-1     ABDAY_2     lun +fr_FR.ISO-8859-1     ABDAY_3     mar +fr_FR.ISO-8859-1     ABDAY_4     mer +fr_FR.ISO-8859-1     ABDAY_5     jeu +fr_FR.ISO-8859-1     ABDAY_6     ven +fr_FR.ISO-8859-1     ABDAY_7     sam +fr_FR.ISO-8859-1     DAY_1       dimanche +fr_FR.ISO-8859-1     DAY_2       lundi +fr_FR.ISO-8859-1     DAY_3       mardi +fr_FR.ISO-8859-1     DAY_4       mercredi +fr_FR.ISO-8859-1     DAY_5       jeudi +fr_FR.ISO-8859-1     DAY_6       vendredi +fr_FR.ISO-8859-1     DAY_7       samedi +fr_FR.ISO-8859-1     ABMON_1     jan +fr_FR.ISO-8859-1     ABMON_2     fév +fr_FR.ISO-8859-1     ABMON_3     mar +fr_FR.ISO-8859-1     ABMON_4     avr +fr_FR.ISO-8859-1     ABMON_5     mai +fr_FR.ISO-8859-1     ABMON_6     jun +fr_FR.ISO-8859-1     ABMON_7     jui +fr_FR.ISO-8859-1     ABMON_8     aoû +fr_FR.ISO-8859-1     ABMON_9     sep +fr_FR.ISO-8859-1     ABMON_10    oct +fr_FR.ISO-8859-1     ABMON_11    nov +fr_FR.ISO-8859-1     ABMON_12    déc +fr_FR.ISO-8859-1     MON_1       janvier +fr_FR.ISO-8859-1     MON_2       février +fr_FR.ISO-8859-1     MON_3       mars +fr_FR.ISO-8859-1     MON_4       avril +fr_FR.ISO-8859-1     MON_5       mai +fr_FR.ISO-8859-1     MON_6       juin +fr_FR.ISO-8859-1     MON_7       juillet +fr_FR.ISO-8859-1     MON_8       août +fr_FR.ISO-8859-1     MON_9       septembre +fr_FR.ISO-8859-1     MON_10      octobre +fr_FR.ISO-8859-1     MON_11      novembre +fr_FR.ISO-8859-1     MON_12      décembre +fr_FR.ISO-8859-1     D_T_FMT     "%a %d %b %Y %T %Z" +fr_FR.ISO-8859-1     D_FMT       "%d.%m.%Y" +fr_FR.ISO-8859-1     T_FMT       "%T" +fr_FR.ISO-8859-1     RADIXCHAR   , +fr_FR.ISO-8859-1     THOUSEP     "" +fr_FR.ISO-8859-1     YESEXPR     ^[oOyY].* +fr_FR.ISO-8859-1     NOEXPR      ^[nN].* +ja_JP.EUC-JP         ABDAY_1     Æü +ja_JP.EUC-JP         ABDAY_2     ·î +ja_JP.EUC-JP         ABDAY_3     ²Ð +ja_JP.EUC-JP         ABDAY_4     ¿å +ja_JP.EUC-JP         ABDAY_5     ÌÚ +ja_JP.EUC-JP         ABDAY_6     ¶â +ja_JP.EUC-JP         ABDAY_7     ÅÚ +ja_JP.EUC-JP         DAY_1       ÆüÍËÆü +ja_JP.EUC-JP         DAY_2       ·îÍËÆü +ja_JP.EUC-JP         DAY_3       ²ÐÍËÆü +ja_JP.EUC-JP         DAY_4       ¿åÍËÆü +ja_JP.EUC-JP         DAY_5       ÌÚÍËÆü +ja_JP.EUC-JP         DAY_6       ¶âÍËÆü +ja_JP.EUC-JP         DAY_7       ÅÚÍËÆü +ja_JP.EUC-JP         ABMON_1     " 1·î" +ja_JP.EUC-JP         ABMON_2     " 2·î" +ja_JP.EUC-JP         ABMON_3     " 3·î" +ja_JP.EUC-JP         ABMON_4     " 4·î" +ja_JP.EUC-JP         ABMON_5     " 5·î" +ja_JP.EUC-JP         ABMON_6     " 6·î" +ja_JP.EUC-JP         ABMON_7     " 7·î" +ja_JP.EUC-JP         ABMON_8     " 8·î" +ja_JP.EUC-JP         ABMON_9     " 9·î" +ja_JP.EUC-JP         ABMON_10    "10·î" +ja_JP.EUC-JP         ABMON_11    "11·î" +ja_JP.EUC-JP         ABMON_12    "12·î" +ja_JP.EUC-JP         MON_1       "1·î" +ja_JP.EUC-JP         MON_2       "2·î" +ja_JP.EUC-JP         MON_3       "3·î" +ja_JP.EUC-JP         MON_4       "4·î" +ja_JP.EUC-JP         MON_5       "5·î" +ja_JP.EUC-JP         MON_6       "6·î" +ja_JP.EUC-JP         MON_7       "7·î" +ja_JP.EUC-JP         MON_8       "8·î" +ja_JP.EUC-JP         MON_9       "9·î" +ja_JP.EUC-JP         MON_10      "10·î" +ja_JP.EUC-JP         MON_11      "11·î" +ja_JP.EUC-JP         MON_12      "12·î" +ja_JP.EUC-JP         T_FMT_AMPM  "%p%I»þ%Mʬ%SÉÃ" +ja_JP.EUC-JP         ERA_D_FMT   "%EY%m·î%dÆü" +ja_JP.EUC-JP         ERA_D_T_FMT "%EY%m·î%dÆü %H»þ%Mʬ%SÉÃ" +ja_JP.EUC-JP         RADIXCHAR   . +ja_JP.EUC-JP         THOUSEP     , +ja_JP.EUC-JP         YESEXPR     ^([yY£ù£Ù]|¤Ï¤¤|¥Ï¥¤) +ja_JP.EUC-JP         NOEXPR      ^([nN£î£Î]|¤¤¤¤¤¨|¥¤¥¤¥¨) +# Is CRNCYSTR supposed to be the national or international sign? +# ja_JP.EUC-JP         CRNCYSTR    JPY +ja_JP.EUC-JP         CODESET     EUC-JP diff --git a/test/locale/tst-leaks.c b/test/locale/tst-leaks.c new file mode 100644 index 000000000..7a4b557f5 --- /dev/null +++ b/test/locale/tst-leaks.c @@ -0,0 +1,18 @@ +#include <locale.h> +#include <mcheck.h> + +int +main (void) +{ +  int cnt; + +  mtrace (); + +  for (cnt = 0; cnt < 100; ++cnt) +    { +      setlocale (LC_ALL, "de_DE.ISO-8859-1"); +      setlocale (LC_ALL, "de_DE.UTF-8"); +    } + +  return 0; +} diff --git a/test/locale/tst-mbswcs1.c b/test/locale/tst-mbswcs1.c new file mode 100644 index 000000000..fb2ea84cd --- /dev/null +++ b/test/locale/tst-mbswcs1.c @@ -0,0 +1,63 @@ +/* Test restarting behaviour of mbrtowc. +   Copyright (C) 2000, 2005 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Bruno Haible <haible@ilog.fr>. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <stdio.h> +#include <string.h> +#include <wchar.h> +#include <locale.h> + +#define show(expr, nexp, wcexp) \ +  n = expr;								  \ +  printf (#expr " -> %Zd", n);						  \ +  printf (", wc = %lu", (unsigned long int) wc);			  \ +  if (n != (size_t) nexp || wc != wcexp)				  \ +    {									  \ +      printf (", expected %Zd and %lu", nexp, (unsigned long int) wcexp); \ +      result = 1;							  \ +    }									  \ +  putc ('\n', stdout) + +int +main (void) +{ +  const unsigned char buf[6] = { 0x25,  0xe2, 0x82, 0xac,  0xce, 0xbb }; +  mbstate_t state; +  wchar_t wc = 42; +  size_t n; +  int result = 0; +  const char *used_locale; + +  setlocale (LC_CTYPE, "de_DE.UTF-8"); +  /* Double check.  */ +  used_locale = setlocale (LC_CTYPE, NULL); +  printf ("used locale: \"%s\"\n", used_locale); +  result = strcmp (used_locale, "de_DE.UTF-8"); + +  memset (&state, '\0', sizeof (state)); + +  show (mbrtowc (&wc, (const char *) buf + 0, 1, &state), 1, 37); +  show (mbrtowc (&wc, (const char *) buf + 1, 1, &state), -2, 37); +  show (mbrtowc (&wc, (const char *) buf + 2, 3, &state), 2, 8364); +  show (mbrtowc (&wc, (const char *) buf + 4, 1, &state), -2, 8364); +  show (mbrtowc (&wc, (const char *) buf + 5, 1, &state), 1, 955); +  show (mbrtowc (&wc, (const char *) buf + 5, 1, &state), -1, 955); + +  return result; +} diff --git a/test/locale/tst-mbswcs2.c b/test/locale/tst-mbswcs2.c new file mode 100644 index 000000000..49f13cc87 --- /dev/null +++ b/test/locale/tst-mbswcs2.c @@ -0,0 +1,65 @@ +/* Test restarting behaviour of mbsnrtowcs. +   Copyright (C) 2000 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Bruno Haible <haible@ilog.fr>. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <stdio.h> +#include <string.h> +#include <wchar.h> +#include <locale.h> + +#define show(expr, nexp, wcexp, end) \ +  n = expr;								\ +  printf (#expr " -> %Zd", n);						\ +  printf (", wc = %lu, src = buf+%d", (unsigned long int) wc,		\ +	  src - (const char *) buf);					\ +  if (n != (size_t) nexp || wc != wcexp || src != (const char *) (end))	\ +    {									\ +      printf (", expected %Zd and %lu and buf+%d", nexp,		\ +	      (unsigned long int) wcexp, (end) - buf);			\ +      result = 1;							\ +    }									\ +  putc ('\n', stdout) + +int +main (void) +{ +  unsigned char buf[6] = { 0x25,  0xe2, 0x82, 0xac,  0xce, 0xbb }; +  mbstate_t state; +  const char *src; +  wchar_t wc = 42; +  size_t n; +  int result = 0; +  const char *used_locale; + +  setlocale (LC_CTYPE,"de_DE.UTF-8"); +  /* Double check.  */ +  used_locale = setlocale (LC_CTYPE, NULL); +  printf ("used locale: \"%s\"\n", used_locale); +  result = strcmp (used_locale, "de_DE.UTF-8"); + +  memset (&state, '\0', sizeof (state)); + +  src = (const char *) buf; +  show (mbsnrtowcs (&wc, &src, 1, 1, &state), 1, 37, buf + 1); +  show (mbsnrtowcs (&wc, &src, 3, 1, &state), 1, 8364, buf + 4); +  show (mbsnrtowcs (&wc, &src, 1, 1, &state), 0, 8364, buf + 5); +  show (mbsnrtowcs (&wc, &src, 1, 1, &state), 1, 955, buf + 6); + +  return result; +} diff --git a/test/locale/tst-mbswcs3.c b/test/locale/tst-mbswcs3.c new file mode 100644 index 000000000..0c4af4c14 --- /dev/null +++ b/test/locale/tst-mbswcs3.c @@ -0,0 +1,76 @@ +/* Test restarting behaviour of wcsrtombs. +   Copyright (C) 2000 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Bruno Haible <haible@ilog.fr>. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <stdio.h> +#include <string.h> +#include <wchar.h> +#include <locale.h> + +#define show(expr, nexp, srcexp, bufexp) \ +  {									\ +    size_t res = expr;							\ +    printf (#expr " -> %Zd", res);					\ +    dst += res;								\ +    printf (", src = srcbuf+%td, dst = buf+%td",			\ +	    src - srcbuf, dst - (char *) buf);				\ +    if (res != nexp || src != (srcexp) || dst != (char *) (bufexp))	\ +      {									\ +	printf (", expected %Zd and srcbuf+%td and buf+%td", nexp,	\ +		(srcexp) - srcbuf, (bufexp) - (unsigned char *) buf);	\ +	result = 1;							\ +      }									\ +    putc ('\n', stdout);						\ +  } + +int +main (void) +{ +  unsigned char buf[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +  const unsigned char bufcheck[6] = { 0x25, 0xe2, 0x82, 0xac, 0xce, 0xbb }; +  const wchar_t srcbuf[4] = { 0x25, 0x20ac, 0x03bb, 0 }; +  mbstate_t state; +  const wchar_t *src; +  char *dst; +  int result = 0; +  const char *used_locale; + +  setlocale (LC_CTYPE, "de_DE.UTF-8"); +  /* Double check.  */ +  used_locale = setlocale (LC_CTYPE, NULL); +  printf ("used locale: \"%s\"\n", used_locale); +  result = strcmp (used_locale, "de_DE.UTF-8"); + +  memset (&state, '\0', sizeof (state)); + +  src = srcbuf; +  dst = (char *) buf; +  show (wcsrtombs (dst, &src, 1, &state), 1, srcbuf + 1, buf + 1); +  show (wcsrtombs (dst, &src, 1, &state), 0, srcbuf + 1, buf + 1); +  show (wcsrtombs (dst, &src, 4, &state), 3, srcbuf + 2, buf + 4); +  show (wcsrtombs (dst, &src, 2, &state), 2, srcbuf + 3, buf + 6); + +  if (memcmp (buf, bufcheck, 6)) +    { +      puts ("wrong results"); +      result = 1; +    } + +  return result; +} diff --git a/test/locale/tst-mbswcs4.c b/test/locale/tst-mbswcs4.c new file mode 100644 index 000000000..e02b67569 --- /dev/null +++ b/test/locale/tst-mbswcs4.c @@ -0,0 +1,63 @@ +/* Test restarting behaviour of mbsrtowcs. +   Copyright (C) 2000 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <stdio.h> +#include <string.h> +#include <wchar.h> +#include <locale.h> + +#define show(expr, nexp, wcexp, end) \ +  n = expr;								\ +  printf (#expr " -> %Zd", n);						\ +  printf (", wc = %lu, src = buf+%d", (unsigned long int) wc,		\ +	  src - (const char *) buf);					\ +  if (n != (size_t) nexp || wc != wcexp || src != (const char *) (end))	\ +    {									\ +      printf (", expected %Zd and %lu and buf+%d", nexp,		\ +	      (unsigned long int) wcexp, (end) - buf);			\ +      result = 1;							\ +    }									\ +  putc ('\n', stdout) + +int +main (void) +{ +  unsigned char buf[6] = { 0x25,  0xe2, 0x82, 0xac,  0xce, 0xbb }; +  mbstate_t state; +  const char *src; +  wchar_t wc = 42; +  size_t n; +  int result = 0; +  const char *used_locale; + +  setlocale (LC_CTYPE,"de_DE.UTF-8"); +  /* Double check.  */ +  used_locale = setlocale (LC_CTYPE, NULL); +  printf ("used locale: \"%s\"\n", used_locale); +  result = strcmp (used_locale, "de_DE.UTF-8"); + +  memset (&state, '\0', sizeof (state)); + +  src = (const char *) buf; +  show (mbsrtowcs (&wc, &src, 1, &state), 1, 37, buf + 1); +  show (mbsrtowcs (&wc, &src, 1, &state), 1, 8364, buf + 4); +  show (mbsrtowcs (&wc, &src, 1, &state), 1, 955, buf + 6); + +  return result; +} diff --git a/test/locale/tst-mbswcs5.c b/test/locale/tst-mbswcs5.c new file mode 100644 index 000000000..7cab97e72 --- /dev/null +++ b/test/locale/tst-mbswcs5.c @@ -0,0 +1,75 @@ +/* Test restarting behaviour of wcrtomb. +   Copyright (C) 2000 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Bruno Haible <haible@ilog.fr>. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <stdio.h> +#include <string.h> +#include <wchar.h> +#include <locale.h> + +#define show(expr, nexp, bufexp) \ +  {									\ +    size_t res = expr;							\ +    printf (#expr " -> %Zd", res);					\ +    dst += res;								\ +    printf (", dst = buf+%td", dst - (char *) buf);			\ +    if (res != nexp || dst != (char *) (bufexp))			\ +      {									\ +	printf (", expected %Zd and buf+%td", nexp,			\ +		(bufexp) - (unsigned char *) buf);			\ +	result = 1;							\ +      }									\ +    putc ('\n', stdout);						\ +  } + +int +main (void) +{ +  unsigned char buf[7] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +  const unsigned char bufcheck[7] = { 0x25, 0xe2, 0x82, 0xac, 0xce, 0xbb, 0 }; +  const wchar_t srcbuf[4] = { 0x25, 0x20ac, 0x03bb, 0 }; +  mbstate_t state; +  const wchar_t *src; +  char *dst; +  int result = 0; +  const char *used_locale; + +  setlocale (LC_CTYPE, "de_DE.UTF-8"); +  /* Double check.  */ +  used_locale = setlocale (LC_CTYPE, NULL); +  printf ("used locale: \"%s\"\n", used_locale); +  result = strcmp (used_locale, "de_DE.UTF-8"); + +  memset (&state, '\0', sizeof (state)); + +  src = srcbuf; +  dst = (char *) buf; +  show (wcrtomb (dst, *src++, &state), 1, buf + 1); +  show (wcrtomb (dst, *src++, &state), 3, buf + 4); +  show (wcrtomb (dst, *src++, &state), 2, buf + 6); +  show (wcrtomb (dst, *src, &state), 1, buf + 7); + +  if (memcmp (buf, bufcheck, 7)) +    { +      puts ("wrong results"); +      result = 1; +    } + +  return result; +} diff --git a/test/locale/tst-mbswcs6.c b/test/locale/tst-mbswcs6.c new file mode 100644 index 000000000..eb383ac87 --- /dev/null +++ b/test/locale/tst-mbswcs6.c @@ -0,0 +1,74 @@ +/* Test for invalid input to wcrtomb. +   Copyright (C) 2001 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2001. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <errno.h> +#include <locale.h> +#include <stdio.h> +#include <string.h> +#include <wchar.h> + + +static int +do_test (const char *loc) +{ +  char buf[100]; +  size_t n; +  mbstate_t state; +  const char *nloc; +  int res; + +  nloc = setlocale (LC_ALL, loc); +  if (nloc == NULL) +    { +      printf ("could not set locale \"%s\"\n", loc); +      return 1; +    } +  printf ("new locale: %s\n", nloc); + +  memset (&state, '\0', sizeof (state)); +  errno = 0; +  n = wcrtomb (buf, (wchar_t) -15l, &state); + +  printf ("n = %zd, errno = %d (%s)\n", n, errno, strerror (errno)); + +  res = n != (size_t) -1 || errno != EILSEQ; +  if (res) +    puts ("*** FAIL"); +  putchar ('\n'); + +  return res; +} + + +int +main (void) +{ +  int res; + +  res = do_test ("C"); +  res |= do_test ("de_DE.ISO-8859-1"); +  res |= do_test ("de_DE.UTF-8"); +  res |= do_test ("en_US.ISO-8859-1"); +  res |= do_test ("ja_JP.UTF-8"); +  res |= do_test ("hr_HR.ISO-8859-2"); +  //res |= do_test ("ru_RU.KOI8-R"); + +  return res; +} diff --git a/test/locale/tst-numeric.c b/test/locale/tst-numeric.c new file mode 100644 index 000000000..9d3c91d15 --- /dev/null +++ b/test/locale/tst-numeric.c @@ -0,0 +1,74 @@ +/* Testing the implementation of LC_NUMERIC and snprintf(). +   Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Petter Reinholdtsen <pere@hungry.com>, 2003 + +   Based on tst-fmon.c by Jochen Hein <jochen.hein@delphi.central.de>, 1997. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <stdio.h> +#include <locale.h> +#include <string.h> +#include <stdlib.h> + +/* +  test-numeric gets called with three parameters: +   - the locale +   - the format-string to be used +   - the actual number to be formatted +   - the expected string +   If the test passes, test-numeric terminates with returncode 0, +   otherwise with 1 +*/ +#define EXIT_SUCCESS 0 +#define EXIT_FAILURE 1 +#define EXIT_SETLOCALE 2 +#define EXIT_SNPRINTF 3 + +int +main (int argc, char *argv[]) +{ +  char *s = malloc (201); +  double val; + +  /* Make sure to read the value before setting of the locale, as +     strtod() is locale-dependent. */ +  val = strtod (argv[3], NULL); + +  if (setlocale (LC_ALL, argv[1]) == NULL) +    { +      fprintf (stderr, "setlocale(LC_ALL, \"%s\"): %m\n", argv[1]); +      exit (EXIT_SETLOCALE); +    } + +  if (snprintf (s, 200, argv[2], val) == -1) +    { +      perror ("snprintf"); +      exit (EXIT_SNPRINTF); +    } + +  if (strcmp (s, argv[4]) != 0) +    { +      printf ("\ +locale: \"%s\", format: \"%s\", expected: \"%s\", got: \"%s\" => %s\n", +	      argv[1], argv[2], argv[4], s, +	      strcmp (s, argv[4]) != 0 ? "false" : "correct"); +      exit (EXIT_FAILURE); +    } + +  return EXIT_SUCCESS; +} diff --git a/test/locale/tst-rpmatch.c b/test/locale/tst-rpmatch.c new file mode 100644 index 000000000..d751a43bf --- /dev/null +++ b/test/locale/tst-rpmatch.c @@ -0,0 +1,37 @@ +/* Test program for rpmatch function. +   Copyright (C) 1998, 2000 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jochen Hein <jochen.hein@delphi.central.de>. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> + +int +main (int argc, char* argv[]) +{ +  setlocale (LC_ALL, argv[1]); + +  if (rpmatch (argv[2]) != atol (argv[3])) +    { +      fprintf (stderr,"Failed: Locale %s, String %s, Exp: %s, got %d\n", +	       argv[1], argv[2], argv[3], rpmatch (argv[2])); +      exit (EXIT_FAILURE); +    } +  return EXIT_SUCCESS; +} diff --git a/test/locale/tst-setlocale.c b/test/locale/tst-setlocale.c new file mode 100644 index 000000000..1f8e68d88 --- /dev/null +++ b/test/locale/tst-setlocale.c @@ -0,0 +1,25 @@ +/* Test case by Jakub Jelinek <jakub@redhat.com>.  */ +#include <locale.h> +#include <stdio.h> +#include <string.h> + +int +main (void) +{ +  char q[30]; +  char *s; + +  setlocale (LC_ALL, ""); +  printf ("after setlocale (LC_ALL, \"\"): %s\n", setlocale(LC_NUMERIC, NULL)); + +  strcpy (q, "de_DE.UTF-8"); +  setlocale (LC_NUMERIC, q); +  printf ("after setlocale (LC_NUMERIC, \"%s\"): %s\n", +	  q, setlocale(LC_NUMERIC, NULL)); + +  strcpy (q, "de_DE.ISO-8859-1"); +  s = setlocale (LC_NUMERIC, NULL); +  printf ("after overwriting string: %s\n", s); + +  return strcmp (s, "de_DE.UTF-8") != 0; +} diff --git a/test/locale/tst-sscanf.c b/test/locale/tst-sscanf.c new file mode 100644 index 000000000..32c13285a --- /dev/null +++ b/test/locale/tst-sscanf.c @@ -0,0 +1,56 @@ +#include <stdio.h> +#include <locale.h> +#include <assert.h> + +#define P0 "\xDB\xB0" +#define P1 "\xDB\xB1" +#define P2 "\xDB\xB2" +#define P3 "\xDB\xB3" +#define P4 "\xDB\xB4" +#define P5 "\xDB\xB5" +#define P6 "\xDB\xB6" +#define P7 "\xDB\xB7" +#define P8 "\xDB\xB8" +#define P9 "\xDB\xB9" +#define PD "\xd9\xab" +#define PT "\xd9\xac" + +static int +check_sscanf (const char *s, const char *format, const float n) +{ +  float f; + +  if (sscanf (s, format, &f) != 1) +    { +      printf ("nothing found for \"%s\"\n", s); +      return 1; +    } +  if (f != n) +    { +      printf ("got %f expected %f from \"%s\"\n", f, n, s); +      return 1; +    } +  return 0; +} + +static int +do_test (void) +{ +  if (setlocale (LC_ALL, "fa_IR.UTF-8") == NULL) +    { +      puts ("cannot set fa_IR locale"); +      return 1; +    } + +  int r = check_sscanf (P3 PD P1 P4, "%I8f", 3.14); +  r |= check_sscanf (P3 PT P1 P4 P5, "%I'f", 3145); +  r |= check_sscanf (P3 PD P1 P4 P1 P5 P9, "%If", 3.14159); +  r |= check_sscanf ("-" P3 PD P1 P4 P1 P5, "%If", -3.1415); +  r |= check_sscanf ("+" PD P1 P4 P1 P5, "%If", +.1415); +  r |= check_sscanf (P3 PD P1 P4 P1 P5 "e+" P2, "%Ie", 3.1415e+2); + +  return r; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/test/locale/tst-strfmon1.c b/test/locale/tst-strfmon1.c new file mode 100644 index 000000000..e30aa1b20 --- /dev/null +++ b/test/locale/tst-strfmon1.c @@ -0,0 +1,42 @@ +#include <monetary.h> +#include <locale.h> +#include <stdio.h> +#include <string.h> + +static const struct +{ +  const char *locale; +  const char *expected; +} tests[] = +  { +    { "de_DE.ISO-8859-1", "|-12,34 EUR|-12,34|" }, +    { "da_DK.ISO-8859-1", "|kr -12,34|-12,34|" }, +    { "zh_TW.EUC-TW", "|-NT$12.34|-12.34|" }, +    { "sv_SE.ISO-8859-1", "|-12,34 kr|-12,34|" } +  }; +#define ntests (sizeof (tests) / sizeof (tests[0])) + + +static int +do_test (void) +{ +  int res = 0; +  for (int i = 0; i < ntests; ++i) +    { +      char buf[500]; +      if (setlocale (LC_ALL, tests[i].locale) == NULL) +	{ +	  printf ("failed to set locale %s\n", tests[i].locale); +	  res = 1; +	  continue; +	} +      strfmon (buf, sizeof (buf), "|%n|%!n|", -12.34, -12.34); +      int fail = strcmp (buf, tests[i].expected) != 0; +      printf ("%s%s\n", buf, fail ? " *** FAIL ***" : ""); +      res |= fail; +    } +  return res; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/test/locale/tst-trans.c b/test/locale/tst-trans.c new file mode 100644 index 000000000..034a36216 --- /dev/null +++ b/test/locale/tst-trans.c @@ -0,0 +1,71 @@ +/* Test program for user-defined character maps. +   Copyright (C) 1999, 2000 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@cygnus.com>. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <wchar.h> +#include <wctype.h> + +int +main (void) +{ +  char buf[30]; +  wchar_t wbuf[30]; +  wctrans_t t; +  wint_t wch; +  int errors = 0; +  int len; + +  setlocale (LC_ALL, ""); + +  t = wctrans ("test"); +  if (t == (wctrans_t) 0) +    { +      puts ("locale data files probably not loaded"); +      exit (1); +    } + +  wch = towctrans (L'A', t); +  printf ("towctrans (L'A', t) = %c\n", wch); +  if (wch != L'B') +    errors = 1; + +  wch = towctrans (L'B', t); +  printf ("towctrans (L'B', t) = %c\n", wch); +  if (wch != L'C') +    errors = 1; + +  /* Test the output digit handling.  */ +  swprintf (wbuf, sizeof (wbuf) / sizeof (wbuf[0]), L"%Id", 0x499602D2); +  errors |= wcscmp (wbuf, L"bcdefghija") != 0; +  len = wcslen (wbuf); +  errors |= len != 10; +  printf ("len = %d, wbuf = L\"%ls\"\n", len, wbuf); + +  snprintf (buf, sizeof buf, "%Id", 0x499602D2); +  errors |= strcmp (buf, "bcdefghija") != 0; +  len = strlen (buf); +  errors |= len != 10; +  printf ("len = %d, buf = \"%s\"\n", len, buf); + +  return errors; +} diff --git a/test/locale/tst-wctype.c b/test/locale/tst-wctype.c new file mode 100644 index 000000000..8fd8ce518 --- /dev/null +++ b/test/locale/tst-wctype.c @@ -0,0 +1,144 @@ +/* Test program for iswctype() function in ja_JP locale. +   Copyright (C) 2000 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@cygnus.com>. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <error.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <wchar.h> +#include <wctype.h> + +int +main (void) +{ +  wctype_t wct; +  wchar_t buf[1000]; +  int result = 1; + +  setlocale (LC_ALL, ""); +  wprintf (L"locale = %s\n", setlocale (LC_CTYPE, NULL)); + +  wct = wctype ("jhira"); +  if (wct == 0) +    error (EXIT_FAILURE, 0, "jhira: no such character class"); + +  if (fgetws (buf, sizeof (buf) / sizeof (buf[0]), stdin) != NULL) +    { +      int n; + +      wprintf (L"buf[] = \"%ls\"\n", buf); + +      result = 0; + +      for (n = 0; buf[n] != L'\0'; ++n) +	{ +	  wprintf (L"jhira(U%04lx = %lc) = %d\n", (long) buf[n], buf[n], +		   iswctype (buf[n], wct)); +	  result |= ((buf[n] < 0xff && iswctype (buf[n], wct)) +		     || (buf[n] > 0xff && !iswctype (buf[n], wct))); +	} +    } + +  wct = wctype ("jkata"); +  if (wct == 0) +    error (EXIT_FAILURE, 0, "jkata: no such character class"); + +  if (fgetws (buf, sizeof (buf) / sizeof (buf[0]), stdin) != NULL) +    { +      int n; + +      wprintf (L"buf[] = \"%ls\"\n", buf); + +      result = 0; + +      for (n = 0; buf[n] != L'\0'; ++n) +	{ +	  wprintf (L"jkata(U%04lx = %lc) = %d\n", (long) buf[n], buf[n], +		   iswctype (buf[n], wct)); +	  result |= ((buf[n] < 0xff && iswctype (buf[n], wct)) +		     || (buf[n] > 0xff && !iswctype (buf[n], wct))); +	} +    } + +  wct = wctype ("jdigit"); +  if (wct == 0) +    error (EXIT_FAILURE, 0, "jdigit: no such character class"); + +  if (fgetws (buf, sizeof (buf) / sizeof (buf[0]), stdin) != NULL) +    { +      int n; + +      wprintf (L"buf[] = \"%ls\"\n", buf); + +      result = 0; + +      for (n = 0; buf[n] != L'\0'; ++n) +	{ +	  wprintf (L"jdigit(U%04lx = %lc) = %d\n", (long) buf[n], buf[n], +		   iswctype (buf[n], wct)); +	  result |= ((buf[n] < 0xff && iswctype (buf[n], wct)) +		     || (buf[n] > 0xff && !iswctype (buf[n], wct))); +	} +    } + +  wct = wctype ("jspace"); +  if (wct == 0) +    error (EXIT_FAILURE, 0, "jspace: no such character class"); + +  if (fgetws (buf, sizeof (buf) / sizeof (buf[0]), stdin) != NULL) +    { +      int n; + +      wprintf (L"buf[] = \"%ls\"\n", buf); + +      result = 0; + +      for (n = 0; buf[n] != L'\0'; ++n) +	{ +	  wprintf (L"jspace(U%04lx = %lc) = %d\n", (long) buf[n], buf[n], +		   iswctype (buf[n], wct)); +	  result |= ((buf[n] < 0xff && iswctype (buf[n], wct)) +		     || (buf[n] > 0xff && !iswctype (buf[n], wct))); +	} +    } + +  wct = wctype ("jkanji"); +  if (wct == 0) +    error (EXIT_FAILURE, 0, "jkanji: no such character class"); + +  if (fgetws (buf, sizeof (buf) / sizeof (buf[0]), stdin) != NULL) +    { +      int n; + +      wprintf (L"buf[] = \"%ls\"\n", buf); + +      result = 0; + +      for (n = 0; buf[n] != L'\0'; ++n) +	{ +	  wprintf (L"jkanji(U%04lx = %lc) = %d\n", (long) buf[n], buf[n], +		   iswctype (buf[n], wct)); +	  result |= ((buf[n] < 0xff && iswctype (buf[n], wct)) +		     || (buf[n] > 0xff && !iswctype (buf[n], wct))); +	} +    } + +  return result; +} diff --git a/test/locale/tst-xlocale1.c b/test/locale/tst-xlocale1.c new file mode 100644 index 000000000..297c9ad7e --- /dev/null +++ b/test/locale/tst-xlocale1.c @@ -0,0 +1,75 @@ +#include <locale.h> +#include <stdio.h> +#include <string.h> + + +static struct +{ +  const char *locale; +  const char *str1; +  const char *str2; +  int result; +} tests[] = +  { +    { "C", "TRANSLIT", "translit", 0 }, +    { "de_DE.ISO-8859-1", "TRANSLIT", "translit", 0 }, +    { "de_DE.ISO-8859-1", "TRANSLIT", "trÄnslit", -1 }, +    { "de_DE.UTF-8", "TRANSLIT", "translit", 0 }, +    { "de_DE.ISO-8859-1", "ä", "Ä", 1 } +  }; +#define ntests (sizeof (tests) / sizeof (tests[0])) + + +int +main (void) +{ +  size_t cnt; +  int result = 0; +  locale_t loc = newlocale (1 << LC_ALL, "C", NULL); + +  for (cnt = 0; cnt < ntests; ++cnt) +    { +      int r; + +      if (setlocale (LC_ALL, tests[cnt].locale) == NULL) +	{ +	  printf ("cannot set locale \"%s\": %m\n", tests[cnt].locale); +	  result = 1; +	  continue; +	} + +      printf ("\nstrcasecmp_l (\"%s\", \"%s\", loc)\n", +	      tests[cnt].str1, tests[cnt].str2); + +      r = strcasecmp_l (tests[cnt].str1, tests[cnt].str2, loc); +      if (tests[cnt].result == 0) +	{ +	  if (r != 0) +	    { +	      printf ("\"%s\" and \"%s\" expected to be the same, result %d\n", +		      tests[cnt].str1, tests[cnt].str2, r); +	      result = 1; +	    } +	} +      else if (tests[cnt].result < 0) +	{ +	  if (r >= 0) +	    { +	      printf ("\"%s\" expected to be smaller than \"%s\", result %d\n", +		      tests[cnt].str1, tests[cnt].str2, r); +	      result = 1; +	    } +	} +      else +	{ +	  if (r <= 0) +	    { +	      printf ("\"%s\" expected to be larger than \"%s\", result %d\n", +		      tests[cnt].str1, tests[cnt].str2, r); +	      result = 1; +	    } +	} +    } + +  return result; +} diff --git a/test/locale/tst-xlocale2.c b/test/locale/tst-xlocale2.c new file mode 100644 index 000000000..30d87de72 --- /dev/null +++ b/test/locale/tst-xlocale2.c @@ -0,0 +1,64 @@ +#include <ctype.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> + + +static int do_test (__locale_t l); + +int +main (void) +{ +  locale_t l; +  locale_t l2; +  int result; + +  l = newlocale (1 << LC_ALL, "de_DE.ISO-8859-1", NULL); +  if (l == NULL) +    { +      printf ("newlocale failed: %m\n"); +      exit (EXIT_FAILURE); +    } +  puts ("Running tests of created locale"); +  result = do_test (l); + +  l2 = duplocale (l); +  if (l2 == NULL) +    { +      printf ("duplocale failed: %m\n"); +      exit (EXIT_FAILURE); +    } +  freelocale (l); +  puts ("Running tests of duplicated locale"); +  result |= do_test (l2); + +  return result; +} + + +static const char str[] = "0123456789abcdef ABCDEF ghijklmnopqrstuvwxyzäÄöÖüÜ"; +static const char exd[] = "11111111110000000000000000000000000000000000000000"; +static const char exa[] = "00000000001111110111111011111111111111111111111111"; +static const char exx[] = "11111111111111110111111000000000000000000000000000"; + + +static int +do_test (locale_t l) +{ +  int result = 0; +size_t n; + +#define DO_TEST(TEST, RES) \ +  for (n = 0; n < sizeof (str) - 1; ++n)				      \ +    if ('0' + (TEST (str[n], l) != 0) != RES[n])			      \ +      {									      \ +	printf ("%s(%c) failed\n", #TEST, str[n]);			      \ +	result = 1;							      \ +      } + +  DO_TEST (isdigit_l, exd); +  DO_TEST (isalpha_l, exa); +  DO_TEST (isxdigit_l, exx); + +  return result; +} diff --git a/test/locale/tst_nl_langinfo.c b/test/locale/tst_nl_langinfo.c new file mode 100644 index 000000000..fcf2fe2eb --- /dev/null +++ b/test/locale/tst_nl_langinfo.c @@ -0,0 +1,296 @@ +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <langinfo.h> +#include <nl_types.h> + +#if !defined(__UCLIBC__) && 0 +#define DO_EXTRA +#endif + +int main(int argc, char **argv) +{ +	char *l; +	const unsigned char *x; +/*  	const unsigned char *y; */ +	const unsigned char *p; + +	if (argc > 2) { +		printf("invalid args\n"); +		return EXIT_FAILURE; +	} +	if (argc == 1) { +		l = ""; +	} else { +		l = *++argv; +	} + +	if (!(x = setlocale(LC_ALL,l))) { +		printf("couldn't set locale %s\n", l); +		return EXIT_FAILURE; +	} + +/*  	printf("\nsetlocale returned:\n  "); */ +/*  	do { */ +/*  		printf("\\x%02x", *x); */ +/*  	} while (*x++); */ +/*  	printf("\n"); */ + +#ifndef __BCC__ +#define STR(X) #X +#else +#define STR(X) __STR(X) +#endif +#define __PASTE2(A,B) A.B + +#define DO_NL_I(X) \ +	printf( STR(X) " = %d\n", (int) nl_langinfo(X) ); +#define DO_NL_S(X) \ +	printf( STR(X) " = \"%s\"\n", nl_langinfo(X) ); +#define DO_NL_C(X) \ +	printf( STR(X) " = \"\\x%02x\"\n", *((unsigned char *) nl_langinfo(X)) ); + +	printf("ctype\n"); + +		DO_NL_S(CODESET); +#ifdef DO_EXTRA +		DO_NL_I(_NL_CTYPE_INDIGITS_MB_LEN); +		DO_NL_S(_NL_CTYPE_INDIGITS0_MB); +		DO_NL_S(_NL_CTYPE_INDIGITS1_MB); +		DO_NL_S(_NL_CTYPE_INDIGITS2_MB); +		DO_NL_S(_NL_CTYPE_INDIGITS3_MB); +		DO_NL_S(_NL_CTYPE_INDIGITS4_MB); +		DO_NL_S(_NL_CTYPE_INDIGITS5_MB); +		DO_NL_S(_NL_CTYPE_INDIGITS6_MB); +		DO_NL_S(_NL_CTYPE_INDIGITS7_MB); +		DO_NL_S(_NL_CTYPE_INDIGITS8_MB); +		DO_NL_S(_NL_CTYPE_INDIGITS9_MB); +#endif +		DO_NL_S(_NL_CTYPE_OUTDIGIT0_MB); +		DO_NL_S(_NL_CTYPE_OUTDIGIT1_MB); +		DO_NL_S(_NL_CTYPE_OUTDIGIT2_MB); +		DO_NL_S(_NL_CTYPE_OUTDIGIT3_MB); +		DO_NL_S(_NL_CTYPE_OUTDIGIT4_MB); +		DO_NL_S(_NL_CTYPE_OUTDIGIT5_MB); +		DO_NL_S(_NL_CTYPE_OUTDIGIT6_MB); +		DO_NL_S(_NL_CTYPE_OUTDIGIT7_MB); +		DO_NL_S(_NL_CTYPE_OUTDIGIT8_MB); +		DO_NL_S(_NL_CTYPE_OUTDIGIT9_MB); + + +	printf("numeric\n"); + +		DO_NL_S(RADIXCHAR);		/* DECIMAL_POINT */ +		DO_NL_S(THOUSEP);		/* THOUSANDS_SEP */ +/*  		DO_NL_S(GROUPING); */ + +	printf("GROUPING = \""); +	for (p = (unsigned char *) nl_langinfo(GROUPING) ; *p ; p++) { +		printf("\\x%02x", *p); +	} +	printf("\"\n\n"); + +	printf("monetary\n"); + +		DO_NL_S(INT_CURR_SYMBOL); +		DO_NL_S(CURRENCY_SYMBOL); +		DO_NL_S(MON_DECIMAL_POINT); +		DO_NL_S(MON_THOUSANDS_SEP); +/*  		DO_NL_S(MON_GROUPING); */ + +	printf("MON_GROUPING = \""); +	for (p = (unsigned char *) nl_langinfo(MON_GROUPING) ; *p ; p++) { +		printf("\\x%02x", *p); +	} +	printf("\"\n\n"); + +		DO_NL_S(POSITIVE_SIGN); +		DO_NL_S(NEGATIVE_SIGN); +		DO_NL_C(INT_FRAC_DIGITS); +		DO_NL_C(FRAC_DIGITS); +		DO_NL_C(P_CS_PRECEDES); +		DO_NL_C(P_SEP_BY_SPACE); +		DO_NL_C(N_CS_PRECEDES); +		DO_NL_C(N_SEP_BY_SPACE); +		DO_NL_C(P_SIGN_POSN); +		DO_NL_C(N_SIGN_POSN); +		DO_NL_C(INT_P_CS_PRECEDES); +		DO_NL_C(INT_P_SEP_BY_SPACE); +		DO_NL_C(INT_N_CS_PRECEDES); +		DO_NL_C(INT_N_SEP_BY_SPACE); +		DO_NL_C(INT_P_SIGN_POSN); +		DO_NL_C(INT_N_SIGN_POSN); + +		DO_NL_S(CRNCYSTR);		/* CURRENCY_SYMBOL */ + + +	printf("time\n"); + +		DO_NL_S(ABDAY_1); +		DO_NL_S(ABDAY_2); +		DO_NL_S(ABDAY_3); +		DO_NL_S(ABDAY_4); +		DO_NL_S(ABDAY_5); +		DO_NL_S(ABDAY_6); +		DO_NL_S(ABDAY_7); + +		DO_NL_S(DAY_1); +		DO_NL_S(DAY_2); +		DO_NL_S(DAY_3); +		DO_NL_S(DAY_4); +		DO_NL_S(DAY_5); +		DO_NL_S(DAY_6); +		DO_NL_S(DAY_7); + +		DO_NL_S(ABMON_1); +		DO_NL_S(ABMON_2); +		DO_NL_S(ABMON_3); +		DO_NL_S(ABMON_4); +		DO_NL_S(ABMON_5); +		DO_NL_S(ABMON_6); +		DO_NL_S(ABMON_7); +		DO_NL_S(ABMON_8); +		DO_NL_S(ABMON_9); +		DO_NL_S(ABMON_10); +		DO_NL_S(ABMON_11); +		DO_NL_S(ABMON_12); + +		DO_NL_S(MON_1); +		DO_NL_S(MON_2); +		DO_NL_S(MON_3); +		DO_NL_S(MON_4); +		DO_NL_S(MON_5); +		DO_NL_S(MON_6); +		DO_NL_S(MON_7); +		DO_NL_S(MON_8); +		DO_NL_S(MON_9); +		DO_NL_S(MON_10); +		DO_NL_S(MON_11); +		DO_NL_S(MON_12); + +		DO_NL_S(AM_STR); +		DO_NL_S(PM_STR); + +		DO_NL_S(D_T_FMT); +		DO_NL_S(D_FMT); +		DO_NL_S(T_FMT); +		DO_NL_S(T_FMT_AMPM); +/* 		DO_NL_S(ERA); */ +		{ +		    const char *p = nl_langinfo(ERA); +		    if (!p || !*p) { +			printf("ERA = (none)\n"); +		    } else { +			int i; +			printf("ERA:\n"); +			for (i=0 ; i < 100 ; i++) { +			    printf("  %3d: \"%s\"\n", i, p); +			    while (*p) ++p; +			    ++p; +			    if (!*p) break; +			} +		    } +		} + +		DO_NL_S(ERA_YEAR);		/* non SuSv3 */ +		DO_NL_S(ERA_D_FMT); +/* 		DO_NL_S(ALT_DIGITS); */ +		{ +		    const char *p = nl_langinfo(ALT_DIGITS); +		    if (!p || !*p) { +			printf("ALT_DIGITS = (none)\n"); +		    } else { +			int i; +			printf("ALT_DIGITS:\n"); +			for (i=0 ; i < 100 ; i++) { +			    printf("  %3d: \"%s\"\n", i, p); +			    while (*p) ++p; +			    ++p; +			} +		    } +		} +		DO_NL_S(ERA_D_T_FMT); +		DO_NL_S(ERA_T_FMT); + +#ifdef DO_EXTRA +		DO_NL_C(_NL_TIME_WEEK_NDAYS); +		DO_NL_I(_NL_TIME_WEEK_1STDAY); /* grr... this won't work with 16bit ptrs */ +		DO_NL_C(_NL_TIME_WEEK_1STWEEK); +		DO_NL_C(_NL_TIME_FIRST_WEEKDAY); +		DO_NL_C(_NL_TIME_FIRST_WORKDAY); +		DO_NL_C(_NL_TIME_CAL_DIRECTION); +		DO_NL_S(_NL_TIME_TIMEZONE); +		DO_NL_S(_DATE_FMT); +#endif + +	printf("messages\n"); + +		DO_NL_S(YESEXPR); +		DO_NL_S(NOEXPR); +		DO_NL_S(YESSTR); +		DO_NL_S(NOSTR); + +#ifdef DO_EXTRA + +	printf("paper\n"); + +		DO_NL_I(_NL_PAPER_HEIGHT); +		DO_NL_I(_NL_PAPER_WIDTH); + +	printf("name\n"); + +		DO_NL_S(_NL_NAME_NAME_FMT); +		DO_NL_S(_NL_NAME_NAME_GEN); +		DO_NL_S(_NL_NAME_NAME_MR); +		DO_NL_S(_NL_NAME_NAME_MRS); +		DO_NL_S(_NL_NAME_NAME_MISS); +		DO_NL_S(_NL_NAME_NAME_MS); + +	printf("address\n"); + +		DO_NL_S(_NL_ADDRESS_POSTAL_FMT); +		DO_NL_S(_NL_ADDRESS_COUNTRY_NAME); +		DO_NL_S(_NL_ADDRESS_COUNTRY_POST); +		DO_NL_S(_NL_ADDRESS_COUNTRY_AB2); +		DO_NL_S(_NL_ADDRESS_COUNTRY_AB3); +		DO_NL_S(_NL_ADDRESS_COUNTRY_CAR); +		DO_NL_I(_NL_ADDRESS_COUNTRY_NUM); +		DO_NL_S(_NL_ADDRESS_COUNTRY_ISBN); +		DO_NL_S(_NL_ADDRESS_LANG_NAME); +		DO_NL_S(_NL_ADDRESS_LANG_AB); +		DO_NL_S(_NL_ADDRESS_LANG_TERM); +		DO_NL_S(_NL_ADDRESS_LANG_LIB); + +	printf("telephone\n"); + +		DO_NL_S(_NL_TELEPHONE_TEL_INT_FMT); +		DO_NL_S(_NL_TELEPHONE_TEL_DOM_FMT); +		DO_NL_S(_NL_TELEPHONE_INT_SELECT); +		DO_NL_S(_NL_TELEPHONE_INT_PREFIX); + +	printf("measurement\n"); + +		DO_NL_C(_NL_MEASUREMENT_MEASUREMENT); /* 1 is metric, 2 is US */ + +	printf("identification\n"); + +		DO_NL_S(_NL_IDENTIFICATION_TITLE); +		DO_NL_S(_NL_IDENTIFICATION_SOURCE); +		DO_NL_S(_NL_IDENTIFICATION_ADDRESS); +		DO_NL_S(_NL_IDENTIFICATION_CONTACT); +		DO_NL_S(_NL_IDENTIFICATION_EMAIL); +		DO_NL_S(_NL_IDENTIFICATION_TEL); +		DO_NL_S(_NL_IDENTIFICATION_FAX); +		DO_NL_S(_NL_IDENTIFICATION_LANGUAGE); +		DO_NL_S(_NL_IDENTIFICATION_TERRITORY); +		DO_NL_S(_NL_IDENTIFICATION_AUDIENCE); +		DO_NL_S(_NL_IDENTIFICATION_APPLICATION); +		DO_NL_S(_NL_IDENTIFICATION_ABBREVIATION); +		DO_NL_S(_NL_IDENTIFICATION_REVISION); +		DO_NL_S(_NL_IDENTIFICATION_DATE); +		DO_NL_S(_NL_IDENTIFICATION_CATEGORY); + +#endif + +	return EXIT_SUCCESS; +} diff --git a/test/locale/xfrm-test.c b/test/locale/xfrm-test.c new file mode 100644 index 000000000..199bb6b5a --- /dev/null +++ b/test/locale/xfrm-test.c @@ -0,0 +1,144 @@ +/* Test collation function via transformation using real data. +   Copyright (C) 1997, 1998, 2000, 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <ctype.h> +#include <error.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +struct lines +{ +  char *xfrm; +  char *line; +}; + +static int xstrcmp (const void *, const void *); + +int +main (int argc, char *argv[]) +{ +  int result = 0; +  size_t nstrings, nstrings_max; +  struct lines *strings; +  char *line = NULL; +  size_t len = 0; +  size_t n; + +  if (argc < 2) +    error (1, 0, "usage: %s <random seed>", argv[0]); + +  setlocale (LC_ALL, ""); + +  nstrings_max = 100; +  nstrings = 0; +  strings = (struct lines *) malloc (nstrings_max * sizeof (struct lines)); +  if (strings == NULL) +    { +      perror (argv[0]); +      exit (1); +    } + +  while (1) +    { +      char saved, *newp; +      int needed; +      int l; +      if (getline (&line, &len, stdin) < 0) +	break; + +      if (nstrings == nstrings_max) +	{ +	  strings = (struct lines *) realloc (strings, +					      (nstrings_max *= 2) +					       * sizeof (*strings)); +	  if (strings == NULL) +	    { +	      perror (argv[0]); +	      exit (1); +	    } +	} +      strings[nstrings].line = strdup (line); +      l = strcspn (line, ":(;"); +      while (l > 0 && isspace (line[l - 1])) +	--l; + +      saved = line[l]; +      line[l] = '\0'; +      needed = strxfrm (NULL, line, 0); +      newp = malloc (needed + 1); +      strxfrm (newp, line, needed + 1); +      strings[nstrings].xfrm = newp; +      line[l] = saved; +      ++nstrings; +    } +  free (line); + +  /* First shuffle.  */ +  srandom (atoi (argv[1])); +  for (n = 0; n < 10 * nstrings; ++n) +    { +      int r1, r2, r; +      size_t idx1 = random () % nstrings; +      size_t idx2 = random () % nstrings; +      struct lines tmp = strings[idx1]; +      strings[idx1] = strings[idx2]; +      strings[idx2] = tmp; + +      /* While we are at it a first little test.  */ +      r1 = strcmp (strings[idx1].xfrm, strings[idx2].xfrm); +      r2 = strcmp (strings[idx2].xfrm, strings[idx1].xfrm); +      r = -(r1 ^ r2); +      if (r) +	r /= abs (r1 ^ r2); + +      if (r < 0 || (r == 0 && (r1 != 0 || r2 != 0)) +	  || (r > 0 && (r1 ^ r2) >= 0)) +	printf ("collate wrong: %d vs. %d\n", r1, r2); +    } + +  /* Now sort.  */ +  qsort (strings, nstrings, sizeof (struct lines), xstrcmp); + +  /* Print the result.  */ +  for (n = 0; n < nstrings; ++n) +    { +      fputs (strings[n].line, stdout); +      free (strings[n].line); +      free (strings[n].xfrm); +    } +  free (strings); + +  return result; +} + + +static int +xstrcmp (ptr1, ptr2) +     const void *ptr1; +     const void *ptr2; +{ +  const struct lines *l1 = (const struct lines *) ptr1; +  const struct lines *l2 = (const struct lines *) ptr2; + +  return strcmp (l1->xfrm, l2->xfrm); +}  | 
