Print this page
2964 need POSIX 2008 locale object support
Reviewed by: Robert Mustacchi <rm@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libc/port/locale/wcsnrtombs.c
          +++ new/usr/src/lib/libc/port/locale/wcsnrtombs.c
   1    1  /*
        2 + * Copyright 2013 Garrett D'Amore <garrett@damore.org>
   2    3   * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
   3    4   * Copyright (c) 2002-2004 Tim J. Robbins.
   4    5   * All rights reserved.
   5    6   *
   6    7   * Redistribution and use in source and binary forms, with or without
   7    8   * modification, are permitted provided that the following conditions
   8    9   * are met:
   9   10   * 1. Redistributions of source code must retain the above copyright
  10   11   *    notice, this list of conditions and the following disclaimer.
  11   12   * 2. Redistributions in binary form must reproduce the above copyright
↓ open down ↓ 10 lines elided ↑ open up ↑
  22   23   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  23   24   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  24   25   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  25   26   * SUCH DAMAGE.
  26   27   */
  27   28  
  28   29  #include "lint.h"
  29   30  #include <limits.h>
  30   31  #include <stdlib.h>
  31   32  #include <string.h>
       33 +#include <locale.h>
  32   34  #include <wchar.h>
  33   35  #include "mblocal.h"
       36 +#include "localeimpl.h"
       37 +#include "lctype.h"
  34   38  
  35   39  size_t
  36      -wcsnrtombs(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
  37      -    size_t nwc, size_t len, mbstate_t *_RESTRICT_KYWD ps)
       40 +wcsnrtombs_l(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
       41 +    size_t nwc, size_t len, mbstate_t *_RESTRICT_KYWD ps, locale_t loc)
  38   42  {
  39   43          static mbstate_t mbs;
  40   44  
  41   45          if (ps == NULL)
  42   46                  ps = &mbs;
  43      -        return (__wcsnrtombs(dst, src, nwc, len, ps));
       47 +        return (loc->ctype->lc_wcsnrtombs(dst, src, nwc, len, ps));
  44   48  }
  45   49  
  46   50  size_t
  47      -__wcsnrtombs_std(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
       51 +wcsnrtombs(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
  48   52      size_t nwc, size_t len, mbstate_t *_RESTRICT_KYWD ps)
  49   53  {
       54 +        return (wcsnrtombs_l(dst, src, nwc, len, ps, uselocale(NULL)));
       55 +}
       56 +
       57 +size_t
       58 +__wcsnrtombs_std(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
       59 +    size_t nwc, size_t len, mbstate_t *_RESTRICT_KYWD ps,
       60 +    wcrtomb_pfn_t pwcrtomb)
       61 +{
  50   62          mbstate_t mbsbak;
  51   63          char buf[MB_LEN_MAX];
  52   64          const wchar_t *s;
  53   65          size_t nbytes;
  54   66          size_t nb;
  55   67  
  56   68          s = *src;
  57   69          nbytes = 0;
  58   70  
  59   71          if (dst == NULL) {
  60   72                  while (nwc-- > 0) {
  61      -                        if ((nb = __wcrtomb(buf, *s, ps)) == (size_t)-1)
       73 +                        if ((nb = pwcrtomb(buf, *s, ps)) == (size_t)-1)
  62   74                                  /* Invalid character - wcrtomb() sets errno. */
  63   75                                  return ((size_t)-1);
  64   76                          else if (*s == L'\0')
  65   77                                  return (nbytes + nb - 1);
  66   78                          s++;
  67   79                          nbytes += nb;
  68   80                  }
  69   81                  return (nbytes);
  70   82          }
  71   83  
  72   84          while (len > 0 && nwc-- > 0) {
  73   85                  if (len > (size_t)MB_CUR_MAX) {
  74   86                          /* Enough space to translate in-place. */
  75      -                        if ((nb = __wcrtomb(dst, *s, ps)) == (size_t)-1) {
       87 +                        if ((nb = pwcrtomb(dst, *s, ps)) == (size_t)-1) {
  76   88                                  *src = s;
  77   89                                  return ((size_t)-1);
  78   90                          }
  79   91                  } else {
  80   92                          /*
  81   93                           * May not be enough space; use temp. buffer.
  82   94                           *
  83   95                           * We need to save a copy of the conversion state
  84   96                           * here so we can restore it if the multibyte
  85   97                           * character is too long for the buffer.
  86   98                           */
  87   99                          mbsbak = *ps;
  88      -                        if ((nb = __wcrtomb(buf, *s, ps)) == (size_t)-1) {
      100 +                        if ((nb = pwcrtomb(buf, *s, ps)) == (size_t)-1) {
  89  101                                  *src = s;
  90  102                                  return ((size_t)-1);
  91  103                          }
  92  104                          if (nb > (int)len) {
  93  105                                  /* MB sequence for character won't fit. */
  94  106                                  *ps = mbsbak;
  95  107                                  break;
  96  108                          }
  97  109                          (void) memcpy(dst, buf, nb);
  98  110                  }
↓ open down ↓ 12 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX