Print this page
2964 need POSIX 2008 locale object support
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Approved by: TBD

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libc/port/locale/fgetwc.c
          +++ new/usr/src/lib/libc/port/locale/fgetwc.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 ↓ 16 lines elided ↑ open up ↑
  28   29  #include "lint.h"
  29   30  #include "mse_int.h"
  30   31  #include "file64.h"
  31   32  #include "mtlib.h"
  32   33  #include <errno.h>
  33   34  #include <stdio.h>
  34   35  #include <stdlib.h>
  35   36  #include <wchar.h>
  36   37  #include "mblocal.h"
  37   38  #include "stdiom.h"
       39 +#include "localeimpl.h"
       40 +#include "lctype.h"
  38   41  
  39   42  /*
  40   43   * Non-MT-safe version.
  41   44   */
  42   45  wint_t
  43      -_fgetwc_unlocked(FILE *fp)
       46 +_fgetwc_unlocked_l(FILE *fp, locale_t loc)
  44   47  {
  45   48          wchar_t wc;
  46   49          size_t nconv;
  47   50          int     c;
  48   51          mbstate_t       *statep;
       52 +        const struct lc_ctype *lct;
  49   53  
  50   54          if ((c = GETC(fp)) == EOF)
  51   55                  return (WEOF);
  52   56  
  53      -        if (MB_CUR_MAX == 1) {
       57 +        lct = loc->ctype;
       58 +        if (lct->lc_max_mblen == 1) {
  54   59                  /* Fast path for single-byte encodings. */
  55   60                  return ((wint_t)c);
  56   61          }
  57   62          if ((statep = _getmbstate(fp)) == NULL) {
  58   63                  fp->_flag = _IOERR;
  59   64                  errno = EBADF;
  60   65                  return (WEOF);
  61   66          }
  62   67          do {
  63   68                  char    x = (char)c;
  64      -                nconv = __mbrtowc(&wc, &x, 1, statep);
       69 +                nconv = lct->lc_mbrtowc(&wc, &x, 1, statep);
  65   70                  if (nconv == (size_t)-1) {
  66   71                          break;
  67   72                  } else if (nconv == (size_t)-2) {
  68   73                          /* Incompletely decoded, consume another char */
  69   74                          continue;
  70   75                  } else if (nconv == 0) {
  71   76                          /*
  72   77                           * Assume that the only valid representation of
  73   78                           * the null wide character is a single null byte.
  74   79                           */
↓ open down ↓ 7 lines elided ↑ open up ↑
  82   87           * If we got here it means we got truncated in a character, or
  83   88           * the character did not decode properly.  Note that in the case
  84   89           * of a botched decoding, we don't UNGETC the bad bytes.  Should
  85   90           * we?
  86   91           */
  87   92          fp->_flag |= _IOERR;
  88   93          errno = EILSEQ;
  89   94          return (WEOF);
  90   95  }
  91   96  
       97 +wint_t
       98 +_fgetwc_unlocked(FILE *fp)
       99 +{
      100 +        return (_fgetwc_unlocked_l(fp, uselocale(NULL)));
      101 +}
  92  102  
      103 +
  93  104  /*
  94  105   * MT safe version
  95  106   */
      107 +#undef getwc
      108 +#pragma weak getwc = fgetwc
  96  109  wint_t
  97  110  fgetwc(FILE *fp)
  98  111  {
  99  112          wint_t          r;
 100  113          rmutex_t        *l;
      114 +        locale_t        loc = uselocale(NULL);
 101  115  
 102  116          FLOCKFILE(l, fp);
 103      -        r = _fgetwc_unlocked(fp);
      117 +        r = _fgetwc_unlocked_l(fp, loc);
 104  118          FUNLOCKFILE(l);
 105  119  
 106  120          return (r);
 107  121  }
 108  122  
 109      -#undef  getwc
 110      -wint_t
 111      -getwc(FILE *fp)
 112      -{
 113      -        return (getwc(fp));
 114      -}
 115      -
 116  123  /*
 117  124   * XPG5 version.
 118  125   */
      126 +#undef  __getwc_xpg5
      127 +#pragma weak __getwc_xpg5 = __fgetwc_xpg5
 119  128  wint_t
 120  129  __fgetwc_xpg5(FILE *fp)
 121  130  {
 122  131          wint_t          r;
 123  132          rmutex_t        *l;
      133 +        locale_t        loc = uselocale(NULL);
 124  134  
 125  135          FLOCKFILE(l, fp);
 126  136          if (GET_NO_MODE(fp))
 127  137                  _setorientation(fp, _WC_MODE);
 128      -        r = _fgetwc_unlocked(fp);
      138 +        r = _fgetwc_unlocked_l(fp, loc);
 129  139          FUNLOCKFILE(l);
 130  140  
 131  141          return (r);
 132  142  }
 133  143  
 134      -#undef  __getwc_xpg5
      144 +#pragma weak getwc_l = fgetwc_l
 135  145  wint_t
 136      -__getwc_xpg5(FILE *fp)
      146 +fgetwc_l(FILE *fp, locale_t loc)
 137  147  {
 138      -        return (__fgetwc_xpg5(fp));
      148 +        wint_t          r;
      149 +        rmutex_t        *l;
      150 +        FLOCKFILE(l, fp);
      151 +        if (GET_NO_MODE(fp))
      152 +                _setorientation(fp, _WC_MODE);
      153 +        r = _fgetwc_unlocked_l(fp, loc);
      154 +        FUNLOCKFILE(l);
      155 +
      156 +        return (r);
 139  157  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX