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