Skip to content

Commit

Permalink
Replace use of error_msg_() in src/regexp.c with error_msg()
Browse files Browse the repository at this point in the history
This is a continuation of the work started in commit f1ff10b.
  • Loading branch information
craigbarnes committed Jan 15, 2025
1 parent 340e75c commit 2594dac
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 86 deletions.
26 changes: 10 additions & 16 deletions src/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -788,7 +788,7 @@ static bool cmd_errorfmt(EditorState *e, const CommandArgs *a)

const char *pattern = a->args[1];
regex_t re;
if (unlikely(!regexp_compile(&re, pattern, 0))) {
if (unlikely(!regexp_compile(e->err, &re, pattern, 0))) {
return false;
}

Expand Down Expand Up @@ -854,31 +854,25 @@ static bool cmd_exec(EditorState *e, const CommandArgs *a)

static bool cmd_ft(EditorState *e, const CommandArgs *a)
{
ErrorBuffer *ebuf = e->err;
char **args = a->args;
const char *filetype = args[0];
if (unlikely(!is_valid_filetype_name(filetype))) {
return error_msg(e->err, "Invalid filetype name: '%s'", filetype);
return error_msg(ebuf, "Invalid filetype name: '%s'", filetype);
}

FileDetectionType dt = FT_EXTENSION;
switch (last_flag(a)) {
case 'b':
dt = FT_BASENAME;
break;
case 'c':
dt = FT_CONTENT;
break;
case 'f':
dt = FT_FILENAME;
break;
case 'i':
dt = FT_INTERPRETER;
break;
case 'b': dt = FT_BASENAME; break;
case 'c': dt = FT_CONTENT; break;
case 'f': dt = FT_FILENAME; break;
case 'i': dt = FT_INTERPRETER; break;
}

PointerArray *filetypes = &e->filetypes;
size_t nfailed = 0;
for (size_t i = 1, n = a->nr_args; i < n; i++) {
if (!add_filetype(&e->filetypes, filetype, args[i], dt)) {
if (!add_filetype(filetypes, filetype, args[i], dt, ebuf)) {
nfailed++;
}
}
Expand Down Expand Up @@ -1299,7 +1293,7 @@ static bool cmd_option(EditorState *e, const CommandArgs *a)

PointerArray *opts = &e->file_options;
if (has_flag(a, 'r')) {
FileTypeOrFileName u = {.filename = regexp_intern(arg0)};
FileTypeOrFileName u = {.filename = regexp_intern(e->err, arg0)};
if (unlikely(!u.filename)) {
return false;
}
Expand Down
11 changes: 8 additions & 3 deletions src/filetype.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,17 @@ static bool ft_uses_regex(FileDetectionType type)
return type == FT_CONTENT || type == FT_FILENAME;
}

bool add_filetype(PointerArray *filetypes, const char *name, const char *str, FileDetectionType type)
{
bool add_filetype (
PointerArray *filetypes,
const char *name,
const char *str,
FileDetectionType type,
ErrorBuffer *ebuf
) {
BUG_ON(!is_valid_filetype_name(name));
const InternedRegexp *ir = NULL;
if (ft_uses_regex(type)) {
ir = regexp_intern(str);
ir = regexp_intern(ebuf, str);
if (unlikely(!ir)) {
return false;
}
Expand Down
11 changes: 10 additions & 1 deletion src/filetype.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define FILETYPE_H

#include <stdbool.h>
#include "error.h"
#include "util/macros.h"
#include "util/ptr-array.h"
#include "util/string-view.h"
Expand Down Expand Up @@ -29,11 +30,19 @@ static inline bool is_valid_filetype_name(const char *name)
return is_valid_filetype_name_sv(&sv);
}

bool add_filetype(PointerArray *filetypes, const char *name, const char *str, FileDetectionType type) NONNULL_ARGS WARN_UNUSED_RESULT;
bool is_ft(const PointerArray *filetypes, const char *name);
const char *find_ft(const PointerArray *filetypes, const char *filename, StringView line);
void collect_ft(const PointerArray *filetypes, PointerArray *a, const char *prefix);
String dump_filetypes(const PointerArray *filetypes);
void free_filetypes(PointerArray *filetypes);

WARN_UNUSED_RESULT NONNULL_ARG(1, 2, 3)
bool add_filetype (
PointerArray *filetypes,
const char *name,
const char *str,
FileDetectionType type,
ErrorBuffer *ebuf
);

#endif
8 changes: 5 additions & 3 deletions src/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,18 +244,20 @@ static OptionValue re_get(const OptionDesc* UNUSED_ARG(desc), void *ptr)

static void re_set(const OptionDesc* UNUSED_ARG(d), void *ptr, OptionValue v)
{
// Note that this function is only ever called if re_parse() has already
// validated the pattern
const InternedRegexp **irp = ptr;
*irp = v.str_val ? regexp_intern(v.str_val) : NULL;
*irp = v.str_val ? regexp_intern(NULL, v.str_val) : NULL;
}

static bool re_parse(const OptionDesc* UNUSED_ARG(d), ErrorBuffer* UNUSED_ARG(ebuf), const char *str, OptionValue *v)
static bool re_parse(const OptionDesc* UNUSED_ARG(d), ErrorBuffer *ebuf, const char *str, OptionValue *v)
{
if (str[0] == '\0') {
v->str_val = NULL;
return true;
}

bool valid = regexp_is_interned(str) || regexp_is_valid(str, REG_NEWLINE);
bool valid = regexp_is_interned(str) || regexp_is_valid(ebuf, str, REG_NEWLINE);
v->str_val = valid ? str : NULL;
return valid;
}
Expand Down
28 changes: 11 additions & 17 deletions src/regexp.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include <errno.h>
#include <stdlib.h>
#include "regexp.h"
#include "error.h"
#include "util/ascii.h"
#include "util/debug.h"
#include "util/hashmap.h"
Expand All @@ -12,17 +11,14 @@
// NOLINTNEXTLINE(*-avoid-non-const-global-variables)
static HashMap interned_regexps;

bool regexp_error_msg(const regex_t *re, const char *pattern, int err)
bool regexp_error_msg(ErrorBuffer *ebuf, const regex_t *re, const char *pattern, int err)
{
if (!ebuf) {
return false;
}
char msg[1024];
regerror(err, re, msg, sizeof(msg));
return error_msg_("%s: %s", msg, pattern);
}

bool regexp_compile_internal(regex_t *re, const char *pattern, int flags)
{
int err = regcomp(re, pattern, flags);
return !err || regexp_error_msg(re, pattern, err);
return error_msg(ebuf, "%s: %s", msg, pattern);
}

void regexp_compile_or_fatal_error(regex_t *re, const char *pattern, int flags)
Expand All @@ -46,14 +42,12 @@ bool regexp_exec (
regmatch_t *pmatch,
int flags
) {
// "If REG_STARTEND is specified, pmatch must point to at least one
// regmatch_t (even if nmatch is 0 or REG_NOSUB was specified), to
// hold the input offsets for REG_STARTEND."
// -- https://man.openbsd.org/regex.3
BUG_ON(!pmatch);

// ASan's __interceptor_regexec() doesn't support REG_STARTEND
#if defined(REG_STARTEND) && ASAN_ENABLED == 0 && MSAN_ENABLED == 0
// "If REG_STARTEND is specified, pmatch must point to at least
// one regmatch_t (even if nmatch is 0 or REG_NOSUB was specified),
// to hold the input offsets for REG_STARTEND."
// -- https://man.openbsd.org/regex.3
pmatch[0].rm_so = 0;
pmatch[0].rm_eo = size;
return !regexec(re, buf, nmatch, pmatch, flags | REG_STARTEND);
Expand Down Expand Up @@ -125,7 +119,7 @@ char *regexp_escape(const char *pattern, size_t len)
return buf;
}

const InternedRegexp *regexp_intern(const char *pattern)
const InternedRegexp *regexp_intern(ErrorBuffer *ebuf, const char *pattern)
{
if (pattern[0] == '\0') {
return NULL;
Expand All @@ -139,7 +133,7 @@ const InternedRegexp *regexp_intern(const char *pattern)
ir = xnew(InternedRegexp, 1);
int err = regcomp(&ir->re, pattern, DEFAULT_REGEX_FLAGS | REG_NEWLINE | REG_NOSUB);
if (unlikely(err)) {
regexp_error_msg(&ir->re, pattern, err);
regexp_error_msg(ebuf, &ir->re, pattern, err);
free(ir);
return NULL;
}
Expand Down
53 changes: 27 additions & 26 deletions src/regexp.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <regex.h>
#include <stdbool.h>
#include <stddef.h>
#include "error.h"
#include "util/macros.h"

enum {
Expand Down Expand Up @@ -34,42 +35,42 @@ typedef struct {
char end[8];
} RegexpWordBoundaryTokens;

bool regexp_compile_internal(regex_t *re, const char *pattern, int flags) WARN_UNUSED_RESULT;
void regexp_compile_or_fatal_error(regex_t *re, const char *pattern, int flags) NONNULL_ARGS;
bool regexp_init_word_boundary_tokens(RegexpWordBoundaryTokens *rwbt) NONNULL_ARGS;
bool regexp_error_msg(ErrorBuffer *ebuf, const regex_t *re, const char *pattern, int err) NONNULL_ARG(2, 3);
char *regexp_escape(const char *pattern, size_t len) NONNULL_ARGS WARN_UNUSED_RESULT;
size_t regexp_escapeb(char *buf, size_t buflen, const char *pat, size_t plen) NONNULL_ARG(1);

WARN_UNUSED_RESULT
static inline bool regexp_compile(regex_t *re, const char *pattern, int flags)
const InternedRegexp *regexp_intern(ErrorBuffer *ebuf, const char *pattern) NONNULL_ARG(2) WARN_UNUSED_RESULT;
bool regexp_is_interned(const char *pattern) NONNULL_ARGS;
void free_interned_regexps(void);

WARN_UNUSED_RESULT NONNULL_ARGS
bool regexp_exec (
const regex_t *re,
const char *buf,
size_t size,
size_t nmatch,
regmatch_t *pmatch,
int flags
);

WARN_UNUSED_RESULT NONNULL_ARG(2, 3)
static inline bool regexp_compile(ErrorBuffer *ebuf, regex_t *re, const char *pattern, int flags)
{
return regexp_compile_internal(re, pattern, flags | DEFAULT_REGEX_FLAGS);
int err = regcomp(re, pattern, flags | DEFAULT_REGEX_FLAGS);
return !err || regexp_error_msg(ebuf, re, pattern, err);
}

WARN_UNUSED_RESULT
static inline bool regexp_is_valid(const char *pattern, int flags)
WARN_UNUSED_RESULT NONNULL_ARG(2)
static inline bool regexp_is_valid(ErrorBuffer *ebuf, const char *pattern, int flags)
{
regex_t re;
if (!regexp_compile(&re, pattern, flags | REG_NOSUB)) {
if (!regexp_compile(ebuf, &re, pattern, flags | REG_NOSUB)) {
return false;
}
regfree(&re);
return true;
}

void regexp_compile_or_fatal_error(regex_t *re, const char *pattern, int flags);
bool regexp_init_word_boundary_tokens(RegexpWordBoundaryTokens *rwbt);
bool regexp_error_msg(const regex_t *re, const char *pattern, int err);
char *regexp_escape(const char *pattern, size_t len);
size_t regexp_escapeb(char *buf, size_t buflen, const char *pat, size_t plen);

const InternedRegexp *regexp_intern(const char *pattern);
bool regexp_is_interned(const char *pattern);
void free_interned_regexps(void);

bool regexp_exec (
const regex_t *re,
const char *buf,
size_t size,
size_t nmatch,
regmatch_t *pmatch,
int flags
) WARN_UNUSED_RESULT;

#endif
5 changes: 3 additions & 2 deletions src/replace.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,9 @@ bool reg_replace(View *view, const char *pattern, const char *format, ReplaceFla
re_flags |= (flags & REPLACE_BASIC) ? 0 : DEFAULT_REGEX_FLAGS;

regex_t re;
if (unlikely(!regexp_compile_internal(&re, pattern, re_flags))) {
return false;
int err = regcomp(&re, pattern, re_flags);
if (unlikely(err)) {
return regexp_error_msg(ebuf, &re, pattern, err);
}

BlockIter bi;
Expand Down
21 changes: 11 additions & 10 deletions src/search.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,9 @@ bool search_tag(View *view, const char *pattern)
// DEFAULT_REGEX_FLAGS is not used here because pattern has been
// escaped by parse_ex_pattern() for use as a POSIX BRE
regex_t regex;
if (!regexp_compile_internal(&regex, pattern, REG_NEWLINE)) {
return false;
int err = regcomp(&regex, pattern, REG_NEWLINE);
if (unlikely(err)) {
regexp_error_msg(view->window->editor->err, &regex, pattern, err);
}

BlockIter bi = block_iter(view->buffer);
Expand All @@ -140,7 +141,7 @@ static bool has_upper(const char *str)
return false;
}

static bool update_regex(SearchState *search, SearchCaseSensitivity cs)
static bool update_regex(SearchState *search, ErrorBuffer *ebuf, SearchCaseSensitivity cs)
{
const char *pattern = search->pattern;
bool icase = (cs == CSS_FALSE) || (cs == CSS_AUTO && !has_upper(pattern));
Expand All @@ -154,7 +155,7 @@ static bool update_regex(SearchState *search, SearchCaseSensitivity cs)
search->re_flags = 0;
}

if (regexp_compile(&search->regex, pattern, flags)) {
if (regexp_compile(ebuf, &search->regex, pattern, flags)) {
search->re_flags = flags;
return true;
}
Expand All @@ -180,11 +181,11 @@ void search_set_regexp(SearchState *search, const char *pattern)

bool do_search_next(View *view, SearchState *search, SearchCaseSensitivity cs, bool skip)
{
ErrorBuffer *err = view->window->editor->err;
ErrorBuffer *ebuf = view->window->editor->err;
if (!search->pattern) {
return error_msg(err, "No previous search pattern");
return error_msg(ebuf, "No previous search pattern");
}
if (!update_regex(search, cs)) {
if (!update_regex(search, ebuf, cs)) {
return false;
}

Expand All @@ -196,7 +197,7 @@ bool do_search_next(View *view, SearchState *search, SearchCaseSensitivity cs, b
}
block_iter_bof(&bi);
if (do_search_fwd(view, regex, &bi, false)) {
return info_msg(err, "Continuing at top");
return info_msg(ebuf, "Continuing at top");
}
} else {
size_t cursor_x = block_iter_bol(&bi);
Expand All @@ -205,9 +206,9 @@ bool do_search_next(View *view, SearchState *search, SearchCaseSensitivity cs, b
}
block_iter_eof(&bi);
if (do_search_bwd(view, regex, &bi, -1, false)) {
return info_msg(err, "Continuing at bottom");
return info_msg(ebuf, "Continuing at bottom");
}
}

return error_msg(err, "Pattern '%s' not found", search->pattern);
return error_msg(ebuf, "Pattern '%s' not found", search->pattern);
}
2 changes: 1 addition & 1 deletion test/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ static void test_make_indent(TestContext *ctx)
static void test_get_indent_for_next_line(TestContext *ctx)
{
const char *pattern = "\\{$";
const InternedRegexp *ir = regexp_intern(pattern);
const InternedRegexp *ir = regexp_intern(NULL, pattern);
ASSERT_NONNULL(ir);

LocalOptions options = {
Expand Down
10 changes: 5 additions & 5 deletions test/filetype.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,28 +326,28 @@ static void test_find_ft_dynamic(TestContext *ctx)
const char *ft = "test1";
StringView line = STRING_VIEW_INIT;
EXPECT_FALSE(is_ft(&a, ft));
EXPECT_TRUE(add_filetype(&a, ft, "ext-test", FT_EXTENSION));
EXPECT_TRUE(add_filetype(&a, ft, "ext-test", FT_EXTENSION, NULL));
EXPECT_TRUE(is_ft(&a, ft));
EXPECT_STREQ(find_ft(&a, "/tmp/file.ext-test", line), ft);

ft = "test2";
EXPECT_TRUE(add_filetype(&a, ft, "/zdir/__[A-Z]+$", FT_FILENAME));
EXPECT_TRUE(add_filetype(&a, ft, "/zdir/__[A-Z]+$", FT_FILENAME, NULL));
EXPECT_STREQ(find_ft(&a, "/tmp/zdir/__TESTFILE", line), ft);
EXPECT_STREQ(find_ft(&a, "/tmp/zdir/__testfile", line), NULL);

ft = "test3";
EXPECT_TRUE(add_filetype(&a, ft, "._fiLeName", FT_BASENAME));
EXPECT_TRUE(add_filetype(&a, ft, "._fiLeName", FT_BASENAME, NULL));
EXPECT_STREQ(find_ft(&a, "/tmp/._fiLeName", line), ft);
EXPECT_STREQ(find_ft(&a, "/tmp/._filename", line), NULL);

ft = "test4";
line = strview_from_cstring("!!42");
EXPECT_TRUE(add_filetype(&a, ft, "^!+42$", FT_CONTENT));
EXPECT_TRUE(add_filetype(&a, ft, "^!+42$", FT_CONTENT, NULL));
EXPECT_STREQ(find_ft(&a, NULL, line), ft);

ft = "test5";
line = strview_from_cstring("#!/usr/bin/xyzlang4.2");
EXPECT_TRUE(add_filetype(&a, ft, "xyzlang", FT_INTERPRETER));
EXPECT_TRUE(add_filetype(&a, ft, "xyzlang", FT_INTERPRETER, NULL));
EXPECT_STREQ(find_ft(&a, NULL, line), ft);

EXPECT_TRUE(is_ft(&a, "test1"));
Expand Down
Loading

0 comments on commit 2594dac

Please sign in to comment.