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 /*

   2  * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
   3  * Copyright (c) 2002-2004 Tim J. Robbins.
   4  * All rights reserved.
   5  *
   6  * Redistribution and use in source and binary forms, with or without
   7  * modification, are permitted provided that the following conditions
   8  * are met:
   9  * 1. Redistributions of source code must retain the above copyright
  10  *    notice, this list of conditions and the following disclaimer.
  11  * 2. Redistributions in binary form must reproduce the above copyright
  12  *    notice, this list of conditions and the following disclaimer in the
  13  *    documentation and/or other materials provided with the distribution.
  14  *
  15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  25  * SUCH DAMAGE.
  26  */
  27 
  28 #include "lint.h"
  29 #include "mse_int.h"
  30 #include "file64.h"
  31 #include "mtlib.h"
  32 #include <errno.h>
  33 #include <stdio.h>
  34 #include <stdlib.h>
  35 #include <wchar.h>
  36 #include "mblocal.h"
  37 #include "stdiom.h"


  38 
  39 /*
  40  * Non-MT-safe version.
  41  */
  42 wint_t
  43 _fgetwc_unlocked(FILE *fp)
  44 {
  45         wchar_t wc;
  46         size_t nconv;
  47         int     c;
  48         mbstate_t       *statep;

  49 
  50         if ((c = GETC(fp)) == EOF)
  51                 return (WEOF);
  52 
  53         if (MB_CUR_MAX == 1) {

  54                 /* Fast path for single-byte encodings. */
  55                 return ((wint_t)c);
  56         }
  57         if ((statep = _getmbstate(fp)) == NULL) {
  58                 fp->_flag = _IOERR;
  59                 errno = EBADF;
  60                 return (WEOF);
  61         }
  62         do {
  63                 char    x = (char)c;
  64                 nconv = __mbrtowc(&wc, &x, 1, statep);
  65                 if (nconv == (size_t)-1) {
  66                         break;
  67                 } else if (nconv == (size_t)-2) {
  68                         /* Incompletely decoded, consume another char */
  69                         continue;
  70                 } else if (nconv == 0) {
  71                         /*
  72                          * Assume that the only valid representation of
  73                          * the null wide character is a single null byte.
  74                          */
  75                         return (L'\0');
  76                 } else {
  77                         return (wc);
  78                 }
  79         } while ((c = GETC(fp)) != EOF);
  80 
  81         /*
  82          * If we got here it means we got truncated in a character, or
  83          * the character did not decode properly.  Note that in the case
  84          * of a botched decoding, we don't UNGETC the bad bytes.  Should
  85          * we?
  86          */
  87         fp->_flag |= _IOERR;
  88         errno = EILSEQ;
  89         return (WEOF);
  90 }
  91 





  92 

  93 /*
  94  * MT safe version
  95  */


  96 wint_t
  97 fgetwc(FILE *fp)
  98 {
  99         wint_t          r;
 100         rmutex_t        *l;

 101 
 102         FLOCKFILE(l, fp);
 103         r = _fgetwc_unlocked(fp);
 104         FUNLOCKFILE(l);
 105 
 106         return (r);
 107 }
 108 
 109 #undef  getwc
 110 wint_t
 111 getwc(FILE *fp)
 112 {
 113         return (getwc(fp));
 114 }
 115 
 116 /*
 117  * XPG5 version.
 118  */


 119 wint_t
 120 __fgetwc_xpg5(FILE *fp)
 121 {
 122         wint_t          r;
 123         rmutex_t        *l;

 124 
 125         FLOCKFILE(l, fp);
 126         if (GET_NO_MODE(fp))
 127                 _setorientation(fp, _WC_MODE);
 128         r = _fgetwc_unlocked(fp);
 129         FUNLOCKFILE(l);
 130 
 131         return (r);
 132 }
 133 
 134 #undef  __getwc_xpg5
 135 wint_t
 136 __getwc_xpg5(FILE *fp)
 137 {
 138         return (__fgetwc_xpg5(fp));








 139 }
   1 /*
   2  * Copyright 2013 Garrett D'Amore <garrett@damore.org>
   3  * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
   4  * Copyright (c) 2002-2004 Tim J. Robbins.
   5  * All rights reserved.
   6  *
   7  * Redistribution and use in source and binary forms, with or without
   8  * modification, are permitted provided that the following conditions
   9  * are met:
  10  * 1. Redistributions of source code must retain the above copyright
  11  *    notice, this list of conditions and the following disclaimer.
  12  * 2. Redistributions in binary form must reproduce the above copyright
  13  *    notice, this list of conditions and the following disclaimer in the
  14  *    documentation and/or other materials provided with the distribution.
  15  *
  16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26  * SUCH DAMAGE.
  27  */
  28 
  29 #include "lint.h"
  30 #include "mse_int.h"
  31 #include "file64.h"
  32 #include "mtlib.h"
  33 #include <errno.h>
  34 #include <stdio.h>
  35 #include <stdlib.h>
  36 #include <wchar.h>
  37 #include "mblocal.h"
  38 #include "stdiom.h"
  39 #include "localeimpl.h"
  40 #include "lctype.h"
  41 
  42 /*
  43  * Non-MT-safe version.
  44  */
  45 wint_t
  46 _fgetwc_unlocked_l(FILE *fp, locale_t loc)
  47 {
  48         wchar_t wc;
  49         size_t nconv;
  50         int     c;
  51         mbstate_t       *statep;
  52         const struct lc_ctype *lct;
  53 
  54         if ((c = GETC(fp)) == EOF)
  55                 return (WEOF);
  56 
  57         lct = loc->ctype;
  58         if (lct->lc_max_mblen == 1) {
  59                 /* Fast path for single-byte encodings. */
  60                 return ((wint_t)c);
  61         }
  62         if ((statep = _getmbstate(fp)) == NULL) {
  63                 fp->_flag = _IOERR;
  64                 errno = EBADF;
  65                 return (WEOF);
  66         }
  67         do {
  68                 char    x = (char)c;
  69                 nconv = lct->lc_mbrtowc(&wc, &x, 1, statep);
  70                 if (nconv == (size_t)-1) {
  71                         break;
  72                 } else if (nconv == (size_t)-2) {
  73                         /* Incompletely decoded, consume another char */
  74                         continue;
  75                 } else if (nconv == 0) {
  76                         /*
  77                          * Assume that the only valid representation of
  78                          * the null wide character is a single null byte.
  79                          */
  80                         return (L'\0');
  81                 } else {
  82                         return (wc);
  83                 }
  84         } while ((c = GETC(fp)) != EOF);
  85 
  86         /*
  87          * If we got here it means we got truncated in a character, or
  88          * the character did not decode properly.  Note that in the case
  89          * of a botched decoding, we don't UNGETC the bad bytes.  Should
  90          * we?
  91          */
  92         fp->_flag |= _IOERR;
  93         errno = EILSEQ;
  94         return (WEOF);
  95 }
  96 
  97 wint_t
  98 _fgetwc_unlocked(FILE *fp)
  99 {
 100         return (_fgetwc_unlocked_l(fp, uselocale(NULL)));
 101 }
 102 
 103 
 104 /*
 105  * MT safe version
 106  */
 107 #undef getwc
 108 #pragma weak getwc = fgetwc
 109 wint_t
 110 fgetwc(FILE *fp)
 111 {
 112         wint_t          r;
 113         rmutex_t        *l;
 114         locale_t        loc = uselocale(NULL);
 115 
 116         FLOCKFILE(l, fp);
 117         r = _fgetwc_unlocked_l(fp, loc);
 118         FUNLOCKFILE(l);
 119 
 120         return (r);
 121 }
 122 







 123 /*
 124  * XPG5 version.
 125  */
 126 #undef  __getwc_xpg5
 127 #pragma weak __getwc_xpg5 = __fgetwc_xpg5
 128 wint_t
 129 __fgetwc_xpg5(FILE *fp)
 130 {
 131         wint_t          r;
 132         rmutex_t        *l;
 133         locale_t        loc = uselocale(NULL);
 134 
 135         FLOCKFILE(l, fp);
 136         if (GET_NO_MODE(fp))
 137                 _setorientation(fp, _WC_MODE);
 138         r = _fgetwc_unlocked_l(fp, loc);
 139         FUNLOCKFILE(l);
 140 
 141         return (r);
 142 }
 143 
 144 #pragma weak getwc_l = fgetwc_l
 145 wint_t
 146 fgetwc_l(FILE *fp, locale_t loc)
 147 {
 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);
 157 }