diff options
Diffstat (limited to 'src/sciteco.h')
-rw-r--r-- | src/sciteco.h | 159 |
1 files changed, 89 insertions, 70 deletions
diff --git a/src/sciteco.h b/src/sciteco.h index 664b69d..dcf5359 100644 --- a/src/sciteco.h +++ b/src/sciteco.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2017 Robin Haberkorn + * 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 @@ -14,100 +14,119 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#pragma once -#ifndef __SCITECO_H -#define __SCITECO_H - +#include <stdio.h> #include <signal.h> #include <glib.h> -#include "interface.h" - -namespace SciTECO { - #if TECO_INTEGER == 32 -typedef gint32 tecoInt; -#define TECO_INTEGER_FORMAT G_GINT32_FORMAT +typedef gint32 teco_int_t; +#define TECO_INT_FORMAT G_GINT32_FORMAT #elif TECO_INTEGER == 64 -typedef gint64 tecoInt; -#define TECO_INTEGER_FORMAT G_GINT64_FORMAT +typedef gint64 teco_int_t; +#define TECO_INT_FORMAT G_GINT64_FORMAT #else #error Invalid TECO integer storage size #endif -typedef tecoInt tecoBool; - -namespace Flags { - enum { - ED_AUTOCASEFOLD = (1 << 3), - ED_AUTOEOL = (1 << 4), - ED_HOOKS = (1 << 5), - ED_FNKEYS = (1 << 6), - ED_SHELLEMU = (1 << 7), - ED_XTERM_CLIPBOARD = (1 << 8) - }; - - extern tecoInt ed; -} - -extern sig_atomic_t sigint_occurred; /** - * For sentinels: NULL might not be defined as a - * pointer type (LLVM/CLang) + * A TECO boolean - this differs from C booleans. + * See teco_is_success()/teco_is_failure(). */ -#define NIL ((void *)0) +typedef teco_int_t teco_bool_t; + +#define TECO_SUCCESS ((teco_bool_t)-1) +#define TECO_FAILURE ((teco_bool_t)0) + +static inline teco_bool_t +teco_bool(gboolean x) +{ + return x ? TECO_SUCCESS : TECO_FAILURE; +} + +static inline gboolean +teco_is_success(teco_bool_t x) +{ + return x < 0; +} -/** true if C is a control character */ -#define IS_CTL(C) ((C) < ' ') +static inline gboolean +teco_is_failure(teco_bool_t x) +{ + return x >= 0; +} + +/** TRUE if C is a control character */ +#define TECO_IS_CTL(C) ((C) < ' ') /** ASCII character to echo control character C */ -#define CTL_ECHO(C) ((C) | 0x40) +#define TECO_CTL_ECHO(C) ((C) | 0x40) /** * Control character of ASCII C, i.e. * control character corresponding to CTRL+C keypress. */ -#define CTL_KEY(C) ((C) & ~0x40) -/** - * Control character of the escape key. - * Equivalent to CTL_KEY('[') or '\\e', - * but more portable. - */ -#define CTL_KEY_ESC 27 +#define TECO_CTL_KEY(C) ((C) & ~0x40) + /** - * String containing the escape character. - * There is "\e", but it's not really standard C/C++. + * ED flags. + * This is not a bitfield, since it is set from SciTECO. */ -#define CTL_KEY_ESC_STR "\x1B" - -#define SUCCESS ((tecoBool)-1) -#define FAILURE ((tecoBool)0) -#define TECO_BOOL(X) ((X) ? SUCCESS : FAILURE) - -#define IS_SUCCESS(X) ((X) < 0) -#define IS_FAILURE(X) (!IS_SUCCESS(X)) +enum { + TECO_ED_AUTOCASEFOLD = (1 << 3), + TECO_ED_AUTOEOL = (1 << 4), + TECO_ED_HOOKS = (1 << 5), + TECO_ED_FNKEYS = (1 << 6), + TECO_ED_SHELLEMU = (1 << 7), + TECO_ED_XTERM_CLIPBOARD = (1 << 8) +}; -/* in main.cpp */ -void interrupt(void); +/* in main.c */ +extern teco_int_t teco_ed; -/* in main.cpp */ -const gchar *get_eol_seq(gint eol_mode); +/* in main.c */ +extern volatile sig_atomic_t teco_sigint_occurred; -namespace Validate { +/* in main.c */ +void teco_interrupt(void); -static inline bool -pos(gint n) -{ - return n >= 0 && n <= interface.ssm(SCI_GETLENGTH); -} - -static inline bool -line(gint n) -{ - return n >= 0 && n < interface.ssm(SCI_GETLINECOUNT); -} +/* + * Allows automatic cleanup of FILE pointers. + */ +G_DEFINE_AUTOPTR_CLEANUP_FUNC(FILE, fclose); -} /* namespace Validate */ +/* + * BEWARE DRAGONS! + */ +#define __TECO_FE_0(WHAT, WHAT_LAST) +#define __TECO_FE_1(WHAT, WHAT_LAST, X) WHAT_LAST(1,X) +#define __TECO_FE_2(WHAT, WHAT_LAST, X, ...) WHAT(2,X)__TECO_FE_1(WHAT, WHAT_LAST, __VA_ARGS__) +#define __TECO_FE_3(WHAT, WHAT_LAST, X, ...) WHAT(3,X)__TECO_FE_2(WHAT, WHAT_LAST, __VA_ARGS__) +#define __TECO_FE_4(WHAT, WHAT_LAST, X, ...) WHAT(4,X)__TECO_FE_3(WHAT, WHAT_LAST, __VA_ARGS__) +#define __TECO_FE_5(WHAT, WHAT_LAST, X, ...) WHAT(5,X)__TECO_FE_4(WHAT, WHAT_LAST, __VA_ARGS__) +//... repeat as needed -} /* namespace SciTECO */ +#define __TECO_GET_MACRO(_0,_1,_2,_3,_4,_5,NAME,...) NAME -#endif +/** + * Invoke macro `action(ID, ARG)` on every argument + * and `action_last(ID, ARG)` on the very last one. + * Currently works only for 5 arguments, + * but if more are needed you can add __TECO_FE_X macros. + */ +#define TECO_FOR_EACH(action, action_last, ...) \ + __TECO_GET_MACRO(_0,##__VA_ARGS__,__TECO_FE_5,__TECO_FE_4,__TECO_FE_3, \ + __TECO_FE_2,__TECO_FE_1,__TECO_FE_0)(action,action_last,##__VA_ARGS__) + +#define __TECO_GEN_ARG(ID, X) X arg_##ID, +#define __TECO_GEN_ARG_LAST(ID, X) X arg_##ID +#define __TECO_VTABLE_GEN_CALL(ID, X) arg_##ID, +#define __TECO_VTABLE_GEN_CALL_LAST(ID, X) arg_##ID + +#define TECO_DECLARE_VTABLE_METHOD(RET_TYPE, NS, NAME, OBJ_TYPE, ...) \ + static inline RET_TYPE \ + NS##_##NAME(OBJ_TYPE ctx, ##TECO_FOR_EACH(__TECO_GEN_ARG, __TECO_ARG_LAST, ##__VA_ARGS__)) \ + { \ + return ctx->vtable->NAME(ctx, ##TECO_FOR_EACH(__TECO_VTABLE_GEN_CALL, __TECO_VTABLE_GEN_CALL_LAST, ##__VA_ARGS__)); \ + } \ + typedef RET_TYPE (*NS##_##NAME##_t)(OBJ_TYPE, ##__VA_ARGS__) |