no more minix more, *whatis

This commit is contained in:
Ben Gras 2010-06-26 01:08:31 +00:00
parent aa6ff4c8be
commit 6ebe0cdf82
39 changed files with 3 additions and 5296 deletions

View file

@ -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 \

View file

@ -1,4 +0,0 @@
SCRIPTS= makewhatis.sh
MAN=
.include <bsd.prog.mk>

View file

@ -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
}

View file

@ -1,6 +0,0 @@
SCRIPTS= whatis.sh
MAN=
LINKS+= ${BINDIR}/whatis ${BINDIR}/apropos
.include <bsd.prog.mk>

View file

@ -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

View file

@ -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>

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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 */
}

View file

@ -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

View file

@ -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]);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -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));
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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();
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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();
}

View file

@ -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

View file

@ -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;
}

View file

@ -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