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:
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, "e_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) {