Coverage Report

Created: 2026-10-28 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/r-source/src/extra/tre/regcomp.c
Line
Count
Source
1
/*
2
  tre_regcomp.c - TRE POSIX compatible regex compilation functions.
3
4
  This software is released under a BSD-style license.
5
  See the file LICENSE for details and copyright.
6
7
*/
8
9
#ifdef HAVE_CONFIG_H
10
#include <config.h>
11
#endif /* HAVE_CONFIG_H */
12
13
#include <string.h>
14
#include <errno.h>
15
#include <stdlib.h>
16
17
#include "tre.h"
18
#include "tre-internal.h"
19
#include "xmalloc.h"
20
21
int
22
tre_regncomp(regex_t *preg, const char *regex, size_t n, int cflags)
23
336
{
24
336
  int ret;
25
336
#if TRE_WCHAR
26
336
  tre_char_t *wregex;
27
336
  size_t wlen;
28
29
336
  wregex = xmalloc(sizeof(tre_char_t) * (n + 1));
30
336
  if (wregex == NULL)
31
0
    return REG_ESPACE;
32
33
  /* If the current locale uses the standard single byte encoding of
34
     characters, we don't do a multibyte string conversion.  If we did,
35
     many applications which use the default locale would break since
36
     the default "C" locale uses the 7-bit ASCII character set, and
37
     all characters with the eighth bit set would be considered invalid. */
38
336
#if TRE_MULTIBYTE
39
336
  if (TRE_MB_CUR_MAX == 1)
40
336
#endif /* TRE_MULTIBYTE */
41
336
    {
42
336
      size_t i;
43
336
      const unsigned char *str = (const unsigned char *)regex;
44
336
      tre_char_t *wstr = wregex;
45
46
672
      for (i = 0; i < n; i++)
47
336
  *(wstr++) = *(str++);
48
336
      wlen = n;
49
336
    }
50
0
#if TRE_MULTIBYTE
51
0
  else
52
0
    {
53
0
      size_t consumed;
54
0
      tre_char_t *wcptr = wregex;
55
0
#ifdef HAVE_MBSTATE_T
56
0
      mbstate_t state;
57
0
      memset(&state, '\0', sizeof(state));
58
0
#endif /* HAVE_MBSTATE_T */
59
0
      while (n > 0)
60
0
  {
61
0
    consumed = tre_mbrtowc(wcptr, regex, n, &state);
62
63
0
    switch (consumed)
64
0
      {
65
0
      case 0:
66
0
        if (*regex == '\0')
67
0
    consumed = 1;
68
0
        else
69
0
    {
70
0
      xfree(wregex);
71
0
      return REG_BADPAT;
72
0
    }
73
0
        break;
74
0
      case (size_t)-1:
75
0
        DPRINT(("mbrtowc: error %d: %s.\n", errno, strerror(errno)));
76
0
        xfree(wregex);
77
0
        return REG_BADPAT;
78
0
      case (size_t)-2:
79
        /* The last character wasn't complete.  Let's not call it a
80
     fatal error. */
81
0
        consumed = n;
82
0
        break;
83
0
      }
84
0
    regex += consumed;
85
0
    n -= consumed;
86
0
    wcptr++;
87
0
  }
88
0
      wlen = wcptr - wregex;
89
0
    }
90
336
#endif /* TRE_MULTIBYTE */
91
92
336
  wregex[wlen] = L'\0';
93
336
  ret = tre_compile(preg, wregex, wlen, cflags);
94
336
  xfree(wregex);
95
#else /* !TRE_WCHAR */
96
  ret = tre_compile(preg, (const tre_char_t *)regex, n, cflags);
97
#endif /* !TRE_WCHAR */
98
99
336
  return ret;
100
336
}
101
102
/* this version takes bytes literally, to be used with raw vectors */
103
int
104
tre_regncompb(regex_t *preg, const char *regex, size_t n, int cflags)
105
0
{
106
0
  int ret;
107
#if TRE_WCHAR /* wide chars = we need to convert it all to the wide format */
108
0
  tre_char_t *wregex;
109
0
  size_t i;
110
111
0
  wregex = xmalloc(sizeof(tre_char_t) * n);
112
0
  if (wregex == NULL)
113
0
    return REG_ESPACE;
114
115
0
  for (i = 0; i < n; i++)
116
0
    wregex[i] = (tre_char_t) ((unsigned char) regex[i]);
117
118
0
  ret = tre_compile(preg, wregex, n, cflags | REG_USEBYTES);
119
0
  xfree(wregex);
120
#else /* !TRE_WCHAR */
121
  ret = tre_compile(preg, (const tre_char_t *)regex, n, cflags | REG_USEBYTES);
122
#endif /* !TRE_WCHAR */
123
124
0
  return ret;
125
0
}
126
127
int
128
tre_regcomp(regex_t *preg, const char *regex, int cflags)
129
336
{
130
336
  return tre_regncomp(preg, regex, regex ? strlen(regex) : 0, cflags);
131
336
}
132
133
int
134
tre_regcompb(regex_t *preg, const char *regex, int cflags)
135
844k
{
136
844k
  int ret;
137
844k
  tre_char_t *wregex;
138
844k
  size_t wlen, n = strlen(regex);
139
844k
  unsigned int i;
140
844k
  const unsigned char *str = (const unsigned char *)regex;
141
844k
  tre_char_t *wstr;
142
143
844k
  wregex = xmalloc(sizeof(tre_char_t) * (n + 1));
144
844k
  if (wregex == NULL) return REG_ESPACE;
145
844k
  wstr = wregex;
146
147
8.02M
  for (i = 0; i < n; i++) *(wstr++) = *(str++);
148
844k
  wlen = n;
149
844k
  wregex[wlen] = L'\0';
150
844k
  ret = tre_compile(preg, wregex, wlen, cflags | REG_USEBYTES);
151
844k
  xfree(wregex);
152
844k
  return ret;
153
844k
}
154
155
156
#ifdef TRE_WCHAR
157
int
158
tre_regwncomp(regex_t *preg, const wchar_t *regex, size_t n, int cflags)
159
0
{
160
0
  return tre_compile(preg, regex, n, cflags);
161
0
}
162
163
int
164
tre_regwcomp(regex_t *preg, const wchar_t *regex, int cflags)
165
1.96k
{
166
1.96k
  return tre_compile(preg, regex, regex ? wcslen(regex) : 0, cflags);
167
1.96k
}
168
#endif /* TRE_WCHAR */
169
170
void
171
tre_regfree(regex_t *preg)
172
847k
{
173
847k
  tre_free(preg);
174
847k
}
175
176
/* EOF */