%{
#include <sys/time.h>
#include <dev/wscons/wsksymdef.h>
#include <dev/wscons/wsconsio.h>
#include <err.h>
#include "wsconsctl.h"
extern struct wskbd_map_data kbmap;
static struct wscons_keymap mapdata[KS_NUMKEYCODES];
struct wskbd_map_data newkbmap;
static struct wscons_keymap *cur_mp;
static int ksym_lookup(keysym_t);
static int
ksym_lookup(keysym_t ksym)
{
int i;
struct wscons_keymap *mp;
for (i = 0; i < kbmap.maplen; i++) {
mp = kbmap.map + i;
if (mp->command == ksym ||
mp->group1[0] == ksym || mp->group1[1] == ksym ||
mp->group2[0] == ksym || mp->group2[1] == ksym)
return(i);
}
errx(1, "keysym %s not found", ksym2name(ksym));
}
%}
%union {
keysym_t kval;
int ival;
}
%token T_KEYSYM T_KEYCODE
%token <kval> T_KEYSYM_VAR T_KEYSYM_CMD_VAR
%token <ival> T_NUMBER
%type <kval> keysym_var
%%
program : = {
int i;
struct wscons_keymap *mp;
for (i = 0; i < KS_NUMKEYCODES; i++) {
mp = mapdata + i;
mp->command = KS_voidSymbol;
mp->group1[0] = KS_voidSymbol;
mp->group1[1] = KS_voidSymbol;
mp->group2[0] = KS_voidSymbol;
mp->group2[1] = KS_voidSymbol;
}
newkbmap.maplen = 0;
newkbmap.map = mapdata;
} expr_list
;
expr_list : expr
| expr_list expr
;
expr : keysym_expr
| keycode_expr
;
keysym_expr : T_KEYSYM keysym_var "=" keysym_var = {
int src, dst;
dst = ksym_lookup($2);
src = ksym_lookup($4);
newkbmap.map[dst] = kbmap.map[src];
if (dst >= newkbmap.maplen)
newkbmap.maplen = dst + 1;
}
;
keycode_expr : T_KEYCODE T_NUMBER "=" = {
if ($2 >= KS_NUMKEYCODES)
errx(1, "%d: keycode too large", $2);
if ($2 >= newkbmap.maplen)
newkbmap.maplen = $2 + 1;
cur_mp = mapdata + $2;
} keysym_cmd keysym_list
;
keysym_cmd :
| T_KEYSYM_CMD_VAR = {
cur_mp->command = $1;
}
;
keysym_list : keysym_var = {
cur_mp->group1[0] = $1;
cur_mp->group1[1] = ksym_upcase(cur_mp->group1[0]);
cur_mp->group2[0] = cur_mp->group1[0];
cur_mp->group2[1] = cur_mp->group1[1];
}
| keysym_var keysym_var = {
cur_mp->group1[0] = $1;
cur_mp->group1[1] = $2;
cur_mp->group2[0] = cur_mp->group1[0];
cur_mp->group2[1] = cur_mp->group1[1];
}
| keysym_var keysym_var keysym_var = {
cur_mp->group1[0] = $1;
cur_mp->group1[1] = $2;
cur_mp->group2[0] = $3;
cur_mp->group2[1] = ksym_upcase(cur_mp->group2[0]);
}
| keysym_var keysym_var keysym_var keysym_var = {
cur_mp->group1[0] = $1;
cur_mp->group1[1] = $2;
cur_mp->group2[0] = $3;
cur_mp->group2[1] = $4;
}
;
keysym_var : T_KEYSYM_VAR = {
$$ = $1;
}
| T_NUMBER = {
char name[2];
int res;
if ($1 < 0 || $1 > 9)
yyerror("keysym expected");
name[0] = $1 + '0';
name[1] = '\0';
res = name2ksym(name);
if (res < 0)
yyerror("keysym expected");
$$ = res;
}
;
%%
void
yyerror(char *msg)
{
errx(1, "parse: %s", msg);
}