@.		{
		    (void) fprintf(stderr,
			"keybind: bad scan-code specifier, line %d, token %d\n",
			yylineno, yytokno);
			interactive--;
			while (input() != '\n')
			    continue;
			interactive++;
		    return(LEXERR);
		}

nul		{yylval = A_NUL; yytokno++; return(CHARKEY);}
soh		{yylval = A_SOH; yytokno++; return(CHARKEY);}
stx		{yylval = A_STX; yytokno++; return(CHARKEY);}
etx		{yylval = A_ETX; yytokno++; return(CHARKEY);}
eot		{yylval = A_EOT; yytokno++; return(CHARKEY);}
enq		{yylval = A_ENQ; yytokno++; return(CHARKEY);}
ack		{yylval = A_ACK; yytokno++; return(CHARKEY);}
bel		{yylval = A_BEL; yytokno++; return(CHARKEY);}
bs		{yylval = A_BS; yytokno++; return(CHARKEY);}
ht		{yylval = A_HT; yytokno++; return(CHARKEY);}
tab		{yylval = A_HT; yytokno++; return(CHARKEY);}
nl		{yylval = A_NL; yytokno++; return(CHARKEY);}
lf		{yylval = A_NL; yytokno++; return(CHARKEY);}
vt		{yylval = A_VT; yytokno++; return(CHARKEY);}
ff		{yylval = A_FF; yytokno++; return(CHARKEY);}
cr		{yylval = A_CR; yytokno++; return(CHARKEY);}
so		{yylval = A_SO; yytokno++; return(CHARKEY);}
si		{yylval = A_SI; yytokno++; return(CHARKEY);}
dle		{yylval = A_DLE; yytokno++; return(CHARKEY);}
dc1		{yylval = A_DC1; yytokno++; return(CHARKEY);}
xon		{yylval = A_DC1; yytokno++; return(CHARKEY);}
dc2		{yylval = A_DC2; yytokno++; return(CHARKEY);}
dc3		{yylval = A_DC3; yytokno++; return(CHARKEY);}
xoff		{yylval = A_DC3; yytokno++; return(CHARKEY);}
dc4		{yylval = A_DC4; yytokno++; return(CHARKEY);}
nak		{yylval = A_NAK; yytokno++; return(CHARKEY);}
syn		{yylval = A_SYN; yytokno++; return(CHARKEY);}
etb		{yylval = A_ETB; yytokno++; return(CHARKEY);}
can		{yylval = A_CAN; yytokno++; return(CHARKEY);}
em		{yylval = A_EM; yytokno++; return(CHARKEY);}
sub		{yylval = A_SUB; yytokno++; return(CHARKEY);}
esc		{yylval = A_ESC; yytokno++; return(CHARKEY);}
fs		{yylval = A_FS; yytokno++; return(CHARKEY);}
gs		{yylval = A_GS; yytokno++; return(CHARKEY);}
rs		{yylval = A_RS; yytokno++; return(CHARKEY);}
us		{yylval = A_US; yytokno++; return(CHARKEY);}
del		{yylval = A_DEL; yytokno++; return(CHARKEY);}
csi		{yylval = A_CSI; yytokno++; return(CHARKEY);}

nop		{yylval = K_NOP; yytokno++; return(SPECIAL);}
lshift		{yylval = K_LSH; yytokno++; return(SPECIAL);}
rshift		{yylval = K_RSH; yytokno++; return(SPECIAL);}
clock		{yylval = K_CLK; yytokno++; return(SPECIAL);}
nlock		{yylval = K_NLK; yytokno++; return(SPECIAL);}
slock		{yylval = K_SLK; yytokno++; return(SPECIAL);}
alt		{yylval = K_ALT; yytokno++; return(SPECIAL);}
btab		{yylval = K_BTAB; yytokno++; return(SPECIAL);}
ctrl		{yylval = K_CTL; yytokno++; return(SPECIAL);}
lalt		{yylval = K_LAL; yytokno++; return(SPECIAL);}
ralt		{yylval = K_RAL; yytokno++; return(SPECIAL);}
lctrl		{yylval = K_LCT; yytokno++; return(SPECIAL);}
rctrl		{yylval = K_RCT; yytokno++; return(SPECIAL);}

fkey[0-9][0-9]?	{yylval = K_FUNF+atoi(yytext+4)-1; yytokno++; return(FUNKEY);}

sysreq		{yylval = K_SRQ; yytokno++; return(SPECIAL);}
brk		{yylval = K_BRK; yytokno++; return(SPECIAL);}
escn		{yylval = K_ESN; yytokno++; return(SPECIAL);}
esco		{yylval = K_ESO; yytokno++; return(SPECIAL);}
escl		{yylval = K_ESL; yytokno++; return(SPECIAL);}
rboot		{yylval = K_RBT; yytokno++; return(SPECIAL);}
debug		{yylval = K_DBG; yytokno++; return(SPECIAL);}
next		{yylval = K_NEXT; yytokno++; return(SPECIAL);}
prev		{yylval = K_PREV; yytokno++; return(SPECIAL);}
fnext		{yylval = K_FRCNEXT; yytokno++; return(SPECIAL);}
fprev		{yylval = K_FRCPREV; yytokno++; return(SPECIAL);}

