%{
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
#ifndef lint
#pragma ident "%Z%%M% %I% %E% SMI"
#endif
/*
* Copyright (c) 1999 by Sun Microsystems, Inc.
* All rights reserved.
*/
#include <ctype.h>
#include <stdio.h>
#include <search.h>
#include <string.h>
#include <malloc.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
/*
* SunOS 4.x and Solaris 2.[1234] put Type 4 key tables into
* the keytables directory with no type qualification.
* If we're a SPARC, we might be using an NFS server that
* doesn't have the new type-qualified directories.
* (loadkeys wasn't used on non-SPARCs in 2.[1234].)
*/
#ifdef sparc
#define COMPATIBILITY_DIR
#endif
#ifdef COMPATIBILITY_DIR
static char keytable_dir2[] = "/usr/share/lib/keytables/";
#endif
static char layout_prefix[] = "layout_";
struct keyentry {
struct kiockeymap ke_entry;
};
static keyentry *firstentry;
struct dupentry {
int de_station;
int de_otherstation;
};
static dupentry *firstduplicate;
static dupentry *lastduplicate;
static char *infilename;
static int lineno;
static int begline;
static char *strings[16] = {
"\033[H", /* HOMEARROW */
"\033[A", /* UPARROW */
"\033[B", /* DOWNARROW */
"\033[D", /* LEFTARROW */
"\033[C", /* RIGHTARROW */
};
typedef enum {
SM_INVALID, /* this shift mask is invalid for this keyboard */
SM_NORMAL, /* "normal", valid shift mask */
SM_NUMLOCK, /* "Num Lock" shift mask */
SM_UP /* "Up" shift mask */
} smtype_t;
typedef struct {
int sm_mask;
} smentry_t;
static smentry_t shiftmasks[] = {
{ 0, SM_NORMAL },
{ ALTGRAPHMASK, SM_NORMAL },
{ NUMLOCKMASK, SM_NUMLOCK },
};
static int yylex();
static void usage(void);
static void set_layout(char *arg);
int
int argc;
char **argv;
{
register int kbdfd;
int type;
int layout;
/* maxint is 8 hex digits. */
char pathbuf[MAXPATHLEN];
register int shift;
struct kiockeymap mapentry;
if(argv[0][0] != '-') break;
switch(argv[0][1]) {
case 'e':
/* -e obsolete, silently ignore */
break;
case 's':
if (argc != 2) {
usage();
/* NOTREACHED */
}
exit(0);
default:
usage();
/* NOTREACHED */
}
}
return (1);
}
/*
* There may not be a keyboard connected,
* return silently
*/
return (1);
}
if (argc == 0) {
/* If no keyboard detected, exit silently. */
if (type == -1)
return (0);
perror("loadkeys: ioctl(KIOCLAYOUT)");
return (1);
}
(void) sprintf(layout_filename,
} else {
infilename = argv[0];
}
lineno = 0;
begline = 1;
yyparse();
/*
* See which shift masks are valid for this keyboard.
* We do that by trying to get the entry for keystation 0 and that
* shift mask; if the "ioctl" fails, we assume it's because the shift
* mask is invalid.
*/
mapentry.kio_station = 0;
}
case SM_INVALID:
continue;
case SM_NUMLOCK:
/*
* Defaults to NONL, not to a copy of
* the base entry.
*/
break;
case SM_UP:
/*
* Defaults to NOP, not to a copy of
* the base entry.
*/
break;
}
return (1);
}
} else {
return (1);
}
}
return (0);
}
}
}
return (0);
}
}
}
return (0);
}
static void
usage()
{
exit(1);
}
static void
set_layout(char *arg)
{
int layout;
int ret;
int kbdfd;
if (*arg != '\0') {
exit(1);
}
exit(1);
}
if (ret == -1) {
perror("KIOCSLAYOUT");
}
}
/*
* Attempt to find the specified mapping file. Return a FILE * if found,
* else print a message on stderr and return NULL.
*/
FILE *
char *pathbuf,
char *name,
int type
) {
/* If the user specified the name, try it "raw". */
if (explicit_name) {
}
/* Everything after this point applies only to relative names. */
/* Try the type-qualified directory name. */
name);
return (NULL);
}
#ifdef COMPATIBILITY_DIR
/* If not, and either the name was specified explicitly */
/* or this is a type 4... */
/* Try the compatibility name. */
/* No need to check len here, it's shorter. */
}
#endif
return (NULL);
}
/*
* We have a list of entries for a given keystation, and the keystation number
* for that keystation; put that keystation number into all the entries in that
* list, and chain that list to the end of the main list of entries.
*/
static void
int station;
{
else
kep = entrylistp;
for (;;) {
break;
}
}
}
/*
* Allocate and fill in a new entry.
*/
static keyentry *
int tablemask;
int entry;
{
register int index;
yyerror("out of memory for entries");
return (kep);
}
/*
* Make a set of entries for a keystation that indicate that that keystation's
* settings should be copied from another keystation's settings.
*/
static void
int station;
int otherstation;
{
yyerror("out of memory for entries");
if (lastduplicate == NULL)
else
lastduplicate = dep;
}
/*
* Make a set of entries for a keystation that indicate that that keystation's
* settings should be swapped with another keystation's settings.
*/
static void
int station;
int otherstation;
{
yyerror("out of memory for entries");
else
}
static int
int kbdfd;
{
perror("loadkeys: ioctl(KIOCSKEY)");
return (0);
}
return (1);
}
static int
int kbdfd;
int shiftmask;
{
struct kiockeymap entry;
perror("loadkeys: ioctl(KIOCGKEY)");
return (0);
}
perror("loadkeys: ioctl(KIOCSKEY)");
return (0);
}
return (1);
}
static int
int kbdfd;
int shiftmask;
{
perror("loadkeys: ioctl(KIOCGKEY)");
return (0);
}
perror("loadkeys: ioctl(KIOCGKEY)");
return (0);
}
perror("loadkeys: ioctl(KIOCSKEY)");
return (0);
}
perror("loadkeys: ioctl(KIOCSKEY)");
return (0);
}
return (1);
}
%}
%union {
int number;
};
%%
| /* null */
;
line:
{
}
{
}
{
}
| '\n'
;
{
/*
* Append this entry to the end of the entry list.
*/
kep = $1;
for (;;) {
break;
}
}
$$ = $1;
}
| entry
{
$$ = $1;
}
;
{
}
;
code:
{
$$ = $1;
}
| CHAR
{
$$ = $1;
}
| '('
{
$$ = '(';
}
| ')'
{
$$ = ')';
}
| '+'
{
$$ = '+';
}
| expr
{
$$ = $1;
}
;
expr:
{
$$ = $1;
}
{
$$ = $1 + $3;
}
;
term:
{
$$ = $1;
}
{
if ($3 < 1 || $3 > 16)
yyerror("invalid function key number");
$$ = $1 + $3 - 1;
}
;
{
$$ = $1;
}
| CHAR
{
if (isdigit($1))
$$ = $1 - '0';
else
yyerror("syntax error");
}
;
%%
typedef struct {
char *w_string;
int w_type; /* token type */
int w_lval; /* yylval for this token */
} word_t;
/*
* Table must be in alphabetical order.
*/
{ "as", AS, 0 },
{ "base", TABLENAME, 0 },
{ "key", KEY, 0 },
{ "same", SAME, 0 },
{ "swap", SWAP, 0 },
{ "with", WITH, 0 },
};
static int
yylex()
{
register int c;
register char *cp;
register int tokentype;
;
if (begline) {
lineno++;
begline = 0;
if (c == '#') {
;
}
}
if (c == EOF)
return (0); /* end marker */
if (c == '\n') {
begline = 1;
return (c);
}
switch (c) {
case '\'':
yyerror("unterminated character constant");
if (c == '\n') {
} else {
switch (c) {
case '\'':
yyerror("null character constant");
break;
case '\\':
break;
default:
break;
}
yyerror("unterminated character constant");
else if (c != '\'')
yyerror("only one character allowed in character constant");
}
break;
case '"':
yyerror("unterminated string constant");
if (c == '\n') {
} else {
do {
yyerror("line too long");
if (c == '\\')
*cp++ = (char)c;
c != '"');
if (c != '"')
yyerror("unterminated string constant");
*cp = '\0';
if (nstrings == 16)
yyerror("too many strings");
yyerror("string too long");
nstrings++;
}
break;
case '(':
case ')':
case '+':
tokentype = c;
break;
case '^':
yyerror("missing newline at end of line");
if (c == ' ' || c == '\t' || c == '\n') {
/*
* '^' by itself.
*/
} else {
yyerror("missing newline at end of line");
if (c != ' ' && c != '\t' && c != '\n')
yyerror("invalid control character");
}
break;
default:
do {
yyerror("line too long");
*cp++ = (char)c;
if (c == EOF)
yyerror("newline missing");
*cp = '\0';
} else {
char *ptr;
if (isupper(c))
}
wordcmp);
} else {
yyerror("syntax error");
else
}
break;
}
}
return (tokentype);
}
static int
int delim;
int single_char;
{
register int c;
register int val;
register int i;
yyerror("unterminated character constant");
if (c >= '0' && c <= '7') {
val = 0;
i = 1;
for (;;) {
yyerror("unterminated character constant");
if (c == delim)
break;
i++;
if (i > 3) {
if (single_char)
yyerror("escape sequence too long");
else
break;
}
if (c < '0' || c > '7') {
if (single_char)
yyerror("illegal character in escape sequence");
else
break;
}
}
} else {
switch (c) {
case 'n':
val = '\n';
break;
case 't':
val = '\t';
break;
case 'b':
val = '\b';
break;
case 'r':
val = '\r';
break;
case 'v':
val = '\v';
break;
case '\\':
val = '\\';
break;
default:
if (c == delim)
else
yyerror("illegal character in escape sequence");
}
}
return (val);
}
static int
{
return (strcmp(
}
static int
char *msg;
{
exit(1);
}