# line 2 "loadkeys.y" /* * 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 * or http://www.opensolaris.org/os/licensing. * 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 #include #include #include #include #include #include #include #include #include #include #include #define ALL -1 /* special symbol for all tables */ /* * 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 static char keytable_dir[] = "/usr/share/lib/keytables/type_%d/"; #ifdef COMPATIBILITY_DIR static char keytable_dir2[] = "/usr/share/lib/keytables/"; #endif static char layout_prefix[] = "layout_"; struct keyentry { struct keyentry *ke_next; struct kiockeymap ke_entry; }; typedef struct keyentry keyentry; static keyentry *firstentry; static keyentry *lastentry; struct dupentry { struct dupentry *de_next; int de_station; int de_otherstation; }; typedef struct dupentry dupentry; static dupentry *firstduplicate; static dupentry *lastduplicate; static dupentry *firstswap; static dupentry *lastswap; static char *infilename; static FILE *infile; 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 */ }; static int nstrings = 5; /* start out with 5 strings */ 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; smtype_t sm_type; } smentry_t; static smentry_t shiftmasks[] = { { 0, SM_NORMAL }, { SHIFTMASK, SM_NORMAL }, { CAPSMASK, SM_NORMAL }, { CTRLMASK, SM_NORMAL }, { ALTGRAPHMASK, SM_NORMAL }, { NUMLOCKMASK, SM_NUMLOCK }, { UPMASK, SM_UP }, }; #define NSHIFTS (sizeof (shiftmasks) / sizeof (shiftmasks[0])) static void enter_mapentry(int station, keyentry *entrylistp); static keyentry *makeentry(int tablemask, int entry); static int loadkey(int kbdfd, keyentry *kep); static int dupkey(int kbdfd, dupentry *dep, int shiftmask); static int swapkey(int kbdfd, dupentry *dep, int shiftmask); static int yylex(); static int readesc(FILE *stream, int delim, int single_char); static int wordcmp(const void *w1, const void *w2); static int yyerror(char *msg); static void usage(void); static void set_layout(char *arg); static FILE *open_mapping_file(char *pathbuf, char *name, boolean_t explicit_name, int type); int main(argc, argv) int argc; char **argv; { register int kbdfd; int type; int layout; /* maxint is 8 hex digits. */ char layout_filename[sizeof(layout_prefix)+8]; char pathbuf[MAXPATHLEN]; register int shift; struct kiockeymap mapentry; register keyentry *kep; register dupentry *dep; boolean_t explicit_name; while(++argv, --argc) { if(argv[0][0] != '-') break; switch(argv[0][1]) { case 'e': /* -e obsolete, silently ignore */ break; case 's': if (argc != 2) { usage(); /* NOTREACHED */ } set_layout(argv[1]); exit(0); default: usage(); /* NOTREACHED */ } } if (argc > 1) usage(); if ((kbdfd = open("/dev/kbd", O_WRONLY)) < 0) { /* perror("loadkeys: /dev/kbd"); */ return (1); } if (ioctl(kbdfd, KIOCTYPE, &type) < 0) { /* * 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); if (ioctl(kbdfd, KIOCLAYOUT, &layout) < 0) { perror("loadkeys: ioctl(KIOCLAYOUT)"); return (1); } (void) sprintf(layout_filename, "%s%.2x", layout_prefix, layout); infilename = layout_filename; explicit_name = B_FALSE; } else { infilename = argv[0]; explicit_name = B_TRUE; } infile = open_mapping_file(pathbuf, infilename, explicit_name, type); if (infile == NULL) return (1); infilename = pathbuf; lineno = 0; begline = 1; yyparse(); fclose(infile); /* * 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. */ for (shift = 0; shift < NSHIFTS; shift++) { mapentry.kio_tablemask = shiftmasks[shift].sm_mask; mapentry.kio_station = 0; if (ioctl(kbdfd, KIOCGKEY, &mapentry) < 0) shiftmasks[shift].sm_type = SM_INVALID; } for (kep = firstentry; kep != NULL; kep = kep->ke_next) { if (kep->ke_entry.kio_tablemask == ALL) { for (shift = 0; shift < NSHIFTS; shift++) { switch (shiftmasks[shift].sm_type) { case SM_INVALID: continue; case SM_NUMLOCK: /* * Defaults to NONL, not to a copy of * the base entry. */ if (kep->ke_entry.kio_entry != HOLE) kep->ke_entry.kio_entry = NONL; break; case SM_UP: /* * Defaults to NOP, not to a copy of * the base entry. */ if (kep->ke_entry.kio_entry != HOLE) kep->ke_entry.kio_entry = NOP; break; } kep->ke_entry.kio_tablemask = shiftmasks[shift].sm_mask; if (!loadkey(kbdfd, kep)) return (1); } } else { if (!loadkey(kbdfd, kep)) return (1); } } for (dep = firstswap; dep != NULL; dep = dep->de_next) { for (shift = 0; shift < NSHIFTS; shift++) { if (shiftmasks[shift].sm_type != SM_INVALID) { if (!swapkey(kbdfd, dep, shiftmasks[shift].sm_mask)) return (0); } } } for (dep = firstduplicate; dep != NULL; dep = dep->de_next) { for (shift = 0; shift < NSHIFTS; shift++) { if (shiftmasks[shift].sm_type != SM_INVALID) { if (!dupkey(kbdfd, dep, shiftmasks[shift].sm_mask)) return (0); } } } close(kbdfd); return (0); } static void usage() { (void) fprintf(stderr, "usage: loadkeys [ file ]\n"); exit(1); } static void set_layout(char *arg) { int layout; int ret; int kbdfd; layout = (int) strtol(arg, &arg, 0); if (*arg != '\0') { fprintf(stderr, "usage: loadkeys -s layoutnumber\n"); exit(1); } if ((kbdfd = open("/dev/kbd", O_WRONLY)) < 0) { perror("/dev/kbd"); exit(1); } ret = ioctl(kbdfd, KIOCSLAYOUT, layout); if (ret == -1) { perror("KIOCSLAYOUT"); } close(kbdfd); } /* * Attempt to find the specified mapping file. Return a FILE * if found, * else print a message on stderr and return NULL. */ FILE * open_mapping_file( char *pathbuf, char *name, boolean_t explicit_name, int type ) { /* If the user specified the name, try it "raw". */ if (explicit_name) { strcpy(pathbuf, name); infile = fopen(pathbuf, "r"); if (infile) return (infile); if (errno != ENOENT) goto fopen_fail; } /* Everything after this point applies only to relative names. */ if (*name == '/') goto fopen_fail; /* Try the type-qualified directory name. */ sprintf(pathbuf, keytable_dir, type); if ((int)(strlen(pathbuf) + strlen(name) + 1) >= MAXPATHLEN) { (void) fprintf(stderr, "loadkeys: Name %s is too long\n", name); return (NULL); } (void) strcat(pathbuf, name); infile = fopen(pathbuf, "r"); if (infile) return (infile); if (errno != ENOENT) goto fopen_fail; #ifdef COMPATIBILITY_DIR /* If not, and either the name was specified explicitly */ /* or this is a type 4... */ if (explicit_name || type == KB_SUN4) { /* Try the compatibility name. */ /* No need to check len here, it's shorter. */ (void) strcpy(pathbuf, keytable_dir2); (void) strcat(pathbuf, infilename); infile = fopen(pathbuf, "r"); if (infile) return (infile); if (errno != ENOENT) goto fopen_fail; } #endif fopen_fail: (void) fprintf(stderr, "loadkeys: "); perror(name); 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 enter_mapentry(station, entrylistp) int station; keyentry *entrylistp; { register keyentry *kep; if (lastentry == NULL) firstentry = entrylistp; else lastentry->ke_next = entrylistp; kep = entrylistp; for (;;) { kep->ke_entry.kio_station = (u_char)station; if (kep->ke_next == NULL) { lastentry = kep; break; } kep = kep->ke_next; } } /* * Allocate and fill in a new entry. */ static keyentry * makeentry(tablemask, entry) int tablemask; int entry; { register keyentry *kep; register int index; if ((kep = (keyentry *) malloc((unsigned)sizeof (keyentry))) == NULL) yyerror("out of memory for entries"); kep->ke_next = NULL; kep->ke_entry.kio_tablemask = tablemask; kep->ke_entry.kio_station = 0; kep->ke_entry.kio_entry = (u_short)entry; index = entry - STRING; if (index >= 0 && index <= 15) (void) strncpy(kep->ke_entry.kio_string, strings[index], KTAB_STRLEN); 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 duplicate_mapentry(station, otherstation) int station; int otherstation; { register dupentry *dep; if ((dep = (dupentry *) malloc((unsigned)sizeof (dupentry))) == NULL) yyerror("out of memory for entries"); if (lastduplicate == NULL) firstduplicate = dep; else lastduplicate->de_next = dep; lastduplicate = dep; dep->de_next = NULL; dep->de_station = station; dep->de_otherstation = otherstation; } /* * 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 swap_mapentry(station, otherstation) int station; int otherstation; { register dupentry *dep; if ((dep = (dupentry *) malloc((unsigned)sizeof (dupentry))) == NULL) yyerror("out of memory for entries"); if (lastswap == NULL) firstswap = dep; else lastswap->de_next = dep; lastswap = dep; dep->de_next = NULL; dep->de_station = station; dep->de_otherstation = otherstation; } static int loadkey(kbdfd, kep) int kbdfd; register keyentry *kep; { if (ioctl(kbdfd, KIOCSKEY, &kep->ke_entry) < 0) { perror("loadkeys: ioctl(KIOCSKEY)"); return (0); } return (1); } static int dupkey(kbdfd, dep, shiftmask) int kbdfd; register dupentry *dep; int shiftmask; { struct kiockeymap entry; entry.kio_tablemask = shiftmask; entry.kio_station = dep->de_otherstation; if (ioctl(kbdfd, KIOCGKEY, &entry) < 0) { perror("loadkeys: ioctl(KIOCGKEY)"); return (0); } entry.kio_station = dep->de_station; if (ioctl(kbdfd, KIOCSKEY, &entry) < 0) { perror("loadkeys: ioctl(KIOCSKEY)"); return (0); } return (1); } static int swapkey(kbdfd, dep, shiftmask) int kbdfd; register dupentry *dep; int shiftmask; { struct kiockeymap entry1, entry2; entry1.kio_tablemask = shiftmask; entry1.kio_station = dep->de_station; if (ioctl(kbdfd, KIOCGKEY, &entry1) < 0) { perror("loadkeys: ioctl(KIOCGKEY)"); return (0); } entry2.kio_tablemask = shiftmask; entry2.kio_station = dep->de_otherstation; if (ioctl(kbdfd, KIOCGKEY, &entry2) < 0) { perror("loadkeys: ioctl(KIOCGKEY)"); return (0); } entry1.kio_station = dep->de_otherstation; if (ioctl(kbdfd, KIOCSKEY, &entry1) < 0) { perror("loadkeys: ioctl(KIOCSKEY)"); return (0); } entry2.kio_station = dep->de_station; if (ioctl(kbdfd, KIOCSKEY, &entry2) < 0) { perror("loadkeys: ioctl(KIOCSKEY)"); return (0); } return (1); } # line 556 "loadkeys.y" typedef union #ifdef __cplusplus YYSTYPE #endif { keyentry *keyentry; int number; } YYSTYPE; # define TABLENAME 257 # define INT 258 # define CHAR 259 # define CHARSTRING 260 # define CONSTANT 261 # define FKEY 262 # define KEY 263 # define SAME 264 # define AS 265 # define SWAP 266 # define WITH 267 #include #ifdef __STDC__ #include #include #define YYCONST const #else #include #include #define YYCONST #endif #include #if defined(__cplusplus) || defined(__STDC__) #if defined(__cplusplus) && defined(__EXTERN_C__) extern "C" { #endif #ifndef yyerror #if defined(__cplusplus) void yyerror(YYCONST char *); #endif #endif #ifndef yylex int yylex(void); #endif int yyparse(void); #if defined(__cplusplus) && defined(__EXTERN_C__) } #endif #endif #define yyclearin yychar = -1 #define yyerrok yyerrflag = 0 extern int yychar; extern int yyerrflag; YYSTYPE yylval; YYSTYPE yyval; typedef int yytabelem; #ifndef YYMAXDEPTH #define YYMAXDEPTH 150 #endif #if YYMAXDEPTH > 0 int yy_yys[YYMAXDEPTH], *yys = yy_yys; YYSTYPE yy_yyv[YYMAXDEPTH], *yyv = yy_yyv; #else /* user does initial allocation */ int *yys; YYSTYPE *yyv; #endif static int yymaxdepth = YYMAXDEPTH; # define YYERRCODE 256 # line 683 "loadkeys.y" 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. */ word_t wordtab[] = { { "all", TABLENAME, ALL }, { "alt", CONSTANT, ALT }, { "altg", TABLENAME, ALTGRAPHMASK }, { "altgraph", CONSTANT, ALTGRAPH }, { "as", AS, 0 }, { "base", TABLENAME, 0 }, { "bf", FKEY, BOTTOMFUNC }, { "buckybits", CONSTANT, BUCKYBITS }, { "caps", TABLENAME, CAPSMASK }, { "capslock", CONSTANT, CAPSLOCK }, { "compose", CONSTANT, COMPOSE }, { "ctrl", TABLENAME, CTRLMASK }, { "downarrow", CONSTANT, DOWNARROW }, { "error", CONSTANT, ERROR }, { "fa_acute", CONSTANT, FA_ACUTE }, { "fa_cedilla", CONSTANT, FA_CEDILLA }, { "fa_cflex", CONSTANT, FA_CFLEX }, { "fa_grave", CONSTANT, FA_GRAVE }, { "fa_tilde", CONSTANT, FA_TILDE }, { "fa_umlaut", CONSTANT, FA_UMLAUT }, { "hole", CONSTANT, HOLE }, { "homearrow", CONSTANT, HOMEARROW }, { "idle", CONSTANT, IDLE }, { "key", KEY, 0 }, { "leftarrow", CONSTANT, LEFTARROW }, { "leftctrl", CONSTANT, LEFTCTRL }, { "leftshift", CONSTANT, LEFTSHIFT }, { "lf", FKEY, LEFTFUNC }, { "metabit", CONSTANT, METABIT }, { "nonl", CONSTANT, NONL }, { "nop", CONSTANT, NOP }, { "numl", TABLENAME, NUMLOCKMASK }, { "numlock", CONSTANT, NUMLOCK }, { "oops", CONSTANT, OOPS }, { "pad0", CONSTANT, PAD0 }, { "pad1", CONSTANT, PAD1 }, { "pad2", CONSTANT, PAD2 }, { "pad3", CONSTANT, PAD3 }, { "pad4", CONSTANT, PAD4 }, { "pad5", CONSTANT, PAD5 }, { "pad6", CONSTANT, PAD6 }, { "pad7", CONSTANT, PAD7 }, { "pad8", CONSTANT, PAD8 }, { "pad9", CONSTANT, PAD9 }, { "paddot", CONSTANT, PADDOT }, { "padenter", CONSTANT, PADENTER }, { "padequal", CONSTANT, PADEQUAL }, { "padminus", CONSTANT, PADMINUS }, { "padplus", CONSTANT, PADPLUS }, { "padsep", CONSTANT, PADSEP }, { "padslash", CONSTANT, PADSLASH }, { "padstar", CONSTANT, PADSTAR }, { "reset", CONSTANT, RESET }, { "rf", FKEY, RIGHTFUNC }, { "rightarrow", CONSTANT, RIGHTARROW }, { "rightctrl", CONSTANT, RIGHTCTRL }, { "rightshift", CONSTANT, RIGHTSHIFT }, { "same", SAME, 0 }, { "shift", TABLENAME, SHIFTMASK }, { "shiftkeys", CONSTANT, SHIFTKEYS }, { "shiftlock", CONSTANT, SHIFTLOCK }, { "string", CONSTANT, STRING }, { "swap", SWAP, 0 }, { "systembit", CONSTANT, SYSTEMBIT }, { "tf", FKEY, TOPFUNC }, { "up", TABLENAME, UPMASK }, { "uparrow", CONSTANT, UPARROW }, { "with", WITH, 0 }, }; #define NWORDS (sizeof (wordtab) / sizeof (wordtab[0])) static int yylex() { register int c; char tokbuf[256+1]; register char *cp; register int tokentype; while ((c = getc(infile)) == ' ' || c == '\t') ; if (begline) { lineno++; begline = 0; if (c == '#') { while ((c = getc(infile)) != EOF && c != '\n') ; } } if (c == EOF) return (0); /* end marker */ if (c == '\n') { begline = 1; return (c); } switch (c) { case '\'': tokentype = CHAR; if ((c = getc(infile)) == EOF) yyerror("unterminated character constant"); if (c == '\n') { (void) ungetc(c, infile); yylval.number = '\''; } else { switch (c) { case '\'': yyerror("null character constant"); break; case '\\': yylval.number = readesc(infile, '\'', 1); break; default: yylval.number = c; break; } if ((c = getc(infile)) == EOF || c == '\n') yyerror("unterminated character constant"); else if (c != '\'') yyerror("only one character allowed in character constant"); } break; case '"': if ((c = getc(infile)) == EOF) yyerror("unterminated string constant"); if (c == '\n') { (void) ungetc(c, infile); tokentype = CHAR; yylval.number = '"'; } else { tokentype = CHARSTRING; cp = &tokbuf[0]; do { if (cp > &tokbuf[256]) yyerror("line too long"); if (c == '\\') c = readesc(infile, '"', 0); *cp++ = (char)c; } while ((c = getc(infile)) != EOF && c != '\n' && c != '"'); if (c != '"') yyerror("unterminated string constant"); *cp = '\0'; if (nstrings == 16) yyerror("too many strings"); if ((int) strlen(tokbuf) > KTAB_STRLEN) yyerror("string too long"); strings[nstrings] = strdup(tokbuf); yylval.number = STRING+nstrings; nstrings++; } break; case '(': case ')': case '+': tokentype = c; break; case '^': if ((c = getc(infile)) == EOF) yyerror("missing newline at end of line"); tokentype = CHAR; if (c == ' ' || c == '\t' || c == '\n') { /* * '^' by itself. */ yylval.number = '^'; } else { yylval.number = c & 037; if ((c = getc(infile)) == EOF) yyerror("missing newline at end of line"); if (c != ' ' && c != '\t' && c != '\n') yyerror("invalid control character"); } (void) ungetc(c, infile); break; default: cp = &tokbuf[0]; do { if (cp > &tokbuf[256]) yyerror("line too long"); *cp++ = (char)c; } while ((c = getc(infile)) != EOF && (isalnum(c) || c == '_')); if (c == EOF) yyerror("newline missing"); (void) ungetc(c, infile); *cp = '\0'; if (strlen(tokbuf) == 1) { tokentype = CHAR; yylval.number = (unsigned char)tokbuf[0]; } else if (strlen(tokbuf) == 2 && tokbuf[0] == '^') { tokentype = CHAR; yylval.number = (unsigned char)(tokbuf[1] & 037); } else { word_t word; register word_t *wptr; char *ptr; for (cp = &tokbuf[0]; (c = *cp) != '\0'; cp++) { if (isupper(c)) *cp = tolower(c); } word.w_string = tokbuf; wptr = (word_t *)bsearch((char *)&word, (char *)wordtab, NWORDS, sizeof (word_t), wordcmp); if (wptr != NULL) { yylval.number = wptr->w_lval; tokentype = wptr->w_type; } else { yylval.number = strtol(tokbuf, &ptr, 10); if (ptr == tokbuf) yyerror("syntax error"); else tokentype = INT; } break; } } return (tokentype); } static int readesc(stream, delim, single_char) FILE *stream; int delim; int single_char; { register int c; register int val; register int i; if ((c = getc(stream)) == EOF || c == '\n') yyerror("unterminated character constant"); if (c >= '0' && c <= '7') { val = 0; i = 1; for (;;) { val = val*8 + c - '0'; if ((c = getc(stream)) == EOF || c == '\n') 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; } } (void) ungetc(c, stream); } 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) val = delim; else yyerror("illegal character in escape sequence"); } } return (val); } static int wordcmp(const void *w1, const void *w2) { return (strcmp( ((const word_t *)w1)->w_string, ((const word_t *)w2)->w_string)); } static int yyerror(msg) char *msg; { (void) fprintf(stderr, "%s, line %d: %s\n", infilename, lineno, msg); exit(1); } static YYCONST yytabelem yyexca[] ={ -1, 1, 0, -1, -2, 0, }; # define YYNPROD 22 # define YYLAST 260 static YYCONST yytabelem yyact[]={ 21, 22, 5, 23, 14, 17, 13, 26, 27, 7, 8, 30, 15, 11, 36, 31, 6, 12, 25, 33, 32, 9, 2, 1, 24, 18, 10, 0, 16, 0, 0, 28, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 19, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 13 }; static YYCONST yytabelem yypact[]={ -10000000, -8,-10000000, -249, -249,-10000000, -251,-10000000,-10000000, -263, 2, -260,-10000000, -40, -249,-10000000,-10000000, -249,-10000000,-10000000, -10000000,-10000000,-10000000,-10000000, -32,-10000000,-10000000, -25, 10, 9, -254, -249,-10000000,-10000000,-10000000, -27,-10000000 }; static YYCONST yytabelem yypgo[]={ 0, 26, 17, 25, 24, 18, 16, 23, 22 }; static YYCONST yytabelem yyr1[]={ 0, 7, 7, 8, 8, 8, 8, 1, 1, 2, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 6, 6 }; static YYCONST yytabelem yyr2[]={ 0, 4, 0, 9, 13, 11, 2, 5, 3, 5, 3, 3, 3, 3, 3, 3, 3, 7, 3, 9, 3, 3 }; static YYCONST yytabelem yychk[]={ -10000000, -7, -8, 263, 266, 10, -6, 258, 259, -6, -1, 264, -2, 257, 267, 10, -2, 265, -3, 260, 259, 40, 41, 43, -4, -5, 261, 262, -6, -6, 43, 40, 10, 10, -5, -6, 41 }; static YYCONST yytabelem yydef[]={ 2, -2, 1, 0, 0, 6, 0, 20, 21, 0, 0, 0, 8, 0, 0, 3, 7, 0, 9, 10, 11, 12, 13, 14, 15, 16, 18, 0, 0, 0, 0, 0, 5, 4, 17, 0, 19 }; typedef struct #ifdef __cplusplus yytoktype #endif { #ifdef __cplusplus const #endif char *t_name; int t_val; } yytoktype; #ifndef YYDEBUG # define YYDEBUG 0 /* don't allow debugging */ #endif #if YYDEBUG yytoktype yytoks[] = { "TABLENAME", 257, "INT", 258, "CHAR", 259, "CHARSTRING", 260, "CONSTANT", 261, "FKEY", 262, "KEY", 263, "SAME", 264, "AS", 265, "SWAP", 266, "WITH", 267, "-unknown-", -1 /* ends search */ }; #ifdef __cplusplus const #endif char * yyreds[] = { "-no such reduction-", "table : table line", "table : /* empty */", "line : KEY number entrylist '\n'", "line : KEY number SAME AS number '\n'", "line : SWAP number WITH number '\n'", "line : '\n'", "entrylist : entrylist entry", "entrylist : entry", "entry : TABLENAME code", "code : CHARSTRING", "code : CHAR", "code : '('", "code : ')'", "code : '+'", "code : expr", "expr : term", "expr : expr '+' term", "term : CONSTANT", "term : FKEY '(' number ')'", "number : INT", "number : CHAR", }; #endif /* YYDEBUG */ # line 1 "/usr/share/lib/ccs/yaccpar" /* * 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 * or http://www.opensolaris.org/os/licensing. * 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 */ /* * Copyright 1993 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ #pragma ident "%Z%%M% %I% %E% SMI" /* ** Skeleton parser driver for yacc output */ /* ** yacc user known macros and defines */ #define YYERROR goto yyerrlab #define YYACCEPT return(0) #define YYABORT return(1) #define YYBACKUP( newtoken, newvalue )\ {\ if ( yychar >= 0 || ( yyr2[ yytmp ] >> 1 ) != 1 )\ {\ yyerror( "syntax error - cannot backup" );\ goto yyerrlab;\ }\ yychar = newtoken;\ yystate = *yyps;\ yylval = newvalue;\ goto yynewstate;\ } #define YYRECOVERING() (!!yyerrflag) #define YYNEW(type) malloc(sizeof(type) * yynewmax) #define YYCOPY(to, from, type) \ (type *) memcpy(to, (char *) from, yymaxdepth * sizeof (type)) #define YYENLARGE( from, type) \ (type *) realloc((char *) from, yynewmax * sizeof(type)) #ifndef YYDEBUG # define YYDEBUG 1 /* make debugging available */ #endif /* ** user known globals */ int yydebug; /* set to 1 to get debugging */ /* ** driver internal defines */ #define YYFLAG (-10000000) /* ** global variables used by the parser */ YYSTYPE *yypv; /* top of value stack */ int *yyps; /* top of state stack */ int yystate; /* current state */ int yytmp; /* extra var (lasts between blocks) */ int yynerrs; /* number of errors */ int yyerrflag; /* error recovery flag */ int yychar; /* current input token number */ #ifdef YYNMBCHARS #define YYLEX() yycvtok(yylex()) /* ** yycvtok - return a token if i is a wchar_t value that exceeds 255. ** If i<255, i itself is the token. If i>255 but the neither ** of the 30th or 31st bit is on, i is already a token. */ #if defined(__STDC__) || defined(__cplusplus) int yycvtok(int i) #else int yycvtok(i) int i; #endif { int first = 0; int last = YYNMBCHARS - 1; int mid; wchar_t j; if(i&0x60000000){/*Must convert to a token. */ if( yymbchars[last].character < i ){ return i;/*Giving up*/ } while ((last>=first)&&(first>=0)) {/*Binary search loop*/ mid = (first+last)/2; j = yymbchars[mid].character; if( j==i ){/*Found*/ return yymbchars[mid].tvalue; }else if( j= 0; yy_i++ ) { if ( yytoks[yy_i].t_val == yychar ) break; } printf( "%s\n", yytoks[yy_i].t_name ); } } #endif /* YYDEBUG */ if ( ++yy_ps >= &yys[ yymaxdepth ] ) /* room on stack? */ { /* ** reallocate and recover. Note that pointers ** have to be reset, or bad things will happen */ long yyps_index = (yy_ps - yys); long yypv_index = (yy_pv - yyv); long yypvt_index = (yypvt - yyv); int yynewmax; #ifdef YYEXPAND yynewmax = YYEXPAND(yymaxdepth); #else yynewmax = 2 * yymaxdepth; /* double table size */ if (yymaxdepth == YYMAXDEPTH) /* first time growth */ { char *newyys = (char *)YYNEW(int); char *newyyv = (char *)YYNEW(YYSTYPE); if (newyys != 0 && newyyv != 0) { yys = YYCOPY(newyys, yys, int); yyv = YYCOPY(newyyv, yyv, YYSTYPE); } else yynewmax = 0; /* failed */ } else /* not first time */ { yys = YYENLARGE(yys, int); yyv = YYENLARGE(yyv, YYSTYPE); if (yys == 0 || yyv == 0) yynewmax = 0; /* failed */ } #endif if (yynewmax <= yymaxdepth) /* tables not expanded */ { yyerror( "yacc stack overflow" ); YYABORT; } yymaxdepth = yynewmax; yy_ps = yys + yyps_index; yy_pv = yyv + yypv_index; yypvt = yyv + yypvt_index; } *yy_ps = yy_state; *++yy_pv = yyval; /* ** we have a new state - find out what to do */ yy_newstate: if ( ( yy_n = yypact[ yy_state ] ) <= YYFLAG ) goto yydefault; /* simple state */ #if YYDEBUG /* ** if debugging, need to mark whether new token grabbed */ yytmp = yychar < 0; #endif if ( ( yychar < 0 ) && ( ( yychar = YYLEX() ) < 0 ) ) yychar = 0; /* reached EOF */ #if YYDEBUG if ( yydebug && yytmp ) { register int yy_i; printf( "Received token " ); if ( yychar == 0 ) printf( "end-of-file\n" ); else if ( yychar < 0 ) printf( "-none-\n" ); else { for ( yy_i = 0; yytoks[yy_i].t_val >= 0; yy_i++ ) { if ( yytoks[yy_i].t_val == yychar ) break; } printf( "%s\n", yytoks[yy_i].t_name ); } } #endif /* YYDEBUG */ if ( ( ( yy_n += yychar ) < 0 ) || ( yy_n >= YYLAST ) ) goto yydefault; if ( yychk[ yy_n = yyact[ yy_n ] ] == yychar ) /*valid shift*/ { yychar = -1; yyval = yylval; yy_state = yy_n; if ( yyerrflag > 0 ) yyerrflag--; goto yy_stack; } yydefault: if ( ( yy_n = yydef[ yy_state ] ) == -2 ) { #if YYDEBUG yytmp = yychar < 0; #endif if ( ( yychar < 0 ) && ( ( yychar = YYLEX() ) < 0 ) ) yychar = 0; /* reached EOF */ #if YYDEBUG if ( yydebug && yytmp ) { register int yy_i; printf( "Received token " ); if ( yychar == 0 ) printf( "end-of-file\n" ); else if ( yychar < 0 ) printf( "-none-\n" ); else { for ( yy_i = 0; yytoks[yy_i].t_val >= 0; yy_i++ ) { if ( yytoks[yy_i].t_val == yychar ) { break; } } printf( "%s\n", yytoks[yy_i].t_name ); } } #endif /* YYDEBUG */ /* ** look through exception table */ { register YYCONST int *yyxi = yyexca; while ( ( *yyxi != -1 ) || ( yyxi[1] != yy_state ) ) { yyxi += 2; } while ( ( *(yyxi += 2) >= 0 ) && ( *yyxi != yychar ) ) ; if ( ( yy_n = yyxi[1] ) < 0 ) YYACCEPT; } } /* ** check for syntax error */ if ( yy_n == 0 ) /* have an error */ { /* no worry about speed here! */ switch ( yyerrflag ) { case 0: /* new error */ yyerror( "syntax error" ); goto skip_init; yyerrlab: /* ** get globals into registers. ** we have a user generated syntax type error */ yy_pv = yypv; yy_ps = yyps; yy_state = yystate; skip_init: yynerrs++; /* FALLTHRU */ case 1: case 2: /* incompletely recovered error */ /* try again... */ yyerrflag = 3; /* ** find state where "error" is a legal ** shift action */ while ( yy_ps >= yys ) { yy_n = yypact[ *yy_ps ] + YYERRCODE; if ( yy_n >= 0 && yy_n < YYLAST && yychk[yyact[yy_n]] == YYERRCODE) { /* ** simulate shift of "error" */ yy_state = yyact[ yy_n ]; goto yy_stack; } /* ** current state has no shift on ** "error", pop stack */ #if YYDEBUG # define _POP_ "Error recovery pops state %d, uncovers state %d\n" if ( yydebug ) printf( _POP_, *yy_ps, yy_ps[-1] ); # undef _POP_ #endif yy_ps--; yy_pv--; } /* ** there is no state on stack with "error" as ** a valid shift. give up. */ YYABORT; case 3: /* no shift yet; eat a token */ #if YYDEBUG /* ** if debugging, look up token in list of ** pairs. 0 and negative shouldn't occur, ** but since timing doesn't matter when ** debugging, it doesn't hurt to leave the ** tests here. */ if ( yydebug ) { register int yy_i; printf( "Error recovery discards " ); if ( yychar == 0 ) printf( "token end-of-file\n" ); else if ( yychar < 0 ) printf( "token -none-\n" ); else { for ( yy_i = 0; yytoks[yy_i].t_val >= 0; yy_i++ ) { if ( yytoks[yy_i].t_val == yychar ) { break; } } printf( "token %s\n", yytoks[yy_i].t_name ); } } #endif /* YYDEBUG */ if ( yychar == 0 ) /* reached EOF. quit */ YYABORT; yychar = -1; goto yy_newstate; } }/* end if ( yy_n == 0 ) */ /* ** reduction by production yy_n ** put stack tops, etc. so things right after switch */ #if YYDEBUG /* ** if debugging, print the string that is the user's ** specification of the reduction which is just about ** to be done. */ if ( yydebug ) printf( "Reduce by (%d) \"%s\"\n", yy_n, yyreds[ yy_n ] ); #endif yytmp = yy_n; /* value to switch over */ yypvt = yy_pv; /* $vars top of value stack */ /* ** Look in goto table for next state ** Sorry about using yy_state here as temporary ** register variable, but why not, if it works... ** If yyr2[ yy_n ] doesn't have the low order bit ** set, then there is no action to be done for ** this reduction. So, no saving & unsaving of ** registers done. The only difference between the ** code just after the if and the body of the if is ** the goto yy_stack in the body. This way the test ** can be made before the choice of what to do is needed. */ { /* length of production doubled with extra bit */ register int yy_len = yyr2[ yy_n ]; if ( !( yy_len & 01 ) ) { yy_len >>= 1; yyval = ( yy_pv -= yy_len )[1]; /* $$ = $1 */ yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] + *( yy_ps -= yy_len ) + 1; if ( yy_state >= YYLAST || yychk[ yy_state = yyact[ yy_state ] ] != -yy_n ) { yy_state = yyact[ yypgo[ yy_n ] ]; } goto yy_stack; } yy_len >>= 1; yyval = ( yy_pv -= yy_len )[1]; /* $$ = $1 */ yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] + *( yy_ps -= yy_len ) + 1; if ( yy_state >= YYLAST || yychk[ yy_state = yyact[ yy_state ] ] != -yy_n ) { yy_state = yyact[ yypgo[ yy_n ] ]; } } /* save until reenter driver code */ yystate = yy_state; yyps = yy_ps; yypv = yy_pv; } /* ** code supplied by user is placed in this switch */ switch( yytmp ) { case 3: # line 574 "loadkeys.y" { enter_mapentry(yypvt[-2].number, yypvt[-1].keyentry); } break; case 4: # line 578 "loadkeys.y" { duplicate_mapentry(yypvt[-4].number, yypvt[-1].number); } break; case 5: # line 582 "loadkeys.y" { swap_mapentry(yypvt[-3].number, yypvt[-1].number); } break; case 7: # line 590 "loadkeys.y" { /* * Append this entry to the end of the entry list. */ register keyentry *kep; kep = yypvt[-1].keyentry; for (;;) { if (kep->ke_next == NULL) { kep->ke_next = yypvt[-0].keyentry; break; } kep = kep->ke_next; } yyval.keyentry = yypvt[-1].keyentry; } break; case 8: # line 606 "loadkeys.y" { yyval.keyentry = yypvt[-0].keyentry; } break; case 9: # line 613 "loadkeys.y" { yyval.keyentry = makeentry(yypvt[-1].number, yypvt[-0].number); } break; case 10: # line 620 "loadkeys.y" { yyval.number = yypvt[-0].number; } break; case 11: # line 624 "loadkeys.y" { yyval.number = yypvt[-0].number; } break; case 12: # line 628 "loadkeys.y" { yyval.number = '('; } break; case 13: # line 632 "loadkeys.y" { yyval.number = ')'; } break; case 14: # line 636 "loadkeys.y" { yyval.number = '+'; } break; case 15: # line 640 "loadkeys.y" { yyval.number = yypvt[-0].number; } break; case 16: # line 647 "loadkeys.y" { yyval.number = yypvt[-0].number; } break; case 17: # line 651 "loadkeys.y" { yyval.number = yypvt[-2].number + yypvt[-0].number; } break; case 18: # line 658 "loadkeys.y" { yyval.number = yypvt[-0].number; } break; case 19: # line 662 "loadkeys.y" { if (yypvt[-1].number < 1 || yypvt[-1].number > 16) yyerror("invalid function key number"); yyval.number = yypvt[-3].number + yypvt[-1].number - 1; } break; case 20: # line 671 "loadkeys.y" { yyval.number = yypvt[-0].number; } break; case 21: # line 675 "loadkeys.y" { if (isdigit(yypvt[-0].number)) yyval.number = yypvt[-0].number - '0'; else yyerror("syntax error"); } break; # line 556 "/usr/share/lib/ccs/yaccpar" } goto yystack; /* reset registers in driver code */ }