1 /* $NetBSD: map_parse.y,v 1.7 2008/04/28 20:23:09 martin 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 int ksym_lookup(keysym_t); 67 68 static int 69 ksym_lookup(keysym_t ksym) 70 { 71 int 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 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 int 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 ($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 ; 151 152 keysym_list : keysym_var = { 153 cur_mp->group1[0] = $1; 154 cur_mp->group1[1] = ksym_upcase(cur_mp->group1[0]); 155 cur_mp->group2[0] = cur_mp->group1[0]; 156 cur_mp->group2[1] = cur_mp->group1[1]; 157 } 158 | keysym_var keysym_var = { 159 cur_mp->group1[0] = $1; 160 cur_mp->group1[1] = $2; 161 cur_mp->group2[0] = cur_mp->group1[0]; 162 cur_mp->group2[1] = cur_mp->group1[1]; 163 } 164 | keysym_var keysym_var keysym_var = { 165 cur_mp->group1[0] = $1; 166 cur_mp->group1[1] = $2; 167 cur_mp->group2[0] = $3; 168 cur_mp->group2[1] = ksym_upcase(cur_mp->group2[0]); 169 } 170 | keysym_var keysym_var keysym_var keysym_var = { 171 cur_mp->group1[0] = $1; 172 cur_mp->group1[1] = $2; 173 cur_mp->group2[0] = $3; 174 cur_mp->group2[1] = $4; 175 } 176 ; 177 178 keysym_var : T_KEYSYM_VAR = { 179 $$ = $1; 180 } 181 | T_NUMBER = { 182 char name[2]; 183 int res; 184 185 if ($1 < 0 || $1 > 9) 186 yyerror("keysym expected"); 187 name[0] = $1 + '0'; 188 name[1] = '\0'; 189 res = name2ksym(name); 190 if (res < 0) 191 yyerror("keysym expected"); 192 $$ = res; 193 }; 194 %% 195 196 void 197 yyerror(const char *msg) 198 { 199 200 errx(EXIT_FAILURE, "parse: %s", msg); 201 } 202