160 lines
5.6 KiB
Diff
160 lines
5.6 KiB
Diff
From ae57646896bd218b1c5c3087d8937da635fb9ef7 Mon Sep 17 00:00:00 2001
|
|
From: Mark Nudelman <markn@greenwoodsoftware.com>
|
|
Date: Wed, 12 Oct 2022 09:35:22 -0700
|
|
Subject: [PATCH 21/48] lesstest: add support for combining and composing
|
|
chars.
|
|
|
|
---
|
|
lesstest/display.c | 1 +
|
|
lesstest/lt_screen.c | 11 ++++++++---
|
|
lesstest/parse.c | 1 +
|
|
lesstest/pipeline.c | 4 ++--
|
|
lesstest/run.c | 5 +++--
|
|
lesstest/unicode.c | 23 +++++++++++++++++++++++
|
|
lesstest/wchar.h | 2 ++
|
|
7 files changed, 40 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/lesstest/display.c b/lesstest/display.c
|
|
index 5243337..54ae7c5 100644
|
|
--- a/lesstest/display.c
|
|
+++ b/lesstest/display.c
|
|
@@ -119,6 +119,7 @@ void display_screen_debug(const byte* img, int imglen, int screen_width, int scr
|
|
}
|
|
|
|
void print_strings(const char* title, char* const* strings) {
|
|
+ if (1) return; ///
|
|
fprintf(stderr, "%s:\n", title);
|
|
char* const* s;
|
|
for (s = strings; *s != NULL; ++s) {
|
|
diff --git a/lesstest/lt_screen.c b/lesstest/lt_screen.c
|
|
index 4bc1c50..6677650 100644
|
|
--- a/lesstest/lt_screen.c
|
|
+++ b/lesstest/lt_screen.c
|
|
@@ -277,10 +277,15 @@ static int exec_esc(wchar ch) {
|
|
static int add_char(wchar ch) {
|
|
//if (verbose) fprintf(stderr, "add (%c) %lx at %d,%d\n", (char)ch, (long)ch, screen.cx, screen.cy);
|
|
screen_char_set(screen.cx, screen.cy, ch, screen.curr_attr, screen.curr_color);
|
|
- int fits = screen_incr(&screen.cx, &screen.cy);
|
|
- if (fits && is_wide_char(ch)) {
|
|
- screen_char_set(screen.cx, screen.cy, 0, 0, NULL_COLOR);
|
|
+ int fits = 1;
|
|
+ int zero_width = (is_composing_char(ch) ||
|
|
+ (screen.cx > 0 && is_combining_char(screen_char(screen.cx-1,screen.cy)->ch, ch)));
|
|
+ if (!zero_width) {
|
|
fits = screen_incr(&screen.cx, &screen.cy);
|
|
+ if (fits && is_wide_char(ch)) {
|
|
+ screen_char_set(screen.cx, screen.cy, 0, 0, NULL_COLOR);
|
|
+ fits = screen_incr(&screen.cx, &screen.cy);
|
|
+ }
|
|
}
|
|
if (!fits) { // Wrap at bottom of screen = scroll
|
|
screen.cx = 0;
|
|
diff --git a/lesstest/parse.c b/lesstest/parse.c
|
|
index 3d79a83..d1e8c74 100644
|
|
--- a/lesstest/parse.c
|
|
+++ b/lesstest/parse.c
|
|
@@ -100,6 +100,7 @@ int read_zline(FILE* fd, char* line, int line_len) {
|
|
return nread;
|
|
}
|
|
|
|
+// Read the header of a .lt file (up to the R line).
|
|
TestSetup* read_test_setup(FILE* fd, const char* less) {
|
|
TestSetup* setup = new_test_setup();
|
|
int hdr_complete = 0;
|
|
diff --git a/lesstest/pipeline.c b/lesstest/pipeline.c
|
|
index 4122f4a..01fe15d 100644
|
|
--- a/lesstest/pipeline.c
|
|
+++ b/lesstest/pipeline.c
|
|
@@ -42,7 +42,7 @@ static void become_child_less(char* less, int argc, char* const* argv, char* con
|
|
less_argv[less_argc++] = (argc > 1 || tempfile == NULL) ? arg : (char*) tempfile;
|
|
}
|
|
less_argv[less_argc] = NULL;
|
|
- //if (verbose) { print_strings("less argv", less_argv); print_strings("less envp", envp); }
|
|
+ if (verbose) { print_strings("less argv", less_argv); print_strings("less envp", envp); }
|
|
execve(less, less_argv, envp);
|
|
fprintf(stderr, "cannot exec %s: %s\n", less, strerror(errno));
|
|
exit(1);
|
|
@@ -74,7 +74,7 @@ static void become_child_screen(char* lt_screen, int screen_width, int screen_he
|
|
if (1)
|
|
screen_argv[screen_argc++] = "-q";
|
|
screen_argv[screen_argc] = NULL;
|
|
- //if (verbose) print_strings("screen argv", screen_argv);
|
|
+ if (verbose) print_strings("screen argv", screen_argv);
|
|
char* const screen_envp[] = { NULL };
|
|
execve(lt_screen, screen_argv, screen_envp);
|
|
fprintf(stderr, "cannot exec %s: %s\n", lt_screen, strerror(errno));
|
|
diff --git a/lesstest/run.c b/lesstest/run.c
|
|
index 25850d5..f35781f 100644
|
|
--- a/lesstest/run.c
|
|
+++ b/lesstest/run.c
|
|
@@ -178,7 +178,8 @@ static int run_test(TestSetup* setup, FILE* testfd) {
|
|
return ok;
|
|
}
|
|
|
|
-// Should run in empty directory.
|
|
+// Should be run in an empty temp directory;
|
|
+// it creates its own files in the current directory.
|
|
int run_testfile(const char* testfile, const char* less) {
|
|
FILE* testfd = fopen(testfile, "r");
|
|
if (testfd == NULL) {
|
|
@@ -187,7 +188,7 @@ int run_testfile(const char* testfile, const char* less) {
|
|
}
|
|
int tests = 0;
|
|
int fails = 0;
|
|
- for (;;) {
|
|
+ for (;;) { // might be multiple tests in one file
|
|
TestSetup* setup = read_test_setup(testfd, less);
|
|
if (setup == NULL)
|
|
break;
|
|
diff --git a/lesstest/unicode.c b/lesstest/unicode.c
|
|
index beb9bfc..c2320a8 100644
|
|
--- a/lesstest/unicode.c
|
|
+++ b/lesstest/unicode.c
|
|
@@ -5,6 +5,15 @@ typedef struct wchar_range { wchar first, last; } wchar_range;
|
|
static wchar_range wide_chars[] = {
|
|
#include "../wide.uni"
|
|
};
|
|
+static wchar_range compose_table[] = {
|
|
+#include "../compose.uni"
|
|
+};
|
|
+static wchar_range fmt_table[] = {
|
|
+#include "../fmt.uni"
|
|
+};
|
|
+static wchar_range comb_table[] = {
|
|
+ {0x0644,0x0622}, {0x0644,0x0623}, {0x0644,0x0625}, {0x0644,0x0627},
|
|
+};
|
|
|
|
static int is_in_table(wchar ch, wchar_range table[], int count) {
|
|
if (ch < table[0].first)
|
|
@@ -26,3 +35,17 @@ static int is_in_table(wchar ch, wchar_range table[], int count) {
|
|
int is_wide_char(wchar ch) {
|
|
return is_in_table(ch, wide_chars, countof(wide_chars));
|
|
}
|
|
+
|
|
+int is_composing_char(wchar ch) {
|
|
+ return is_in_table(ch, compose_table, countof(compose_table)) ||
|
|
+ is_in_table(ch, fmt_table, countof(fmt_table));
|
|
+}
|
|
+
|
|
+int is_combining_char(wchar ch1, wchar ch2) {
|
|
+ for (int i = 0; i < countof(comb_table); i++) {
|
|
+ if (ch1 == comb_table[i].first &&
|
|
+ ch2 == comb_table[i].last)
|
|
+ return 1;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
diff --git a/lesstest/wchar.h b/lesstest/wchar.h
|
|
index 0ffd541..84af5ee 100644
|
|
--- a/lesstest/wchar.h
|
|
+++ b/lesstest/wchar.h
|
|
@@ -3,3 +3,5 @@ void store_wchar(byte** p, wchar ch);
|
|
wchar load_wchar(const byte** p);
|
|
wchar read_wchar(int fd);
|
|
int is_wide_char(wchar ch);
|
|
+int is_composing_char(wchar ch);
|
|
+int is_combining_char(wchar ch1, wchar ch2);
|
|
--
|
|
2.27.0
|
|
|