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