%{

/*
    Terminal capabilities (termcap) parser
    Copyright (c) Tudor Hulubei & Andrei Pitis, April 1994

This file is part of UIT (UNIX Interactive Tools)

UIT is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 2, or (at your option) any later version.

UIT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
details .

You should have received a copy of the GNU General Public License along with
UIT; see the file COPYING.  If not, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA.  */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include "termcap.h"


void fatal(char *);

int  tty_found = 0;
char tty_type[64];
char termcap[TTY_MAXCAP][16];
char termcap_len[TTY_MAXCAP];


%}

%%

^[-a-zA-Z0-9_]+"|"		{
				    if (tty_found)
					return TTY_DESCRIPTION_END;
				    goto resume;
				}

[-a-zA-Z0-9_]+"|"		{
				    if (!tty_found)
				    {
				      resume:
       				        yytext[yyleng-1] = 0;
       				        if (strcmp(yytext, tty_type) == 0)
					    tty_found = 1;
				    }
				}

kl=[^:\n]+:			if (tty_found) return TTY_CURSOR_LEFT;
kr=[^:\n]+:			if (tty_found) return TTY_CURSOR_RIGHT;
ku=[^:\n]+:			if (tty_found) return TTY_CURSOR_UP;
kd=[^:\n]+:			if (tty_found) return TTY_CURSOR_DOWN;

kh=[^:\n]+:			if (tty_found) return TTY_HOME;
kH=[^:\n]+:			if (tty_found) return TTY_END;
kI=[^:\n]+:			if (tty_found) return TTY_INS;
kD=[^:\n]+:			if (tty_found) return TTY_DEL;
kP=[^:\n]+:			if (tty_found) return TTY_PGUP;
kN=[^:\n]+:			if (tty_found) return TTY_PGDN;

k1=[^:\n]+:			if (tty_found) return TTY_F1;
k2=[^:\n]+:			if (tty_found) return TTY_F2;
k3=[^:\n]+:			if (tty_found) return TTY_F3;
k4=[^:\n]+:			if (tty_found) return TTY_F4;
k5=[^:\n]+:			if (tty_found) return TTY_F5;
k6=[^:\n]+:			if (tty_found) return TTY_F6;
k7=[^:\n]+:			if (tty_found) return TTY_F7;
k8=[^:\n]+:			if (tty_found) return TTY_F8;
k9=[^:\n]+:			if (tty_found) return TTY_F9;
k0=[^:\n]+:			if (tty_found) return TTY_F10;

cm=[^:\n]+:			if (tty_found) return TTY_CURSOR_MOVE;

us=[^:\n]+:			if (tty_found) return TTY_UNDERLINE_ON;
ue=[^:\n]+:			if (tty_found) return TTY_UNDERLINE_OFF;

so=[^:\n]+: |
mr=[^:\n]+:			if (tty_found) return TTY_REVERSE_ON;
se=[^:\n]+:			if (tty_found) return TTY_REVERSE_OFF;

cl=[^:\n]+:			if (tty_found) return TTY_CLRSCR;

md=[^:\n]+:			if (tty_found) return TTY_BRIGHT_ON;
me=[^:\n]+:			if (tty_found) return TTY_BRIGHT_OFF;

tc=[-a-zA-Z0-9_]+:		{
				    if (tty_found)
				    {
					yytext[yyleng - 1] = 0;
					strcpy(tty_type, yytext + 3);
					tty_found = 0;
					fseek(yyin, 0, SEEK_SET);
				    }
				}

.|\n				{}

%%


/*
 * This function was originally written by Joseph H. Allen
 * (joe termcap.c)
 */

char escape(char **s)
{
    char c= *(*s)++;

    if(c=='^' && **s)
	if (**s != '?') return 037 & *(*s)++;
	else return (*s)++, 127;
    else
	if (c == '\\' && **s)
	    switch (c= *((*s)++))
	    {
		case '0': case '1': case '2': case '3':
		case '4': case '5': case '6': case '7':
			c-='0';
			if(**s >= '0' && **s <= '7') c = (c<<3)+*((*s)++)-'0';
			if(**s >= '0' && **s <= '7') c = (c<<3)+*((*s)++)-'0';
			return c;
		case 'e': case 'E': return 27;
		case 'n': case 'l': return 10;
		case 'r': return 13;
		case 't': return  9;
		case 'b': return  8;
		case 'f': return 12;
		case 's': return 32;
		default: return c;
	    }
	else return c;
}


int yywrap(void)
{
    return 1;
}


void termcap_init(void)
{
    int index, i;
    char *ptr, *temp, *term_type, *home, local_termcap[PATH_MAX];


    if ((home = getenv("HOME")))
    {
	strcpy(local_termcap, home);
	strcat(local_termcap, "/.uittermcap");
    }

    if ((yyin = fopen(local_termcap, "r")) == NULL)
        if ((yyin = fopen("/etc/termcap", "r")) == NULL)
	    fatal("neither $HOME/.uittermcap nor /etc/termcap can be opened !\n");

    term_type = getenv("TERM");

    if (term_type && term_type[0])
	strcpy(tty_type, term_type);
    else
    {
	fprintf(stderr, "TERM undefined. Trying vt100.\n");
	strcpy(tty_type, "vt100");
    }

    termcap[TTY_TAB][0] = 9;
    termcap[TTY_TAB][1] = 0;
    termcap_len[TTY_TAB] = 1;

    termcap[TTY_BACKSPACE][0] = 127;
    termcap[TTY_BACKSPACE][1] = 0;
    termcap_len[TTY_BACKSPACE] = 1;

    while ((index = yylex()))
    {
	yytext[yyleng - 1] = 0;
	temp = yytext + 3;
	while (isdigit(*temp)) temp++;
	ptr = termcap[index];
	while (*ptr++ = escape(&temp));
	termcap_len[index] = strlen(termcap[index]);
    }

    fclose(yyin);

    if (!tty_found)
    {
	fprintf(stderr, "Can't find terminal type %s. Stop.\n", tty_type);
	exit(1);
    }
}
