1 /* $OpenBSD: map_parse.y,v 1.7 2012/07/14 08:27:05 shadchin Exp $ */ 2 /* $NetBSD: map_parse.y,v 1.2 1999/02/08 11:08:23 hannken Exp $ */ 3 4 /*- 5 * Copyright (c) 1998 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Juergen Hannken-Illjes. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* Parse a keyboard map. Statements are one of 34 * 35 * keysym sym1 = sym2 Assign the key containing `sym2' to 36 * the key containing `sym1'. This is a copy 37 * from the old to the new map. Therefore it 38 * is possible to exchange keys. 39 * 40 * keycode pos = sym ... assign the symbols to key `pos'. 41 * The first symbol may be a command. 42 * The following symbols are assigned 43 * to the normal and altgr groups. 44 * Missing symbols are generated automatically 45 * as either the upper case variant or the 46 * normal group. 47 */ 48 49 %{ 50 51 #include <sys/time.h> 52 #include <dev/wscons/wsksymdef.h> 53 #include <dev/wscons/wsconsio.h> 54 #include <err.h> 55 #include "wsconsctl.h" 56 57 extern struct wskbd_map_data kbmap; /* from keyboard.c */ 58 59 static struct wscons_keymap mapdata[KS_NUMKEYCODES]; 60 struct wskbd_map_data newkbmap; /* used in util.c */ 61 static struct wscons_keymap *cur_mp; 62 63 static int ksym_lookup(keysym_t); 64 65 static int 66 ksym_lookup(keysym_t ksym) 67 { 68 int i; 69 struct wscons_keymap *mp; 70 71 for (i = 0; i < kbmap.maplen; i++) { 72 mp = kbmap.map + i; 73 if (mp->command == ksym || 74 mp->group1[0] == ksym || mp->group1[1] == ksym || 75 mp->group2[0] == ksym || mp->group2[1] == ksym) 76 return(i); 77 } 78 79 errx(1, "keysym %s not found", ksym2name(ksym)); 80 } 81 82 %} 83 84 %union { 85 keysym_t kval; 86 int ival; 87 } 88 89 %token T_KEYSYM T_KEYCODE 90 %token <kval> T_KEYSYM_VAR T_KEYSYM_CMD_VAR 91 %token <ival> T_NUMBER 92 93 %type <kval> keysym_var 94 95 %% 96 97 program : = { 98 int i; 99 struct wscons_keymap *mp; 100 101 for (i = 0; i < KS_NUMKEYCODES; i++) { 102 mp = mapdata + i; 103 mp->command = KS_voidSymbol; 104 mp->group1[0] = KS_voidSymbol; 105 mp->group1[1] = KS_voidSymbol; 106 mp->group2[0] = KS_voidSymbol; 107 mp->group2[1] = KS_voidSymbol; 108 } 109 110 newkbmap.maplen = 0; 111 newkbmap.map = mapdata; 112 } expr_list 113 ; 114 115 expr_list : expr 116 | expr_list expr 117 ; 118 119 expr : keysym_expr 120 | keycode_expr 121 ; 122 123 keysym_expr : T_KEYSYM keysym_var "=" keysym_var = { 124 int src, dst; 125 126 dst = ksym_lookup($2); 127 src = ksym_lookup($4); 128 newkbmap.map[dst] = kbmap.map[src]; 129 if (dst >= newkbmap.maplen) 130 newkbmap.maplen = dst + 1; 131 } 132 ; 133 134 keycode_expr : T_KEYCODE T_NUMBER "=" = { 135 if ($2 >= KS_NUMKEYCODES) 136 errx(1, "%d: keycode too large", $2); 137 if ($2 >= newkbmap.maplen) 138 newkbmap.maplen = $2 + 1; 139 cur_mp = mapdata + $2; 140 } keysym_cmd keysym_list 141 ; 142 143 keysym_cmd : /* empty */ 144 | T_KEYSYM_CMD_VAR = { 145 cur_mp->command = $1; 146 } 147 ; 148 149 keysym_list : keysym_var = { 150 cur_mp->group1[0] = $1; 151 cur_mp->group1[1] = ksym_upcase(cur_mp->group1[0]); 152 cur_mp->group2[0] = cur_mp->group1[0]; 153 cur_mp->group2[1] = cur_mp->group1[1]; 154 } 155 | keysym_var keysym_var = { 156 cur_mp->group1[0] = $1; 157 cur_mp->group1[1] = $2; 158 cur_mp->group2[0] = cur_mp->group1[0]; 159 cur_mp->group2[1] = cur_mp->group1[1]; 160 } 161 | keysym_var keysym_var keysym_var = { 162 cur_mp->group1[0] = $1; 163 cur_mp->group1[1] = $2; 164 cur_mp->group2[0] = $3; 165 cur_mp->group2[1] = ksym_upcase(cur_mp->group2[0]); 166 } 167 | keysym_var keysym_var keysym_var keysym_var = { 168 cur_mp->group1[0] = $1; 169 cur_mp->group1[1] = $2; 170 cur_mp->group2[0] = $3; 171 cur_mp->group2[1] = $4; 172 } 173 ; 174 175 keysym_var : T_KEYSYM_VAR = { 176 $$ = $1; 177 } 178 | T_NUMBER = { 179 char name[2]; 180 int res; 181 182 if ($1 < 0 || $1 > 9) 183 yyerror("keysym expected"); 184 name[0] = $1 + '0'; 185 name[1] = '\0'; 186 res = name2ksym(name); 187 if (res < 0) 188 yyerror("keysym expected"); 189 $$ = res; 190 } 191 ; 192 %% 193 194 void 195 yyerror(char *msg) 196 { 197 errx(1, "parse: %s", msg); 198 } 199