aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/sciteco.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/sciteco.h')
-rw-r--r--src/sciteco.h159
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__)