Print this page
    
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
    loader: pxe receive cleanup
    9475 libefi: Do not return only if ReceiveFilter
    installboot: should support efi system partition
    8931 boot1.efi: scan all display modes rather than
    loader: spinconsole updates
    loader: gfx experiment to try GOP Blt() function.
    sha1 build test
    loader: add sha1 hash calculation
    common/sha1: update for loader build
    loader: biosdisk rework
    uts: 32-bit kernel FB needs mapping in low memory
    uts: add diag-device
    uts: boot console mirror with diag-device
    uts: enable very early console on ttya
    kmdb: add diag-device as input/output device
    uts: test VGA memory exclusion from mapping
    uts: clear boot mapping and protect boot pages test
    uts: add dboot map debug printf
    uts: need to release FB pages in release_bootstrap()
    uts: add screenmap ioctl
    uts: update sys/queue.h
    loader: add illumos uts/common to include path
    loader: tem/gfx font cleanup
    loader: vbe checks
    uts: gfx_private set KD_TEXT when KD_RESETTEXT is
    uts: gfx 8-bit update
    loader: gfx 8-bit fix
    loader: always set media size from partition.
    uts: MB2 support for 32-bit kernel
    loader: x86 should have tem 80x25
    uts: x86 should have tem 80x25
    uts: font update
    loader: font update
    uts: tem attributes
    loader: tem.c comment added
    uts: use font module
    loader: add font module
    loader: build rules for new font setup
    uts: gfx_private update for new font structure
    uts: early boot update for new font structure
    uts: font update
    uts: font build rules update for new fonts
    uts: tem update to new font structure
    loader: module.c needs to include tem_impl.h
    uts: gfx_private 8x16 font rework
    uts: make font_lookup public
    loader: font rework
    uts: font rework
    9259 libefi: efi_alloc_and_read should check for PMBR
    uts: tem utf-8 support
    loader: implement tem utf-8 support
    loader: tem should be able to display UTF-8
    7784 uts: console input should support utf-8
    7796 uts: ldterm default to utf-8
    uts: do not reset serial console
    uts: set up colors even if tem is not console
    uts: add type for early boot properties
    uts: gfx_private experiment with drm and vga
    uts: gfx_private should use setmode drm callback.
    uts: identify FB types and set up gfx_private based
    loader: replace gop and vesa with framebuffer
    uts: boot needs simple tem to support mdb
    uts: boot_keyboard should emit esc sequences for
    uts: gfx_private FB showuld be written by line
    kmdb: set terminal window size
    uts: gfx_private needs to keep track of early boot FB
    pnglite: move pnglite to usr/src/common
    loader: gfx_fb
    ficl-sys: add gfx primitives
    loader: add illumos.png logo
    ficl: add fb-putimage
    loader: add png support
    loader: add alpha blending for gfx_fb
    loader: use term-drawrect for menu frame
    ficl: add simple gfx words
    uts: provide fb_info via fbgattr dev_specific array.
    uts: gfx_private add alpha blending
    uts: update sys/ascii.h
    uts: tem OSC support (incomplete)
    uts: implement env module support and use data from
    uts: tem get colors from early boot data
    loader: use crc32 from libstand (libz)
    loader: optimize for size
    loader: pass tem info to the environment
    loader: import tem for loader console
    loader: UEFI loader needs to set ISADIR based on
    loader: need UEFI32 support
    8918 loader.efi: add vesa edid support
    uts: tem_safe_pix_clear_prom_output() should only
    uts: tem_safe_pix_clear_entire_screen() should use
    uts: tem_safe_check_first_time() should query cursor
    uts: tem implement cls callback & visual_io v4
    uts: gfx_vgatext use block cursor for vgatext
    uts: gfx_private implement cls callback & visual_io
    uts: gfx_private bitmap framebuffer implementation
    uts: early start frame buffer console support
    uts: font functions should check the input char
    uts: font rendering should support 16/24/32bit depths
    uts: use smallest font as fallback default.
    uts: update terminal dimensions based on selected
    7834 uts: vgatext should use gfx_private
    uts: add spacing property to 8859-1.bdf
    terminfo: add underline for sun-color
    terminfo: sun-color has 16 colors
    uts: add font load callback type
    loader: do not repeat int13 calls with error 0x20 and
    8905 loader: add skein/edonr support
    8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Revert "NEX-16819 loader UEFI support"
