no more minix more, *whatis
This commit is contained in:
parent
aa6ff4c8be
commit
6ebe0cdf82
39 changed files with 3 additions and 5296 deletions
|
@ -16,7 +16,7 @@ SUBDIR= aal add_route adduser advent arp ash at autil awk \
|
|||
hostaddr id ifconfig ifdef indent install \
|
||||
intr ipcrm ipcs irdpd isoread join kill last leave \
|
||||
lex life loadkeys loadramdisk logger login look lp \
|
||||
lpd ls lspci M m4 mail make MAKEDEV makewhatis man \
|
||||
lpd ls lspci M m4 mail make MAKEDEV man \
|
||||
mdb mesg mined mkdep mkdir mkdist mkfifo mkfs mknod \
|
||||
mkproto modem mount mt netconf newroot nice nm nohup \
|
||||
nonamed od packit packman passwd paste patch pax \
|
||||
|
@ -31,8 +31,8 @@ SUBDIR= aal add_route adduser advent arp ash at autil awk \
|
|||
telnetd term termcap tget time tinyhalt top touch tr \
|
||||
truncate tsort ttt tty udpstat umount uname unexpand \
|
||||
uniq unstack update urlget uud uue version vol wc \
|
||||
whatis whereis which who whoami write writeisofs \
|
||||
xargs yacc yap yes zdump zic zmodem
|
||||
whereis which who whoami write writeisofs \
|
||||
xargs yacc yes zdump zic zmodem
|
||||
|
||||
.if ${ARCH} == "i386"
|
||||
SUBDIR+= atnormalize dosread fdisk loadfont \
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
SCRIPTS= makewhatis.sh
|
||||
MAN=
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -1,86 +0,0 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# makewhatis 2.2 - make whatis(5) database. Author: Kees J. Bot.
|
||||
#
|
||||
# Make the whatis database of a man directory from the manual pages.
|
||||
|
||||
case $1 in
|
||||
-*) set -$- x x
|
||||
esac
|
||||
|
||||
case $# in
|
||||
1) ;;
|
||||
*) echo "Usage: $0 <mandir>" >&2
|
||||
exit 1
|
||||
esac
|
||||
|
||||
cd $1 || exit
|
||||
|
||||
{
|
||||
# First pass, gathering the .SH NAME lines in various forms.
|
||||
|
||||
# First the man[1-9] directories, the titles are under the .SH NAME
|
||||
# section header.
|
||||
for chap in 1 2 3 4 5 6 7 8 9
|
||||
do
|
||||
for page in man$chap/*.$chap
|
||||
do
|
||||
if test -f "$page"; then # (Old sh barfs on 'continue')
|
||||
|
||||
sed -e 's/ / /g
|
||||
s/"NAME"/NAME/g
|
||||
s/^\.Sh/\.SH/g
|
||||
/^\.SH NAME/,/^\.SH /!d
|
||||
/^\.SH /d
|
||||
s/\\f.//g
|
||||
s/\\s[+-].//g
|
||||
s/\\s.//g
|
||||
s/\\//
|
||||
'"s/ - / ($chap) - /" < "$page"
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
# The Minix "Book style" documents, look for .CD
|
||||
for page in man1x/*.1x
|
||||
do
|
||||
if test -f "$page"; then
|
||||
|
||||
sed -e 's/ / /g
|
||||
/^\.CD /!d
|
||||
s/^[^"]*"//
|
||||
s/"[^"]*$//
|
||||
s/\\(en/-/g
|
||||
s/\\f.//g
|
||||
s/\\s[+-].//g
|
||||
s/\\s.//g
|
||||
s/\\\*(M2/MINIX/g
|
||||
s/\\//
|
||||
'"s/ - / (1x) - /" < "$page"
|
||||
fi
|
||||
done
|
||||
|
||||
# Some people throw extra flat text files into the cat[1-9]
|
||||
# directories. It would be nice if man(1) can find them.
|
||||
trap 'rm -f /tmp/mkw[cmn]$$; exit 1' 1 2 15
|
||||
for chap in 1 2 3 4 5 6 7 8 9
|
||||
do
|
||||
ls cat$chap 2>/dev/null >/tmp/mkwc$$
|
||||
ls man$chap 2>/dev/null >/tmp/mkwm$$
|
||||
comm -23 /tmp/mkwc$$ /tmp/mkwm$$ >/tmp/mkwn$$
|
||||
sed -e "/.*\\.$chap\$/!d
|
||||
s/\\.$chap\$/ ($chap) - ???/" < /tmp/mkwn$$
|
||||
done
|
||||
rm -f /tmp/mkw[cmn]$$
|
||||
} | {
|
||||
# Second pass, remove empty lines, leading and trailing spaces,
|
||||
# multiple spaces to one space, remove lines without a dash.
|
||||
sed -e 's/ */ /g
|
||||
s/^ //
|
||||
s/ $//
|
||||
/^$/d
|
||||
/-/!d'
|
||||
} | {
|
||||
# Third pass, sort by section.
|
||||
sort -t'(' +1 -o whatis
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
SCRIPTS= whatis.sh
|
||||
MAN=
|
||||
|
||||
LINKS+= ${BINDIR}/whatis ${BINDIR}/apropos
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -1,53 +0,0 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# whatis/apropos 1.3 - search whatis(5) database for commands
|
||||
# Author: Kees J. Bot
|
||||
# BUGS
|
||||
# whatis file must be as if created by makewhatis(8).
|
||||
#
|
||||
# This version includes a fix by Michael Haardt originally posted to
|
||||
# comp.os.minix in July 1999. Fixes for grep provided by Michael in May
|
||||
# 1999 caused whatis to break, this is now fixed. (ASW 2004-12-12)
|
||||
|
||||
all='exit 0'
|
||||
|
||||
case "$1" in
|
||||
-a) all="found='exit 0'"
|
||||
shift
|
||||
esac
|
||||
|
||||
case $#:$0 in
|
||||
1:*whatis)
|
||||
;;
|
||||
1:*apropos)
|
||||
all="found='exit 0'"
|
||||
;;
|
||||
*) echo "Usage: `basename $0` [-a] <keyword>" >&2
|
||||
exit 1
|
||||
esac
|
||||
|
||||
IFS=":$IFS"
|
||||
MANPATH="${MANPATH-/usr/local/man:/usr/man}"
|
||||
|
||||
found=
|
||||
|
||||
for m in $MANPATH
|
||||
do
|
||||
for w in $m/whatis
|
||||
do
|
||||
test -f $w || continue
|
||||
|
||||
case $0 in
|
||||
*whatis)
|
||||
grep '^\('$1'\|[^(]* '$1'\)[ ,][^(]*(' $w && eval $all
|
||||
;;
|
||||
*apropos)
|
||||
grep -i "$1" $w && eval $all
|
||||
esac
|
||||
done
|
||||
done
|
||||
|
||||
$found
|
||||
|
||||
echo "`basename $0`: $1: not found" >&2
|
||||
exit 1
|
|
@ -1,15 +0,0 @@
|
|||
# yap Makefile
|
||||
|
||||
# XXX: Can only be built with ACK currently
|
||||
CC:=${CC:C/^gcc/cc/}
|
||||
COMPILER_TYPE:=ack
|
||||
|
||||
PROG= yap
|
||||
SRCS= assert.c commands.c display.c getcomm.c getline.c help.c \
|
||||
keys.c machine.c main.c options.c output.c pattern.c \
|
||||
process.c prompt.c term.c
|
||||
CPPFLAGS+= -wa
|
||||
LINKS+= ${BINDIR}/yap ${BINDIR}/more
|
||||
MAN=
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -1,21 +0,0 @@
|
|||
$Header$
|
||||
|
||||
The software and documentation contained within this
|
||||
directory is copyright (c) Ceriel J.H. Jacobs, 1988.
|
||||
|
||||
Permission is granted to reproduce and distribute
|
||||
this software as long as no fee is charged and
|
||||
this notice is included.
|
||||
|
||||
Other rights are reserved except as explicitly
|
||||
granted by written permission from the author.
|
||||
|
||||
Ceriel J.H. Jacobs
|
||||
Dept. of Maths and Computer Science
|
||||
Vrije Universiteit
|
||||
De Boelelaan 1081
|
||||
1081 HV Amsterdam
|
||||
The Netherlands
|
||||
email :
|
||||
ceriel@cs.vu.nl
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
$Header$
|
||||
|
||||
This directory contains the sources of YAP, Yet Another Pager.
|
||||
It can do most of the things more(1) can, and much much more.
|
||||
|
||||
Yap has been tested on the following systems:
|
||||
|
||||
- DEC PDP 11/44 running V7
|
||||
- DEC PDP 11/60 running V7
|
||||
- DEC VAX 11/750 running 4.1BSD
|
||||
- IBM PC/XT running PC/IX
|
||||
- NCR Minitower running a System V
|
||||
- Several 68k systems
|
||||
- SUN-3 and SUN-4
|
||||
|
||||
On other systems, you might have some problems getting yap to run, but then
|
||||
again, you might not. You can always ask me for help, and maybe even get it.
|
||||
If you make any changes, please
|
||||
- tell me about them
|
||||
- mark them clearly, preferably through conditional compilation.
|
||||
|
||||
What you need to run yap:
|
||||
|
||||
- you need termlib/termcap.
|
||||
It probably is'nt too hard to adapt yap to terminfo.
|
||||
It might even work unchanged, but I don't know about that. We don't have
|
||||
terminfo or the system V curses.
|
||||
If you adapt yap to terminfo, I would sure like to get the changes you made,
|
||||
so please send them to me (email address at the bottom of this note);
|
||||
- you also need regex(III) (Either Berkeley style or USG will do).
|
||||
If you do not have it, you should define NOREGEX, which gives you
|
||||
simpleminded searches without meta-characters.
|
||||
|
||||
How to install yap:
|
||||
|
||||
- edit Makefile (easy)
|
||||
- edit in_all.h (easy)
|
||||
- type "make install"
|
||||
|
||||
Ceriel Jacobs, Vrije Universiteit Amsterdam
|
||||
ceriel@cs.vu.nl
|
|
@ -1,34 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
# ifndef lint
|
||||
static char rcsid[] = "$Header$";
|
||||
# endif
|
||||
|
||||
# define _ASSERT_
|
||||
|
||||
# include "in_all.h"
|
||||
# include "assert.h"
|
||||
# if DO_ASSERT
|
||||
# include "output.h"
|
||||
# include "term.h"
|
||||
|
||||
/*
|
||||
* Assertion fails. Tell me about it.
|
||||
*/
|
||||
|
||||
VOID
|
||||
badassertion(ass,f,l) char *ass, *f; {
|
||||
|
||||
clrbline();
|
||||
putline("Assertion \"");
|
||||
putline(ass);
|
||||
putline("\" failed ");
|
||||
putline(f);
|
||||
putline(", line ");
|
||||
prnum((long) l);
|
||||
putline(".\r\n");
|
||||
flush();
|
||||
resettty();
|
||||
abort();
|
||||
}
|
||||
# endif
|
|
@ -1,28 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
/* Assertion macro */
|
||||
|
||||
# ifndef _ASSERT_
|
||||
# define PUBLIC extern
|
||||
# else
|
||||
# define PUBLIC
|
||||
# endif
|
||||
|
||||
#if DO_ASSERT
|
||||
#define assert(x) if(!(x)) badassertion("x",__FILE__,__LINE__)
|
||||
VOID badassertion();
|
||||
/*
|
||||
* void badassertion(ass,fn,lineno)
|
||||
* char *ass, The assertion in string form,
|
||||
* *fn; The filename in which the assertion failed,
|
||||
* int lineno; The line number of the assertion.
|
||||
*
|
||||
* Reports the assertion on standard output and then aborts with a core dump.
|
||||
*/
|
||||
#else
|
||||
#define assert(x) /* nothing */
|
||||
#endif
|
||||
|
||||
# undef PUBLIC
|
|
@ -1,706 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
# ifndef lint
|
||||
static char rcsid[] = "$Header$";
|
||||
# endif
|
||||
|
||||
# define _COMMANDS_
|
||||
|
||||
# include "in_all.h"
|
||||
# include "commands.h"
|
||||
# include "output.h"
|
||||
# include "process.h"
|
||||
# include "help.h"
|
||||
# include "term.h"
|
||||
# include "prompt.h"
|
||||
# include "getline.h"
|
||||
# include "getcomm.h"
|
||||
# include "pattern.h"
|
||||
# include "display.h"
|
||||
# include "options.h"
|
||||
# include "machine.h"
|
||||
# include "keys.h"
|
||||
# include "main.h"
|
||||
# include "assert.h"
|
||||
# if USG_OPEN
|
||||
# include <fcntl.h>
|
||||
# include <errno.h>
|
||||
extern int errno;
|
||||
# endif
|
||||
# if BSD4_2_OPEN
|
||||
# include <sys/file.h>
|
||||
# include <errno.h>
|
||||
extern int errno;
|
||||
# endif
|
||||
# if POSIX_OPEN
|
||||
# include <sys/types.h>
|
||||
# include <fcntl.h>
|
||||
# include <errno.h>
|
||||
# endif
|
||||
|
||||
char *strcpy(), *strcat();
|
||||
|
||||
static long lastcount; /* Save last count for '.' command */
|
||||
static int lastcomm; /* Save last command for '.' command */
|
||||
|
||||
/*ARGSUSED*/
|
||||
STATIC int
|
||||
do_nocomm(cnt) long cnt; { /* Do nothing */
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
do_chkm(cnt) long cnt; { /* Change key map */
|
||||
register struct keymap *p;
|
||||
|
||||
if (!(p = othermap)) {
|
||||
error("No other keymap");
|
||||
return;
|
||||
}
|
||||
othermap = currmap;
|
||||
currmap = p;
|
||||
}
|
||||
|
||||
static int searchdir; /* Direction of last search */
|
||||
|
||||
/*
|
||||
* Perform searches
|
||||
*/
|
||||
|
||||
STATIC VOID
|
||||
do_search(str,cnt,dir) char *str; long cnt; int dir; {
|
||||
register char *p;
|
||||
register long lineno;
|
||||
|
||||
if (str) {
|
||||
/*
|
||||
* We have to get a pattern, which we have to prompt for
|
||||
* with the string "str".
|
||||
*/
|
||||
if ((p = readline(str)) == 0) {
|
||||
/*
|
||||
* User cancelled command
|
||||
*/
|
||||
return;
|
||||
}
|
||||
if ((p = re_comp(p))) {
|
||||
/*
|
||||
* There was an error in the pattern
|
||||
*/
|
||||
error(p);
|
||||
return;
|
||||
}
|
||||
searchdir = dir;
|
||||
}
|
||||
if (dir < 0) lineno = scr_info.firstline;
|
||||
else lineno = scr_info.lastline;
|
||||
for (;;) {
|
||||
p = 0;
|
||||
if ((lineno += dir) > 0) p = getline(lineno, 0);
|
||||
if (interrupt) return;
|
||||
if (!p) { /* End of file reached */
|
||||
error("pattern not found");
|
||||
return;
|
||||
}
|
||||
if (re_exec(p) && --cnt <= 0) {
|
||||
/*
|
||||
* We found the pattern, and we found it often enough.
|
||||
* Pity that we still don't know where the match is.
|
||||
* We only know the linenumber. So, we just hope the
|
||||
* following will at least bring it on the screen ...
|
||||
*/
|
||||
(VOID) display(lineno,0,pagesize,0);
|
||||
(VOID) scrollb(2,0);
|
||||
redraw(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
STATIC int
|
||||
do_fsearch(cnt) long cnt; { /* Forward search */
|
||||
|
||||
do_search("/", cnt, 1);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
do_bsearch(cnt) long cnt; { /* Backward search */
|
||||
|
||||
do_search("?", cnt, -1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Repeat last search in direction "dir"
|
||||
*/
|
||||
|
||||
STATIC int
|
||||
n_or_rn_search(cnt,dir) long cnt; int dir; {
|
||||
register char *p;
|
||||
|
||||
if (dir == 1) {
|
||||
p = "/\r";
|
||||
}
|
||||
else if (dir == -1) {
|
||||
p = "?\r";
|
||||
}
|
||||
else {
|
||||
error("No previous pattern");
|
||||
return;
|
||||
}
|
||||
if (!stupid) clrbline();
|
||||
putline(p);
|
||||
flush();
|
||||
do_search((char *) 0, cnt, dir);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
do_nsearch(cnt) long cnt; { /* Repeat search in same direction */
|
||||
|
||||
n_or_rn_search(cnt,searchdir);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
do_rnsearch(cnt) long cnt; { /* Repeat search in opposite direction */
|
||||
|
||||
n_or_rn_search(cnt, -searchdir);
|
||||
}
|
||||
|
||||
STATIC int shell(esc_ch, cnt) long cnt;
|
||||
{
|
||||
register char *p;
|
||||
static char buf[2];
|
||||
|
||||
buf[0] = esc_ch;
|
||||
if (p = readline(buf)) {
|
||||
shellescape(p, esc_ch);
|
||||
if (cnt >= 0 && !hardcopy) {
|
||||
p = startcomm;
|
||||
startcomm = 0;
|
||||
ret_to_continue();
|
||||
putline(TI);
|
||||
if (!p) {
|
||||
/*
|
||||
* Avoid double redraw.
|
||||
* After a "startcomm", a redraw will
|
||||
* take place anyway.
|
||||
*/
|
||||
redraw(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC int
|
||||
do_shell(cnt) long cnt; { /* Execute a shell escape */
|
||||
shell('!', cnt);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
do_pipe(cnt) long cnt; { /* Execute a shell escape */
|
||||
shell('|', cnt);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
STATIC int
|
||||
do_writefile(cnt) long cnt; { /* Write input to a file */
|
||||
register char *p;
|
||||
int fd;
|
||||
|
||||
if ((p = readline("Filename: ")) == 0 || !*p) {
|
||||
/*
|
||||
* No file name given
|
||||
*/
|
||||
return;
|
||||
}
|
||||
# if USG_OPEN || BSD4_2_OPEN || POSIX_OPEN
|
||||
if ((fd = open(p,O_CREAT|O_EXCL|O_WRONLY,0644)) < 0) {
|
||||
if (errno == EEXIST) {
|
||||
error("File exists");
|
||||
return;
|
||||
}
|
||||
error("Could not open file");
|
||||
return;
|
||||
}
|
||||
# else
|
||||
if (!access(p,0)) {
|
||||
error("File exists");
|
||||
return;
|
||||
}
|
||||
if ((fd = creat(p,0644)) < 0) {
|
||||
error("Could not open file");
|
||||
return;
|
||||
}
|
||||
# endif
|
||||
wrt_fd(fd);
|
||||
(VOID) close(fd);
|
||||
}
|
||||
|
||||
VOID
|
||||
wrt_fd(fd)
|
||||
{
|
||||
register long l = 1;
|
||||
register char *p = getline(l,0), *pbuf;
|
||||
char buf[1024];
|
||||
|
||||
while (p) {
|
||||
pbuf = buf;
|
||||
while (p && pbuf < &buf[1024]) {
|
||||
if (!*p) {
|
||||
*pbuf++ = '\n';
|
||||
p = getline(++l,0);
|
||||
}
|
||||
else *pbuf++ = *p++ & 0177;
|
||||
}
|
||||
if (write(fd, buf, pbuf - buf) < 0) {
|
||||
error("Write failed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC int
|
||||
do_absolute(cnt) long cnt; { /* Go to linenumber "cnt" */
|
||||
|
||||
if (!getline(cnt,0)) { /* Not there or interrupt */
|
||||
if (!interrupt) {
|
||||
/*
|
||||
* User did'nt give an interrupt, so the line number
|
||||
* was too high. Go to the last line.
|
||||
*/
|
||||
do_lline(cnt);
|
||||
}
|
||||
return;
|
||||
}
|
||||
(VOID) display(cnt,0,pagesize,1);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
STATIC int
|
||||
do_visit(cnt) long cnt; { /* Visit a file */
|
||||
register char *p;
|
||||
static char fn[128]; /* Keep file name */
|
||||
|
||||
if ((p = readline("Filename: ")) == 0) {
|
||||
return;
|
||||
}
|
||||
if (*p) {
|
||||
(VOID) strcpy(fn,p);
|
||||
visitfile(fn);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* User typed a return. Visit the current file
|
||||
*/
|
||||
if (!(p = filenames[filecount])) {
|
||||
error("No current file");
|
||||
return;
|
||||
}
|
||||
visitfile(p);
|
||||
}
|
||||
(VOID) display(1L, 0, pagesize, 1);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
STATIC int
|
||||
do_error(cnt) long cnt; { /* Called when user types wrong key sequence */
|
||||
|
||||
error(currmap->k_help);
|
||||
}
|
||||
|
||||
/*
|
||||
* Interface routine for displaying previous screen,
|
||||
* depending on cflag.
|
||||
*/
|
||||
|
||||
STATIC int
|
||||
prev_screen(sz,really) int sz, really; {
|
||||
register int retval;
|
||||
|
||||
retval = scrollb(sz - 1, really && cflag);
|
||||
if (really && !cflag) {
|
||||
/*
|
||||
* The previous call did not display anything, but at least we
|
||||
* know where to start
|
||||
*/
|
||||
return display(scr_info.firstline, scr_info.nf, sz, 1);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Interface routine for displaying the next screen,
|
||||
* dependent on cflag.
|
||||
*/
|
||||
|
||||
STATIC int
|
||||
next_screen(sz,really) int sz, really; {
|
||||
|
||||
register int t;
|
||||
register struct scr_info *p = &scr_info;
|
||||
|
||||
if (cflag) {
|
||||
return scrollf(sz-1,really);
|
||||
}
|
||||
t = p->tail->cnt - 1;
|
||||
if (p->lastline == p->firstline) {
|
||||
t += p->nf;
|
||||
}
|
||||
return display(p->lastline, t, sz, really);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
STATIC int
|
||||
do_redraw(cnt) long cnt; {
|
||||
|
||||
redraw(1);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
page_size(cnt) unsigned cnt; {
|
||||
|
||||
if (cnt) {
|
||||
if (cnt > maxpagesize) return maxpagesize;
|
||||
if (cnt < MINPAGESIZE) return MINPAGESIZE;
|
||||
return (int) cnt;
|
||||
}
|
||||
return pagesize;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
do_forward(cnt) long cnt; { /* Display next page */
|
||||
register int i;
|
||||
|
||||
i = page_size((unsigned) cnt);
|
||||
if (status & EOFILE) {
|
||||
/*
|
||||
* May seem strange, but actually a visit to the next file
|
||||
* has already been done here
|
||||
*/
|
||||
(VOID) display(1L,0,i,1);
|
||||
return;
|
||||
}
|
||||
(VOID) next_screen(i,1);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
do_backward(cnt) long cnt; {
|
||||
register int i, temp;
|
||||
|
||||
i = page_size((unsigned) cnt);
|
||||
if (!(status & START)) {
|
||||
(VOID) prev_screen(i,1);
|
||||
return;
|
||||
}
|
||||
if (stdf < 0) {
|
||||
(VOID) display(1L,0,i,1);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* The next part is a bit clumsy.
|
||||
* We want to display the last page of the previous file (for which
|
||||
* a visit has already been done), but the pagesize may temporarily
|
||||
* be different because the command had a count
|
||||
*/
|
||||
temp = pagesize;
|
||||
pagesize = i;
|
||||
do_lline(cnt);
|
||||
pagesize = temp;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
STATIC int
|
||||
do_firstline(cnt) long cnt; { /* Go to start of input */
|
||||
|
||||
do_absolute(1L);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
do_lline(cnt) long cnt; { /* Go to end of input */
|
||||
register int i = 0;
|
||||
register int j = pagesize - 1;
|
||||
|
||||
if ((cnt = to_lastline()) < 0) {
|
||||
/*
|
||||
* Interrupted by the user
|
||||
*/
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Display the page such that only the last line of the page is
|
||||
* a "~", independant of the pagesize
|
||||
*/
|
||||
while (!(display(cnt,i,j,0) & EOFILE)) {
|
||||
/*
|
||||
* The last line could of course be very long ...
|
||||
*/
|
||||
i+= j;
|
||||
}
|
||||
(VOID) scrollb(j - scr_info.tail->cnt, 0);
|
||||
redraw(0);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
do_lf(cnt) long cnt; { /* Display next line, or go to line */
|
||||
|
||||
if (cnt) { /* Go to line */
|
||||
do_absolute(cnt);
|
||||
return;
|
||||
}
|
||||
(VOID) scrollf(1,1);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
do_upline(cnt) long cnt; { /* Display previous line, or go to line */
|
||||
|
||||
if (cnt) { /* Go to line */
|
||||
do_absolute(cnt);
|
||||
return;
|
||||
}
|
||||
(VOID) scrollb(1,1);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
do_skiplines(cnt) long cnt; { /* Skip lines forwards */
|
||||
|
||||
/* Should be interruptable ... */
|
||||
(VOID) scrollf((int) (cnt + maxpagesize - 1), 0);
|
||||
redraw(0);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
do_bskiplines(cnt) long cnt; { /* Skip lines backwards */
|
||||
|
||||
/* Should be interruptable ... */
|
||||
(VOID) scrollb((int) (cnt + pagesize - 1), 0);
|
||||
redraw(0);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
do_fscreens(cnt) long cnt; { /* Skip screens forwards */
|
||||
|
||||
do {
|
||||
if ((next_screen(pagesize,0) & EOFILE) || interrupt) break;
|
||||
} while (--cnt >= 0);
|
||||
redraw(0);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
do_bscreens(cnt) long cnt; { /* Skip screens backwards */
|
||||
|
||||
do {
|
||||
if ((prev_screen(pagesize,0) & START) || interrupt) break;
|
||||
} while (--cnt >= 0);
|
||||
redraw(0);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
scro_size(cnt) unsigned cnt; {
|
||||
|
||||
if (cnt >= maxpagesize) return maxpagesize;
|
||||
if (cnt) return (int) cnt;
|
||||
return scrollsize;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
do_f_scroll(cnt) long cnt; { /* Scroll forwards */
|
||||
|
||||
(VOID) scrollf(scro_size((unsigned) cnt),1);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
do_b_scroll(cnt) long cnt; { /* Scroll backwards */
|
||||
|
||||
(VOID) scrollb(scro_size((unsigned) cnt),1);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
do_previousfile(cnt) long cnt; {/* Visit previous file */
|
||||
|
||||
if (nextfile(- (int) cnt)) {
|
||||
error("No (Nth) previous file");
|
||||
return;
|
||||
}
|
||||
redraw(0);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
do_nextfile(cnt) long cnt; { /* Visit next file */
|
||||
|
||||
if (nextfile((int) cnt)) {
|
||||
error("No (Nth) next file");
|
||||
return;
|
||||
}
|
||||
redraw(0);
|
||||
}
|
||||
|
||||
STATIC int do_lcomm();
|
||||
|
||||
/*
|
||||
* The next array is initialized, sorted on the first element of the structs,
|
||||
* so that we can perform binary search
|
||||
*/
|
||||
struct commands commands[] = {
|
||||
{"", 0, do_error, ""},
|
||||
{"", 0, do_nocomm, ""},
|
||||
{"bf", STICKY|NEEDS_COUNT,
|
||||
do_previousfile,"Visit previous file"},
|
||||
{"bl", NEEDS_SCREEN|STICKY,
|
||||
do_upline, "Scroll one line up, or go to line"},
|
||||
{"bot", STICKY,
|
||||
do_lline, "Go to last line of the input"},
|
||||
{"bp", BACK|NEEDS_SCREEN|TOPREVFILE|STICKY,
|
||||
do_backward, "display previous page"},
|
||||
{"bps", SCREENSIZE_ADAPT|BACK|NEEDS_SCREEN|TOPREVFILE|STICKY,
|
||||
do_backward, "Display previous page, set pagesize"},
|
||||
{"bs", BACK|NEEDS_SCREEN|STICKY,
|
||||
do_b_scroll, "Scroll backwards"},
|
||||
{"bse", 0, do_bsearch, "Search backwards for pattern"},
|
||||
{"bsl", BACK|NEEDS_SCREEN|STICKY|NEEDS_COUNT,
|
||||
do_bskiplines, "Skip lines backwards"},
|
||||
{"bsp", BACK|NEEDS_SCREEN|STICKY|NEEDS_COUNT,
|
||||
do_bscreens, "Skip screens backwards"},
|
||||
{"bss", SCROLLSIZE_ADAPT|BACK|NEEDS_SCREEN|STICKY,
|
||||
do_b_scroll, "Scroll backwards, set scrollsize"},
|
||||
{"chm", 0, do_chkm, "Switch to other keymap"},
|
||||
{"exg", STICKY, exgmark, "Exchange current page with mark"},
|
||||
{"ff", STICKY|NEEDS_COUNT,
|
||||
do_nextfile, "Visit next file"},
|
||||
{"fl", NEEDS_SCREEN|STICKY,
|
||||
do_lf, "Scroll one line down, or go to line"},
|
||||
{"fp", TONEXTFILE|AHEAD|STICKY,
|
||||
do_forward, "Display next page"},
|
||||
{"fps", SCREENSIZE_ADAPT|TONEXTFILE|AHEAD|STICKY,
|
||||
do_forward, "Display next page, set pagesize"},
|
||||
{"fs", AHEAD|NEEDS_SCREEN|STICKY,
|
||||
do_f_scroll, "Scroll forwards"},
|
||||
{"fse", 0, do_fsearch, "Search forwards for pattern"},
|
||||
{"fsl", AHEAD|NEEDS_SCREEN|STICKY|NEEDS_COUNT,
|
||||
do_skiplines, "Skip lines forwards"},
|
||||
{"fsp", AHEAD|NEEDS_SCREEN|STICKY|NEEDS_COUNT,
|
||||
do_fscreens, "Skip screens forwards"},
|
||||
{"fss", SCROLLSIZE_ADAPT|AHEAD|NEEDS_SCREEN|STICKY,
|
||||
do_f_scroll, "Scroll forwards, set scrollsize"},
|
||||
{"hlp", 0, do_help, "Give description of all commands"},
|
||||
{"mar", 0, setmark, "Set a mark on the current page"},
|
||||
{"nse", STICKY, do_nsearch, "Repeat the last search"},
|
||||
{"nsr", STICKY, do_rnsearch, "Repeat last search in other direction"},
|
||||
{"pip", ESC, do_pipe, "pipe input into shell command"},
|
||||
{"qui", 0, quit, "Exit from yap"},
|
||||
{"red", 0, do_redraw, "Redraw screen"},
|
||||
{"rep", 0, do_lcomm, "Repeat last command"},
|
||||
{"shl", ESC, do_shell, "Execute a shell escape"},
|
||||
{"tom", 0, tomark, "Go to mark"},
|
||||
{"top", STICKY, do_firstline, "Go to the first line of the input"},
|
||||
{"vis", 0, do_visit, "Visit a file"},
|
||||
{"wrf", 0, do_writefile, "Write input to a file"},
|
||||
};
|
||||
|
||||
/*
|
||||
* Lookup string "s" in the commands array, and return index.
|
||||
* return 0 if not found.
|
||||
*/
|
||||
|
||||
int
|
||||
lookup(s) char *s; {
|
||||
register struct commands *l, *u, *m;
|
||||
|
||||
l = &commands[2];
|
||||
u = &commands[sizeof(commands) / sizeof(*u) - 1];
|
||||
do {
|
||||
/*
|
||||
* Perform binary search
|
||||
*/
|
||||
m = l + (u - l) / 2;
|
||||
if (strcmp(s, m->c_cmd) > 0) l = m + 1;
|
||||
else u = m;
|
||||
} while (l < u);
|
||||
if (!strcmp(s, u->c_cmd)) return u - commands;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
STATIC int
|
||||
do_lcomm(cnt) long cnt; { /* Repeat last command */
|
||||
|
||||
if (!lastcomm) {
|
||||
error("No previous command");
|
||||
return;
|
||||
}
|
||||
do_comm(lastcomm, lastcount);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute a command, with optional count "count".
|
||||
*/
|
||||
|
||||
VOID
|
||||
do_comm(comm, count) register int comm; register long count; {
|
||||
|
||||
register struct commands *pcomm;
|
||||
register int temp;
|
||||
register int flags;
|
||||
|
||||
pcomm = &commands[comm];
|
||||
flags = pcomm->c_flags;
|
||||
|
||||
/*
|
||||
* Check the command.
|
||||
* If the last line of the file is displayed and the command goes
|
||||
* forwards and does'nt have the ability to go to the next file, it
|
||||
* is an error.
|
||||
* If the first line of the file is displayed and the command goes
|
||||
* backwards and does'nt have the ability to go to the previous file,
|
||||
* it is an error.
|
||||
* Also check wether we need the next or previous file. If so, get it.
|
||||
*/
|
||||
if ((status & EOFILE) && (flags & AHEAD)) {
|
||||
if (qflag || !(flags & TONEXTFILE)) return;
|
||||
if (nextfile(1)) quit();
|
||||
}
|
||||
if ((status & START) && (flags & BACK)) {
|
||||
if (qflag || !(flags & TOPREVFILE)) return;
|
||||
if (nextfile(-1)) quit();
|
||||
}
|
||||
/*
|
||||
* Does the command stick around for LASTCOMM?
|
||||
*/
|
||||
if (flags & STICKY) {
|
||||
lastcomm = comm;
|
||||
lastcount = count;
|
||||
}
|
||||
if (!count) {
|
||||
if (flags & NEEDS_COUNT) count = 1;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Does the command adapt the screensize?
|
||||
*/
|
||||
if (flags & SCREENSIZE_ADAPT) {
|
||||
temp = maxpagesize;
|
||||
if ((unsigned) count < temp) {
|
||||
temp = count;
|
||||
}
|
||||
if (temp < MINPAGESIZE) {
|
||||
temp = MINPAGESIZE;
|
||||
}
|
||||
count = 0;
|
||||
pagesize = temp;
|
||||
}
|
||||
/*
|
||||
* Does the command adapt the scrollsize?
|
||||
*/
|
||||
if (flags & SCROLLSIZE_ADAPT) {
|
||||
temp = maxpagesize - 1;
|
||||
if ((unsigned) count < temp) {
|
||||
temp = (int) count;
|
||||
}
|
||||
scrollsize = temp;
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Now execute the command.
|
||||
*/
|
||||
(*(pcomm->c_func))(count);
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
# ifndef _COMMANDS_
|
||||
# define PUBLIC extern
|
||||
# else
|
||||
# define PUBLIC
|
||||
# endif
|
||||
|
||||
/* Flags, describing properties of commands */
|
||||
|
||||
# define SCREENSIZE_ADAPT 01 /* Can change screen size */
|
||||
# define SCROLLSIZE_ADAPT 02 /* Can change scrollsize */
|
||||
# define TONEXTFILE 04 /* to next file */
|
||||
# define AHEAD 010 /* goes ahead in the file */
|
||||
# define BACK 020 /* goes back in the file */
|
||||
# define NEEDS_SCREEN 040 /* needs screen info */
|
||||
# define TOPREVFILE 0100 /* to previous file */
|
||||
# define STICKY 0200 /* remember for lastcomm */
|
||||
# define NEEDS_COUNT 0400 /* command needs a count */
|
||||
# define ESC 01000 /* shell or pipe escape */
|
||||
|
||||
extern struct commands {
|
||||
char *c_cmd; /* Short mnemonic for a command */
|
||||
int c_flags; /* describes command properties */
|
||||
int (*c_func)(); /* Function executing the command */
|
||||
char *c_descr; /* Short command description */
|
||||
} commands[];
|
||||
|
||||
int do_chkm();
|
||||
/*
|
||||
* int do_chkm(cnt)
|
||||
* long cnt; Ignored
|
||||
*
|
||||
* Switch to other keymap
|
||||
*/
|
||||
|
||||
VOID do_comm();
|
||||
/*
|
||||
* void do_comm(command, count)
|
||||
* int command; Index in the commands array
|
||||
* long count; Some commands possibly take a count
|
||||
*
|
||||
* Checks and executes commands.
|
||||
*/
|
||||
|
||||
int lookup();
|
||||
/*
|
||||
* int lookup(str)
|
||||
* char *str;
|
||||
*
|
||||
* Searches the string "str" in the command list.
|
||||
* It returns its index if it exists, otherwise it returns 0.
|
||||
*/
|
||||
|
||||
VOID wrt_fd();
|
||||
/*
|
||||
* void wrt_fd(fd)
|
||||
* int fd; File descriptor
|
||||
*
|
||||
* Write input to file descriptor fd
|
||||
*/
|
||||
# undef PUBLIC
|
|
@ -1,547 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
# ifndef lint
|
||||
static char rcsid[] = "$Header$";
|
||||
# endif
|
||||
|
||||
# define _DISPLAY_
|
||||
|
||||
# include "in_all.h"
|
||||
# include "display.h"
|
||||
# include "assert.h"
|
||||
# include "machine.h"
|
||||
# include "term.h"
|
||||
# include "output.h"
|
||||
# include "options.h"
|
||||
# include "process.h"
|
||||
# include "getline.h"
|
||||
# include "main.h"
|
||||
|
||||
STATIC char * do_line();
|
||||
|
||||
/*
|
||||
* Fill n lines of the screen, each with "str".
|
||||
*/
|
||||
|
||||
STATIC VOID
|
||||
fillscr(n,str) char *str; int n; {
|
||||
|
||||
while (n-- > 0) {
|
||||
putline(str);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip "n" screenlines of line "p", and return what's left of it.
|
||||
*/
|
||||
|
||||
STATIC char *
|
||||
skiplines(p,n) char *p; int n; {
|
||||
|
||||
while (n-- > 0) {
|
||||
p = do_line(p,0);
|
||||
scr_info.currentpos--;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* Redraw screen.
|
||||
* "n" = 1 if it is a real redraw, 0 if one page must be displayed.
|
||||
* It is also called when yap receives a stop signal.
|
||||
*/
|
||||
|
||||
VOID
|
||||
redraw(n) int n; {
|
||||
register struct scr_info *p = &scr_info;
|
||||
register int i;
|
||||
|
||||
i = pagesize;
|
||||
if (n && p->currentpos) {
|
||||
i = p->currentpos;
|
||||
}
|
||||
(VOID) display(p->firstline,p->nf,i,1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute return value for the routines "display" and "scrollf".
|
||||
* This return value indicates wether we are at the end of file
|
||||
* or at the start, or both.
|
||||
* "s" contains that part of the last line that was not displayed.
|
||||
*/
|
||||
|
||||
STATIC int
|
||||
compretval(s) char *s; {
|
||||
register int i;
|
||||
register struct scr_info *p = &scr_info;
|
||||
|
||||
i = 0;
|
||||
if (!s || (!*s && !getline(p->lastline+1, 1))) {
|
||||
i = EOFILE;
|
||||
}
|
||||
if (p->firstline == 1 && !p->nf) {
|
||||
i |= START;
|
||||
}
|
||||
status = i;
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Display nlines, starting at line n, not displaying the first
|
||||
* nd screenlines of n.
|
||||
* If reallydispl = 0, the actual displaying is not performed,
|
||||
* only the computing associated with it is done.
|
||||
*/
|
||||
|
||||
int
|
||||
display(n,nd,nlines,reallydispl)
|
||||
long n; int nd; register int nlines; int reallydispl; {
|
||||
|
||||
register struct scr_info *s = &scr_info;
|
||||
register char *p; /* pointer to line to be displayed */
|
||||
|
||||
if (startcomm) { /* No displaying on a command from the
|
||||
* yap command line. In this case, displaying
|
||||
* will be done after executing the command,
|
||||
* by a redraw.
|
||||
*/
|
||||
reallydispl = 0;
|
||||
}
|
||||
if (!n) {
|
||||
n = 1L;
|
||||
nd = 0;
|
||||
}
|
||||
if (reallydispl) { /* move cursor to starting point */
|
||||
if (stupid) {
|
||||
putline(currentfile);
|
||||
putline(", line ");
|
||||
prnum(n);
|
||||
nlines--;
|
||||
}
|
||||
if (cflag) {
|
||||
putline("\r\n");
|
||||
}
|
||||
else {
|
||||
home();
|
||||
clrscreen();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Now, do computations and display
|
||||
*/
|
||||
s->currentpos = 0;
|
||||
s->nf = nd;
|
||||
s->head = s->tail;
|
||||
s->tail->cnt = 0;
|
||||
s->tail->line = n;
|
||||
p = skiplines(getline(n,1),nd);
|
||||
while (nlines && p) {
|
||||
/*
|
||||
* While there is room,
|
||||
* and there is something left to display ...
|
||||
*/
|
||||
(s->tail->cnt)++;
|
||||
nlines--;
|
||||
if (*(p = do_line(p,reallydispl)) == '\0') {
|
||||
/*
|
||||
* File-line finished, get next one ...
|
||||
*/
|
||||
p = getline(++n,1);
|
||||
if (nlines && p) {
|
||||
s->tail = s->tail->next;
|
||||
s->tail->cnt = 0;
|
||||
s->tail->line = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!stupid) {
|
||||
s->currentpos += nlines;
|
||||
if (reallydispl) {
|
||||
fillscr(nlines, "~\r\n");
|
||||
fillscr(maxpagesize - s->currentpos, "\r\n");
|
||||
}
|
||||
}
|
||||
return compretval(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* Scroll forwards n lines.
|
||||
*/
|
||||
|
||||
int
|
||||
scrollf(n,reallydispl) int n; int reallydispl; {
|
||||
|
||||
register struct scr_info *s = &scr_info;
|
||||
register char *p;
|
||||
register long ll;
|
||||
register int i;
|
||||
|
||||
/*
|
||||
* First, find out how many screenlines of the last line were already
|
||||
* on the screen, and possibly above it.
|
||||
*/
|
||||
|
||||
if (n <= 0 || (status & EOFILE)) return status;
|
||||
if (startcomm) reallydispl = 0;
|
||||
/*
|
||||
* Find out where to begin displaying
|
||||
*/
|
||||
i = s->tail->cnt;
|
||||
if ((ll = s->lastline) == s->firstline) i += s->nf;
|
||||
p = skiplines(getline(ll, 1), i);
|
||||
/*
|
||||
* Now, place the cursor at the first free line
|
||||
*/
|
||||
if (reallydispl && !stupid) {
|
||||
clrbline();
|
||||
mgoto(s->currentpos);
|
||||
}
|
||||
/*
|
||||
* Now display lines, keeping track of which lines are on the screen.
|
||||
*/
|
||||
while (n-- > 0) { /* There are still rows to be displayed */
|
||||
if (!*p) { /* End of line, get next one */
|
||||
if (!(p = getline(++ll, 1))) {
|
||||
/*
|
||||
* No lines left. At end of file
|
||||
*/
|
||||
break;
|
||||
}
|
||||
s->tail = s->tail->next;
|
||||
s->tail->cnt = 0;
|
||||
s->tail->line = ll;
|
||||
}
|
||||
if (s->currentpos >= maxpagesize) {
|
||||
/*
|
||||
* No room, delete first screen-line
|
||||
*/
|
||||
s->currentpos--;
|
||||
s->nf++;
|
||||
if (--(s->head->cnt) == 0) {
|
||||
/*
|
||||
* The first file-line on the screen is wiped
|
||||
* out completely; update administration
|
||||
* accordingly.
|
||||
*/
|
||||
s->nf = 0;
|
||||
s->head = s->head->next;
|
||||
assert(s->head->cnt > 0);
|
||||
}
|
||||
}
|
||||
s->tail->cnt++;
|
||||
p = do_line(p, reallydispl);
|
||||
}
|
||||
return compretval(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* Scroll back n lines
|
||||
*/
|
||||
|
||||
int
|
||||
scrollb(n, reallydispl) int n, reallydispl; {
|
||||
|
||||
register struct scr_info *s = &scr_info;
|
||||
register char *p; /* Holds string to be displayed */
|
||||
register int i;
|
||||
register int count;
|
||||
register long ln; /* a line number */
|
||||
register int nodispl;
|
||||
int cannotscroll; /* stupid or no insert-line */
|
||||
|
||||
/*
|
||||
* First, find out where to start
|
||||
*/
|
||||
if ((count = n) <= 0 || (status & START)) return status;
|
||||
if (startcomm) reallydispl = 0;
|
||||
cannotscroll = stupid || (!*AL && !*SR);
|
||||
ln = s->firstline;
|
||||
nodispl = s->nf;
|
||||
while (count) { /* While scrolling back ... */
|
||||
if (i = nodispl) {
|
||||
/*
|
||||
* There were screen-lines of s->firstline that were not
|
||||
* displayed.
|
||||
* We can use them now, but only "count" of them.
|
||||
*/
|
||||
if (i > count) i = count;
|
||||
s->currentpos += i;
|
||||
nodispl -= i;
|
||||
count -= i;
|
||||
}
|
||||
else { /* Get previous line */
|
||||
if (ln == 1) break; /* isn't there ... */
|
||||
p = getline(--ln, 1);
|
||||
/*
|
||||
* Make it the first line of the screen and compute
|
||||
* how many screenlines it takes. These lines are not
|
||||
* displayed, but nodispl is set to this count, so
|
||||
* that it will be nonzero next time around
|
||||
*/
|
||||
nodispl = 0;
|
||||
do { /* Find out how many screenlines */
|
||||
nodispl++;
|
||||
p = skiplines(p, 1);
|
||||
} while (*p);
|
||||
}
|
||||
}
|
||||
n -= count;
|
||||
if ((i = s->currentpos) > maxpagesize) i = maxpagesize;
|
||||
if (reallydispl && hardcopy) i = n;
|
||||
/*
|
||||
* Now that we know where to start, we can use "display" to do the
|
||||
* rest of the computing for us, and maybe even the displaying ...
|
||||
*/
|
||||
i = display(ln,
|
||||
nodispl,
|
||||
i,
|
||||
reallydispl && cannotscroll);
|
||||
if (cannotscroll || !reallydispl) {
|
||||
/*
|
||||
* Yes, "display" did the displaying, or we did'nt have to
|
||||
* display at all.
|
||||
* I like it, but the user obviously does not.
|
||||
* Let him buy another (smarter) terminal ...
|
||||
*/
|
||||
return i;
|
||||
}
|
||||
/*
|
||||
* Now, all we have to do is the displaying. And we are dealing with
|
||||
* a smart terminal (it can insert lines or scroll back).
|
||||
*/
|
||||
home();
|
||||
/*
|
||||
* Insert lines all at once
|
||||
*/
|
||||
for (i = n; i; i--) {
|
||||
if (DB && *CE) {
|
||||
/*
|
||||
* Grumble..., terminal retains lines below, so we have
|
||||
* to clear the lines that we push off the screen
|
||||
*/
|
||||
clrbline();
|
||||
home();
|
||||
}
|
||||
if (*SR) {
|
||||
scrollreverse();
|
||||
}
|
||||
else {
|
||||
# ifdef VT100_PATCH
|
||||
insert_line(0);
|
||||
# else
|
||||
insert_line();
|
||||
# endif
|
||||
}
|
||||
}
|
||||
p = skiplines(getline(ln = s->firstline, 1), s->nf);
|
||||
for (i = 0; i < n; i++) {
|
||||
p = do_line(p,1);
|
||||
s->currentpos--;
|
||||
if (!*p) {
|
||||
p = getline(++ln, 1);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a line.
|
||||
* If reallydispl > 0 then display it.
|
||||
*/
|
||||
|
||||
STATIC char *
|
||||
do_line(str, reallydispl) register char *str; int reallydispl; {
|
||||
|
||||
char buf[1024];
|
||||
register char *p = buf;
|
||||
register int pos = COLS;
|
||||
register int c;
|
||||
register int c1;
|
||||
register int do_ul = 0, do_hl = 0;
|
||||
int lastmode = 0, lasthlmode = 0;
|
||||
int c2;
|
||||
|
||||
while (*str && pos > 0) {
|
||||
if (*str < ' ' && (c1 = match(str,&c2,sppat)) > 0) {
|
||||
/*
|
||||
* We found a string that matches, and thus must be
|
||||
* echoed literally
|
||||
*/
|
||||
if ((pos - c2) <= 0) {
|
||||
/*
|
||||
* It did not fit
|
||||
*/
|
||||
break;
|
||||
}
|
||||
pos -= c2;
|
||||
str += c1;
|
||||
if (reallydispl) {
|
||||
c = *str;
|
||||
*p = *str = 0;
|
||||
cputline(p = buf);
|
||||
putline(str - c1);
|
||||
*str = c;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
c = *str++;
|
||||
do_hl = 0;
|
||||
if (*str == '\b' && *(str+1) != 0
|
||||
&& (c != '_' || *(str+2) == '\b')) {
|
||||
while (*str == '\b' && *(str+1) != 0) {
|
||||
str++;
|
||||
c = *str++;
|
||||
do_hl = 1;
|
||||
}
|
||||
}
|
||||
do_ul = 1;
|
||||
/*
|
||||
* Find underline sequences ...
|
||||
*/
|
||||
if (c == '_' && *str == '\b') {
|
||||
str++;
|
||||
c = *str++;
|
||||
}
|
||||
else {
|
||||
if (*str == '\b' && *(str+1) == '_') {
|
||||
str += 2;
|
||||
}
|
||||
else do_ul = 0;
|
||||
}
|
||||
if (reallydispl && do_hl != lasthlmode) {
|
||||
*p = 0;
|
||||
cputline(p = buf);
|
||||
if (do_hl) bold();
|
||||
else end_bold();
|
||||
}
|
||||
lasthlmode = do_hl;
|
||||
if (reallydispl && do_ul != lastmode) {
|
||||
*p = 0;
|
||||
cputline(p = buf);
|
||||
if (do_ul) underline();
|
||||
else end_underline();
|
||||
}
|
||||
lastmode = do_ul;
|
||||
*p++ = c;
|
||||
if (c >= ' ' && c < 0177) {
|
||||
pos--;
|
||||
if (reallydispl && do_ul && *UC && pos > 0) {
|
||||
/*
|
||||
* Underlining apparently is done one
|
||||
* character at a time.
|
||||
*/
|
||||
*p = 0;
|
||||
cputline(p = buf);
|
||||
backspace();
|
||||
underchar();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (c == '\t') {
|
||||
p--;
|
||||
c1 = 8 - ((COLS - pos) & 07);
|
||||
/*
|
||||
* Actually, if COLS is a multiple of 8, this can be
|
||||
* simplified to
|
||||
* c1 = pos & 07;
|
||||
* But of course, we don't know that for sure.
|
||||
*/
|
||||
if (pos - c1 < 0) break;
|
||||
pos -= c1;
|
||||
if (reallydispl) {
|
||||
if (expandtabs) {
|
||||
/*
|
||||
* Expand tabs. We cannot let the
|
||||
* kernel take care of this
|
||||
* for two reasons:
|
||||
* 1. There can be tabs in cursor
|
||||
* addressing strings,
|
||||
* 2. We probably do it better.
|
||||
*/
|
||||
while (c1-- > 0) {
|
||||
*p++ = ' ';
|
||||
}
|
||||
}
|
||||
else {
|
||||
*p = 0;
|
||||
cputline(p = buf);
|
||||
givetab();
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Now we have a control character, which takes two positions
|
||||
*/
|
||||
if (pos <= 1) {
|
||||
p--;
|
||||
break;
|
||||
}
|
||||
pos -= 2;
|
||||
}
|
||||
if (reallydispl) {
|
||||
*p = 0;
|
||||
cputline(buf);
|
||||
if (pos > 0 || (pos <= 0 && (!AM || XN))) {
|
||||
putline("\r\n");
|
||||
}
|
||||
/*
|
||||
* The next should be here! I.e. it may not be before printing
|
||||
* the newline. This has to do with XN. We don't know exactly
|
||||
* WHEN the terminal will stop ignoring the newline.
|
||||
* I have for example a terminal (Ampex a230) that will
|
||||
* continue to ignore the newline after a clear to end of line
|
||||
* sequence, but not after an end_underline sequence.
|
||||
*/
|
||||
if (do_ul) {
|
||||
end_underline();
|
||||
}
|
||||
if (do_hl) {
|
||||
standend();
|
||||
}
|
||||
}
|
||||
scr_info.currentpos++;
|
||||
return str;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
setmark(cnt) long cnt; { /* Set a mark on the current page */
|
||||
register struct scr_info *p = &scr_info;
|
||||
|
||||
p->savfirst = p->firstline;
|
||||
p->savnf = p->nf;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
tomark(cnt) long cnt; { /* Go to the mark */
|
||||
register struct scr_info *p = &scr_info;
|
||||
|
||||
(VOID) display(p->savfirst,p->savnf,pagesize,1);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
exgmark(cnt) long cnt; { /* Exchange mark and current page */
|
||||
register struct scr_info *p = &scr_info;
|
||||
register long svfirst;
|
||||
register int svnf;
|
||||
|
||||
svfirst = p->firstline;
|
||||
svnf = p->nf;
|
||||
tomark(0L);
|
||||
p->savfirst = svfirst;
|
||||
p->savnf = svnf;
|
||||
}
|
||||
|
||||
VOID
|
||||
d_clean() { /* Clean up */
|
||||
register struct scr_info *p = &scr_info;
|
||||
|
||||
p->savnf = 0;
|
||||
p->savfirst = 0;
|
||||
p->head = p->tail;
|
||||
p->head->line = 0;
|
||||
p->currentpos = 0;
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
# ifndef _DISPLAY_
|
||||
# define PUBLIC extern
|
||||
# else
|
||||
# define PUBLIC
|
||||
# endif
|
||||
|
||||
# define MINPAGESIZE 5
|
||||
|
||||
PUBLIC int pagesize; /* How many lines on a page */
|
||||
PUBLIC int maxpagesize; /* Maximum # of lines on a page */
|
||||
PUBLIC int scrollsize; /* number of lines in a scroll */
|
||||
struct scr_info {
|
||||
struct linelist {
|
||||
int cnt; /* # of screenlines for this line */
|
||||
long line; /* lineno of this line */
|
||||
# define firstline head->line
|
||||
# define lastline tail->line
|
||||
struct linelist *next;
|
||||
struct linelist *prev;
|
||||
} *tail, *head; /* Of all lines of the input file that are
|
||||
* on the screen, remember how many
|
||||
* screenlines they occupy. Keep this
|
||||
* info in a doubly linked list.
|
||||
*/
|
||||
int nf; /* How many screenlines of the first line
|
||||
* on the screen are not on the screen?
|
||||
*/
|
||||
int currentpos; /* Y coordinate of first free line */
|
||||
struct linelist ssaavv; /* Mark */
|
||||
# define savfirst ssaavv.line
|
||||
# define savnf ssaavv.cnt
|
||||
};
|
||||
|
||||
PUBLIC struct scr_info scr_info;
|
||||
PUBLIC int status; /* EOFILE on end of file
|
||||
* START on start of file
|
||||
* logical "or" if both
|
||||
*/
|
||||
/* Flags for status field */
|
||||
|
||||
# define EOFILE 01
|
||||
# define START 02
|
||||
|
||||
VOID redraw();
|
||||
/*
|
||||
* void redraw(flag)
|
||||
* int flag; Either 0 or 1
|
||||
*
|
||||
* Redraws the screen. If flag = 1, the screen is redrawn as precisely
|
||||
* as possible, otherwise one page is displayed (which possibly does not
|
||||
* take a whole screen.
|
||||
*/
|
||||
|
||||
int display();
|
||||
/*
|
||||
* int display(firstline, nodispl, nlines, really)
|
||||
* long firstline; Line with which to start
|
||||
* int nodispl; Do not display nodispl lines of it
|
||||
* int nlines; Number of screen lines that must be displayed
|
||||
* int really; Either 0 or 1
|
||||
*
|
||||
* Displays nlines as a page. if "really" = 0, the actual displaying is not
|
||||
* performed. Only the computing associated with it is done.
|
||||
*/
|
||||
|
||||
int scrollf();
|
||||
/*
|
||||
* int scrollf(nlines,really)
|
||||
* int nlines; Number of lines to scroll
|
||||
* int really; Either 0 or 1, see explanation above
|
||||
*
|
||||
* Scroll forwards "nlines" (screen)lines.
|
||||
*/
|
||||
|
||||
int scrollb();
|
||||
/*
|
||||
* int scrollb(nlines,really)
|
||||
* int nlines; Number of lines to scroll
|
||||
* int really; Either 0 or 1, see explanation above
|
||||
*
|
||||
* Scroll backwards "nlines" (screen)lines.
|
||||
*/
|
||||
|
||||
int tomark();
|
||||
/*
|
||||
* int tomark(cnt)
|
||||
* long cnt; (Argument ignored)
|
||||
*
|
||||
* Display a page starting at the mark. If there was no
|
||||
* mark, display the first page of the file.
|
||||
* (There is always assumed to be a mark, the initial one is on the first page
|
||||
* of the file).
|
||||
*/
|
||||
|
||||
int setmark();
|
||||
/*
|
||||
* int setmark(cnt)
|
||||
* long cnt; (Argument ignored)
|
||||
*
|
||||
* Sets a mark on the current page.
|
||||
* It returns nothing (but the address is taken ...)
|
||||
*/
|
||||
|
||||
int exgmark();
|
||||
/*
|
||||
* int exgmark(cnt)
|
||||
* long cnt; (Argumewnt ignored)
|
||||
*
|
||||
* Sets the mark on the current page and displays the
|
||||
* previously marked page.
|
||||
*/
|
||||
|
||||
VOID d_clean();
|
||||
/*
|
||||
* void d_clean()
|
||||
*
|
||||
* Clean up and initialize. To be called before displaying a new file
|
||||
*/
|
||||
|
||||
# undef PUBLIC
|
|
@ -1,313 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
/*
|
||||
* Command reader, also executes shell escapes
|
||||
*/
|
||||
|
||||
# ifndef lint
|
||||
static char rcsid[] = "$Header$";
|
||||
# endif
|
||||
|
||||
# define _GETCOMM_
|
||||
|
||||
# include <ctype.h>
|
||||
# include "in_all.h"
|
||||
# include "term.h"
|
||||
# include "process.h"
|
||||
# include "getcomm.h"
|
||||
# include "commands.h"
|
||||
# include "prompt.h"
|
||||
# include "main.h"
|
||||
# include "output.h"
|
||||
# include "getline.h"
|
||||
# include "machine.h"
|
||||
# include "keys.h"
|
||||
# include "display.h"
|
||||
# include "assert.h"
|
||||
|
||||
#if USG_OPEN
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#if POSIX_OPEN
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
char *strcpy(),
|
||||
*getenv();
|
||||
|
||||
STATIC int killchar();
|
||||
|
||||
/*
|
||||
* Read a line from the terminal, doing line editing.
|
||||
* The parameter s contains the prompt for the line.
|
||||
*/
|
||||
|
||||
char *
|
||||
readline(s) char *s; {
|
||||
|
||||
static char buf[80];
|
||||
register char *p = buf;
|
||||
register int ch;
|
||||
register int pos;
|
||||
|
||||
clrbline();
|
||||
putline(s);
|
||||
pos = strlen(s);
|
||||
while ((ch = getch()) != '\n' && ch != '\r') {
|
||||
if (ch == -1) {
|
||||
/*
|
||||
* Can only occur because of an interrupted read.
|
||||
*/
|
||||
ch = erasech;
|
||||
interrupt = 0;
|
||||
}
|
||||
if (ch == erasech) {
|
||||
/*
|
||||
* Erase last char
|
||||
*/
|
||||
if (p == buf) {
|
||||
/*
|
||||
* There was none, so return
|
||||
*/
|
||||
return (char *) 0;
|
||||
}
|
||||
pos -= killchar(*--p);
|
||||
if (*p != '\\') continue;
|
||||
}
|
||||
if (ch == killch) {
|
||||
/*
|
||||
* Erase the whole line
|
||||
*/
|
||||
if (!(p > buf && *(p-1) == '\\')) {
|
||||
while (p > buf) {
|
||||
pos -= killchar(*--p);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
pos -= killchar(*--p);
|
||||
}
|
||||
if (p > &buf[78] || pos >= COLS - 2) {
|
||||
/*
|
||||
* Line does not fit.
|
||||
* Simply refuse to make it any longer
|
||||
*/
|
||||
pos -= killchar(*--p);
|
||||
}
|
||||
*p++ = ch;
|
||||
if (ch < ' ' || ch >= 0177) {
|
||||
fputch('^');
|
||||
pos++;
|
||||
ch ^= 0100;
|
||||
}
|
||||
fputch(ch);
|
||||
pos++;
|
||||
}
|
||||
fputch('\r');
|
||||
*p++ = '\0';
|
||||
flush();
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Erase a character from the command line.
|
||||
*/
|
||||
|
||||
STATIC int
|
||||
killchar(c) {
|
||||
|
||||
backspace();
|
||||
putch(' ');
|
||||
backspace();
|
||||
if (c < ' ' || c >= 0177) {
|
||||
(VOID) killchar(' ');
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do a shell escape, after expanding '%' and '!'.
|
||||
*/
|
||||
|
||||
VOID
|
||||
shellescape(p, esc_char) register char *p; {
|
||||
|
||||
register char *p2; /* walks through command */
|
||||
register int id; /* procid of child */
|
||||
register int cnt; /* prevent array bound errors */
|
||||
register int lastc = 0; /* will contain the previous char */
|
||||
# ifdef SIGTSTP
|
||||
VOID (*savetstp)();
|
||||
# endif
|
||||
static char previous[256]; /* previous command */
|
||||
char comm[256]; /* space for command */
|
||||
int piped[2];
|
||||
|
||||
p2 = comm;
|
||||
*p2++ = esc_char;
|
||||
cnt = 253;
|
||||
while (*p) {
|
||||
/*
|
||||
* expand command
|
||||
*/
|
||||
switch(*p++) {
|
||||
case '!':
|
||||
/*
|
||||
* An unescaped ! expands to the previous
|
||||
* command, but disappears if there is none
|
||||
*/
|
||||
if (lastc != '\\') {
|
||||
if (*previous) {
|
||||
id = strlen(previous);
|
||||
if ((cnt -= id) <= 0) break;
|
||||
(VOID) strcpy(p2,previous);
|
||||
p2 += id;
|
||||
}
|
||||
}
|
||||
else {
|
||||
*(p2-1) = '!';
|
||||
}
|
||||
continue;
|
||||
case '%':
|
||||
/*
|
||||
* An unescaped % will expand to the current
|
||||
* filename, but disappears is there is none
|
||||
*/
|
||||
if (lastc != '\\') {
|
||||
if (nopipe) {
|
||||
id = strlen(currentfile);
|
||||
if ((cnt -= id) <= 0) break;
|
||||
(VOID) strcpy(p2,currentfile);
|
||||
p2 += id;
|
||||
}
|
||||
}
|
||||
else {
|
||||
*(p2-1) = '%';
|
||||
}
|
||||
continue;
|
||||
default:
|
||||
lastc = *(p-1);
|
||||
if (cnt-- <= 0) break;
|
||||
*p2++ = lastc;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
clrbline();
|
||||
*p2 = '\0';
|
||||
if (!stupid) {
|
||||
/*
|
||||
* Display expanded command
|
||||
*/
|
||||
cputline(comm);
|
||||
putline("\r\n");
|
||||
}
|
||||
flush();
|
||||
(VOID) strcpy(previous,comm + 1);
|
||||
resettty();
|
||||
if (esc_char == '|' && pipe(piped) < 0) {
|
||||
error("Cannot create pipe");
|
||||
return;
|
||||
}
|
||||
if ((id = fork()) < 0) {
|
||||
error("Cannot fork");
|
||||
return;
|
||||
}
|
||||
if (id == 0) {
|
||||
/*
|
||||
* Close files, as child might need the file descriptors
|
||||
*/
|
||||
cls_files();
|
||||
if (esc_char == '|') {
|
||||
close(piped[1]);
|
||||
#if USG_OPEN || POSIX_OPEN
|
||||
close(0);
|
||||
fcntl(piped[0], F_DUPFD, 0);
|
||||
#else
|
||||
dup2(piped[0], 0);
|
||||
#endif
|
||||
close(piped[0]);
|
||||
}
|
||||
execl("/bin/sh", "sh", "-c", comm + 1, (char *) 0);
|
||||
exit(1);
|
||||
}
|
||||
(VOID) signal(SIGINT,SIG_IGN);
|
||||
(VOID) signal(SIGQUIT,SIG_IGN);
|
||||
# ifdef SIGTSTP
|
||||
if ((savetstp = signal(SIGTSTP,SIG_IGN)) != SIG_IGN) {
|
||||
(VOID) signal(SIGTSTP,SIG_DFL);
|
||||
}
|
||||
# endif
|
||||
if (esc_char == '|') {
|
||||
(VOID) close(piped[0]);
|
||||
(VOID) signal(SIGPIPE, SIG_IGN);
|
||||
wrt_fd(piped[1]);
|
||||
(VOID) close(piped[1]);
|
||||
}
|
||||
while ((lastc = wait((int *) 0)) != id && lastc >= 0) {
|
||||
/*
|
||||
* Wait for child, making sure it is the one we expected ...
|
||||
*/
|
||||
}
|
||||
(VOID) signal(SIGINT,catchdel);
|
||||
(VOID) signal(SIGQUIT,quit);
|
||||
# ifdef SIGTSTP
|
||||
(VOID) signal(SIGTSTP, savetstp);
|
||||
# endif
|
||||
inittty();
|
||||
}
|
||||
|
||||
/*
|
||||
* Get all those commands ...
|
||||
*/
|
||||
|
||||
int
|
||||
getcomm (plong) long *plong; {
|
||||
int c;
|
||||
long count;
|
||||
char *p;
|
||||
int i;
|
||||
int j;
|
||||
char buf[10];
|
||||
|
||||
for (;;) {
|
||||
count = 0;
|
||||
give_prompt();
|
||||
while (isdigit((c = getch()))) {
|
||||
count = count * 10 + (c - '0');
|
||||
}
|
||||
*plong = count;
|
||||
p = buf;
|
||||
for (;;) {
|
||||
if (c == -1) {
|
||||
/*
|
||||
* This should never happen, but it does,
|
||||
* when the user gives a TSTP signal (^Z) or
|
||||
* an interrupt while the program is trying
|
||||
* to read a character from the terminal.
|
||||
* In this case, the read is interrupted, so
|
||||
* we end up here.
|
||||
* Right, we will have to read again.
|
||||
*/
|
||||
if (interrupt) return 1;
|
||||
break;
|
||||
}
|
||||
*p++ = c;
|
||||
*p = 0;
|
||||
if ((i = match(buf, &j, currmap->k_mach)) > 0) {
|
||||
/*
|
||||
* The key sequence matched. We have a command
|
||||
*/
|
||||
return j;
|
||||
}
|
||||
if (i == 0) return 0;
|
||||
/*
|
||||
* We have a prefix of a command.
|
||||
*/
|
||||
assert(i == FSM_ISPREFIX);
|
||||
c = getch();
|
||||
}
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
# ifndef _GETCOMM_
|
||||
# define PUBLIC extern
|
||||
# else
|
||||
# define PUBLIC
|
||||
# endif
|
||||
|
||||
int getcomm();
|
||||
/*
|
||||
* int getcomm()
|
||||
*
|
||||
* Reads commands given by the user. The command is returned.
|
||||
*/
|
||||
|
||||
VOID shellescape();
|
||||
/*
|
||||
* void shellescape(command)
|
||||
* char *command; The shell command to be executed
|
||||
*
|
||||
* Expands '%' and '!' in the command "command" to the current filename
|
||||
* and the previous command respectively, and then executes "command".
|
||||
*/
|
||||
|
||||
char * readline();
|
||||
/*
|
||||
* char * readline(prompt)
|
||||
* char *prompt; Prompt given to the user
|
||||
*
|
||||
* Gives a prompt "prompt" and reads a line to be typed in by the user.
|
||||
* A pointer to this line is returned. Space for this line is static.
|
||||
*/
|
||||
|
||||
# undef PUBLIC
|
|
@ -1,722 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
# ifndef lint
|
||||
static char rcsid[] = "$Header$";
|
||||
# endif
|
||||
|
||||
# define _GETLINE_
|
||||
|
||||
# include <errno.h>
|
||||
# include "in_all.h"
|
||||
# include "getline.h"
|
||||
# include "options.h"
|
||||
# include "process.h"
|
||||
# include "term.h"
|
||||
# include "main.h"
|
||||
# include "display.h"
|
||||
# include "output.h"
|
||||
# include "assert.h"
|
||||
|
||||
extern int errno;
|
||||
|
||||
# define BLOCKSIZE 2048 /* size of blocks */
|
||||
# define CHUNK 50 /* # of blockheaders allocated at a time */
|
||||
|
||||
/*
|
||||
* The blockheaders of the blocks that are in core are kept in a linked list.
|
||||
* The last added block is indicated by b_head,
|
||||
* the tail of the list is indicated by b_tail.
|
||||
* The links go from b_tail to b_head.
|
||||
* The blockheaders are all in an array, in the order of the line numbers.
|
||||
* Also, the blockheaders must always be in core, so they have to be rather
|
||||
* small. On systems with a small address space, yap can run out of core,
|
||||
* and panic. However, this should only happen with very large files (>> 1M).
|
||||
*/
|
||||
|
||||
struct block {
|
||||
int b_flags; /* Contains the following flags: */
|
||||
# define DUMPED 01 /* block dumped on temporary file */
|
||||
# define PARTLY 02 /* block not filled completely (eof) */
|
||||
int b_next; /* ptr in linked list */
|
||||
long b_end; /* line number of last line in block */
|
||||
char * b_info; /* the block */
|
||||
int * b_offs; /* line offsets within the block */
|
||||
long b_foff; /* offset of block in file */
|
||||
};
|
||||
|
||||
static struct block * blocklist, /* beginning of the list of blocks */
|
||||
* maxblocklist, /* first free entry in the list */
|
||||
* topblocklist; /* end of allocated core for the list */
|
||||
static int b_head,
|
||||
b_tail;
|
||||
static int tfdes, ifdes; /* File descriptors for temporary's */
|
||||
static long lastreadline; /* lineno of last line read */
|
||||
static int ENDseen;
|
||||
|
||||
STATIC VOID readblock();
|
||||
STATIC VOID nextblock();
|
||||
STATIC char *re_alloc();
|
||||
|
||||
STATIC struct block *
|
||||
new_block()
|
||||
{
|
||||
register struct block *pblock = maxblocklist - 1;
|
||||
|
||||
if (!maxblocklist || !(pblock->b_flags & PARTLY)) {
|
||||
/*
|
||||
* There is no last block, or it was filled completely,
|
||||
* so allocate a new blockheader.
|
||||
*/
|
||||
register int siz;
|
||||
|
||||
pblock = blocklist;
|
||||
if (maxblocklist == topblocklist) {
|
||||
/*
|
||||
* No blockheaders left. Allocate new ones
|
||||
*/
|
||||
siz = topblocklist - pblock;
|
||||
blocklist = pblock = (struct block *)
|
||||
re_alloc((char *) pblock,
|
||||
(unsigned) (siz * sizeof(*pblock)),
|
||||
(unsigned) ((siz + CHUNK) * sizeof(*pblock)));
|
||||
pblock += siz;
|
||||
topblocklist = pblock + CHUNK;
|
||||
maxblocklist = pblock;
|
||||
for (; pblock < topblocklist; pblock++) {
|
||||
pblock->b_end = 0;
|
||||
pblock->b_info = 0;
|
||||
pblock->b_flags = 0;
|
||||
}
|
||||
if (!siz) {
|
||||
/*
|
||||
* Create dummy header cell.
|
||||
*/
|
||||
maxblocklist++;
|
||||
}
|
||||
}
|
||||
pblock = maxblocklist++;
|
||||
}
|
||||
nextblock(pblock);
|
||||
return pblock;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the block in which line 'n' of the current file can be found.
|
||||
* If "disable_interrupt" = 0, the call may be interrupted, in which
|
||||
* case it returns 0.
|
||||
*/
|
||||
|
||||
STATIC struct block *
|
||||
getblock(n, disable_interrupt) register long n; {
|
||||
register struct block * pblock;
|
||||
|
||||
if (stdf < 0) {
|
||||
/*
|
||||
* Not file descriptor, so return end of file
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
pblock = maxblocklist - 1;
|
||||
if (n < lastreadline ||
|
||||
(n == lastreadline && !(pblock->b_flags & PARTLY))) {
|
||||
/*
|
||||
* The line asked for has been read already.
|
||||
* Perform binary search in the blocklist to find the block
|
||||
* where it's in.
|
||||
*/
|
||||
register struct block *min, *mid;
|
||||
|
||||
min = blocklist + 1;
|
||||
do {
|
||||
mid = min + (pblock - min) / 2;
|
||||
if (n > mid->b_end) {
|
||||
min = mid + 1;
|
||||
}
|
||||
else pblock = mid;
|
||||
} while (min < pblock);
|
||||
/* Found, pblock is now a reference to the block wanted */
|
||||
if (!pblock->b_info) readblock(pblock);
|
||||
return pblock;
|
||||
}
|
||||
|
||||
/*
|
||||
* The line was'nt read yet, so read blocks until found
|
||||
*/
|
||||
for (;;) {
|
||||
if (interrupt && !disable_interrupt) return 0;
|
||||
pblock = new_block();
|
||||
if (pblock->b_end >= n) {
|
||||
return pblock;
|
||||
}
|
||||
if (pblock->b_flags & PARTLY) {
|
||||
/*
|
||||
* We did not find it, and the last block could not be
|
||||
* read completely, so return 0;
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
char *
|
||||
getline(n, disable_interrupt) long n; {
|
||||
register struct block *pblock;
|
||||
|
||||
if (!(pblock = getblock(n, disable_interrupt))) {
|
||||
return (char *) 0;
|
||||
}
|
||||
return pblock->b_info + pblock->b_offs[n - ((pblock-1)->b_end + 1)];
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the last line of the input, and return its number
|
||||
*/
|
||||
|
||||
long
|
||||
to_lastline() {
|
||||
|
||||
for (;;) {
|
||||
if (!getline(lastreadline + 1, 0)) {
|
||||
/*
|
||||
* "lastreadline" always contains the linenumber of
|
||||
* the last line read. So, if the call to getline
|
||||
* succeeds, "lastreadline" is affected
|
||||
*/
|
||||
if (interrupt) return -1L;
|
||||
return lastreadline;
|
||||
}
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
#if MAXNBLOCKS
|
||||
int nblocks; /* Count number of large blocks */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Allocate some memory. If unavailable, free some and try again.
|
||||
* If all fails, panic.
|
||||
*/
|
||||
|
||||
char *
|
||||
alloc(size, isblock) unsigned size; {
|
||||
|
||||
register char *pmem;
|
||||
register struct block *pblock, *bllist;
|
||||
char *malloc();
|
||||
long lseek();
|
||||
register long i;
|
||||
|
||||
bllist = blocklist;
|
||||
while (
|
||||
#if MAXNBLOCKS
|
||||
(isblock && nblocks >= MAXNBLOCKS) ||
|
||||
#endif
|
||||
!(pmem = malloc(size)) /* No space */
|
||||
) {
|
||||
if (b_tail == 0) {
|
||||
/*
|
||||
* Also, no blocks in core. Pity
|
||||
*/
|
||||
panic("No core");
|
||||
}
|
||||
#if MAXNBLOCKS
|
||||
nblocks--;
|
||||
#endif
|
||||
pblock = bllist + b_tail;
|
||||
b_tail = pblock->b_next;
|
||||
if (!nopipe && !(pblock->b_flags & DUMPED)) {
|
||||
/*
|
||||
* Dump the block on a temporary file
|
||||
*/
|
||||
if (!tfdes) {
|
||||
/*
|
||||
* create and open temporary files
|
||||
*/
|
||||
tfdes = opentemp(0);
|
||||
ifdes = opentemp(1);
|
||||
}
|
||||
pblock->b_flags |= DUMPED;
|
||||
/*
|
||||
* Find out where to dump the block, and dump it
|
||||
*/
|
||||
i = (pblock-1)->b_end * sizeof(int);
|
||||
(VOID) lseek(tfdes,
|
||||
((long) BLOCKSIZE * (pblock - bllist)), 0);
|
||||
if (write(tfdes, pblock->b_info, BLOCKSIZE)
|
||||
!= BLOCKSIZE) {
|
||||
panic("write failed");
|
||||
}
|
||||
/*
|
||||
* Also dump the offsets of the lines in the block
|
||||
*/
|
||||
(VOID) lseek(ifdes, i, 0);
|
||||
i = pblock->b_end * sizeof(int) - i;
|
||||
if (write(ifdes, (char *) pblock->b_offs, (int) i)
|
||||
!= (int) i) {
|
||||
panic("Write failed");
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Now that the block is dumped, the space taken by it can
|
||||
* be freed
|
||||
*/
|
||||
free((char *) pblock->b_offs);
|
||||
free(pblock->b_info);
|
||||
pblock->b_info = (char *) 0;
|
||||
}
|
||||
#if MAXNBLOCKS
|
||||
if (isblock) nblocks++;
|
||||
#endif
|
||||
return pmem;
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-allocate the memorychunk pointed to by ptr, to let it
|
||||
* grow or shrink.
|
||||
* realloc of the standard C library is useless, as it is destructive
|
||||
* if the malloc fails.
|
||||
*/
|
||||
|
||||
STATIC char *
|
||||
re_alloc(ptr,oldsize, newsize)
|
||||
char *ptr; unsigned oldsize; unsigned newsize; {
|
||||
register char *pmem;
|
||||
register char *c1, *c2;
|
||||
|
||||
/*
|
||||
* We could be smarter here, by checking if newsize < oldsize, and in
|
||||
* that case using realloc, but this depends on realloc using the
|
||||
* same block if the block shrinks. The question is, wether all
|
||||
* reallocs in the world do this.
|
||||
*/
|
||||
pmem = alloc(newsize, 0);
|
||||
if (oldsize) {
|
||||
/*
|
||||
* This test makes re_alloc also work if there was no old block
|
||||
*/
|
||||
c1 = pmem;
|
||||
c2 = ptr;
|
||||
if (newsize > oldsize) {
|
||||
newsize = oldsize;
|
||||
}
|
||||
while (newsize--) {
|
||||
*c1++ = *c2++;
|
||||
}
|
||||
free(ptr);
|
||||
}
|
||||
return pmem;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append a block to the linked list of blockheaders of blocks that are
|
||||
* in core.
|
||||
*/
|
||||
|
||||
STATIC VOID
|
||||
addtolist(pblock) register struct block *pblock; {
|
||||
register struct block *bllist = blocklist;
|
||||
|
||||
pblock->b_next = 0;
|
||||
(bllist + b_head)->b_next = pblock - bllist;
|
||||
b_head = pblock - bllist;
|
||||
if (!b_tail) {
|
||||
/*
|
||||
* The list was empty, initialize
|
||||
*/
|
||||
b_tail = b_head;
|
||||
}
|
||||
}
|
||||
|
||||
static char *saved;
|
||||
static long filldegree;
|
||||
|
||||
/*
|
||||
* Try to read the block indicated by pblock
|
||||
*/
|
||||
|
||||
STATIC VOID
|
||||
nextblock(pblock) register struct block *pblock; {
|
||||
register char *c, /* Run through pblock->b_info */
|
||||
*c1; /* indicate end of pblock->b_info */
|
||||
register int *poff; /* pointer in line-offset list */
|
||||
register int cnt; /* # of characters read */
|
||||
register unsigned siz; /* Size of allocated line-offset list */
|
||||
static unsigned savedsiz; /* saved "siz" */
|
||||
static int *savedpoff; /* saved "poff" */
|
||||
static char *savedc1; /* saved "c1" */
|
||||
|
||||
if (pblock->b_flags & PARTLY) {
|
||||
/*
|
||||
* The block was already partly filled. Initialize locals
|
||||
* accordingly
|
||||
*/
|
||||
poff = savedpoff;
|
||||
siz = savedsiz;
|
||||
pblock->b_flags = 0;
|
||||
c1 = savedc1;
|
||||
if (c1 == pblock->b_info || *(c1 - 1)) {
|
||||
/*
|
||||
* We had incremented "lastreadline" temporarily,
|
||||
* because the last line could not be completely read
|
||||
* last time we tried. Undo this increment
|
||||
*/
|
||||
poff--;
|
||||
--lastreadline;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (nopipe) pblock->b_foff = lseek(stdf, 0L, 1);
|
||||
if (saved) {
|
||||
/*
|
||||
* There were leftovers from the previous block
|
||||
*/
|
||||
pblock->b_info = saved;
|
||||
if (nopipe) pblock->b_foff -= savedc1 - saved;
|
||||
c1 = savedc1;
|
||||
saved = 0;
|
||||
}
|
||||
else { /* Allocate new block */
|
||||
pblock->b_info = c1 = alloc(BLOCKSIZE + 1, 1);
|
||||
}
|
||||
/*
|
||||
* Allocate some space for line-offsets
|
||||
*/
|
||||
pblock->b_offs = poff = (int *)
|
||||
alloc((unsigned) (100 * sizeof(int)), 0);
|
||||
siz = 99;
|
||||
*poff++ = 0;
|
||||
}
|
||||
c = c1;
|
||||
for (;;) {
|
||||
/*
|
||||
* Read loop
|
||||
*/
|
||||
cnt = read(stdf, c1, BLOCKSIZE - (c1 - pblock->b_info));
|
||||
if (cnt < 0) {
|
||||
/*
|
||||
* Interrupted read
|
||||
*/
|
||||
if (errno == EINTR) continue;
|
||||
error("Could not read input file");
|
||||
cnt = 0;
|
||||
}
|
||||
c1 += cnt;
|
||||
if (c1 != pblock->b_info + BLOCKSIZE) {
|
||||
ENDseen = 1;
|
||||
pblock->b_flags |= PARTLY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
assert(c <= c1);
|
||||
while (c < c1) {
|
||||
/*
|
||||
* Now process the block
|
||||
*/
|
||||
*c &= 0177; /* Most significant bit ignored */
|
||||
if (*c == '\n') {
|
||||
/*
|
||||
* Newlines are replaced by '\0', so that "getline"
|
||||
* can deliver one line at a time
|
||||
*/
|
||||
*c = 0;
|
||||
lastreadline++;
|
||||
/*
|
||||
* Remember the line-offset
|
||||
*/
|
||||
if (poff == pblock->b_offs + siz) {
|
||||
/*
|
||||
* No space for it, allocate some more
|
||||
*/
|
||||
pblock->b_offs = (int *)
|
||||
re_alloc((char *) pblock->b_offs,
|
||||
(siz+1) * sizeof(int),
|
||||
(siz + 51) * sizeof(int));
|
||||
poff = pblock->b_offs + siz;
|
||||
siz += 50;
|
||||
}
|
||||
*poff++ = c - pblock->b_info + 1;
|
||||
}
|
||||
else if (*c == '\0') {
|
||||
/*
|
||||
* 0-bytes are replaced by 0200, because newlines are
|
||||
* replaced by 0, and 0200 & 0177 gives again 0 ...
|
||||
*/
|
||||
*c = 0200;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
assert(c==c1);
|
||||
*c = 0;
|
||||
if (c != pblock->b_info && *(c-1) != 0) {
|
||||
/*
|
||||
* The last line read does not end with a newline, so add one
|
||||
*/
|
||||
lastreadline++;
|
||||
*poff++ = c - pblock->b_info + 1;
|
||||
if (!(pblock->b_flags & PARTLY) && *(poff - 2) != 0) {
|
||||
/*
|
||||
* Save the started line; it will be in the next block.
|
||||
* Remove the newline we added just now.
|
||||
*/
|
||||
saved = c1 = alloc(BLOCKSIZE + 1, 1);
|
||||
c = pblock->b_info + *(--poff - 1);
|
||||
while (*c) *c1++ = *c++;
|
||||
c = pblock->b_info + *(poff - 1);
|
||||
savedc1 = c1;
|
||||
--lastreadline;
|
||||
}
|
||||
}
|
||||
pblock->b_end = lastreadline;
|
||||
if (pblock->b_flags & PARTLY) {
|
||||
/*
|
||||
* Take care, that we can call "nextblock" again, to fill in
|
||||
* the rest of this block
|
||||
*/
|
||||
savedsiz = siz;
|
||||
savedpoff = poff;
|
||||
savedc1 = c;
|
||||
if (c == pblock->b_info) {
|
||||
lastreadline++;
|
||||
pblock->b_end = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Not completely read blocks are not in the linked list,
|
||||
* so can never be "swapped out".
|
||||
*/
|
||||
addtolist(pblock);
|
||||
cnt = pblock - blocklist;
|
||||
filldegree = ((c-pblock->b_info) + (cnt-1) * filldegree) / cnt;
|
||||
}
|
||||
assert(pblock->b_end - (pblock-1)->b_end <= poff - pblock->b_offs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate core for the block, and read it back from
|
||||
* the temporary file.
|
||||
*/
|
||||
|
||||
STATIC VOID
|
||||
readblock(pblock) register struct block *pblock; {
|
||||
|
||||
register int size;
|
||||
register long i;
|
||||
|
||||
/*
|
||||
* Find out where the block is, and read it
|
||||
*/
|
||||
pblock->b_info = alloc(BLOCKSIZE + 1, 1);
|
||||
i = (pblock - 1)->b_end * sizeof(int);
|
||||
size = (int) (pblock->b_end * sizeof(int) - i);
|
||||
pblock->b_offs = (int *) alloc((unsigned) size, 0);
|
||||
if (nopipe) {
|
||||
register char *c;
|
||||
register int line_index;
|
||||
int cnt;
|
||||
long l = lseek(stdf, 0L, 1);
|
||||
|
||||
(VOID) lseek(stdf, pblock->b_foff, 0);
|
||||
cnt = read(stdf, pblock->b_info, BLOCKSIZE);
|
||||
(VOID) lseek(stdf, l, 0);
|
||||
c = pblock->b_info;
|
||||
pblock->b_offs[0] = 0;
|
||||
line_index = 1;
|
||||
size /= sizeof(int);
|
||||
while (c < pblock->b_info + cnt) {
|
||||
*c &= 0177;
|
||||
if (*c == '\n') {
|
||||
*c = '\0';
|
||||
if (line_index < size)
|
||||
pblock->b_offs[line_index++] =
|
||||
(c - pblock->b_info) + 1;
|
||||
}
|
||||
else if (*c == '\0') *c = 0200;
|
||||
c++;
|
||||
}
|
||||
*c = '\0';
|
||||
}
|
||||
else {
|
||||
(VOID) lseek(tfdes, (long) ((long) BLOCKSIZE * (pblock - blocklist)),0);
|
||||
if (read(tfdes, pblock->b_info,BLOCKSIZE) != BLOCKSIZE) {
|
||||
panic("read error");
|
||||
}
|
||||
/*
|
||||
* Find out where the line-offset list is, and read it
|
||||
*/
|
||||
(VOID) lseek(ifdes, i, 0);
|
||||
if (read(ifdes, (char *) pblock->b_offs, size) != size) {
|
||||
panic("read error");
|
||||
}
|
||||
pblock->b_info[BLOCKSIZE] = '\0';
|
||||
}
|
||||
/*
|
||||
* Add this block to the list of incore blocks
|
||||
*/
|
||||
addtolist(pblock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called after processing a file.
|
||||
* Free all core.
|
||||
*/
|
||||
|
||||
VOID
|
||||
do_clean() {
|
||||
|
||||
register struct block *pblock;
|
||||
register char *p;
|
||||
|
||||
for (pblock = blocklist; pblock < maxblocklist; pblock++) {
|
||||
if (p = pblock->b_info) {
|
||||
free(p);
|
||||
free((char *) pblock->b_offs);
|
||||
}
|
||||
}
|
||||
if (p = (char *) blocklist) {
|
||||
free(p);
|
||||
}
|
||||
blocklist = 0;
|
||||
maxblocklist = 0;
|
||||
topblocklist = 0;
|
||||
lastreadline = 0;
|
||||
filldegree = 0;
|
||||
ENDseen = 0;
|
||||
if (p = saved) free(p);
|
||||
saved = 0;
|
||||
b_head = 0;
|
||||
b_tail = 0;
|
||||
# if MAXNBLOCKS
|
||||
nblocks = 0;
|
||||
# endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Close a file with file-descriptor "file", if it indeed is one
|
||||
*/
|
||||
|
||||
STATIC VOID
|
||||
cls(file) {
|
||||
if (file) (VOID) close(file);
|
||||
}
|
||||
|
||||
/*
|
||||
* Close all files
|
||||
*/
|
||||
|
||||
VOID
|
||||
cls_files() {
|
||||
|
||||
cls(tfdes);
|
||||
cls(ifdes);
|
||||
cls(stdf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a character. If possible, do some workahead.
|
||||
*/
|
||||
|
||||
int
|
||||
getch() {
|
||||
# if USG_OPEN
|
||||
# include <fcntl.h>
|
||||
# include <sys/stat.h>
|
||||
|
||||
register int i,j;
|
||||
struct stat buf;
|
||||
# else
|
||||
# ifdef FIONREAD
|
||||
# include <sys/stat.h>
|
||||
|
||||
struct stat buf;
|
||||
long i;
|
||||
# endif
|
||||
# endif
|
||||
|
||||
char c;
|
||||
int retval;
|
||||
|
||||
flush();
|
||||
if (startcomm) {
|
||||
/*
|
||||
* Command line option command
|
||||
*/
|
||||
if (*startcomm) return *startcomm++;
|
||||
return '\n';
|
||||
}
|
||||
# if USG_OPEN
|
||||
if (stdf >= 0) {
|
||||
/*
|
||||
* Make reads from the terminal non-blocking, so that
|
||||
* we can see if the user typed something
|
||||
*/
|
||||
i = fcntl(0,F_GETFL,0);
|
||||
if (i != -1 && fcntl(0, F_SETFL, i|O_NDELAY) != -1) {
|
||||
j = 0;
|
||||
while (! ENDseen &&
|
||||
((j = read(0,&c,1)) == 0
|
||||
#ifdef EWOULDBLOCK
|
||||
|| (j < 0 && errno == EWOULDBLOCK)
|
||||
#endif
|
||||
)
|
||||
&&
|
||||
(nopipe ||
|
||||
(fstat(stdf,&buf) >= 0 && buf.st_size > 0))) {
|
||||
/*
|
||||
* Do some read ahead, after making sure there
|
||||
* is input and the user did not type a command
|
||||
*/
|
||||
new_block();
|
||||
}
|
||||
(VOID) fcntl(0,F_SETFL,i);
|
||||
if (j < 0) {
|
||||
/*
|
||||
* Could this have happened?
|
||||
* I'm not sure, because the read is
|
||||
* nonblocking. Can it be interrupted then?
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
if (j > 0) return c;
|
||||
}
|
||||
}
|
||||
# else
|
||||
# ifdef FIONREAD
|
||||
if (stdf >= 0) {
|
||||
/*
|
||||
* See if there are any characters waiting in the terminal input
|
||||
* queue. If there are not, read ahead.
|
||||
*/
|
||||
while (! ENDseen &&
|
||||
( ioctl(0, FIONREAD, (char *) &i) >= 0 && i == 0) &&
|
||||
( nopipe || fstat(stdf,&buf) >= 0 && buf.st_size > 0)) {
|
||||
/*
|
||||
* While the user does'nt type anything, and there is
|
||||
* input to be processed, work ahead
|
||||
*/
|
||||
if (interrupt) return -1;
|
||||
new_block();
|
||||
}
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
if (read(0,&c,1) <= 0) retval = -1; else retval = c & 0177;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the position of line "ln" in the file.
|
||||
*/
|
||||
|
||||
long
|
||||
getpos(ln) long ln; {
|
||||
register struct block *pblock;
|
||||
register long i;
|
||||
|
||||
pblock = getblock(ln,1);
|
||||
assert(pblock != 0);
|
||||
i = filldegree * (pblock - blocklist);
|
||||
return i - (filldegree - pblock->b_offs[ln - (pblock-1)->b_end]);
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
# ifndef _GETLINE_
|
||||
# define PUBLIC extern
|
||||
# else
|
||||
# define PUBLIC
|
||||
# endif
|
||||
|
||||
char * getline();
|
||||
/*
|
||||
* char * getline(ln,disable_interrupt)
|
||||
* long ln; The line number of the line to be returned
|
||||
* int disable_interrupt; 1 if interrupts must be ignored, 0 otherwise
|
||||
*
|
||||
* Returns a pointer to the line with linenumber "ln".
|
||||
* It returns 0 if
|
||||
* - there was an interrupt, and interrupts were not disabled, or
|
||||
* - there is no line with linenumber "ln".
|
||||
*/
|
||||
|
||||
char * alloc();
|
||||
/*
|
||||
* char * alloc(size, isblock)
|
||||
* unsigned size; The size in bytes
|
||||
* int isblock; Flag indicating whether this is a file-text
|
||||
* block
|
||||
*
|
||||
* Return a pointer to a block of "size" bytes.
|
||||
* Panics if no core can be found.
|
||||
*/
|
||||
|
||||
VOID do_clean();
|
||||
/*
|
||||
* void do_clean()
|
||||
*
|
||||
* Cleans up and initializes.
|
||||
*/
|
||||
|
||||
VOID cls_files();
|
||||
/*
|
||||
* void cls_files()
|
||||
*
|
||||
* Closes files. Useful for shell escapes.
|
||||
*/
|
||||
|
||||
int getch();
|
||||
/*
|
||||
* int getch()
|
||||
*
|
||||
* Get a character from input or command option line (only at start up).
|
||||
* Some systems allow us to do some workahead while the user is
|
||||
* thinking/reading. Use this to get parts of the input file in core.
|
||||
*/
|
||||
|
||||
long to_lastline();
|
||||
/*
|
||||
* long to_lastline()
|
||||
*
|
||||
* Finds the last line of the file, and returns its number.
|
||||
* This command can be interrupted, in which case it returns 0.
|
||||
*/
|
||||
|
||||
long getpos();
|
||||
/*
|
||||
* long getpos(line);
|
||||
*
|
||||
* get offset of line "line" in the input
|
||||
*/
|
||||
# undef PUBLIC
|
|
@ -1,107 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Header$";
|
||||
#endif
|
||||
|
||||
#define _HELP_
|
||||
#include "in_all.h"
|
||||
#include "help.h"
|
||||
#include "machine.h"
|
||||
#include "commands.h"
|
||||
#include "keys.h"
|
||||
#include "output.h"
|
||||
#include "prompt.h"
|
||||
#include "main.h"
|
||||
#include "display.h"
|
||||
#include "term.h"
|
||||
#include "options.h"
|
||||
|
||||
static int h_cnt; /* Count # of lines */
|
||||
static struct state *origin; /* Keep track of startstate */
|
||||
|
||||
/*
|
||||
* Print a key sequence.
|
||||
* We arrived at an endstate. The s_next link in the state structure now
|
||||
* leads us from "origin" to the current state, so that we can print the key
|
||||
* sequence easily.
|
||||
*/
|
||||
|
||||
STATIC VOID
|
||||
pr_comm() {
|
||||
register struct state *p = origin;
|
||||
register char *pb;
|
||||
register int c;
|
||||
char buf[30];
|
||||
register int i = 0; /* How many characters printed? */
|
||||
|
||||
pb = buf;
|
||||
for (;;) {
|
||||
c = p->s_char & 0177;
|
||||
if (c < ' ' || c == 0177) {
|
||||
/*
|
||||
* Will take an extra position
|
||||
*/
|
||||
i++;
|
||||
}
|
||||
*pb++ = c;
|
||||
i++;
|
||||
if (!p->s_match) break;
|
||||
p = p->s_next;
|
||||
}
|
||||
do {
|
||||
*pb++ = ' ';
|
||||
} while (++i < 12);
|
||||
*pb = 0;
|
||||
cputline(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print out a description of the keymap. This is done, by temporarily using
|
||||
* the s_next field in the state structure indicate the state matching the
|
||||
* next character, so that we can walk from "origin" to an endstate.
|
||||
*/
|
||||
|
||||
STATIC VOID
|
||||
pr_mach(currstate, back) register struct state *currstate, *back; {
|
||||
struct state *save;
|
||||
|
||||
while (currstate) {
|
||||
if (interrupt) break;
|
||||
if (back) {
|
||||
save = back->s_next; /* Save original link */
|
||||
back->s_next = currstate;
|
||||
}
|
||||
if (!currstate->s_match) {
|
||||
/*
|
||||
* End state, print command
|
||||
*/
|
||||
pr_comm();
|
||||
putline(commands[currstate->s_cnt].c_descr);
|
||||
putline("\r\n");
|
||||
if (++h_cnt >= maxpagesize) {
|
||||
ret_to_continue();
|
||||
h_cnt = 0;
|
||||
}
|
||||
}
|
||||
else pr_mach(currstate->s_match, currstate);
|
||||
currstate = currstate->s_next;
|
||||
if (back) back->s_next = save; /* restore */
|
||||
else origin = currstate;
|
||||
}
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
do_help(i) long i; { /* The help command */
|
||||
|
||||
startcomm = 0;
|
||||
h_cnt = 2;
|
||||
putline("\r\nSummary of yap commands:\r\n");
|
||||
origin = currmap->k_mach;
|
||||
pr_mach(currmap->k_mach, (struct state *) 0);
|
||||
if (h_cnt) {
|
||||
ret_to_continue();
|
||||
}
|
||||
if (!hardcopy && scr_info.currentpos) redraw(1);
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
# ifndef _HELP_
|
||||
# define PUBLIC extern
|
||||
# else
|
||||
# define PUBLIC
|
||||
# endif
|
||||
|
||||
int do_help();
|
||||
/*
|
||||
* int do_help(cnt);
|
||||
* long cnt; This is ignored, but a count is given
|
||||
* to any command
|
||||
*
|
||||
* Give a summary of commands
|
||||
*/
|
||||
|
||||
# undef PUBLIC
|
|
@ -1,89 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
#define DO_ASSERT 0 /* define when debugging */
|
||||
# ifdef DO_ASSERT
|
||||
# define STATIC
|
||||
# else
|
||||
# define STATIC static
|
||||
# endif
|
||||
|
||||
#define VOID void /* preferably void, but int if your compiler does
|
||||
not recognize void
|
||||
*/
|
||||
|
||||
#if _POSIX_SOURCE
|
||||
#define POSIX_OPEN 1 /* POSIX "open" system call */
|
||||
#else
|
||||
#define USG_OPEN 0 /* USG "open" system call (include <fcntl.h>) */
|
||||
#define BSD4_2_OPEN 0 /* BSD 4.2 "open" system call (include <sys/file.h>)*/
|
||||
#endif
|
||||
|
||||
/* Sanity check 1 */
|
||||
# if (!!USG_OPEN) + (!!BSD4_2_OPEN) + (!!POSIX_OPEN) > 1
|
||||
Oops, now why did you do that?
|
||||
O, never mind, just try it again with
|
||||
USG_OPEN = 1 or for System III, System V etc.
|
||||
BSD4_2_OPEN = 1 or for Berkeley 4.2, Ultrix etc.
|
||||
POSIX_OPEN = 1 or for POSIX compliant systems.
|
||||
USG_OPEN = 0 and BSD4_2_OPEN = 0 and POSIX_OOPEN
|
||||
for Berkeley 4.1, v7 and whatever else
|
||||
# endif
|
||||
|
||||
#define BSD_REGEX 0 /* Berkeley style re_comp/re_exec */
|
||||
#define V8_REGEX 1 /* V8 style regexec/regcomp */
|
||||
#define USG_REGEX 0 /* USG style regex/regcmp */
|
||||
|
||||
/* Sanity check 2 */
|
||||
# if USG_REGEX + BSD_REGEX + V8_REGEX > 1
|
||||
Select one style for the regular expressions please!
|
||||
# endif
|
||||
|
||||
#define USG_TTY 0 /* define if you have an USG tty driver (termio) */
|
||||
/* If you do not define this, you get either the
|
||||
* V7 tty driver or the BSD one.
|
||||
*/
|
||||
#if _POSIX_SOURCE
|
||||
#define POSIX_TTY 1
|
||||
#endif
|
||||
|
||||
#if __minix && !__minix_vmd
|
||||
#define MAXNBLOCKS 10 /* Limit the number of blocks that yap will use to keep
|
||||
* the input in core.
|
||||
* This was needed to let yap run on an IBM XT
|
||||
* running PC/IX. The problem is that malloc can
|
||||
* allocate almost all available space, leaving no
|
||||
* space for the stack, which causes a memory fault.
|
||||
* Internal yap blocks are 2K, but there is a lot of
|
||||
* additional information that yap keeps around. You
|
||||
* can also use it if you want to limit yap's maximum
|
||||
* size. If defined, it should be at least 3.
|
||||
* 10 is probably a reasonable number.
|
||||
*/
|
||||
#endif
|
||||
/* Sanity check 3 */
|
||||
# ifdef MAXNBLOCKS
|
||||
# if MAXNBLOCKS < 3
|
||||
Read the above comment!
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#define VT100_PATCH /* This involves a patch that will insert lines
|
||||
* correctly on a VT100 terminal. The termcap entry
|
||||
* for it contains an "al" with %-escapes. According
|
||||
* to the termcap-documentation this is not allowed,
|
||||
* but ...
|
||||
* If VT100_PATCH is defined, the "al" capability will
|
||||
* be offered to "tgoto", before "tputs"-ing it.
|
||||
* I don't know if there are any terminals out there
|
||||
* that have a % in their "al" capability. If there
|
||||
* are, yap will not work properly when compiled with
|
||||
* VT100_PATCH defined.
|
||||
* Also, escape sequences for standout and underline
|
||||
* will be tputs-ed if VT100_PATCH is defined.
|
||||
*/
|
||||
|
||||
#if _MINIX
|
||||
#define LCASE 0 /* Minix doesn;t have LCASE */
|
||||
#endif
|
|
@ -1,188 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
# ifndef lint
|
||||
static char rcsid[] = "$Header$";
|
||||
# endif
|
||||
|
||||
# define _KEYS_
|
||||
|
||||
# include <ctype.h>
|
||||
# include "in_all.h"
|
||||
# include "machine.h"
|
||||
# include "keys.h"
|
||||
# include "commands.h"
|
||||
# include "prompt.h"
|
||||
# include "assert.h"
|
||||
|
||||
char defaultmap[] = "\
|
||||
bf=P:bl=k:bl=^K:bl=^[[A:bot=l:bot=$:bot=^[[Y:bp=-:bp=^[[V:bs=^B:bse=?:bsl=S:\
|
||||
bsp=F:chm=X:exg=x:ff=N:fl=^J:fl=^M:fl=j:fl=^[[B:fp= :fp=^[[U:fs=^D:fse=/:\
|
||||
fsl=s:fsp=f:hlp=h:nse=n:nsr=r:red=^L:rep=.:bps=Z:bss=b:fps=z:fss=d:shl=!:\
|
||||
tom=':top=\\^:top=^[[H:vis=e:wrf=w:qui=q:qui=Q:mar=m:pip=|";
|
||||
|
||||
char *strcpy();
|
||||
char *strcat();
|
||||
char *getenv();
|
||||
|
||||
/*
|
||||
* Construct an error message and return it
|
||||
*/
|
||||
|
||||
STATIC char *
|
||||
kerror(key, emess) char *key, *emess; {
|
||||
static char ebuf[80]; /* Room for the error message */
|
||||
|
||||
(VOID) strcpy(ebuf, key);
|
||||
(VOID) strcat(ebuf, emess);
|
||||
return ebuf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compile a keymap into commtable. Returns an error message if there
|
||||
* is one
|
||||
*/
|
||||
|
||||
STATIC char *
|
||||
compile(map, commtable)
|
||||
register char *map; register struct keymap *commtable; {
|
||||
register char *mark; /* Indicates start of mnemonic */
|
||||
register char *c; /* Runs through buf */
|
||||
register int temp;
|
||||
char *escapes = commtable->k_esc;
|
||||
char buf[10]; /* Will hold key sequence */
|
||||
|
||||
(VOID) strcpy(commtable->k_help,"Illegal command");
|
||||
while (*map) {
|
||||
c = buf;
|
||||
mark = map; /* Start of mnemonic */
|
||||
while (*map && *map != '=') {
|
||||
map++;
|
||||
}
|
||||
if (!*map) {
|
||||
/*
|
||||
* Mnemonic should end with '='
|
||||
*/
|
||||
return kerror(mark, ": Syntax error");
|
||||
}
|
||||
*map++ = 0;
|
||||
while (*map) {
|
||||
/*
|
||||
* Get key sequence
|
||||
*/
|
||||
if (*map == ':') {
|
||||
/*
|
||||
* end of key sequence
|
||||
*/
|
||||
map++;
|
||||
break;
|
||||
}
|
||||
*c = *map++ & 0177;
|
||||
if (*c == '^' || *c == '\\') {
|
||||
if (!(temp = *map++)) {
|
||||
/*
|
||||
* Escape not followed by a character
|
||||
*/
|
||||
return kerror(mark, ": Syntax error");
|
||||
}
|
||||
if (*c == '^') {
|
||||
if (temp == '?') *c = 0177;
|
||||
else *c = temp & 037;
|
||||
}
|
||||
else *c = temp & 0177;
|
||||
}
|
||||
setused(*c);
|
||||
c++;
|
||||
if (c >= &buf[9]) {
|
||||
return kerror(mark,": Key sequence too long");
|
||||
}
|
||||
}
|
||||
*c = 0;
|
||||
if (!(temp = lookup(mark))) {
|
||||
return kerror(mark,": Nonexistent function");
|
||||
}
|
||||
if (c == &buf[1] && (commands[temp].c_flags & ESC) &&
|
||||
escapes < &(commtable->k_esc[sizeof(commtable->k_esc)-1])) {
|
||||
*escapes++ = buf[0] & 0177;
|
||||
}
|
||||
temp = addstring(buf, temp, &(commtable->k_mach));
|
||||
if (temp == FSM_ISPREFIX) {
|
||||
return kerror(mark,": Prefix of other key sequence");
|
||||
}
|
||||
if (temp == FSM_HASPREFIX) {
|
||||
return kerror(mark,": Other key sequence is prefix");
|
||||
}
|
||||
assert(temp == FSM_OKE);
|
||||
if (!strcmp(mark, "hlp")) {
|
||||
/*
|
||||
* Create an error message to be given when the user
|
||||
* types an illegal command
|
||||
*/
|
||||
(VOID) strcpy(commtable->k_help, "Type ");
|
||||
(VOID) strcat(commtable->k_help, buf);
|
||||
(VOID) strcat(commtable->k_help, " for help");
|
||||
}
|
||||
}
|
||||
*escapes = 0;
|
||||
return (char *) 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the keymaps
|
||||
*/
|
||||
|
||||
VOID
|
||||
initkeys() {
|
||||
register char *p;
|
||||
static struct keymap xx[2];
|
||||
|
||||
currmap = &xx[0];
|
||||
othermap = &xx[1];
|
||||
p = compile(defaultmap, currmap); /* Compile default map */
|
||||
assert(p == (char *) 0);
|
||||
p = getenv("YAPKEYS");
|
||||
if (p) {
|
||||
if (!(p = compile(p, othermap))) {
|
||||
/*
|
||||
* No errors in user defined keymap. So, use it
|
||||
*/
|
||||
do_chkm(0L);
|
||||
return;
|
||||
}
|
||||
error(p);
|
||||
}
|
||||
othermap = 0; /* No other keymap */
|
||||
}
|
||||
|
||||
int
|
||||
is_escape(c)
|
||||
{
|
||||
register char *p = currmap->k_esc;
|
||||
|
||||
while (*p) {
|
||||
if (c == *p++) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char keyset[16]; /* bitset indicating which keys are
|
||||
* used
|
||||
*/
|
||||
/*
|
||||
* Mark key "key" as used
|
||||
*/
|
||||
|
||||
VOID
|
||||
setused(key) int key; {
|
||||
|
||||
keyset[(key & 0177) >> 3] |= (1 << (key & 07));
|
||||
}
|
||||
|
||||
/*
|
||||
* return non-zero if key "key" is used in a keymap
|
||||
*/
|
||||
|
||||
int
|
||||
isused(key) int key; {
|
||||
|
||||
return keyset[(key & 0177) >> 3] & (1 << (key & 07));
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
# ifndef _KEYS_
|
||||
# define PUBLIC extern
|
||||
# else
|
||||
# define PUBLIC
|
||||
# endif
|
||||
|
||||
PUBLIC struct keymap {
|
||||
char k_help[80]; /* To be printed on illegal command */
|
||||
struct state *k_mach; /* Finite state machine */
|
||||
char k_esc[10]; /* escape chars */
|
||||
} *currmap, /* pointer to current key map */
|
||||
*othermap; /* pointer to other keymap */
|
||||
|
||||
VOID initkeys();
|
||||
/*
|
||||
* void initkeys();
|
||||
*
|
||||
* Initializes the keymap(s).
|
||||
*/
|
||||
|
||||
VOID setused();
|
||||
/*
|
||||
* void setused(key);
|
||||
* int key;
|
||||
*
|
||||
* Marks the key "key" as used.
|
||||
*/
|
||||
|
||||
int isused();
|
||||
/*
|
||||
* int isused(key);
|
||||
* int key;
|
||||
*
|
||||
* returns 0 if the key "key" is not used.
|
||||
* Otherwise it returns non-zero.
|
||||
*/
|
||||
|
||||
int is_escape();
|
||||
/*
|
||||
* int is_escape(c);
|
||||
* int c;
|
||||
*
|
||||
* Returns 1 if "c" is an escape char (shell or pipe) in the current
|
||||
* keymap.
|
||||
*/
|
||||
# undef PUBLIC
|
|
@ -1,137 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
# ifndef lint
|
||||
static char rcsid[] = "$Header$";
|
||||
# endif
|
||||
|
||||
# define _MACHINE_
|
||||
|
||||
# include <ctype.h>
|
||||
# include "in_all.h"
|
||||
# include "machine.h"
|
||||
# include "getline.h"
|
||||
# include "assert.h"
|
||||
|
||||
/*
|
||||
* Add part of finite state machine to recognize the string s.
|
||||
*/
|
||||
|
||||
STATIC int
|
||||
addtomach(s, cnt, list) char *s; struct state **list; {
|
||||
|
||||
register struct state *l;
|
||||
register int i = FSM_OKE; /* Return value */
|
||||
register int j;
|
||||
|
||||
for (;;) {
|
||||
l = *list;
|
||||
if (!l) {
|
||||
/*
|
||||
* Create new list element
|
||||
*/
|
||||
*list = l = (struct state *) alloc(sizeof(*l), 0);
|
||||
l->s_char = *s;
|
||||
l->s_endstate = 0;
|
||||
l->s_match = 0;
|
||||
l->s_next = 0;
|
||||
}
|
||||
if (l->s_char == *s) {
|
||||
/*
|
||||
* Continue with next character
|
||||
*/
|
||||
if (!*++s) {
|
||||
/*
|
||||
* No next character
|
||||
*/
|
||||
j = l->s_endstate;
|
||||
l->s_endstate = 1;
|
||||
if (l->s_match || j) {
|
||||
/*
|
||||
* If the state already was an endstate,
|
||||
* or has a successor, the currently
|
||||
* added string is a prefix of an
|
||||
* already recognized string
|
||||
*/
|
||||
return FSM_ISPREFIX;
|
||||
}
|
||||
l->s_cnt = cnt;
|
||||
return i;
|
||||
}
|
||||
if (l->s_endstate) {
|
||||
/*
|
||||
* In this case, the currently added string has
|
||||
* a prefix that is an already recognized
|
||||
* string.
|
||||
*/
|
||||
i = FSM_HASPREFIX;
|
||||
}
|
||||
list = &(l->s_match);
|
||||
continue;
|
||||
}
|
||||
list = &(l->s_next);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a string to the FSM.
|
||||
*/
|
||||
|
||||
int
|
||||
addstring(s,cnt,machine) register char *s; struct state **machine; {
|
||||
|
||||
if (!s || !*s) {
|
||||
return FSM_ISPREFIX;
|
||||
}
|
||||
return addtomach(s,cnt,machine);
|
||||
}
|
||||
|
||||
/*
|
||||
* Match string s with the finite state machine.
|
||||
* If it matches, the number of characters actually matched is returned,
|
||||
* and the count is put in the word pointed to by i.
|
||||
* If the string is a prefix of a string that could be matched,
|
||||
* FSM_ISPREFIX is returned. Otherwise, 0 is returned.
|
||||
*/
|
||||
|
||||
int
|
||||
match(s,i,mach) char *s; int *i; register struct state *mach; {
|
||||
|
||||
register char *s1 = s; /* Walk through string */
|
||||
register struct state *mach1 = 0;
|
||||
/* Keep track of previous state */
|
||||
|
||||
while (mach && *s1) {
|
||||
if (mach->s_char == *s1) {
|
||||
/*
|
||||
* Current character matches. Carry on with next
|
||||
* character and next state
|
||||
*/
|
||||
mach1 = mach;
|
||||
mach = mach->s_match;
|
||||
s1++;
|
||||
continue;
|
||||
}
|
||||
mach = mach->s_next;
|
||||
}
|
||||
if (!mach1) {
|
||||
/*
|
||||
* No characters matched
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
if (mach1->s_endstate) {
|
||||
/*
|
||||
* The string matched
|
||||
*/
|
||||
*i = mach1->s_cnt;
|
||||
return s1 - s;
|
||||
}
|
||||
if (!*s1) {
|
||||
/*
|
||||
* The string matched a prefix
|
||||
*/
|
||||
return FSM_ISPREFIX;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
# ifndef _MACHINE_
|
||||
# define PUBLIC extern
|
||||
# else
|
||||
# define PUBLIC
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Simple minded finite state machine implementation to recognize
|
||||
* strings.
|
||||
*/
|
||||
|
||||
struct state {
|
||||
char s_char; /* character to match with */
|
||||
char s_endstate; /* flag, 1 if this state is an endstate */
|
||||
struct state *s_match; /* new state if matched */
|
||||
struct state *s_next; /* other characters to match with */
|
||||
short s_cnt; /* if an endstate, this field is filled with
|
||||
* some info, dependant on the machine.
|
||||
*/
|
||||
};
|
||||
|
||||
# define FSM_OKE 0
|
||||
# define FSM_ISPREFIX -1 /* Must be < 0 */
|
||||
# define FSM_HASPREFIX 1
|
||||
|
||||
int addstring();
|
||||
/*
|
||||
* int addstring(str,cnt,mach)
|
||||
* char *str; The string to be recognized
|
||||
* int cnt; Attribute of the string.
|
||||
* struct state **mach; The finite state machine
|
||||
*
|
||||
* This routine adds a string to a finite state automaton.
|
||||
* It returns FSM_ISPREFIX if the added string is a prefix of a string already
|
||||
* in the automaton, FSM_HASPREFIX if a string, already recognized by the
|
||||
* automaton, is a prefix of the added string.
|
||||
* Otherwise it returns FSM_OKE.
|
||||
*/
|
||||
|
||||
int match();
|
||||
/*
|
||||
* int match(str,p_int,mach)
|
||||
* char *str; pointer to string
|
||||
* int *p_int; Pointer to an integer
|
||||
* struct state *mach; The finite state machine
|
||||
*
|
||||
* A match of the string indicated by "str" is tried. If a head of "str"
|
||||
* is recognized by the finite state automaton, a machine dependant number
|
||||
* is put in the integer pointed to by "p_int".
|
||||
* The number of characters that match is returned, so a return value of 0
|
||||
* means no match.
|
||||
* A return value of FSM_PREFIX means that the string "str" was a prefix of a
|
||||
* matched string.
|
||||
*/
|
||||
|
||||
# undef PUBLIC
|
|
@ -1,221 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
# ifndef lint
|
||||
static char rcsid[] = "$Header$";
|
||||
# endif
|
||||
|
||||
# define _MAIN_
|
||||
|
||||
# include "in_all.h"
|
||||
# if USG_OPEN
|
||||
# include <fcntl.h>
|
||||
# endif
|
||||
# if BSD4_2_OPEN
|
||||
# include <sys/file.h>
|
||||
# endif
|
||||
# if POSIX_OPEN
|
||||
# include <sys/types.h>
|
||||
# include <fcntl.h>
|
||||
# endif
|
||||
# include "main.h"
|
||||
# include "term.h"
|
||||
# include "options.h"
|
||||
# include "output.h"
|
||||
# include "process.h"
|
||||
# include "commands.h"
|
||||
# include "display.h"
|
||||
# include "prompt.h"
|
||||
|
||||
char *strcpy();
|
||||
|
||||
STATIC int initialize();
|
||||
# ifdef SIGTSTP
|
||||
STATIC int suspsig();
|
||||
# endif
|
||||
|
||||
int
|
||||
main(argc,argv) register char ** argv; {
|
||||
|
||||
register char ** av;
|
||||
char *empty_envp[] = { (char *) 0 };
|
||||
|
||||
if (! isatty(1)) {
|
||||
no_tty = 1;
|
||||
}
|
||||
argv[argc] = 0;
|
||||
progname = argv[0];
|
||||
if ((av = readoptions(argv)) == (char **) 0 ||
|
||||
initialize(*av ? 1 : 0)) {
|
||||
if (no_tty) {
|
||||
close(1);
|
||||
(VOID) dup(2);
|
||||
}
|
||||
putline("Usage: ");
|
||||
putline(argv[0]);
|
||||
putline(
|
||||
" [-c] [-u] [-n] [-q] [-number] [+command] [file ... ]\n");
|
||||
flush();
|
||||
exit(1);
|
||||
}
|
||||
if (no_tty) {
|
||||
*--av = "cat";
|
||||
execve("/bin/cat", av, &empty_envp);
|
||||
}
|
||||
else processfiles(argc-(av-argv), av);
|
||||
(VOID) quit();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
char *mktemp();
|
||||
|
||||
/*
|
||||
* Open temporary file for reading and writing.
|
||||
* Panic if it fails
|
||||
*/
|
||||
|
||||
static char indexfile[30], tempfile[30];
|
||||
|
||||
int
|
||||
opentemp(i) {
|
||||
|
||||
register fildes;
|
||||
register char *f;
|
||||
|
||||
f = i ? mktemp(indexfile) : mktemp(tempfile);
|
||||
# if BSD4_2_OPEN || USG_OPEN || POSIX_OPEN
|
||||
if ((fildes = open(f,O_RDWR|O_TRUNC|O_CREAT,0600)) < 0) {
|
||||
# else
|
||||
if ((fildes = creat(f,0600)) <= 0 || close(fildes) < 0 ||
|
||||
(fildes = open(f,2)) < 0) {
|
||||
# endif
|
||||
panic("Couldn't open temporary file");
|
||||
}
|
||||
(VOID) unlink(f);
|
||||
return fildes;
|
||||
}
|
||||
|
||||
/*
|
||||
* Collect initializing stuff here.
|
||||
*/
|
||||
|
||||
STATIC int
|
||||
initialize(x) {
|
||||
|
||||
if (!(nopipe = x)) {
|
||||
/*
|
||||
* Reading from pipe
|
||||
*/
|
||||
if (isatty(0)) {
|
||||
return 1;
|
||||
}
|
||||
stdf = dup(0); /* Duplicate file descriptor of input */
|
||||
if (no_tty) return 0;
|
||||
/*
|
||||
* Make sure standard input is from the terminal.
|
||||
*/
|
||||
(VOID) close(0);
|
||||
# if BSD4_2_OPEN || USG_OPEN || POSIX_OPEN
|
||||
if (open("/dev/tty",O_RDONLY,0) != 0) {
|
||||
# else
|
||||
if (open("/dev/tty",0) != 0) {
|
||||
# endif
|
||||
putline("Couldn't open terminal\n");
|
||||
flush();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (no_tty) return 0;
|
||||
(VOID) strcpy(tempfile,"/usr/tmp/yap_XXXXXX");
|
||||
(VOID) strcpy(indexfile,"/usr/tmp/yap-XXXXXX");
|
||||
/*
|
||||
* Handle signals.
|
||||
* Catch QUIT, DELETE and ^Z
|
||||
*/
|
||||
(VOID) signal(SIGQUIT,SIG_IGN);
|
||||
(VOID) signal(SIGINT, catchdel);
|
||||
ini_terminal();
|
||||
# ifdef SIGTSTP
|
||||
if (signal(SIGTSTP,SIG_IGN) == SIG_DFL) {
|
||||
(VOID) signal(SIGTSTP,suspsig);
|
||||
}
|
||||
# endif
|
||||
(VOID) signal(SIGQUIT,quit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
catchdel() {
|
||||
(VOID) signal(SIGINT, catchdel);
|
||||
interrupt = 1;
|
||||
}
|
||||
|
||||
# ifdef SIGTSTP
|
||||
|
||||
/*
|
||||
* We had a SIGTSTP signal.
|
||||
* Suspend, by a call to this routine.
|
||||
*/
|
||||
|
||||
VOID
|
||||
suspend() {
|
||||
|
||||
nflush();
|
||||
resettty();
|
||||
(VOID) signal(SIGTSTP,SIG_DFL);
|
||||
#if BSD4_2_OPEN
|
||||
sigsetmask(sigblock(0)&~(1 << (SIGTSTP - 1)));
|
||||
#endif
|
||||
(VOID) kill(0, SIGTSTP);
|
||||
/*
|
||||
* We are not here anymore ...
|
||||
*
|
||||
|
||||
*
|
||||
* But we arive here ...
|
||||
*/
|
||||
inittty();
|
||||
putline(TI);
|
||||
flush();
|
||||
(VOID) signal(SIGTSTP,suspsig);
|
||||
}
|
||||
|
||||
/*
|
||||
* SIGTSTP signal handler.
|
||||
* Just indicate that we had one, ignore further ones and return.
|
||||
*/
|
||||
|
||||
STATIC int
|
||||
suspsig() {
|
||||
|
||||
suspend();
|
||||
if (DoneSetJmp) longjmp(SetJmpBuf, 1);
|
||||
}
|
||||
# endif
|
||||
|
||||
/*
|
||||
* quit : called on exit.
|
||||
* I bet you guessed that much.
|
||||
*/
|
||||
|
||||
int
|
||||
quit() {
|
||||
|
||||
clrbline();
|
||||
resettty();
|
||||
flush();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Exit, but nonvoluntarily.
|
||||
* At least tell the user why.
|
||||
*/
|
||||
|
||||
VOID
|
||||
panic(s) char *s; {
|
||||
|
||||
putline("\007\007\007\r\n");
|
||||
putline(s);
|
||||
putline("\r\n");
|
||||
quit();
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
# ifndef _MAIN_
|
||||
# define PUBLIC extern
|
||||
# else
|
||||
# define PUBLIC
|
||||
# endif
|
||||
|
||||
PUBLIC int nopipe; /* Not reading from pipe? */
|
||||
PUBLIC char * progname; /* Name of this program */
|
||||
PUBLIC int interrupt; /* Interrupt given? */
|
||||
PUBLIC int no_tty; /* output not to a terminal, behave like cat */
|
||||
|
||||
int main();
|
||||
/*
|
||||
* int main(argc,argv)
|
||||
* int argc; Argument count
|
||||
* char *argv[]; The arguments
|
||||
*
|
||||
* Main program.
|
||||
*/
|
||||
|
||||
int opentemp();
|
||||
/*
|
||||
* int opentemp(i)
|
||||
* int i; Either 0 or 1, indicates which temporary to open
|
||||
*
|
||||
* Returns a file descriptor for the temporary file, or panics if
|
||||
* it couldn't open one.
|
||||
*/
|
||||
|
||||
int catchdel();
|
||||
/*
|
||||
* int catchdel();
|
||||
*
|
||||
* interrupt handler. Does not return a value, but PCC has some
|
||||
* difficulty with the type pointer to function returning void.
|
||||
* This routine only sets a flag indicating that there was an interrupt.
|
||||
*/
|
||||
|
||||
int quit();
|
||||
/*
|
||||
* int quit();
|
||||
*
|
||||
* Quit signal handler. Also used for normal exits.
|
||||
* It resets the terminal and exits
|
||||
*/
|
||||
|
||||
VOID panic();
|
||||
/*
|
||||
* void panic(str)
|
||||
* char *str; Reason for panic
|
||||
*
|
||||
* Panic, but at least tell the user why.
|
||||
*/
|
||||
|
||||
# ifdef SIGTSTP
|
||||
VOID suspend();
|
||||
/*
|
||||
* void suspend()
|
||||
*
|
||||
* Suspends this process
|
||||
*/
|
||||
# endif
|
||||
|
||||
# undef PUBLIC
|
|
@ -1,88 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
# ifndef lint
|
||||
static char rcsid[] = "$Header$";
|
||||
# endif
|
||||
|
||||
# define _OPTIONS_
|
||||
|
||||
# include "in_all.h"
|
||||
# include "options.h"
|
||||
# include "output.h"
|
||||
# include "display.h"
|
||||
# include <ctype.h>
|
||||
|
||||
STATIC int parsopt();
|
||||
char *getenv();
|
||||
|
||||
/*
|
||||
* Read the options. Return the argv pointer following them if there were
|
||||
* no errors, otherwise return 0.
|
||||
*/
|
||||
|
||||
char **
|
||||
readoptions(argv) char ** argv; {
|
||||
|
||||
register char ** av = argv+1;
|
||||
register char *p;
|
||||
|
||||
if (p = getenv("YAP")) {
|
||||
(VOID) parsopt(p);
|
||||
}
|
||||
while (*av && **av == '-') {
|
||||
if (parsopt(*av)) {
|
||||
/*
|
||||
* Error in option
|
||||
*/
|
||||
putline(*av);
|
||||
putline(": illegal option\n");
|
||||
return (char **) 0;
|
||||
}
|
||||
av++;
|
||||
}
|
||||
if (*av && **av == '+') {
|
||||
/*
|
||||
* Command in command line
|
||||
*/
|
||||
startcomm = *av + 1;
|
||||
av++;
|
||||
}
|
||||
return av;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
parsopt(s) register char *s; {
|
||||
register i;
|
||||
|
||||
if (*s == '-') s++;
|
||||
if (isdigit(*s)) {
|
||||
/*
|
||||
* pagesize option
|
||||
*/
|
||||
i = 0;
|
||||
do {
|
||||
i = i * 10 + *s++ - '0';
|
||||
} while (isdigit(*s));
|
||||
if (i < MINPAGESIZE) i = MINPAGESIZE;
|
||||
pagesize = i;
|
||||
}
|
||||
while (*s) {
|
||||
switch(*s++) {
|
||||
case 'c' :
|
||||
cflag++;
|
||||
break;
|
||||
case 'n' :
|
||||
nflag++;
|
||||
break;
|
||||
case 'u' :
|
||||
uflag++;
|
||||
break;
|
||||
case 'q' :
|
||||
qflag++;
|
||||
break;
|
||||
default :
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
# ifndef _OPTIONS_
|
||||
# define PUBLIC extern
|
||||
# else
|
||||
# define PUBLIC
|
||||
# endif
|
||||
|
||||
PUBLIC int cflag; /* no home before each page */
|
||||
PUBLIC int uflag; /* no underlining */
|
||||
PUBLIC int nflag; /* no pattern matching on input */
|
||||
PUBLIC int qflag; /* no exit on the next page command */
|
||||
PUBLIC char * startcomm; /* There was a command option */
|
||||
|
||||
char ** readoptions();
|
||||
/*
|
||||
* char ** readoptions(argv)
|
||||
* char **argv; Arguments given to yap.
|
||||
*
|
||||
* process the options from the arguments. Return 0 if there was an error,
|
||||
* otherwise return a pointer to where the filenames start.
|
||||
*/
|
||||
|
||||
# undef PUBLIC
|
|
@ -1,100 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
/*
|
||||
* Handle output to screen
|
||||
*/
|
||||
|
||||
# ifndef lint
|
||||
static char rcsid[] = "$Header$";
|
||||
# endif
|
||||
|
||||
# define _OUTPUT_
|
||||
|
||||
# include "in_all.h"
|
||||
# include "output.h"
|
||||
# include "main.h"
|
||||
|
||||
# define OBUFSIZ 64*128
|
||||
|
||||
static char _outbuf[OBUFSIZ];
|
||||
|
||||
VOID
|
||||
flush() { /* Flush output buffer, by writing it */
|
||||
register char *p = _outbuf;
|
||||
|
||||
_ocnt = OBUFSIZ;
|
||||
if (_optr) (VOID) write(1, p, _optr - p);
|
||||
_optr = p;
|
||||
}
|
||||
|
||||
VOID
|
||||
nflush() { /* Flush output buffer, ignoring it */
|
||||
|
||||
_ocnt = OBUFSIZ;
|
||||
_optr = _outbuf;
|
||||
}
|
||||
|
||||
int
|
||||
fputch(ch) char ch; { /* print a character */
|
||||
putch(ch);
|
||||
}
|
||||
|
||||
VOID
|
||||
putline(s) register char *s; { /* Print string s */
|
||||
|
||||
if (!s) return;
|
||||
while (*s) {
|
||||
putch(*s++);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A safe version of putline. All control characters are echoed as ^X
|
||||
*/
|
||||
|
||||
VOID
|
||||
cputline(s) char *s; {
|
||||
register c;
|
||||
|
||||
while (c = *s++) {
|
||||
if ((unsigned) c > 0177) c &= 0177;
|
||||
if (c < ' ' || c == 0177) {
|
||||
putch('^');
|
||||
c ^= 0100;
|
||||
}
|
||||
putch(c);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple minded routine to print a number
|
||||
*/
|
||||
|
||||
VOID
|
||||
prnum(n) long n; {
|
||||
|
||||
putline(getnum(n));
|
||||
}
|
||||
|
||||
static char *
|
||||
fillnum(n, p)
|
||||
long n;
|
||||
char *p;
|
||||
{
|
||||
if (n >= 10) {
|
||||
p = fillnum(n / 10, p);
|
||||
}
|
||||
*p++ = (int) (n % 10) + '0';
|
||||
*p = '\0';
|
||||
return p;
|
||||
}
|
||||
|
||||
char *
|
||||
getnum(n)
|
||||
long n;
|
||||
{
|
||||
static char buf[20];
|
||||
|
||||
fillnum(n, buf);
|
||||
return buf;
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
# ifndef _OUTPUT_
|
||||
# define PUBLIC extern
|
||||
# else
|
||||
# define PUBLIC
|
||||
# endif
|
||||
|
||||
PUBLIC int _ocnt;
|
||||
PUBLIC char *_optr;
|
||||
|
||||
#define putch(ch) if (1) {if (--_ocnt <= 0) flush(); *_optr++ = (ch);} else
|
||||
|
||||
VOID flush();
|
||||
/*
|
||||
* void flush()
|
||||
*
|
||||
* Write the output buffer to the screen
|
||||
*/
|
||||
|
||||
VOID nflush();
|
||||
/*
|
||||
* void nflush()
|
||||
*
|
||||
* Clear output buffer, but do not write it
|
||||
*/
|
||||
|
||||
int fputch();
|
||||
/*
|
||||
* int fputch(c)
|
||||
* int c; The character to be printed
|
||||
*
|
||||
* Put character "c" in output buffer and flush if necessary.
|
||||
*/
|
||||
|
||||
VOID putline();
|
||||
/*
|
||||
* void putline(s)
|
||||
* char *s; The string to be printed
|
||||
*
|
||||
* Put string "s" in output buffer etc...
|
||||
*/
|
||||
|
||||
VOID cputline();
|
||||
/*
|
||||
* void cputline(s)
|
||||
* char *s; The string to be handled
|
||||
*
|
||||
* Put string "s" in the output buffer, expanding control characters
|
||||
*/
|
||||
|
||||
VOID prnum();
|
||||
/*
|
||||
* void prnum(n)
|
||||
* long n; The number to be printed
|
||||
*
|
||||
* print the number "n", using putch.
|
||||
*/
|
||||
|
||||
char *getnum();
|
||||
/*
|
||||
* char *getnum(n)
|
||||
* long n; The number to be converted to a string
|
||||
*
|
||||
* Convert a number to a string and return a pointer to it.
|
||||
*/
|
||||
# undef PUBLIC
|
|
@ -1,160 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
# ifndef lint
|
||||
static char rcsid[] = "$Header$";
|
||||
# endif /* not lint */
|
||||
|
||||
# define _PATTERN_
|
||||
|
||||
# include "in_all.h"
|
||||
# include "pattern.h"
|
||||
# include "getline.h"
|
||||
|
||||
# if V8_REGEX
|
||||
# include <regexp.h>
|
||||
# endif /* V8_REGEX */
|
||||
|
||||
/*
|
||||
* Interface to regular expression routines.
|
||||
* Also: simple minded patterns without meta-characters.
|
||||
*/
|
||||
|
||||
# if USG_REGEX
|
||||
static char *pattern; /* Pointer to compiled pattern */
|
||||
char *regcmp(), *regex();
|
||||
# endif /* USG_REGEX */
|
||||
# if V8_REGEX
|
||||
static struct regexp *pattern;
|
||||
static char *rc_error;
|
||||
struct regexp *regcomp();
|
||||
# endif /* V8_REGEX */
|
||||
|
||||
# if USG_REGEX || V8_REGEX
|
||||
/*
|
||||
* Compile a new pattern, but first free previous result.
|
||||
*/
|
||||
|
||||
char *
|
||||
re_comp(s) char *s; {
|
||||
|
||||
if (!*s) {
|
||||
/*
|
||||
* user wants previous pattern
|
||||
*/
|
||||
return (char *) 0;
|
||||
}
|
||||
if (pattern) {
|
||||
/*
|
||||
* there was a compiled pattern
|
||||
*/
|
||||
free(pattern);
|
||||
pattern = 0;
|
||||
}
|
||||
# if USG_REGEX
|
||||
return (pattern = regcmp(s, (char *) 0)) ?
|
||||
(char *) 0 :
|
||||
"Error in pattern";
|
||||
# endif /* USG_REGEX */
|
||||
# if V8_REGEX
|
||||
pattern = regcomp(s);
|
||||
if (pattern) return (char *) 0;
|
||||
if (rc_error) return rc_error;
|
||||
return "Error in pattern";
|
||||
# endif /* V8_REGEX */
|
||||
}
|
||||
|
||||
# if V8_REGEX
|
||||
VOID
|
||||
regerror(str) char *str; {
|
||||
rc_error = str;
|
||||
}
|
||||
# endif /* V8_REGEX */
|
||||
|
||||
/*
|
||||
* Search for compiled pattern in string "s". Return 0 if not found.
|
||||
*/
|
||||
|
||||
re_exec(s) char *s; {
|
||||
|
||||
# if USG_REGEX
|
||||
return !(regex(pattern,s) == 0);
|
||||
# endif /* USG_REGEX */
|
||||
# if V8_REGEX
|
||||
# if _MINIX
|
||||
return regexec(pattern,s,1);
|
||||
# else
|
||||
return regexec(pattern,s);
|
||||
# endif
|
||||
# endif /* V8_REGEX */
|
||||
}
|
||||
# else
|
||||
# ifndef BSD_REGEX
|
||||
/*
|
||||
* In this case, simple minded pattern search without meta-characters
|
||||
*/
|
||||
|
||||
char *strcpy();
|
||||
|
||||
static char *pattern;
|
||||
|
||||
/*
|
||||
* re_comp : Just remember pattern.
|
||||
*/
|
||||
|
||||
char *
|
||||
re_comp(s) char *s; {
|
||||
|
||||
if (!*s) {
|
||||
/*
|
||||
* User wants previous pattern
|
||||
*/
|
||||
if (!pattern) {
|
||||
return "No previous regular expression";
|
||||
}
|
||||
return (char *) 0;
|
||||
}
|
||||
if (pattern) {
|
||||
/*
|
||||
* Free old pattern
|
||||
*/
|
||||
free(pattern);
|
||||
}
|
||||
pattern = alloc((unsigned) (strlen(s) + 1), 0);
|
||||
(VOID) strcpy(pattern,s);
|
||||
return (char *) 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* re-exec : Simple minded pattern matcher
|
||||
*/
|
||||
|
||||
re_exec(s) register char *s; {
|
||||
|
||||
register char *ppat, *pstr;
|
||||
|
||||
for (; *s; s++) {
|
||||
/*
|
||||
* As long as there are characters ...
|
||||
*/
|
||||
ppat = pattern; /* Try the pattern again */
|
||||
pstr = s;
|
||||
while (*ppat == *pstr) {
|
||||
if (*++ppat == '\0') {
|
||||
/*
|
||||
* The pattern matched! Report success
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
if (*++pstr == '\0') {
|
||||
/*
|
||||
* Not enough characters left in the string.
|
||||
* Report failure
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0; /* Failure */
|
||||
}
|
||||
# endif /* not BSD_REGEX */
|
||||
# endif
|
|
@ -1,14 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
# ifndef _PATTERN_
|
||||
# define PUBLIC extern
|
||||
# else
|
||||
# define PUBLIC
|
||||
# endif
|
||||
|
||||
char * re_comp();
|
||||
int re_exec();
|
||||
|
||||
# undef PUBLIC
|
|
@ -1,127 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
# ifndef lint
|
||||
static char rcsid[] = "$Header$";
|
||||
# endif
|
||||
|
||||
# define _PROCESS_
|
||||
|
||||
# include "in_all.h"
|
||||
# if USG_OPEN
|
||||
# include <fcntl.h>
|
||||
# endif
|
||||
# if BSD4_2_OPEN
|
||||
# include <sys/file.h>
|
||||
# endif
|
||||
# if POSIX_OPEN
|
||||
# include <sys/types.h>
|
||||
# include <fcntl.h>
|
||||
# endif
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# include "process.h"
|
||||
# include "commands.h"
|
||||
# include "display.h"
|
||||
# include "prompt.h"
|
||||
# include "getline.h"
|
||||
# include "main.h"
|
||||
# include "options.h"
|
||||
# include "output.h"
|
||||
|
||||
static int nfiles; /* Number of filenames on command line */
|
||||
|
||||
/*
|
||||
* Visit a file, file name is "fn".
|
||||
*/
|
||||
|
||||
VOID
|
||||
visitfile(fn) char *fn; {
|
||||
struct stat statbuf;
|
||||
|
||||
if (stdf > 0) {
|
||||
/*
|
||||
* Close old input file
|
||||
*/
|
||||
(VOID) close(stdf);
|
||||
}
|
||||
currentfile = fn;
|
||||
# if USG_OPEN || BSD4_2_OPEN || POSIX_OPEN
|
||||
if ((stdf = open(fn,O_RDONLY,0)) < 0) {
|
||||
# else
|
||||
if ((stdf = open(fn,0)) < 0) {
|
||||
# endif
|
||||
error(": could not open");
|
||||
maxpos = 0;
|
||||
}
|
||||
else { /* Get size for percentage in prompt */
|
||||
(VOID) fstat(stdf, &statbuf);
|
||||
maxpos = statbuf.st_size;
|
||||
}
|
||||
do_clean();
|
||||
d_clean();
|
||||
}
|
||||
|
||||
/*
|
||||
* process the input files, one by one.
|
||||
* If there is none, input is from a pipe.
|
||||
*/
|
||||
|
||||
VOID
|
||||
processfiles(n,argv) char ** argv; {
|
||||
|
||||
static char *dummies[3];
|
||||
long arg;
|
||||
|
||||
if (!(nfiles = n)) {
|
||||
/*
|
||||
* Input from pipe
|
||||
*/
|
||||
currentfile = "standard-input";
|
||||
/*
|
||||
* Take care that *(filenames - 1) and *(filenames + 1) are 0
|
||||
*/
|
||||
filenames = &dummies[1];
|
||||
d_clean();
|
||||
do_clean();
|
||||
}
|
||||
else {
|
||||
filenames = argv;
|
||||
(VOID) nextfile(0);
|
||||
}
|
||||
*--argv = 0;
|
||||
if (startcomm) {
|
||||
n = getcomm(&arg);
|
||||
if (commands[n].c_flags & NEEDS_SCREEN) {
|
||||
redraw(0);
|
||||
}
|
||||
do_comm(n,arg);
|
||||
startcomm = 0;
|
||||
}
|
||||
redraw(1);
|
||||
if (setjmp(SetJmpBuf)) {
|
||||
nflush();
|
||||
redraw(1);
|
||||
}
|
||||
DoneSetJmp = 1;
|
||||
for (;;) {
|
||||
interrupt = 0;
|
||||
n = getcomm(&arg);
|
||||
do_comm(n, arg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the next file the user asks for.
|
||||
*/
|
||||
|
||||
int
|
||||
nextfile(n) {
|
||||
register i;
|
||||
|
||||
if ((i = filecount + n) >= nfiles || i < 0) {
|
||||
return 1;
|
||||
}
|
||||
filecount = i;
|
||||
visitfile(filenames[i]);
|
||||
return 0;
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
# ifndef _PROCESS_
|
||||
# define PUBLIC extern
|
||||
# else
|
||||
# define PUBLIC
|
||||
# endif
|
||||
|
||||
# include <setjmp.h>
|
||||
|
||||
PUBLIC jmp_buf SetJmpBuf;
|
||||
PUBLIC int DoneSetJmp;
|
||||
|
||||
PUBLIC int stdf; /* input file descriptor */
|
||||
PUBLIC int filecount; /* index in filename table */
|
||||
PUBLIC char ** filenames; /* the filenametable */
|
||||
PUBLIC char * currentfile; /* Name of current file */
|
||||
PUBLIC long maxpos; /* Size of file */
|
||||
|
||||
VOID visitfile();
|
||||
/*
|
||||
* void visitfile(fn)
|
||||
* char *fn; name of file to be visited
|
||||
*
|
||||
* Opens the file "fn" and gives an error message if this fails.
|
||||
*/
|
||||
|
||||
VOID processfiles();
|
||||
/*
|
||||
* void processfiles(n,argv)
|
||||
* int n; number of files to be handled
|
||||
* char ** argv; names of the files
|
||||
*
|
||||
* Does all the work according to the divide and conquer method
|
||||
*/
|
||||
|
||||
int nextfile();
|
||||
/*
|
||||
* int nextfile(n)
|
||||
* int n;
|
||||
*
|
||||
* Visits n'th next file. If not there in argument list, return 1.
|
||||
* Otherwise return 0.
|
||||
*/
|
||||
|
||||
# undef PUBLIC
|
|
@ -1,193 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
# ifndef lint
|
||||
static char rcsid[] = "$Header$";
|
||||
# endif
|
||||
|
||||
# define _PROMPT_
|
||||
|
||||
# include "in_all.h"
|
||||
# include "prompt.h"
|
||||
# include "term.h"
|
||||
# include "output.h"
|
||||
# include "options.h"
|
||||
# include "display.h"
|
||||
# include "process.h"
|
||||
# include "getline.h"
|
||||
# include "main.h"
|
||||
# include "getcomm.h"
|
||||
# include "keys.h"
|
||||
# include "assert.h"
|
||||
# include "commands.h"
|
||||
|
||||
#define basename(x) x
|
||||
|
||||
#ifndef basename
|
||||
STATIC char * basename();
|
||||
#endif
|
||||
|
||||
static char *errorgiven; /* Set to error message, if there is one */
|
||||
|
||||
char *
|
||||
copy(p, ep, s)
|
||||
register char *p, *s;
|
||||
char *ep;
|
||||
{
|
||||
while (p < ep && *s) {
|
||||
*p++ = *s++;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* display the prompt and refresh the screen.
|
||||
*/
|
||||
|
||||
VOID
|
||||
give_prompt() {
|
||||
|
||||
register char **name;
|
||||
register struct scr_info *p = &scr_info;
|
||||
char buf[256];
|
||||
register char *pb = buf;
|
||||
|
||||
if (startcomm) return;
|
||||
flush();
|
||||
if (window()) {
|
||||
redraw(0);
|
||||
flush();
|
||||
}
|
||||
if (!stupid) {
|
||||
/*
|
||||
* fancy prompt
|
||||
*/
|
||||
clrbline();
|
||||
standout();
|
||||
pb = copy(pb, &buf[255], basename(currentfile));
|
||||
if (stdf >= 0) {
|
||||
pb = copy(pb, &buf[255], ", ");
|
||||
pb = copy(pb, &buf[255], getnum(p->firstline));
|
||||
pb = copy(pb, &buf[255], "-");
|
||||
pb = copy(pb, &buf[255], getnum(p->lastline));
|
||||
}
|
||||
}
|
||||
else {
|
||||
*pb++ = '\007'; /* Stupid terminal, stupid prompt */
|
||||
}
|
||||
if (errorgiven) {
|
||||
/*
|
||||
* display error message
|
||||
*/
|
||||
pb = copy(pb, &buf[255], " ");
|
||||
pb = copy(pb, &buf[255], errorgiven);
|
||||
if (stupid) {
|
||||
pb = copy(pb, &buf[255], "\r\n");
|
||||
}
|
||||
errorgiven = 0;
|
||||
}
|
||||
else if (!stupid && (status || maxpos)) {
|
||||
pb = copy(pb, &buf[255], " (");
|
||||
name = &filenames[filecount];
|
||||
if (status) {
|
||||
/*
|
||||
* indicate top and/or bottom
|
||||
*/
|
||||
if (status & START) {
|
||||
if (!*(name - 1)) {
|
||||
pb = copy(pb, &buf[255], "Top");
|
||||
}
|
||||
else {
|
||||
pb = copy(pb, &buf[255], "Previous: ");
|
||||
pb = copy(pb, &buf[255], basename(*(name - 1)));
|
||||
}
|
||||
if (status & EOFILE) {
|
||||
pb = copy(pb, &buf[255], ", ");
|
||||
}
|
||||
}
|
||||
if (status & EOFILE) {
|
||||
if (!*(name+1)) {
|
||||
pb = copy(pb, &buf[255], "Bottom");
|
||||
}
|
||||
else {
|
||||
pb = copy(pb, &buf[255], "Next: ");
|
||||
pb = copy(pb, &buf[255], basename(*(name + 1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* display percentage */
|
||||
pb = copy(pb, &buf[255], getnum((100 * getpos(p->lastline))/maxpos));
|
||||
pb = copy(pb, &buf[255], "%");
|
||||
}
|
||||
pb = copy(pb, &buf[255], ")");
|
||||
}
|
||||
*pb = '\0';
|
||||
if (!stupid) {
|
||||
buf[COLS-1] = 0;
|
||||
putline(buf);
|
||||
standend();
|
||||
}
|
||||
else putline(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remember error message
|
||||
*/
|
||||
|
||||
VOID
|
||||
error(str) char *str; {
|
||||
|
||||
errorgiven = str;
|
||||
}
|
||||
|
||||
#ifndef basename
|
||||
STATIC char *
|
||||
basename(fn) char *fn; { /* Return name without path */
|
||||
|
||||
register char *s;
|
||||
|
||||
s = fn;
|
||||
while (*s++) ; /* Search end of name */
|
||||
for (;;) {
|
||||
if (*--s == '/') {
|
||||
/*
|
||||
* Backwards to first '/'
|
||||
*/
|
||||
if (*(s+1)) {
|
||||
/*
|
||||
* There is a name after the '/'
|
||||
*/
|
||||
return s + 1;
|
||||
}
|
||||
*s = 0; /* No name after the '/' */
|
||||
}
|
||||
if (s == fn) return s;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
#endif
|
||||
|
||||
VOID
|
||||
ret_to_continue() { /* Obvious */
|
||||
int c;
|
||||
static char buf[2];
|
||||
|
||||
for (;;) {
|
||||
clrbline();
|
||||
standout();
|
||||
if (errorgiven) {
|
||||
putline(errorgiven);
|
||||
putline(" ");
|
||||
errorgiven = 0;
|
||||
}
|
||||
putline("[Type anything to continue]");
|
||||
standend();
|
||||
if (is_escape(c = getch())) {
|
||||
buf[0] = c;
|
||||
(VOID) match(buf, &c, currmap->k_mach);
|
||||
assert(c > 0);
|
||||
do_comm(c, -1L);
|
||||
}
|
||||
else break;
|
||||
}
|
||||
clrbline();
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
# ifndef _PROMPT_
|
||||
# define PUBLIC extern
|
||||
# else
|
||||
# define PUBLIC
|
||||
# endif
|
||||
|
||||
VOID give_prompt();
|
||||
/*
|
||||
* void give_prompt()
|
||||
*
|
||||
* Displays a prompt, with possibly an error message
|
||||
*/
|
||||
|
||||
VOID error();
|
||||
/*
|
||||
* void error(s)
|
||||
* char *s; The error
|
||||
*
|
||||
* Takes care that there will be an error message in the next prompt.
|
||||
*/
|
||||
|
||||
VOID ret_to_continue();
|
||||
/*
|
||||
* void ret_to_continue();
|
||||
*
|
||||
* Asks the user to type something before continuing.
|
||||
*/
|
||||
|
||||
# undef PUBLIC
|
|
@ -1,487 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
/*
|
||||
* Terminal handling routines, mostly initializing.
|
||||
*/
|
||||
|
||||
# ifndef lint
|
||||
static char rcsid[] = "$Header$";
|
||||
# endif
|
||||
|
||||
# define _TERM_
|
||||
|
||||
#include "in_all.h"
|
||||
#include "term.h"
|
||||
#include "machine.h"
|
||||
#include "output.h"
|
||||
#include "display.h"
|
||||
#include "options.h"
|
||||
#include "getline.h"
|
||||
#include "keys.h"
|
||||
#include "main.h"
|
||||
|
||||
#ifdef TIOCGWINSZ
|
||||
static struct winsize w;
|
||||
#endif
|
||||
|
||||
char *strcpy(),
|
||||
*strcat(),
|
||||
*tgoto(),
|
||||
*tgetstr(),
|
||||
*getenv();
|
||||
|
||||
static char tcbuf1[1024]; /* Holds terminal capability strings */
|
||||
static char * ptc; /* Pointer in it */
|
||||
static char tcbuf[1024]; /* Another termcap buffer */
|
||||
short ospeed; /* Needed for tputs() */
|
||||
char PC; /* Needed for tputs() */
|
||||
char * UP; /* Needed for tgoto() */
|
||||
static char *ll;
|
||||
|
||||
struct linelist _X[100]; /* 100 is enough ? */
|
||||
|
||||
# if USG_TTY
|
||||
static struct termio _tty,_svtty;
|
||||
# elif POSIX_TTY
|
||||
static struct termios _tty, _svtty;
|
||||
# else
|
||||
# ifdef TIOCSPGRP
|
||||
static int proc_id, saved_pgrpid;
|
||||
# endif
|
||||
static struct sgttyb _tty,_svtty;
|
||||
# ifdef TIOCGETC
|
||||
static struct tchars _ttyc, _svttyc;
|
||||
# endif
|
||||
# ifdef TIOCGLTC
|
||||
static int line_discipline;
|
||||
static struct ltchars _lttyc, _svlttyc;
|
||||
# endif
|
||||
# endif
|
||||
|
||||
static VOID
|
||||
handle(c) char *c; { /* if character *c is used, set it to undefined */
|
||||
|
||||
if (isused(*c)) *c = 0377;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set terminal in cbreak mode.
|
||||
* Also check if tabs need expanding.
|
||||
*/
|
||||
|
||||
VOID
|
||||
inittty() {
|
||||
# if USG_TTY
|
||||
register struct termio *p = &_tty;
|
||||
|
||||
ioctl(0,TCGETA,(char *) p);
|
||||
_svtty = *p;
|
||||
if (p->c_oflag & TAB3) {
|
||||
/*
|
||||
* We do tab expansion ourselves
|
||||
*/
|
||||
expandtabs = 1;
|
||||
}
|
||||
p->c_oflag &= ~(TAB3|OCRNL|ONLRET|ONLCR);
|
||||
p->c_oflag |= (/*ONOCR|*/OPOST); /* ONOCR does not seem to work
|
||||
very well in combination with
|
||||
~ONLCR
|
||||
*/
|
||||
p->c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON);
|
||||
if (isused('S'&037) || isused('Q'&037)) p->c_iflag &= ~IXON;
|
||||
handle(&(p->c_cc[0])); /* INTR and QUIT (mnemonics not defined ??) */
|
||||
handle(&(p->c_cc[1]));
|
||||
erasech = p->c_cc[VERASE];
|
||||
killch = p->c_cc[VKILL];
|
||||
p->c_cc[VMIN] = 1; /* Just wait for one character */
|
||||
p->c_cc[VTIME] = 0;
|
||||
ospeed = p->c_cflag & CBAUD;
|
||||
ioctl(0,TCSETAW,(char *) p);
|
||||
#elif POSIX_TTY
|
||||
register struct termios *p = &_tty;
|
||||
|
||||
tcgetattr(0, p);
|
||||
_svtty = *p;
|
||||
#ifdef _MINIX /* Should be XTABS */
|
||||
if (p->c_oflag & XTABS) {
|
||||
/*
|
||||
* We do tab expansion ourselves
|
||||
*/
|
||||
expandtabs = 1;
|
||||
}
|
||||
p->c_oflag &= (OPOST|XTABS);
|
||||
#else
|
||||
p->c_oflag &= ~OPOST;
|
||||
#endif
|
||||
p->c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON);
|
||||
if (isused('S'&037) || isused('Q'&037)) p->c_iflag &= ~IXON;
|
||||
handle(&(p->c_cc[VINTR]));
|
||||
handle(&(p->c_cc[VQUIT]));
|
||||
erasech = p->c_cc[VERASE];
|
||||
killch = p->c_cc[VKILL];
|
||||
p->c_cc[VMIN] = 1; /* Just wait for one character */
|
||||
p->c_cc[VTIME] = 0;
|
||||
ospeed = cfgetospeed(p);
|
||||
tcsetattr(0, TCSANOW, p);
|
||||
# else
|
||||
register struct sgttyb *p = &_tty;
|
||||
|
||||
# ifdef TIOCSPGRP
|
||||
/*
|
||||
* If we can, we put yap in another process group, and the terminal
|
||||
* with it. This is done, so that interrupts given by the user
|
||||
* will only affect yap and not it's children (processes writing
|
||||
* on a pipe to yap)
|
||||
*/
|
||||
if (ioctl(0, TIOCSPGRP, (char *) &proc_id) != -1) {
|
||||
setpgrp(0, proc_id);
|
||||
}
|
||||
# endif
|
||||
ioctl(0,TIOCGETP,(char *) p);
|
||||
_svtty = *p;
|
||||
erasech = p->sg_erase;
|
||||
killch = p->sg_kill;
|
||||
ospeed = p->sg_ospeed;
|
||||
if (p->sg_flags & XTABS) {
|
||||
/*
|
||||
* We do tab expansion ourselves
|
||||
*/
|
||||
expandtabs = 1;
|
||||
}
|
||||
p->sg_flags |= (CBREAK);
|
||||
p->sg_flags &= ~(ECHO|XTABS|RAW|LCASE|CRMOD);
|
||||
#ifdef TIOCSETN
|
||||
ioctl(0, TIOCSETN, (char *) p);
|
||||
#else
|
||||
ioctl(0,TIOCSETP,(char *) p);
|
||||
#endif
|
||||
/* Bloody Sun ... */
|
||||
#undef t_startc
|
||||
#undef t_stopc
|
||||
#undef t_intrc
|
||||
#undef t_quitc
|
||||
#undef t_suspc
|
||||
#undef t_dsuspc
|
||||
#undef t_flushc
|
||||
#undef t_lnextc
|
||||
# ifdef TIOCGETC
|
||||
{ register struct tchars *q = &_ttyc;
|
||||
|
||||
ioctl(0,TIOCGETC,(char *) q);
|
||||
_svttyc = *q;
|
||||
handle(&(q->t_intrc));
|
||||
handle(&(q->t_quitc));
|
||||
if (isused(q->t_startc) || isused(q->t_stopc)) {
|
||||
q->t_startc = q->t_stopc = 0377;
|
||||
}
|
||||
ioctl(0,TIOCSETC, (char *) q);
|
||||
}
|
||||
# endif
|
||||
# ifdef TIOCGLTC
|
||||
{ register struct ltchars *q = &_lttyc;
|
||||
|
||||
ioctl(0,TIOCGETD,(char *) &line_discipline);
|
||||
if (line_discipline == NTTYDISC) {
|
||||
ioctl(0, TIOCGLTC,(char *) q);
|
||||
_svlttyc = *q;
|
||||
handle(&(q->t_suspc));
|
||||
handle(&(q->t_dsuspc));
|
||||
q->t_flushc = q->t_lnextc = 0377;
|
||||
ioctl(0,TIOCSLTC, (char *) q);
|
||||
}
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset the terminal to its original state
|
||||
*/
|
||||
|
||||
VOID
|
||||
resettty() {
|
||||
|
||||
# if USG_TTY
|
||||
ioctl(0,TCSETAW,(char *) &_svtty);
|
||||
# elif POSIX_TTY
|
||||
tcsetattr(0, TCSANOW, &_svtty);
|
||||
# else
|
||||
# ifdef TIOCSPGRP
|
||||
ioctl(0, TIOCSPGRP, (char *) &saved_pgrpid);
|
||||
setpgrp(0, saved_pgrpid);
|
||||
# endif
|
||||
ioctl(0,TIOCSETP,(char *) &_svtty);
|
||||
# ifdef TIOCGETC
|
||||
ioctl(0,TIOCSETC, (char *) &_svttyc);
|
||||
# endif
|
||||
# ifdef TIOCGLTC
|
||||
if (line_discipline == NTTYDISC) ioctl(0,TIOCSLTC, (char *) &_svlttyc);
|
||||
# endif
|
||||
# endif
|
||||
putline(TE);
|
||||
flush();
|
||||
}
|
||||
|
||||
/*
|
||||
* Get terminal capability "cap".
|
||||
* If not present, return an empty string.
|
||||
*/
|
||||
|
||||
STATIC char *
|
||||
getcap(cap) char *cap; {
|
||||
register char *s;
|
||||
|
||||
s = tgetstr(cap, &ptc);
|
||||
if (!s) return "";
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize some terminal-dependent stuff.
|
||||
*/
|
||||
|
||||
VOID
|
||||
ini_terminal() {
|
||||
|
||||
register char * s;
|
||||
register struct linelist *lp, *lp1;
|
||||
register i;
|
||||
register UG, SG;
|
||||
char tempbuf[20];
|
||||
char *mb, *mh, *mr; /* attributes */
|
||||
|
||||
initkeys();
|
||||
#if !_MINIX
|
||||
# ifdef TIOCSPGRP
|
||||
proc_id = getpid();
|
||||
ioctl(0,TIOCGPGRP, (char *) &saved_pgrpid);
|
||||
# endif
|
||||
#endif
|
||||
inittty();
|
||||
stupid = 1;
|
||||
ptc = tcbuf1;
|
||||
BC = "\b";
|
||||
TA = "\t";
|
||||
if (!(s = getenv("TERM"))) s = "dumb";
|
||||
if (tgetent(tcbuf, s) <= 0) {
|
||||
panic("No termcap entry");
|
||||
}
|
||||
stupid = 0;
|
||||
hardcopy = tgetflag("hc"); /* Hard copy terminal?*/
|
||||
PC = *(getcap("pc"));
|
||||
if (*(s = getcap("bc"))) {
|
||||
/*
|
||||
* Backspace if not ^H
|
||||
*/
|
||||
BC = s;
|
||||
}
|
||||
UP = getcap("up"); /* move up a line */
|
||||
CE = getcap("ce"); /* clear to end of line */
|
||||
CL = getcap("cl"); /* clear screen */
|
||||
if (!*CL) cflag = 1;
|
||||
TI = getcap("ti"); /* Initialization for CM */
|
||||
TE = getcap("te"); /* end for CM */
|
||||
CM = getcap("cm"); /* cursor addressing */
|
||||
SR = getcap("sr"); /* scroll reverse */
|
||||
AL = getcap("al"); /* Insert line */
|
||||
SO = getcap("so"); /* standout */
|
||||
SE = getcap("se"); /* standend */
|
||||
SG = tgetnum("sg"); /* blanks left by SO, SE */
|
||||
if (SG < 0) SG = 0;
|
||||
US = getcap("us"); /* underline */
|
||||
UE = getcap("ue"); /* end underline */
|
||||
UG = tgetnum("ug"); /* blanks left by US, UE */
|
||||
if (UG < 0) UG = 0;
|
||||
UC = getcap("uc"); /* underline a character */
|
||||
mb = getcap("mb"); /* blinking attribute */
|
||||
MD = getcap("md"); /* bold attribute */
|
||||
ME = getcap("me"); /* turn off attributes */
|
||||
mh = getcap("mh"); /* half bright attribute */
|
||||
mr = getcap("mr"); /* reversed video attribute */
|
||||
if (!nflag) {
|
||||
/*
|
||||
* Recognize special strings
|
||||
*/
|
||||
(VOID) addstring(SO,SG,&sppat);
|
||||
(VOID) addstring(SE,SG,&sppat);
|
||||
(VOID) addstring(US,UG,&sppat);
|
||||
(VOID) addstring(UE,UG,&sppat);
|
||||
(VOID) addstring(mb,0,&sppat);
|
||||
(VOID) addstring(MD,0,&sppat);
|
||||
(VOID) addstring(ME,0,&sppat);
|
||||
(VOID) addstring(mh,0,&sppat);
|
||||
(VOID) addstring(mr,0,&sppat);
|
||||
if (*UC) {
|
||||
(VOID) strcpy(tempbuf,BC);
|
||||
(VOID) strcat(tempbuf,UC);
|
||||
(VOID) addstring(tempbuf,0,&sppat);
|
||||
}
|
||||
}
|
||||
if (UG > 0 || uflag) {
|
||||
US = "";
|
||||
UE = "";
|
||||
}
|
||||
if (*US || uflag) UC = "";
|
||||
COLS = tgetnum("co"); /* columns on page */
|
||||
i = tgetnum("li"); /* Lines on page */
|
||||
AM = tgetflag("am"); /* terminal wraps automatically? */
|
||||
XN = tgetflag("xn"); /* and then ignores next newline? */
|
||||
DB = tgetflag("db"); /* terminal retains lines below */
|
||||
if (!*(s = getcap("ho")) && *CM) {
|
||||
s = tgoto(CM,0,0); /* Another way of getting home */
|
||||
}
|
||||
if ((!*CE && !*AL) || !*s || hardcopy) {
|
||||
cflag = stupid = 1;
|
||||
}
|
||||
(VOID) strcpy(HO,s);
|
||||
if (*(s = getcap("ta"))) {
|
||||
/*
|
||||
* Tab (other than ^I or padding)
|
||||
*/
|
||||
TA = s;
|
||||
}
|
||||
if (!*(ll = getcap("ll")) && *CM && i > 0) {
|
||||
/*
|
||||
* Lower left hand corner
|
||||
*/
|
||||
(VOID) strcpy(BO, tgoto(CM,0,i-1));
|
||||
}
|
||||
else (VOID) strcpy(BO, ll);
|
||||
if (COLS <= 0 || COLS > 256) {
|
||||
if ((unsigned) COLS >= 65409) {
|
||||
/* SUN bug */
|
||||
COLS &= 0xffff;
|
||||
COLS -= (65409 - 128);
|
||||
}
|
||||
if (COLS <= 0 || COLS > 256) COLS = 80;
|
||||
}
|
||||
if (i <= 0) {
|
||||
i = 24;
|
||||
cflag = stupid = 1;
|
||||
}
|
||||
LINES = i;
|
||||
maxpagesize = i - 1;
|
||||
scrollsize = maxpagesize / 2;
|
||||
if (scrollsize <= 0) scrollsize = 1;
|
||||
if (!pagesize || pagesize >= i) {
|
||||
pagesize = maxpagesize;
|
||||
}
|
||||
|
||||
/*
|
||||
* The next part does not really belong here, but there it is ...
|
||||
* Initialize a circular list for the screenlines.
|
||||
*/
|
||||
|
||||
scr_info.tail = lp = _X;
|
||||
lp1 = lp + (100 - 1);
|
||||
for (; lp <= lp1; lp++) {
|
||||
/*
|
||||
* Circular doubly linked list
|
||||
*/
|
||||
lp->next = lp + 1;
|
||||
lp->prev = lp - 1;
|
||||
}
|
||||
lp1->next = scr_info.tail;
|
||||
lp1->next->prev = lp1;
|
||||
if (stupid) {
|
||||
(VOID) strcpy(BO,"\r\n");
|
||||
}
|
||||
putline(TI);
|
||||
window();
|
||||
}
|
||||
|
||||
/*
|
||||
* Place cursor at start of line n.
|
||||
*/
|
||||
|
||||
VOID
|
||||
mgoto(n) register n; {
|
||||
|
||||
if (n == 0) home();
|
||||
else if (n == maxpagesize && *BO) bottom();
|
||||
else if (*CM) {
|
||||
/*
|
||||
* Cursor addressing
|
||||
*/
|
||||
tputs(tgoto(CM,0,n),1,fputch);
|
||||
}
|
||||
else if (*BO && *UP && n >= (maxpagesize >> 1)) {
|
||||
/*
|
||||
* Bottom and then up
|
||||
*/
|
||||
bottom();
|
||||
while (n++ < maxpagesize) putline(UP);
|
||||
}
|
||||
else { /* Home, and then down */
|
||||
home();
|
||||
while (n--) putline("\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear bottom line
|
||||
*/
|
||||
|
||||
VOID
|
||||
clrbline() {
|
||||
|
||||
if (stupid) {
|
||||
putline("\r\n");
|
||||
return;
|
||||
}
|
||||
bottom();
|
||||
if (*CE) {
|
||||
/*
|
||||
* We can clear to end of line
|
||||
*/
|
||||
clrtoeol();
|
||||
return;
|
||||
}
|
||||
# ifdef VT100_PATCH
|
||||
insert_line(maxpagesize);
|
||||
# else
|
||||
insert_line();
|
||||
# endif
|
||||
}
|
||||
|
||||
# ifdef VT100_PATCH
|
||||
ins_line(l) {
|
||||
tputs(tgoto(AL, l, 0), maxpagesize - l, fputch);
|
||||
}
|
||||
# endif
|
||||
|
||||
VOID
|
||||
home() {
|
||||
|
||||
tputs(HO,1,fputch);
|
||||
}
|
||||
|
||||
VOID
|
||||
bottom() {
|
||||
|
||||
tputs(BO,1,fputch);
|
||||
if (!*BO) mgoto(maxpagesize);
|
||||
}
|
||||
|
||||
int
|
||||
window()
|
||||
{
|
||||
#ifdef TIOCGWINSZ
|
||||
if (ioctl(1, TIOCGWINSZ, &w) < 0) return 0;
|
||||
|
||||
if (w.ws_col == 0) w.ws_col = COLS;
|
||||
if (w.ws_row == 0) w.ws_row = LINES;
|
||||
if (w.ws_col != COLS || w.ws_row != LINES) {
|
||||
COLS = w.ws_col;
|
||||
LINES = w.ws_row;
|
||||
maxpagesize = LINES - 1;
|
||||
pagesize = maxpagesize;
|
||||
if (! *ll) (VOID) strcpy(BO, tgoto(CM,0,maxpagesize));
|
||||
scr_info.currentpos = 0;
|
||||
scrollsize = maxpagesize / 2;
|
||||
if (scrollsize <= 0) scrollsize = 1;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
|
@ -1,137 +0,0 @@
|
|||
/* Copyright (c) 1985 Ceriel J.H. Jacobs */
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
/* All terminal and terminal dependent stuff */
|
||||
|
||||
# ifndef _TERM_
|
||||
# define PUBLIC extern
|
||||
# else
|
||||
# define PUBLIC
|
||||
# endif
|
||||
|
||||
# if USG_TTY
|
||||
# include <termio.h>
|
||||
# elif POSIX_TTY
|
||||
# include <termios.h>
|
||||
# else
|
||||
# include <sgtty.h>
|
||||
# endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
/* Terminal setting */
|
||||
|
||||
PUBLIC int expandtabs; /* Tabs need expanding? */
|
||||
PUBLIC int stupid; /* Stupid terminal */
|
||||
PUBLIC int hardcopy; /* Hardcopy terminal */
|
||||
|
||||
/* termcap stuff */
|
||||
PUBLIC
|
||||
char *CE, /* clear to end of line */
|
||||
*CL, /* clear screen */
|
||||
*SO, /* stand out */
|
||||
*SE, /* stand end */
|
||||
*US, /* underline start */
|
||||
*UE, /* underline end */
|
||||
*UC, /* underline character */
|
||||
*MD, /* bold start */
|
||||
*ME, /* attributes (like bold) off */
|
||||
*TI, /* initialize for CM */
|
||||
*TE, /* End of CM */
|
||||
*CM, /* Cursor addressing */
|
||||
*TA, /* Tab */
|
||||
*SR, /* Scroll reverse */
|
||||
*AL; /* insert line */
|
||||
PUBLIC
|
||||
int LINES, /* # of lines on screen */
|
||||
COLS, /* # of colums */
|
||||
AM, /* Automatic margins */
|
||||
XN, /* newline ignored after wrap */
|
||||
DB; /* terminal retains lines below */
|
||||
PUBLIC
|
||||
char HO[20], /* Sequence to get to home position */
|
||||
BO[20]; /* sequence to get to lower left hand corner */
|
||||
PUBLIC
|
||||
int erasech, /* users erase character */
|
||||
killch; /* users kill character */
|
||||
PUBLIC struct state *sppat; /* Special patterns to be recognized */
|
||||
PUBLIC char
|
||||
*BC; /* Back space */
|
||||
|
||||
#define backspace() putline(BC)
|
||||
#define clrscreen() tputs(CL,LINES,fputch)
|
||||
#define clrtoeol() tputs(CE,1,fputch)
|
||||
#define scrollreverse() tputs(SR,LINES,fputch)
|
||||
#ifdef VT100_PATCH
|
||||
#define insert_line(l) ins_line(l)
|
||||
#define standout() tputs(SO,1,fputch)
|
||||
#define standend() tputs(SE,1,fputch)
|
||||
#define underline() tputs(US,1,fputch)
|
||||
#define end_underline() tputs(UE,1,fputch)
|
||||
#define bold() tputs(MD,1,fputch)
|
||||
#define end_bold() tputs(ME,1,fputch)
|
||||
#define underchar() tputs(UC,1,fputch)
|
||||
# else
|
||||
#define insert_line() tputs(AL,LINES,fputch)
|
||||
#define standout() putline(SO)
|
||||
#define standend() putline(SE)
|
||||
#define underline() putline(US)
|
||||
#define end_underline() putline(UE)
|
||||
#define bold() putline(MD)
|
||||
#define end_bold() putline(ME)
|
||||
#define underchar() putline(UC)
|
||||
# endif
|
||||
#define givetab() tputs(TA,1,fputch)
|
||||
|
||||
VOID inittty();
|
||||
/*
|
||||
* void inittty()
|
||||
*
|
||||
* Initialises the terminal (sets it in cbreak mode, etc)
|
||||
*/
|
||||
|
||||
VOID resettty();
|
||||
/*
|
||||
* void resettty()
|
||||
*
|
||||
* resets the terminal to the mode in which it was before yap was invoked
|
||||
*/
|
||||
|
||||
VOID ini_terminal();
|
||||
/*
|
||||
* void ini_terminal()
|
||||
*
|
||||
* Handles the termcap entry for your terminal. In some cases, the terminal
|
||||
* will be considered stupid.
|
||||
*/
|
||||
|
||||
VOID mgoto();
|
||||
/*
|
||||
* void mgoto(n)
|
||||
* int n; Line to go to
|
||||
*
|
||||
* Put the cursor at the start of the n'th screen line.
|
||||
* This can be done in several ways (of course).
|
||||
*/
|
||||
|
||||
VOID clrbline();
|
||||
/*
|
||||
* void clrbline()
|
||||
*
|
||||
* clears the bottom line, by either clearing it to end of line,
|
||||
* or pushing it of the screen by inserting a line before it.
|
||||
*/
|
||||
|
||||
VOID home();
|
||||
VOID bottom();
|
||||
/*
|
||||
* Obvious
|
||||
*/
|
||||
|
||||
#ifdef WINDOW
|
||||
int window();
|
||||
#endif
|
||||
# undef PUBLIC
|
Loading…
Reference in a new issue