(root)/
coreutils-9.4/
gnulib-tests/
test-mbsalign.c
       1  /* Test that mbsalign works as advertised.
       2     Copyright (C) 2010-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  /* Written by Pádraig Brady.  */
      18  
      19  #include <config.h>
      20  
      21  #include "mbsalign.h"
      22  #include "macros.h"
      23  #include <stdlib.h>
      24  #include <locale.h>
      25  
      26  int
      27  main (void)
      28  {
      29    char dest[4 * 16 + 1];
      30    size_t width, n;
      31  
      32  #ifdef __ANDROID__
      33    /* On Android ≥ 5.0, the default locale is the "C.UTF-8" locale, not the
      34       "C" locale.  Furthermore, when you attempt to set the "C" or "POSIX"
      35       locale via setlocale(), what you get is a "C" locale with UTF-8 encoding,
      36       that is, effectively the "C.UTF-8" locale.  */
      37    if (MB_CUR_MAX == 1)
      38  #endif
      39      {
      40        /* Test unibyte truncation.  */
      41        width = 4;
      42        n = mbsalign ("t\tés", dest, sizeof dest, &width, MBS_ALIGN_LEFT, 0);
      43        ASSERT (n == 4);
      44      }
      45  
      46    /* Test center alignment.  */
      47    width = 4;
      48    n = mbsalign ("es", dest, sizeof dest, &width, MBS_ALIGN_CENTER, 0);
      49    ASSERT (*dest == ' ' && *(dest + n - 1) == ' ');
      50    ASSERT (n == 4);
      51  
      52    /* Test center alignment, with no trailing padding.  */
      53    width = 4;
      54    n = mbsalign ("es", dest, sizeof dest, &width, MBS_ALIGN_CENTER,
      55                  MBA_NO_RIGHT_PAD);
      56    ASSERT (n == 3);
      57    ASSERT (*dest == ' ' && *(dest + n - 1) == 's');
      58  
      59    /* Test left alignment, with no trailing padding. (truncate only).  */
      60    width = 4;
      61    n = mbsalign ("es", dest, sizeof dest, &width, MBS_ALIGN_LEFT,
      62                  MBA_NO_RIGHT_PAD);
      63    ASSERT (n == 2);
      64    ASSERT (*dest == 'e' && *(dest + n - 1) == 's');
      65  
      66    /* Test center alignment, with no padding. (truncate only).  */
      67    width = 4;
      68    n = mbsalign ("es", dest, sizeof dest, &width, MBS_ALIGN_CENTER,
      69                  MBA_NO_LEFT_PAD | MBA_NO_RIGHT_PAD);
      70    ASSERT (n == 2);
      71    ASSERT (*dest == 'e' && *(dest + n - 1) == 's');
      72  
      73    /* Test center alignment, with no left padding. (may be useful for RTL?)  */
      74    width = 4;
      75    n = mbsalign ("es", dest, sizeof dest, &width, MBS_ALIGN_CENTER,
      76                  MBA_NO_LEFT_PAD);
      77    ASSERT (n == 3);
      78    ASSERT (*dest == 'e' && *(dest + n - 1) == ' ');
      79  
      80    if (setlocale (LC_ALL, "en_US.UTF8"))
      81      {
      82        /* Check invalid input is flagged.  */
      83        width = 4;
      84        n = mbsalign ("t\xe1\xe2s", dest, sizeof dest, &width, MBS_ALIGN_LEFT, 0);
      85        ASSERT (n == (size_t) -1);
      86  
      87        /* Check invalid input is treated as unibyte  */
      88        width = 4;
      89        n = mbsalign ("t\xe1\xe2s", dest, sizeof dest, &width,
      90                      MBS_ALIGN_LEFT, MBA_UNIBYTE_FALLBACK);
      91        ASSERT (n == 4);
      92  
      93        /* Test multibyte center alignment.  */
      94        width = 4;
      95        n = mbsalign ("és", dest, sizeof dest, &width, MBS_ALIGN_CENTER, 0);
      96        ASSERT (n == 5);
      97        ASSERT (*dest == ' ' && *(dest + n - 1) == ' ');
      98  
      99        /* Test multibyte left alignment.  */
     100        width = 4;
     101        n = mbsalign ("és", dest, sizeof dest, &width, MBS_ALIGN_LEFT, 0);
     102        ASSERT (n == 5);
     103        ASSERT (*(dest + n - 1) == ' ' && *(dest + n - 2) == ' ');
     104  
     105        /* Test multibyte right alignment.  */
     106        width = 4;
     107        n = mbsalign ("és", dest, sizeof dest, &width, MBS_ALIGN_RIGHT, 0);
     108        ASSERT (n == 5);
     109        ASSERT (*(dest) == ' ' && *(dest + 1) == ' ');
     110  
     111        /* multibyte multicell truncation.  */
     112        width = 4;                /* cells */
     113        n = mbsalign ("日月火水", dest, sizeof dest, &width,
     114                      MBS_ALIGN_LEFT, 0);
     115        ASSERT (n == 6);          /* 2 characters */
     116  
     117        /* multibyte unicell truncation.  */
     118        width = 3;                /* cells */
     119        n = mbsalign ("¹²³⁴", dest, sizeof dest, &width, MBS_ALIGN_LEFT, 0);
     120        ASSERT (n == 6);          /* 3 characters */
     121  
     122        /* Check independence from dest buffer. */
     123        width = 4;                /* cells */
     124        n = mbsalign ("¹²³⁴", dest, 0, &width, MBS_ALIGN_LEFT, 0);
     125        ASSERT (n == 9);          /* 4 characters */
     126  
     127        /* Check that width is updated with cells required before padding.  */
     128        width = 4;                /* cells */
     129        n = mbsalign ("¹²³", dest, 0, &width, MBS_ALIGN_LEFT, 0);
     130        ASSERT (width == 3);
     131  
     132        /* Test case where output is larger than input
     133           (as tab converted to multi byte replacement char).  */
     134        width = 4;
     135        n = mbsalign ("t\tés" /* 6 including NUL */ , dest, sizeof dest,
     136                      &width, MBS_ALIGN_LEFT, 0);
     137        ASSERT (n == 7);
     138  
     139        /* Test forced unibyte truncation.  */
     140        width = 4;
     141        n = mbsalign ("t\tés", dest, sizeof dest, &width, MBS_ALIGN_LEFT,
     142                      MBA_UNIBYTE_ONLY);
     143        ASSERT (n == 4);
     144      }
     145  
     146    return 0;
     147  }