This reverts commit ec06b9fc617b99234e538bf2e7e4d02a24993e0c.
Reverting due to failures in the zfs-tests and the sharefs-tests
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
    loader: pxe receive cleanup
    9475 libefi: Do not return only if ReceiveFilter
    installboot: should support efi system partition
    8931 boot1.efi: scan all display modes rather than
    loader: spinconsole updates
    loader: gfx experiment to try GOP Blt() function.
    sha1 build test
    loader: add sha1 hash calculation
    common/sha1: update for loader build
    loader: biosdisk rework
    uts: 32-bit kernel FB needs mapping in low memory
    uts: add diag-device
    uts: boot console mirror with diag-device
    uts: enable very early console on ttya
    kmdb: add diag-device as input/output device
    uts: test VGA memory exclusion from mapping
    uts: clear boot mapping and protect boot pages test
    uts: add dboot map debug printf
    uts: need to release FB pages in release_bootstrap()
    uts: add screenmap ioctl
    uts: update sys/queue.h
    loader: add illumos uts/common to include path
    loader: tem/gfx font cleanup
    loader: vbe checks
    uts: gfx_private set KD_TEXT when KD_RESETTEXT is
    uts: gfx 8-bit update
    loader: gfx 8-bit fix
    loader: always set media size from partition.
    uts: MB2 support for 32-bit kernel
    loader: x86 should have tem 80x25
    uts: x86 should have tem 80x25
    uts: font update
    loader: font update
    uts: tem attributes
    loader: tem.c comment added
    uts: use font module
    loader: add font module
    loader: build rules for new font setup
    uts: gfx_private update for new font structure
    uts: early boot update for new font structure
    uts: font update
    uts: font build rules update for new fonts
    uts: tem update to new font structure
    loader: module.c needs to include tem_impl.h
    uts: gfx_private 8x16 font rework
    uts: make font_lookup public
    loader: font rework
    uts: font rework
    libefi: efi_alloc_and_read should check for PMBR
    uts: tem utf-8 support
    loader: implement tem utf-8 support
    loader: tem should be able to display UTF-8
    7784 uts: console input should support utf-8
    7796 uts: ldterm default to utf-8
    uts: do not reset serial console
    uts: set up colors even if tem is not console
    uts: add type for early boot properties
    uts: gfx_private experiment with drm and vga
    uts: gfx_private should use setmode drm callback.
    uts: identify FB types and set up gfx_private based
    loader: replace gop and vesa with framebuffer
    uts: boot needs simple tem to support mdb
    uts: boot_keyboard should emit esc sequences for
    uts: gfx_private FB showuld be written by line
    kmdb: set terminal window size
    uts: gfx_private needs to keep track of early boot FB
    pnglite: move pnglite to usr/src/common
    loader: gfx_fb
    ficl-sys: add gfx primitives
    loader: add illumos.png logo
    ficl: add fb-putimage
    loader: add png support
    loader: add alpha blending for gfx_fb
    loader: use term-drawrect for menu frame
    ficl: add simple gfx words
    uts: provide fb_info via fbgattr dev_specific array.
    uts: gfx_private add alpha blending
    uts: update sys/ascii.h
    uts: tem OSC support (incomplete)
    uts: implement env module support and use data from
    uts: tem get colors from early boot data
    loader: use crc32 from libstand (libz)
    loader: optimize for size
    loader: pass tem info to the environment
    loader: import tem for loader console
    loader: UEFI loader needs to set ISADIR based on
    loader: need UEFI32 support
    8918 loader.efi: add vesa edid support
    uts: tem_safe_pix_clear_prom_output() should only
    uts: tem_safe_pix_clear_entire_screen() should use
    uts: tem_safe_check_first_time() should query cursor
    uts: tem implement cls callback & visual_io v4
    uts: gfx_vgatext use block cursor for vgatext
    uts: gfx_private implement cls callback & visual_io
    uts: gfx_private bitmap framebuffer implementation
    uts: early start frame buffer console support
    uts: font functions should check the input char
    uts: font rendering should support 16/24/32bit depths
    uts: use smallest font as fallback default.
    uts: update terminal dimensions based on selected
    7834 uts: vgatext should use gfx_private
    uts: add spacing property to 8859-1.bdf
    terminfo: add underline for sun-color
    terminfo: sun-color has 16 colors
    uts: add font load callback type
    loader: do not repeat int13 calls with error 0x20 and
    8905 loader: add skein/edonr support
    8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/loadkeys/loadkeys.y
          +++ new/usr/src/cmd/loadkeys/loadkeys.y
   1    1  %{
   2    2  /*
   3    3   * CDDL HEADER START
   4    4   *
   5    5   * The contents of this file are subject to the terms of the
   6    6   * Common Development and Distribution License, Version 1.0 only
   7    7   * (the "License").  You may not use this file except in compliance
   8    8   * with the License.
   9    9   *
  10   10   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  11   11   * or http://www.opensolaris.org/os/licensing.
  12   12   * See the License for the specific language governing permissions
  13   13   * and limitations under the License.
  
    | 
      ↓ open down ↓ | 
    13 lines elided | 
    
      ↑ open up ↑ | 
  
  14   14   *
  15   15   * When distributing Covered Code, include this CDDL HEADER in each
  16   16   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  17   17   * If applicable, add the following below this CDDL HEADER, with the
  18   18   * fields enclosed by brackets "[]" replaced with your own identifying
  19   19   * information: Portions Copyright [yyyy] [name of copyright owner]
  20   20   *
  21   21   * CDDL HEADER END
  22   22   */
  23   23  
  24      -#ifndef lint
  25      -#pragma ident   "%Z%%M% %I%     %E% SMI"
  26      -#endif
  27      -
  28   24  /*
  29   25   * Copyright (c) 1999 by Sun Microsystems, Inc.
  30   26   * All rights reserved.
  31   27   */
  32   28  
  33   29  #include <sys/param.h>
  34   30  #include <ctype.h>
  35   31  #include <stdio.h>
  36   32  #include <search.h>
  37   33  #include <string.h>
  38   34  #include <malloc.h>
  39   35  #include <fcntl.h>
  40   36  #include <stdlib.h>
  41   37  #include <errno.h>
  42   38  #include <unistd.h>
  43   39  #include <sys/kbd.h>
  44   40  #include <sys/kbio.h>
  45   41  
  46   42  #define ALL     -1      /* special symbol for all tables */
  47   43  
  48      -/*
  49      - * SunOS 4.x and Solaris 2.[1234] put Type 4 key tables into
  50      - * the keytables directory with no type qualification.
  51      - * If we're a SPARC, we might be using an NFS server that
  52      - * doesn't have the new type-qualified directories.
  53      - * (loadkeys wasn't used on non-SPARCs in 2.[1234].)
  54      - */
  55      -#ifdef  sparc
  56      -#define COMPATIBILITY_DIR
  57      -#endif
  58      -
  59   44  static char     keytable_dir[] = "/usr/share/lib/keytables/type_%d/";
  60      -#ifdef  COMPATIBILITY_DIR
  61      -static char     keytable_dir2[] = "/usr/share/lib/keytables/";
  62      -#endif
  63   45  static char     layout_prefix[] = "layout_";
  64   46  
  65   47  struct keyentry {
  66   48          struct keyentry *ke_next;
  67   49          struct kiockeymap ke_entry;
  68   50  };
  69   51  
  70   52  typedef struct keyentry keyentry;
  71   53  
  72   54  static keyentry *firstentry;
  73   55  static keyentry *lastentry;
  74   56  
  75   57  struct dupentry {
  76   58          struct dupentry *de_next;
  77   59          int     de_station;
  78   60          int     de_otherstation;
  79   61  };
  80   62  
  81   63  typedef struct dupentry dupentry;
  82   64  
  83   65  static dupentry *firstduplicate;
  84   66  static dupentry *lastduplicate;
  85   67  
  86   68  static dupentry *firstswap;
  87   69  static dupentry *lastswap;
  88   70  
  89   71  static char     *infilename;
  90   72  static FILE     *infile;
  91   73  static int      lineno;
  92   74  static int      begline;
  93   75  
  94   76  static char     *strings[16] = {
  95   77          "\033[H",               /* HOMEARROW */
  96   78          "\033[A",               /* UPARROW */
  97   79          "\033[B",               /* DOWNARROW */
  98   80          "\033[D",               /* LEFTARROW */
  99   81          "\033[C",               /* RIGHTARROW */
 100   82  };
 101   83  
 102   84  static int      nstrings = 5;   /* start out with 5 strings */
 103   85  
 104   86  typedef enum {
 105   87          SM_INVALID,     /* this shift mask is invalid for this keyboard */
 106   88          SM_NORMAL,      /* "normal", valid shift mask */
 107   89          SM_NUMLOCK,     /* "Num Lock" shift mask */
 108   90          SM_UP           /* "Up" shift mask */
 109   91  } smtype_t;
 110   92  
 111   93  typedef struct {
 112   94          int     sm_mask;
 113   95          smtype_t sm_type;
 114   96  } smentry_t;
 115   97  
 116   98  static  smentry_t shiftmasks[] = {
 117   99          { 0,            SM_NORMAL },
 118  100          { SHIFTMASK,    SM_NORMAL },
 119  101          { CAPSMASK,     SM_NORMAL },
 120  102          { CTRLMASK,     SM_NORMAL },
 121  103          { ALTGRAPHMASK, SM_NORMAL },
 122  104          { NUMLOCKMASK,  SM_NUMLOCK },
 123  105          { UPMASK,       SM_UP },
 124  106  };
  
    | 
      ↓ open down ↓ | 
    52 lines elided | 
    
      ↑ open up ↑ | 
  
 125  107  
 126  108  
 127  109  #define NSHIFTS (sizeof (shiftmasks) / sizeof (shiftmasks[0]))
 128  110  
 129  111  static void     enter_mapentry(int station, keyentry *entrylistp);
 130  112  static keyentry *makeentry(int tablemask, int entry);
 131  113  static int      loadkey(int kbdfd, keyentry *kep);
 132  114  static int      dupkey(int kbdfd, dupentry *dep, int shiftmask);
 133  115  static int      swapkey(int kbdfd, dupentry *dep, int shiftmask);
 134  116  static int      yylex();
      117 +extern int      yyparse(void);
 135  118  static int      readesc(FILE *stream, int delim, int single_char);
 136  119  static int      wordcmp(const void *w1, const void *w2);
 137  120  static int      yyerror(char *msg);
 138  121  static void     usage(void);
 139  122  static void     set_layout(char *arg);
 140  123  static FILE     *open_mapping_file(char *pathbuf, char *name,
 141  124                          boolean_t explicit_name, int type);
 142  125  
 143  126  int
 144      -main(argc, argv)
 145      -        int argc;
 146      -        char **argv;
      127 +main(int argc, char **argv)
 147  128  {
 148      -        register int kbdfd;
      129 +        int kbdfd;
 149  130          int type;
 150  131          int layout;
 151  132          /* maxint is 8 hex digits. */
 152  133          char layout_filename[sizeof(layout_prefix)+8];
 153  134          char pathbuf[MAXPATHLEN];
 154      -        register int shift;
      135 +        int shift;
 155  136          struct kiockeymap mapentry;
 156      -        register keyentry *kep;
 157      -        register dupentry *dep;
      137 +        keyentry *kep;
      138 +        dupentry *dep;
 158  139          boolean_t explicit_name;
 159  140  
 160  141          while(++argv, --argc) {
 161  142                  if(argv[0][0] != '-') break;
 162  143                  switch(argv[0][1]) {
 163  144                  case 'e':
 164  145                          /* -e obsolete, silently ignore */
 165  146                          break;
 166  147                  case 's':
 167  148                          if (argc != 2) {
 168  149                                  usage();
 169  150                                  /* NOTREACHED */
 170  151                          }
 171  152                          set_layout(argv[1]);
 172  153                          exit(0);
 173  154                  default:
 174  155                          usage();
 175  156                          /* NOTREACHED */
 176  157                  }
 177  158          }
 178  159  
 179  160          if (argc > 1) usage();
 180  161  
 181  162          if ((kbdfd = open("/dev/kbd", O_WRONLY)) < 0) {
 182  163                  /* perror("loadkeys: /dev/kbd"); */
 183  164                  return (1);
 184  165          }
 185  166  
 186  167          if (ioctl(kbdfd, KIOCTYPE, &type) < 0) {
 187  168                  /*
 188  169                   * There may not be a keyboard connected,
 189  170                   * return silently
 190  171                   */
 191  172                  return (1);
 192  173          }
 193  174  
 194  175          if (argc == 0) {
 195  176                  /* If no keyboard detected, exit silently. */
 196  177                  if (type == -1)
 197  178                          return (0);
 198  179  
 199  180                  if (ioctl(kbdfd, KIOCLAYOUT, &layout) < 0) {
 200  181                          perror("loadkeys: ioctl(KIOCLAYOUT)");
 201  182                          return (1);
 202  183                  }
 203  184  
 204  185                  (void) sprintf(layout_filename,
 205  186                                  "%s%.2x", layout_prefix, layout);
 206  187                  infilename = layout_filename;
 207  188                  explicit_name = B_FALSE;
 208  189          } else {
 209  190                  infilename = argv[0];
 210  191                  explicit_name = B_TRUE;
 211  192          }
 212  193  
 213  194          infile = open_mapping_file(pathbuf, infilename, explicit_name, type);
 214  195          if (infile == NULL) return (1);
 215  196  
 216  197          infilename = pathbuf;
 217  198  
 218  199          lineno = 0;
 219  200          begline = 1;
 220  201          yyparse();
 221  202          fclose(infile);
 222  203  
 223  204          /*
 224  205           * See which shift masks are valid for this keyboard.
 225  206           * We do that by trying to get the entry for keystation 0 and that
 226  207           * shift mask; if the "ioctl" fails, we assume it's because the shift
 227  208           * mask is invalid.
 228  209           */
 229  210          for (shift = 0; shift < NSHIFTS; shift++) {
 230  211                  mapentry.kio_tablemask =
 231  212                      shiftmasks[shift].sm_mask;
 232  213                  mapentry.kio_station = 0;
 233  214                  if (ioctl(kbdfd, KIOCGKEY, &mapentry) < 0)
 234  215                          shiftmasks[shift].sm_type = SM_INVALID;
 235  216          }
 236  217  
 237  218          for (kep = firstentry; kep != NULL; kep = kep->ke_next) {
 238  219                  if (kep->ke_entry.kio_tablemask == ALL) {
 239  220                          for (shift = 0; shift < NSHIFTS; shift++) {
 240  221                                  switch (shiftmasks[shift].sm_type) {
 241  222  
 242  223                                  case SM_INVALID:
 243  224                                          continue;
 244  225  
 245  226                                  case SM_NUMLOCK:
 246  227                                          /*
 247  228                                           * Defaults to NONL, not to a copy of
 248  229                                           * the base entry.
 249  230                                           */
 250  231                                          if (kep->ke_entry.kio_entry != HOLE)
 251  232                                                  kep->ke_entry.kio_entry = NONL;
 252  233                                          break;
 253  234  
 254  235                                  case SM_UP:
 255  236                                          /*
 256  237                                           * Defaults to NOP, not to a copy of
 257  238                                           * the base entry.
 258  239                                           */
 259  240                                          if (kep->ke_entry.kio_entry != HOLE)
 260  241                                                  kep->ke_entry.kio_entry = NOP;
 261  242                                          break;
 262  243                                  }
 263  244                                  kep->ke_entry.kio_tablemask =
 264  245                                      shiftmasks[shift].sm_mask;
 265  246                                  if (!loadkey(kbdfd, kep))
 266  247                                          return (1);
 267  248                          }
 268  249                  } else {
 269  250                          if (!loadkey(kbdfd, kep))
 270  251                                  return (1);
 271  252                  }
 272  253          }
 273  254  
 274  255          for (dep = firstswap; dep != NULL; dep = dep->de_next) {
 275  256                  for (shift = 0; shift < NSHIFTS; shift++) {
 276  257                          if (shiftmasks[shift].sm_type != SM_INVALID) {
 277  258                                  if (!swapkey(kbdfd, dep,
 278  259                                      shiftmasks[shift].sm_mask))
 279  260                                          return (0);
 280  261                          }
 281  262                  }
 282  263          }
 283  264  
 284  265          for (dep = firstduplicate; dep != NULL; dep = dep->de_next) {
 285  266                  for (shift = 0; shift < NSHIFTS; shift++) {
 286  267                          if (shiftmasks[shift].sm_type != SM_INVALID) {
 287  268                                  if (!dupkey(kbdfd, dep,
 288  269                                      shiftmasks[shift].sm_mask))
 289  270                                          return (0);
 290  271                          }
 291  272                  }
 292  273          }
 293  274  
 294  275          close(kbdfd);
 295  276          return (0);
 296  277  }
 297  278  
 298  279  static void
 299  280  usage()
 300  281  {
 301  282          (void) fprintf(stderr, "usage: loadkeys [ file ]\n");
 302  283          exit(1);
 303  284  }
 304  285  
 305  286  static void
 306  287  set_layout(char *arg)
 307  288  {
 308  289          int layout;
 309  290          int ret;
 310  291          int kbdfd;
 311  292  
 312  293          layout = (int) strtol(arg, &arg, 0);
 313  294          if (*arg != '\0') {
 314  295                  fprintf(stderr, "usage:  loadkeys -s layoutnumber\n");
 315  296                  exit(1);
 316  297          }
 317  298  
 318  299          if ((kbdfd = open("/dev/kbd", O_WRONLY)) < 0) {
 319  300                  perror("/dev/kbd");
 320  301                  exit(1);
 321  302          }
 322  303  
 323  304          ret = ioctl(kbdfd, KIOCSLAYOUT, layout);
 324  305          if (ret == -1) {
 325  306                  perror("KIOCSLAYOUT");
  
    | 
      ↓ open down ↓ | 
    158 lines elided | 
    
      ↑ open up ↑ | 
  
 326  307          }
 327  308  
 328  309          close(kbdfd);
 329  310  }
 330  311  
 331  312  /*
 332  313   * Attempt to find the specified mapping file.  Return a FILE * if found,
 333  314   * else print a message on stderr and return NULL.
 334  315   */
 335  316  FILE *
 336      -open_mapping_file(
 337      -        char *pathbuf,
 338      -        char *name,
 339      -        boolean_t explicit_name,
 340      -        int type
 341      -) {
      317 +open_mapping_file(char *pathbuf, char *name, boolean_t explicit_name, int type)
      318 +{
 342  319          /* If the user specified the name, try it "raw". */
 343  320          if (explicit_name) {
 344  321                  strcpy(pathbuf, name);
 345  322                  infile = fopen(pathbuf, "r");
 346  323                  if (infile) return (infile);
 347  324                  if (errno != ENOENT) goto fopen_fail;
 348  325          }
 349  326  
 350  327          /* Everything after this point applies only to relative names. */
 351  328          if (*name == '/') goto fopen_fail;
 352  329  
 353  330          /* Try the type-qualified directory name. */
 354  331          sprintf(pathbuf, keytable_dir, type);
 355  332          if ((int)(strlen(pathbuf) + strlen(name) + 1) >= MAXPATHLEN) {
 356  333                  (void) fprintf(stderr, "loadkeys: Name %s is too long\n",
 357  334                                  name);
 358  335                  return (NULL);
 359  336          }
 360  337          (void) strcat(pathbuf, name);
 361      -        infile = fopen(pathbuf, "r");
 362      -        if (infile) return (infile);
 363      -        if (errno != ENOENT) goto fopen_fail;
      338 +        if ((infile = fopen(pathbuf, "r")) != NULL)
      339 +                return (infile);
 364  340  
 365      -#ifdef  COMPATIBILITY_DIR
 366      -        /* If not, and either the name was specified explicitly */
 367      -        /*     or this is a type 4... */
 368      -        if (explicit_name || type == KB_SUN4) {
 369      -                /* Try the compatibility name. */
 370      -                /* No need to check len here, it's shorter. */
 371      -                (void) strcpy(pathbuf, keytable_dir2);
 372      -                (void) strcat(pathbuf, infilename);
 373      -                infile = fopen(pathbuf, "r");
 374      -                if (infile) return (infile);
 375      -                if (errno != ENOENT) goto fopen_fail;
 376      -        }
 377      -#endif
 378      -
 379  341  fopen_fail:
 380  342          (void) fprintf(stderr, "loadkeys: ");
 381  343          perror(name);
 382  344          return (NULL);
 383  345  }
 384  346  
 385  347  /*
 386  348   * We have a list of entries for a given keystation, and the keystation number
 387  349   * for that keystation; put that keystation number into all the entries in that
 388  350   * list, and chain that list to the end of the main list of entries.
 389  351   */
 390  352  static void
 391  353  enter_mapentry(station, entrylistp)
 392  354          int station;
 393  355          keyentry *entrylistp;
 394  356  {
 395  357          register keyentry *kep;
 396  358  
 397  359          if (lastentry == NULL)
 398  360                  firstentry = entrylistp;
 399  361          else
 400  362                  lastentry->ke_next = entrylistp;
 401  363          kep = entrylistp;
 402  364          for (;;) {
 403  365                  kep->ke_entry.kio_station = (u_char)station;
 404  366                  if (kep->ke_next == NULL) {
 405  367                          lastentry = kep;
 406  368                          break;
 407  369                  }
 408  370                  kep = kep->ke_next;
 409  371          }
 410  372  }
 411  373  
 412  374  /*
 413  375   * Allocate and fill in a new entry.
 414  376   */
 415  377  static keyentry *
 416  378  makeentry(tablemask, entry)
 417  379          int tablemask;
  
    | 
      ↓ open down ↓ | 
    29 lines elided | 
    
      ↑ open up ↑ | 
  
 418  380          int entry;
 419  381  {
 420  382          register keyentry *kep;
 421  383          register int index;
 422  384  
 423  385          if ((kep = (keyentry *) malloc((unsigned)sizeof (keyentry))) == NULL)
 424  386                  yyerror("out of memory for entries");
 425  387          kep->ke_next = NULL;
 426  388          kep->ke_entry.kio_tablemask = tablemask;
 427  389          kep->ke_entry.kio_station = 0;
 428      -        kep->ke_entry.kio_entry = (u_short)entry;
      390 +        kep->ke_entry.kio_entry = entry;
 429  391          index = entry - STRING;
 430  392          if (index >= 0 && index <= 15)
 431  393                  (void) strncpy(kep->ke_entry.kio_string, strings[index],
 432  394                      KTAB_STRLEN);
 433  395          return (kep);
 434  396  }
 435  397  
 436  398  /*
 437  399   * Make a set of entries for a keystation that indicate that that keystation's
 438  400   * settings should be copied from another keystation's settings.
 439  401   */
 440  402  static void
 441  403  duplicate_mapentry(station, otherstation)
 442  404          int station;
 443  405          int otherstation;
 444  406  {
 445  407          register dupentry *dep;
 446  408  
 447  409          if ((dep = (dupentry *) malloc((unsigned)sizeof (dupentry))) == NULL)
 448  410                  yyerror("out of memory for entries");
 449  411  
 450  412          if (lastduplicate == NULL)
 451  413                  firstduplicate = dep;
 452  414          else
 453  415                  lastduplicate->de_next = dep;
 454  416          lastduplicate = dep;
 455  417          dep->de_next = NULL;
 456  418          dep->de_station = station;
 457  419          dep->de_otherstation = otherstation;
 458  420  }
 459  421  
 460  422  /*
 461  423   * Make a set of entries for a keystation that indicate that that keystation's
 462  424   * settings should be swapped with another keystation's settings.
 463  425   */
 464  426  static void
 465  427  swap_mapentry(station, otherstation)
 466  428          int station;
 467  429          int otherstation;
 468  430  {
 469  431          register dupentry *dep;
 470  432  
 471  433          if ((dep = (dupentry *) malloc((unsigned)sizeof (dupentry))) == NULL)
 472  434                  yyerror("out of memory for entries");
 473  435  
 474  436          if (lastswap == NULL)
 475  437                  firstswap = dep;
 476  438          else
 477  439                  lastswap->de_next = dep;
 478  440          lastswap = dep;
 479  441          dep->de_next = NULL;
 480  442          dep->de_station = station;
 481  443          dep->de_otherstation = otherstation;
 482  444  }
 483  445  
 484  446  static int
 485  447  loadkey(kbdfd, kep)
 486  448          int kbdfd;
 487  449          register keyentry *kep;
 488  450  {
 489  451          if (ioctl(kbdfd, KIOCSKEY, &kep->ke_entry) < 0) {
 490  452                  perror("loadkeys: ioctl(KIOCSKEY)");
 491  453                  return (0);
 492  454          }
 493  455          return (1);
 494  456  }
 495  457  
 496  458  static int
 497  459  dupkey(kbdfd, dep, shiftmask)
 498  460          int kbdfd;
 499  461          register dupentry *dep;
 500  462          int shiftmask;
 501  463  {
 502  464          struct kiockeymap entry;
 503  465  
 504  466          entry.kio_tablemask = shiftmask;
 505  467          entry.kio_station = dep->de_otherstation;
 506  468          if (ioctl(kbdfd, KIOCGKEY, &entry) < 0) {
 507  469                  perror("loadkeys: ioctl(KIOCGKEY)");
 508  470                  return (0);
 509  471          }
 510  472          entry.kio_station = dep->de_station;
 511  473          if (ioctl(kbdfd, KIOCSKEY, &entry) < 0) {
 512  474                  perror("loadkeys: ioctl(KIOCSKEY)");
 513  475                  return (0);
 514  476          }
 515  477          return (1);
 516  478  }
 517  479  
 518  480  
 519  481  
 520  482  static int
 521  483  swapkey(kbdfd, dep, shiftmask)
 522  484          int kbdfd;
 523  485          register dupentry *dep;
 524  486          int shiftmask;
 525  487  {
 526  488          struct kiockeymap entry1, entry2;
 527  489  
 528  490          entry1.kio_tablemask = shiftmask;
 529  491          entry1.kio_station = dep->de_station;
 530  492          if (ioctl(kbdfd, KIOCGKEY, &entry1) < 0) {
 531  493                  perror("loadkeys: ioctl(KIOCGKEY)");
 532  494                  return (0);
 533  495          }
 534  496          entry2.kio_tablemask = shiftmask;
 535  497          entry2.kio_station = dep->de_otherstation;
 536  498          if (ioctl(kbdfd, KIOCGKEY, &entry2) < 0) {
 537  499                  perror("loadkeys: ioctl(KIOCGKEY)");
 538  500                  return (0);
 539  501          }
 540  502          entry1.kio_station = dep->de_otherstation;
 541  503          if (ioctl(kbdfd, KIOCSKEY, &entry1) < 0) {
 542  504                  perror("loadkeys: ioctl(KIOCSKEY)");
 543  505                  return (0);
 544  506          }
 545  507          entry2.kio_station = dep->de_station;
 546  508          if (ioctl(kbdfd, KIOCSKEY, &entry2) < 0) {
 547  509                  perror("loadkeys: ioctl(KIOCSKEY)");
 548  510                  return (0);
 549  511          }
 550  512          return (1);
 551  513  }
 552  514  %}
 553  515  
 554  516  %term TABLENAME INT CHAR CHARSTRING CONSTANT FKEY KEY SAME AS SWAP WITH
 555  517  
 556  518  %union {
 557  519          keyentry *keyentry;
 558  520          int     number;
 559  521  };
 560  522  
 561  523  %type <keyentry>        entrylist entry
 562  524  %type <number>          CHARSTRING CHAR INT CONSTANT FKEY TABLENAME
 563  525  %type <number>          code expr term number
 564  526  
 565  527  %%
 566  528  
 567  529  table:
 568  530          table line
 569  531  |       /* null */
 570  532  ;
 571  533  
 572  534  line:
 573  535          KEY number entrylist '\n'
 574  536                  {
 575  537                  enter_mapentry($2, $3);
 576  538                  }
 577  539  |       KEY number SAME AS number '\n'
 578  540                  {
 579  541                  duplicate_mapentry($2, $5);
 580  542                  }
 581  543  |       SWAP number WITH number '\n'
 582  544                  {
 583  545                  swap_mapentry($2, $4);
 584  546                  }
 585  547  |       '\n'
 586  548  ;
 587  549  
 588  550  entrylist:
 589  551          entrylist entry
 590  552                  {
 591  553                  /*
 592  554                   * Append this entry to the end of the entry list.
 593  555                   */
 594  556                  register keyentry *kep;
 595  557                  kep = $1;
 596  558                  for (;;) {
 597  559                          if (kep->ke_next == NULL) {
 598  560                                  kep->ke_next = $2;
 599  561                                  break;
 600  562                          }
 601  563                          kep = kep->ke_next;
 602  564                  }
 603  565                  $$ = $1;
 604  566                  }
 605  567  |       entry
 606  568                  {
 607  569                  $$ = $1;
 608  570                  }
 609  571  ;
 610  572  
 611  573  entry:
 612  574          TABLENAME code
 613  575                  {
 614  576                  $$ = makeentry($1, $2);
 615  577                  }
 616  578  ;
  
    | 
      ↓ open down ↓ | 
    178 lines elided | 
    
      ↑ open up ↑ | 
  
 617  579  
 618  580  code:
 619  581          CHARSTRING
 620  582                  {
 621  583                  $$ = $1;
 622  584                  }
 623  585  |       CHAR
 624  586                  {
 625  587                  $$ = $1;
 626  588                  }
      589 +|       INT
      590 +                {
      591 +                $$ = $1;
      592 +                }
 627  593  |       '('
 628  594                  {
 629  595                  $$ = '(';
 630  596                  }
 631  597  |       ')'
 632  598                  {
 633  599                  $$ = ')';
 634  600                  }
 635  601  |       '+'
 636  602                  {
 637  603                  $$ = '+';
 638  604                  }
 639  605  |       expr
 640  606                  {
 641  607                  $$ = $1;
 642  608                  }
 643  609  ;
 644  610  
 645  611  expr:
 646  612          term
 647  613                  {
 648  614                  $$ = $1;
 649  615                  }
 650  616  |       expr '+' term
 651  617                  {
 652  618                  $$ = $1 + $3;
 653  619                  }
 654  620  ;
 655  621  
 656  622  term:
 657  623          CONSTANT
 658  624                  {
 659  625                  $$ = $1;
 660  626                  }
 661  627  |       FKEY '(' number ')'
 662  628                  {
 663  629                  if ($3 < 1 || $3 > 16)
 664  630                          yyerror("invalid function key number");
 665  631                  $$ = $1 + $3 - 1;
 666  632                  }
 667  633  ;
 668  634  
 669  635  number:
 670  636          INT
 671  637                  {
 672  638                  $$ = $1;
 673  639                  }
 674  640  |       CHAR
 675  641                  {
 676  642                  if (isdigit($1))
 677  643                          $$ = $1 - '0';
 678  644                  else
 679  645                          yyerror("syntax error");
 680  646                  }
 681  647  ;
 682  648  
 683  649  %%
 684  650  
 685  651  typedef struct {
 686  652          char    *w_string;
 687  653          int     w_type;         /* token type */
 688  654          int     w_lval;         /* yylval for this token */
 689  655  } word_t;
 690  656  
 691  657  /*
 692  658   * Table must be in alphabetical order.
 693  659   */
 694  660  word_t  wordtab[] = {
 695  661          { "all",        TABLENAME,      ALL },
 696  662          { "alt",        CONSTANT,       ALT },
 697  663          { "altg",       TABLENAME,      ALTGRAPHMASK },
 698  664          { "altgraph",   CONSTANT,       ALTGRAPH },
 699  665          { "as",         AS,             0 },
  
    | 
      ↓ open down ↓ | 
    63 lines elided | 
    
      ↑ open up ↑ | 
  
 700  666          { "base",       TABLENAME,      0 },
 701  667          { "bf",         FKEY,           BOTTOMFUNC },
 702  668          { "buckybits",  CONSTANT,       BUCKYBITS },
 703  669          { "caps",       TABLENAME,      CAPSMASK },
 704  670          { "capslock",   CONSTANT,       CAPSLOCK },
 705  671          { "compose",    CONSTANT,       COMPOSE },
 706  672          { "ctrl",       TABLENAME,      CTRLMASK },
 707  673          { "downarrow",  CONSTANT,       DOWNARROW },
 708  674          { "error",      CONSTANT,       ERROR },
 709  675          { "fa_acute",   CONSTANT,       FA_ACUTE },
      676 +        { "fa_apostrophe", CONSTANT,    FA_APOSTROPHE },
      677 +        { "fa_breve",   CONSTANT,       FA_BREVE },
      678 +        { "fa_caron",   CONSTANT,       FA_CARON },
 710  679          { "fa_cedilla", CONSTANT,       FA_CEDILLA },
 711  680          { "fa_cflex",   CONSTANT,       FA_CFLEX },
      681 +        { "fa_dacute",  CONSTANT,       FA_DACUTE },
      682 +        { "fa_dot",     CONSTANT,       FA_DOT },
 712  683          { "fa_grave",   CONSTANT,       FA_GRAVE },
      684 +        { "fa_macron",  CONSTANT,       FA_MACRON },
      685 +        { "fa_ogonek",  CONSTANT,       FA_OGONEK },
      686 +        { "fa_ring",    CONSTANT,       FA_RING },
      687 +        { "fa_slash",   CONSTANT,       FA_SLASH },
 713  688          { "fa_tilde",   CONSTANT,       FA_TILDE },
 714  689          { "fa_umlaut",  CONSTANT,       FA_UMLAUT },
 715  690          { "hole",       CONSTANT,       HOLE },
 716  691          { "homearrow",  CONSTANT,       HOMEARROW },
 717  692          { "idle",       CONSTANT,       IDLE },
 718  693          { "key",        KEY,            0 },
 719  694          { "leftarrow",  CONSTANT,       LEFTARROW },
 720  695          { "leftctrl",   CONSTANT,       LEFTCTRL },
 721  696          { "leftshift",  CONSTANT,       LEFTSHIFT },
 722  697          { "lf",         FKEY,           LEFTFUNC },
 723  698          { "metabit",    CONSTANT,       METABIT },
 724  699          { "nonl",       CONSTANT,       NONL },
 725  700          { "nop",        CONSTANT,       NOP },
 726  701          { "numl",       TABLENAME,      NUMLOCKMASK },
 727  702          { "numlock",    CONSTANT,       NUMLOCK },
 728  703          { "oops",       CONSTANT,       OOPS },
 729  704          { "pad0",       CONSTANT,       PAD0 },
 730  705          { "pad1",       CONSTANT,       PAD1 },
 731  706          { "pad2",       CONSTANT,       PAD2 },
 732  707          { "pad3",       CONSTANT,       PAD3 },
 733  708          { "pad4",       CONSTANT,       PAD4 },
 734  709          { "pad5",       CONSTANT,       PAD5 },
 735  710          { "pad6",       CONSTANT,       PAD6 },
 736  711          { "pad7",       CONSTANT,       PAD7 },
 737  712          { "pad8",       CONSTANT,       PAD8 },
 738  713          { "pad9",       CONSTANT,       PAD9 },
 739  714          { "paddot",     CONSTANT,       PADDOT },
 740  715          { "padenter",   CONSTANT,       PADENTER },
 741  716          { "padequal",   CONSTANT,       PADEQUAL },
 742  717          { "padminus",   CONSTANT,       PADMINUS },
 743  718          { "padplus",    CONSTANT,       PADPLUS },
 744  719          { "padsep",     CONSTANT,       PADSEP },
 745  720          { "padslash",   CONSTANT,       PADSLASH },
 746  721          { "padstar",    CONSTANT,       PADSTAR },
 747  722          { "reset",      CONSTANT,       RESET },
 748  723          { "rf",         FKEY,           RIGHTFUNC },
 749  724          { "rightarrow", CONSTANT,       RIGHTARROW },
 750  725          { "rightctrl",  CONSTANT,       RIGHTCTRL },
 751  726          { "rightshift", CONSTANT,       RIGHTSHIFT },
 752  727          { "same",       SAME,           0 },
 753  728          { "shift",      TABLENAME,      SHIFTMASK },
 754  729          { "shiftkeys",  CONSTANT,       SHIFTKEYS },
 755  730          { "shiftlock",  CONSTANT,       SHIFTLOCK },
 756  731          { "string",     CONSTANT,       STRING },
 757  732          { "swap",       SWAP,           0 },
 758  733          { "systembit",  CONSTANT,       SYSTEMBIT },
 759  734          { "tf",         FKEY,           TOPFUNC },
 760  735          { "up",         TABLENAME,      UPMASK },
 761  736          { "uparrow",    CONSTANT,       UPARROW },
 762  737          { "with",       WITH,           0 },
 763  738  };
 764  739  
 765  740  #define NWORDS          (sizeof (wordtab) / sizeof (wordtab[0]))
 766  741  
 767  742  static int
 768  743  yylex()
 769  744  {
 770  745          register int c;
 771  746          char tokbuf[256+1];
 772  747          register char *cp;
 773  748          register int tokentype;
 774  749  
 775  750          while ((c = getc(infile)) == ' ' || c == '\t')
 776  751                  ;
 777  752          if (begline) {
 778  753                  lineno++;
 779  754                  begline = 0;
 780  755                  if (c == '#') {
 781  756                          while ((c = getc(infile)) != EOF && c != '\n')
 782  757                                  ;
 783  758                  }
 784  759          }
 785  760          if (c == EOF)
 786  761                  return (0);     /* end marker */
 787  762          if (c == '\n') {
 788  763                  begline = 1;
 789  764                  return (c);
 790  765          }
 791  766  
 792  767          switch (c) {
 793  768  
 794  769          case '\'':
 795  770                  tokentype = CHAR;
 796  771                  if ((c = getc(infile)) == EOF)
 797  772                          yyerror("unterminated character constant");
 798  773                  if (c == '\n') {
 799  774                          (void) ungetc(c, infile);
 800  775                          yylval.number = '\'';
 801  776                  } else {
 802  777                          switch (c) {
 803  778  
 804  779                          case '\'':
 805  780                                  yyerror("null character constant");
 806  781                                  break;
 807  782  
 808  783                          case '\\':
 809  784                                  yylval.number = readesc(infile, '\'', 1);
 810  785                                  break;
 811  786  
 812  787                          default:
 813  788                                  yylval.number = c;
 814  789                                  break;
 815  790                          }
 816  791                          if ((c = getc(infile)) == EOF || c == '\n')
 817  792                                  yyerror("unterminated character constant");
 818  793                          else if (c != '\'')
 819  794                                  yyerror("only one character allowed in character constant");
 820  795                  }
 821  796                  break;
 822  797  
 823  798          case '"':
 824  799                  if ((c = getc(infile)) == EOF)
 825  800                          yyerror("unterminated string constant");
 826  801                  if (c == '\n') {
 827  802                          (void) ungetc(c, infile);
 828  803                          tokentype = CHAR;
 829  804                          yylval.number = '"';
 830  805                  } else {
 831  806                          tokentype = CHARSTRING;
 832  807                          cp = &tokbuf[0];
 833  808                          do {
 834  809                                  if (cp > &tokbuf[256])
 835  810                                          yyerror("line too long");
 836  811                                  if (c == '\\')
 837  812                                          c = readesc(infile, '"', 0);
 838  813                                  *cp++ = (char)c;
 839  814                          } while ((c = getc(infile)) != EOF && c != '\n' &&
 840  815                                  c != '"');
 841  816                          if (c != '"')
 842  817                                  yyerror("unterminated string constant");
 843  818                          *cp = '\0';
 844  819                          if (nstrings == 16)
 845  820                                  yyerror("too many strings");
 846  821                          if ((int) strlen(tokbuf) > KTAB_STRLEN)
 847  822                                  yyerror("string too long");
 848  823                          strings[nstrings] = strdup(tokbuf);
 849  824                          yylval.number = STRING+nstrings;
 850  825                          nstrings++;
 851  826                  }
 852  827                  break;
 853  828  
 854  829          case '(':
 855  830          case ')':
 856  831          case '+':
 857  832                  tokentype = c;
 858  833                  break;
 859  834  
 860  835          case '^':
 861  836                  if ((c = getc(infile)) == EOF)
 862  837                          yyerror("missing newline at end of line");
 863  838                  tokentype = CHAR;
 864  839                  if (c == ' ' || c == '\t' || c == '\n') {
 865  840                          /*
 866  841                           * '^' by itself.
 867  842                           */
 868  843                          yylval.number = '^';
 869  844                  } else {
 870  845                          yylval.number = c & 037;
 871  846                          if ((c = getc(infile)) == EOF)
 872  847                                  yyerror("missing newline at end of line");
 873  848                          if (c != ' ' && c != '\t' && c != '\n')
 874  849                                  yyerror("invalid control character");
 875  850                  }
 876  851                  (void) ungetc(c, infile);
 877  852                  break;
 878  853  
 879  854          default:
 880  855                  cp = &tokbuf[0];
 881  856                  do {
 882  857                          if (cp > &tokbuf[256])
 883  858                                  yyerror("line too long");
 884  859                          *cp++ = (char)c;
 885  860                  } while ((c = getc(infile)) != EOF && (isalnum(c) || c == '_'));
 886  861                  if (c == EOF)
 887  862                          yyerror("newline missing");
 888  863                  (void) ungetc(c, infile);
 889  864                  *cp = '\0';
 890  865                  if (strlen(tokbuf) == 1) {
 891  866                          tokentype = CHAR;
 892  867                          yylval.number = (unsigned char)tokbuf[0];
 893  868                  } else if (strlen(tokbuf) == 2 && tokbuf[0] == '^') {
 894  869                          tokentype = CHAR;
 895  870                          yylval.number = (unsigned char)(tokbuf[1] & 037);
 896  871                  } else {
 897  872                          word_t word;
 898  873                          register word_t *wptr;
 899  874                          char *ptr;
 900  875  
 901  876                          for (cp = &tokbuf[0]; (c = *cp) != '\0'; cp++) {
 902  877                                  if (isupper(c))
  
    | 
      ↓ open down ↓ | 
    180 lines elided | 
    
      ↑ open up ↑ | 
  
 903  878                                          *cp = tolower(c);
 904  879                          }
 905  880                          word.w_string = tokbuf;
 906  881                          wptr = (word_t *)bsearch((char *)&word,
 907  882                              (char *)wordtab, NWORDS, sizeof (word_t),
 908  883                              wordcmp);
 909  884                          if (wptr != NULL) {
 910  885                                  yylval.number = wptr->w_lval;
 911  886                                  tokentype = wptr->w_type;
 912  887                          } else {
 913      -                                yylval.number = strtol(tokbuf, &ptr, 10);
      888 +                                yylval.number = strtol(tokbuf, &ptr, 0);
 914  889                                  if (ptr == tokbuf)
 915  890                                          yyerror("syntax error");
 916  891                                  else
 917  892                                          tokentype = INT;
 918  893                          }
 919  894                          break;
 920  895                  }
 921  896          }
 922  897  
 923  898          return (tokentype);
 924  899  }
 925  900  
 926  901  static int
 927  902  readesc(stream, delim, single_char)
 928  903          FILE *stream;
 929  904          int delim;
 930  905          int single_char;
 931  906  {
 932  907          register int c;
 933  908          register int val;
 934  909          register int i;
 935  910  
 936  911          if ((c = getc(stream)) == EOF || c == '\n')
 937  912                  yyerror("unterminated character constant");
 938  913  
 939  914          if (c >= '0' && c <= '7') {
 940  915                  val = 0;
 941  916                  i = 1;
 942  917                  for (;;) {
 943  918                          val = val*8 + c - '0';
 944  919                          if ((c = getc(stream)) == EOF || c == '\n')
 945  920                                  yyerror("unterminated character constant");
 946  921                          if (c == delim)
 947  922                                  break;
 948  923                          i++;
 949  924                          if (i > 3) {
 950  925                                  if (single_char)
 951  926                                          yyerror("escape sequence too long");
 952  927                                  else
 953  928                                          break;
 954  929                          }
 955  930                          if (c < '0' || c > '7') {
 956  931                                  if (single_char)
 957  932                                          yyerror("illegal character in escape sequence");
 958  933                                  else
 959  934                                          break;
 960  935                          }
 961  936                  }
 962  937                  (void) ungetc(c, stream);
 963  938          } else {
 964  939                  switch (c) {
 965  940  
 966  941                  case 'n':
 967  942                          val = '\n';
 968  943                          break;
 969  944  
 970  945                  case 't':
 971  946                          val = '\t';
 972  947                          break;
 973  948  
 974  949                  case 'b':
 975  950                          val = '\b';
 976  951                          break;
 977  952  
 978  953                  case 'r':
 979  954                          val = '\r';
 980  955                          break;
 981  956  
 982  957                  case 'v':
 983  958                          val = '\v';
 984  959                          break;
 985  960  
 986  961                  case '\\':
 987  962                          val = '\\';
 988  963                          break;
 989  964  
 990  965                  default:
 991  966                          if (c == delim)
 992  967                                  val = delim;
 993  968                          else
 994  969                                  yyerror("illegal character in escape sequence");
 995  970                  }
 996  971          }
 997  972          return (val);
 998  973  }
 999  974  
1000  975  static int
1001  976  wordcmp(const void *w1, const void *w2)
1002  977  {
1003  978          return (strcmp(
1004  979                  ((const word_t *)w1)->w_string,
1005  980                  ((const word_t *)w2)->w_string));
1006  981  }
1007  982  
1008  983  static int
1009  984  yyerror(msg)
1010  985          char *msg;
1011  986  {
1012  987          (void) fprintf(stderr, "%s, line %d: %s\n", infilename, lineno, msg);
1013  988          exit(1);
1014  989  }
  
    | 
      ↓ open down ↓ | 
    91 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX