aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2024-11-01 00:17:33 +0100
committerThomas Voss <mail@thomasvoss.com> 2024-11-01 00:17:33 +0100
commitbb6b8ce9146d77cbea6c37eeac0fd1e760061036 (patch)
treec31b40aeb9fd06f7f4d65b987b46fb1620474d6d
parent48b7c4478488046e190f8c9e5fa6bd4ddfb1018e (diff)
Introduce pcre2_bitch_and_die()
-rw-r--r--src/main.c13
-rw-r--r--src/util.c24
-rw-r--r--src/util.h6
-rw-r--r--src/work.c31
4 files changed, 41 insertions, 33 deletions
diff --git a/src/main.c b/src/main.c
index 9e7e522..e004f1e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -19,6 +19,7 @@
#include "exitcodes.h"
#include "tpool.h"
+#include "util.h"
#include "work.h"
#define MAIN_C 1
@@ -39,7 +40,6 @@ const char *lquot = "`", *rquot = "'";
matching or not */
typeof(pcre2_match) *pcre2_match_fn;
-static char emsg[256]; /* Buffer for PCRE2 error messages */
/* TODO: Use the LUT in work.c */
static const bool opchars[] = {
['g'] = true,
@@ -355,15 +355,10 @@ pattern_comp(u8view_t pat)
int ec;
size_t eoff;
op.re = pcre2_compile(re.p, re.len, reopts, &ec, &eoff, nullptr);
- if (op.re == nullptr) {
- /* TODO: Ensure the buffer is large enough for the error message */
- (void)pcre2_get_error_message(ec, emsg, sizeof(emsg));
- cerr(EXIT_FATAL, "Failed to compile regex: %s", emsg);
- }
+ if (op.re == nullptr)
+ pcre2_bitch_and_die(ec, "failed to compile regex: %s");
if ((ec = pcre2_jit_compile(op.re, PCRE2_JIT_COMPLETE)) != 0) {
- /* TODO: Ensure the buffer is large enough for the error message */
- (void)pcre2_get_error_message(ec, emsg, sizeof(emsg));
- warn("Failed to JIT compile regex: %s", emsg);
+ pcre2_bitch_and_die(ec, "failed to JIT compile regex: %s");
rv = EXIT_WARNING;
pcre2_match_fn = pcre2_match;
} else
diff --git a/src/util.c b/src/util.c
new file mode 100644
index 0000000..d20611f
--- /dev/null
+++ b/src/util.c
@@ -0,0 +1,24 @@
+#include <stddef.h>
+#include <stdlib.h>
+
+#include <errors.h>
+#include <pcre2.h>
+
+#include "exitcodes.h"
+
+void
+pcre2_bitch_and_die(int ec, const char *fmt)
+{
+ /* If we’ve gotten here, we don’t care about writing efficient code */
+ ptrdiff_t bufsz = 512;
+ for (;;) {
+ char *buf = malloc(bufsz);
+ if (buf == nullptr)
+ cerr(EXIT_FATAL, "malloc:");
+ if (pcre2_get_error_message(ec, buf, bufsz) == PCRE2_ERROR_NOMEMORY) {
+ free(buf);
+ bufsz *= 2;
+ } else
+ cerr(EXIT_FATAL, fmt, buf);
+ }
+} \ No newline at end of file
diff --git a/src/util.h b/src/util.h
new file mode 100644
index 0000000..d2909ce
--- /dev/null
+++ b/src/util.h
@@ -0,0 +1,6 @@
+#ifndef GRAB_UTIL_H
+#define GRAB_UTIL_H
+
+void pcre2_bitch_and_die(int ec, const char *fmt);
+
+#endif /* !GRAB_UTIL_H */ \ No newline at end of file
diff --git a/src/work.c b/src/work.c
index 85cdbce..06b0eb8 100644
--- a/src/work.c
+++ b/src/work.c
@@ -22,6 +22,7 @@
#include "exitcodes.h"
#include "flags.h"
+#include "util.h"
#include "work.h"
#define DEFINE_OPERATOR(fn) \
@@ -193,13 +194,10 @@ DEFINE_OPERATOR(g)
md, nullptr);
pcre2_match_data_free(md);
- /* This should never happen */
- if (n == 0)
- cerr(EXIT_FATAL, "PCRE2 match data too small");
if (n == PCRE2_ERROR_NOMATCH)
return;
if (n < 0)
- ; /* TODO: Handle error */
+ pcre2_bitch_and_die(n, "failed to match regex: %s");
operator_dispatch(opi + 1, sv, hl);
}
@@ -213,13 +211,10 @@ DEFINE_OPERATOR(G)
md, nullptr);
pcre2_match_data_free(md);
- /* This should never happen */
- if (n == 0)
- cerr(EXIT_FATAL, "PCRE2 match data too small");
if (n == PCRE2_ERROR_NOMATCH)
operator_dispatch(opi + 1, sv, hl);
if (n < 0)
- ; /* TODO: Handle error */
+ pcre2_bitch_and_die(n, "failed to match regex: %s");
}
DEFINE_OPERATOR(h)
@@ -236,13 +231,10 @@ DEFINE_OPERATOR(h)
for (;;) {
int n = pcre2_match_fn(ops[opi].re, sv.p, sv.len, 0,
PCRE2_NOTEMPTY, md, nullptr);
- /* This should never happen */
- if (n == 0)
- cerr(EXIT_FATAL, "PCRE2 match data too small");
if (n == PCRE2_ERROR_NOMATCH)
break;
if (n < 0)
- ; /* TODO: Handle error */
+ pcre2_bitch_and_die(n, "failed to match regex: %s");
size_t *ov = pcre2_get_ovector_pointer(md);
array_push(hl, ((u8view_t){sv.p + ov[0], ov[1] - ov[0]}));
@@ -267,13 +259,10 @@ DEFINE_OPERATOR(H)
for (;;) {
int n = pcre2_match_fn(ops[opi].re, sv.p, sv.len, 0, PCRE2_NOTEMPTY,
md, nullptr);
- /* This should never happen */
- if (n == 0)
- cerr(EXIT_FATAL, "PCRE2 match data too small");
if (n == PCRE2_ERROR_NOMATCH)
break;
if (n < 0)
- ; /* TODO: Handle error */
+ pcre2_bitch_and_die(n, "failed to match regex: %s");
size_t *ov = pcre2_get_ovector_pointer(md);
array_push(hl, ((u8view_t){sv.p, ov[0]}));
@@ -291,13 +280,10 @@ DEFINE_OPERATOR(x)
for (;;) {
int n = pcre2_match_fn(ops[opi].re, sv.p, sv.len, 0, PCRE2_NOTEMPTY,
md, nullptr);
- /* This should never happen */
- if (n == 0)
- cerr(EXIT_FATAL, "PCRE2 match data too small");
if (n == PCRE2_ERROR_NOMATCH)
break;
if (n < 0)
- ; /* TODO: Handle error */
+ pcre2_bitch_and_die(n, "failed to match regex: %s");
size_t *ov = pcre2_get_ovector_pointer(md);
operator_dispatch(opi + 1, (u8view_t){sv.p + ov[0], ov[1] - ov[0]}, hl);
@@ -313,13 +299,10 @@ DEFINE_OPERATOR(X)
for (;;) {
int n = pcre2_match_fn(ops[opi].re, sv.p, sv.len, 0, PCRE2_NOTEMPTY,
md, nullptr);
- /* This should never happen */
- if (n == 0)
- cerr(EXIT_FATAL, "PCRE2 match data too small");
if (n == PCRE2_ERROR_NOMATCH)
break;
if (n < 0)
- ; /* TODO: Handle error */
+ pcre2_bitch_and_die(n, "failed to match regex: %s");
size_t *ov = pcre2_get_ovector_pointer(md);
if (ov[0] != 0)