kc3-lang/libxkbcommon/src/xkbcomp

Branch :


Log

Author Commit Date CI Message
8ba5c453 2025-03-30 10:07:10 xkbcomp: Use section reference as default section name Before this commit the following keymap: ```c xkb_keymap { xkb_keycode {}; }; ``` would result in (boilerplate removed): ```c xkb_keymap { xkb_keycode "(unnamed)" {}; }; ``` This is both useless and wasting allocation: section names are optional, so we should just remove this default name altogether and keep it undefined, as in the original keymap. The situation is a bit different if there is an include, as for keymaps created from RMLVO names. Before this commit, the following keymap: ```c xkb_keymap { xkb_keycode { include "evdev+aliases(qwerty)" }; }; ``` would result in (boilerplate removed): ```c xkb_keymap { xkb_keycode "(unnamed)" { … }; }; ``` With this commit we now follow the Xorg xkbcomp style by using the section reference (the include string) as the *default* section name. So the previous example would now result in: ```c xkb_keymap { xkb_keycode "evdev_aliases(qwerty)" { … }; }; ``` which is useful to give a hint of the original include. Note that if the original section had a name, it would preserve it: ```c xkb_keymap { xkb_keycode "test" { include "evdev+aliases(qwerty)" }; }; ``` would compile to: ```c xkb_keymap { xkb_keycode "test" { … }; }; ```
3150bca8 2025-03-30 09:54:02 xkbcomp: Make all components optional We already accept *empty* components, such as: `xkb_compat {};`. Let’s accept missing components as well, so that we can reduce the boilerplate in our tests. Note that we will still explicitly serialize empty components for compatibility with previous xkbcommon versions and Xorg xkbcomp.
23598fa1 2025-03-25 22:52:06 Enable merge mode “replace” in include statements Previously only the merge modes “override” and “augment” were available in include statements, using the prefix ‘+’ and ‘|’ respectively. While on one hand `replace` include statement can be used in keymap files, on the other hand *rules* files have no way to express the *replace* mode. This commit enables the merge mode “replace” using the prefix `^`. This prefix was chosen due to its similarity with the `XOR` bit operator, which convey *mutual exclusion*. Other candidates: - `!` conveys some kind of higher precedence, akin to CSS `!important`. But it conflicts with the section header `!`, which is a token in the current parser. It would require special handling, not worth it. It also convey the meaning of negation, which is confusing. - `&` has the advantage of not corresponding to a token in the rules parser. `^` seems however to stand out more and it is less likely to trigger erroneous comparison with `|` and `&` bit operators.
6fc6e64b 2025-03-26 10:35:22 rules: Added extended wild cards <none>, <some> and <any> Added the following wild cards to the rules file syntax, in addition to the current `*` legacy wild card: - `<none>`: Match *empty* value. - `<some>`: Match *non-empty* value. - `<any>`: Match *any* (optionally empty) value. Its behavior does not depend on the context, contrary to the legacy wild card `*`. This will enable writing much simpler rules, see [!764] for an example of tricky rules in the `xkeyboard-config` project, that would benefit from the new wild cards. [!764]: https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/merge_requests/764 The verbose wild cards are preferred to single characters: - More intuitive: self-explanatory. - Does not steal syntax from other token. - Extensible syntax, should we need it. A previous proposal used the characters (`!`, `+`, `?`) for their similarity with the corresponding syntax of regular expressions (negative assertion & quantifiers), in line with `*`. But `!` is not that intuitive after all and conflict with its role as section header. Furthermore, `+` is also used as a merge mode. Finally, nothing beats whole short words for readability.
500b260b 2025-03-28 09:38:58 xkbcomp: Fix parser failure on floating-point numbers Before this commit we used `strtold`, which depends on the locale. But the XKB syntax is fixed and uses a period as decimal separator. So ensure the syntax is correct without relying on `strtold` and truncate the result, as the parser does not use floating-point numbers.
cc95f217 2025-03-25 11:15:45 xkbcomp: Fix whichGroupState serialization This indicator field was previously looked up in the wrong table, resulting the erroneous serialization `(null)`.
9a5547ce 2025-03-28 11:01:18 symbols: Fix leak in HandleSymbolsDef
8e92f25e 2025-03-13 21:26:59 rules: Added xkb_components_names_from_rules() This is mainly for debugging purposes and to enable displaying KcCGST values from RMLVO resolution in `xkbcli compile-keymap --kccgst`.
f3a4eeaa 2025-03-26 16:04:39 symbols: Improve keysym parsing
e5401b07 2025-03-26 16:02:58 symbols: Improve Modmap parsing Parse, dont’t validate: ensure *at parsing* that `modifier_map` definitions use a list of keys and keysyms. This enables to remove the redundant `ExprResolveKeySym` and have keysym parsing exclusively in handled in `parser.y`.
70d11abd 2025-03-26 07:38:05 messages: Add file encoding and invalid syntax entries Added: - `XKB_ERROR_INVALID_FILE_ENCODING` - `XKB_ERROR_INVALID_RULES_SYNTAX` - `XKB_ERROR_INVALID_COMPOSE_SYNTAX` Changed: - `XKB_ERROR_INVALID_SYNTAX` renamed to `XKB_ERROR_INVALID_XKB_SYNTAX`.
e8561909 2025-03-18 14:34:10 xkbcomp: Fix keycodes bounds - Refactor to check conflicts first for the key names and then for the keycodes. This seems more useful for the user and enable further memory optimizations. - Do not allocate until we are sure to add the keycode. The bounds are only updated afterwards, so the call to `FindKeyByName` should be more efficient. - Fixed keycodes bounds not shrunk correctly when an existing keycode is overridden. - Do not prepare keyname strings for logging if we are not going to use them.
4e90cb9c 2025-03-17 07:02:07 xkbcomp: Improve logging of virtual modifiers When logging about virtual modifier *explicit* mappings, we should always use only real modifiers or hexadecimal numbers to print the mask. Consider: ``` virtual_modifiers M1, M2=0x200, M2=0x400; ``` Before this commit we would get the following warning: ``` WARNING: Virtual modifier M2 defined multiple times; Using M2, ignoring M1 ``` while we would prefer the less confusing: ``` WARNING: Virtual modifier M2 defined multiple times; Using 0x400, ignoring 0x200 ```
9953d9f0 2025-03-10 21:58:05 xkbcomp/ast-build: fix possible UB in expr AST node allocations (#659) The expression AST constructors all return `ExprDef *`. `ExprDef` is a union of all expr types. As a memory optimization, instead of allocating `sizeof(ExprDef)`, we only allocate the size of the actual type (e.g. `sizeof(ExprBinary)`) which is sometimes smaller than `sizeof(ExprDef)`. This is probably undefined behavior, and gcc (with optimization turned on) complains about it, for example: src/xkbcomp/ast-build.c:69:23: warning: array subscript ‘ExprDef[0]’ is partly outside array bounds of ‘unsigned char[24]’ [-Warray-bounds=] Since it doesn't save that much memory, drop this optimization. Fix #292. Signed-off-by: Ran Benita <ran@unusedvar.com>
e1892266 2025-02-13 16:57:46 clang-tidy: Miscellaneous fixes
350931ad 2025-02-12 14:20:58 xkbcomp: Fix compat group index
f2dd0302 2025-02-12 14:15:26 xkbcomp: Fix LED index int type
2d111bbe 2025-02-12 13:54:51 xkbcomp: Fix possible overflow in numbers parser
a4038a47 2025-02-12 09:50:36 Miscellaneous int types fixes
14a816e5 2025-02-11 18:41:08 xkbcomp: Fix int cast
6c9806ae 2025-02-12 07:46:07 xkbcomp: Fix ExprResolveMaskLookup error message
558447d8 2025-02-11 17:34:27 xkbcomp: Explicit vars initialization The `Resolve*` functions do not always initialize the parameters that they can modify, so it is safer to always initialize them at the call site.
97698fca 2025-02-11 17:34:23 xkbcomp: Use explicit int sizes for Expr resolution
2d94da3d 2025-02-11 17:34:15 xkbcomp: Fix the int type of ExprInteger Avoid implicit conversion from `int64_t`.
3a0b77f0 2025-02-12 16:41:09 xkbcomp: Fix parser headers
bb5e464e 2025-02-07 14:30:51 xkbcomp/expr: remove comment on ExprResolveIntegerLookup What it says mostly no longer holds, I think it's more confusing than helpful now. Signed-off-by: Ran Benita <ran@unusedvar.com>
aa3e4c71 2025-02-07 14:10:16 xkbcomp/expr: remove unused ExprResolveKeyCode This function was added in commit 4e22851141d89436c0659e68da57e91bbf971461. But that commit also changed the grammar: -KeyNameDecl : KeyName EQUALS Expr SEMI +KeyNameDecl : KeyName EQUALS KeyCode SEMI i.e. while before you could write <AE01> = 9+1; now this is a syntax error, an integer literal is expected. I'm not sure if it was intended to remove this ability. In any case, this rendered `ExprResolveKeyCode` useless since there's no longer an expression to evaluate, and after some refactoring it went unused. Even if we choose to restore Expr here, I don't see a reason for the specialized function over `ExprResolveInteger` except the type (which we should probably widen from int to int64_t...). So remove it. Signed-off-by: Ran Benita <ran@unusedvar.com>
d9fc01b3 2025-02-06 15:12:53 xkbcomp/ast: combine expr_op_type into stmt_type It's better to have a single AST type enum. Signed-off-by: Ran Benita <ran@unusedvar.com>
635c48f8 2025-02-06 14:47:15 xkbcomp: remove unused EXPR_TYPE_ACTION Signed-off-by: Ran Benita <ran@unusedvar.com>
a4d782c7 2025-02-06 16:00:19 xkbcomp/ast: remove ExprCommon It's now empty and no longer serves a purpose. Signed-off-by: Ran Benita <ran@unusedvar.com>
9d7eb849 2025-02-06 15:25:03 xkbcomp/ast: combine expr_value_type into stmt_type This field is a funky attempt at type inference, or perhaps some optimization? Anyway, after careful examination I conclude it serves no purpose except specifying the type of a literal (string/integer/float/boolean/keyname) when `STMT_EXPR_VALUE` (i.e. literal). Remove it and replace `STMT_EXPR_VALUE` with specific statement types for each literal type. Signed-off-by: Ran Benita <ran@unusedvar.com>
f4e95280 2025-02-02 22:29:05 xkbcomp/scanner: avoid unneeded strdup of IDENT tokens The allocation is immediately discarded, either turned into a keysym or an atom. So use an sval slice into the input string instead strdup'ing. memusage ./release/bench-compile-keymap --iter=1000 --layout us,de --variant ,neo Before: Memory usage summary: heap total: 534063576, heap peak: 581022, stack peak: 18848 total calls total memory failed calls malloc| 11240525 291897104 0 realloc| 1447657 192307328 0 (nomove:37629, dec:0, free:0) calloc| 430573 49859144 0 free| 13993903 534063576 After: Memory usage summary: heap total: 506839909, heap peak: 581022, stack peak: 18960 total calls total memory failed calls malloc| 8016419 264673437 0 realloc| 1447657 192307328 0 (nomove:37278, dec:0, free:0) calloc| 430573 49859144 0 free| 10769797 506839909 Signed-off-by: Ran Benita <ran@unusedvar.com>
113ac304 2025-01-25 03:18:01 meson: link tests and benches against shared library, not static library This makes the tests, and especially benches, more realistic, since xkbcommon is almost always used as a shared library. Also significantly reduces the build time with LTO enabled (for me, from 90s to 30s). Signed-off-by: Ran Benita <ran@unusedvar.com>
df2322d7 2025-02-05 14:41:21 Replace include guards by `#pragma once` We currently have a mix of include headers, pragma once and some missing. pragma once is not standard but is widely supported, and we already use it with no issues, so I'd say it's not a problem. Let's convert all headers to pragma once to avoid the annoying include guards. The public headers are *not* converted. Signed-off-by: Ran Benita <ran@unusedvar.com>
02456c14 2025-02-02 21:51:20 xkbcomp/keymap: avoid some allocations in ApplyInterpsToKey Reuse the darray. memusage ./release/bench-compile-keymap --iter=1000 --layout us,de --variant ,neo Before: Memory usage summary: heap total: 552866360, heap peak: 581022, stack peak: 18848 total calls total memory failed calls realloc| 2035244 211110112 0 (nomove:37629, dec:0, free:0) After: Memory usage summary: heap total: 534063576, heap peak: 581022, stack peak: 18848 total calls total memory failed calls realloc| 1447657 192307328 0 (nomove:37629, dec:0, free:0) Signed-off-by: Ran Benita <ran@unusedvar.com>
7e84c845 2025-02-01 17:04:33 xkbcomp/scanner: avoid extra copies for keynames, keywords, identifiers The tokens don't have escapes so no need to use the `buf` for them. Signed-off-by: Ran Benita <ran@unusedvar.com>
43f6036d 2025-02-01 16:34:00 xkbcomp/keywords: don't require C string for keyword lookup Needed for next commit, but good regardless. No noticeable effect on performance. Signed-off-by: Ran Benita <ran@unusedvar.com>
e120807b 2025-01-29 15:35:22 Update license notices to SDPX short identifiers + update LICENSE Fix #628. Signed-off-by: Ran Benita <ran@unusedvar.com>
1f436703 2025-01-24 23:04:43 xkbcomp: rework KeysymList AST representation This is similar to the previous commit, for keysym lists. Signed-off-by: Ran Benita <ran@unusedvar.com>
39689867 2025-01-24 22:43:45 xkbcomp: rework ActionList AST representation The AST is heavily based on intrusive lists for representing lists, but actions are an exception, instead using darray. I don't see any reason for this; it ends up allocating more, and we don't especially need a flat array for this. Change it to use the familiar linked-list style. Signed-off-by: Ran Benita <ran@unusedvar.com>
26807a90 2025-01-28 20:24:05 scanner: compute token line/column lazily on errors The scanner functions are hot, and the line/column location tracking is quite expensive. We only use it for errors, which don't need to be fast, because we bail if there are too many; and for warnings, which are usually not shown by default. So only keep the token start pos, and compute the line/column lazily from that. This will also allow some further improvements ahead. bench/rulescomp before: compiled 1000 keymaps in 1.669028s after: compiled 1000 keymaps in 1.550411s bench/compose: before: compiled 1000 compose tables in 2.145217s after: compiled 1000 compose tables in 2.016044s Signed-off-by: Ran Benita <ran@unusedvar.com>
502e9e5b 2025-01-29 12:19:10 xkbcomp: Add stricter bounds for keycodes and levels Our current implementation uses continuous arrays indexed by keycodes and levels. This is simple and good enough for realistic keymaps. However, they are allowed to have big values that will lead to either memory exhaustion or a waste of memory (sparse arrays). Added the much stricter upper bounds `0xfff` for keycodes[^1] and 2048 for levels[^2], which should still be plenty enough and provides stronger memory security. [^1]: Current max keycode is 0x2ff in Linux. [^2]: Should be big enough to satisfy automatically generated keymaps.
c85c9bdc 2025-01-27 17:15:06 symbols: Allow levels with different keysyms and actions counts Contrary to groups, there is no reason for levels to restrict the same count of keysyms and actions.
27ac30b2 2025-01-27 17:13:44 symbols: Normalize levels by dropping NoSymbol & NoAction
4ac22263 2025-01-16 23:22:40 keysyms: Check clashes between keysyms names and keywords Due to how our parser is implemented, keysyms names that are also valid keywords require special handling. Added a check for these clashes in the keysym generator. The only current clash, `section`, is already handled. Note that it means that e.g. `section`, `Section` and `sEcTiOn` all parse to the same keysym. This side effect is fine here, because *currently* there is no other keysym that clashes with any possible of the case variation of `section`. But in order to be extra cautious, we now test thoses clashes too. Hopefully we will never have a clash again, but while it is unlikely that we modify the keywords, the keysyms are not a frozen set.
7c124fd9 2025-01-22 17:20:04 rules: Fix incrementing a variable in a complex condition
818b1b6b 2025-01-22 17:19:41 symbols: Simplify GetGroupIndex call
357ab0cb 2025-01-23 16:42:30 clang-tidy: Fix missing default case in switch statement
842497d9 2025-01-22 16:46:11 clang-tidy: Fix implicit or incorrect integer casts
53b3f446 2025-01-22 17:43:53 clang-tidy: Fix headers includes
0c940827 2025-01-22 16:39:35 clang-tidy: Macro arguments should be enclosed in parentheses
b1e1aae6 2025-01-23 15:20:44 xkbcomp: Fix memory leak when extra content after keymap It triggers with e.g.: ``` xkb_keymap { xkb_keycodes { }; }; }; // erroneous ```
709027ec 2025-01-23 09:12:15 symbols: Fix inconsistent error handling Currently the following keymap triggers a critical error (invalid `vmods`) only for the second key statement, while it should handle both equally. ``` xkb_keymap { xkb_keycodes { <> = 9; }; xkb_types { }; xkb_compat { }; xkb_symbols { key <> { vmods = [], repeats = false }; key <> { repeats = false, vmods = [] }; }; }; ``` Fixed by parsing the whole symbols body and failing if any error was found.
ec2915fe 2025-01-22 17:18:21 symbols: Fix a possible null pointer deference Introduce a new Expression type, `EXPR_EMPTY_LIST`, to avoid the ambiguity between action and keysym empty lists. Two alternatives were rejected to keep the semantics clear: - Using `EXPR_KEYSYM_LIST`: because we would end up accepting an empty keysym list while processing actions. - Using NULL: convey no info and is hazardous.
9ef45dc5 2025-01-21 19:55:47 Fix incompatible pointer types with enums The enum casts can possibly lead to unaligned access. The warnings trigger in the Windows CI but not on Linux. One may use `-fshort-enums` with gcc in order to trigger the errors.
425dc634 2025-01-21 15:40:33 Fix some implicit integers casts
b1aecd47 2025-01-21 17:51:56 actions: Fix SwitchScreen screen value range Currently we accept values of -255..255 while parsing the screen value of `SwitchScreen` actions`, but then we silently cast it against `int8_t`, i.e. in range -128..127. We actually do as xkbcomp, but this seems a bug because the target storage is a `char`. Let’s simply raise a parse error if the value does not fit in our type.
26069b76 2025-01-21 10:48:28 xkbcomp/parser: silence a set but unused warning ``` libxkbcommon.so.0.7.0.p/parser.c:1632:9: warning: variable '_xkbcommon_nerrs' set but not used [-Wunused-but-set-variable] 1632 | int yynerrs = 0; ``` Signed-off-by: Ran Benita <ran@unusedvar.com>
c0762c49 2025-01-20 16:33:50 keymap: Fix buffer unnecessary written twice When dumping the keymap, we first try to write to the buffer and get the min size requirement. Then we reallocate if necessary. However, we should not write it again if we got enough space previously!
24fe4bac 2025-01-20 16:31:44 Fix undefined behaviours with NULL pointer Issues detected by the sanitizers: - fix indexing NULL pointer - fix zero offset to NULL pointer
b0d9a790 2025-01-15 12:03:10 vmods: Fix explicit vmods not dumped
c7fdf506 2025-01-16 20:23:28 Use portable integer literal suffixes
e3e44998 2025-01-16 20:23:47 Fix missing or incorrect integer literal suffixes The correct suffix is required in order to have the expected value in a portable way.
dfa286b2 2025-01-15 13:56:36 compat: Fix Interp & LED merge modes
d43bb955 2024-12-19 18:21:01 symbols: Fix key symbols/actions merge - Fixed field for defined keysyms/actions - Fixed regression introduced by fdf2c525977e7e8af4135d593110f5bc1454abd8
bf03b4b5 2024-12-19 16:23:05 symbols: Parse empty key The following syntax does not parse in xkbcommon, but it does in xkbcomp: ``` xkb_symbols "x" { key <AD01> { }; }; ``` While the usefulness of such statement is debatable, the fact that it does parse in xkbcomp and that tools may generate such keymap entry make it relevant to handle.
60228356 2024-10-07 10:42:27 symbols: Add message ID for incompatible keysyms and actions counts
fdf2c525 2024-10-08 19:43:30 actions: Add support for multiple actions per level This makes 1 keysym == 1 action holds also for multiple keysyms per level. The motivation of this new feature are: - Make multiple keysyms per level more intuitive. - Explore how to fix the issue with shortcuts in multi-layout settings (see the xkeyboard-config issue[^1]). The idea is to use e.g.: ```c key <LCTL> { symbols[1] = [ {Control_L, ISO_First_Group } ], actions[1] = [ {SetMods(modifiers=Control), SetGroup(group=-4) } ] }; ``` in order to switch temporarily to a reference layout in order to get the same shortcuts on every layout. When no action is specified, `interpret` statements are used to find an action corresponding for *each* keysym, as expected. For an interpretation matching Any keysym, we may get the same interpretation for multiple keysyms. This may result in unwanted duplicate actions. So set this interpretation only if no previous keysym was matched with this interpret at this level, else set the default interpretation. For now, at most one action of each following categories is allowed per level: - modifier actions: `SetMods`, `LatchMods`, `LockMods`; - group actions: `SetGroup`, `LatchGroup`, `LockGroup`. Some examples: - `SetMods` + `SetGroup`: ok - `SetMods` + `SetMods`: error - `SetMods` + `LockMods`: error - `SetMods` + `LockGroup`: ok [^1]: https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/issues/416
772ac0c4 2024-09-23 11:02:35 keymap: Rename keysyms field in xkb_level The current field `u` (short for “union”) is not very descriptive. Next commit will add multiple actions per level, so let’s rename the keysym field to `s` (short for “symmbols”).
31c6d866 2024-10-08 18:39:00 symbols: Min. 2 keysyms in level list Do not allow `{ a }` when a single `a` suffices.
7c4c718b 2024-09-30 06:13:38 Allow only the first group in symbols sections when using RMLVO Currently `xkb_keymap_num_layouts` may return a greater number than the number of layouts configured using RMLVO, because we allow symbols sections to define various groups per key. This is unintuitive and kind of buggy: groups should be added via rules by setting an explicit `:n` modifier. Fix: when parsing a keymap using RMLVO resolution: - Get the expected layouts count from the resulting KcCGST. - Drop the groups after the first one in included symbols sections. This will ensure that a symbol section can only define one group per key. Notes: - Compiling a keymap string directly is unaffected. - RMLVO resolution may still produce more groups than the input layouts. Indeed, some legacy rules in xkeyboard-config rely on this to insert automatically a US layout before the given non-Latin one, resulting in two layouts while only one was given.
948f7a59 2024-10-09 08:34:27 symbols: Skip interprets only for groups with explicit actions Previously setting explicit actions for a group in symbols files made the parser skip compatibility interpretations for the corresponding *whole* key, so the other groups with *no* explicit actions could result broken on some levels. In the following example, `<RALT>` would have an action on group 2, because it is explicit, but none on group 1 because interpretation are also skipped there as a side effect: ```c key <RALT> { symbols[1]= [ ISO_Level3_Shift ], symbols[2]= [ ISO_Level3_Shift ], actions[2]= [ SetMods(modifiers=LevelThree) ] }; ``` Fixed by skipping interpretations *only* for groups with explicit actions. We still set `key->explicit |= EXPLICIT_INTERP` if at least one group has explicit actions. In such case, when dumping a keymap, we will write explicit actions for *all* groups, in order to ensure that X11 and previous versions of libxkbcommon can parse the keymap as intended. One side effect is that no interpretation will be run on this key anymore, so we may have to set some extra fields explicitly: repeat, virtualMods. Thus the previous example would be bumped as: ```c key <RALT> { repeat= No, symbols[1]= [ ISO_Level3_Shift ], actions[1]= [ SetMods(modifiers=LevelThree,clearLocks) ], symbols[2]= [ ISO_Level3_Shift ], actions[2]= [ SetMods(modifiers=LevelThree) ] }; ```
929a485f 2024-10-08 12:52:53 symbols: Fix too liberal parsing of keysyms lists Currently we are too liberal when parsing symbols lists: e.g. `[{a,{b}}]` is parsed as `[{a,b}]` but it should be rejected.
4ea9d431 2023-11-16 17:12:03 rules: Add support for :all qualifier Some layout options require to be applied to every group to maintain consistency (e.g. a group switcher). Currently this must be done manually for all layout indexes. This is error prone and prevents the increase of the maximum group count. This commit introduces the `:all` qualifier for KcCGST values. When a rule with this qualifier is matched, it will expands the qualified value (and its optional merge mode) for every layout, e.g. `+group(toggle):all` (respectively `|group(toggle)`) would expand to `+group(toggle):1+group(toggle):2` (respectively `|group(toggle):1|group(toggle):2`) if there are 2 layouts, etc. If there is no merge mode, it defaults to *override* `+`, e.g. `x:all` expands to `x:1+x:2+x:3` for 3 layouts. Note that only the qualified *value* is expanded, e.g. `x+y:all` expands to `x+y:1+y:2` for 2 layouts. `:all` can be used in combination with special layout indexes. Since this can lead to an unexpected behaviour, a warning will be raised.
cdafba4f 2024-09-24 15:23:16 rules: Add support for index ranges There is a lot of repetition in the current rules files provided by xkeyboard-config, because the MLVO mappings need to match on the exact layout/variant index. This also prevents to increase the number of maximum groups, because it does not scale. We introduces the following new special layout/variant indexes: - “single”: matches a single layout; same as with no index. - “first”: matches the first layout/variant, no matter how many layouts are in the RMLVO configuration. It allows to merge `layout` and `layout[1]` patterns. - “later”: matches all but the first layout. This is an index range. - “any”: matches layout at any position. This is an index range. We also introduces the new `%i` expansion, which correspond to the index of the matched layout in a mapping with an index range. Example: layout[later] = symbols my_layout = +my_symbols:%i * = +%l[%i]:%i Let’s have a look at concrete examples from xkeyboard-config: ! model layout = symbols * * = pc+%l%(v) ! model layout[1] = symbols * * = pc+%l[1]%(v[1]) ! model layout[2] = symbols * * = +%l[2]%(v[2]) ! model layout[3] = symbols * * = +%l[3]%(v[3]) ! model layout[4] = symbols * * = +%l[4]%(v[4]) ! layout option = symbols * grp:toggle = +group(toggle) ! layout[1] option = symbols * grp:toggle = +group(toggle):1 ! layout[2] option = symbols * grp:toggle = +group(toggle):2 ! layout[3] option = symbols * grp:toggle = +group(toggle):3 ! layout[4] option = symbols * grp:toggle = +group(toggle):4 With this commit we can now simplify it into: ! model layout[first] = symbols * * = pc+%l[%i]%(v[%i]) ! model layout[later] = symbols * * = +%l[%i]%(v[%i]):%i ! layout[any] option = symbols * grp:toggle = +group(toggle):%i The latter rule will work even if we increase XKB_MAX_GROUPS, whereas the former would require to add the missing entries for the new groups. In order to maintain consistent rules, we now disallow layout and variant to have different indexes. For example, the following mapping are now invalid: - layout variant[1] - layout[1] variant[2] - layout[1] variant - layout[first] variant[1] - layout[first] variant - layout variant[any] - etc.
076c60df 2024-09-25 16:21:05 rules: Ensure same number of layouts and variants
c67ec170 2024-09-25 14:59:23 include: Use constants for merge mode prefixes This will make their semantics explicit.
a898bc81 2024-09-25 06:47:23 logging: Added new error messages ID for keymap and rules
ba896935 2024-09-24 21:28:12 logging: Make scanner_warn use a message ID
c8bd57dd 2024-09-24 21:20:41 logging: Make scanner_err use a message ID
fdcd458c 2024-09-24 21:20:29 nit: Format files
7697c712 2024-09-16 16:09:11 rules: Resolve relative include statements using XKB paths Contrary to keymap files, the `! include` statement in rules does not lookup include paths added to `xkb_context`. So it is not possible e.g. to import another file in the same folder without using an absolute path. - Added path utils: `is_absolute(path)`. - Added XKB paths lookup to enable e.g. `! include evdev` to work. - Added test.
44df6eee 2024-09-23 07:27:48 Add new warnings for deprecated keysyms Add 2 new warnings: - Deprecated keysym name (typo, historical alias, etc.); - Deprecated keysym (all names and forms). Guard deprecated keysym tests with verbosity level ≥2, so they are run only when actually needed.
05ba96db 2024-08-20 16:41:38 rules: Fix wild card handling The handling of wild card `*` is different in libxkbfile and X server: wild card matches empty strings for model and option but not for layout nor variant, while in libxkbcommon wild cards always match empty strings. See: - https://gitlab.freedesktop.org/xorg/lib/libxkbfile/-/blob/bf985c68acb1244f51ec91414532a2347fbc1c4c/src/maprules.c#L687 - https://gitlab.freedesktop.org/xorg/lib/libxkbfile/-/blob/bf985c68acb1244f51ec91414532a2347fbc1c4c/src/maprules.c#L712 The difference of handling between the components is unfortunately not documented, but we should follow the behavior of the original implementations for consistency. - Fixed by implementing the same behavior than libxkbfile. - Added tests and fixed failing tests. - Improve the documentation of rules to highlight the special behavior.
e83d08dd 2024-02-23 17:10:15 keysyms: Fast and complete case mappings (Unicode 15.1) The current code to handle keysym case mappings is quite complex and slow. It is also incomplete, as it does not cover recent Unicode database. Finally, it does not handle title case correctly. It would be easier if we were to use only a lookup table, but a trivial implementation would lead to a huge array: the cased characters range from `U+0041` to `U+`1F189, i.e. a span of 127 304 elements. Thus we need some tricks to compress the lookup table. We based our work on the post: https://github.com/apankrat/notes/blob/3c551cb028595fd34046c5761fd12d1692576003/fast-case-conversion/README.md The compression algorithm is roughly: 1. Compute the delta between the characters and their mappings. 2. Split the delta array in chunk of a given size. 3. Rearrange the order of the chunks in order to optimize consecutive chunks overlap. 4. Create a data table with the reordered chunks and an index table that maps the original chunk index to its offset in the data table. The compression algorithm is then applied a second time to the previous index table. The complete algorithm optimizes the two chunk sizes in order to get the lowest total data size. The mappings were generated using CPython 3.12.4, PyICU 2.13, PyYaml 6.0.1 and ICU 75.1. Also: - Added explicit list of named keysyms and their case mappings. - Added benchmark for case mappings. - Rework ICU tests. Note: 13b30f4f0dccc08dfea426d73570b913596ed602 introduced a fix for sharp S `U+00DF`. With the new implementation, the *conversion* functions `xkb_keysym_to_{lower,upper}` leave it *unchanged*, while the *predicate* functions `xkb_keysym_is_{lower,upper_or_title}` produce the expected results: ```c xkb_keysym_to_upper(XKB_KEY_ssharp) == XKB_KEY_ssharp; xkb_keysym_to_lower(XKB_KEY_ssharp) == XKB_KEY_ssharp; xkb_keysym_to_lower(XKB_KEY_Ssharp) == XKB_KEY_ssharp; xkb_keysym_is_lower (XKB_KEY_ssharp) == true; xkb_keysym_is_upper_or_title(XKB_KEY_Ssharp) == true; ```
9944be7e 2024-07-15 15:40:54 nit: Fix typo
d455e805 2024-03-24 05:07:18 rules: fix variant index being ignored for layout index (#475) We accidentally ignored the variant index and used the layout index instead. In realistic rules they are always the same but don't have to be.
ba76ec16 2024-03-01 15:02:42 Global default statement: Fix types Do not accept statements like garbage.level_name in types files Fix parser accepting clearly nonsensical type definitions like type "ONE_LEVEL" { garbage.modifiers = None; garbage.map[None] = Level1; garbage.level_name[Level1] = "Any"; }; and ignoring the garbage part. Co-authored-by: Mikhail Gusarov <dottedmag@dottedmag.net> Co-authored-by: Pierre Le Marre <dev@wismill.eu>
24f69645 2024-03-01 15:02:42 Global default statement: Fix symbols
13b36a76 2024-03-01 15:02:41 Global default statement: Improve code & error message - Simplify error handling. - Improve error message: add message ID and relevant quotes and try to standardize a bit. - Add proper doc for in the message registry. Note: Instead of testing the value of `expr.op`, we test if the argument `elem` of `ExprResolveLhs` is set: this allows us to catch also the error with `x.y[z]` rather than just `x.y` as previously.
d21645be 2024-02-18 13:57:15 xkbcomp: Require newline after !include line in rules files Rules file parser allows constructs like !include "foo" !include "bar" !layout = symbols This is most likely an oversight in original code. Closes #452
efdb05d1 2024-01-27 23:00:28 parser: Do now allow the empty symbol declaration An empty element is allowed in SymbolsBody definition, so the following keymap is gramatically correct. ``` xkb_keymap { ... xkb_symbols "sym" { key <SPC> {, [Space] }; }; }; ``` However, the current parser crashes with the keymap due to null pointer access. This change fixes it by changing the parser not to allow it.
20329baf 2023-11-23 09:30:57 xkbcomp: Use `steal` for better memory handling
00e3058e 2023-11-06 21:53:51 Prevent recursive includes of keymap components - Add check for recursive includes of keymap components. It relies on limiting the include depth. The threshold is currently to 15, which seems reasonable with plenty of margin for keymaps in the wild. - Add corresponding new log message `recursive-include`. - Add tests for recursive includes.
171e0170 2023-10-25 20:39:39 Fix memory leak in FindFileInXkbPath The string `buf` was not freed after each call to `asprintf_safe`. Avoid allocating and introduce the new message: `XKB_ERROR_INSUFFICIENT_BUFFER_SIZE`.
2b714310 2023-10-25 20:01:22 Fix memory leaks in key types compilation When there is no error the types are “stolen” and copied to the keymap. But when there is an error, `MergeIncludedKeyTypes` just return without “stealing” nor freeing the types. Fixed by explicitly freeing the key types. Fixed another leak in `HandleKeyTypeDef` that may occur if there is an error in parsing a type definition.
3aaa4e2a 2023-10-30 15:51:34 rules: early detection of invalid encoding
82e9293e 2023-10-30 15:28:10 xkbcomp: early detection of invalid encoding
9e887180 2023-10-29 07:44:39 rules: skip heading UTF-8 encoded BOM (U+FEFF) Leading BOM is legal and is used as a signature — an indication that an otherwise unmarked text file is in UTF-8. See: https://www.unicode.org/faq/utf_bom.html#bom5 for further details.
f937c308 2023-10-29 07:31:34 xkbcomp: skip heading UTF-8 encoded BOM (U+FEFF) Leading BOM is legal and is used as a signature — an indication that an otherwise unmarked text file is in UTF-8. See: https://www.unicode.org/faq/utf_bom.html#bom5 for further details.