Coverage Report

Created: 2026-10-10 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/flex/src/regex.c
Line
Count
Source
1
/** regex - regular expression functions related to POSIX regex lib. */
2
3
/* SPDX-License-Identifier: BSD-3-Clause-flex */
4
5
/*  This file is part of flex. */
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
11
/*  1. Redistributions of source code must retain the above copyright */
12
/*     notice, this list of conditions and the following disclaimer. */
13
/*  2. Redistributions in binary form must reproduce the above copyright */
14
/*     notice, this list of conditions and the following disclaimer in the */
15
/*     documentation and/or other materials provided with the distribution. */
16
17
/*  Neither the name of the University nor the names of its contributors */
18
/*  may be used to endorse or promote products derived from this software */
19
/*  without specific prior written permission. */
20
21
/*  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
22
/*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
23
/*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
24
/*  PURPOSE. */
25
26
#include "flexdef.h"
27
28
29
regex_t regex_linedir; /**< matches line directives */
30
31
32
/** Initialize the regular expressions.
33
 * @return true upon success.
34
 */
35
bool flex_init_regex(const char *traceline_re)
36
0
{
37
0
  if (traceline_re != NULL)
38
0
    flex_regcomp(&regex_linedir, traceline_re, REG_EXTENDED);
39
0
  return true;
40
0
}
41
42
/** Compiles a regular expression or dies trying.
43
 * @param preg  Same as for regcomp().
44
 * @param regex Same as for regcomp().
45
 * @param cflags Same as for regcomp().
46
 */
47
void flex_regcomp(regex_t *preg, const char *regex, int cflags)
48
0
{
49
0
  int err;
50
51
0
  memset (preg, 0, sizeof (regex_t));
52
53
0
  if ((err = regcomp (preg, regex, cflags)) != 0) {
54
0
    const size_t errbuf_sz = 200;
55
0
    char *errbuf;
56
0
    int n;
57
58
0
    errbuf = malloc(errbuf_sz * sizeof(char));
59
0
    if (!errbuf)
60
0
      flexfatal(_("Unable to allocate buffer to report regcomp"));
61
0
    n = snprintf(errbuf, errbuf_sz, "regcomp for \"%s\" failed: ", regex);
62
0
    regerror(err, preg, errbuf+n, errbuf_sz-(size_t)n);
63
64
0
    flexfatal (errbuf); /* never returns - no need to free(errbuf) */
65
0
  }
66
0
}
67
68
/** Extract a copy of the match, or NULL if no match.
69
 * @param m A match as returned by regexec().
70
 * @param src The source string that was passed to regexec().
71
 * @return The allocated string.
72
 */
73
char   *regmatch_dup (regmatch_t * m, const char *src)
74
0
{
75
0
  char   *str;
76
0
  size_t  len;
77
78
0
  if (m == NULL || m->rm_so < 0 || m->rm_eo < m->rm_so)
79
0
    return NULL;
80
0
  len = (size_t) (m->rm_eo - m->rm_so);
81
0
  str = malloc((len + 1) * sizeof(char));
82
0
  if (!str)
83
0
    flexfatal(_("Unable to allocate a copy of the match"));
84
0
  strncpy (str, src + m->rm_so, len);
85
0
  str[len] = 0;
86
0
  return str;
87
0
}
88
89
/** Copy the match.
90
 * @param m A match as returned by regexec().
91
 * @param dest The destination buffer.
92
 * @param src The source string that was passed to regexec().
93
 * @return dest
94
 */
95
char   *regmatch_cpy (regmatch_t * m, char *dest, const char *src)
96
0
{
97
0
  if (m == NULL || m->rm_so < 0) {
98
0
    if (dest)
99
0
      dest[0] = '\0';
100
0
    return dest;
101
0
  }
102
103
0
  snprintf (dest, (size_t) regmatch_len(m), "%s", src + m->rm_so);
104
0
  return dest;
105
0
}
106
107
/** Get the length in characters of the match.
108
 * @param m A match as returned by regexec().
109
 * @return The length of the match.
110
 */
111
int regmatch_len (regmatch_t * m)
112
0
{
113
0
  if (m == NULL || m->rm_so < 0) {
114
0
    return 0;
115
0
  }
116
117
0
  return m->rm_eo - m->rm_so;
118
0
}
119
120
121
122
/** Convert a regmatch_t object to an integer using the strtol() function.
123
 * @param m A match as returned by regexec().
124
 * @param src The source string that was passed to regexec().
125
 * @param endptr Same as the second argument to strtol().
126
 * @param base   Same as the third argument to strtol().
127
 * @return The converted integer or error (Return value is the same as for strtol()).
128
 */
129
int regmatch_strtol (regmatch_t * m, const char *src, char **endptr,
130
         int base)
131
0
{
132
0
  int     n = 0;
133
134
0
#define bufsz 20
135
0
  char    buf[bufsz];
136
0
  char   *s;
137
138
0
  if (m == NULL || m->rm_so < 0)
139
0
    return 0;
140
141
0
  if (regmatch_len (m) < bufsz)
142
0
    s = regmatch_cpy (m, buf, src);
143
0
  else
144
0
    s = regmatch_dup (m, src);
145
146
0
  n = (int) strtol (s, endptr, base);
147
148
0
  if (s != buf)
149
0
    free (s);
150
151
0
  return n;
152
0
}
153
154
/** Check for empty or non-existent match.
155
 * @param m A match as returned by regexec().
156
 * @return false if match length is non-zero.
157
 * Note that reg_empty returns true even if match did not occur at all.
158
 */
159
bool regmatch_empty (regmatch_t * m)
160
0
{
161
0
  return (m == NULL || m->rm_so < 0 || m->rm_so == m->rm_eo);
162
0
}
163
164
/* vim:set expandtab cindent tabstop=4 softtabstop=4 shiftwidth=4 textwidth=0: */