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