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