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