(root)/
glibc-2.38/
wcsmbs/
btowc.c
       1  /* Copyright (C) 1996-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <ctype.h>
      19  #include <dlfcn.h>
      20  #include <gconv.h>
      21  #include <stdio.h>
      22  #include <string.h>
      23  #include <wchar.h>
      24  #include <wcsmbsload.h>
      25  #include <limits.h>
      26  
      27  #include <pointer_guard.h>
      28  
      29  
      30  wint_t
      31  __btowc (int c)
      32  {
      33    const struct gconv_fcts *fcts;
      34  
      35    /* If the parameter does not fit into one byte or it is the EOF value
      36       we can give the answer now.  */
      37    if (c < SCHAR_MIN || c > UCHAR_MAX || c == EOF)
      38      return WEOF;
      39  
      40    /* We know that only ASCII compatible encodings are used for the
      41       locale and that the wide character encoding is ISO 10646.  */
      42    if (isascii (c))
      43      return (wint_t) c;
      44  
      45    /* Get the conversion functions.  */
      46    fcts = get_gconv_fcts (_NL_CURRENT_DATA (LC_CTYPE));
      47    __gconv_btowc_fct btowc_fct = fcts->towc->__btowc_fct;
      48    if (fcts->towc->__shlib_handle != NULL)
      49      PTR_DEMANGLE (btowc_fct);
      50  
      51    if (__builtin_expect (fcts->towc_nsteps == 1, 1)
      52        && __builtin_expect (btowc_fct != NULL, 1))
      53      {
      54        /* Use the shortcut function.  */
      55        return DL_CALL_FCT (btowc_fct, (fcts->towc, (unsigned char) c));
      56      }
      57    else
      58      {
      59        /* Fall back to the slow but generic method.  */
      60        wchar_t result;
      61        struct __gconv_step_data data;
      62        unsigned char inbuf[1];
      63        const unsigned char *inptr = inbuf;
      64        size_t dummy;
      65        int status;
      66  
      67        /* Tell where we want the result.  */
      68        data.__outbuf = (unsigned char *) &result;
      69        data.__outbufend = data.__outbuf + sizeof (wchar_t);
      70        data.__invocation_counter = 0;
      71        data.__internal_use = 1;
      72        data.__flags = __GCONV_IS_LAST;
      73        data.__statep = &data.__state;
      74  
      75        /* Make sure we start in the initial state.  */
      76        memset (&data.__state, '\0', sizeof (mbstate_t));
      77  
      78        /* Create the input string.  */
      79        inbuf[0] = c;
      80  
      81        __gconv_fct fct = fcts->towc->__fct;
      82        if (fcts->towc->__shlib_handle != NULL)
      83  	PTR_DEMANGLE (fct);
      84        status = DL_CALL_FCT (fct, (fcts->towc, &data, &inptr, inptr + 1,
      85  				  NULL, &dummy, 0, 1));
      86  
      87        if (status != __GCONV_OK && status != __GCONV_FULL_OUTPUT
      88  	  && status != __GCONV_EMPTY_INPUT)
      89  	/* The conversion failed.  */
      90  	result = WEOF;
      91  
      92        return result;
      93      }
      94  }
      95  weak_alias (__btowc, btowc)