1 /* $NetBSD: map_parse.y,v 1.2 1999/02/08 11:08:23 hannken 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 * kecode 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 automacically 51 * as either the upper case variant or the 52 * normal group. 53 */ 54 55 %{ 56 57 #include <sys/time.h> 58 #include <dev/wscons/wsksymdef.h> 59 #include <dev/wscons/wsconsio.h> 60 #include <err.h> 61 #include "wsconsctl.h" 62 63 extern struct wskbd_map_data kbmap; /* from keyboard.c */ 64 65 static struct wscons_keymap mapdata[KS_NUMKEYCODES]; 66 struct wskbd_map_data newkbmap; /* used in util.c */ 67 static struct wscons_keymap *cur_mp; 68 69 static int ksym_lookup __P((keysym_t)); 70 71 static int 72 ksym_lookup(ksym) 73 keysym_t ksym; 74 { 75 int i; 76 struct wscons_keymap *mp; 77 78 for (i = 0; i < kbmap.maplen; i++) { 79 mp = kbmap.map + i; 80 if (mp->command == ksym || 81 mp->group1[0] == ksym || mp->group1[1] == ksym || 82 mp->group2[0] == ksym || mp->group2[1] == ksym) 83 return(i); 84 } 85 86 errx(1, "keysym %s not found", ksym2name(ksym)); 87 } 88 89 %} 90 91 %union { 92 keysym_t kval; 93 int ival; 94 } 95 96 %token T_KEYSYM T_KEYCODE 97 %token <kval> T_KEYSYM_VAR T_KEYSYM_CMD_VAR 98 %token <ival> T_NUMBER 99 100 %type <kval> keysym_var 101 102 %% 103 104 program : = { 105 int i; 106 struct wscons_keymap *mp; 107 108 for (i = 0; i < KS_NUMKEYCODES; i++) { 109 mp = mapdata + i; 110 mp->command = KS_voidSymbol; 111 mp->group1[0] = KS_voidSymbol; 112 mp->group1[1] = KS_voidSymbol; 113 mp->group2[0] = KS_voidSymbol; 114 mp->group2[1] = KS_voidSymbol; 115 } 116 117 newkbmap.maplen = 0; 118 newkbmap.map = mapdata; 119 } expr_list 120 ; 121 122 expr_list : expr 123 | expr_list expr 124 ; 125 126 expr : keysym_expr 127 | keycode_expr 128 ; 129 130 keysym_expr : T_KEYSYM keysym_var "=" keysym_var = { 131 int src, dst; 132 133 dst = ksym_lookup($2); 134 src = ksym_lookup($4); 135 newkbmap.map[dst] = kbmap.map[src]; 136 if (dst >= newkbmap.maplen) 137 newkbmap.maplen = dst + 1; 138 } 139 ; 140 141 keycode_expr : T_KEYCODE T_NUMBER "=" = { 142 if ($2 >= KS_NUMKEYCODES) 143 errx(1, "%d: keycode too large", $2); 144 if ($2 >= newkbmap.maplen) 145 newkbmap.maplen = $2 + 1; 146 cur_mp = mapdata + $2; 147 } keysym_cmd keysym_list 148 ; 149 150 keysym_cmd : /* empty */ 151 | T_KEYSYM_CMD_VAR = { 152 cur_mp->command = $1; 153 } 154 ; 155 156 keysym_list : keysym_var = { 157 cur_mp->group1[0] = $1; 158 cur_mp->group1[1] = ksym_upcase(cur_mp->group1[0]); 159 cur_mp->group2[0] = cur_mp->group1[0]; 160 cur_mp->group2[1] = cur_mp->group1[1]; 161 } 162 | keysym_var keysym_var = { 163 cur_mp->group1[0] = $1; 164 cur_mp->group1[1] = $2; 165 cur_mp->group2[0] = cur_mp->group1[0]; 166 cur_mp->group2[1] = cur_mp->group1[1]; 167 } 168 | 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] = ksym_upcase(cur_mp->group2[0]); 173 } 174 | keysym_var keysym_var keysym_var keysym_var = { 175 cur_mp->group1[0] = $1; 176 cur_mp->group1[1] = $2; 177 cur_mp->group2[0] = $3; 178 cur_mp->group2[1] = $4; 179 } 180 ; 181 182 keysym_var : T_KEYSYM_VAR = { 183 $$ = $1; 184 } 185 | T_NUMBER = { 186 char name[2]; 187 int res; 188 189 if ($1 < 0 || $1 > 9) 190 yyerror("keysym expected"); 191 name[0] = $1 + '0'; 192 name[1] = '\0'; 193 res = name2ksym(name); 194 if (res < 0) 195 yyerror("keysym expected"); 196 $$ = res; 197 }; 198 %% 199 200 void 201 yyerror(msg) 202 char *msg; 203 { 204 errx(1, "parse: %s", msg); 205 } 206