(root)/
coreutils-9.4/
gnulib-tests/
test-c32islower.c
       1  /* Test of c32islower() function.
       2     Copyright (C) 2020-2023 Free Software Foundation, Inc.
       3  
       4     This program is free software: you can redistribute it and/or modify
       5     it under the terms of the GNU General Public License as published by
       6     the Free Software Foundation, either version 3 of the License, or
       7     (at your option) any later version.
       8  
       9     This program is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12     GNU General Public License for more details.
      13  
      14     You should have received a copy of the GNU General Public License
      15     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  #include <config.h>
      18  
      19  #include <uchar.h>
      20  
      21  #include "signature.h"
      22  SIGNATURE_CHECK (c32islower, int, (wint_t));
      23  
      24  #include <locale.h>
      25  #include <stdlib.h>
      26  #include <string.h>
      27  #include <wchar.h>
      28  
      29  #include "macros.h"
      30  
      31  /* Returns the value of c32islower for the multibyte character s[0..n-1].  */
      32  static int
      33  for_character (const char *s, size_t n)
      34  {
      35    mbstate_t state;
      36    char32_t wc;
      37    size_t ret;
      38  
      39    memset (&state, '\0', sizeof (mbstate_t));
      40    wc = (char32_t) 0xBADFACE;
      41    ret = mbrtoc32 (&wc, s, n, &state);
      42    ASSERT (ret == n);
      43  
      44    return c32islower (wc);
      45  }
      46  
      47  int
      48  main (int argc, char *argv[])
      49  {
      50    int is;
      51    char buf[4];
      52  
      53    /* configure should already have checked that the locale is supported.  */
      54    if (setlocale (LC_ALL, "") == NULL)
      55      return 1;
      56  
      57    /* Test WEOF.  */
      58    is = c32islower (WEOF);
      59    ASSERT (is == 0);
      60  
      61    /* Test single-byte characters.
      62       POSIX specifies in
      63         <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html>
      64       that
      65         - in all locales, the lowercase characters include the a ... z
      66           characters,
      67         - in the "POSIX" locale (which is usually the same as the "C" locale),
      68           the lowercase characters include only the ASCII a ... z characters.
      69     */
      70    {
      71      int c;
      72  
      73      for (c = 0; c < 0x100; c++)
      74        switch (c)
      75          {
      76          case '\t': case '\v': case '\f':
      77          case ' ': case '!': case '"': case '#': case '%':
      78          case '&': case '\'': case '(': case ')': case '*':
      79          case '+': case ',': case '-': case '.': case '/':
      80          case '0': case '1': case '2': case '3': case '4':
      81          case '5': case '6': case '7': case '8': case '9':
      82          case ':': case ';': case '<': case '=': case '>':
      83          case '?':
      84          case 'A': case 'B': case 'C': case 'D': case 'E':
      85          case 'F': case 'G': case 'H': case 'I': case 'J':
      86          case 'K': case 'L': case 'M': case 'N': case 'O':
      87          case 'P': case 'Q': case 'R': case 'S': case 'T':
      88          case 'U': case 'V': case 'W': case 'X': case 'Y':
      89          case 'Z':
      90          case '[': case '\\': case ']': case '^': case '_':
      91          case 'a': case 'b': case 'c': case 'd': case 'e':
      92          case 'f': case 'g': case 'h': case 'i': case 'j':
      93          case 'k': case 'l': case 'm': case 'n': case 'o':
      94          case 'p': case 'q': case 'r': case 's': case 't':
      95          case 'u': case 'v': case 'w': case 'x': case 'y':
      96          case 'z': case '{': case '|': case '}': case '~':
      97            /* c is in the ISO C "basic character set".  */
      98            buf[0] = (unsigned char) c;
      99            is = for_character (buf, 1);
     100            switch (c)
     101              {
     102              case 'a': case 'b': case 'c': case 'd': case 'e':
     103              case 'f': case 'g': case 'h': case 'i': case 'j':
     104              case 'k': case 'l': case 'm': case 'n': case 'o':
     105              case 'p': case 'q': case 'r': case 's': case 't':
     106              case 'u': case 'v': case 'w': case 'x': case 'y':
     107              case 'z':
     108                ASSERT (is != 0);
     109                break;
     110              default:
     111                ASSERT (is == 0);
     112                break;
     113              }
     114            break;
     115          }
     116    }
     117  
     118    if (argc > 1)
     119      switch (argv[1][0])
     120        {
     121        case '0':
     122          /* C locale; tested above.  */
     123          return 0;
     124  
     125        case '1':
     126          /* Locale encoding is ISO-8859-1 or ISO-8859-15.  */
     127          {
     128            /* U+00B2 SUPERSCRIPT TWO */
     129            is = for_character ("\262", 1);
     130            ASSERT (is == 0);
     131          #if !(defined __GLIBC__ || (defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __NetBSD__ || defined __sun || defined __CYGWIN__ || (defined _WIN32 && !defined __CYGWIN__))
     132            /* U+00B5 MICRO SIGN */
     133            is = for_character ("\265", 1);
     134            ASSERT (is == 0);
     135          #endif
     136            /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */
     137            is = for_character ("\311", 1);
     138            ASSERT (is == 0);
     139          #if !defined __CYGWIN__
     140            /* U+00DF LATIN SMALL LETTER SHARP S */
     141            is = for_character ("\337", 1);
     142            ASSERT (is != 0);
     143          #endif
     144            /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */
     145            is = for_character ("\351", 1);
     146            ASSERT (is != 0);
     147            /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */
     148            is = for_character ("\377", 1);
     149            ASSERT (is != 0);
     150          }
     151          return 0;
     152  
     153        case '2':
     154          /* Locale encoding is EUC-JP.  */
     155          {
     156            /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */
     157            is = for_character ("\217\252\261", 3);
     158            ASSERT (is == 0);
     159          #if !((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__ || defined __CYGWIN__)
     160            /* U+00DF LATIN SMALL LETTER SHARP S */
     161            is = for_character ("\217\251\316", 3);
     162            ASSERT (is != 0);
     163          #endif
     164          #if !((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__)
     165            /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */
     166            is = for_character ("\217\253\261", 3);
     167            ASSERT (is != 0);
     168            /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */
     169            is = for_character ("\217\253\363", 3);
     170            ASSERT (is != 0);
     171          #endif
     172            /* U+0141 LATIN CAPITAL LETTER L WITH STROKE */
     173            is = for_character ("\217\251\250", 3);
     174            ASSERT (is == 0);
     175          #if !((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__)
     176            /* U+0142 LATIN SMALL LETTER L WITH STROKE */
     177            is = for_character ("\217\251\310", 3);
     178            ASSERT (is != 0);
     179          #endif
     180            /* U+0429 CYRILLIC CAPITAL LETTER SHCHA */
     181            is = for_character ("\247\273", 2);
     182            ASSERT (is == 0);
     183          #if !(defined __FreeBSD__ || defined __DragonFly__)
     184            /* U+0449 CYRILLIC SMALL LETTER SHCHA */
     185            is = for_character ("\247\353", 2);
     186            ASSERT (is != 0);
     187          #endif
     188            /* U+3073 HIRAGANA LETTER BI */
     189            is = for_character ("\244\323", 2);
     190            ASSERT (is == 0);
     191          #if !defined __DragonFly__
     192            /* U+FF47 FULLWIDTH LATIN SMALL LETTER G */
     193            is = for_character ("\243\347", 2);
     194            ASSERT (is != 0);
     195          #endif
     196          }
     197          return 0;
     198  
     199        case '3':
     200          /* Locale encoding is UTF-8.  */
     201          {
     202            /* U+00B2 SUPERSCRIPT TWO */
     203            is = for_character ("\302\262", 2);
     204            ASSERT (is == 0);
     205          #if !(defined __GLIBC__ || defined MUSL_LIBC || (defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__ || defined _AIX || defined __sun || defined __CYGWIN__ || (defined _WIN32 && !defined __CYGWIN__))
     206            /* U+00B5 MICRO SIGN */
     207            is = for_character ("\302\265", 2);
     208            ASSERT (is == 0);
     209          #endif
     210            /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */
     211            is = for_character ("\303\211", 2);
     212            ASSERT (is == 0);
     213          #if !defined __CYGWIN__
     214            /* U+00DF LATIN SMALL LETTER SHARP S */
     215            is = for_character ("\303\237", 2);
     216            ASSERT (is != 0);
     217          #endif
     218            /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */
     219            is = for_character ("\303\251", 2);
     220            ASSERT (is != 0);
     221            /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */
     222            is = for_character ("\303\277", 2);
     223            ASSERT (is != 0);
     224            /* U+0141 LATIN CAPITAL LETTER L WITH STROKE */
     225            is = for_character ("\305\201", 2);
     226            ASSERT (is == 0);
     227            /* U+0142 LATIN SMALL LETTER L WITH STROKE */
     228            is = for_character ("\305\202", 2);
     229            ASSERT (is != 0);
     230            /* U+0429 CYRILLIC CAPITAL LETTER SHCHA */
     231            is = for_character ("\320\251", 2);
     232            ASSERT (is == 0);
     233            /* U+0449 CYRILLIC SMALL LETTER SHCHA */
     234            is = for_character ("\321\211", 2);
     235            ASSERT (is != 0);
     236            /* U+05D5 HEBREW LETTER VAV */
     237            is = for_character ("\327\225", 2);
     238            ASSERT (is == 0);
     239            /* U+3073 HIRAGANA LETTER BI */
     240            is = for_character ("\343\201\263", 3);
     241            ASSERT (is == 0);
     242            /* U+3162 HANGUL LETTER YI */
     243            is = for_character ("\343\205\242", 3);
     244            ASSERT (is == 0);
     245            /* U+FF47 FULLWIDTH LATIN SMALL LETTER G */
     246            is = for_character ("\357\275\207", 3);
     247            ASSERT (is != 0);
     248            /* U+FFDB HALFWIDTH HANGUL LETTER YI */
     249            is = for_character ("\357\277\233", 3);
     250            ASSERT (is == 0);
     251            /* U+10419 DESERET CAPITAL LETTER EF */
     252            is = for_character ("\360\220\220\231", 4);
     253            ASSERT (is == 0);
     254          #if !(defined __FreeBSD__ || defined __DragonFly__ || defined __sun)
     255            /* U+10441 DESERET SMALL LETTER EF */
     256            is = for_character ("\360\220\221\201", 4);
     257            ASSERT (is != 0);
     258          #endif
     259            /* U+E0041 TAG LATIN CAPITAL LETTER A */
     260            is = for_character ("\363\240\201\201", 4);
     261            ASSERT (is == 0);
     262            /* U+E0061 TAG LATIN SMALL LETTER A */
     263            is = for_character ("\363\240\201\241", 4);
     264            ASSERT (is == 0);
     265          }
     266          return 0;
     267  
     268        case '4':
     269          /* Locale encoding is GB18030.  */
     270          #if (defined __GLIBC__ && __GLIBC__ == 2 && __GLIBC_MINOR__ >= 13 && __GLIBC_MINOR__ <= 15) || (GL_CHAR32_T_IS_UNICODE && (defined __NetBSD__ || defined __sun))
     271          fputs ("Skipping test: The GB18030 converter in this system's iconv is broken.\n", stderr);
     272          return 77;
     273          #endif
     274          {
     275            /* U+00B2 SUPERSCRIPT TWO */
     276            is = for_character ("\201\060\205\065", 4);
     277            ASSERT (is == 0);
     278          #if !(defined __GLIBC__ || (defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __NetBSD__)
     279            /* U+00B5 MICRO SIGN */
     280            is = for_character ("\201\060\205\070", 4);
     281            ASSERT (is == 0);
     282          #endif
     283            /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */
     284            is = for_character ("\201\060\207\067", 4);
     285            ASSERT (is == 0);
     286          #if !(defined __FreeBSD__ || defined __DragonFly__ || defined __sun)
     287            /* U+00DF LATIN SMALL LETTER SHARP S */
     288            is = for_character ("\201\060\211\070", 4);
     289            ASSERT (is != 0);
     290          #endif
     291          #if !defined __DragonFly__
     292            /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */
     293            is = for_character ("\250\246", 2);
     294            ASSERT (is != 0);
     295          #endif
     296          #if !(defined __FreeBSD__ || defined __DragonFly__ || defined __sun)
     297            /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */
     298            is = for_character ("\201\060\213\067", 4);
     299            ASSERT (is != 0);
     300          #endif
     301            /* U+0141 LATIN CAPITAL LETTER L WITH STROKE */
     302            is = for_character ("\201\060\221\071", 4);
     303            ASSERT (is == 0);
     304          #if !(defined __FreeBSD__ || defined __DragonFly__ || defined __sun)
     305            /* U+0142 LATIN SMALL LETTER L WITH STROKE */
     306            is = for_character ("\201\060\222\060", 4);
     307            ASSERT (is != 0);
     308          #endif
     309            /* U+0429 CYRILLIC CAPITAL LETTER SHCHA */
     310            is = for_character ("\247\273", 2);
     311            ASSERT (is == 0);
     312          #if !(defined __FreeBSD__ || defined __DragonFly__)
     313            /* U+0449 CYRILLIC SMALL LETTER SHCHA */
     314            is = for_character ("\247\353", 2);
     315            ASSERT (is != 0);
     316          #endif
     317            /* U+05D5 HEBREW LETTER VAV */
     318            is = for_character ("\201\060\371\067", 4);
     319            ASSERT (is == 0);
     320            /* U+3073 HIRAGANA LETTER BI */
     321            is = for_character ("\244\323", 2);
     322            ASSERT (is == 0);
     323            /* U+3162 HANGUL LETTER YI */
     324            is = for_character ("\201\071\256\062", 4);
     325            ASSERT (is == 0);
     326          #if !defined __DragonFly__
     327            /* U+FF47 FULLWIDTH LATIN SMALL LETTER G */
     328            is = for_character ("\243\347", 2);
     329            ASSERT (is != 0);
     330          #endif
     331            /* U+FFDB HALFWIDTH HANGUL LETTER YI */
     332            is = for_character ("\204\061\241\071", 4);
     333            ASSERT (is == 0);
     334            /* U+10419 DESERET CAPITAL LETTER EF */
     335            is = for_character ("\220\060\351\071", 4);
     336            ASSERT (is == 0);
     337          #if !((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__ || defined __sun)
     338            /* U+10441 DESERET SMALL LETTER EF */
     339            is = for_character ("\220\060\355\071", 4);
     340            ASSERT (is != 0);
     341          #endif
     342            /* U+E0041 TAG LATIN CAPITAL LETTER A */
     343            is = for_character ("\323\066\234\063", 4);
     344            ASSERT (is == 0);
     345            /* U+E0061 TAG LATIN SMALL LETTER A */
     346            is = for_character ("\323\066\237\065", 4);
     347            ASSERT (is == 0);
     348          }
     349          return 0;
     350  
     351        }
     352  
     353    return 1;
     354  }