чување 31dcd2bcf4114cf0e16827181252faa1126bc58b
родитељ 83e5082fdcd3661c838f93e559032e055803a1cb
Аутор: Страхиња Радић <sr@strahinja.org>
Датум: Thu, 11 Jun 2026 09:22:05 +0000
Add -O and -o; handle invalid UTF-8 similar to table(1)
Diffstat:
измењених датотека: 5, додавања: 47(+), брисања: 17(-)
diff --git a/TODO b/TODO
@@ -3,8 +3,9 @@ TODO
[~] Code optimization (struct coord...)
-[ ] Add changes from table(1) regarding the drawing of invalid UTF-8.
+[x] Add changes from table(1) regarding the drawing of invalid UTF-8.
That would perhaps also make open_binary obsolete.
+ - Add -O/-o parameters
[ ] Implement proper drawing of wide characters covering dialogs, now
that termbox has a function for getting characters from the display
diff --git a/sled.1.in b/sled.1.in
@@ -16,6 +16,8 @@
.Nm
.Op Fl B | Fl \-no\-backup
.Op Fl b | Fl \-backup
+.Op Fl O | Fl \-no\-open\-binary
+.Op Fl o | Fl \-open\-binary
.Ar filename
.Sh DESCRIPTION
.Nm
@@ -29,6 +31,14 @@ This option overrides the setting in
Enables backups.
This option overrides the setting in
.Pa config.h .
+.It Fl O , \-no\-open\-binary
+Disables opening of binary files (containing the NUL character).
+This option overrides the setting in
+.Pa config.h .
+.It Fl o , \-open\-binary
+Enables opening of binary files (containing the NUL character).
+This option overrides the setting in
+.Pa config.h .
.It Fl h , \-help
Show option summary.
.It Fl V , \-full\-version
diff --git a/sled.c b/sled.c
@@ -2901,7 +2901,9 @@ main_options_loop:
{
printf("Usage:\t%s -h | --help | -V | --full-version | "
"-v | --version\n"
- "\t%s [-B | --no-backup] [-b | --backup] filename\n",
+ "\t%s [-B | --no-backup] [-b | --backup] "
+ "[-O | --no-open-binary] [-o | --open-binary] "
+ "filename\n",
PROGRAM_NAME, PROGRAM_NAME);
return 0;
}
@@ -2941,6 +2943,20 @@ main_options_loop:
optind++;
goto main_options_loop;
}
+ else if (!strcmp(argv[optind], "-O")
+ || !strcmp(argv[optind], "--no-open-binary"))
+ {
+ open_binary = 0;
+ optind++;
+ goto main_options_loop;
+ }
+ else if (!strcmp(argv[optind], "-o")
+ || !strcmp(argv[optind], "--open-binary"))
+ {
+ open_binary = 1;
+ optind++;
+ goto main_options_loop;
+ }
/*
* Chicken and egg problem: to get fpathconf(dirfd, _PC_PATH_MAX)
diff --git a/util.c b/util.c
@@ -18,32 +18,33 @@
#define B_FULL " \v\t()[]{},.;:/\\"
size_t
-u8_string_to_unicode(uint32_t* us, const char* s, const size_t max)
+u8_string_to_unicode(uint32_t* us, const char* s, const ssize_t max)
{
uint32_t uch;
uint32_t* pus = us;
+ const char* ps = s;
int u8_len = 0;
size_t added = 0;
assert(s != NULL);
- while (*s)
+ while (ps - s < max && *ps)
{
- u8_len = tb_utf8_char_to_unicode(&uch, s);
- if (added + 1 > max)
- break;
- if (u8_len > 0)
+ u8_len = tb_utf8_char_to_unicode(&uch, ps);
+ if (!u8_len)
{
- *pus++ = uch;
- s += u8_len;
- added++;
+ uch = U32_REPL_CHAR;
+ u8_len = 1;
}
+ added++;
+ ps += u8_len;
+ *pus++ = uch;
}
- *pus++ = 0;
+ *pus = 0;
return added;
}
size_t
-unicode_string_to_u8(char* s, const uint32_t* us, const size_t max)
+unicode_string_to_u8(char* s, const uint32_t* us, const ssize_t max)
{
char ch[8];
char* ps = NULL;
@@ -53,10 +54,10 @@ unicode_string_to_u8(char* s, const uint32_t* us, const size_t max)
assert((s != NULL) && (us != NULL));
ps = s;
- while (*pus)
+ while (pus - us < max && *pus)
{
len = tb_utf8_unicode_to_char(ch, *pus);
- if (added + 1 >= max)
+ if (len < 0)
return added;
memccpy(ps, ch, 0, len);
ps += len;
diff --git a/util.h b/util.h
@@ -17,6 +17,8 @@
#define UNUSED(x) ((void)(x))
/* clang-format on */
+#define U32_REPL_CHAR ((uint32_t)0xFFFD)
+
#define MEMCCPY(to, from, tolen, temp) \
do \
{ \
@@ -116,8 +118,8 @@ enum {
enum { ACT_IDLE, ACT_WRITING, ACT_READING, ACT_WRAPPING };
-size_t u8_string_to_unicode(uint32_t* us, const char* s, const size_t max);
-size_t unicode_string_to_u8(char* s, const uint32_t* us, const size_t max);
+size_t u8_string_to_unicode(uint32_t* us, const char* s, const ssize_t max);
+size_t unicode_string_to_u8(char* s, const uint32_t* us, const ssize_t max);
int u32_has_nonblanks(const uint32_t* s);
uint32_t* u32_memccpy(uint32_t* dst, const uint32_t* src, uint32_t c,
size_t len);