talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

commit 1640c84783b813243dae7c10de23553e6be1f220
parent e789c3054683a2bbda2e551ff9a367b5efec6830
Author: Oliver Lowe <o@olowe.co>
Date:   Mon, 18 Aug 2025 19:48:51 +1000

Quote depth with zig

phew that's better

Diffstat:
Msrc/Makefile.am | 4++--
Msrc/common/utils.c | 44--------------------------------------------
Msrc/common/utils.h | 2--
Msrc/compose.c | 4++--
Msrc/fence/src/fence.h | 1+
Msrc/fence/src/root.zig | 42++++++++++++++++++++++++++++++++++++++++++
Msrc/prefs_common.c | 4++--
Msrc/textview.c | 3++-
8 files changed, 51 insertions(+), 53 deletions(-)

diff --git a/src/Makefile.am b/src/Makefile.am @@ -493,8 +493,8 @@ AM_CPPFLAGS = \ $(NETTLE_CFLAGS) \ $(GPGME_CFLAGS) \ $(LIBETPAN_CPPFLAGS) \ - $(SVG_CFLAGS) \ - $(VALGRIND_CFLAGS) + $(VALGRIND_CFLAGS) \ + -Ifence/zig-out/include #no-unused-function because of bison stuff matcher_parser_lex.$(OBJEXT) : AM_CFLAGS += -Wno-unused-function diff --git a/src/common/utils.c b/src/common/utils.c @@ -956,50 +956,6 @@ static const gchar * line_has_quote_char_last(const gchar * str, const gchar *qu return position; } -gint get_quote_level(const gchar *str, const gchar *quote_chars) -{ - const gchar *first_pos; - const gchar *last_pos; - const gchar *p = str; - gint quote_level = -1; - - /* speed up line processing by only searching to the last '>' */ - if ((first_pos = line_has_quote_char(str, quote_chars)) != NULL) { - /* skip a line if it contains a '<' before the initial '>' */ - if (memchr(str, '<', first_pos - str) != NULL) - return -1; - last_pos = line_has_quote_char_last(first_pos, quote_chars); - } else - return -1; - - while (p <= last_pos) { - while (p < last_pos) { - if (g_ascii_isspace(*p)) - p++; - else - break; - } - - if (strchr(quote_chars, *p)) - quote_level++; - else if (*p != '-' && !g_ascii_isspace(*p) && p <= last_pos) { - /* any characters are allowed except '-','<' and space */ - while (*p != '-' && *p != '<' - && !strchr(quote_chars, *p) - && !g_ascii_isspace(*p) - && p < last_pos) - p++; - if (strchr(quote_chars, *p)) - quote_level++; - else - break; - } - - p++; - } - - return quote_level; -} gint check_line_length(const gchar *str, gint max_chars, gint *line) { diff --git a/src/common/utils.h b/src/common/utils.h @@ -359,8 +359,6 @@ void subst_chars (gchar *str, void subst_for_filename (gchar *str); void subst_for_shellsafe_filename (gchar *str); gboolean is_ascii_str (const gchar *str); -gint get_quote_level (const gchar *str, - const gchar *quote_chars); gint check_line_length (const gchar *str, gint max_chars, gint *line); diff --git a/src/compose.c b/src/compose.c @@ -101,6 +101,7 @@ #include "spell_entry.h" #include "headers.h" #include "file-utils.h" +#include "fence.h" enum { @@ -4405,10 +4406,9 @@ static gboolean compose_beautify_paragraph(Compose *compose, GtkTextIter *par_it quote_str = compose_get_quote_str(buffer, &iter, &quote_len); if (quote_str) { -/* debug_print("compose_beautify_paragraph(): quote_str = '%s'\n", quote_str); */ if (startq_offset == -1) startq_offset = gtk_text_iter_get_offset(&iter); - quotelevel = get_quote_level(quote_str, prefs_common.quote_chars); + quotelevel = quote_depth(quote_str); if (quotelevel > 2) { /* recycle colors */ if (prefs_common.recycle_quote_colors) diff --git a/src/fence/src/fence.h b/src/fence/src/fence.h @@ -1 +1,2 @@ char fence_is_top_level_domain(char *domain); +int quote_depth(char *line); diff --git a/src/fence/src/root.zig b/src/fence/src/root.zig @@ -22,6 +22,48 @@ fn isRfc822Char(c: u8) bool { return true; } +fn quoteDepth(line: []const u8) u8 { + const ln = std.mem.trim(u8, line, &std.ascii.whitespace); + const first = std.mem.indexOfScalar(u8, ln, '>') orelse return 0; + if (first != 0) return 0; + + var depth: u8 = 0; + const last = std.mem.lastIndexOfScalar(u8, ln, '>') orelse return 1; + for (line[first..last+1]) |c| { + if (c == '>') { + if (depth == 0xff) return depth; + depth += 1; + continue; + } + if (std.ascii.isWhitespace(c)) continue; + break; + } + return depth; +} + +export fn quote_depth(line: [*:0]const u8) c_int { + const n = quoteDepth(std.mem.span(line)); + return @as(c_int, n); +} + +test "quote depth" { + const tests = [_]struct{[]const u8, u8}{ + .{">>> hello", 3}, + .{"> >> hello", 3}, + .{" > hello >", 1}, + .{"hello>>", 0}, + .{">> hello >>", 2}, + .{"> \t> hello", 2}, + .{">", 1}, + .{ "xxx > hello >>", 0}, + }; + for (tests) |t| { + const got = quoteDepth(t[0]); + errdefer std.debug.print("quote depth for \"{s}\"\n", .{t[0]}); + try testing.expectEqual(t[1], got); + } +} + test "check domains" { try testing.expect(isTopLevelDomain("com")); try testing.expect(isTopLevelDomain("69yamum") == false); diff --git a/src/prefs_common.c b/src/prefs_common.c @@ -502,9 +502,9 @@ static PrefParam param[] = { {"quote_level1_color", "#0000b3", &prefs_common.color[COL_QUOTE_LEVEL1], P_COLOR, NULL, NULL, NULL}, - {"quote_level2_color", "#0000b3", &prefs_common.color[COL_QUOTE_LEVEL2], + {"quote_level2_color", "#b35a00", &prefs_common.color[COL_QUOTE_LEVEL2], P_COLOR, NULL, NULL, NULL}, - {"quote_level3_color", "#0000b3", &prefs_common.color[COL_QUOTE_LEVEL3], + {"quote_level3_color", "#5ab300", &prefs_common.color[COL_QUOTE_LEVEL3], P_COLOR, NULL, NULL, NULL}, {"enable_bgcolor", "FALSE", &prefs_common.enable_bgcolor, P_BOOL, NULL, NULL, NULL}, diff --git a/src/textview.c b/src/textview.c @@ -62,6 +62,7 @@ #include "hooks.h" #include "avatars.h" #include "file-utils.h" +#include "fence.h" static GdkRGBA quote_colors[3] = { {0, 0, 0, 1}, @@ -1423,7 +1424,7 @@ static void textview_write_line(TextView *textview, const gchar *str, if (prefs_common.enable_color && !textview->is_attachment && line_has_quote_char(buf, prefs_common.quote_chars)) { - real_quotelevel = get_quote_level(buf, prefs_common.quote_chars); + real_quotelevel = quote_depth(buf); quotelevel = real_quotelevel; /* set up the correct foreground color */ if (quotelevel > 2) {