-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathregexp.c
92 lines (79 loc) · 2.76 KB
/
regexp.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/*
* regexp.h -- PCRE wrapper
*
* Copyright (c) 2012-2017 Nick Reynolds
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef FH_NO_REGEXP
#include <pcre.h>
#endif
#include "regexp.h"
#include "flathead.h"
const int regexp_vector_len = 30;
/* Gateway to the PCRE library. Compiles a regular expression pattern and
* returns matches. When compiled with FH_NO_REGEXP, this function is still
* available, but will throw an error when called. */
int *
fh_regexp(char *str, char *pattern, int *count, int offset, bool caseless)
{
#ifndef FH_NO_REGEXP
const char *error;
int rc;
int error_offset;
int *output_vector = malloc(regexp_vector_len * sizeof(int));
int options = PCRE_JAVASCRIPT_COMPAT;
if (caseless)
options |= PCRE_CASELESS;
pcre *regexp = pcre_compile(pattern, options, &error, &error_offset, NULL);
if (!regexp) {
char *fmt = "Invalid Regular Expression:\n %s at offset %d";
fh_throw(NULL, fh_new_error(E_SYNTAX, fmt, error, error_offset));
}
rc = pcre_exec(regexp, NULL, str, strlen(str), offset, 0,
output_vector, regexp_vector_len);
if (count != NULL)
*count = rc > 0 ? rc : 0;
pcre_free(regexp);
if (rc < 0) {
free(output_vector);
return NULL;
}
return output_vector;
#else
fh_throw(NULL, fh_new_error(E_ERROR, "Regular expressions are not available"));
UNREACHABLE();
#endif
}
/* Get the number of capturing subpatterns in the regular expression. This is
* used to get the `NCapturingParens` value used in parts of the ECMA spec */
int
fh_regexp_ncaptures(char *pattern)
{
#ifndef FH_NO_REGEXP
const char *error;
int error_offset;
int options = PCRE_JAVASCRIPT_COMPAT;
int captures;
pcre *regexp = pcre_compile(pattern, options, &error, &error_offset, NULL);
if (!regexp) {
char *fmt = "Invalid Regular Expression:\n %s at offset %d";
fh_throw(NULL, fh_new_error(E_SYNTAX, fmt, error, error_offset));
}
pcre_fullinfo(regexp, NULL, PCRE_INFO_CAPTURECOUNT, &captures);
return captures;
#else
fh_throw(NULL, fh_new_error(E_ERROR, "Regular expressions are not available"));
UNREACHABLE();
#endif
}