1 2 # line 2 "loadkeys.y" 3 /* 4 * CDDL HEADER START 5 * 6 * The contents of this file are subject to the terms of the 7 * Common Development and Distribution License, Version 1.0 only 8 * (the "License"). You may not use this file except in compliance 9 * with the License. 10 * 11 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 12 * or http://www.opensolaris.org/os/licensing. 13 * See the License for the specific language governing permissions 14 * and limitations under the License. 15 * 16 * When distributing Covered Code, include this CDDL HEADER in each 17 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 18 * If applicable, add the following below this CDDL HEADER, with the 19 * fields enclosed by brackets "[]" replaced with your own identifying 20 * information: Portions Copyright [yyyy] [name of copyright owner] 21 * 22 * CDDL HEADER END 23 */ 24 25 #ifndef lint 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 #endif 28 29 /* 30 * Copyright (c) 1999 by Sun Microsystems, Inc. 31 * All rights reserved. 32 */ 33 34 #include <sys/param.h> 35 #include <ctype.h> 36 #include <stdio.h> 37 #include <search.h> 38 #include <string.h> 39 #include <malloc.h> 40 #include <fcntl.h> 41 #include <stdlib.h> 42 #include <errno.h> 43 #include <unistd.h> 44 #include <sys/kbd.h> 45 #include <sys/kbio.h> 46 47 #define ALL -1 /* special symbol for all tables */ 48 49 /* 50 * SunOS 4.x and Solaris 2.[1234] put Type 4 key tables into 51 * the keytables directory with no type qualification. 52 * If we're a SPARC, we might be using an NFS server that 53 * doesn't have the new type-qualified directories. 54 * (loadkeys wasn't used on non-SPARCs in 2.[1234].) 55 */ 56 #ifdef sparc 57 #define COMPATIBILITY_DIR 58 #endif 59 60 static char keytable_dir[] = "/usr/share/lib/keytables/type_%d/"; 61 #ifdef COMPATIBILITY_DIR 62 static char keytable_dir2[] = "/usr/share/lib/keytables/"; 63 #endif 64 static char layout_prefix[] = "layout_"; 65 66 struct keyentry { 67 struct keyentry *ke_next; 68 struct kiockeymap ke_entry; 69 }; 70 71 typedef struct keyentry keyentry; 72 73 static keyentry *firstentry; 74 static keyentry *lastentry; 75 76 struct dupentry { 77 struct dupentry *de_next; 78 int de_station; 79 int de_otherstation; 80 }; 81 82 typedef struct dupentry dupentry; 83 84 static dupentry *firstduplicate; 85 static dupentry *lastduplicate; 86 87 static dupentry *firstswap; 88 static dupentry *lastswap; 89 90 static char *infilename; 91 static FILE *infile; 92 static int lineno; 93 static int begline; 94 95 static char *strings[16] = { 96 "\033[H", /* HOMEARROW */ 97 "\033[A", /* UPARROW */ 98 "\033[B", /* DOWNARROW */ 99 "\033[D", /* LEFTARROW */ 100 "\033[C", /* RIGHTARROW */ 101 }; 102 103 static int nstrings = 5; /* start out with 5 strings */ 104 105 typedef enum { 106 SM_INVALID, /* this shift mask is invalid for this keyboard */ 107 SM_NORMAL, /* "normal", valid shift mask */ 108 SM_NUMLOCK, /* "Num Lock" shift mask */ 109 SM_UP /* "Up" shift mask */ 110 } smtype_t; 111 112 typedef struct { 113 int sm_mask; 114 smtype_t sm_type; 115 } smentry_t; 116 117 static smentry_t shiftmasks[] = { 118 { 0, SM_NORMAL }, 119 { SHIFTMASK, SM_NORMAL }, 120 { CAPSMASK, SM_NORMAL }, 121 { CTRLMASK, SM_NORMAL }, 122 { ALTGRAPHMASK, SM_NORMAL }, 123 { NUMLOCKMASK, SM_NUMLOCK }, 124 { UPMASK, SM_UP }, 125 }; 126 127 128 #define NSHIFTS (sizeof (shiftmasks) / sizeof (shiftmasks[0])) 129 130 static void enter_mapentry(int station, keyentry *entrylistp); 131 static keyentry *makeentry(int tablemask, int entry); 132 static int loadkey(int kbdfd, keyentry *kep); 133 static int dupkey(int kbdfd, dupentry *dep, int shiftmask); 134 static int swapkey(int kbdfd, dupentry *dep, int shiftmask); 135 static int yylex(); 136 static int readesc(FILE *stream, int delim, int single_char); 137 static int wordcmp(const void *w1, const void *w2); 138 static int yyerror(char *msg); 139 static void usage(void); 140 static void set_layout(char *arg); 141 static FILE *open_mapping_file(char *pathbuf, char *name, 142 boolean_t explicit_name, int type); 143 144 int 145 main(argc, argv) 146 int argc; 147 char **argv; 148 { 149 register int kbdfd; 150 int type; 151 int layout; 152 /* maxint is 8 hex digits. */ 153 char layout_filename[sizeof(layout_prefix)+8]; 154 char pathbuf[MAXPATHLEN]; 155 register int shift; 156 struct kiockeymap mapentry; 157 register keyentry *kep; 158 register dupentry *dep; 159 boolean_t explicit_name; 160 161 while(++argv, --argc) { 162 if(argv[0][0] != '-') break; 163 switch(argv[0][1]) { 164 case 'e': 165 /* -e obsolete, silently ignore */ 166 break; 167 case 's': 168 if (argc != 2) { 169 usage(); 170 /* NOTREACHED */ 171 } 172 set_layout(argv[1]); 173 exit(0); 174 default: 175 usage(); 176 /* NOTREACHED */ 177 } 178 } 179 180 if (argc > 1) usage(); 181 182 if ((kbdfd = open("/dev/kbd", O_WRONLY)) < 0) { 183 /* perror("loadkeys: /dev/kbd"); */ 184 return (1); 185 } 186 187 if (ioctl(kbdfd, KIOCTYPE, &type) < 0) { 188 /* 189 * There may not be a keyboard connected, 190 * return silently 191 */ 192 return (1); 193 } 194 195 if (argc == 0) { 196 /* If no keyboard detected, exit silently. */ 197 if (type == -1) 198 return (0); 199 200 if (ioctl(kbdfd, KIOCLAYOUT, &layout) < 0) { 201 perror("loadkeys: ioctl(KIOCLAYOUT)"); 202 return (1); 203 } 204 205 (void) sprintf(layout_filename, 206 "%s%.2x", layout_prefix, layout); 207 infilename = layout_filename; 208 explicit_name = B_FALSE; 209 } else { 210 infilename = argv[0]; 211 explicit_name = B_TRUE; 212 } 213 214 infile = open_mapping_file(pathbuf, infilename, explicit_name, type); 215 if (infile == NULL) return (1); 216 217 infilename = pathbuf; 218 219 lineno = 0; 220 begline = 1; 221 yyparse(); 222 fclose(infile); 223 224 /* 225 * See which shift masks are valid for this keyboard. 226 * We do that by trying to get the entry for keystation 0 and that 227 * shift mask; if the "ioctl" fails, we assume it's because the shift 228 * mask is invalid. 229 */ 230 for (shift = 0; shift < NSHIFTS; shift++) { 231 mapentry.kio_tablemask = 232 shiftmasks[shift].sm_mask; 233 mapentry.kio_station = 0; 234 if (ioctl(kbdfd, KIOCGKEY, &mapentry) < 0) 235 shiftmasks[shift].sm_type = SM_INVALID; 236 } 237 238 for (kep = firstentry; kep != NULL; kep = kep->ke_next) { 239 if (kep->ke_entry.kio_tablemask == ALL) { 240 for (shift = 0; shift < NSHIFTS; shift++) { 241 switch (shiftmasks[shift].sm_type) { 242 243 case SM_INVALID: 244 continue; 245 246 case SM_NUMLOCK: 247 /* 248 * Defaults to NONL, not to a copy of 249 * the base entry. 250 */ 251 if (kep->ke_entry.kio_entry != HOLE) 252 kep->ke_entry.kio_entry = NONL; 253 break; 254 255 case SM_UP: 256 /* 257 * Defaults to NOP, not to a copy of 258 * the base entry. 259 */ 260 if (kep->ke_entry.kio_entry != HOLE) 261 kep->ke_entry.kio_entry = NOP; 262 break; 263 } 264 kep->ke_entry.kio_tablemask = 265 shiftmasks[shift].sm_mask; 266 if (!loadkey(kbdfd, kep)) 267 return (1); 268 } 269 } else { 270 if (!loadkey(kbdfd, kep)) 271 return (1); 272 } 273 } 274 275 for (dep = firstswap; dep != NULL; dep = dep->de_next) { 276 for (shift = 0; shift < NSHIFTS; shift++) { 277 if (shiftmasks[shift].sm_type != SM_INVALID) { 278 if (!swapkey(kbdfd, dep, 279 shiftmasks[shift].sm_mask)) 280 return (0); 281 } 282 } 283 } 284 285 for (dep = firstduplicate; dep != NULL; dep = dep->de_next) { 286 for (shift = 0; shift < NSHIFTS; shift++) { 287 if (shiftmasks[shift].sm_type != SM_INVALID) { 288 if (!dupkey(kbdfd, dep, 289 shiftmasks[shift].sm_mask)) 290 return (0); 291 } 292 } 293 } 294 295 close(kbdfd); 296 return (0); 297 } 298 299 static void 300 usage() 301 { 302 (void) fprintf(stderr, "usage: loadkeys [ file ]\n"); 303 exit(1); 304 } 305 306 static void 307 set_layout(char *arg) 308 { 309 int layout; 310 int ret; 311 int kbdfd; 312 313 layout = (int) strtol(arg, &arg, 0); 314 if (*arg != '\0') { 315 fprintf(stderr, "usage: loadkeys -s layoutnumber\n"); 316 exit(1); 317 } 318 319 if ((kbdfd = open("/dev/kbd", O_WRONLY)) < 0) { 320 perror("/dev/kbd"); 321 exit(1); 322 } 323 324 ret = ioctl(kbdfd, KIOCSLAYOUT, layout); 325 if (ret == -1) { 326 perror("KIOCSLAYOUT"); 327 } 328 329 close(kbdfd); 330 } 331 332 /* 333 * Attempt to find the specified mapping file. Return a FILE * if found, 334 * else print a message on stderr and return NULL. 335 */ 336 FILE * 337 open_mapping_file( 338 char *pathbuf, 339 char *name, 340 boolean_t explicit_name, 341 int type 342 ) { 343 /* If the user specified the name, try it "raw". */ 344 if (explicit_name) { 345 strcpy(pathbuf, name); 346 infile = fopen(pathbuf, "r"); 347 if (infile) return (infile); 348 if (errno != ENOENT) goto fopen_fail; 349 } 350 351 /* Everything after this point applies only to relative names. */ 352 if (*name == '/') goto fopen_fail; 353 354 /* Try the type-qualified directory name. */ 355 sprintf(pathbuf, keytable_dir, type); 356 if ((int)(strlen(pathbuf) + strlen(name) + 1) >= MAXPATHLEN) { 357 (void) fprintf(stderr, "loadkeys: Name %s is too long\n", 358 name); 359 return (NULL); 360 } 361 (void) strcat(pathbuf, name); 362 infile = fopen(pathbuf, "r"); 363 if (infile) return (infile); 364 if (errno != ENOENT) goto fopen_fail; 365 366 #ifdef COMPATIBILITY_DIR 367 /* If not, and either the name was specified explicitly */ 368 /* or this is a type 4... */ 369 if (explicit_name || type == KB_SUN4) { 370 /* Try the compatibility name. */ 371 /* No need to check len here, it's shorter. */ 372 (void) strcpy(pathbuf, keytable_dir2); 373 (void) strcat(pathbuf, infilename); 374 infile = fopen(pathbuf, "r"); 375 if (infile) return (infile); 376 if (errno != ENOENT) goto fopen_fail; 377 } 378 #endif 379 380 fopen_fail: 381 (void) fprintf(stderr, "loadkeys: "); 382 perror(name); 383 return (NULL); 384 } 385 386 /* 387 * We have a list of entries for a given keystation, and the keystation number 388 * for that keystation; put that keystation number into all the entries in that 389 * list, and chain that list to the end of the main list of entries. 390 */ 391 static void 392 enter_mapentry(station, entrylistp) 393 int station; 394 keyentry *entrylistp; 395 { 396 register keyentry *kep; 397 398 if (lastentry == NULL) 399 firstentry = entrylistp; 400 else 401 lastentry->ke_next = entrylistp; 402 kep = entrylistp; 403 for (;;) { 404 kep->ke_entry.kio_station = (u_char)station; 405 if (kep->ke_next == NULL) { 406 lastentry = kep; 407 break; 408 } 409 kep = kep->ke_next; 410 } 411 } 412 413 /* 414 * Allocate and fill in a new entry. 415 */ 416 static keyentry * 417 makeentry(tablemask, entry) 418 int tablemask; 419 int entry; 420 { 421 register keyentry *kep; 422 register int index; 423 424 if ((kep = (keyentry *) malloc((unsigned)sizeof (keyentry))) == NULL) 425 yyerror("out of memory for entries"); 426 kep->ke_next = NULL; 427 kep->ke_entry.kio_tablemask = tablemask; 428 kep->ke_entry.kio_station = 0; 429 kep->ke_entry.kio_entry = (u_short)entry; 430 index = entry - STRING; 431 if (index >= 0 && index <= 15) 432 (void) strncpy(kep->ke_entry.kio_string, strings[index], 433 KTAB_STRLEN); 434 return (kep); 435 } 436 437 /* 438 * Make a set of entries for a keystation that indicate that that keystation's 439 * settings should be copied from another keystation's settings. 440 */ 441 static void 442 duplicate_mapentry(station, otherstation) 443 int station; 444 int otherstation; 445 { 446 register dupentry *dep; 447 448 if ((dep = (dupentry *) malloc((unsigned)sizeof (dupentry))) == NULL) 449 yyerror("out of memory for entries"); 450 451 if (lastduplicate == NULL) 452 firstduplicate = dep; 453 else 454 lastduplicate->de_next = dep; 455 lastduplicate = dep; 456 dep->de_next = NULL; 457 dep->de_station = station; 458 dep->de_otherstation = otherstation; 459 } 460 461 /* 462 * Make a set of entries for a keystation that indicate that that keystation's 463 * settings should be swapped with another keystation's settings. 464 */ 465 static void 466 swap_mapentry(station, otherstation) 467 int station; 468 int otherstation; 469 { 470 register dupentry *dep; 471 472 if ((dep = (dupentry *) malloc((unsigned)sizeof (dupentry))) == NULL) 473 yyerror("out of memory for entries"); 474 475 if (lastswap == NULL) 476 firstswap = dep; 477 else 478 lastswap->de_next = dep; 479 lastswap = dep; 480 dep->de_next = NULL; 481 dep->de_station = station; 482 dep->de_otherstation = otherstation; 483 } 484 485 static int 486 loadkey(kbdfd, kep) 487 int kbdfd; 488 register keyentry *kep; 489 { 490 if (ioctl(kbdfd, KIOCSKEY, &kep->ke_entry) < 0) { 491 perror("loadkeys: ioctl(KIOCSKEY)"); 492 return (0); 493 } 494 return (1); 495 } 496 497 static int 498 dupkey(kbdfd, dep, shiftmask) 499 int kbdfd; 500 register dupentry *dep; 501 int shiftmask; 502 { 503 struct kiockeymap entry; 504 505 entry.kio_tablemask = shiftmask; 506 entry.kio_station = dep->de_otherstation; 507 if (ioctl(kbdfd, KIOCGKEY, &entry) < 0) { 508 perror("loadkeys: ioctl(KIOCGKEY)"); 509 return (0); 510 } 511 entry.kio_station = dep->de_station; 512 if (ioctl(kbdfd, KIOCSKEY, &entry) < 0) { 513 perror("loadkeys: ioctl(KIOCSKEY)"); 514 return (0); 515 } 516 return (1); 517 } 518 519 520 521 static int 522 swapkey(kbdfd, dep, shiftmask) 523 int kbdfd; 524 register dupentry *dep; 525 int shiftmask; 526 { 527 struct kiockeymap entry1, entry2; 528 529 entry1.kio_tablemask = shiftmask; 530 entry1.kio_station = dep->de_station; 531 if (ioctl(kbdfd, KIOCGKEY, &entry1) < 0) { 532 perror("loadkeys: ioctl(KIOCGKEY)"); 533 return (0); 534 } 535 entry2.kio_tablemask = shiftmask; 536 entry2.kio_station = dep->de_otherstation; 537 if (ioctl(kbdfd, KIOCGKEY, &entry2) < 0) { 538 perror("loadkeys: ioctl(KIOCGKEY)"); 539 return (0); 540 } 541 entry1.kio_station = dep->de_otherstation; 542 if (ioctl(kbdfd, KIOCSKEY, &entry1) < 0) { 543 perror("loadkeys: ioctl(KIOCSKEY)"); 544 return (0); 545 } 546 entry2.kio_station = dep->de_station; 547 if (ioctl(kbdfd, KIOCSKEY, &entry2) < 0) { 548 perror("loadkeys: ioctl(KIOCSKEY)"); 549 return (0); 550 } 551 return (1); 552 } 553 554 # line 556 "loadkeys.y" 555 typedef union 556 #ifdef __cplusplus 557 YYSTYPE 558 #endif 559 { 560 keyentry *keyentry; 561 int number; 562 } YYSTYPE; 563 # define TABLENAME 257 564 # define INT 258 565 # define CHAR 259 566 # define CHARSTRING 260 567 # define CONSTANT 261 568 # define FKEY 262 569 # define KEY 263 570 # define SAME 264 571 # define AS 265 572 # define SWAP 266 573 # define WITH 267 574 575 #include <inttypes.h> 576 577 #ifdef __STDC__ 578 #include <stdlib.h> 579 #include <string.h> 580 #define YYCONST const 581 #else 582 #include <malloc.h> 583 #include <memory.h> 584 #define YYCONST 585 #endif 586 587 #include <values.h> 588 589 #if defined(__cplusplus) || defined(__STDC__) 590 591 #if defined(__cplusplus) && defined(__EXTERN_C__) 592 extern "C" { 593 #endif 594 #ifndef yyerror 595 #if defined(__cplusplus) 596 void yyerror(YYCONST char *); 597 #endif 598 #endif 599 #ifndef yylex 600 int yylex(void); 601 #endif 602 int yyparse(void); 603 #if defined(__cplusplus) && defined(__EXTERN_C__) 604 } 605 #endif 606 607 #endif 608 609 #define yyclearin yychar = -1 610 #define yyerrok yyerrflag = 0 611 extern int yychar; 612 extern int yyerrflag; 613 YYSTYPE yylval; 614 YYSTYPE yyval; 615 typedef int yytabelem; 616 #ifndef YYMAXDEPTH 617 #define YYMAXDEPTH 150 618 #endif 619 #if YYMAXDEPTH > 0 620 int yy_yys[YYMAXDEPTH], *yys = yy_yys; 621 YYSTYPE yy_yyv[YYMAXDEPTH], *yyv = yy_yyv; 622 #else /* user does initial allocation */ 623 int *yys; 624 YYSTYPE *yyv; 625 #endif 626 static int yymaxdepth = YYMAXDEPTH; 627 # define YYERRCODE 256 628 629 # line 683 "loadkeys.y" 630 631 632 typedef struct { 633 char *w_string; 634 int w_type; /* token type */ 635 int w_lval; /* yylval for this token */ 636 } word_t; 637 638 /* 639 * Table must be in alphabetical order. 640 */ 641 word_t wordtab[] = { 642 { "all", TABLENAME, ALL }, 643 { "alt", CONSTANT, ALT }, 644 { "altg", TABLENAME, ALTGRAPHMASK }, 645 { "altgraph", CONSTANT, ALTGRAPH }, 646 { "as", AS, 0 }, 647 { "base", TABLENAME, 0 }, 648 { "bf", FKEY, BOTTOMFUNC }, 649 { "buckybits", CONSTANT, BUCKYBITS }, 650 { "caps", TABLENAME, CAPSMASK }, 651 { "capslock", CONSTANT, CAPSLOCK }, 652 { "compose", CONSTANT, COMPOSE }, 653 { "ctrl", TABLENAME, CTRLMASK }, 654 { "downarrow", CONSTANT, DOWNARROW }, 655 { "error", CONSTANT, ERROR }, 656 { "fa_acute", CONSTANT, FA_ACUTE }, 657 { "fa_cedilla", CONSTANT, FA_CEDILLA }, 658 { "fa_cflex", CONSTANT, FA_CFLEX }, 659 { "fa_grave", CONSTANT, FA_GRAVE }, 660 { "fa_tilde", CONSTANT, FA_TILDE }, 661 { "fa_umlaut", CONSTANT, FA_UMLAUT }, 662 { "hole", CONSTANT, HOLE }, 663 { "homearrow", CONSTANT, HOMEARROW }, 664 { "idle", CONSTANT, IDLE }, 665 { "key", KEY, 0 }, 666 { "leftarrow", CONSTANT, LEFTARROW }, 667 { "leftctrl", CONSTANT, LEFTCTRL }, 668 { "leftshift", CONSTANT, LEFTSHIFT }, 669 { "lf", FKEY, LEFTFUNC }, 670 { "metabit", CONSTANT, METABIT }, 671 { "nonl", CONSTANT, NONL }, 672 { "nop", CONSTANT, NOP }, 673 { "numl", TABLENAME, NUMLOCKMASK }, 674 { "numlock", CONSTANT, NUMLOCK }, 675 { "oops", CONSTANT, OOPS }, 676 { "pad0", CONSTANT, PAD0 }, 677 { "pad1", CONSTANT, PAD1 }, 678 { "pad2", CONSTANT, PAD2 }, 679 { "pad3", CONSTANT, PAD3 }, 680 { "pad4", CONSTANT, PAD4 }, 681 { "pad5", CONSTANT, PAD5 }, 682 { "pad6", CONSTANT, PAD6 }, 683 { "pad7", CONSTANT, PAD7 }, 684 { "pad8", CONSTANT, PAD8 }, 685 { "pad9", CONSTANT, PAD9 }, 686 { "paddot", CONSTANT, PADDOT }, 687 { "padenter", CONSTANT, PADENTER }, 688 { "padequal", CONSTANT, PADEQUAL }, 689 { "padminus", CONSTANT, PADMINUS }, 690 { "padplus", CONSTANT, PADPLUS }, 691 { "padsep", CONSTANT, PADSEP }, 692 { "padslash", CONSTANT, PADSLASH }, 693 { "padstar", CONSTANT, PADSTAR }, 694 { "reset", CONSTANT, RESET }, 695 { "rf", FKEY, RIGHTFUNC }, 696 { "rightarrow", CONSTANT, RIGHTARROW }, 697 { "rightctrl", CONSTANT, RIGHTCTRL }, 698 { "rightshift", CONSTANT, RIGHTSHIFT }, 699 { "same", SAME, 0 }, 700 { "shift", TABLENAME, SHIFTMASK }, 701 { "shiftkeys", CONSTANT, SHIFTKEYS }, 702 { "shiftlock", CONSTANT, SHIFTLOCK }, 703 { "string", CONSTANT, STRING }, 704 { "swap", SWAP, 0 }, 705 { "systembit", CONSTANT, SYSTEMBIT }, 706 { "tf", FKEY, TOPFUNC }, 707 { "up", TABLENAME, UPMASK }, 708 { "uparrow", CONSTANT, UPARROW }, 709 { "with", WITH, 0 }, 710 }; 711 712 #define NWORDS (sizeof (wordtab) / sizeof (wordtab[0])) 713 714 static int 715 yylex() 716 { 717 register int c; 718 char tokbuf[256+1]; 719 register char *cp; 720 register int tokentype; 721 722 while ((c = getc(infile)) == ' ' || c == '\t') 723 ; 724 if (begline) { 725 lineno++; 726 begline = 0; 727 if (c == '#') { 728 while ((c = getc(infile)) != EOF && c != '\n') 729 ; 730 } 731 } 732 if (c == EOF) 733 return (0); /* end marker */ 734 if (c == '\n') { 735 begline = 1; 736 return (c); 737 } 738 739 switch (c) { 740 741 case '\'': 742 tokentype = CHAR; 743 if ((c = getc(infile)) == EOF) 744 yyerror("unterminated character constant"); 745 if (c == '\n') { 746 (void) ungetc(c, infile); 747 yylval.number = '\''; 748 } else { 749 switch (c) { 750 751 case '\'': 752 yyerror("null character constant"); 753 break; 754 755 case '\\': 756 yylval.number = readesc(infile, '\'', 1); 757 break; 758 759 default: 760 yylval.number = c; 761 break; 762 } 763 if ((c = getc(infile)) == EOF || c == '\n') 764 yyerror("unterminated character constant"); 765 else if (c != '\'') 766 yyerror("only one character allowed in character constant"); 767 } 768 break; 769 770 case '"': 771 if ((c = getc(infile)) == EOF) 772 yyerror("unterminated string constant"); 773 if (c == '\n') { 774 (void) ungetc(c, infile); 775 tokentype = CHAR; 776 yylval.number = '"'; 777 } else { 778 tokentype = CHARSTRING; 779 cp = &tokbuf[0]; 780 do { 781 if (cp > &tokbuf[256]) 782 yyerror("line too long"); 783 if (c == '\\') 784 c = readesc(infile, '"', 0); 785 *cp++ = (char)c; 786 } while ((c = getc(infile)) != EOF && c != '\n' && 787 c != '"'); 788 if (c != '"') 789 yyerror("unterminated string constant"); 790 *cp = '\0'; 791 if (nstrings == 16) 792 yyerror("too many strings"); 793 if ((int) strlen(tokbuf) > KTAB_STRLEN) 794 yyerror("string too long"); 795 strings[nstrings] = strdup(tokbuf); 796 yylval.number = STRING+nstrings; 797 nstrings++; 798 } 799 break; 800 801 case '(': 802 case ')': 803 case '+': 804 tokentype = c; 805 break; 806 807 case '^': 808 if ((c = getc(infile)) == EOF) 809 yyerror("missing newline at end of line"); 810 tokentype = CHAR; 811 if (c == ' ' || c == '\t' || c == '\n') { 812 /* 813 * '^' by itself. 814 */ 815 yylval.number = '^'; 816 } else { 817 yylval.number = c & 037; 818 if ((c = getc(infile)) == EOF) 819 yyerror("missing newline at end of line"); 820 if (c != ' ' && c != '\t' && c != '\n') 821 yyerror("invalid control character"); 822 } 823 (void) ungetc(c, infile); 824 break; 825 826 default: 827 cp = &tokbuf[0]; 828 do { 829 if (cp > &tokbuf[256]) 830 yyerror("line too long"); 831 *cp++ = (char)c; 832 } while ((c = getc(infile)) != EOF && (isalnum(c) || c == '_')); 833 if (c == EOF) 834 yyerror("newline missing"); 835 (void) ungetc(c, infile); 836 *cp = '\0'; 837 if (strlen(tokbuf) == 1) { 838 tokentype = CHAR; 839 yylval.number = (unsigned char)tokbuf[0]; 840 } else if (strlen(tokbuf) == 2 && tokbuf[0] == '^') { 841 tokentype = CHAR; 842 yylval.number = (unsigned char)(tokbuf[1] & 037); 843 } else { 844 word_t word; 845 register word_t *wptr; 846 char *ptr; 847 848 for (cp = &tokbuf[0]; (c = *cp) != '\0'; cp++) { 849 if (isupper(c)) 850 *cp = tolower(c); 851 } 852 word.w_string = tokbuf; 853 wptr = (word_t *)bsearch((char *)&word, 854 (char *)wordtab, NWORDS, sizeof (word_t), 855 wordcmp); 856 if (wptr != NULL) { 857 yylval.number = wptr->w_lval; 858 tokentype = wptr->w_type; 859 } else { 860 yylval.number = strtol(tokbuf, &ptr, 10); 861 if (ptr == tokbuf) 862 yyerror("syntax error"); 863 else 864 tokentype = INT; 865 } 866 break; 867 } 868 } 869 870 return (tokentype); 871 } 872 873 static int 874 readesc(stream, delim, single_char) 875 FILE *stream; 876 int delim; 877 int single_char; 878 { 879 register int c; 880 register int val; 881 register int i; 882 883 if ((c = getc(stream)) == EOF || c == '\n') 884 yyerror("unterminated character constant"); 885 886 if (c >= '0' && c <= '7') { 887 val = 0; 888 i = 1; 889 for (;;) { 890 val = val*8 + c - '0'; 891 if ((c = getc(stream)) == EOF || c == '\n') 892 yyerror("unterminated character constant"); 893 if (c == delim) 894 break; 895 i++; 896 if (i > 3) { 897 if (single_char) 898 yyerror("escape sequence too long"); 899 else 900 break; 901 } 902 if (c < '0' || c > '7') { 903 if (single_char) 904 yyerror("illegal character in escape sequence"); 905 else 906 break; 907 } 908 } 909 (void) ungetc(c, stream); 910 } else { 911 switch (c) { 912 913 case 'n': 914 val = '\n'; 915 break; 916 917 case 't': 918 val = '\t'; 919 break; 920 921 case 'b': 922 val = '\b'; 923 break; 924 925 case 'r': 926 val = '\r'; 927 break; 928 929 case 'v': 930 val = '\v'; 931 break; 932 933 case '\\': 934 val = '\\'; 935 break; 936 937 default: 938 if (c == delim) 939 val = delim; 940 else 941 yyerror("illegal character in escape sequence"); 942 } 943 } 944 return (val); 945 } 946 947 static int 948 wordcmp(const void *w1, const void *w2) 949 { 950 return (strcmp( 951 ((const word_t *)w1)->w_string, 952 ((const word_t *)w2)->w_string)); 953 } 954 955 static int 956 yyerror(msg) 957 char *msg; 958 { 959 (void) fprintf(stderr, "%s, line %d: %s\n", infilename, lineno, msg); 960 exit(1); 961 } 962 static YYCONST yytabelem yyexca[] ={ 963 -1, 1, 964 0, -1, 965 -2, 0, 966 }; 967 # define YYNPROD 22 968 # define YYLAST 260 969 static YYCONST yytabelem yyact[]={ 970 971 21, 22, 5, 23, 14, 17, 13, 26, 27, 7, 972 8, 30, 15, 11, 36, 31, 6, 12, 25, 33, 973 32, 9, 2, 1, 24, 18, 10, 0, 16, 0, 974 0, 28, 0, 0, 29, 0, 0, 0, 0, 0, 975 0, 0, 0, 0, 0, 0, 0, 0, 35, 34, 976 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 977 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 978 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 979 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 980 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 981 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 982 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 983 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 984 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 985 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 986 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 987 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 988 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 989 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 990 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 991 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 992 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 993 19, 26, 27, 0, 0, 0, 0, 0, 0, 0, 994 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 995 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 996 0, 0, 0, 0, 0, 3, 0, 0, 4, 13 }; 997 static YYCONST yytabelem yypact[]={ 998 999 -10000000, -8,-10000000, -249, -249,-10000000, -251,-10000000,-10000000, -263, 1000 2, -260,-10000000, -40, -249,-10000000,-10000000, -249,-10000000,-10000000, 1001 -10000000,-10000000,-10000000,-10000000, -32,-10000000,-10000000, -25, 10, 9, 1002 -254, -249,-10000000,-10000000,-10000000, -27,-10000000 }; 1003 static YYCONST yytabelem yypgo[]={ 1004 1005 0, 26, 17, 25, 24, 18, 16, 23, 22 }; 1006 static YYCONST yytabelem yyr1[]={ 1007 1008 0, 7, 7, 8, 8, 8, 8, 1, 1, 2, 1009 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 1010 6, 6 }; 1011 static YYCONST yytabelem yyr2[]={ 1012 1013 0, 4, 0, 9, 13, 11, 2, 5, 3, 5, 1014 3, 3, 3, 3, 3, 3, 3, 7, 3, 9, 1015 3, 3 }; 1016 static YYCONST yytabelem yychk[]={ 1017 1018 -10000000, -7, -8, 263, 266, 10, -6, 258, 259, -6, 1019 -1, 264, -2, 257, 267, 10, -2, 265, -3, 260, 1020 259, 40, 41, 43, -4, -5, 261, 262, -6, -6, 1021 43, 40, 10, 10, -5, -6, 41 }; 1022 static YYCONST yytabelem yydef[]={ 1023 1024 2, -2, 1, 0, 0, 6, 0, 20, 21, 0, 1025 0, 0, 8, 0, 0, 3, 7, 0, 9, 10, 1026 11, 12, 13, 14, 15, 16, 18, 0, 0, 0, 1027 0, 0, 5, 4, 17, 0, 19 }; 1028 typedef struct 1029 #ifdef __cplusplus 1030 yytoktype 1031 #endif 1032 { 1033 #ifdef __cplusplus 1034 const 1035 #endif 1036 char *t_name; int t_val; } yytoktype; 1037 #ifndef YYDEBUG 1038 # define YYDEBUG 0 /* don't allow debugging */ 1039 #endif 1040 1041 #if YYDEBUG 1042 1043 yytoktype yytoks[] = 1044 { 1045 "TABLENAME", 257, 1046 "INT", 258, 1047 "CHAR", 259, 1048 "CHARSTRING", 260, 1049 "CONSTANT", 261, 1050 "FKEY", 262, 1051 "KEY", 263, 1052 "SAME", 264, 1053 "AS", 265, 1054 "SWAP", 266, 1055 "WITH", 267, 1056 "-unknown-", -1 /* ends search */ 1057 }; 1058 1059 #ifdef __cplusplus 1060 const 1061 #endif 1062 char * yyreds[] = 1063 { 1064 "-no such reduction-", 1065 "table : table line", 1066 "table : /* empty */", 1067 "line : KEY number entrylist '\n'", 1068 "line : KEY number SAME AS number '\n'", 1069 "line : SWAP number WITH number '\n'", 1070 "line : '\n'", 1071 "entrylist : entrylist entry", 1072 "entrylist : entry", 1073 "entry : TABLENAME code", 1074 "code : CHARSTRING", 1075 "code : CHAR", 1076 "code : '('", 1077 "code : ')'", 1078 "code : '+'", 1079 "code : expr", 1080 "expr : term", 1081 "expr : expr '+' term", 1082 "term : CONSTANT", 1083 "term : FKEY '(' number ')'", 1084 "number : INT", 1085 "number : CHAR", 1086 }; 1087 #endif /* YYDEBUG */ 1088 # line 1 "/usr/share/lib/ccs/yaccpar" 1089 /* 1090 * CDDL HEADER START 1091 * 1092 * The contents of this file are subject to the terms of the 1093 * Common Development and Distribution License, Version 1.0 only 1094 * (the "License"). You may not use this file except in compliance 1095 * with the License. 1096 * 1097 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 1098 * or http://www.opensolaris.org/os/licensing. 1099 * See the License for the specific language governing permissions 1100 * and limitations under the License. 1101 * 1102 * When distributing Covered Code, include this CDDL HEADER in each 1103 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1104 * If applicable, add the following below this CDDL HEADER, with the 1105 * fields enclosed by brackets "[]" replaced with your own identifying 1106 * information: Portions Copyright [yyyy] [name of copyright owner] 1107 * 1108 * CDDL HEADER END 1109 */ 1110 /* 1111 * Copyright 1993 Sun Microsystems, Inc. All rights reserved. 1112 * Use is subject to license terms. 1113 */ 1114 1115 /* Copyright (c) 1988 AT&T */ 1116 /* All Rights Reserved */ 1117 1118 #pragma ident "%Z%%M% %I% %E% SMI" 1119 1120 /* 1121 ** Skeleton parser driver for yacc output 1122 */ 1123 1124 /* 1125 ** yacc user known macros and defines 1126 */ 1127 #define YYERROR goto yyerrlab 1128 #define YYACCEPT return(0) 1129 #define YYABORT return(1) 1130 #define YYBACKUP( newtoken, newvalue )\ 1131 {\ 1132 if ( yychar >= 0 || ( yyr2[ yytmp ] >> 1 ) != 1 )\ 1133 {\ 1134 yyerror( "syntax error - cannot backup" );\ 1135 goto yyerrlab;\ 1136 }\ 1137 yychar = newtoken;\ 1138 yystate = *yyps;\ 1139 yylval = newvalue;\ 1140 goto yynewstate;\ 1141 } 1142 #define YYRECOVERING() (!!yyerrflag) 1143 #define YYNEW(type) malloc(sizeof(type) * yynewmax) 1144 #define YYCOPY(to, from, type) \ 1145 (type *) memcpy(to, (char *) from, yymaxdepth * sizeof (type)) 1146 #define YYENLARGE( from, type) \ 1147 (type *) realloc((char *) from, yynewmax * sizeof(type)) 1148 #ifndef YYDEBUG 1149 # define YYDEBUG 1 /* make debugging available */ 1150 #endif 1151 1152 /* 1153 ** user known globals 1154 */ 1155 int yydebug; /* set to 1 to get debugging */ 1156 1157 /* 1158 ** driver internal defines 1159 */ 1160 #define YYFLAG (-10000000) 1161 1162 /* 1163 ** global variables used by the parser 1164 */ 1165 YYSTYPE *yypv; /* top of value stack */ 1166 int *yyps; /* top of state stack */ 1167 1168 int yystate; /* current state */ 1169 int yytmp; /* extra var (lasts between blocks) */ 1170 1171 int yynerrs; /* number of errors */ 1172 int yyerrflag; /* error recovery flag */ 1173 int yychar; /* current input token number */ 1174 1175 1176 1177 #ifdef YYNMBCHARS 1178 #define YYLEX() yycvtok(yylex()) 1179 /* 1180 ** yycvtok - return a token if i is a wchar_t value that exceeds 255. 1181 ** If i<255, i itself is the token. If i>255 but the neither 1182 ** of the 30th or 31st bit is on, i is already a token. 1183 */ 1184 #if defined(__STDC__) || defined(__cplusplus) 1185 int yycvtok(int i) 1186 #else 1187 int yycvtok(i) int i; 1188 #endif 1189 { 1190 int first = 0; 1191 int last = YYNMBCHARS - 1; 1192 int mid; 1193 wchar_t j; 1194 1195 if(i&0x60000000){/*Must convert to a token. */ 1196 if( yymbchars[last].character < i ){ 1197 return i;/*Giving up*/ 1198 } 1199 while ((last>=first)&&(first>=0)) {/*Binary search loop*/ 1200 mid = (first+last)/2; 1201 j = yymbchars[mid].character; 1202 if( j==i ){/*Found*/ 1203 return yymbchars[mid].tvalue; 1204 }else if( j<i ){ 1205 first = mid + 1; 1206 }else{ 1207 last = mid -1; 1208 } 1209 } 1210 /*No entry in the table.*/ 1211 return i;/* Giving up.*/ 1212 }else{/* i is already a token. */ 1213 return i; 1214 } 1215 } 1216 #else/*!YYNMBCHARS*/ 1217 #define YYLEX() yylex() 1218 #endif/*!YYNMBCHARS*/ 1219 1220 /* 1221 ** yyparse - return 0 if worked, 1 if syntax error not recovered from 1222 */ 1223 #if defined(__STDC__) || defined(__cplusplus) 1224 int yyparse(void) 1225 #else 1226 int yyparse() 1227 #endif 1228 { 1229 register YYSTYPE *yypvt = 0; /* top of value stack for $vars */ 1230 1231 #if defined(__cplusplus) || defined(lint) 1232 /* 1233 hacks to please C++ and lint - goto's inside 1234 switch should never be executed 1235 */ 1236 static int __yaccpar_lint_hack__ = 0; 1237 switch (__yaccpar_lint_hack__) 1238 { 1239 case 1: goto yyerrlab; 1240 case 2: goto yynewstate; 1241 } 1242 #endif 1243 1244 /* 1245 ** Initialize externals - yyparse may be called more than once 1246 */ 1247 yypv = &yyv[-1]; 1248 yyps = &yys[-1]; 1249 yystate = 0; 1250 yytmp = 0; 1251 yynerrs = 0; 1252 yyerrflag = 0; 1253 yychar = -1; 1254 1255 #if YYMAXDEPTH <= 0 1256 if (yymaxdepth <= 0) 1257 { 1258 if ((yymaxdepth = YYEXPAND(0)) <= 0) 1259 { 1260 yyerror("yacc initialization error"); 1261 YYABORT; 1262 } 1263 } 1264 #endif 1265 1266 { 1267 register YYSTYPE *yy_pv; /* top of value stack */ 1268 register int *yy_ps; /* top of state stack */ 1269 register int yy_state; /* current state */ 1270 register int yy_n; /* internal state number info */ 1271 goto yystack; /* moved from 6 lines above to here to please C++ */ 1272 1273 /* 1274 ** get globals into registers. 1275 ** branch to here only if YYBACKUP was called. 1276 */ 1277 yynewstate: 1278 yy_pv = yypv; 1279 yy_ps = yyps; 1280 yy_state = yystate; 1281 goto yy_newstate; 1282 1283 /* 1284 ** get globals into registers. 1285 ** either we just started, or we just finished a reduction 1286 */ 1287 yystack: 1288 yy_pv = yypv; 1289 yy_ps = yyps; 1290 yy_state = yystate; 1291 1292 /* 1293 ** top of for (;;) loop while no reductions done 1294 */ 1295 yy_stack: 1296 /* 1297 ** put a state and value onto the stacks 1298 */ 1299 #if YYDEBUG 1300 /* 1301 ** if debugging, look up token value in list of value vs. 1302 ** name pairs. 0 and negative (-1) are special values. 1303 ** Note: linear search is used since time is not a real 1304 ** consideration while debugging. 1305 */ 1306 if ( yydebug ) 1307 { 1308 register int yy_i; 1309 1310 printf( "State %d, token ", yy_state ); 1311 if ( yychar == 0 ) 1312 printf( "end-of-file\n" ); 1313 else if ( yychar < 0 ) 1314 printf( "-none-\n" ); 1315 else 1316 { 1317 for ( yy_i = 0; yytoks[yy_i].t_val >= 0; 1318 yy_i++ ) 1319 { 1320 if ( yytoks[yy_i].t_val == yychar ) 1321 break; 1322 } 1323 printf( "%s\n", yytoks[yy_i].t_name ); 1324 } 1325 } 1326 #endif /* YYDEBUG */ 1327 if ( ++yy_ps >= &yys[ yymaxdepth ] ) /* room on stack? */ 1328 { 1329 /* 1330 ** reallocate and recover. Note that pointers 1331 ** have to be reset, or bad things will happen 1332 */ 1333 long yyps_index = (yy_ps - yys); 1334 long yypv_index = (yy_pv - yyv); 1335 long yypvt_index = (yypvt - yyv); 1336 int yynewmax; 1337 #ifdef YYEXPAND 1338 yynewmax = YYEXPAND(yymaxdepth); 1339 #else 1340 yynewmax = 2 * yymaxdepth; /* double table size */ 1341 if (yymaxdepth == YYMAXDEPTH) /* first time growth */ 1342 { 1343 char *newyys = (char *)YYNEW(int); 1344 char *newyyv = (char *)YYNEW(YYSTYPE); 1345 if (newyys != 0 && newyyv != 0) 1346 { 1347 yys = YYCOPY(newyys, yys, int); 1348 yyv = YYCOPY(newyyv, yyv, YYSTYPE); 1349 } 1350 else 1351 yynewmax = 0; /* failed */ 1352 } 1353 else /* not first time */ 1354 { 1355 yys = YYENLARGE(yys, int); 1356 yyv = YYENLARGE(yyv, YYSTYPE); 1357 if (yys == 0 || yyv == 0) 1358 yynewmax = 0; /* failed */ 1359 } 1360 #endif 1361 if (yynewmax <= yymaxdepth) /* tables not expanded */ 1362 { 1363 yyerror( "yacc stack overflow" ); 1364 YYABORT; 1365 } 1366 yymaxdepth = yynewmax; 1367 1368 yy_ps = yys + yyps_index; 1369 yy_pv = yyv + yypv_index; 1370 yypvt = yyv + yypvt_index; 1371 } 1372 *yy_ps = yy_state; 1373 *++yy_pv = yyval; 1374 1375 /* 1376 ** we have a new state - find out what to do 1377 */ 1378 yy_newstate: 1379 if ( ( yy_n = yypact[ yy_state ] ) <= YYFLAG ) 1380 goto yydefault; /* simple state */ 1381 #if YYDEBUG 1382 /* 1383 ** if debugging, need to mark whether new token grabbed 1384 */ 1385 yytmp = yychar < 0; 1386 #endif 1387 if ( ( yychar < 0 ) && ( ( yychar = YYLEX() ) < 0 ) ) 1388 yychar = 0; /* reached EOF */ 1389 #if YYDEBUG 1390 if ( yydebug && yytmp ) 1391 { 1392 register int yy_i; 1393 1394 printf( "Received token " ); 1395 if ( yychar == 0 ) 1396 printf( "end-of-file\n" ); 1397 else if ( yychar < 0 ) 1398 printf( "-none-\n" ); 1399 else 1400 { 1401 for ( yy_i = 0; yytoks[yy_i].t_val >= 0; 1402 yy_i++ ) 1403 { 1404 if ( yytoks[yy_i].t_val == yychar ) 1405 break; 1406 } 1407 printf( "%s\n", yytoks[yy_i].t_name ); 1408 } 1409 } 1410 #endif /* YYDEBUG */ 1411 if ( ( ( yy_n += yychar ) < 0 ) || ( yy_n >= YYLAST ) ) 1412 goto yydefault; 1413 if ( yychk[ yy_n = yyact[ yy_n ] ] == yychar ) /*valid shift*/ 1414 { 1415 yychar = -1; 1416 yyval = yylval; 1417 yy_state = yy_n; 1418 if ( yyerrflag > 0 ) 1419 yyerrflag--; 1420 goto yy_stack; 1421 } 1422 1423 yydefault: 1424 if ( ( yy_n = yydef[ yy_state ] ) == -2 ) 1425 { 1426 #if YYDEBUG 1427 yytmp = yychar < 0; 1428 #endif 1429 if ( ( yychar < 0 ) && ( ( yychar = YYLEX() ) < 0 ) ) 1430 yychar = 0; /* reached EOF */ 1431 #if YYDEBUG 1432 if ( yydebug && yytmp ) 1433 { 1434 register int yy_i; 1435 1436 printf( "Received token " ); 1437 if ( yychar == 0 ) 1438 printf( "end-of-file\n" ); 1439 else if ( yychar < 0 ) 1440 printf( "-none-\n" ); 1441 else 1442 { 1443 for ( yy_i = 0; 1444 yytoks[yy_i].t_val >= 0; 1445 yy_i++ ) 1446 { 1447 if ( yytoks[yy_i].t_val 1448 == yychar ) 1449 { 1450 break; 1451 } 1452 } 1453 printf( "%s\n", yytoks[yy_i].t_name ); 1454 } 1455 } 1456 #endif /* YYDEBUG */ 1457 /* 1458 ** look through exception table 1459 */ 1460 { 1461 register YYCONST int *yyxi = yyexca; 1462 1463 while ( ( *yyxi != -1 ) || 1464 ( yyxi[1] != yy_state ) ) 1465 { 1466 yyxi += 2; 1467 } 1468 while ( ( *(yyxi += 2) >= 0 ) && 1469 ( *yyxi != yychar ) ) 1470 ; 1471 if ( ( yy_n = yyxi[1] ) < 0 ) 1472 YYACCEPT; 1473 } 1474 } 1475 1476 /* 1477 ** check for syntax error 1478 */ 1479 if ( yy_n == 0 ) /* have an error */ 1480 { 1481 /* no worry about speed here! */ 1482 switch ( yyerrflag ) 1483 { 1484 case 0: /* new error */ 1485 yyerror( "syntax error" ); 1486 goto skip_init; 1487 yyerrlab: 1488 /* 1489 ** get globals into registers. 1490 ** we have a user generated syntax type error 1491 */ 1492 yy_pv = yypv; 1493 yy_ps = yyps; 1494 yy_state = yystate; 1495 skip_init: 1496 yynerrs++; 1497 /* FALLTHRU */ 1498 case 1: 1499 case 2: /* incompletely recovered error */ 1500 /* try again... */ 1501 yyerrflag = 3; 1502 /* 1503 ** find state where "error" is a legal 1504 ** shift action 1505 */ 1506 while ( yy_ps >= yys ) 1507 { 1508 yy_n = yypact[ *yy_ps ] + YYERRCODE; 1509 if ( yy_n >= 0 && yy_n < YYLAST && 1510 yychk[yyact[yy_n]] == YYERRCODE) { 1511 /* 1512 ** simulate shift of "error" 1513 */ 1514 yy_state = yyact[ yy_n ]; 1515 goto yy_stack; 1516 } 1517 /* 1518 ** current state has no shift on 1519 ** "error", pop stack 1520 */ 1521 #if YYDEBUG 1522 # define _POP_ "Error recovery pops state %d, uncovers state %d\n" 1523 if ( yydebug ) 1524 printf( _POP_, *yy_ps, 1525 yy_ps[-1] ); 1526 # undef _POP_ 1527 #endif 1528 yy_ps--; 1529 yy_pv--; 1530 } 1531 /* 1532 ** there is no state on stack with "error" as 1533 ** a valid shift. give up. 1534 */ 1535 YYABORT; 1536 case 3: /* no shift yet; eat a token */ 1537 #if YYDEBUG 1538 /* 1539 ** if debugging, look up token in list of 1540 ** pairs. 0 and negative shouldn't occur, 1541 ** but since timing doesn't matter when 1542 ** debugging, it doesn't hurt to leave the 1543 ** tests here. 1544 */ 1545 if ( yydebug ) 1546 { 1547 register int yy_i; 1548 1549 printf( "Error recovery discards " ); 1550 if ( yychar == 0 ) 1551 printf( "token end-of-file\n" ); 1552 else if ( yychar < 0 ) 1553 printf( "token -none-\n" ); 1554 else 1555 { 1556 for ( yy_i = 0; 1557 yytoks[yy_i].t_val >= 0; 1558 yy_i++ ) 1559 { 1560 if ( yytoks[yy_i].t_val 1561 == yychar ) 1562 { 1563 break; 1564 } 1565 } 1566 printf( "token %s\n", 1567 yytoks[yy_i].t_name ); 1568 } 1569 } 1570 #endif /* YYDEBUG */ 1571 if ( yychar == 0 ) /* reached EOF. quit */ 1572 YYABORT; 1573 yychar = -1; 1574 goto yy_newstate; 1575 } 1576 }/* end if ( yy_n == 0 ) */ 1577 /* 1578 ** reduction by production yy_n 1579 ** put stack tops, etc. so things right after switch 1580 */ 1581 #if YYDEBUG 1582 /* 1583 ** if debugging, print the string that is the user's 1584 ** specification of the reduction which is just about 1585 ** to be done. 1586 */ 1587 if ( yydebug ) 1588 printf( "Reduce by (%d) \"%s\"\n", 1589 yy_n, yyreds[ yy_n ] ); 1590 #endif 1591 yytmp = yy_n; /* value to switch over */ 1592 yypvt = yy_pv; /* $vars top of value stack */ 1593 /* 1594 ** Look in goto table for next state 1595 ** Sorry about using yy_state here as temporary 1596 ** register variable, but why not, if it works... 1597 ** If yyr2[ yy_n ] doesn't have the low order bit 1598 ** set, then there is no action to be done for 1599 ** this reduction. So, no saving & unsaving of 1600 ** registers done. The only difference between the 1601 ** code just after the if and the body of the if is 1602 ** the goto yy_stack in the body. This way the test 1603 ** can be made before the choice of what to do is needed. 1604 */ 1605 { 1606 /* length of production doubled with extra bit */ 1607 register int yy_len = yyr2[ yy_n ]; 1608 1609 if ( !( yy_len & 01 ) ) 1610 { 1611 yy_len >>= 1; 1612 yyval = ( yy_pv -= yy_len )[1]; /* $$ = $1 */ 1613 yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] + 1614 *( yy_ps -= yy_len ) + 1; 1615 if ( yy_state >= YYLAST || 1616 yychk[ yy_state = 1617 yyact[ yy_state ] ] != -yy_n ) 1618 { 1619 yy_state = yyact[ yypgo[ yy_n ] ]; 1620 } 1621 goto yy_stack; 1622 } 1623 yy_len >>= 1; 1624 yyval = ( yy_pv -= yy_len )[1]; /* $$ = $1 */ 1625 yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] + 1626 *( yy_ps -= yy_len ) + 1; 1627 if ( yy_state >= YYLAST || 1628 yychk[ yy_state = yyact[ yy_state ] ] != -yy_n ) 1629 { 1630 yy_state = yyact[ yypgo[ yy_n ] ]; 1631 } 1632 } 1633 /* save until reenter driver code */ 1634 yystate = yy_state; 1635 yyps = yy_ps; 1636 yypv = yy_pv; 1637 } 1638 /* 1639 ** code supplied by user is placed in this switch 1640 */ 1641 switch( yytmp ) 1642 { 1643 1644 case 3: 1645 # line 574 "loadkeys.y" 1646 { 1647 enter_mapentry(yypvt[-2].number, yypvt[-1].keyentry); 1648 } break; 1649 case 4: 1650 # line 578 "loadkeys.y" 1651 { 1652 duplicate_mapentry(yypvt[-4].number, yypvt[-1].number); 1653 } break; 1654 case 5: 1655 # line 582 "loadkeys.y" 1656 { 1657 swap_mapentry(yypvt[-3].number, yypvt[-1].number); 1658 } break; 1659 case 7: 1660 # line 590 "loadkeys.y" 1661 { 1662 /* 1663 * Append this entry to the end of the entry list. 1664 */ 1665 register keyentry *kep; 1666 kep = yypvt[-1].keyentry; 1667 for (;;) { 1668 if (kep->ke_next == NULL) { 1669 kep->ke_next = yypvt[-0].keyentry; 1670 break; 1671 } 1672 kep = kep->ke_next; 1673 } 1674 yyval.keyentry = yypvt[-1].keyentry; 1675 } break; 1676 case 8: 1677 # line 606 "loadkeys.y" 1678 { 1679 yyval.keyentry = yypvt[-0].keyentry; 1680 } break; 1681 case 9: 1682 # line 613 "loadkeys.y" 1683 { 1684 yyval.keyentry = makeentry(yypvt[-1].number, yypvt[-0].number); 1685 } break; 1686 case 10: 1687 # line 620 "loadkeys.y" 1688 { 1689 yyval.number = yypvt[-0].number; 1690 } break; 1691 case 11: 1692 # line 624 "loadkeys.y" 1693 { 1694 yyval.number = yypvt[-0].number; 1695 } break; 1696 case 12: 1697 # line 628 "loadkeys.y" 1698 { 1699 yyval.number = '('; 1700 } break; 1701 case 13: 1702 # line 632 "loadkeys.y" 1703 { 1704 yyval.number = ')'; 1705 } break; 1706 case 14: 1707 # line 636 "loadkeys.y" 1708 { 1709 yyval.number = '+'; 1710 } break; 1711 case 15: 1712 # line 640 "loadkeys.y" 1713 { 1714 yyval.number = yypvt[-0].number; 1715 } break; 1716 case 16: 1717 # line 647 "loadkeys.y" 1718 { 1719 yyval.number = yypvt[-0].number; 1720 } break; 1721 case 17: 1722 # line 651 "loadkeys.y" 1723 { 1724 yyval.number = yypvt[-2].number + yypvt[-0].number; 1725 } break; 1726 case 18: 1727 # line 658 "loadkeys.y" 1728 { 1729 yyval.number = yypvt[-0].number; 1730 } break; 1731 case 19: 1732 # line 662 "loadkeys.y" 1733 { 1734 if (yypvt[-1].number < 1 || yypvt[-1].number > 16) 1735 yyerror("invalid function key number"); 1736 yyval.number = yypvt[-3].number + yypvt[-1].number - 1; 1737 } break; 1738 case 20: 1739 # line 671 "loadkeys.y" 1740 { 1741 yyval.number = yypvt[-0].number; 1742 } break; 1743 case 21: 1744 # line 675 "loadkeys.y" 1745 { 1746 if (isdigit(yypvt[-0].number)) 1747 yyval.number = yypvt[-0].number - '0'; 1748 else 1749 yyerror("syntax error"); 1750 } break; 1751 # line 556 "/usr/share/lib/ccs/yaccpar" 1752 } 1753 goto yystack; /* reset registers in driver code */ 1754 } 1755 1756