diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2021-06-02 19:18:10 +0200 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2021-06-02 19:18:10 +0200 |
commit | ffbc962c0a241f7d70b48162f92f2023fe6c043f (patch) | |
tree | d97dd89b680162b935cb8aae223405ffd0d9e16a /src/scintilla.c | |
parent | 3939a60c73694d5b76d60f61354e0aeb60b270c6 (diff) | |
download | sciteco-ffbc962c0a241f7d70b48162f92f2023fe6c043f.tar.gz |
renamed scintilla.[ch] to symbols.[ch]: fixes builds on case-insensitive file systems
* There is a "Scintilla.h" as well.
* should fix macOS and builds on native Windows hosts
* It wasn't practical to refer to the Scintilla includes using paths since
the Scintilla location is configurable (--with-scintilla).
So we'd have to write something like #include <include/Scintilla.h>.
For Scinterm we cannot avoid collisions neither as its path is also
configurable (--with-scinterm).
Effectively, we must prevent name clashes across SciTECO and all
of Scintilla and Scinterm.
Diffstat (limited to 'src/scintilla.c')
-rw-r--r-- | src/scintilla.c | 349 |
1 files changed, 0 insertions, 349 deletions
diff --git a/src/scintilla.c b/src/scintilla.c deleted file mode 100644 index f58b6f4..0000000 --- a/src/scintilla.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Copyright (C) 2012-2021 Robin Haberkorn - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <string.h> - -#include <glib.h> - -#include "sciteco.h" -#include "string-utils.h" -#include "error.h" -#include "parser.h" -#include "core-commands.h" -#include "undo.h" -#include "expressions.h" -#include "interface.h" -#include "scintilla.h" - -teco_symbol_list_t teco_symbol_list_scintilla = {NULL, 0}; -teco_symbol_list_t teco_symbol_list_scilexer = {NULL, 0}; - -/* - * FIXME: Could be static. - */ -TECO_DEFINE_UNDO_OBJECT_OWN(scintilla_message, teco_machine_scintilla_t, /* don't delete */); - -/** @memberof teco_symbol_list_t */ -void -teco_symbol_list_init(teco_symbol_list_t *ctx, const teco_symbol_entry_t *entries, gint size, - gboolean case_sensitive) -{ - memset(ctx, 0, sizeof(*ctx)); - ctx->entries = entries; - ctx->size = size; - ctx->cmp_fnc = case_sensitive ? strncmp : g_ascii_strncasecmp; -} - -/** - * @note Since symbol lists are presorted constant arrays we can do a simple - * binary search. - * This does not use bsearch() since we'd have to prepend `prefix` in front of - * the name. - * - * @memberof teco_symbol_list_t - */ -gint -teco_symbol_list_lookup(teco_symbol_list_t *ctx, const gchar *name, const gchar *prefix) -{ - gsize name_len = strlen(name); - - gsize prefix_skip = strlen(prefix); - if (!ctx->cmp_fnc(name, prefix, prefix_skip)) - prefix_skip = 0; - - gint left = 0; - gint right = ctx->size - 1; - - while (left <= right) { - gint cur = left + (right-left)/2; - gint cmp = ctx->cmp_fnc(ctx->entries[cur].name + prefix_skip, - name, name_len + 1); - - if (!cmp) - return ctx->entries[cur].value; - - if (cmp > 0) - right = cur-1; - else /* cmp < 0 */ - left = cur+1; - } - - return -1; -} - -/** - * Auto-complete a Scintilla symbol. - * - * @param ctx The symbol list. - * @param symbol The symbol to auto-complete or NULL. - * @param insert String to initialize with the completion. - * @return TRUE in case of an unambiguous completion. - * - * @memberof teco_symbol_list_t - */ -gboolean -teco_symbol_list_auto_complete(teco_symbol_list_t *ctx, const gchar *symbol, teco_string_t *insert) -{ - memset(insert, 0, sizeof(*insert)); - - if (!symbol) - symbol = ""; - gsize symbol_len = strlen(symbol); - - if (G_UNLIKELY(!ctx->list)) - for (gint i = ctx->size; i; i--) - ctx->list = g_list_prepend(ctx->list, (gchar *)ctx->entries[i-1].name); - - /* NOTE: element data must not be freed */ - g_autoptr(GList) glist = g_list_copy(ctx->list); - guint glist_len = 0; - - gsize prefix_len = 0; - - for (GList *entry = g_list_first(glist), *next = g_list_next(entry); - entry != NULL; - entry = next, next = entry ? g_list_next(entry) : NULL) { - if (g_ascii_strncasecmp(entry->data, symbol, symbol_len) != 0) { - glist = g_list_delete_link(glist, entry); - continue; - } - - teco_string_t glist_str; - glist_str.data = (gchar *)glist->data + symbol_len; - glist_str.len = strlen(glist_str.data); - - gsize len = teco_string_casediff(&glist_str, (gchar *)entry->data + symbol_len, - strlen(entry->data) - symbol_len); - if (!prefix_len || len < prefix_len) - prefix_len = len; - - glist_len++; - } - - if (prefix_len > 0) { - teco_string_init(insert, (gchar *)glist->data + symbol_len, prefix_len); - } else if (glist_len > 1) { - for (GList *entry = g_list_first(glist); - entry != NULL; - entry = g_list_next(entry)) { - teco_interface_popup_add(TECO_POPUP_PLAIN, entry->data, - strlen(entry->data), FALSE); - } - - teco_interface_popup_show(); - } - - return glist_len == 1; -} - -/* - * Command states - */ - -/* - * FIXME: This state could be static. - */ -TECO_DECLARE_STATE(teco_state_scintilla_lparam); - -static gboolean -teco_scintilla_parse_symbols(teco_machine_scintilla_t *scintilla, const teco_string_t *str, GError **error) -{ - if (teco_string_contains(str, '\0')) { - g_set_error_literal(error, TECO_ERROR, TECO_ERROR_FAILED, - "Scintilla symbol names must not contain null-byte"); - return FALSE; - } - - g_auto(GStrv) symbols = g_strsplit(str->data, ",", -1); - - if (!symbols[0]) - return TRUE; - if (*symbols[0]) { - gint v = teco_symbol_list_lookup(&teco_symbol_list_scintilla, symbols[0], "SCI_"); - if (v < 0) { - g_set_error(error, TECO_ERROR, TECO_ERROR_FAILED, - "Unknown Scintilla message symbol \"%s\"", - symbols[0]); - return FALSE; - } - scintilla->iMessage = v; - } - - if (!symbols[1]) - return TRUE; - if (*symbols[1]) { - gint v = teco_symbol_list_lookup(&teco_symbol_list_scilexer, symbols[1], ""); - if (v < 0) { - g_set_error(error, TECO_ERROR, TECO_ERROR_FAILED, - "Unknown Scintilla Lexer symbol \"%s\"", - symbols[1]); - return FALSE; - } - scintilla->wParam = v; - } - - if (!symbols[2]) - return TRUE; - if (*symbols[2]) { - gint v = teco_symbol_list_lookup(&teco_symbol_list_scilexer, symbols[2], ""); - if (v < 0) { - g_set_error(error, TECO_ERROR, TECO_ERROR_FAILED, - "Unknown Scintilla Lexer symbol \"%s\"", - symbols[2]); - return FALSE; - } - scintilla->lParam = v; - } - - return TRUE; -} - -static teco_state_t * -teco_state_scintilla_symbols_done(teco_machine_main_t *ctx, const teco_string_t *str, GError **error) -{ - if (ctx->mode > TECO_MODE_NORMAL) - return &teco_state_scintilla_lparam; - - /* - * NOTE: This is more memory efficient than pushing the individual - * members of teco_machine_scintilla_t and we won't need to define - * undo methods for the Scintilla types. - */ - if (ctx->parent.must_undo) - teco_undo_object_scintilla_message_push(&ctx->scintilla); - memset(&ctx->scintilla, 0, sizeof(ctx->scintilla)); - - if ((str->len > 0 && !teco_scintilla_parse_symbols(&ctx->scintilla, str, error)) || - !teco_expressions_eval(FALSE, error)) - return NULL; - - teco_int_t value; - - if (!ctx->scintilla.iMessage) { - if (!teco_expressions_args()) { - g_set_error_literal(error, TECO_ERROR, TECO_ERROR_FAILED, - "<ES> command requires at least a message code"); - return NULL; - } - - if (!teco_expressions_pop_num_calc(&value, 0, error)) - return NULL; - ctx->scintilla.iMessage = value; - } - if (!ctx->scintilla.wParam) { - if (!teco_expressions_pop_num_calc(&value, 0, error)) - return NULL; - ctx->scintilla.wParam = value; - } - - return &teco_state_scintilla_lparam; -} - -/* in cmdline.c */ -gboolean teco_state_scintilla_symbols_process_edit_cmd(teco_machine_main_t *ctx, teco_machine_t *parent_ctx, gchar key, GError **error); - -/*$ ES scintilla message - * -- Send Scintilla message - * [lParam[,wParam]]ESmessage[,wParam[,lParam]]$[lParam]$ -> result - * - * Send Scintilla message with code specified by symbolic - * name <message>, <wParam> and <lParam>. - * <wParam> may be symbolic when specified as part of the - * first string argument. - * If not it is popped from the stack. - * <lParam> may be specified as a constant string whose - * pointer is passed to Scintilla if specified as the second - * string argument. - * If the second string argument is empty, <lParam> is popped - * from the stack instead. - * Parameters popped from the stack may be omitted, in which - * case 0 is implied. - * The message's return value is pushed onto the stack. - * - * All messages defined by Scintilla (as C macros) can be - * used by passing their name as a string to ES - * (e.g. ESSCI_LINESONSCREEN...). - * The \(lqSCI_\(rq prefix may be omitted and message symbols - * are case-insensitive. - * Only the Scintilla lexer symbols (SCLEX_..., SCE_...) - * may be used symbolically with the ES command as <wParam>, - * other values must be passed as integers on the stack. - * In interactive mode, symbols may be auto-completed by - * pressing Tab. - * String-building characters are by default interpreted - * in the string arguments. - * - * .BR Warning : - * Almost all Scintilla messages may be dispatched using - * this command. - * \*(ST does not keep track of the editor state changes - * performed by these commands and cannot undo them. - * You should never use it to change the editor state - * (position changes, deletions, etc.) or otherwise - * rub out will result in an inconsistent editor state. - * There are however exceptions: - * - In the editor profile and batch mode in general, - * the ES command may be used freely. - * - In the ED hook macro (register \(lqED\(rq), - * when a file is added to the ring, most destructive - * operations can be performed since rubbing out the - * EB command responsible for the hook execution also - * removes the buffer from the ring again. - * - As part of function key macros that immediately - * terminate the command line. - */ -TECO_DEFINE_STATE_EXPECTSTRING(teco_state_scintilla_symbols, - .process_edit_cmd_cb = (teco_state_process_edit_cmd_cb_t)teco_state_scintilla_symbols_process_edit_cmd, - .expectstring.last = FALSE -); - -static teco_state_t * -teco_state_scintilla_lparam_done(teco_machine_main_t *ctx, const teco_string_t *str, GError **error) -{ - if (ctx->mode > TECO_MODE_NORMAL) - return &teco_state_start; - - if (teco_string_contains(str, '\0')) { - g_set_error_literal(error, TECO_ERROR, TECO_ERROR_FAILED, - "Scintilla lParam string must not contain null-byte."); - return NULL; - } - - if (!ctx->scintilla.lParam) { - if (str->len > 0) { - ctx->scintilla.lParam = (sptr_t)str->data; - } else { - teco_int_t v; - if (!teco_expressions_pop_num_calc(&v, 0, error)) - return NULL; - ctx->scintilla.lParam = v; - } - } - - teco_expressions_push(teco_interface_ssm(ctx->scintilla.iMessage, - ctx->scintilla.wParam, - ctx->scintilla.lParam)); - - return &teco_state_start; -} - -TECO_DEFINE_STATE_EXPECTSTRING(teco_state_scintilla_lparam); |