Coverage Report

Created: 2025-02-06 07:40

/src/augeas/gnulib/lib/mbrtowc.c
Line
Count
Source (jump to first uncovered line)
1
/* Convert multibyte character to wide character.
2
   Copyright (C) 1999-2002, 2005-2022 Free Software Foundation, Inc.
3
   Written by Bruno Haible <bruno@clisp.org>, 2008.
4
5
   This file is free software: you can redistribute it and/or modify
6
   it under the terms of the GNU Lesser General Public License as
7
   published by the Free Software Foundation; either version 2.1 of the
8
   License, or (at your option) any later version.
9
10
   This file is distributed in the hope that it will be useful,
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
   GNU Lesser General Public License for more details.
14
15
   You should have received a copy of the GNU Lesser General Public License
16
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
17
18
#include <config.h>
19
20
/* Specification.  */
21
#include <wchar.h>
22
23
#if GNULIB_defined_mbstate_t
24
/* Implement mbrtowc() on top of mbtowc() for the non-UTF-8 locales
25
   and directly for the UTF-8 locales.  */
26
27
# include <errno.h>
28
# include <stdint.h>
29
# include <stdlib.h>
30
31
# if defined _WIN32 && !defined __CYGWIN__
32
33
#  define WIN32_LEAN_AND_MEAN  /* avoid including junk */
34
#  include <windows.h>
35
36
# elif HAVE_PTHREAD_API
37
38
#  include <pthread.h>
39
#  if HAVE_THREADS_H && HAVE_WEAK_SYMBOLS
40
#   include <threads.h>
41
#   pragma weak thrd_exit
42
#   define c11_threads_in_use() (thrd_exit != NULL)
43
#  else
44
#   define c11_threads_in_use() 0
45
#  endif
46
47
# elif HAVE_THREADS_H
48
49
#  include <threads.h>
50
51
# endif
52
53
# include "attribute.h"
54
# include "lc-charset-dispatch.h"
55
# include "mbtowc-lock.h"
56
57
static_assert (sizeof (mbstate_t) >= 4);
58
static char internal_state[4];
59
60
size_t
61
mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
62
{
63
# define FITS_IN_CHAR_TYPE(wc)  ((wc) <= WCHAR_MAX)
64
# include "mbrtowc-impl.h"
65
}
66
67
#else
68
/* Override the system's mbrtowc() function.  */
69
70
# if MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ
71
#  include "hard-locale.h"
72
#  include <locale.h>
73
# endif
74
75
# undef mbrtowc
76
77
size_t
78
rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
79
0
{
80
0
  size_t ret;
81
0
  wchar_t wc;
82
83
# if MBRTOWC_NULL_ARG2_BUG || MBRTOWC_RETVAL_BUG || MBRTOWC_EMPTY_INPUT_BUG
84
  if (s == NULL)
85
    {
86
      pwc = NULL;
87
      s = "";
88
      n = 1;
89
    }
90
# endif
91
92
# if MBRTOWC_EMPTY_INPUT_BUG
93
  if (n == 0)
94
    return (size_t) -2;
95
# endif
96
97
0
  if (! pwc)
98
0
    pwc = &wc;
99
100
# if MBRTOWC_RETVAL_BUG
101
  {
102
    static mbstate_t internal_state;
103
104
    /* Override mbrtowc's internal state.  We cannot call mbsinit() on the
105
       hidden internal state, but we can call it on our variable.  */
106
    if (ps == NULL)
107
      ps = &internal_state;
108
109
    if (!mbsinit (ps))
110
      {
111
        /* Parse the rest of the multibyte character byte for byte.  */
112
        size_t count = 0;
113
        for (; n > 0; s++, n--)
114
          {
115
            ret = mbrtowc (&wc, s, 1, ps);
116
117
            if (ret == (size_t)(-1))
118
              return (size_t)(-1);
119
            count++;
120
            if (ret != (size_t)(-2))
121
              {
122
                /* The multibyte character has been completed.  */
123
                *pwc = wc;
124
                return (wc == 0 ? 0 : count);
125
              }
126
          }
127
        return (size_t)(-2);
128
      }
129
  }
130
# endif
131
132
# if MBRTOWC_STORES_INCOMPLETE_BUG
133
  ret = mbrtowc (&wc, s, n, ps);
134
  if (ret < (size_t) -2 && pwc != NULL)
135
    *pwc = wc;
136
# else
137
0
  ret = mbrtowc (pwc, s, n, ps);
138
0
# endif
139
140
# if MBRTOWC_NUL_RETVAL_BUG
141
  if (ret < (size_t) -2 && !*pwc)
142
    return 0;
143
# endif
144
145
0
# if MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ
146
0
  if ((size_t) -2 <= ret && n != 0 && ! hard_locale (LC_CTYPE))
147
0
    {
148
0
      unsigned char uc = *s;
149
0
      *pwc = uc;
150
0
      return 1;
151
0
    }
152
0
# endif
153
154
0
  return ret;
155
0
}
156
157
#endif