Resolve keysyms early in parser
Instead of having the parser passing strings to the AST, and symbols/compat etc. resolving them themselves. This simplifies the code a bit, and makes it possible to print where exactly in the file the bad keysym originates from. The previous lazy approach had an advantage of not needlessly resolving keysyms from unrelated maps. However, I think reporting these errors in *any* map is better, and the parser is also a bit smarter then old xkbcomp and doesn't parse many useless maps. So there's no discernible speed/memory difference with this change. Signed-off-by: Ran Benita <ran234@gmail.com>master
parent
ba7530fa90
commit
9dc5b8cb60
|
@ -201,7 +201,7 @@ BoolVarCreate(xkb_atom_t nameToken, unsigned set)
|
|||
}
|
||||
|
||||
InterpDef *
|
||||
InterpCreate(char *sym, ExprDef *match)
|
||||
InterpCreate(xkb_keysym_t sym, ExprDef *match)
|
||||
{
|
||||
InterpDef *def = malloc(sizeof(*def));
|
||||
if (!def)
|
||||
|
@ -329,7 +329,7 @@ ActionCreate(xkb_atom_t name, ExprDef *args)
|
|||
}
|
||||
|
||||
ExprDef *
|
||||
CreateKeysymList(char *sym)
|
||||
CreateKeysymList(xkb_keysym_t sym)
|
||||
{
|
||||
ExprDef *def;
|
||||
|
||||
|
@ -360,7 +360,7 @@ CreateMultiKeysymList(ExprDef *list)
|
|||
}
|
||||
|
||||
ExprDef *
|
||||
AppendKeysymList(ExprDef *list, char *sym)
|
||||
AppendKeysymList(ExprDef *list, xkb_keysym_t sym)
|
||||
{
|
||||
size_t nSyms = darray_size(list->value.list.syms);
|
||||
|
||||
|
@ -549,8 +549,6 @@ err:
|
|||
static void
|
||||
FreeExpr(ExprDef *expr)
|
||||
{
|
||||
char **sym;
|
||||
|
||||
if (!expr)
|
||||
return;
|
||||
|
||||
|
@ -581,8 +579,6 @@ FreeExpr(ExprDef *expr)
|
|||
break;
|
||||
|
||||
case EXPR_KEYSYM_LIST:
|
||||
darray_foreach(sym, expr->value.list.syms)
|
||||
free(*sym);
|
||||
darray_free(expr->value.list.syms);
|
||||
darray_free(expr->value.list.symsMapIndex);
|
||||
darray_free(expr->value.list.symsNumEntries);
|
||||
|
@ -640,7 +636,6 @@ FreeStmt(ParseCommon *stmt)
|
|||
FreeStmt(&u.keyType->body->common);
|
||||
break;
|
||||
case STMT_INTERP:
|
||||
free(u.interp->sym);
|
||||
FreeStmt(&u.interp->match->common);
|
||||
FreeStmt(&u.interp->def->common);
|
||||
break;
|
||||
|
|
|
@ -56,7 +56,7 @@ VarDef *
|
|||
BoolVarCreate(xkb_atom_t nameToken, unsigned set);
|
||||
|
||||
InterpDef *
|
||||
InterpCreate(char *sym, ExprDef *match);
|
||||
InterpCreate(xkb_keysym_t sym, ExprDef *match);
|
||||
|
||||
KeyTypeDef *
|
||||
KeyTypeCreate(xkb_atom_t name, VarDef *body);
|
||||
|
@ -83,13 +83,13 @@ ExprDef *
|
|||
CreateMultiKeysymList(ExprDef *list);
|
||||
|
||||
ExprDef *
|
||||
CreateKeysymList(char *sym);
|
||||
CreateKeysymList(xkb_keysym_t sym);
|
||||
|
||||
ExprDef *
|
||||
AppendMultiKeysymList(ExprDef *list, ExprDef *append);
|
||||
|
||||
ExprDef *
|
||||
AppendKeysymList(ExprDef *list, char *sym);
|
||||
AppendKeysymList(ExprDef *list, xkb_keysym_t sym);
|
||||
|
||||
IncludeStmt *
|
||||
IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge);
|
||||
|
|
|
@ -181,7 +181,7 @@ typedef struct _Expr {
|
|||
struct _Expr *args;
|
||||
} action;
|
||||
struct {
|
||||
darray(char *) syms;
|
||||
darray(xkb_keysym_t) syms;
|
||||
darray(int) symsMapIndex;
|
||||
darray(unsigned int) symsNumEntries;
|
||||
} list;
|
||||
|
@ -252,7 +252,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
ParseCommon common;
|
||||
enum merge_mode merge;
|
||||
char *sym;
|
||||
xkb_keysym_t sym;
|
||||
ExprDef *match;
|
||||
VarDef *def;
|
||||
} InterpDef;
|
||||
|
|
|
@ -840,15 +840,7 @@ HandleInterpDef(CompatInfo *info, InterpDef *def, enum merge_mode merge)
|
|||
|
||||
si = info->default_interp;
|
||||
si.merge = merge = (def->merge == MERGE_DEFAULT ? merge : def->merge);
|
||||
|
||||
if (!LookupKeysym(def->sym, &si.interp.sym)) {
|
||||
log_err(info->keymap->ctx,
|
||||
"Could not resolve keysym %s; "
|
||||
"Symbol interpretation ignored\n",
|
||||
def->sym);
|
||||
return false;
|
||||
}
|
||||
|
||||
si.interp.sym = def->sym;
|
||||
si.interp.match = pred;
|
||||
si.interp.mods = mods;
|
||||
|
||||
|
|
|
@ -43,11 +43,47 @@ struct parser_param {
|
|||
};
|
||||
|
||||
static void
|
||||
_xkbcommon_error(struct parser_param *param, const char *msg)
|
||||
parser_error(struct parser_param *param, const char *msg)
|
||||
{
|
||||
scanner_error(param->scanner, msg);
|
||||
}
|
||||
|
||||
static void
|
||||
parser_warn(struct parser_param *param, const char *msg)
|
||||
{
|
||||
scanner_warn(param->scanner, msg);
|
||||
}
|
||||
|
||||
static void
|
||||
_xkbcommon_error(struct parser_param *param, const char *msg)
|
||||
{
|
||||
parser_error(param, msg);
|
||||
}
|
||||
|
||||
static bool
|
||||
resolve_keysym(const char *str, xkb_keysym_t *sym_rtrn)
|
||||
{
|
||||
xkb_keysym_t sym;
|
||||
|
||||
if (!str || istreq(str, "any") || istreq(str, "nosymbol")) {
|
||||
*sym_rtrn = XKB_KEY_NoSymbol;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (istreq(str, "none") || istreq(str, "voidsymbol")) {
|
||||
*sym_rtrn = XKB_KEY_VoidSymbol;
|
||||
return true;
|
||||
}
|
||||
|
||||
sym = xkb_keysym_from_name(str, XKB_KEYSYM_NO_FLAGS);
|
||||
if (sym != XKB_KEY_NoSymbol) {
|
||||
*sym_rtrn = sym;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#define scanner param->scanner
|
||||
%}
|
||||
|
||||
|
@ -137,6 +173,7 @@ _xkbcommon_error(struct parser_param *param, const char *msg)
|
|||
xkb_atom_t sval;
|
||||
enum merge_mode merge;
|
||||
enum xkb_map_flags mapFlags;
|
||||
xkb_keysym_t keysym;
|
||||
ParseCommon *any;
|
||||
ExprDef *expr;
|
||||
VarDef *var;
|
||||
|
@ -163,8 +200,9 @@ _xkbcommon_error(struct parser_param *param, const char *msg)
|
|||
%type <file_type> XkbCompositeType FileType
|
||||
%type <uval> DoodadType
|
||||
%type <mapFlags> Flag Flags OptFlags
|
||||
%type <str> MapName OptMapName KeySym
|
||||
%type <str> MapName OptMapName
|
||||
%type <sval> FieldSpec Ident Element String
|
||||
%type <keysym> KeySym
|
||||
%type <any> DeclList Decl
|
||||
%type <expr> OptExprList ExprList Expr Term Lhs Terminal ArrayInit KeySyms
|
||||
%type <expr> OptKeySymList KeySymList Action ActionList Coord CoordList
|
||||
|
@ -707,18 +745,23 @@ KeySyms : OBRACE KeySymList CBRACE
|
|||
{ $$ = $2; }
|
||||
;
|
||||
|
||||
KeySym : IDENT { $$ = $1; }
|
||||
| SECTION { $$ = strdup("section"); }
|
||||
KeySym : IDENT
|
||||
{
|
||||
if (!resolve_keysym($1, &$$))
|
||||
parser_warn(param, "unrecognized keysym");
|
||||
free($1);
|
||||
}
|
||||
| SECTION { $$ = XKB_KEY_section; }
|
||||
| Integer
|
||||
{
|
||||
if ($1 < 10) { /* XK_0 .. XK_9 */
|
||||
$$ = malloc(2);
|
||||
$$[0] = $1 + '0';
|
||||
$$[1] = '\0';
|
||||
if ($1 < 10) { /* XKB_KEY_0 .. XKB_KEY_9 */
|
||||
$$ = XKB_KEY_0 + $1;
|
||||
}
|
||||
else {
|
||||
$$ = malloc(17);
|
||||
snprintf($$, 17, "0x%x", $1);
|
||||
char buf[17];
|
||||
snprintf(buf, sizeof(buf), "0x%x", $1);
|
||||
if (!resolve_keysym(buf, &$$))
|
||||
parser_warn(param, "unrecognized keysym");
|
||||
}
|
||||
}
|
||||
;
|
||||
|
|
|
@ -626,30 +626,6 @@ GetGroupIndex(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
LookupKeysym(const char *str, xkb_keysym_t *sym_rtrn)
|
||||
{
|
||||
xkb_keysym_t sym;
|
||||
|
||||
if (!str || istreq(str, "any") || istreq(str, "nosymbol")) {
|
||||
*sym_rtrn = XKB_KEY_NoSymbol;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (istreq(str, "none") || istreq(str, "voidsymbol")) {
|
||||
*sym_rtrn = XKB_KEY_VoidSymbol;
|
||||
return true;
|
||||
}
|
||||
|
||||
sym = xkb_keysym_from_name(str, XKB_KEYSYM_NO_FLAGS);
|
||||
if (sym != XKB_KEY_NoSymbol) {
|
||||
*sym_rtrn = sym;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
|
||||
ExprDef *value)
|
||||
|
@ -703,28 +679,8 @@ AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
|
|||
leveli->u.syms = calloc(leveli->num_syms, sizeof(*leveli->u.syms));
|
||||
|
||||
for (j = 0; j < leveli->num_syms; j++) {
|
||||
char *sym_name = darray_item(value->value.list.syms,
|
||||
sym_index + j);
|
||||
xkb_keysym_t keysym;
|
||||
|
||||
if (!LookupKeysym(sym_name, &keysym)) {
|
||||
const char *group_name = "unnamed";
|
||||
|
||||
if (ndx < darray_size(info->group_names) &&
|
||||
darray_item(info->group_names, ndx))
|
||||
group_name = xkb_atom_text(info->keymap->ctx,
|
||||
darray_item(info->group_names,
|
||||
ndx));
|
||||
|
||||
log_warn(info->keymap->ctx,
|
||||
"Could not resolve keysym %s for key %s, group %u (%s), level %u\n",
|
||||
sym_name, KeyInfoText(info, keyi), ndx + 1,
|
||||
group_name, i);
|
||||
|
||||
ClearLevelInfo(leveli);
|
||||
leveli->num_syms = 0;
|
||||
break;
|
||||
}
|
||||
xkb_keysym_t keysym = darray_item(value->value.list.syms,
|
||||
sym_index + j);
|
||||
|
||||
if (leveli->num_syms == 1) {
|
||||
if (keysym == XKB_KEY_NoSymbol)
|
||||
|
|
|
@ -79,9 +79,6 @@ bool
|
|||
CompileKeymap(XkbFile *file, struct xkb_keymap *keymap,
|
||||
enum merge_mode merge);
|
||||
|
||||
bool
|
||||
LookupKeysym(const char *str, xkb_keysym_t *sym_rtrn);
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static inline bool
|
||||
|
|
Loading…
Reference in New Issue