aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/lexer.c
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2025-04-13 00:40:37 +0300
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2025-04-13 01:33:43 +0300
commit628c73d984fd7663607cc3fd9368f809855906fd (patch)
treebf9922ec94bbce2df19ef146724bbfe124138998 /src/lexer.c
parent3b06b44fc22cd5c936dd3ce677290e3f65f7f8ce (diff)
downloadsciteco-628c73d984fd7663607cc3fd9368f809855906fd.tar.gz
fixed undoing bitfields on Windows
* It turns out that `bool` (_Bool) in bitfields may cause padding to the next 32-bit word. This was only observed on MinGW. I am not entirely sure why, although the C standard does not guarantee much with regard to bitfield memory layout and there are 64-bit available due to passing anyway. Actually, they could also be layed out in a different order. * I am now consistently using guint instead of `bool` in bitfields to prevent any potential surprises. * The way that guint was aliased with bitfield structs for undoing teco_machine_main_t and teco_machine_qregspec_t flags was therefore insecure. It was not guaranteed that the __flags field really "captures" all of the bit field. Even with `guint v : 1` fields, this was not guaranteed. We would have required a static assertion for robustness. Alternatively, we could have declared a `gsize __flags` variable as well. This __should__ be safe since gsize should always be pointer sized and correspond to the platform's alignment. However, it's also not 100% guaranteed. Using classic ANSI C enums with bit operations to encode multiple fields and flags into a single integer also doesn't look very attractive. * Instead, we now define scalar types with their own teco_undo_push() shortcuts for the bitfield structs. This is in one way simpler and much more robust, but on the other hand complicates access to the flag variables. * It's a good question whether a `struct __attribute__((packed))` bitfield with guint fields would be a reliable replacement for flag enums, that are communicated with the "outside" (TECO) world. I am not going to risk it until GCC gives any guarantees, though. For the time being, bitfields are only used internally where the concrete memory layout (bit positions) is not crucial. * This fixes the test suite and therefore probably CI and nightly builds on Windows. * Test case: Rub out `@I//` or `@Xq` until before the `@`. The parser doesn't know that `@` is still set and allows all sorts of commands where `@` should be forbidden. * It's unknown how long this has been broken on Windows - quite possibly since v2.0.
Diffstat (limited to 'src/lexer.c')
-rw-r--r--src/lexer.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/src/lexer.c b/src/lexer.c
index 84ddcc3..5e6202d 100644
--- a/src/lexer.c
+++ b/src/lexer.c
@@ -64,7 +64,7 @@ teco_lexer_getstyle(teco_view_t *view, teco_machine_main_t *machine,
gsize macro_pc = machine->macro_pc;
teco_machine_main_clear(machine);
teco_machine_main_init(machine, NULL, FALSE);
- machine->mode = TECO_MODE_LEXING;
+ machine->flags.mode = TECO_MODE_LEXING;
machine->macro_pc = macro_pc;
return SCE_SCITECO_INVALID;
@@ -164,7 +164,7 @@ teco_lexer_step(teco_view_t *view, teco_machine_main_t *machine,
if (style != SCE_SCITECO_INVALID &&
machine->parent.current->keymacro_mask & TECO_KEYMACRO_MASK_START &&
- !machine->modifier_at)
+ !machine->flags.modifier_at)
/* clean parser state */
*safe_col = *cur_col;
}
@@ -206,12 +206,12 @@ teco_lexer_style(teco_view_t *view, gsize end)
g_auto(teco_machine_main_t) machine;
teco_machine_main_init(&machine, NULL, FALSE);
- machine.mode = TECO_MODE_LEXING;
+ machine.flags.mode = TECO_MODE_LEXING;
/* for lexing the contents of @^Uq{...} */
g_auto(teco_machine_main_t) macrodef_machine;
teco_machine_main_init(&macrodef_machine, NULL, FALSE);
- macrodef_machine.mode = TECO_MODE_LEXING;
+ macrodef_machine.flags.mode = TECO_MODE_LEXING;
g_assert(start_col >= 0);
guint col = start_col;