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
        
*** 1,6 ****
--- 1,7 ----
  /*
+  * Copyright 2013 Garrett D'Amore <garrett@damore.org>
   * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
   * Copyright (c) 2002-2004 Tim J. Robbins.
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
*** 33,58 ****
  #include <stdio.h>
  #include <stdlib.h>
  #include <wchar.h>
  #include "mblocal.h"
  #include "stdiom.h"
  
  /*
   * Non-MT-safe version.
   */
  wint_t
! _fgetwc_unlocked(FILE *fp)
  {
          wchar_t wc;
          size_t nconv;
          int     c;
          mbstate_t       *statep;
  
          if ((c = GETC(fp)) == EOF)
                  return (WEOF);
  
!         if (MB_CUR_MAX == 1) {
                  /* Fast path for single-byte encodings. */
                  return ((wint_t)c);
          }
          if ((statep = _getmbstate(fp)) == NULL) {
                  fp->_flag = _IOERR;
--- 34,63 ----
  #include <stdio.h>
  #include <stdlib.h>
  #include <wchar.h>
  #include "mblocal.h"
  #include "stdiom.h"
+ #include "localeimpl.h"
+ #include "lctype.h"
  
  /*
   * Non-MT-safe version.
   */
  wint_t
! _fgetwc_unlocked_l(FILE *fp, locale_t loc)
  {
          wchar_t wc;
          size_t nconv;
          int     c;
          mbstate_t       *statep;
+         const struct lc_ctype *lct;
  
          if ((c = GETC(fp)) == EOF)
                  return (WEOF);
  
!         lct = loc->ctype;
!         if (lct->lc_max_mblen == 1) {
                  /* Fast path for single-byte encodings. */
                  return ((wint_t)c);
          }
          if ((statep = _getmbstate(fp)) == NULL) {
                  fp->_flag = _IOERR;
*** 59,69 ****
                  errno = EBADF;
                  return (WEOF);
          }
          do {
                  char    x = (char)c;
!                 nconv = __mbrtowc(&wc, &x, 1, statep);
                  if (nconv == (size_t)-1) {
                          break;
                  } else if (nconv == (size_t)-2) {
                          /* Incompletely decoded, consume another char */
                          continue;
--- 64,74 ----
                  errno = EBADF;
                  return (WEOF);
          }
          do {
                  char    x = (char)c;
!                 nconv = lct->lc_mbrtowc(&wc, &x, 1, statep);
                  if (nconv == (size_t)-1) {
                          break;
                  } else if (nconv == (size_t)-2) {
                          /* Incompletely decoded, consume another char */
                          continue;
*** 87,139 ****
          fp->_flag |= _IOERR;
          errno = EILSEQ;
          return (WEOF);
  }
  
  
  /*
   * MT safe version
   */
  wint_t
  fgetwc(FILE *fp)
  {
          wint_t          r;
          rmutex_t        *l;
  
          FLOCKFILE(l, fp);
!         r = _fgetwc_unlocked(fp);
          FUNLOCKFILE(l);
  
          return (r);
  }
  
- #undef  getwc
- wint_t
- getwc(FILE *fp)
- {
-         return (getwc(fp));
- }
- 
  /*
   * XPG5 version.
   */
  wint_t
  __fgetwc_xpg5(FILE *fp)
  {
          wint_t          r;
          rmutex_t        *l;
  
          FLOCKFILE(l, fp);
          if (GET_NO_MODE(fp))
                  _setorientation(fp, _WC_MODE);
!         r = _fgetwc_unlocked(fp);
          FUNLOCKFILE(l);
  
          return (r);
  }
  
! #undef  __getwc_xpg5
  wint_t
! __getwc_xpg5(FILE *fp)
  {
!         return (__fgetwc_xpg5(fp));
  }
--- 92,157 ----
          fp->_flag |= _IOERR;
          errno = EILSEQ;
          return (WEOF);
  }
  
+ wint_t
+ _fgetwc_unlocked(FILE *fp)
+ {
+         return (_fgetwc_unlocked_l(fp, uselocale(NULL)));
+ }
  
+ 
  /*
   * MT safe version
   */
+ #undef getwc
+ #pragma weak getwc = fgetwc
  wint_t
  fgetwc(FILE *fp)
  {
          wint_t          r;
          rmutex_t        *l;
+         locale_t        loc = uselocale(NULL);
  
          FLOCKFILE(l, fp);
!         r = _fgetwc_unlocked_l(fp, loc);
          FUNLOCKFILE(l);
  
          return (r);
  }
  
  /*
   * XPG5 version.
   */
+ #undef  __getwc_xpg5
+ #pragma weak __getwc_xpg5 = __fgetwc_xpg5
  wint_t
  __fgetwc_xpg5(FILE *fp)
  {
          wint_t          r;
          rmutex_t        *l;
+         locale_t        loc = uselocale(NULL);
  
          FLOCKFILE(l, fp);
          if (GET_NO_MODE(fp))
                  _setorientation(fp, _WC_MODE);
!         r = _fgetwc_unlocked_l(fp, loc);
          FUNLOCKFILE(l);
  
          return (r);
  }
  
! #pragma weak getwc_l = fgetwc_l
  wint_t
! fgetwc_l(FILE *fp, locale_t loc)
  {
!         wint_t          r;
!         rmutex_t        *l;
!         FLOCKFILE(l, fp);
!         if (GET_NO_MODE(fp))
!                 _setorientation(fp, _WC_MODE);
!         r = _fgetwc_unlocked_l(fp, loc);
!         FUNLOCKFILE(l);
! 
!         return (r);
  }