1 /* $OpenBSD: map_parse.y,v 1.5 2012/01/31 18:32:52 deraadt 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 automacically 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(ksym) 67 keysym_t ksym; 68 { 69 int i; 70 struct wscons_keymap *mp; 71 72 for (i = 0; i < kbmap.maplen; i++) { 73 mp = kbmap.map + i; 74 if (mp->command == ksym || 75 mp->group1[0] == ksym || mp->group1[1] == ksym || 76 mp->group2[0] == ksym || mp->group2[1] == ksym) 77 return(i); 78 } 79 80 errx(1, "keysym %s not found", ksym2name(ksym)); 81 } 82 83 %} 84 85 %union { 86 keysym_t kval; 87 int ival; 88 } 89 90 %token T_KEYSYM T_KEYCODE 91 %token <kval> T_KEYSYM_VAR T_KEYSYM_CMD_VAR 92 %token <ival> T_NUMBER 93 94 %type <kval> keysym_var 95 96 %% 97 98 program : = { 99 int i; 100 struct wscons_keymap *mp; 101 102 for (i = 0; i < KS_NUMKEYCODES; i++) { 103 mp = mapdata + i; 104 mp->command = KS_voidSymbol; 105 mp->group1[0] = KS_voidSymbol; 106 mp->group1[1] = KS_voidSymbol; 107 mp->group2[0] = KS_voidSymbol; 108 mp->group2[1] = KS_voidSymbol; 109 } 110 111 newkbmap.maplen = 0; 112 newkbmap.map = mapdata; 113 } expr_list 114 ; 115 116 expr_list : expr 117 | expr_list expr 118 ; 119 120 expr : keysym_expr 121 | keycode_expr 122 ; 123 124 keysym_expr : T_KEYSYM keysym_var "=" keysym_var = { 125 int src, dst; 126 127 dst = ksym_lookup($2); 128 src = ksym_lookup($4); 129 newkbmap.map[dst] = kbmap.map[src]; 130 if (dst >= newkbmap.maplen) 131 newkbmap.maplen = dst + 1; 132 } 133 ; 134 135 keycode_expr : T_KEYCODE T_NUMBER "=" = { 136 if ($2 >= KS_NUMKEYCODES) 137 errx(1, "%d: keycode too large", $2); 138 if ($2 >= newkbmap.maplen) 139 newkbmap.maplen = $2 + 1; 140 cur_mp = mapdata + $2; 141 } keysym_cmd keysym_list 142 ; 143 144 keysym_cmd : /* empty */ 145 | T_KEYSYM_CMD_VAR = { 146 cur_mp->command = $1; 147 } 148 ; 149 150 keysym_list : keysym_var = { 151 cur_mp->group1[0] = $1; 152 cur_mp->group1[1] = ksym_upcase(cur_mp->group1[0]); 153 cur_mp->group2[0] = cur_mp->group1[0]; 154 cur_mp->group2[1] = cur_mp->group1[1]; 155 } 156 | keysym_var keysym_var = { 157 cur_mp->group1[0] = $1; 158 cur_mp->group1[1] = $2; 159 cur_mp->group2[0] = cur_mp->group1[0]; 160 cur_mp->group2[1] = cur_mp->group1[1]; 161 } 162 | keysym_var keysym_var keysym_var = { 163 cur_mp->group1[0] = $1; 164 cur_mp->group1[1] = $2; 165 cur_mp->group2[0] = $3; 166 cur_mp->group2[1] = ksym_upcase(cur_mp->group2[0]); 167 } 168 | keysym_var keysym_var keysym_var keysym_var = { 169 cur_mp->group1[0] = $1; 170 cur_mp->group1[1] = $2; 171 cur_mp->group2[0] = $3; 172 cur_mp->group2[1] = $4; 173 } 174 ; 175 176 keysym_var : T_KEYSYM_VAR = { 177 $$ = $1; 178 } 179 | T_NUMBER = { 180 char name[2]; 181 int res; 182 183 if ($1 < 0 || $1 > 9) 184 yyerror("keysym expected"); 185 name[0] = $1 + '0'; 186 name[1] = '\0'; 187 res = name2ksym(name); 188 if (res < 0) 189 yyerror("keysym expected"); 190 $$ = res; 191 } 192 ; 193 %% 194 195 void 196 yyerror(msg) 197 char *msg; 198 { 199 errx(1, "parse: %s", msg); 200 } 201