aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2017-01-23 23:18:55 +0100
committerPřemysl Janouch <p.janouch@gmail.com>2017-01-23 23:18:55 +0100
commit6d81ea596bebc41466a697c431481d6b862e9e1a (patch)
treeba435a5a616df12000439ee292f10a6d7e440497
parentfccfd1dd3b3e256db8759cfd6dba7cf6c3952e37 (diff)
downloadhex-6d81ea596bebc41466a697c431481d6b862e9e1a.tar.gz
hex-6d81ea596bebc41466a697c431481d6b862e9e1a.tar.xz
hex-6d81ea596bebc41466a697c431481d6b862e9e1a.zip
Bump liberty
Lots of stuff has been moved into it etc.
-rw-r--r--CMakeLists.txt3
-rw-r--r--cmake/FindNcursesw.cmake17
-rw-r--r--cmake/FindUnistring.cmake10
-rw-r--r--hex.c27
m---------liberty0
-rw-r--r--tui.c266
6 files changed, 6 insertions, 317 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5eff8a6..0f50518 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,14 +18,13 @@ set (project_VERSION "${project_VERSION}.${project_VERSION_MINOR}")
set (project_VERSION "${project_VERSION}.${project_VERSION_PATCH}")
# For custom modules
-set (CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
+set (CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/liberty/cmake)
# Dependencies
find_package (Ncursesw REQUIRED)
find_package (PkgConfig REQUIRED)
find_package (Unistring REQUIRED)
-set (CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/liberty/cmake)
include (AddThreads)
find_package (Termo QUIET NO_MODULE)
diff --git a/cmake/FindNcursesw.cmake b/cmake/FindNcursesw.cmake
deleted file mode 100644
index 88c1d01..0000000
--- a/cmake/FindNcursesw.cmake
+++ /dev/null
@@ -1,17 +0,0 @@
-# Public Domain
-
-find_package (PkgConfig REQUIRED)
-pkg_check_modules (NCURSESW QUIET ncursesw)
-
-# OpenBSD doesn't provide a pkg-config file
-set (required_vars NCURSESW_LIBRARIES)
-if (NOT NCURSESW_FOUND)
- find_library (NCURSESW_LIBRARIES NAMES ncursesw)
- find_path (NCURSESW_INCLUDE_DIRS ncurses.h)
- list (APPEND required_vars NCURSESW_INCLUDE_DIRS)
-endif (NOT NCURSESW_FOUND)
-
-include (FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS (NCURSESW DEFAULT_MSG ${required_vars})
-
-mark_as_advanced (NCURSESW_LIBRARIES NCURSESW_INCLUDE_DIRS)
diff --git a/cmake/FindUnistring.cmake b/cmake/FindUnistring.cmake
deleted file mode 100644
index 6b74efb..0000000
--- a/cmake/FindUnistring.cmake
+++ /dev/null
@@ -1,10 +0,0 @@
-# Public Domain
-
-find_path (UNISTRING_INCLUDE_DIRS unistr.h)
-find_library (UNISTRING_LIBRARIES NAMES unistring libunistring)
-
-include (FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS (UNISTRING DEFAULT_MSG
- UNISTRING_INCLUDE_DIRS UNISTRING_LIBRARIES)
-
-mark_as_advanced (UNISTRING_LIBRARIES UNISTRING_INCLUDE_DIRS)
diff --git a/hex.c b/hex.c
index 6756d8a..ffbf5b1 100644
--- a/hex.c
+++ b/hex.c
@@ -58,6 +58,7 @@ enum
#define LIBERTY_WANT_ASYNC
#define LIBERTY_WANT_PROTO_HTTP
#include "liberty/liberty.c"
+#include "liberty/liberty-tui.c"
#include <locale.h>
#include <termios.h>
@@ -65,7 +66,6 @@ enum
#include <sys/ioctl.h>
#endif // ! TIOCGWINSZ
-#include "tui.c"
#include "termo.h"
#ifdef HAVE_LUA
@@ -101,23 +101,6 @@ update_curses_terminal_size (void)
#endif // HAVE_RESIZETERM && TIOCGWINSZ
}
-// --- Simple array support ----------------------------------------------------
-
-// The most basic helper macros to make working with arrays not suck
-
-#define ARRAY(type, name) type *name; size_t name ## _len, name ## _size;
-#define ARRAY_INIT_SIZED(a, n) \
- BLOCK_START \
- (a) = xcalloc (sizeof *(a), (a ## _size) = (n)); \
- (a ## _len) = 0; \
- BLOCK_END
-#define ARRAY_INIT(a) ARRAY_INIT_SIZED (a, 16)
-#define ARRAY_RESERVE(a, n) \
- BLOCK_START \
- while ((a ## _size) - (a ## _len) < n) \
- (a) = xreallocarray ((a), sizeof *(a), (a ## _size) <<= 1); \
- BLOCK_END
-
// --- Application -------------------------------------------------------------
enum
@@ -1277,8 +1260,8 @@ app_lua_init (void)
luaL_setfuncs (g_ctx.L, app_lua_chunk_table, 0);
lua_pop (g_ctx.L, 1);
- struct str_vector v;
- str_vector_init (&v);
+ struct strv v;
+ strv_init (&v);
get_xdg_data_dirs (&v);
for (size_t i = 0; i < v.len; i++)
{
@@ -1287,7 +1270,7 @@ app_lua_init (void)
app_lua_load_plugins (path);
free (path);
}
- str_vector_free (&v);
+ strv_free (&v);
}
#endif // HAVE_LUA
@@ -1971,7 +1954,7 @@ main (int argc, char *argv[])
while (buf.len < (size_t) size_limit)
{
- str_ensure_space (&buf, 8192);
+ str_reserve (&buf, 8192);
ssize_t n_read = read (input_fd, buf.str + buf.len,
MIN (size_limit - buf.len, buf.alloc - buf.len));
if (!n_read)
diff --git a/liberty b/liberty
-Subproject f53b717f3bba27ca1c42486d3742c91967f3fe9
+Subproject 084e964286bfcd13ee6a25a2ee35dfba9da1072
diff --git a/tui.c b/tui.c
deleted file mode 100644
index d313bcb..0000000
--- a/tui.c
+++ /dev/null
@@ -1,266 +0,0 @@
-// This file is to be moved to liberty, along with FindUnistring.cmake,
-// and then used in both hex and nncmpp
-
-// This file includes some common stuff to build TUI applications with
-
-#include <ncurses.h>
-
-// It is surprisingly hard to find a good library to handle Unicode shenanigans,
-// and there's enough of those for it to be impractical to reimplement them.
-//
-// GLib ICU libunistring utf8proc
-// Decently sized . . x x
-// Grapheme breaks . x . x
-// Character width x . x x
-// Locale handling . . x .
-// Liberal license . x . x
-//
-// Also note that the ICU API is icky and uses UTF-16 for its primary encoding.
-//
-// Currently we're chugging along with libunistring but utf8proc seems viable.
-// Non-Unicode locales can mostly be handled with simple iconv like in sdtui.
-// Similarly grapheme breaks can be guessed at using character width (a basic
-// test here is Zalgo text).
-//
-// None of this is ever going to work too reliably anyway because terminals
-// and Unicode don't go awfully well together. In particular, character cell
-// devices have some problems with double-wide characters.
-
-#include <unistr.h>
-#include <uniwidth.h>
-#include <uniconv.h>
-#include <unicase.h>
-
-// --- Configurable display attributes -----------------------------------------
-
-struct attrs
-{
- short fg; ///< Foreground colour index
- short bg; ///< Background colour index
- chtype attrs; ///< Other attributes
-};
-
-/// Decode attributes in the value using a subset of the git config format,
-/// ignoring all errors since it doesn't affect functionality
-static struct attrs
-attrs_decode (const char *value)
-{
- struct str_vector v;
- str_vector_init (&v);
- cstr_split (value, " ", true, &v);
-
- int colors = 0;
- struct attrs attrs = { -1, -1, 0 };
- for (char **it = v.vector; *it; it++)
- {
- char *end = NULL;
- long n = strtol (*it, &end, 10);
- if (*it != end && !*end && n >= SHRT_MIN && n <= SHRT_MAX)
- {
- if (colors == 0) attrs.fg = n;
- if (colors == 1) attrs.bg = n;
- colors++;
- }
- else if (!strcmp (*it, "bold")) attrs.attrs |= A_BOLD;
- else if (!strcmp (*it, "dim")) attrs.attrs |= A_DIM;
- else if (!strcmp (*it, "ul")) attrs.attrs |= A_UNDERLINE;
- else if (!strcmp (*it, "blink")) attrs.attrs |= A_BLINK;
- else if (!strcmp (*it, "reverse")) attrs.attrs |= A_REVERSE;
-#ifdef A_ITALIC
- else if (!strcmp (*it, "italic")) attrs.attrs |= A_ITALIC;
-#endif // A_ITALIC
- }
- str_vector_free (&v);
- return attrs;
-}
-
-// --- Terminal output ---------------------------------------------------------
-
-// Necessary abstraction to simplify aligned, formatted character output
-
-// This callback you need to implement in the application
-static bool app_is_character_in_locale (ucs4_t ch);
-
-struct row_char
-{
- ucs4_t c; ///< Unicode codepoint
- chtype attrs; ///< Special attributes
- int width; ///< How many cells this takes
-};
-
-struct row_buffer
-{
- // TODO: rewrite this using ARRAY
- struct row_char *chars; ///< Characters
- size_t chars_len; ///< Character count
- size_t chars_alloc; ///< Characters allocated
- int total_width; ///< Total width of all characters
-};
-
-static void
-row_buffer_init (struct row_buffer *self)
-{
- memset (self, 0, sizeof *self);
- self->chars = xcalloc (sizeof *self->chars, (self->chars_alloc = 256));
-}
-
-static void
-row_buffer_free (struct row_buffer *self)
-{
- free (self->chars);
-}
-
-/// Replace invalid chars and push all codepoints to the array w/ attributes.
-static void
-row_buffer_append (struct row_buffer *self, const char *str, chtype attrs)
-{
- // The encoding is only really used internally for some corner cases
- const char *encoding = locale_charset ();
-
- // Note that this function is a hotspot, try to keep it decently fast
- struct row_char current = { .attrs = attrs };
- struct row_char invalid = { .attrs = attrs, .c = '?', .width = 1 };
- const uint8_t *next = (const uint8_t *) str;
- while ((next = u8_next (&current.c, next)))
- {
- if (self->chars_len >= self->chars_alloc)
- self->chars = xreallocarray (self->chars,
- sizeof *self->chars, (self->chars_alloc <<= 1));
-
- current.width = uc_width (current.c, encoding);
- if (current.width < 0 || !app_is_character_in_locale (current.c))
- current = invalid;
-
- self->chars[self->chars_len++] = current;
- self->total_width += current.width;
- }
-}
-
-static void
-row_buffer_append_args (struct row_buffer *self, const char *s, ...)
- ATTRIBUTE_SENTINEL;
-
-static void
-row_buffer_append_args (struct row_buffer *self, const char *s, ...)
-{
- va_list ap;
- va_start (ap, s);
-
- while (s)
- {
- row_buffer_append (self, s, va_arg (ap, chtype));
- s = va_arg (ap, const char *);
- }
- va_end (ap);
-}
-
-static void
-row_buffer_append_buffer (struct row_buffer *self, const struct row_buffer *rb)
-{
- while (self->chars_alloc - self->chars_len < rb->chars_len)
- self->chars = xreallocarray (self->chars,
- sizeof *self->chars, (self->chars_alloc <<= 1));
-
- memcpy (self->chars + self->chars_len, rb->chars,
- rb->chars_len * sizeof *rb->chars);
-
- self->chars_len += rb->chars_len;
- self->total_width += rb->total_width;
-}
-
-/// Pop as many codepoints as needed to free up "space" character cells.
-/// Given the suffix nature of combining marks, this should work pretty fine.
-static int
-row_buffer_pop_cells (struct row_buffer *self, int space)
-{
- int made = 0;
- while (self->chars_len && made < space)
- made += self->chars[--self->chars_len].width;
- self->total_width -= made;
- return made;
-}
-
-static void
-row_buffer_space (struct row_buffer *self, int width, chtype attrs)
-{
- if (width < 0)
- return;
-
- while (self->chars_len + width >= self->chars_alloc)
- self->chars = xreallocarray (self->chars,
- sizeof *self->chars, (self->chars_alloc <<= 1));
-
- struct row_char space = { .attrs = attrs, .c = ' ', .width = 1 };
- self->total_width += width;
- while (width-- > 0)
- self->chars[self->chars_len++] = space;
-}
-
-static void
-row_buffer_ellipsis (struct row_buffer *self, int target)
-{
- if (self->total_width <= target
- || !row_buffer_pop_cells (self, self->total_width - target))
- return;
-
- // We use attributes from the last character we've removed,
- // assuming that we don't shrink the array (and there's no real need)
- ucs4_t ellipsis = 0x2026; // …
- if (app_is_character_in_locale (ellipsis))
- {
- if (self->total_width >= target)
- row_buffer_pop_cells (self, 1);
- if (self->total_width + 1 <= target)
- row_buffer_append (self, "…", self->chars[self->chars_len].attrs);
- }
- else if (target >= 3)
- {
- if (self->total_width >= target)
- row_buffer_pop_cells (self, 3);
- if (self->total_width + 3 <= target)
- row_buffer_append (self, "...", self->chars[self->chars_len].attrs);
- }
-}
-
-static void
-row_buffer_align (struct row_buffer *self, int target, chtype attrs)
-{
- row_buffer_ellipsis (self, target);
- row_buffer_space (self, target - self->total_width, attrs);
-}
-
-static void
-row_buffer_print (uint32_t *ucs4, chtype attrs)
-{
- // This assumes that we can reset the attribute set without consequences
- char *str = u32_strconv_to_locale (ucs4);
- if (str)
- {
- attrset (attrs);
- addstr (str);
- attrset (0);
- free (str);
- }
-}
-
-static void
-row_buffer_flush (struct row_buffer *self)
-{
- if (!self->chars_len)
- return;
-
- // We only NUL-terminate the chunks because of the libunistring API
- uint32_t chunk[self->chars_len + 1], *insertion_point = chunk;
- for (size_t i = 0; i < self->chars_len; i++)
- {
- struct row_char *iter = self->chars + i;
- if (i && iter[0].attrs != iter[-1].attrs)
- {
- row_buffer_print (chunk, iter[-1].attrs);
- insertion_point = chunk;
- }
- *insertion_point++ = iter->c;
- *insertion_point = 0;
- }
- row_buffer_print (chunk, self->chars[self->chars_len - 1].attrs);
-}