X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fxkbcomp%2Fparser.y;h=1beb30bbe62ca73c58d560331af46047da621bd7;hb=ef81d04eef4b1a60ff42bd9ccbe2918b0a5420ec;hp=d9f6cbc0cfbd305cedb50d4d640f19bc52a4dc5a;hpb=28d5f7708cac3b78e62cc47768a4a9956300a6de;p=platform%2Fupstream%2Flibxkbcommon.git diff --git a/src/xkbcomp/parser.y b/src/xkbcomp/parser.y index d9f6cbc..1beb30b 100644 --- a/src/xkbcomp/parser.y +++ b/src/xkbcomp/parser.y @@ -31,9 +31,13 @@ */ %{ -#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; @@ -42,34 +46,34 @@ struct parser_param { bool more_maps; }; -#define parser_err(param, fmt, ...) \ - scanner_err((param)->scanner, fmt, ##__VA_ARGS__) +#define parser_err(param, error_id, fmt, ...) \ + scanner_err_with_code((param)->scanner, error_id, fmt, ##__VA_ARGS__) -#define parser_warn(param, fmt, ...) \ - scanner_warn((param)->scanner, 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 parser_param *param, const char *msg) { - parser_err(param, "%s", msg); + parser_err(param, XKB_ERROR_INVALID_SYNTAX, "%s", msg); } static bool -resolve_keysym(const char *str, xkb_keysym_t *sym_rtrn) +resolve_keysym(const char *name, xkb_keysym_t *sym_rtrn) { xkb_keysym_t sym; - if (!str || istreq(str, "any") || istreq(str, "nosymbol")) { + if (!name || istreq(name, "any") || istreq(name, "nosymbol")) { *sym_rtrn = XKB_KEY_NoSymbol; return true; } - if (istreq(str, "none") || istreq(str, "voidsymbol")) { + if (istreq(name, "none") || istreq(name, "voidsymbol")) { *sym_rtrn = XKB_KEY_VoidSymbol; return true; } - sym = xkb_keysym_from_name(str, XKB_KEYSYM_NO_FLAGS); + sym = xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS); if (sym != XKB_KEY_NoSymbol) { *sym_rtrn = sym; return true; @@ -81,7 +85,7 @@ resolve_keysym(const char *str, xkb_keysym_t *sym_rtrn) #define param_scanner param->scanner %} -%pure-parser +%define api.pure %lex-param { struct scanner *param_scanner } %parse-param { struct parser_param *param } @@ -159,18 +163,21 @@ resolve_keysym(const char *str, xkb_keysym_t *sym_rtrn) %start XkbFile %union { - int ival; 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; @@ -182,24 +189,28 @@ resolve_keysym(const char *str, xkb_keysym_t *sym_rtrn) KeyAliasDef *keyAlias; void *geom; XkbFile *file; + struct { XkbFile *head; XkbFile *last; } fileList; } %type INTEGER FLOAT %type IDENT STRING -%type KEYNAME -%type KeyCode -%type Number Integer Float SignedNumber DoodadType +%type KEYNAME +%type KeyCode Number Integer Float SignedNumber DoodadType %type MergeMode OptMergeMode %type XkbCompositeType FileType %type Flag Flags OptFlags %type MapName OptMapName -%type FieldSpec Ident Element String +%type FieldSpec Ident Element String %type KeySym -%type DeclList Decl -%type OptExprList ExprList Expr Term Lhs Terminal ArrayInit KeySyms -%type OptKeySymList KeySymList Action ActionList Coord CoordList -%type VarDecl VarDeclList SymbolsBody SymbolsVarDecl -%type VModDecl VModDefList VModDef +%type Decl +%type DeclList +%type Expr Term Lhs Terminal ArrayInit KeySyms +%type OptKeySymList KeySymList Action Coord CoordList +%type OptExprList ExprList ActionList +%type VarDecl SymbolsVarDecl +%type VarDeclList SymbolsBody +%type VModDef +%type VModDefList VModDecl %type InterpretDecl InterpretMatch %type KeyTypeDecl %type SymbolsDecl @@ -212,9 +223,21 @@ resolve_keysym(const char *str, xkb_keysym_t *sym_rtrn) %type ShapeDecl SectionDecl SectionBody SectionBodyItem RowBody RowBodyItem %type Keys Key OverlayDecl OverlayKeyList OverlayKey OutlineList OutlineInList %type DoodadDecl -%type XkbFile XkbMapConfigList XkbMapConfig +%type XkbFile XkbMapConfig +%type XkbMapConfigList %type XkbCompositeMap +%destructor { FreeStmt((ParseCommon *) $$); } + + +%destructor { FreeStmt((ParseCommon *) $$.head); } + +/* The destructor also runs on the start symbol when the parser *succeeds*. + * The `if` here catches this case. */ +%destructor { if (!param->rtrn) FreeXkbFile($$); } +%destructor { FreeXkbFile($$.head); } +%destructor { free($$); } + %% /* @@ -230,9 +253,9 @@ resolve_keysym(const char *str, xkb_keysym_t *sym_rtrn) */ 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; } ; @@ -240,7 +263,7 @@ XkbFile : XkbCompositeMap XkbCompositeMap : OptFlags XkbCompositeType OptMapName OBRACE XkbMapConfigList CBRACE SEMI - { $$ = XkbFileCreate($2, $3, &$5->common, $1); } + { $$ = XkbFileCreate($2, $3, (ParseCommon *) $5.head, $1); } ; XkbCompositeType: XKB_KEYMAP { $$ = FILE_TYPE_KEYMAP; } @@ -249,28 +272,16 @@ 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($2, $3, $5, $1); - } + $$ = XkbFileCreate($2, $3, $5.head, $1); } ; @@ -300,71 +311,90 @@ Flag : PARTIAL { $$ = MAP_IS_PARTIAL; } ; 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); } ; @@ -390,9 +420,9 @@ VModDecl : VIRTUAL_MODS VModDefList 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 @@ -404,7 +434,7 @@ VModDef : Ident InterpretDecl : INTERPRET InterpretMatch OBRACE VarDeclList CBRACE SEMI - { $2->def = $4; $$ = $2; } + { $2->def = $4.head; $$ = $2; } ; InterpretMatch : KeySym PLUS Expr @@ -414,28 +444,28 @@ 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, $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); } @@ -448,7 +478,7 @@ SymbolsVarDecl : Lhs EQUALS Expr { $$ = VarCreate($1, $3); } 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 @@ -456,11 +486,11 @@ 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 @@ -472,7 +502,7 @@ 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 @@ -486,11 +516,11 @@ SectionBody : SectionBody SectionBodyItem { $$ = NULL;} 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; } ; @@ -501,7 +531,7 @@ RowBody : RowBody RowBodyItem { $$ = NULL;} RowBodyItem : KEYS OBRACE Keys CBRACE SEMI { $$ = NULL; } | VarDecl - { FreeStmt(&$1->common); $$ = NULL; } + { FreeStmt((ParseCommon *) $1); $$ = NULL; } ; Keys : Keys COMMA Key { $$ = NULL; } @@ -511,7 +541,7 @@ 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 @@ -532,17 +562,17 @@ OutlineList : OutlineList COMMA OutlineInList ; 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 @@ -550,7 +580,7 @@ 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; } @@ -578,13 +608,13 @@ Element : ACTION_TOK | INDICATOR { $$ = xkb_atom_intern_literal(param->ctx, "indicator"); } | SHAPE - { $$ = XKB_ATOM_NONE; } + { $$ = 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; } @@ -606,13 +636,13 @@ MergeMode : INCLUDE { $$ = MERGE_DEFAULT; } ; 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 @@ -640,7 +670,7 @@ Term : MINUS Term | Lhs { $$ = $1; } | FieldSpec OPAREN OptExprList CPAREN %prec OPAREN - { $$ = ExprCreateAction($1, $3); } + { $$ = ExprCreateAction($1, $3.head); } | Terminal { $$ = $1; } | OPAREN Expr CPAREN @@ -648,13 +678,13 @@ Term : MINUS Term ; 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 - { $$ = ExprCreateAction($1, $3); } + { $$ = ExprCreateAction($1, $3.head); } ; Lhs : FieldSpec @@ -672,7 +702,7 @@ Terminal : String | Integer { $$ = ExprCreateInteger($1); } | Float - { $$ = NULL; } + { $$ = ExprCreateFloat(/* Discard $1 */); } | KEYNAME { $$ = ExprCreateKeyName($1); } ; @@ -697,25 +727,42 @@ KeySyms : OBRACE KeySymList CBRACE KeySym : IDENT { - if (!resolve_keysym($1, &$$)) - parser_warn(param, "unrecognized keysym"); + 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 < 0) { - parser_warn(param, "unrecognized keysym"); + 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 { - char buf[17]; - snprintf(buf, sizeof(buf), "0x%x", $1); - if (!resolve_keysym(buf, &$$)) { - parser_warn(param, "unrecognized keysym"); + 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; } } @@ -739,11 +786,11 @@ Integer : INTEGER { $$ = $1; } KeyCode : INTEGER { $$ = $1; } ; -Ident : IDENT { $$ = xkb_atom_steal(param->ctx, $1); } +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; } @@ -763,6 +810,8 @@ parse(struct xkb_context *ctx, struct scanner *scanner, const char *map) struct parser_param param = { .scanner = scanner, .ctx = ctx, + .rtrn = NULL, + .more_maps = false, }; /* @@ -792,6 +841,7 @@ parse(struct xkb_context *ctx, struct scanner *scanner, const char *map) FreeXkbFile(param.rtrn); } } + param.rtrn = NULL; } if (ret != 0) { @@ -799,5 +849,11 @@ parse(struct xkb_context *ctx, struct scanner *scanner, const char *map) return NULL; } + if (first) + log_vrb(ctx, 5, + "No map in include statement, but \"%s\" contains several; " + "Using first defined map, \"%s\"\n", + scanner->file_name, first->name); + return first; }