diff options
| author | Berke Güzel <wenekar1@gmail.com> | 2026-10-13 12:50:54 +0300 |
|---|---|---|
| committer | Berke Güzel <wenekar1@gmail.com> | 2026-10-13 12:50:54 +0300 |
| commit | a0fefd3856a4f03be0abbc51f7a9a0416db69eb5 (patch) | |
| tree | a06737c8fcea5ee6d7d20223e9c36272e66b9e26 | |
| parent | 71f0b19476adb170c24d6a8de4ab3133701b1aeb (diff) | |
Make term standalone library and export Meson dependencies
| -rw-r--r-- | .gitignore | 6 | ||||
| -rw-r--r-- | LICENSE | 21 | ||||
| -rw-r--r-- | meson.build | 36 | ||||
| -rw-r--r-- | src/kernels.h | 2 | ||||
| -rw-r--r-- | src/meson.build | 5 | ||||
| -rw-r--r-- | src/text.c | 84 | ||||
| -rw-r--r-- | tests/extern/kitty/screen.py | 2 | ||||
| -rw-r--r-- | tests/meson.build | 6 |
8 files changed, 111 insertions, 51 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..90e08a6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +build*/ +.cache/ +*.o +*.a +*.so +*.dylib @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Berke Güzel + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/meson.build b/meson.build index a78fa68..d23c0b4 100644 --- a/meson.build +++ b/meson.build @@ -1,8 +1,13 @@ project('term', 'c', version: '0.1.0', + license: 'MIT', + license_files: 'LICENSE', meson_version: '>=1.1.0', default_options: [ 'c_std=c11', + 'buildtype=release', + 'optimization=3', + 'b_lto=true', 'warning_level=3', 'b_ndebug=if-release', ], @@ -23,7 +28,7 @@ subdir('src') term_dep = declare_dependency( include_directories: term_inc, - link_with: term_headless_lib.get_static_lib(), + link_with: term_lib.get_static_lib(), dependencies: m_dep, ) meson.override_dependency('term', term_dep) @@ -31,7 +36,7 @@ meson.override_dependency('term', term_dep) # The private headers too. Only the term tests and benchmarks use it. term_internal_dep = declare_dependency( include_directories: [term_inc, term_private_inc], - link_with: term_headless_lib.get_static_lib(), + link_with: term_lib.get_static_lib(), dependencies: m_dep, ) @@ -41,8 +46,35 @@ term_test_dep = declare_dependency( include_directories: include_directories('tests/helpers'), dependencies: term_dep, ) +meson.override_dependency('term-test', term_test_dep) + +install_headers( + 'include/term/term.h', + 'include/term/term_input.h', + 'include/term/term_types.h', + subdir: 'term', +) + +install_headers( + 'include/term/unicode/grapheme.h', + 'include/term/unicode/unicode.h', + 'include/term/unicode/unicode_data.inc', + 'include/term/unicode/utf8.h', + 'include/term/unicode/width.h', + subdir: 'term/unicode', +) + +pkg = import('pkgconfig') +pkg.generate( + term_lib.get_shared_lib(), + name: 'term', + description: 'Headless terminal emulator core library', + version: meson.project_version(), + subdirs: ['.', 'term'], +) if get_option('tests') subdir('tests') subdir('benchmarks') endif + diff --git a/src/kernels.h b/src/kernels.h index 48088b5..45d25b7 100644 --- a/src/kernels.h +++ b/src/kernels.h @@ -88,7 +88,7 @@ static inline size_t scan_printable_span(const char *buf, size_t len, return scan_printable_span_avx512(buf, len, hi); #endif #if defined(TERM_KERNEL_AVX2) - if (len >= 64 && term_use_avx2()) + if (len >= 32 && term_use_avx2()) return scan_printable_span_avx2(buf, len, hi); #endif size_t i = 0; diff --git a/src/meson.build b/src/meson.build index 6eaf0d4..694ee0e 100644 --- a/src/meson.build +++ b/src/meson.build @@ -2,7 +2,7 @@ subdir('osc') # The x86-64 SIMD kernels pick their level at run time (see simd.h), so the # library needs no ISA flags. -march in c_args sets the lowest level. -term_headless_lib = both_libraries('term_headless', +term_lib = both_libraries('term', 'core.c', 'escape.c', 'fastcsi.c', @@ -23,5 +23,6 @@ term_headless_lib = both_libraries('term_headless', include_directories: term_private_inc, dependencies: [m_dep], gnu_symbol_visibility: 'hidden', - install: false + install: true ) + @@ -216,48 +216,6 @@ static void term_feed_inner(struct term *t, const char *buf, size_t len, unsigne } unsigned char ch = (unsigned char)buf[i]; - if ((ch < 0x20 || ch == 0x7f) && t->state == ST_GROUND) - term_text_utf8_interrupt(t); - - if (TERM_EXPECT(ch < 0x20 && t->state == ST_GROUND && - ch != 0x1b && ch != '\n' && ch != '\r' && ch != '\b' && ch != '\t' && - ch != 0x0e && ch != 0x0f && ch != 0x07 && ch != 0x0b && - ch != 0x0c, 0)) { - continue; - } - - if (TERM_EXPECT(ch == 0x1b && t->state == ST_GROUND && - t->utf8_state == UTF8_ACCEPT && i + 1 < len && - buf[i + 1] == '[' && !t->insert_mode && - !t->lr_margin_mode && !t->graphics, 0)) { - int fast = term_try_fast_csi(t, buf + i + 2, len - i - 2); - if (fast > 0) { - i += 1 + (size_t)fast; - continue; - } - t->state = ST_CSI; - csi_parser_reset(&t->csi_parser); - i += 1 + term_escape_csi(t, buf + i + 2, len - i - 2); - continue; - } - - if (TERM_EXPECT(t->state == ST_GROUND && ch == '\n', 0)) { - size_t end = i + 1 + scan_byte_run(buf + i + 1, len - i - 1, '\n'); - if (term_lnm(t)) sc_cr(t); - sc_linefeed(t, end - i); - i = end - 1; - continue; - } - - if (TERM_EXPECT(t->state == ST_GROUND && ch == '\r' && - i + 1 < len && buf[i + 1] == '\n', 0)) { - size_t end = i + 2 + scan_crlf_pairs(buf + i + 2, len - i - 2); - sc_cr(t); - sc_linefeed(t, (end - i) / 2); - i = end - 1; - continue; - } - if (TERM_EXPECT(ch >= 0x20 && ch < 0x7f && !t->insert_mode && !t->lr_margin_mode && t->state == ST_GROUND && !t->graphics && t->utf8_state == UTF8_ACCEPT, 1)) { @@ -307,6 +265,48 @@ static void term_feed_inner(struct term *t, const char *buf, size_t len, unsigne continue; } + if ((ch < 0x20 || ch == 0x7f) && t->state == ST_GROUND) + term_text_utf8_interrupt(t); + + if (TERM_EXPECT(ch < 0x20 && t->state == ST_GROUND && + ch != 0x1b && ch != '\n' && ch != '\r' && ch != '\b' && ch != '\t' && + ch != 0x0e && ch != 0x0f && ch != 0x07 && ch != 0x0b && + ch != 0x0c, 0)) { + continue; + } + + if (TERM_EXPECT(ch == 0x1b && t->state == ST_GROUND && + t->utf8_state == UTF8_ACCEPT && i + 1 < len && + buf[i + 1] == '[' && !t->insert_mode && + !t->lr_margin_mode && !t->graphics, 0)) { + int fast = term_try_fast_csi(t, buf + i + 2, len - i - 2); + if (fast > 0) { + i += 1 + (size_t)fast; + continue; + } + t->state = ST_CSI; + csi_parser_reset(&t->csi_parser); + i += 1 + term_escape_csi(t, buf + i + 2, len - i - 2); + continue; + } + + if (TERM_EXPECT(t->state == ST_GROUND && ch == '\n', 0)) { + size_t end = i + 1 + scan_byte_run(buf + i + 1, len - i - 1, '\n'); + if (term_lnm(t)) sc_cr(t); + sc_linefeed(t, end - i); + i = end - 1; + continue; + } + + if (TERM_EXPECT(t->state == ST_GROUND && ch == '\r' && + i + 1 < len && buf[i + 1] == '\n', 0)) { + size_t end = i + 2 + scan_crlf_pairs(buf + i + 2, len - i - 2); + sc_cr(t); + sc_linefeed(t, (end - i) / 2); + i = end - 1; + continue; + } + if (TERM_EXPECT(ch == '\r' && t->state == ST_GROUND, 0)) { sc_cr(t); continue; diff --git a/tests/extern/kitty/screen.py b/tests/extern/kitty/screen.py index 80f8e71..cc7289b 100644 --- a/tests/extern/kitty/screen.py +++ b/tests/extern/kitty/screen.py @@ -13,7 +13,7 @@ import os # Shared library loading # --------------------------------------------------------------------------- -_lib = ctypes.CDLL(os.environ.get('WSAP_KITTY_LIB', os.path.join(os.path.dirname(__file__), 'libterm.so'))) +_lib = ctypes.CDLL(os.environ.get('WSAP_KITTY_LIB', os.path.join(os.path.dirname(__file__), 'libkitty_bridge.so'))) # struct term_cell { uint32_t text, fg, bg; uint16_t attrs; uint8_t width, reserved; } class TermCell(ctypes.Structure): diff --git a/tests/meson.build b/tests/meson.build index 0aa78e8..4cf559c 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -95,9 +95,9 @@ foreach entry : term_tests endforeach test('term-symbols-test', bash, - args: [files('symbols_test.sh'), term_headless_lib.get_static_lib(), + args: [files('symbols_test.sh'), term_lib.get_static_lib(), meson.project_source_root() / 'include' / 'term', - term_headless_lib.get_shared_lib()], + term_lib.get_shared_lib()], env: test_env, suite: 'unit', ) @@ -119,7 +119,7 @@ kitty_tests = get_option('kitty').require( ) term_kitty_tests = kitty_tests.allowed() if term_kitty_tests - kitty_bridge = shared_library('term', 'extern/kitty/screen_bridge.c', + kitty_bridge = shared_library('kitty_bridge', 'extern/kitty/screen_bridge.c', dependencies: term_internal_dep, ) kitty_env = environment() |