vt[0-9][0-9]?	{yylval = K_VTF+atoi(yytext+2); yytokno++; return(SPECIAL);}
vtf		{yylval = K_VTF; yytokno++; return(SPECIAL);}
vtl		{yylval = K_VTL; yytokno++; return(SPECIAL);}
mgr[0-9][0-9]?	{yylval = K_MGRF+atoi(yytext+3); yytokno++; return(SPECIAL);}
mgrf		{yylval = K_MGRF; yytokno++; return(SPECIAL);}
mgrl		{yylval = K_MGRL; yytokno++; return(SPECIAL);}
pfx[0-9][0-9]?	{yylval = K_PFXF+atoi(yytext+3); yytokno++; return(SPECIAL);}
pfxf		{yylval = K_PFXF; yytokno++; return(SPECIAL);}
pfxl		{yylval = K_PFXL; yytokno++; return(SPECIAL);}

"#"		{while (input() != '\n') continue; unput('\n');}

[\n;]		{yytokno = 0; return(NEWLINE);}
=		{yytokno++; return(ASSIGN);}
-		{yytokno++; return(DASH);}
[\ \t,]		;

"?"		{yytokno++; interactive++; return(HELP);}

.		{
		    (void) fprintf(stderr,
			    "keybind: bad char, line %d, after token %d = \"",
			     yylineno, yytokno);
		    dump_string(yytext);
		    (void) fputs("\"\n", stdout);
		    interactive--;
		    while (input() != '\n')
			continue;
		    interactive++;
		    return(LEXERR);
		}

%%
/*
 * klex2.l -- lexical analyzer for keymap editor program, part 2
 *
 *	@(#)klex2.l	1.3
 *
 * Copyright 1989 by Eric S. Raymond <esr@snark.thyrsus.com>, all rights
 * reserved.  You may use, modify or redistribute this code freely, but do not
 * delete this notice. Check with me before you make money with it.
 */

static int yywrap()
{
    if (interactive)
	(void) putchar('\n');
    interactive = 0;
    return(EOF);
}

void getstring(buf, term)
char	*buf, term;
{
    char *tp;
    int c, cval;

    smashcase = 0;
    buf[0] = '\0';
    for (tp = buf; (c = input()) != term && c != EOF; *tp++ = cval)
    {
	if (c == '\\')
	{
	    c = input();
	    if (strchr("0123456789xX", c))
	    {
		char *dp, *hex = "0123456789abcdef";
		int dcount = 0;

		if (c == 'x' || c == 'X')
		    while ((dp = strchr(hex, (c = input()))) && (dcount++ < 2))
			cval = (cval * 16) + (dp - hex);
		else if (c == '0')
		    while (strchr("01234567", (c = input())) && (dcount++ < 3))
			cval = (cval * 8) + (c - '0');
		else
		    while (strchr("0123456789", (c = input())) && (dcount++ < 3))
			cval = (cval * 10) + (c - '0');
		unput(c);
	    }
	    else		/* C-style character escapes */
	    {
		switch (c)
		{
		case '\\': cval = '\\'; break;
		case 'e': cval = '\033'; break;
		case 'n': cval = '\n'; break;
		case 't': cval = '\t'; break;
		case 'b': cval = '\b'; break;
		case 'r': cval = '\r'; break;
		case 'v': cval = '\v'; break;
		default: cval = c;
		}
	    }
	}
	else if (c == '^')	/* control-character syntax */
	    cval = (input() & 0x1f);
	else if (c == '!')	/* alt-character syntax */
	    cval = (input() | 0x80);
	else
	    cval = c;
    }
    *tp = '\0';
    smashcase = 1;
}

void dump_string(str)
char *str;
{
    register char *cp;

    for (cp = str; *cp; cp++)
	if (isprint(*cp))
	    (void) putchar(*cp);
	else if (*cp == '"')
	    (void) fputs("\\\"", stdout);
	else if (*cp == '\b')
	    (void) fputs("\\b", stdout);
	else if (*cp == '\033')
	    (void) fputs("\\e", stdout);
	else if (*cp == '\n')
	    (void) fputs("\\n", stdout);
	else if (*cp == '\r')
	    (void) fputs("\\r", stdout);
	else if (*cp == '\t')
	    (void) fputs("\\t", stdout);
	else if (*cp == '\v')
	    (void) fputs("\\v", stdout);
	else
	    (void) printf("\\x%02x", *cp);
}

#ifdef MAIN
int yylval;

main()
{
    int class;

    while ((class = yylex()) > 0)
    {
	if (class == NEWLINE)
	    (void) fputs("NEWLINE\n", stdout);
	else
	    (void) printf("text \"%s\", class %d, value %d\n",
						yytext, class, yylval);
	yylval = 0;
    }
}

#endif /* MAIN */

/* klex.l ends here */
