home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Der Mediaplex Sampler - Die 6 von Plex
/
6_v_plex.zip
/
6_v_plex
/
DISK5
/
DOS_50
/
PVIC.ZIP
/
TERMCAP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-21
|
16KB
|
604 lines
#include <stdio.h>
#include "pvic.h"
#include "locdefs.h"
#define TERMCAP_ENTRY_SIZE 1024
/* Items read from the termcap file. */
int termcap_lines=DEFAULT_TERMCAP_LINES;
int termcap_columns=DEFAULT_TERMCAP_COLUMNS;
char *termcap_clr_eol=DEFAULT_TERMCAP_CLR_EOL;
char *termcap_save_cursor=DEFAULT_TERMCAP_SAVE_CURSOR;
char *termcap_clear_screen=DEFAULT_TERMCAP_CLEAR_SCREEN;
char *termcap_restore_cursor=DEFAULT_TERMCAP_RESTORE_CURSOR;
char *termcap_cursor_invisible=DEFAULT_TERMCAP_CURSOR_INVISIBLE;
char *termcap_cursor_visible=DEFAULT_TERMCAP_CURSOR_VISIBLE;
char *termcap_cursor_address=DEFAULT_TERMCAP_CURSOR_ADDRESS;
char *termcap_init_terminal=DEFAULT_TERMCAP_INIT_TERMINAL;
char *termcap_deinit_terminal=DEFAULT_TERMCAP_DEINIT_TERMINAL;
char *termcap_bell=DEFAULT_TERMCAP_BELL;
char *termcap_key_f1=DEFAULT_TERMCAP_KEY_F1;
char *termcap_key_f2=DEFAULT_TERMCAP_KEY_F2;
char *termcap_key_ic=DEFAULT_TERMCAP_KEY_IC;
char *termcap_key_dc=DEFAULT_TERMCAP_KEY_DC;
char *termcap_key_home=DEFAULT_TERMCAP_KEY_HOME;
char *termcap_key_eol=DEFAULT_TERMCAP_KEY_EOL;
char *termcap_key_ppage=DEFAULT_TERMCAP_KEY_PPAGE;
char *termcap_key_npage=DEFAULT_TERMCAP_KEY_NPAGE;
char *termcap_key_up=DEFAULT_TERMCAP_KEY_UP;
char *termcap_key_down=DEFAULT_TERMCAP_KEY_DOWN;
char *termcap_key_left=DEFAULT_TERMCAP_KEY_LEFT;
char *termcap_key_right=DEFAULT_TERMCAP_KEY_RIGHT;
char *termcap_key_backspace=DEFAULT_TERMCAP_KEY_BACKSPACE;
/* Initialize all termcap variables. */
void init_termcap()
{
char *term;
char *termcap_entry;
int n;
char *s;
/* Get the terminal type from the environment. */
term=getenv(LOCAL_TERM_ENVIRONMENT_VAR);
/* If the terminal type is not set in the environment, we use
the build in defaults. */
if(term==NULL)return;
/* Read the termcap entry for the given terminal type. */
if( (termcap_entry=read_termcap_entry(term))==NULL )
{
fprintf(stderr,"No termcap entry for %s\n",term);
exit(1);
}
/* Get all obligationary entries. */
if( (s=get_termcap_string(termcap_entry,"cm"))!=NULL )
termcap_cursor_address=s;
else
{
fprintf(stderr,
"Incomplete termcap entry for %s (cm missing)\n",
term);
exit(1);
}
if( (s=get_termcap_string(termcap_entry,"ce"))!=NULL )
termcap_clr_eol=s;
else
{
fprintf(stderr,
"Incomplete termcap entry for %s (ce missing)\n",
term);
exit(1);
}
if( (s=get_termcap_string(termcap_entry,"cl"))!=NULL )
termcap_clear_screen=s;
else
{
fprintf(stderr,
"Incomplete termcap entry for %s (cl missing)\n",
term);
exit(1);
}
/* Get all optional entries. */
if( (s=get_termcap_string(termcap_entry,"sc"))!=NULL )
termcap_save_cursor=s;
else termcap_save_cursor="";
if( (s=get_termcap_string(termcap_entry,"rc"))!=NULL )
termcap_restore_cursor=s;
else termcap_restore_cursor="";
if( (s=get_termcap_string(termcap_entry,"vi"))!=NULL )
termcap_cursor_invisible=s;
else termcap_cursor_invisible="";
if( (s=get_termcap_string(termcap_entry,"vs"))!=NULL )
termcap_cursor_visible=s;
else termcap_cursor_visible="";
if( (s=get_termcap_string(termcap_entry,"ti"))!=NULL )
termcap_init_terminal=s;
else termcap_init_terminal="";
if( (s=get_termcap_string(termcap_entry,"te"))!=NULL )
termcap_deinit_terminal=s;
else termcap_deinit_terminal="";
if( (s=get_termcap_string(termcap_entry,"bl"))!=NULL )
termcap_bell=s;
else termcap_bell="";
if( (s=get_termcap_string(termcap_entry,"k0"))!=NULL )
termcap_key_f1=s;
else termcap_key_f1="";
if( (s=get_termcap_string(termcap_entry,"k1"))!=NULL )
termcap_key_f2=s;
else termcap_key_f2="";
if( (s=get_termcap_string(termcap_entry,"kI"))!=NULL )
termcap_key_ic=s;
else termcap_key_ic="";
if( (s=get_termcap_string(termcap_entry,"kD"))!=NULL )
termcap_key_dc=s;
else termcap_key_dc="";
if( (s=get_termcap_string(termcap_entry,"kh"))!=NULL )
termcap_key_home=s;
else termcap_key_home="";
if( (s=get_termcap_string(termcap_entry,"kE"))!=NULL )
termcap_key_eol=s;
else termcap_key_eol="";
if( (s=get_termcap_string(termcap_entry,"kP"))!=NULL )
termcap_key_ppage=s;
else termcap_key_ppage="";
if( (s=get_termcap_string(termcap_entry,"kN"))!=NULL )
termcap_key_npage=s;
else termcap_key_npage="";
if( (s=get_termcap_string(termcap_entry,"ku"))!=NULL )
termcap_key_up=s;
else termcap_key_up="";
if( (s=get_termcap_string(termcap_entry,"kd"))!=NULL )
termcap_key_down=s;
else termcap_key_down="";
if( (s=get_termcap_string(termcap_entry,"kl"))!=NULL )
termcap_key_left=s;
else termcap_key_left="";
if( (s=get_termcap_string(termcap_entry,"kr"))!=NULL )
termcap_key_right=s;
else termcap_key_right="";
if( (s=get_termcap_string(termcap_entry,"kb"))!=NULL )
termcap_key_backspace=s;
else termcap_key_backspace="";
if( (n=get_termcap_number(termcap_entry,"li"))!=-1 )
PARAMETER_VALUE(PARAMETER_LINES)=termcap_lines=n;
if( (n=get_termcap_number(termcap_entry,"co"))!=-1)
termcap_columns=n;
/* Ready. */
return;
}
/* Write an escape sequence to the terminal. The escape sequence is
defined by the termcap string and two optional parameters. */
void termcap_out(termcap_string,par1,par2)
char termcap_string[];
int par1,par2;
{
int i;
int tmppar;
/* Skip a leading number indicating a delay time. */
for(i=0;'0'<=termcap_string[i] && termcap_string[i]<='9';i++);
/* Write the termcap entry. */
for(;termcap_string[i]!='\0';i++)
{
/* '\200' is translated into '\0'. */
if(termcap_string[i]=='\200')putc('\0',stdout);
/* All other characters except '%' are written unchanged. */
else if(termcap_string[i]!='%')putc(termcap_string[i],stdout);
/* The '%' character introduces an escape. */
else switch(termcap_string[++i])
{
/* "%%" evalueates to a single '%'. */
case '%':
putc('%',stdout);
break;
/* "%d" prints the next parameter as integer. */
case 'd':
fprintf(stdout,"%d",par1);
par1=par2;
break;
/* "%2" prints the next parameter as two digit integer. */
case '2':
fprintf(stdout,"%02d",par1);
par1=par2;
break;
/* "%3" prints the next parameter as three digit integer. */
case '3':
fprintf(stdout,"%03d",par1);
par1=par2;
break;
/* "%." prints the next parameter as character. */
case '.':
fprintf(stdout,"%c",par1);
par1=par2;
break;
/* "%+x" prints 'x' incremented with the next parameter
as character. */
case '+':
i++;
if(termcap_string[i]=='\0')break;
fprintf(stdout,"%c",par1+termcap_string[i]);
par1=par2;
break;
/* "%>xy" adds 'y' to the first parameter if it is greater
then 'y'. */
case '>':
i++;
if(termcap_string[i]=='\0')break;
i++;
if(termcap_string[i]=='\0')break;
if(par1>termcap_string[i-1])par1+=termcap_string[i];
break;
/* "%r" reverses the order of the parameters. */
case 'r':
tmppar=par1;
par1=par2;
par2=tmppar;
break;
/* "%i" increments both parameters with 1. */
case 'i':
par1++;
par2++;
break;
/* "%n" exclusive-or-s both parameters with 0140. */
case 'n':
par1^=0140;
par2^=0140;
break;
/* "%B" first parameter is BCD. */
case 'B':
par1=16*(par1/10)+par1%10;
break;
/* "%D" first parameter is reverse coded. */
case 'D':
par1=par1-2*(par1%16);
break;
}
}
}
/* Read the termcap entry for terminal term into memory. */
char *read_termcap_entry(term)
char term[];
{
static char entry[TERMCAP_ENTRY_SIZE];
char entry_name[128];
int entry_size;
char *termcap_file;
FILE *termcap_fp;
char *current_term;
char *current_entry;
int i,j;
int c;
/* Initially the entry we are looking for is specified by term. */
current_term=term;
/* Initially we start reading the entry into entry. */
current_entry=entry;
/* Initially the entry found doesn't contain anything. */
entry_size=0;
again:
/* Get the name of the termcap file_name from the environment. */
termcap_file=getenv(LOCAL_TERMCAP_ENVIRONMENT_VAR);
/* If the termcap file_name is not specified in the environment,
use the default. */
if(termcap_file==NULL)termcap_file=LOCAL_TERMCAP_FILE;
/* Open termcap file. */
if( (termcap_fp=fopen(termcap_file,"r"))==NULL )
{
fprintf(stderr,"Cannot open termcap file %s\n",termcap_file);
exit(1);
}
/* Read until end of termcap file. */
while(!feof(termcap_fp))
{
/* Read entry. */
entry_size=read_one_entry_from_termcap_file(
termcap_fp,current_entry,TERMCAP_ENTRY_SIZE-entry_size);
/* The first parameter in the entry are one or more entry
names, separated by '|'. Test whether one of these entry
names is the one we are looking for. */
i=0;
for(;;)
{
/* Isolate next entry name. */
for(j=0;current_entry[i]!='|' &&
current_entry[i]!='\0';i++,j++)
entry_name[j]=current_entry[i];
entry_name[j]='\0';
/* If entry for our terminal found. */
if(strcmp(entry_name,current_term)==0)
{
/* Close termcap file. */
fclose(termcap_fp);
/* Overwrite all entry names with '@'. */
for(i=0;current_entry[i]!='\0';i++)
current_entry[i]='@';
/* If the entry found contains a variable
"tc", we will add the entry for the terminal
type specified by this variable to the entry
found. We will do this only once. */
if( current_entry==entry && (current_term=
get_termcap_string(entry,"tc"))
!=NULL )
{
current_entry=entry+entry_size;
goto again;
}
/* Ready. */
return entry;
}
/* If there are no more entry names, break. */
if(current_entry[i]=='\0')break;
/* Otherwise test the next entry name. */
else i++;
}
}
/* Close the termcap file. */
fclose(termcap_fp);
/* We haven't found an entry, so NULL is returned. */
return NULL;
}
/* Get a character termcap variable from the previously read termcap entry. */
char *get_termcap_string(entry,key)
char *entry;
char key[];
{
int i;
/* Only two character variables are recognized. */
if(key[0]=='\0' || key[1]=='\0')return NULL;
/* Find variable. */
for(i=0;;)
{
/* Variable not found. */
if(entry[i]=='\0')return NULL;
/* Variable found, but invalidated by a following '@'. */
if(entry[i]==key[0] && entry[i+1]==key[1] &&
entry[i+2]=='@')return NULL;
/* Found. */
if(entry[i]==key[0] && entry[i+1]==key[1] &&
entry[i+2]=='=')return &entry[i+3];
/* Next variable. */
for(;entry[i]!='\0';i++);
i++;
}
}
/* Get a integer termcap variable from the previously read termcap entry. */
int get_termcap_number(entry,key)
char *entry;
char key[];
{
int i;
int n;
/* Only two character variables are recognized. */
if(key[0]=='\0' || key[1]=='\0')return -1;
/* Find variable. */
for(i=0;;)
{
/* Variable not found. */
if(entry[i]=='\0')return -1;
/* Variable found, but invalidated by a following '@'. */
if(entry[i]==key[0] && entry[i+1]==key[1] &&
entry[i+2]=='@')return -1;
/* Found. */
if(entry[i]==key[0] && entry[i+1]==key[1] &&
entry[i+2]=='#')
{
if(sscanf(&entry[i+3],"%d",&n)!=1)return -1;
else return n;
}
/* Next variable. */
for(;entry[i]!='\0';i++);
i++;
}
}
int read_one_entry_from_termcap_file(termcap_fp,buffer,buffer_size)
FILE *termcap_fp;
char buffer[];
int buffer_size;
{
int i,j;
int c;
for(i=0;;)
{
/* Read one character. */
c=getc(termcap_fp);
/* A '\0' is converted into a '\200', because a '\0' is
already used for end-of-string. */
if(c=='\0')buffer[i]='\200';
/* The entry ends on end-of-file or unescaped end-of-line. */
else if(c==EOF || c=='\n')break;
/* White space is skipped. */
else if(i==0 && (c==' ' || c=='\t'))continue;
/* A colon delimmits the sections in the entry. Empty
sections are dsicarded. */
else if(c==':')
{
if(i==0)continue;
else if(buffer[i-1]=='\0')continue;
else buffer[i]='\0';
}
/* The backslash is the escape character. */
else if(c=='\\')
{
/* Get the next character. Break end-of-file. */
c=getc(termcap_fp);
if(c==EOF)break;
/* Discard an escaped new-line. */
else if(c=='\n')continue;
/* Discard an escaped null character. */
else if(c=='\0')continue;
/* "\n" is translated into a control-j (linefeed). */
else if(c=='n')buffer[i]=CTRL_J;
else if(c=='N')buffer[i]=CTRL_J;
/* "\r" is translated into a control-m
(cariage-return). */
else if(c=='r')buffer[i]=CTRL_M;
else if(c=='R')buffer[i]=CTRL_M;
/* "\t" is translated into a control-i (tab). */
else if(c=='t')buffer[i]=CTRL_I;
else if(c=='T')buffer[i]=CTRL_I;
/* "\b" is translated into a control-h (backspace). */
else if(c=='b')buffer[i]=CTRL_H;
else if(c=='B')buffer[i]=CTRL_H;
/* "\f" is translated into a control-l (formfeed). */
else if(c=='f')buffer[i]=CTRL_L;
else if(c=='F')buffer[i]=CTRL_L;
/* "\e" is translated into an escape. */
else if(c=='e')buffer[i]=ESC;
else if(c=='E')buffer[i]=ESC;
/* An octal numer preceded by a backslash is
translated into the character which has the octal
number as ascii value. */
else if('0'<=c && c<='7')
{
buffer[i]=c-'0';
c=getc(termcap_fp);
if('0'<=c && c<='7')
{
buffer[i]*=8;
buffer[i]+=c-'0';
c=getc(termcap_fp);
if('0'<=c && c<='7')
{
buffer[i]*=8;
buffer[i]+=c-'0';
}
else ungetc(c,termcap_fp);
}
else ungetc(c,termcap_fp);
if(buffer[i]=='\0')buffer[i]='\200';
}
/* If any other character is preceded by a backslash,
the the character is taken litterally. */
else buffer[i]=c;
}
/* "^x" represents control-x. */
else if(c=='^')
{
/* Get next character. Break on end-of-file. */
c=getc(termcap_fp);
if(c==EOF)break;
/* Put appropriate control character in the buffer. */
else if(c=='?')buffer[i]='\177';
else buffer[i]=c&31;
/* Translate a '\0' into a '\200'. */
if(buffer[i]=='\0')buffer[i]='\200';
}
/* Any other character is put without translation into
the buffer. */
else buffer[i]=c;
/* Increment the buffer index only if there is enough space
left in the buffer. */
if(i<buffer_size-2)i++;
}
/* Strip the last variable if there is not enough space in the
buffer for the entry. */
if(i==buffer_size-2)for(;i>0 && buffer[i]!='\0';i--);
/* Strip al terminating '\0' characters. */
for(;i>0 && buffer[i]=='\0';i--);
/* Add two terminating '\0' characters. */
i++;
buffer[i]='\0';
i++;
buffer[i]='\0';
/* Return the number of characters read. */
return i;
}