coreutils
[Top][All Lists]
Advanced

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

Re: [PATCH] maint: add more control flags to mbsalign


From: Jim Meyering
Subject: Re: [PATCH] maint: add more control flags to mbsalign
Date: Mon, 10 Sep 2012 21:11:56 +0200

Pádraig Brady wrote:
> In support of the upcoming `df --output` and
> $cmd --help auto alignment changes, the attached
> patch gives more formatting control to callers of mbsalign().

Thanks.  I've tested that, and it passed.

> Subject: [PATCH] maint: add more control flags to mbsalign
>
> * gl/lib/mbsalign.h: Add MBA_UNIBYTE_ONLY (to allow
> faster processing), and MBA_NO_{LEFT,RIGHT}_PAD

It's slightly better to spell out those symbol names,
to ease log searching.

> to give greater control of padding, useful with the first
> or last fields on a line.
> * gl/lib/mbsalign.c (mbsalign): Implement the new flags.
> * gl/tests/test-mbsalign.c (main): Test combinations
> of the new flags.
> ---
>  gl/lib/mbsalign.c        |   63 ++++++++++++++++++++++++++-------------------
>  gl/lib/mbsalign.h        |   27 ++++++++++++++-----
>  gl/tests/test-mbsalign.c |   32 +++++++++++++++++++++++
>  3 files changed, 88 insertions(+), 34 deletions(-)
>
> diff --git a/gl/lib/mbsalign.c b/gl/lib/mbsalign.c
> index e45456b..3c3170a 100644
> --- a/gl/lib/mbsalign.c
> +++ b/gl/lib/mbsalign.c
> @@ -126,7 +126,7 @@ mbsalign (const char *src, char *dest, size_t dest_size,
>    /* In multi-byte locales convert to wide characters
>       to allow easy truncation. Also determine number
>       of screen columns used.  */
> -  if (MB_CUR_MAX > 1)
> +  if (!(flags & MBA_UNIBYTE_ONLY) && MB_CUR_MAX > 1)
>      {
>        size_t src_chars = mbstowcs (NULL, src, 0);
>        if (src_chars == SIZE_MAX)
> @@ -191,37 +191,46 @@ mbsalign_unibyte:
>    /* indicate to caller how many cells needed (not including padding).  */
>    *width = n_cols;
>
> -  /* indicate to caller how many bytes needed (not including NUL).  */
> -  ret = n_used_bytes + (n_spaces * 1);
> +  {
> +    size_t start_spaces, end_spaces;
>
> -  /* Write as much NUL terminated output to DEST as possible.  */
> -  if (dest_size != 0)
> -    {
> -      size_t start_spaces, end_spaces, space_left;
> -      char *dest_end = dest + dest_size - 1;
> +    switch (align)
> +      {
> +      case MBS_ALIGN_LEFT:
> +        start_spaces = 0;
> +        end_spaces = n_spaces;
> +        break;
> +      case MBS_ALIGN_RIGHT:
> +        start_spaces = n_spaces;
> +        end_spaces = 0;
> +        break;
> +      case MBS_ALIGN_CENTER:
> +      default:
> +        start_spaces = n_spaces / 2 + n_spaces % 2;
> +        end_spaces = n_spaces / 2;
> +        break;
> +      }
> +
> +      if (flags & MBA_NO_LEFT_PAD)
> +        start_spaces = 0;
> +      if (flags & MBA_NO_RIGHT_PAD)
> +        end_spaces = 0;
>
> -      switch (align)
> +      /* Write as much NUL terminated output to DEST as possible.  */
> +      if (dest_size != 0)
>          {
> -        case MBS_ALIGN_LEFT:
> -          start_spaces = 0;
> -          end_spaces = n_spaces;
> -          break;
> -        case MBS_ALIGN_RIGHT:
> -          start_spaces = n_spaces;
> -          end_spaces = 0;
> -          break;
> -        case MBS_ALIGN_CENTER:
> -        default:
> -          start_spaces = n_spaces / 2 + n_spaces % 2;
> -          end_spaces = n_spaces / 2;
> -          break;
> +          size_t space_left;
> +          char *dest_end = dest + dest_size - 1;
> +
> +          dest = mbs_align_pad (dest, dest_end, start_spaces);
> +          space_left = dest_end - dest;
> +          dest = mempcpy (dest, str_to_print, MIN (n_used_bytes, 
> space_left));
> +          mbs_align_pad (dest, dest_end, end_spaces);
>          }
>
> -      dest = mbs_align_pad (dest, dest_end, start_spaces);
> -      space_left = dest_end - dest;
> -      dest = mempcpy (dest, str_to_print, MIN (n_used_bytes, space_left));
> -      mbs_align_pad (dest, dest_end, end_spaces);
> -    }
> +    /* indicate to caller how many bytes needed (not including NUL).  */
> +    ret = n_used_bytes + ((start_spaces + end_spaces) * 1);
> +  }
>
>  mbsalign_cleanup:
>
> diff --git a/gl/lib/mbsalign.h b/gl/lib/mbsalign.h
> index e9340f9..d0eeb14 100644
> --- a/gl/lib/mbsalign.h
> +++ b/gl/lib/mbsalign.h
> @@ -21,20 +21,33 @@ typedef enum { MBS_ALIGN_LEFT, MBS_ALIGN_RIGHT, 
> MBS_ALIGN_CENTER } mbs_align_t;
>  enum {
>    /* Use unibyte mode for invalid multibyte strings
>       or when heap memory is exhausted.  */
> -  MBA_UNIBYTE_FALLBACK = 0x0001
> +  MBA_UNIBYTE_FALLBACK = 0x0001,
> +
> +  /* As an optimization, don't do multibyte processing
> +     when we know no multibyte characters are present.  */
> +  MBA_UNIBYTE_ONLY = 0x0002,
> +
> +  /* Don't add leading padding  */

Trailing period, for consistency with above?

> +  MBA_NO_LEFT_PAD = 0x0004,
> +
> +  /* Don't add trailing padding  */
> +  MBA_NO_RIGHT_PAD = 0x0008

Likewise?

>  #if 0 /* Other possible options.  */
>    /* Skip invalid multibyte chars rather than failing  */
> -  MBA_IGNORE_INVALID   = 0x0002,
> +  MBA_IGNORE_INVALID
>
>    /* Align multibyte strings using "figure space" (\u2007)  */
> -  MBA_USE_FIGURE_SPACE = 0x0004,
> -
> -  /* Don't add any padding  */
> -  MBA_TRUNCATE_ONLY    = 0x0008,
> +  MBA_USE_FIGURE_SPACE
>
>    /* Don't truncate  */
> -  MBA_PAD_ONLY         = 0x0010,
> +  MBA_NO_TRUNCATE
> +
> +  /* Ensure no leading whitepsace  */
> +  MBA_LSTRIP
> +
> +  /* Ensure no trailing whitepsace  */
> +  MBA_RSTRIP

More periods?

>  #endif
>  };
>
> diff --git a/gl/tests/test-mbsalign.c b/gl/tests/test-mbsalign.c
> index 86aa877..a65b1d9 100644
> --- a/gl/tests/test-mbsalign.c
> +++ b/gl/tests/test-mbsalign.c
> @@ -39,6 +39,32 @@ main (void)
>    n = mbsalign ("es", dest, sizeof dest, &width, MBS_ALIGN_CENTER, 0);
>    ASSERT (*dest == ' ' && *(dest + n - 1) == ' ');
>
> +  /* Test center alignment, with no trailing padding.  */
> +  width = 4;
> +  n = mbsalign ("es", dest, sizeof dest, &width, MBS_ALIGN_CENTER,
> +                MBA_NO_RIGHT_PAD);
> +  ASSERT (n == 3);
> +  ASSERT (*dest == ' ' && *(dest + n - 1) == 's');
> +
> +  /* Test left alignment, with no trailing padding. (truncate only).  */
> +  width = 4;
> +  n = mbsalign ("es", dest, sizeof dest, &width, MBS_ALIGN_LEFT,
> +                MBA_NO_RIGHT_PAD);

Is it worth inserting this?

    ASSERT (n == 2);

> +  ASSERT (*dest == 'e' && *(dest + n - 1) == 's');
> +
> +  /* Test center alignment, with no padding. (truncate only).  */
> +  width = 4;
> +  n = mbsalign ("es", dest, sizeof dest, &width, MBS_ALIGN_CENTER,
> +                MBA_NO_LEFT_PAD | MBA_NO_RIGHT_PAD);

Same question here.

> +  ASSERT (*dest == 'e' && *(dest + n - 1) == 's');
> +
> +  /* Test center alignment, with no left padding. (may be useful for RTL?)  
> */
> +  width = 4;
> +  n = mbsalign ("es", dest, sizeof dest, &width, MBS_ALIGN_CENTER,
> +                MBA_NO_LEFT_PAD);
> +  ASSERT (n == 3);
> +  ASSERT (*dest == 'e' && *(dest + n - 1) == ' ');
> +
>    if (setlocale (LC_ALL, "en_US.UTF8"))
>      {
>        /* Check invalid input is flagged.  */
> @@ -94,6 +120,12 @@ main (void)
>        n = mbsalign ("t\tés" /* 6 including NUL */ , dest, sizeof dest,
>                      &width, MBS_ALIGN_LEFT, 0);
>        ASSERT (n == 7);
> +
> +      /* Test forced unibyte truncation.  */
> +      width = 4;
> +      n = mbsalign ("t\tés", dest, sizeof dest, &width, MBS_ALIGN_LEFT,
> +                    MBA_UNIBYTE_ONLY);
> +      ASSERT (n == 4);
>      }
>
>    return 0;



reply via email to

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