********************************************************/
+/*
+ * The parser should work with reasonably recent versions of either
+ * bison or byacc. So if you make changes, try to make sure it works
+ * in both!
+ */
+
%{
-#include "xkbcomp-priv.h"
-#include "ast-build.h"
-#include "parser-priv.h"
+#include "config.h"
+
+#include "xkbcomp/xkbcomp-priv.h"
+#include "xkbcomp/ast-build.h"
+#include "xkbcomp/parser-priv.h"
+#include "scanner-utils.h"
+#include "keysym.h"
struct parser_param {
struct xkb_context *ctx;
- void *scanner;
+ struct scanner *scanner;
XkbFile *rtrn;
bool more_maps;
};
+#define parser_err(param, error_id, fmt, ...) \
+ scanner_err_with_code((param)->scanner, error_id, fmt, ##__VA_ARGS__)
+
+#define parser_warn(param, warning_id, fmt, ...) \
+ scanner_warn_with_code((param)->scanner, warning_id, fmt, ##__VA_ARGS__)
+
static void
-_xkbcommon_error(struct YYLTYPE *loc, struct parser_param *param, const char *msg)
+_xkbcommon_error(struct parser_param *param, const char *msg)
{
- scanner_error(loc, param->scanner, msg);
+ parser_err(param, XKB_ERROR_INVALID_SYNTAX, "%s", msg);
}
-#define scanner param->scanner
+static bool
+resolve_keysym(const char *name, xkb_keysym_t *sym_rtrn)
+{
+ xkb_keysym_t sym;
+
+ if (!name || istreq(name, "any") || istreq(name, "nosymbol")) {
+ *sym_rtrn = XKB_KEY_NoSymbol;
+ return true;
+ }
+
+ if (istreq(name, "none") || istreq(name, "voidsymbol")) {
+ *sym_rtrn = XKB_KEY_VoidSymbol;
+ return true;
+ }
+
+ sym = xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS);
+ if (sym != XKB_KEY_NoSymbol) {
+ *sym_rtrn = sym;
+ return true;
+ }
+
+ return false;
+}
+
+#define param_scanner param->scanner
%}
-%name-prefix "_xkbcommon_"
-%define api.pure
-%locations
-%lex-param { void *scanner }
+%define api.pure
+%lex-param { struct scanner *param_scanner }
%parse-param { struct parser_param *param }
%token
%start XkbFile
%union {
- int ival;
- unsigned uval;
int64_t num;
enum xkb_file_type file_type;
char *str;
- xkb_atom_t sval;
+ xkb_atom_t atom;
enum merge_mode merge;
enum xkb_map_flags mapFlags;
+ xkb_keysym_t keysym;
ParseCommon *any;
+ struct { ParseCommon *head; ParseCommon *last; } anyList;
ExprDef *expr;
+ struct { ExprDef *head; ExprDef *last; } exprList;
VarDef *var;
+ struct { VarDef *head; VarDef *last; } varList;
VModDef *vmod;
+ struct { VModDef *head; VModDef *last; } vmodList;
InterpDef *interp;
KeyTypeDef *keyType;
SymbolsDef *syms;
KeyAliasDef *keyAlias;
void *geom;
XkbFile *file;
+ struct { XkbFile *head; XkbFile *last; } fileList;
}
%type <num> INTEGER FLOAT
%type <str> IDENT STRING
-%type <sval> KEYNAME
-%type <num> KeyCode
-%type <ival> Number Integer Float SignedNumber
+%type <atom> KEYNAME
+%type <num> KeyCode Number Integer Float SignedNumber DoodadType
%type <merge> MergeMode OptMergeMode
%type <file_type> XkbCompositeType FileType
-%type <uval> DoodadType
%type <mapFlags> Flag Flags OptFlags
-%type <str> MapName OptMapName KeySym
-%type <sval> FieldSpec Ident Element String
-%type <any> DeclList Decl
-%type <expr> OptExprList ExprList Expr Term Lhs Terminal ArrayInit KeySyms
-%type <expr> OptKeySymList KeySymList Action ActionList Coord CoordList
-%type <var> VarDecl VarDeclList SymbolsBody SymbolsVarDecl
-%type <vmod> VModDecl VModDefList VModDef
+%type <str> MapName OptMapName
+%type <atom> FieldSpec Ident Element String
+%type <keysym> KeySym
+%type <any> Decl
+%type <anyList> DeclList
+%type <expr> Expr Term Lhs Terminal ArrayInit KeySyms
+%type <expr> OptKeySymList KeySymList Action Coord CoordList
+%type <exprList> OptExprList ExprList ActionList
+%type <var> VarDecl SymbolsVarDecl
+%type <varList> VarDeclList SymbolsBody
+%type <vmod> VModDef
+%type <vmodList> VModDefList VModDecl
%type <interp> InterpretDecl InterpretMatch
%type <keyType> KeyTypeDecl
%type <syms> SymbolsDecl
%type <geom> ShapeDecl SectionDecl SectionBody SectionBodyItem RowBody RowBodyItem
%type <geom> Keys Key OverlayDecl OverlayKeyList OverlayKey OutlineList OutlineInList
%type <geom> DoodadDecl
-%type <file> XkbFile XkbMapConfigList XkbMapConfig
+%type <file> XkbFile XkbMapConfig
+%type <fileList> XkbMapConfigList
%type <file> XkbCompositeMap
+%destructor { FreeStmt((ParseCommon *) $$); }
+ <any> <expr> <var> <vmod> <interp> <keyType> <syms> <modMask> <groupCompat>
+ <ledMap> <ledName> <keyCode> <keyAlias>
+%destructor { FreeStmt((ParseCommon *) $$.head); }
+ <anyList> <exprList> <varList> <vmodList>
+/* The destructor also runs on the start symbol when the parser *succeeds*.
+ * The `if` here catches this case. */
+%destructor { if (!param->rtrn) FreeXkbFile($$); } <file>
+%destructor { FreeXkbFile($$.head); } <fileList>
+%destructor { free($$); } <str>
+
%%
/*
*/
XkbFile : XkbCompositeMap
- { $$ = param->rtrn = $1; param->more_maps = true; }
+ { $$ = param->rtrn = $1; param->more_maps = !!param->rtrn; }
| XkbMapConfig
- { $$ = param->rtrn = $1; param->more_maps = true; YYACCEPT; }
+ { $$ = param->rtrn = $1; param->more_maps = !!param->rtrn; YYACCEPT; }
| END_OF_FILE
{ $$ = param->rtrn = NULL; param->more_maps = false; }
;
XkbCompositeMap : OptFlags XkbCompositeType OptMapName OBRACE
XkbMapConfigList
CBRACE SEMI
- { $$ = XkbFileCreate(param->ctx, $2, $3, &$5->common, $1); }
+ { $$ = XkbFileCreate($2, $3, (ParseCommon *) $5.head, $1); }
;
XkbCompositeType: XKB_KEYMAP { $$ = FILE_TYPE_KEYMAP; }
;
XkbMapConfigList : XkbMapConfigList XkbMapConfig
- {
- if (!$2)
- $$ = $1;
- else
- $$ = (XkbFile *)AppendStmt(&$1->common, &$2->common);
- }
+ { $$.head = $1.head; $$.last->common.next = &$2->common; $$.last = $2; }
| XkbMapConfig
- { $$ = $1; }
+ { $$.head = $$.last = $1; }
;
XkbMapConfig : OptFlags FileType OptMapName OBRACE
DeclList
CBRACE SEMI
{
- if ($2 == FILE_TYPE_GEOMETRY) {
- free($3);
- FreeStmt($5);
- $$ = NULL;
- }
- else {
- $$ = XkbFileCreate(param->ctx, $2, $3, $5, $1);
- }
+ $$ = XkbFileCreate($2, $3, $5.head, $1);
}
;
;
DeclList : DeclList Decl
- { $$ = AppendStmt($1, $2); }
- | { $$ = NULL; }
+ {
+ if ($2) {
+ if ($1.head) {
+ $$.head = $1.head; $1.last->next = $2; $$.last = $2;
+ } else {
+ $$.head = $$.last = $2;
+ }
+ }
+ }
+ /*
+ * VModDecl is "inlined" directly into DeclList, i.e.
+ * each VModDef in the VModDecl is a separate Decl in
+ * the File.
+ */
+ | DeclList OptMergeMode VModDecl
+ {
+ for (VModDef *vmod = $3.head; vmod; vmod = (VModDef *) vmod->common.next)
+ vmod->merge = $2;
+ if ($1.head) {
+ $$.head = $1.head; $1.last->next = &$3.head->common; $$.last = &$3.last->common;
+ } else {
+ $$.head = &$3.head->common; $$.last = &$3.last->common;
+ }
+ }
+ | { $$.head = $$.last = NULL; }
;
Decl : OptMergeMode VarDecl
{
$2->merge = $1;
- $$ = &$2->common;
- }
- | OptMergeMode VModDecl
- {
- $2->merge = $1;
- $$ = &$2->common;
+ $$ = (ParseCommon *) $2;
}
+ /* OptMergeMode VModDecl - see above. */
| OptMergeMode InterpretDecl
{
$2->merge = $1;
- $$ = &$2->common;
+ $$ = (ParseCommon *) $2;
}
| OptMergeMode KeyNameDecl
{
$2->merge = $1;
- $$ = &$2->common;
+ $$ = (ParseCommon *) $2;
}
| OptMergeMode KeyAliasDecl
{
$2->merge = $1;
- $$ = &$2->common;
+ $$ = (ParseCommon *) $2;
}
| OptMergeMode KeyTypeDecl
{
$2->merge = $1;
- $$ = &$2->common;
+ $$ = (ParseCommon *) $2;
}
| OptMergeMode SymbolsDecl
{
$2->merge = $1;
- $$ = &$2->common;
+ $$ = (ParseCommon *) $2;
}
| OptMergeMode ModMapDecl
{
$2->merge = $1;
- $$ = &$2->common;
+ $$ = (ParseCommon *) $2;
}
| OptMergeMode GroupCompatDecl
{
$2->merge = $1;
- $$ = &$2->common;
+ $$ = (ParseCommon *) $2;
}
| OptMergeMode LedMapDecl
{
$2->merge = $1;
- $$ = &$2->common;
+ $$ = (ParseCommon *) $2;
}
| OptMergeMode LedNameDecl
{
$2->merge = $1;
- $$ = &$2->common;
+ $$ = (ParseCommon *) $2;
}
| OptMergeMode ShapeDecl { $$ = NULL; }
| OptMergeMode SectionDecl { $$ = NULL; }
| OptMergeMode DoodadDecl { $$ = NULL; }
| MergeMode STRING
{
- $$ = &IncludeCreate(param->ctx, $2, $1)->common;
+ $$ = (ParseCommon *) IncludeCreate(param->ctx, $2, $1);
free($2);
}
;
VarDecl : Lhs EQUALS Expr SEMI
{ $$ = VarCreate($1, $3); }
| Ident SEMI
- { $$ = BoolVarCreate($1, 1); }
+ { $$ = BoolVarCreate($1, true); }
| EXCLAM Ident SEMI
- { $$ = BoolVarCreate($2, 0); }
+ { $$ = BoolVarCreate($2, false); }
;
KeyNameDecl : KEYNAME EQUALS KeyCode SEMI
;
VModDefList : VModDefList COMMA VModDef
- { $$ = (VModDef *)AppendStmt(&$1->common, &$3->common); }
+ { $$.head = $1.head; $$.last->common.next = &$3->common; $$.last = $3; }
| VModDef
- { $$ = $1; }
+ { $$.head = $$.last = $1; }
;
VModDef : Ident
InterpretDecl : INTERPRET InterpretMatch OBRACE
VarDeclList
CBRACE SEMI
- { $2->def = $4; $$ = $2; }
+ { $2->def = $4.head; $$ = $2; }
;
InterpretMatch : KeySym PLUS Expr
;
VarDeclList : VarDeclList VarDecl
- { $$ = (VarDef *)AppendStmt(&$1->common, &$2->common); }
+ { $$.head = $1.head; $$.last->common.next = &$2->common; $$.last = $2; }
| VarDecl
- { $$ = $1; }
+ { $$.head = $$.last = $1; }
;
KeyTypeDecl : TYPE String OBRACE
VarDeclList
CBRACE SEMI
- { $$ = KeyTypeCreate($2, $4); }
+ { $$ = KeyTypeCreate($2, $4.head); }
;
SymbolsDecl : KEY KEYNAME OBRACE
SymbolsBody
CBRACE SEMI
- { $$ = SymbolsCreate($2, (ExprDef *)$4); }
+ { $$ = SymbolsCreate($2, $4.head); }
;
SymbolsBody : SymbolsBody COMMA SymbolsVarDecl
- { $$ = (VarDef *)AppendStmt(&$1->common, &$3->common); }
+ { $$.head = $1.head; $$.last->common.next = &$3->common; $$.last = $3; }
| SymbolsVarDecl
- { $$ = $1; }
- | { $$ = NULL; }
+ { $$.head = $$.last = $1; }
+ | { $$.head = $$.last = NULL; }
;
SymbolsVarDecl : Lhs EQUALS Expr { $$ = VarCreate($1, $3); }
| Lhs EQUALS ArrayInit { $$ = VarCreate($1, $3); }
- | Ident { $$ = BoolVarCreate($1, 1); }
- | EXCLAM Ident { $$ = BoolVarCreate($2, 0); }
+ | Ident { $$ = BoolVarCreate($1, true); }
+ | EXCLAM Ident { $$ = BoolVarCreate($2, false); }
| ArrayInit { $$ = VarCreate(NULL, $1); }
;
ArrayInit : OBRACKET OptKeySymList CBRACKET
{ $$ = $2; }
| OBRACKET ActionList CBRACKET
- { $$ = ExprCreateUnary(EXPR_ACTION_LIST, EXPR_TYPE_ACTION, $2); }
+ { $$ = ExprCreateActionList($2.head); }
;
GroupCompatDecl : GROUP Integer EQUALS Expr SEMI
;
ModMapDecl : MODIFIER_MAP Ident OBRACE ExprList CBRACE SEMI
- { $$ = ModMapCreate($2, $4); }
+ { $$ = ModMapCreate($2, $4.head); }
;
LedMapDecl: INDICATOR String OBRACE VarDeclList CBRACE SEMI
- { $$ = LedMapCreate($2, $4); }
+ { $$ = LedMapCreate($2, $4.head); }
;
LedNameDecl: INDICATOR Integer EQUALS Expr SEMI
ShapeDecl : SHAPE String OBRACE OutlineList CBRACE SEMI
{ $$ = NULL; }
| SHAPE String OBRACE CoordList CBRACE SEMI
- { $$ = NULL; }
+ { (void) $4; $$ = NULL; }
;
SectionDecl : SECTION String OBRACE SectionBody CBRACE SEMI
SectionBodyItem : ROW OBRACE RowBody CBRACE SEMI
{ $$ = NULL; }
| VarDecl
- { FreeStmt(&$1->common); $$ = NULL; }
+ { FreeStmt((ParseCommon *) $1); $$ = NULL; }
| DoodadDecl
{ $$ = NULL; }
| LedMapDecl
- { FreeStmt(&$1->common); $$ = NULL; }
+ { FreeStmt((ParseCommon *) $1); $$ = NULL; }
| OverlayDecl
{ $$ = NULL; }
;
RowBodyItem : KEYS OBRACE Keys CBRACE SEMI { $$ = NULL; }
| VarDecl
- { FreeStmt(&$1->common); $$ = NULL; }
+ { FreeStmt((ParseCommon *) $1); $$ = NULL; }
;
Keys : Keys COMMA Key { $$ = NULL; }
Key : KEYNAME
{ $$ = NULL; }
| OBRACE ExprList CBRACE
- { FreeStmt(&$2->common); $$ = NULL; }
+ { FreeStmt((ParseCommon *) $2.head); $$ = NULL; }
;
OverlayDecl : OVERLAY String OBRACE OverlayKeyList CBRACE SEMI
;
OutlineInList : OBRACE CoordList CBRACE
- { $$ = NULL; }
+ { (void) $2; $$ = NULL; }
| Ident EQUALS OBRACE CoordList CBRACE
- { $$ = NULL; }
+ { (void) $4; $$ = NULL; }
| Ident EQUALS Expr
- { FreeStmt(&$3->common); $$ = NULL; }
+ { FreeStmt((ParseCommon *) $3); $$ = NULL; }
;
CoordList : CoordList COMMA Coord
- { $$ = NULL; }
+ { (void) $1; (void) $3; $$ = NULL; }
| Coord
- { $$ = NULL; }
+ { (void) $1; $$ = NULL; }
;
Coord : OBRACKET SignedNumber COMMA SignedNumber CBRACKET
;
DoodadDecl : DoodadType String OBRACE VarDeclList CBRACE SEMI
- { FreeStmt(&$4->common); $$ = NULL; }
+ { FreeStmt((ParseCommon *) $4.head); $$ = NULL; }
;
DoodadType : TEXT { $$ = 0; }
;
Element : ACTION_TOK
- { $$ = xkb_atom_intern(param->ctx, "action"); }
+ { $$ = xkb_atom_intern_literal(param->ctx, "action"); }
| INTERPRET
- { $$ = xkb_atom_intern(param->ctx, "interpret"); }
+ { $$ = xkb_atom_intern_literal(param->ctx, "interpret"); }
| TYPE
- { $$ = xkb_atom_intern(param->ctx, "type"); }
+ { $$ = xkb_atom_intern_literal(param->ctx, "type"); }
| KEY
- { $$ = xkb_atom_intern(param->ctx, "key"); }
+ { $$ = xkb_atom_intern_literal(param->ctx, "key"); }
| GROUP
- { $$ = xkb_atom_intern(param->ctx, "group"); }
+ { $$ = xkb_atom_intern_literal(param->ctx, "group"); }
| MODIFIER_MAP
- {$$ = xkb_atom_intern(param->ctx, "modifier_map");}
+ {$$ = xkb_atom_intern_literal(param->ctx, "modifier_map");}
| INDICATOR
- { $$ = xkb_atom_intern(param->ctx, "indicator"); }
+ { $$ = xkb_atom_intern_literal(param->ctx, "indicator"); }
| SHAPE
- { $$ = xkb_atom_intern(param->ctx, "shape"); }
+ { $$ = xkb_atom_intern_literal(param->ctx, "shape"); }
| ROW
- { $$ = XKB_ATOM_NONE; }
+ { $$ = xkb_atom_intern_literal(param->ctx, "row"); }
| SECTION
- { $$ = XKB_ATOM_NONE; }
+ { $$ = xkb_atom_intern_literal(param->ctx, "section"); }
| TEXT
- { $$ = XKB_ATOM_NONE; }
+ { $$ = xkb_atom_intern_literal(param->ctx, "text"); }
;
OptMergeMode : MergeMode { $$ = $1; }
;
OptExprList : ExprList { $$ = $1; }
- | { $$ = NULL; }
+ | { $$.head = $$.last = NULL; }
;
ExprList : ExprList COMMA Expr
- { $$ = (ExprDef *)AppendStmt(&$1->common, &$3->common); }
+ { $$.head = $1.head; $$.last->common.next = &$3->common; $$.last = $3; }
| Expr
- { $$ = $1; }
+ { $$.head = $$.last = $1; }
;
Expr : Expr DIVIDE Expr
;
Term : MINUS Term
- { $$ = ExprCreateUnary(EXPR_NEGATE, $2->value_type, $2); }
+ { $$ = ExprCreateUnary(EXPR_NEGATE, $2->expr.value_type, $2); }
| PLUS Term
- { $$ = ExprCreateUnary(EXPR_UNARY_PLUS, $2->value_type, $2); }
+ { $$ = ExprCreateUnary(EXPR_UNARY_PLUS, $2->expr.value_type, $2); }
| EXCLAM Term
{ $$ = ExprCreateUnary(EXPR_NOT, EXPR_TYPE_BOOLEAN, $2); }
| INVERT Term
- { $$ = ExprCreateUnary(EXPR_INVERT, $2->value_type, $2); }
+ { $$ = ExprCreateUnary(EXPR_INVERT, $2->expr.value_type, $2); }
| Lhs
{ $$ = $1; }
| FieldSpec OPAREN OptExprList CPAREN %prec OPAREN
- { $$ = ActionCreate($1, $3); }
+ { $$ = ExprCreateAction($1, $3.head); }
| Terminal
{ $$ = $1; }
| OPAREN Expr CPAREN
;
ActionList : ActionList COMMA Action
- { $$ = (ExprDef *)AppendStmt(&$1->common, &$3->common); }
+ { $$.head = $1.head; $$.last->common.next = &$3->common; $$.last = $3; }
| Action
- { $$ = $1; }
+ { $$.head = $$.last = $1; }
;
Action : FieldSpec OPAREN OptExprList CPAREN
- { $$ = ActionCreate($1, $3); }
+ { $$ = ExprCreateAction($1, $3.head); }
;
Lhs : FieldSpec
- {
- ExprDef *expr;
- expr = ExprCreate(EXPR_IDENT, EXPR_TYPE_UNKNOWN);
- expr->value.str = $1;
- $$ = expr;
- }
+ { $$ = ExprCreateIdent($1); }
| FieldSpec DOT FieldSpec
- {
- ExprDef *expr;
- expr = ExprCreate(EXPR_FIELD_REF, EXPR_TYPE_UNKNOWN);
- expr->value.field.element = $1;
- expr->value.field.field = $3;
- $$ = expr;
- }
+ { $$ = ExprCreateFieldRef($1, $3); }
| FieldSpec OBRACKET Expr CBRACKET
- {
- ExprDef *expr;
- expr = ExprCreate(EXPR_ARRAY_REF, EXPR_TYPE_UNKNOWN);
- expr->value.array.element = XKB_ATOM_NONE;
- expr->value.array.field = $1;
- expr->value.array.entry = $3;
- $$ = expr;
- }
+ { $$ = ExprCreateArrayRef(XKB_ATOM_NONE, $1, $3); }
| FieldSpec DOT FieldSpec OBRACKET Expr CBRACKET
- {
- ExprDef *expr;
- expr = ExprCreate(EXPR_ARRAY_REF, EXPR_TYPE_UNKNOWN);
- expr->value.array.element = $1;
- expr->value.array.field = $3;
- expr->value.array.entry = $5;
- $$ = expr;
- }
+ { $$ = ExprCreateArrayRef($1, $3, $5); }
;
Terminal : String
- {
- ExprDef *expr;
- expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_STRING);
- expr->value.str = $1;
- $$ = expr;
- }
+ { $$ = ExprCreateString($1); }
| Integer
- {
- ExprDef *expr;
- expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_INT);
- expr->value.ival = $1;
- $$ = expr;
- }
+ { $$ = ExprCreateInteger($1); }
| Float
- {
- $$ = NULL;
- }
+ { $$ = ExprCreateFloat(/* Discard $1 */); }
| KEYNAME
- {
- ExprDef *expr;
- expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_KEYNAME);
- expr->value.keyName = $1;
- $$ = expr;
- }
+ { $$ = ExprCreateKeyName($1); }
;
OptKeySymList : KeySymList { $$ = $1; }
;
KeySymList : KeySymList COMMA KeySym
- { $$ = AppendKeysymList($1, $3); }
+ { $$ = ExprAppendKeysymList($1, $3); }
| KeySymList COMMA KeySyms
- { $$ = AppendMultiKeysymList($1, $3); }
+ { $$ = ExprAppendMultiKeysymList($1, $3); }
| KeySym
- { $$ = CreateKeysymList($1); }
+ { $$ = ExprCreateKeysymList($1); }
| KeySyms
- { $$ = CreateMultiKeysymList($1); }
+ { $$ = ExprCreateMultiKeysymList($1); }
;
KeySyms : OBRACE KeySymList CBRACE
{ $$ = $2; }
;
-KeySym : IDENT { $$ = $1; }
- | SECTION { $$ = strdup("section"); }
+KeySym : IDENT
+ {
+ if (!resolve_keysym($1, &$$)) {
+ parser_warn(
+ param,
+ XKB_WARNING_UNRECOGNIZED_KEYSYM,
+ "unrecognized keysym \"%s\"",
+ $1
+ );
+ $$ = XKB_KEY_NoSymbol;
+ }
+ free($1);
+ }
+ | SECTION { $$ = XKB_KEY_section; }
| Integer
{
- if ($1 < 10) { /* XK_0 .. XK_9 */
- $$ = malloc(2);
- $$[0] = $1 + '0';
- $$[1] = '\0';
+ if ($1 < XKB_KEYSYM_MIN) {
+ parser_warn(
+ param,
+ XKB_WARNING_UNRECOGNIZED_KEYSYM,
+ "unrecognized keysym \"%"PRId64"\"",
+ $1
+ );
+ $$ = XKB_KEY_NoSymbol;
+ }
+ /* Special case for digits 0..9 */
+ else if ($1 < 10) { /* XKB_KEY_0 .. XKB_KEY_9 */
+ $$ = XKB_KEY_0 + (xkb_keysym_t) $1;
}
else {
- $$ = malloc(17);
- snprintf($$, 17, "0x%x", $1);
+ if ($1 <= XKB_KEYSYM_MAX) {
+ $$ = (xkb_keysym_t) $1;
+ } else {
+ parser_warn(
+ param, XKB_WARNING_UNRECOGNIZED_KEYSYM,
+ "unrecognized keysym \"0x%"PRIx64"\" "
+ "(%"PRId64")", $1, $1
+ );
+ $$ = XKB_KEY_NoSymbol;
+ }
+ parser_warn(
+ param, XKB_WARNING_NUMERIC_KEYSYM,
+ "numeric keysym \"0x%"PRIx64"\" (%"PRId64")",
+ $1, $1
+ );
}
}
;
KeyCode : INTEGER { $$ = $1; }
;
-Ident : IDENT { $$ = xkb_atom_steal(param->ctx, $1); }
- | DEFAULT { $$ = xkb_atom_intern(param->ctx, "default"); }
+Ident : IDENT { $$ = xkb_atom_intern(param->ctx, $1, strlen($1)); free($1); }
+ | DEFAULT { $$ = xkb_atom_intern_literal(param->ctx, "default"); }
;
-String : STRING { $$ = xkb_atom_steal(param->ctx, $1); }
+String : STRING { $$ = xkb_atom_intern(param->ctx, $1, strlen($1)); free($1); }
;
OptMapName : MapName { $$ = $1; }
%%
-#undef scanner
-
XkbFile *
-parse(struct xkb_context *ctx, void *scanner, const char *map)
+parse(struct xkb_context *ctx, struct scanner *scanner, const char *map)
{
- struct parser_param param;
int ret;
XkbFile *first = NULL;
-
- param.scanner = scanner;
- param.ctx = ctx;
+ struct parser_param param = {
+ .scanner = scanner,
+ .ctx = ctx,
+ .rtrn = NULL,
+ .more_maps = false,
+ };
/*
* If we got a specific map, we look for it exclusively and return
FreeXkbFile(param.rtrn);
}
}
+ param.rtrn = NULL;
}
if (ret != 0) {
return NULL;
}
+ if (first)
+ log_vrb(ctx, 5,
+ XKB_WARNING_MISSING_DEFAULT_SECTION,
+ "No map in include statement, but \"%s\" contains several; "
+ "Using first defined map, \"%s\"\n",
+ scanner->file_name, first->name);
+
return first;
}