diff options
author | ps <ps@FreeBSD.org> | 2000-05-29 13:31:51 +0000 |
---|---|---|
committer | ps <ps@FreeBSD.org> | 2000-05-29 13:31:51 +0000 |
commit | cde9059fa3e4dc7e259c3864d7536252a5c580a0 (patch) | |
tree | f00074cf86c06f511c00cd5d238e6d67e893f975 | |
parent | 9998c137973dea1fa9b7bfd2b915515ad59ba753 (diff) | |
download | FreeBSD-src-cde9059fa3e4dc7e259c3864d7536252a5c580a0.zip FreeBSD-src-cde9059fa3e4dc7e259c3864d7536252a5c580a0.tar.gz |
Nuke more from the repository.
-rw-r--r-- | usr.bin/more/Makefile | 34 | ||||
-rw-r--r-- | usr.bin/more/ch.c | 465 | ||||
-rw-r--r-- | usr.bin/more/command.c | 751 | ||||
-rw-r--r-- | usr.bin/more/default.morerc | 180 | ||||
-rw-r--r-- | usr.bin/more/help.c | 54 | ||||
-rw-r--r-- | usr.bin/more/input.c | 270 | ||||
-rw-r--r-- | usr.bin/more/less.h | 137 | ||||
-rw-r--r-- | usr.bin/more/less.morerc | 61 | ||||
-rw-r--r-- | usr.bin/more/line.c | 522 | ||||
-rw-r--r-- | usr.bin/more/linenum.c | 395 | ||||
-rw-r--r-- | usr.bin/more/macro.c | 292 | ||||
-rw-r--r-- | usr.bin/more/main.c | 553 | ||||
-rw-r--r-- | usr.bin/more/more.1 | 358 | ||||
-rw-r--r-- | usr.bin/more/more.help | 45 | ||||
-rw-r--r-- | usr.bin/more/most.morerc | 86 | ||||
-rw-r--r-- | usr.bin/more/ncommand.c | 1505 | ||||
-rw-r--r-- | usr.bin/more/option.c | 134 | ||||
-rw-r--r-- | usr.bin/more/os.c | 311 | ||||
-rw-r--r-- | usr.bin/more/output.c | 320 | ||||
-rw-r--r-- | usr.bin/more/pathnames.h | 44 | ||||
-rw-r--r-- | usr.bin/more/position.c | 170 | ||||
-rw-r--r-- | usr.bin/more/prim.c | 842 | ||||
-rw-r--r-- | usr.bin/more/screen.c | 662 | ||||
-rw-r--r-- | usr.bin/more/signal.c | 221 | ||||
-rw-r--r-- | usr.bin/more/tags.c | 595 | ||||
-rw-r--r-- | usr.bin/more/ttyin.c | 79 |
26 files changed, 0 insertions, 9086 deletions
diff --git a/usr.bin/more/Makefile b/usr.bin/more/Makefile deleted file mode 100644 index 354a032..0000000 --- a/usr.bin/more/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -# From: @(#)Makefile 8.1 (Berkeley) 6/6/93 -# $FreeBSD$ -# - -PROG= more -CFLAGS+=-I${.CURDIR} -I${.OBJDIR} -DTERMIOS -SRCS= ch.c command.c defrc.h help.c input.c line.c linenum.c macro.c main.c \ - ncommand.c option.c os.c output.c position.c prim.c screen.c signal.c \ - tags.c ttyin.c -DPADD= ${LIBTERMCAP} -LDADD= -ltermcap - -CLEANFILES+= defrc.h - -EXAMPDIR= /usr/share/examples/more -EXAMPLES= default.morerc less.morerc most.morerc - -defrc.h: default.morerc - @echo '/* ${.TARGET:T} auto-generated from ${.ALLSRC:T} */' \ - > ${.TARGET} - @echo '#define DEFRC "\' >> ${.TARGET} - sed -e 's/\\/\\\\/g' -e 's/\"/\\\"/g' -e 's/$$/\\n\\/' \ - < ${.ALLSRC} >> ${.TARGET} - @echo \" >> ${.TARGET} - -beforeinstall: - ${INSTALL} ${COPY} -o ${SHAREOWN} -g ${SHAREGRP} -m ${SHAREMODE} \ - ${.CURDIR}/more.help ${DESTDIR}/usr/share/misc -.for xzamp in ${EXAMPLES} - ${INSTALL} ${COPY} -o ${SHAREOWN} -g ${SHAREGRP} -m ${SHAREMODE} \ - ${.CURDIR}/${xzamp} ${DESTDIR}${EXAMPDIR}/${xzamp} -.endfor - -.include <bsd.prog.mk> diff --git a/usr.bin/more/ch.c b/usr.bin/more/ch.c deleted file mode 100644 index 8bfc009..0000000 --- a/usr.bin/more/ch.c +++ /dev/null @@ -1,465 +0,0 @@ -/* - * Copyright (c) 1988 Mark Nudleman - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char sccsid[] = "@(#)ch.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ - -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -/* - * Low level character input from the input file. - * We use these special purpose routines which optimize moving - * both forward and backward from the current read pointer. - */ - -#include <sys/types.h> -#include <sys/file.h> -#include <unistd.h> -#include <stdio.h> -#include <less.h> - -int file = -1; /* File descriptor of the input file */ - -/* - * Pool of buffers holding the most recently used blocks of the input file. - */ -struct buf { - struct buf *next, *prev; - long block; - int datasize; - char data[BUFSIZ]; -}; -int nbufs; - -/* - * The buffer pool is kept as a doubly-linked circular list. For the ispipe - * case, this list will always be ordered from highest-numbered block downto - * lowest-numbered block, skipping no blocks. For the !ispipe case, - * it may become disordered. It is not clear that this is a feature. - */ -#define END_OF_CHAIN ((struct buf *)&buf_anchor) -#define buf_head buf_anchor.next -#define buf_tail buf_anchor.prev - -static struct { - struct buf *next, *prev; - long block; /* this is never changed from -1 */ -} buf_anchor = { END_OF_CHAIN, END_OF_CHAIN, (long)-1 }; - -/* - * The last buffer in the circular list that was accessed, and correspondingly - * the most likely to be accessed in the future. - */ -static struct buf *buf_lastacc = END_OF_CHAIN; - -extern int ispipe, cbufs, sigs; - -/* - * Current position in file. - * Stored as a block number and an offset into the block. - */ -static long ch_block; -static int ch_offset; - -/* Length of file, needed if input is a pipe. */ -static off_t ch_fsize; - -/* Number of bytes read, if input is standard input (a pipe). */ -static off_t last_piped_pos; - -/* - * Get the character pointed to by the read pointer. ch_get() is a macro - * which is more efficient to call than fch_get (the function), in the usual - * case that the block desired is at the head of the chain. - */ -#define ch_get() \ - ((buf_lastacc->block == ch_block && \ - ch_offset < buf_lastacc->datasize) ? \ - (unsigned char)buf_lastacc->data[ch_offset] : fch_get()) - -static -fch_get() -{ - register struct buf *bp; - register char *p, *t; - int n, gofor; - off_t pos, lseek(); - - /* - * look for a buffer holding the desired block. - */ - if (abs(buf_lastacc->next->block - ch_block) < - abs(buf_lastacc->prev->block - ch_block)) - gofor = 1; /* Look forwards through the buffer queue */ - else - gofor = 0; /* Look backwards through the buffer queue */ - - bp = buf_lastacc; - do { - if (bp->block == ch_block) { - buf_lastacc = bp; - if (ch_offset >= bp->datasize) - goto read_more; - return((unsigned char)bp->data[ch_offset]); - } - if (gofor) - bp = bp->next; - else - bp = bp->prev; - } while (bp != buf_lastacc); - - /* - * Block is not in a buffer. Take the buffer from the tail and - * read the desired block into it. If the input is a pipe, we try - * to buffer as much input as possible since the input will be - * permanently lost if we throw it from the buffer queue. - */ - if (ispipe && buf_tail->block != (long)(-1)) - (void)ch_addbuf(1); - bp = buf_tail; - bp->block = ch_block; - bp->datasize = 0; - -read_more: - pos = (ch_block * BUFSIZ) + bp->datasize; - if (ispipe) { - /* - * The data requested should be immediately after - * the last data read from the pipe. - */ - if (pos != last_piped_pos) { - error("pipe error"); - quit(); - } - } else - (void)lseek(file, pos, L_SET); - - /* - * Read the block. - * - * If we read less than a full block, we just return the - * partial block and pick up the rest next time. - */ - n = iread(file, &bp->data[bp->datasize], BUFSIZ - bp->datasize); - if (n == READ_INTR) - return (EOI); - if (n < 0) { - error("read error"); - quit(); - } - if (ispipe) - last_piped_pos += n; - - bp->datasize += n; - - if (n == 0) { - ch_fsize = pos; - bp->data[bp->datasize++] = EOI; - } - - /* - * Turn other EOI (nul) chars into 0200 since EOI has special meaning. - */ - for (p = &bp->data[bp->datasize]; --n >= 0;) { - --p; - if (*p == EOI) - *p = 0200; - } - -found: - if (buf_head != bp) { - /* - * Move the buffer to the head of the buffer chain. This - * ensures correct order for the ispipe case and prevents - * needless buffer thrashing for the !ispipe case. It's not - * clear that buffer thrashing isn't desirable in this latter - * case, since the VM should probably be handling the file - * buffer... - */ - bp->next->prev = bp->prev; - bp->prev->next = bp->next; - - bp->next = buf_head; - bp->prev = END_OF_CHAIN; - buf_head->prev = bp; - buf_head = bp; - } - - if (ch_offset >= bp->datasize) - /* - * After all that, we still don't have enough data. - * Go back and try again. - */ - goto read_more; - - return((unsigned char)bp->data[ch_offset]); -} - -/* - * Determine if a specific block is currently in one of the buffers. - * - * In general, this function is only called for the ispipe case. For the - * !ispipe case, ch.c generally assumes that any given block is accessible - * through ch_get(), even though ch_get() may not have it buffered. - */ -static -buffered(block) - long block; -{ - register struct buf *bp; - - /* For the ispipe case, we know that the buffer queue is sequentially - * ordered from tail to head. */ - if (ispipe && (block <= buf_head->block && block >= buf_tail->block)) - return(1); - - /* - * XXX This is dead code. - */ - for (bp = buf_head; bp != END_OF_CHAIN; bp = bp->next) - if (bp->block == block) - return(1); - return(0); -} - -/* - * Seek to a specified position in the file. - * Return 0 if successful, non-zero if can't seek there. - */ -ch_seek(pos) - register off_t pos; -{ - long new_block; - - new_block = pos / BUFSIZ; - if (!ispipe || pos == last_piped_pos || buffered(new_block)) { - /* - * Set read pointer. - */ - ch_block = new_block; - ch_offset = pos % BUFSIZ; - return(0); - } - return(1); -} - -/* - * Seek to the end of the file. - */ -ch_end_seek() -{ - off_t ch_length(); - - if (!ispipe) - return(ch_seek(ch_length())); - - /* - * Do it the slow way: read till end of data. - */ - while (ch_forw_get() != EOI) - if (sigs) - return(1); - return(0); -} - -/* - * Seek to the beginning of the file, or as close to it as we can get. - * We may not be able to seek there if input is a pipe and the - * beginning of the pipe is no longer buffered. - */ -ch_beg_seek() -{ - register struct buf *bp, *firstbp; - - /* - * Try a plain ch_seek first. - */ - if (ch_seek((off_t)0) == 0) - return(0); - - /* - * Can't get to position 0. - * Look thru the buffers for the one closest to position 0. - * - * This should use the obvious optimization that applies for the - * ispipe case (which is also the only case under which this - * code will be executed, ie. the only case under which ch_seek() - * will fail). - */ - firstbp = bp = buf_head; - if (bp == END_OF_CHAIN) - return(1); - while ((bp = bp->next) != END_OF_CHAIN) - if (bp->block < firstbp->block) - firstbp = bp; - ch_block = firstbp->block; - ch_offset = 0; - return(0); -} - -/* - * Return the length of the file, if known. - */ -off_t -ch_length() -{ - off_t lseek(); - - if (ispipe) - return(ch_fsize); - return((off_t)(lseek(file, (off_t)0, L_XTND))); -} - -/* - * Return the current position in the file. - */ -off_t -ch_tell() -{ - return(ch_block * BUFSIZ + ch_offset); -} - -/* - * Get the current char and post-increment the read pointer. - */ -ch_forw_get() -{ - register int c; - - c = ch_get(); - if (c != EOI && ++ch_offset >= BUFSIZ) { - ch_offset = 0; - ++ch_block; - } - return(c); -} - -/* - * Pre-decrement the read pointer and get the new current char. - */ -ch_back_get() -{ - if (--ch_offset < 0) { - if (ch_block <= 0 || (ispipe && !buffered(ch_block-1))) { - ch_offset = 0; - return(EOI); - } - ch_offset = BUFSIZ - 1; - ch_block--; - } - return(ch_get()); -} - -/* - * Allocate buffers. - * Caller wants us to have a total of at least want_nbufs buffers. - * keep==1 means keep the data in the current buffers; - * otherwise discard the old data. - */ -ch_init(want_nbufs, keep) - int want_nbufs; - int keep; -{ - register struct buf *bp; - char message[80]; - - cbufs = nbufs; - if (nbufs < want_nbufs && ch_addbuf(want_nbufs - nbufs)) { - /* - * Cannot allocate enough buffers. - * If we don't have ANY, then quit. - * Otherwise, just report the error and return. - */ - (void)snprintf(message, sizeof(message), - "cannot allocate %d buffers", want_nbufs - nbufs); - error(message); - if (nbufs == 0) - quit(); - return; - } - - if (keep) - return; - - /* - * We don't want to keep the old data, - * so initialize all the buffers now. - */ - for (bp = buf_head; bp != END_OF_CHAIN; bp = bp->next) - bp->block = (long)(-1); - last_piped_pos = (off_t)0; - ch_fsize = NULL_POSITION; - (void)ch_seek((off_t)0); -} - -/* - * Allocate some new buffers. - * The buffers are added to the tail of the buffer chain. - */ -ch_addbuf(nnew) - int nnew; -{ - register struct buf *bp; - register struct buf *newbufs; - char *calloc(); - - /* - * We don't have enough buffers. - * Allocate some new ones. - */ - newbufs = (struct buf *)calloc((u_int)nnew, sizeof(struct buf)); - if (newbufs == NULL) - return(1); - - /* - * Initialize the new buffers and link them together. - * Link them all onto the tail of the buffer list. - */ - nbufs += nnew; - cbufs = nbufs; - for (bp = &newbufs[0]; bp < &newbufs[nnew]; bp++) { - bp->next = bp + 1; - bp->prev = bp - 1; - bp->block = (long)(-1); - } - newbufs[nnew-1].next = END_OF_CHAIN; - newbufs[0].prev = buf_tail; - buf_tail->next = &newbufs[0]; - buf_tail = &newbufs[nnew-1]; - return(0); -} diff --git a/usr.bin/more/command.c b/usr.bin/more/command.c deleted file mode 100644 index cf784fe..0000000 --- a/usr.bin/more/command.c +++ /dev/null @@ -1,751 +0,0 @@ -/* - * Copyright (c) 1988 Mark Nudleman - * Portions copyright (c) 1999 T. Michael Vanderhoek - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char sccsid[] = "@(#)command.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ - -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -/* - * Functions for interacting with the user directly printing hello - * messages or reading from the terminal. All of these functions deal - * specifically with the prompt line, and only the prompt line. - */ - -#include <sys/param.h> - -#include <assert.h> -#include <ctype.h> -#include <stdarg.h> -#include <stdio.h> -#include <string.h> - -#include "less.h" -#include "pathnames.h" - -extern int erase_char, kill_char, werase_char; -extern int sigs; -extern int quit_at_eof; -extern int hit_eof; -extern int horiz_off; -extern int sc_width; -extern int bo_width; -extern int be_width; -extern int so_width; -extern int se_width; -extern int curr_ac; -extern int ac; -extern char **av; -extern int screen_trashed; /* The screen has been overwritten */ - -static int cmd_col; /* Current screen column when accepting input */ - -static cmd_char(), cmd_erase(), getcc(); - - -/***************************************************************************** - * - * Functions for reading-in user input. - * - */ - -static int biggetinputhack_f; - -/* biggetinputhack() - * - * Performs as advertised. - */ -biggetinputhack() -{ - biggetinputhack_f = 1; -} - -/* - * Read a line of input from the terminal. Reads at most bufsiz - 1 characters - * and places them in buffer buf. They are NUL-terminated. Prints the - * temporary prompt prompt. Returns true if the user aborted the input and - * returns false otherwise. - */ -int -getinput(prompt, buf, bufsiz) - const char *prompt; - char *buf; - int bufsiz; -{ - extern bo_width, be_width; - char *bufcur; - int c; - - prmpt(prompt); - - bufcur = buf; - for (;;) { - c = getcc(); - if (c == '\n') { - *bufcur = '\0'; - return 0; - } - if (c == READ_INTR || - cmd_char(c, buf, &bufcur, buf + bufsiz - 1)) { - /* input cancelled */ - if (bufsiz) *buf = '\0'; - return 1; - } - if (biggetinputhack_f) { - biggetinputhack_f = 0; - *bufcur = '\0'; - return 0; - } - } -} - -/* - * Process a single character of a multi-character input, such as - * a number, or the pattern of a search command. Returns true if the user - * has cancelled the multi-character input, false otherwise and attempts - * to add it to buf (not exceeding bufsize). Prints the character on the - * terminal output. The bufcur should initially equal bufbeg. After that - * it does not need to be touched or modified by the user, but may be expected - * to point at the future position of the next character. - */ -static int -cmd_char(c, bufbeg, bufcur, bufend) - int c; /* The character to process */ - char *bufbeg; /* The buffer to add the character to */ - char **bufcur; /* The position at which to add the character */ - char *bufend; /* One after the last address available in the buffer. - * No character will be placed into *bufend. */ -{ - if (c == erase_char) - return(cmd_erase(bufbeg, bufcur)); - /* in this order, in case werase == erase_char */ - if (c == werase_char) { - if (*bufcur > bufbeg) { - while (isspace((*bufcur)[-1]) && - !cmd_erase(bufbeg, bufcur)) ; - while (!isspace((*bufcur)[-1]) && - !cmd_erase(bufbeg, bufcur)) ; - while (isspace((*bufcur)[-1]) && - !cmd_erase(bufbeg, bufcur)) ; - } - return *bufcur == bufbeg; - } - if (c == kill_char) { - while (!cmd_erase(bufbeg, bufcur)); - return 1; - } - - /* - * No room in the command buffer, or no room on the screen; - * XXX If there is no room on the screen, we should just let the - * screen scroll down and set screen_trashed=1 appropriately, or - * alternatively, scroll the prompt line horizontally. - */ - assert (*bufcur <= bufend); - if (*bufcur == bufend || cmd_col >= sc_width - 3) - bell(); - else { - *(*bufcur)++ = c; - if (CONTROL_CHAR(c)) { - putchr('^'); - cmd_col++; - c &= ~0200; - c = CARAT_CHAR(c); - } - putchr(c); - cmd_col++; - } - return 0; -} - -/* - * Helper function to cmd_char(). Backs-up one character from bufcur in the - * buffer passed, and prints a backspace on the screen. Returns true if the - * we backspaced past bufbegin (ie. the input is being aborted), and false - * otherwise. The bufcur is expected to point to the future location of the - * next character in the buffer, and is modified appropriately. - */ -static -cmd_erase(bufbegin, bufcur) - char *bufbegin; - char **bufcur; -{ - int c; - - /* - * XXX Could add code to detect a backspace that is backing us over - * the beginning of a line and onto the previous line. The backspace - * would not be printed for some terminals (eg. hardcopy) in that - * case. - */ - - /* - * backspace past beginning of the string: this usually means - * abort the input. - */ - if (*bufcur == bufbegin) - return 1; - - (*bufcur)--; - - /* If erasing a control-char, erase an extra character for the carat. */ - c = **bufcur; - if (CONTROL_CHAR(c)) { - backspace(); - cmd_col--; - } - - backspace(); - cmd_col--; - - return 0; -} - -static int ungotcc; - -/* - * Get command character from the terminal. - */ -static -getcc() -{ - int ch; - off_t position(); - - /* left over from error() routine. */ - if (ungotcc) { - ch = ungotcc; - ungotcc = 0; - return(ch); - } - - return(getchr()); -} - -/* - * Same as ungetc(), but works for people who don't like to use streams. - */ -ungetcc(c) - int c; -{ - ungotcc = c; -} - - -/***************************************************************************** - * - * prompts - * - */ - -static int longprompt; - -/* - * Prints prmpt where the prompt would normally appear. This is different - * from changing the current prompt --- this is more like printing a - * unimportant notice or error. The prmpt line will be printed in bold (if - * possible). Will in the future print only the last sc_width - 1 - bo_width - * characters (to prevent newline). - */ -prmpt(prmpt) - const char *prmpt; -{ - lower_left(); - clear_eol(); - bo_enter(); - putxstr(prmpt); - bo_exit(); - flush(); - cmd_col = strlen(prmpt) + bo_width + be_width; -} - -/* - * Print the main prompt that signals we are ready for user commands. This - * also magically positions the current file where it should be (either by - * calling repaint() if screen_trashed or by searching for a search - * string that was specified through option.c on the more(1) command line). - * Additional magic will randomly call the quit() function. - * - * This is really intended to do a lot of the work of commands(). It has - * little purpose outside of commands(). - */ -prompt() -{ - extern int linenums, short_file, ispipe; - extern char *current_name, *firstsearch, *next_name; - off_t len, pos, ch_length(), position(), forw_line(); - char pbuf[40]; - - /* - * if nothing is displayed yet, display starting from line 1; - * if search string provided, go there instead. - */ - if (position(TOP) == NULL_POSITION) { -#if 0 -/* This code causes "more zero-byte-file /etc/termcap" to skip straight - * to the /etc/termcap file ... that is undesireable. There are only a few - * instances where these two lines perform something useful. */ - if (forw_line((off_t)0) == NULL_POSITION) - return 0 ; -#endif - if (!firstsearch || !search(1, firstsearch, 1, 1)) - jump_back(1); - } - else if (screen_trashed) - repaint(); - - /* if no -e flag and we've hit EOF on the last file, quit. */ - if (!quit_at_eof && hit_eof && curr_ac + 1 >= ac) - quit(); - - /* select the proper prompt and display it. */ - lower_left(); - clear_eol(); - pbuf[sizeof(pbuf) - 1] = '\0'; - if (longprompt) { - /* - * Get the current line/pos from the BOTTOM of the screen - * even though that's potentially confusing for the user - * when switching between wraplines=true and a valid horiz_off - * (with wraplines=false). In exchange, it is sometimes - * easier for the user to tell when a file is relatively - * short vs. long. - */ - so_enter(); - putstr(current_name); - putstr(":"); - if (!ispipe) { - (void)snprintf(pbuf, sizeof(pbuf) - 1, - " file %d/%d", curr_ac + 1, ac); - putstr(pbuf); - } - if (linenums) { - (void)snprintf(pbuf, sizeof(pbuf) - 1, - " line %d", currline(BOTTOM)); - putstr(pbuf); - } - (void)snprintf(pbuf, sizeof(pbuf) - 1, " col %d", horiz_off); - putstr(pbuf); - if ((pos = position(BOTTOM)) != NULL_POSITION) { - (void)snprintf(pbuf, sizeof(pbuf) - 1, - " byte %qd", pos); - putstr(pbuf); - if (!ispipe && (len = ch_length())) { - (void)snprintf(pbuf, sizeof(pbuf) - 1, - "/%qd pct %qd%%", len, ((100 * pos) / len)); - putstr(pbuf); - } - } - so_exit(); - } - else { - so_enter(); - putstr(current_name); - if (hit_eof) - if (next_name) { - putstr(": END (next file: "); - putstr(next_name); - putstr(")"); - } - else - putstr(": END"); - else if (!ispipe && - (pos = position(BOTTOM)) != NULL_POSITION && - (len = ch_length())) { - (void)snprintf(pbuf, sizeof(pbuf) - 1, - " (%qd%%)", ((100 * pos) / len)); - putstr(pbuf); - } - so_exit(); - } - - /* - * XXX This isn't correct, but until we get around to reworking - * the whole prompt stuff the way we want it to be, this hack - * is necessary to prevent input from being blocked if getinput() - * is called and the user enters an input that fills the cmd - * buffer (or reaches the far rightside end of the screen). - */ - cmd_col = 0; - - return 1; -} - -/* - * Sets the current prompt. Currently it sets the current prompt to the - * long prompt. - */ -statprompt(nostatprompt) - int nostatprompt; /* Turn off the stat prompt? (off by default...) */ -{ - if (nostatprompt) - longprompt = 0; - else - longprompt = 1; -} - - -/***************************************************************************** - * - * Errors, next-of-kin to prompts. - * - */ - -/* - * Shortcut function that may be used when setting the current erreur - * and erreur string at the same time. The function name is chosen to be - * symetric with the SETERR() macro in less.h. This could be written as - * macro, too, but we'd need to use a GNU C extension. - */ -SETERRSTR(enum error e, const char *s, ...) -{ - va_list args; - - erreur = e; - if (errstr) free(errstr); - errstr = NULL; - va_start(args, s); - vasprintf(&errstr, s, args); - va_end(args); -} - -/* - * Prints an error message and clears the current error. - */ -handle_error() -{ - if (erreur == E_OK) - return; - - bell(); - if (errstr) - error(errstr); - else - error(deferr[erreur]); - erreur = E_OK; - errstr = NULL; -} - -/* - * Clears any error messages and pretends they never occurred. - */ -clear_error() -{ - erreur = E_OK; - if (errstr) free(errstr); - errstr = NULL; -} - -int errmsgs; -static char return_to_continue[] = "(press RETURN)"; - -/* - * Output a message in the lower left corner of the screen - * and wait for carriage return. - */ -/* static */ -error(s) - char *s; -{ - extern int any_display; - int ch; - - errmsgs++; - if (!any_display) { - /* - * Nothing has been displayed yet. Output this message on - * error output (file descriptor 2) and don't wait for a - * keystroke to continue. - * - * This has the desirable effect of producing all error - * messages on error output if standard output is directed - * to a file. It also does the same if we never produce - * any real output; for example, if the input file(s) cannot - * be opened. If we do eventually produce output, code in - * edit() makes sure these messages can be seen before they - * are overwritten or scrolled away. - */ - (void)write(2, s, strlen(s)); - (void)write(2, "\n", 1); - return; - } - - lower_left(); - clear_eol(); - so_enter(); - if (s) { - putstr(s); - putstr(" "); - } - putstr(return_to_continue); - so_exit(); - - if ((ch = getchr()) != '\n') { - /* XXX hardcoded */ - if (ch == 'q') - quit(); - ungotcc = ch; - } - lower_left(); - - if ((s==NULL)?0:(strlen(s)) + sizeof(return_to_continue) + - so_width + se_width + 1 > sc_width) { - /* - * Printing the message has probably scrolled the screen. - * {{ Unless the terminal doesn't have auto margins, - * in which case we just hammered on the right margin. }} - */ - /* XXX Should probably just set screen_trashed=1, but I'm - * not going to touch that until all the places that call - * error() have been checked, or until error() is staticized. */ - repaint(); - } - flush(); -} - - -/**************************************************************************** - * - * The main command processor. - * - * (Well, it deals with things on the prompt line, doesn't it?) - * - */ - -/* - * Main command processor. - * - * Accept and execute commands until a quit command, then return. - */ -commands() -{ - enum runmacro runmacro(); - enum runmacro rmret; - long numberN; - enum { NOTGOTTEN=0, GOTTEN=1, GETTING } Nstate; /* ie. numberNstate */ - int c; - char inbuf[20], *incur = inbuf; - *inbuf = '\0'; - - Nstate = GETTING; - for (;;) { - /* - * See if any signals need processing. - */ - if (sigs) - psignals(); - - /* - * Display prompt and generally get setup. Don't display the - * prompt if we are already in the middle of accepting a - * set of characters. - */ - if (!*inbuf && !prompt()) { - next_file(1); - continue; - } - - c = getcc(); - - /* Check sigs here --- getcc() may have given us READ_INTR */ - if (sigs) { - /* terminate any current macro */ - *inbuf = '\0'; - incur = inbuf; - - continue; /* process the sigs */ - } - - if (Nstate == GETTING && !isdigit(c) - && c != erase_char && c != werase_char && c != kill_char) { - /* - * Mark the end of an input number N, if any. - */ - - if (!*inbuf) { - /* We never actually got an input number */ - Nstate = NOTGOTTEN; - } else { - numberN = atol(inbuf); - Nstate = GOTTEN; - } - *inbuf = '\0'; - incur = inbuf; - } - (void) cmd_char(c, inbuf, &incur, inbuf + sizeof(inbuf) - 1); - *incur = '\0'; - if (*inbuf) - prmpt(inbuf); - else - Nstate = GETTING; /* abort command */ - - if (Nstate == GETTING) { - /* Still reading in the number N ... don't want to - * try running the macro expander. */ - continue; - } else { - /* Try expanding the macro */ - switch (runmacro(inbuf, numberN, Nstate)) { - case TOOMACRO: - break; - case BADMACRO: case NOMACRO: case BADCOMMAND: - handle_error(); - /* fallthrough */ - case OK: - /* recock */ - *inbuf = '\0'; - incur = inbuf; - Nstate = GETTING; - break; - } - } - } /* for (;;) */ -} - - -/***************************************************************************** - * - * Misc functions that belong in ncommand.c but are here for historical - * and for copyright reasons. - * - */ - -editfile() -{ - off_t position(); - extern char *current_file; - static int dolinenumber; - static char *editor; - char *base; - int linenumber; - char buf[MAXPATHLEN * 2 + 20], *getenv(); - - if (editor == NULL) { - editor = getenv("EDITOR"); - - /* default editor is vi */ - if (editor == NULL || *editor == '\0') - editor = _PATH_VI; - - /* check last component in case of full path */ - base = strrchr(editor, '/'); - if (!base) - base = editor; - else - base++; - - /* emacs also accepts vi-style +nnnn */ - if (strncmp(base, "vi", 2) == 0 || strcmp(base, "emacs") == 0) - dolinenumber = 1; - else - dolinenumber = 0; - } - /* - * XXX Can't just use currline(MIDDLE) since that might be NULL_POSITION - * if we are editting a short file or some kind of search positioned - * us near the last line. It's not clear what currline() should do - * in those circumstances, but as of this writing, it doesn't do - * anything reasonable from our perspective. The currline(MIDDLE) - * never had the desired results for an editfile() after a search() - * anyways. Note, though, that when vi(1) starts its editting, it - * positions the focus line in the middle of the screen, not the top. - * - * I think what is needed is some kind of setfocus() and getfocus() - * function. This could put the focussed line in the middle, top, - * or wherever as per the user's wishes, and allow things like us - * to getfocus() the correct file-position/line-number. A search would - * then search forward (or backward) from the current focus position, - * etc. - * - * currline() doesn't belong. - */ - if (position(MIDDLE) == NULL_POSITION) - linenumber = currline(TOP); - else - linenumber = currline(MIDDLE); - if (dolinenumber && linenumber) - (void)snprintf(buf, sizeof(buf), - "%s +%d %s", editor, linenumber, current_file); - else - (void)snprintf(buf, sizeof(buf), "%s %s", editor, current_file); - lsystem(buf); -} - -showlist() -{ - extern int sc_width; - register int indx, width; - int len; - char *p; - - if (ac <= 0) { - error("No files provided as arguments."); - return; - } - for (width = indx = 0; indx < ac;) { - p = strcmp(av[indx], "-") ? av[indx] : "stdin"; - len = strlen(p) + 1; - if (curr_ac == indx) - len += 2; - if (width + len + 1 >= sc_width) { - if (!width) { - if (curr_ac == indx) - putchr('['); - putstr(p); - if (curr_ac == indx) - putchr(']'); - ++indx; - } - width = 0; - putchr('\n'); - continue; - } - if (width) - putchr(' '); - if (curr_ac == indx) - putchr('['); - putstr(p); - if (curr_ac == indx) - putchr(']'); - width += len; - ++indx; - } - putchr('\n'); - error((char *)NULL); -} diff --git a/usr.bin/more/default.morerc b/usr.bin/more/default.morerc deleted file mode 100644 index 497f01c..0000000 --- a/usr.bin/more/default.morerc +++ /dev/null @@ -1,180 +0,0 @@ -# -# This is the default initialization file for more(1). To avoid any need to -# change the manpage or helpfile, almost all commands maintain their historical -# keymappings. Some additional twoggles may be added that will be left for -# the intrepid user to discover. -# -# This file is compiled directly into more; changing this file will not change -# the actual defaults (unless it is changed in the source directory and more -# is recompiled). The correct way to change the global defaults is by -# adding a /etc/dot.morerc global initialization file. -# -# In general, the average user is not expected have any interest in changing -# default keybindings. -# -# If you use an ~/.morerc that is dependent on specific features of this -# default morerc, you should copy this default morerc to ~/.defmorerc so that -# possible future changes in this file do not cause problems for you. The -# ~/.defmorerc file will cause the compiled-in default morerc to be ignored. -# -# The default initialization file is compiled into more(1) so that more(1) -# will work and be usable even if the filesystem (and the location -# /usr/share/misc/default.morerc, where this would be stored if it was not -# compiled into more(1)) is missing or away without leave (chroot directory, -# fs crash, badly written rescue floppy, or any other reason). -# -# BUGS: a) There is no documentation (this is arguably a feature). -# b) There is no "map" command. -# -# $FreeBSD$ -# - -# The "deftog" is required to initialize more(1). -# -# Each of the toggle variables in the proceeding list will be initialized. -# A toggle variable "togvar" will be initialized into two variables: -# ${togvar_s} and ${togvar_n}. The _s variant will hold a string representing -# the toggle state, and the _n variant will hold a number representing the -# toggle state. The toggle states are numbered from 0 to n, in the order -# listed for the toggle. -# -# _ls_direction forw back direction of last search -# _ls_sense noinvert invert find match/non-matching to last search -# _wraplines off on currently wrapping lines? -# _statprompt on off currently displaying the long prompt? -# -# If the fact that "off on" is in a different order from "on off" bothers -# you, then you are probably abusing the variables. -# -# Additionally, the following variables are set, -# -# ${_curhscroll} number of columns scrolled horizontally -# ${_ls_regexp} regular expression from the last search -# -# In addition to variables set by deftog, the following variables are -# also available, -# -# ${_sc_height} number of rows on the screen -# ${_sc_width} number of columns on the screen -# ${_termcap_XX} where 'XX' refers to any of the termcap codes from -# termcap(5), string, numeric, or flag -# - -deftog - - -# -# basic internal initialization for things used inside this file -# -set lsthscr 1 -# Add "set hkey_scroll true" to ~/.morerc to enable all the hjkl keys (but -# disabling h)elp). -set hkey_scroll false -set scr_scroll 0 -# We have no way of resetting this on SIGWINCH as the old more A_H_SCROLL did -# It's probably just as well... (since resetting would lose the old value!) -# (Actually, we could emulate it from here if we really wanted to). -set half_scroll (${_sc_height} / 2) -# magic number indicating the value is not initialized -set savedhscroll 87382 - -macro 1 j 'forw_scroll ${number}' -macro 1 k 'back_scroll ${number}' -macro 1 "${_termcap_kd}" \ - 'forw_scroll ${number}' -macro 1 "${_termcap_ku}" \ - 'back_scroll ${number}' -macro 1 \n 'forw_scroll ${number}' -macro 1 "${_termcap_kN}" \ - 'forw (${_sc_height} * ${number})' -macro 1 "${_termcap_kP}" \ - 'back (${_sc_height} * ${number})' -set com_getscr 'condition (${number} != 0); \ - set scr_scroll ${number}; \ - condition (${number} == 0); \ - set scr_scroll ${_sc_height}; \ - condition true;' -macro 0 " " 'eval ${com_getscr}; forw ${scr_scroll};' -macro 0 f 'eval ${com_getscr}; forw ${scr_scroll};' -macro 0 "" 'eval ${com_getscr}; forw ${scr_scroll};' -macro 0 b 'eval ${com_getscr}; back ${scr_scroll};' -macro 0 "" 'eval ${com_getscr}; back ${scr_scroll};' -set com_sethalfscroll 'condition (${number} != 0); \ - set half_scroll ${number}; \ - condition true;' -macro 0 d 'eval ${com_sethalfscroll}; forw_scroll ${half_scroll}' -macro 0 "" 'eval ${com_sethalfscroll}; forw_scroll ${half_scroll}' -macro 0 u 'eval ${com_sethalfscroll}; back_scroll ${half_scroll}' -macro 0 "" 'eval ${com_sethalfscroll}; back_scroll ${half_scroll}' -# An argument can be made that we should move by whatever tab was set to -# using the -x argument to more(1) -macro 1 "\t" 'rscroll (${number} * 8)' -macro 1 '[Z' 'lscroll (${number} * 8)' -set com_rscroll 'condition (${number} != 0); \ - set lsthscr ${number}; \ - condition true; \ - rscroll ${lsthscr};' -set com_lscroll 'condition (${number} != 0); \ - set lsthscr ${number}; \ - condition true; \ - lscroll ${lsthscr};' -# this little trick lets the user simply set hkey_scroll=true in their own -# ~/.morerc file to enable the 'l' and 'h' keys the way Bill meant them -macro 0 h 'condition ${hkey_scroll}; eval ${com_lscroll}; \ - condition_! ${hkey_scroll}; help; \ - condition true;' -macro 0 l 'condition ${hkey_scroll}; eval ${com_rscroll}; \ - condition_! ${hkey_scroll}; error "key not enabled"; \ - condition true;' -macro 0 :help 'help' -macro 0 "${_termcap_kr}" \ - 'eval ${com_rscroll}' -macro 0 "${_termcap_kl}" \ - 'eval ${com_lscroll}' -macro 0 "${_termcap_kh}" \ - 'condition (${_wraplines_n} && (${savedhscroll} != 87382)); \ - rscroll 1; \ - rscroll ${savedhscroll}; \ - condition_toggle; \ - set savedhscroll ${_curhscroll}; \ - lscroll ${_curhscroll}; \ - lscroll 1; \ - condition true;' -macro 1 n 'research ${_ls_direction_n} ${number}' -macro 1 N 'research (${_ls_direction_n} + 1) ${number}' -macro 1 / 'magicasksearch forw ${number}' -macro 1 ? 'magicasksearch back ${number}' -macro 0 G 'condition (${number} == 0); goend; \ - condition (${number} != 0); goline ${number}; \ - condition true;' -macro 1 g 'goline ${number}' -macro 0 p 'gopercent ${number}' -macro 0 % 'gopercent ${number}' -macro 0 "${_termcap_@7}" \ - 'goend' -# Quote since it's technically an isspace() character -macro 0 "" 'repaint' -macro 0 r 'repaint' -macro 0 R 'flush' -macro 0 v 'edit' -macro 0 :e 'askfile' -macro 0 E 'askfile' -# The old keymaping for 'N' -#macro 1 N 'file next ${number}' -macro 1 :n 'file next ${number}' -macro 1 P 'file prev ${number}' -macro 1 :p 'file prev ${number}' -macro 0 :a 'file_list' -macro 0 m 'setmark ?' -macro 0 \' 'gomark ?' -macro 0 :t 'asktag' -macro 1 t 'nexttag ${number}' -macro 1 T 'prevtag ${number}' -macro 0 "" 'stat (${_statprompt_n} + 1)' -macro 0 = 'stat (${_statprompt_n} + 1)' -macro 0 q 'quit' -macro 0 :q 'quit' -macro 0 ZZ 'quit' -# This command intentionally disabled by default. The command parser is -# too baroque to expose hapless users to. -#macro 0 :: 'usercom' diff --git a/usr.bin/more/help.c b/usr.bin/more/help.c deleted file mode 100644 index 6e39c99..0000000 --- a/usr.bin/more/help.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1988 Mark Nudleman - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char sccsid[] = "@(#)help.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ - -#include <sys/param.h> -#include <less.h> - -#include "pathnames.h" - -extern int top_scroll; - -help() -{ - char cmd[MAXPATHLEN + 20]; - - snprintf(cmd, sizeof(cmd), "-more -e%c %s", - top_scroll ? 'c' : ' ', - _PATH_HELPFILE); - lsystem(cmd); -} diff --git a/usr.bin/more/input.c b/usr.bin/more/input.c deleted file mode 100644 index 1ecd346..0000000 --- a/usr.bin/more/input.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (c) 1988 Mark Nudleman - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char sccsid[] = "@(#)input.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ - -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -/* - * High level routines dealing with getting lines of input - * from the file being viewed. - * - * When we speak of "lines" here, we mean PRINTABLE lines; - * lines processed with respect to the screen width. - * We use the term "raw line" to refer to lines simply - * delimited by newlines; not processed with respect to screen width. - */ - -#include <sys/types.h> - -#include "less.h" - -/* NOTE!: if (wraplines) assert (horiz_off == 0) */ -int horiz_off = 0; /* # characters scrolled off left of screen */ -int wraplines = 1; /* wrap lines around screen, yes or no */ - -extern int squeeze; -extern int sigs; -extern char *line; - -off_t ch_tell(); - -/* - * Get the next printable line. - * - * A "current" position is passed and a "new" position is returned. - * The current position is the position of the first character of - * a line. The new position is the position of the first character - * of the NEXT line. The line obtained is the line starting at curr_pos. - * It is placed into the global line buffer ("line"). - */ -off_t -forw_line(curr_pos) - off_t curr_pos; -{ - off_t new_pos; - register int c; - - if (curr_pos == NULL_POSITION || ch_seek(curr_pos)) - return (NULL_POSITION); - - c = ch_forw_get(); - if (c == EOI) - return (NULL_POSITION); - - prewind(); - for (;;) - { - if (sigs) - return (NULL_POSITION); - if (c == '\n' || c == EOI) - { - /* - * End of the line. - */ - new_pos = ch_tell(); - break; - } - - /* - * Append the char to the line and get the next char. - * The pappend() will throw away any unimportant chars - * (ie. not underlines or bolds) as per wraplines. - * - * XXX line.c needs to be rewritten... - */ - if (pappend(c)) - { - /* - * The char won't fit in the line; the line - * is too long to print in the screen width. - * End the line here. - */ - if (!wraplines) { - /* Throw away left-over characters on line */ - c = ch_forw_get(); - while (c != '\n' && c != EOI) - c = ch_forw_get(); - new_pos = ch_tell(); - } else { - new_pos = ch_tell() - 1; - } - break; - } - c = ch_forw_get(); - } - (void) pappend('\0'); - - if (squeeze && *line == '\0') - { - /* - * This line is blank. - * Skip down to the last contiguous blank line - * and pretend it is the one which we are returning. - */ - while ((c = ch_forw_get()) == '\n') - if (sigs) - return (NULL_POSITION); - if (c != EOI) - (void) ch_back_get(); - new_pos = ch_tell(); - } - - return (new_pos); -} - -/* - * Get the previous line. - * - * A "current" position is passed and a "new" position is returned. - * The current position is the position of the first character of - * a line. The new position is the position of the first character - * of the PREVIOUS line. The line obtained is the one starting at new_pos. - * It is placed into the global line buffer ("line"). - */ -off_t -back_line(curr_pos) - off_t curr_pos; -{ - off_t new_pos, begin_new_pos; - int c; - - if (curr_pos == NULL_POSITION || curr_pos <= (off_t)0 || - ch_seek(curr_pos-1)) - return (NULL_POSITION); - - if (squeeze) - { - /* - * Find out if the "current" line was blank. - */ - (void) ch_forw_get(); /* Skip the newline */ - c = ch_forw_get(); /* First char of "current" line */ - (void) ch_back_get(); /* Restore our position */ - (void) ch_back_get(); - - if (c == '\n') - { - /* - * The "current" line was blank. - * Skip over any preceeding blank lines, - * since we skipped them in forw_line(). - */ - while ((c = ch_back_get()) == '\n') - if (sigs) - return (NULL_POSITION); - if (c == EOI) - return (NULL_POSITION); - (void) ch_forw_get(); - } - } - - /* - * Scan backwards until we hit the beginning of the line. - */ - for (;;) - { - if (sigs) - return (NULL_POSITION); - c = ch_back_get(); - if (c == '\n') - { - /* - * This is the newline ending the previous line. - * We have hit the beginning of the line. - */ - new_pos = ch_tell() + 1; - break; - } - if (c == EOI) - { - /* - * We have hit the beginning of the file. - * This must be the first line in the file. - * This must, of course, be the beginning of the line. - */ - new_pos = ch_tell(); - break; - } - } - - /* - * Now scan forwards from the beginning of this line. - * We keep discarding "printable lines" (based on screen width) - * until we reach the curr_pos. - * - * {{ This algorithm is pretty inefficient if the lines - * are much longer than the screen width, - * but I don't know of any better way. }} - */ - if (ch_seek(new_pos)) - return (NULL_POSITION); - loop: - begin_new_pos = new_pos; - prewind(); - - do - { - c = ch_forw_get(); - if (c == EOI || sigs) - return (NULL_POSITION); - new_pos++; - if (c == '\n') - break; - if (pappend(c)) - { - if (wraplines) { - /* - * Got a full printable line, but we haven't - * reached our curr_pos yet. Discard the line - * and start a new one. - */ - (void) pappend('\0'); - (void) ch_back_get(); - new_pos--; - goto loop; - } else - break; /* Got everything we need */ - } - } while (new_pos < curr_pos); - - (void) pappend('\0'); - - return (begin_new_pos); -} diff --git a/usr.bin/more/less.h b/usr.bin/more/less.h deleted file mode 100644 index e383068..0000000 --- a/usr.bin/more/less.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 1988 Mark Nudleman - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)less.h 8.1 (Berkeley) 6/6/93 - * - * $FreeBSD$ - */ - -#define MAXVARLENGTH (20) - -#define NULL_POSITION ((off_t)(-1)) - -#define EOI (0) -#define READ_INTR (-2) - -/* Special chars used to tell put_line() to do something special */ -#define UL_CHAR '\201' /* Enter underline mode */ -#define UE_CHAR '\202' /* Exit underline mode */ -#define BO_CHAR '\203' /* Enter boldface mode */ -#define BE_CHAR '\204' /* Exit boldface mode */ - -#define CONTROL_CHAR(c) (!isprint(c)) -#define CARAT_CHAR(c) ((c == '\177') ? '?' : (c | 0100)) - -#define TOP (0) -#define TOP_PLUS_ONE (1) -#define BOTTOM (-1) -#define BOTTOM_PLUS_ONE (-2) -#define MIDDLE (-3) - -/* The return type of runmacro() */ -enum runmacro { OK=0, TOOMACRO, BADMACRO, NOMACRO, BADCOMMAND }; - -#define NOFLAGS 0 -#define FORCE_OPEN 0 /* edit() flag */ -#define NO_FORCE_OPEN 1 /* edit() flag */ - -#ifdef DEFINEGLOBALS -#define GLOBAL(var, val) var = val -#else -#define GLOBAL(var, val) extern var -#endif - -/* - * This style of error-reporting (see also command.c) is only used by some - * code. Eventually most of the code should use it, since it is becoming - * inconvenient to have John Q. random function() calling error(). - * - * This style of error-reporting still leaves somewhat to be desired.... - * - * Note that more(1) needs to potentially work under low-memory conditions - * (such as may occur when all available memory has been sucked-up by - * the file buffer in ch.c). - */ - -/* Be careful about ordering correctly!! (must match deferrinit_) */ -enum error { E_OK=0, E_AMBIG, E_BADMATH, E_BADVAR, E_BOGCOM, E_CANTPARSE, - E_CANTXPND, E_COMPLIM, E_EXTERN, E_NOMAC, E_MALLOC, E_NONUM, - E_NOSTR, E_NOTOG, E_NULL }; - -/* Listed here for reference only. Be careful about ordering correctly!! */ -#define deferrinit_ { \ - "", /* E_OK */ \ - "ambigious macro", /* E_AMBIG */ \ - "invalid arithmetic expression", /* E_BADMATH */ \ - "bad variable", /* E_BADVAR */ \ - "bogus command", /* E_BOGCOM */ \ - "could not parse command string", /* E_CANTPARSE */ \ - "could not expand macro", /* E_CANTXPND */ \ - "compile time limit", /* E_COMPLIM */ \ - "external dependency error", /* E_EXTERN */ \ - "could not find match for macro", /* E_NOMAC */ \ - "malloc() failed", /* E_MALLOC */ \ - "missing numeric argument to command", /* E_NONUM */ \ - "missing string argument to command", /* E_NOSTR */ \ - "bad n-toggle argument to command", /* E_NOTOG */ \ - "to the unknown error", /* E_NULL */ \ -} -GLOBAL(const char *deferr[], deferrinit_ ); - -/* - * It is possible for erreur to become unsynchronized from errstr if - * its users aren't careful. Access through the macros is considered - * careful. - */ -GLOBAL(enum error erreur, NULL); -GLOBAL(char *errstr, NULL); /* must point be null or free()'ble */ - -#define SETERR(e) do { \ - erreur = (e); \ - if (errstr) free(errstr); \ - errstr = NULL; \ - } while (0) -/* SETERRSTR() also exists. It is in command.c */ - -/* - * An emalloc() traditionally never fails, but fmalloc() may fail, hence - * the non-standard name. The fmalloc() is just syntactic sugar that sets - * erreur for the user. - * - * fmalloc(size, pointer-to-new-memory); - * - * Don't compile this puppy with -Wall or she'll squeel loud! - */ - -#define FMALLOC(s,v) ((((v) = malloc(s)) ? 0 : \ - ((errstr ? free(errstr), errstr=NULL : 0), erreur = E_MALLOC)), (v)) diff --git a/usr.bin/more/less.morerc b/usr.bin/more/less.morerc deleted file mode 100644 index 95fb905..0000000 --- a/usr.bin/more/less.morerc +++ /dev/null @@ -1,61 +0,0 @@ -# -# This sample .morerc causes more to emulate the default GNU less(1) -# keys, in so far as more(1) is capable (which is not very far at the -# moment). -# -# Some of this will/should/may be eventually merged into default.morerc. -# -# $FreeBSD$ -# - -# magic value indicating we should use ${sc_height} -set window 2424989898 - -macro 0 H 'help' -set com_getscr 'condition (${number} == 0); \ - condition (${window} == 2424989898); \ - set scr_scroll ${sc_height}; \ - condition_toggle; \ - set scr_scroll ${window}; \ - condition (${number} != 0); \ - set scr_scroll ${number}; \ - condition true;' -macro 0 "" 'eval ${com_getscr}; forw ${scr_scroll};' -macro 0 z 'condition (${number} == 0); \ - eval ${com_getscr}; forw ${scr_scroll}; \ - condition (${number} != 0); \ - set window ${number}; forw ${number}; \ - condition true;' -macro 0 w 'condition (${number} == 0); \ - eval ${com_getscr}; back ${scr_scroll}; \ - condition (${number} != 0); \ - set window ${number}; back ${number}; \ - condition true;' -macro 0 "\ev" 'eval ${com_getscr}; back ${scr_scroll};' -macro 1 "" 'forw_scroll ${number};' -macro 1 e 'forw_scroll ${number};' -macro 1 "" 'forw_scroll ${number};' -macro 1 y 'back_scroll ${number};' -macro 1 "" 'back_scroll ${number};' -macro 1 "" 'back_scroll ${number};' -macro 1 "" 'back_scroll ${number};' -macro 8 \e) 'rscroll ${number};' -macro 8 \e[C 'rscroll ${number};' -macro 8 \e( 'lscroll ${number};' -macro 8 \e[D 'lscroll ${number};' -macro 1 "<" 'goline ${number};' -macro 1 "\e<" 'goline ${number}; -macro 0 ">" 'condition (${number} == 0); goend; \ - condition (${number} != 0); goline ${number}; \ - condition true;' -macro 0 "\e>" 'condition (${number} == 0); goend; \ - condition (${number} != 0); goline ${number}; \ - condition true;' -macro 0 "" 'gomark ?;' -macro 0 "" 'askfile;' -macro 0 :f 'stat (${_stat_n} + 1);' -macro 0 V 'error "Less is not being run!" -macro 0 Q 'quit;' -macro 0 :Q 'quit;' -# It might be possible to match the brace/bracket-pairing feature of -# less using some complex regexps... Project for a rain weekend... :-) diff --git a/usr.bin/more/line.c b/usr.bin/more/line.c deleted file mode 100644 index f974e83..0000000 --- a/usr.bin/more/line.c +++ /dev/null @@ -1,522 +0,0 @@ -/* - * Copyright (c) 1988 Mark Nudleman - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char sccsid[] = "@(#)line.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ - -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -/* - * Routines to manipulate the "line buffer". - * The line buffer holds a line of output as it is being built - * in preparation for output to the screen. - * We keep track of the PRINTABLE length of the line as it is being built. - */ - -#include <sys/types.h> - -#include <ctype.h> - -#include "less.h" - -static char linebuf[8192]; /* Buffer to hold the current output line */ -static char *curr; /* Pointer into linebuf */ -static int column; /* Printable length, accounting for - backspaces, etc. */ -/* - * A ridiculously complex state machine takes care of backspaces. The - * complexity arises from the attempt to deal with all cases, especially - * involving long lines with underlining, boldfacing or whatever. There - * are still some cases which will break it. - * - * There are four states: - * LN_NORMAL is the normal state (not in underline mode). - * LN_UNDERLINE means we are in underline mode. We expect to get - * either a sequence like "_\bX" or "X\b_" to continue - * underline mode, or anything else to end underline mode. - * LN_BOLDFACE means we are in boldface mode. We expect to get sequences - * like "X\bX\b...X\bX" to continue boldface mode, or anything - * else to end boldface mode. - * LN_UL_X means we are one character after LN_UNDERLINE - * (we have gotten the '_' in "_\bX" or the 'X' in "X\b_"). - * LN_UL_XB means we are one character after LN_UL_X - * (we have gotten the backspace in "_\bX" or "X\b_"; - * we expect one more ordinary character, - * which will put us back in state LN_UNDERLINE). - * LN_BO_X means we are one character after LN_BOLDFACE - * (we have gotten the 'X' in "X\bX"). - * LN_BO_XB means we are one character after LN_BO_X - * (we have gotten the backspace in "X\bX"; - * we expect one more 'X' which will put us back - * in LN_BOLDFACE). - */ -static int ln_state; /* Current normal/underline/bold/etc mode */ -#define LN_NORMAL 0 /* Not in underline/boldface/whatever mode */ -#define LN_UNDERLINE 1 /* In underline, need next char */ -#define LN_UL_X 2 /* In underline, got char, need \b */ -#define LN_UL_XB 3 /* In underline, got char & \b, need one more */ -#define LN_BOLDFACE 4 /* In boldface, need next char */ -#define LN_BO_X 5 /* In boldface, got char, need \b */ -#define LN_BO_XB 6 /* In boldface, got char & \b, need same char */ - -char *line; /* Pointer to the current line. - Usually points to linebuf. */ - -extern int bs_mode; -extern int tabstop; -extern int bo_width, be_width; -extern int ul_width, ue_width; -extern int sc_width, sc_height; -extern int horiz_off; - -/* - * Rewind the line buffer. - */ -prewind() -{ - line = curr = linebuf; - ln_state = LN_NORMAL; - column = -horiz_off; -} - -/* - * Append a character to the line buffer. - * Expand tabs into spaces, handle underlining, boldfacing, etc. - * Returns 0 if ok, 1 if couldn't fit in buffer. Characters before horiz_off - * will be added to the buffer but will not count against the line size. - * - * XXX This function sucks. - */ -#define NEW_COLUMN(addon) \ - if (column + addon + (ln_state ? ue_width : 0) > sc_width) \ - return(1); \ - else \ - column += addon - -pappend(c) - int c; -{ - if (c == '\0') { - /* - * Terminate any special modes, if necessary. - * Append a '\0' to the end of the line. - */ - switch (ln_state) { - case LN_UL_X: - curr[0] = curr[-1]; - curr[-1] = UE_CHAR; - curr++; - break; - case LN_BO_X: - curr[0] = curr[-1]; - curr[-1] = BE_CHAR; - curr++; - break; - case LN_UL_XB: - case LN_UNDERLINE: - *curr++ = UE_CHAR; - break; - case LN_BO_XB: - case LN_BOLDFACE: - *curr++ = BE_CHAR; - break; - } - ln_state = LN_NORMAL; - *curr = '\0'; - return(0); - } - - if (curr > linebuf + sizeof(linebuf) - 12) - /* - * Almost out of room in the line buffer. - * Don't take any chances. - * {{ Linebuf is supposed to be big enough that this - * will never happen, but may need to be made - * bigger for really long lines. }} - */ - return(1); - - if (!bs_mode) { - /* - * Advance the state machine. - */ - switch (ln_state) { - case LN_NORMAL: - if (curr <= linebuf + 1 - || curr[-1] != '\b') - break; - if (c == ((unsigned char)curr[-2])) - goto enter_boldface; - if (c == '_' || curr[-2] == '_') - goto enter_underline; - curr -= 2; - break; - -enter_boldface: - /* - * We have "X\bX" (including the current char). - * Switch into boldface mode. - */ - column--; - if (column + bo_width + be_width >= sc_width) - /* - * Not enough room left on the screen to - * enter and exit boldface mode. - */ - return (1); - - if (bo_width > 0 && curr > linebuf + 2 - && curr[-3] == ' ') { - /* - * Special case for magic cookie terminals: - * if the previous char was a space, replace - * it with the "enter boldface" sequence. - */ - curr[-3] = BO_CHAR; - column += bo_width-1; - } else { - curr[-1] = curr[-2]; - curr[-2] = BO_CHAR; - column += bo_width; - curr++; - } - goto ln_bo_xb_case; - -enter_underline: - /* - * We have either "_\bX" or "X\b_" (including - * the current char). Switch into underline mode. - */ - column--; - if (column + ul_width + ue_width >= sc_width) - /* - * Not enough room left on the screen to - * enter and exit underline mode. - */ - return (1); - - if (ul_width > 0 && - curr > linebuf + 2 && curr[-3] == ' ') - { - /* - * Special case for magic cookie terminals: - * if the previous char was a space, replace - * it with the "enter underline" sequence. - */ - curr[-3] = UL_CHAR; - column += ul_width-1; - } else - { - curr[-1] = curr[-2]; - curr[-2] = UL_CHAR; - column += ul_width; - curr++; - } - goto ln_ul_xb_case; - /*NOTREACHED*/ - case LN_UL_XB: - /* - * Termination of a sequence "_\bX" or "X\b_". - */ - if (c != '_' && curr[-2] != '_' && c == ((unsigned char)curr[-2])) - { - /* - * We seem to have run on from underlining - * into boldfacing - this is a nasty fix, but - * until this whole routine is rewritten as a - * real DFA, ... well ... - */ - curr[0] = curr[-2]; - curr[-2] = UE_CHAR; - curr[-1] = BO_CHAR; - curr += 2; /* char & non-existent backspace */ - ln_state = LN_BO_XB; - goto ln_bo_xb_case; - } -ln_ul_xb_case: - if (c == '_') - c = (unsigned char)curr[-2]; - curr -= 2; - ln_state = LN_UNDERLINE; - break; - case LN_BO_XB: - /* - * Termination of a sequnce "X\bX". - */ - if (c != ((unsigned char)curr[-2]) && (c == '_' || curr[-2] == '_')) - { - /* - * We seem to have run on from - * boldfacing into underlining. - */ - curr[0] = curr[-2]; - curr[-2] = BE_CHAR; - curr[-1] = UL_CHAR; - curr += 2; /* char & non-existent backspace */ - ln_state = LN_UL_XB; - goto ln_ul_xb_case; - } -ln_bo_xb_case: - curr -= 2; - ln_state = LN_BOLDFACE; - break; - case LN_UNDERLINE: - if (column + ue_width + bo_width + be_width >= sc_width) - /* - * We have just barely enough room to - * exit underline mode and handle a possible - * underline/boldface run on mixup. - */ - return (1); - ln_state = LN_UL_X; - break; - case LN_BOLDFACE: - if (c == '\b') - { - ln_state = LN_BO_XB; - break; - } - if (column + be_width + ul_width + ue_width >= sc_width) - /* - * We have just barely enough room to - * exit underline mode and handle a possible - * underline/boldface run on mixup. - */ - return (1); - ln_state = LN_BO_X; - break; - case LN_UL_X: - if (c == '\b') - ln_state = LN_UL_XB; - else - { - /* - * Exit underline mode. - * We have to shuffle the chars a bit - * to make this work. - */ - curr[0] = curr[-1]; - curr[-1] = UE_CHAR; - column += ue_width; - if (ue_width > 0 && curr[0] == ' ') - /* - * Another special case for magic - * cookie terminals: if the next - * char is a space, replace it - * with the "exit underline" sequence. - */ - column--; - else - curr++; - ln_state = LN_NORMAL; - } - break; - case LN_BO_X: - if (c == '\b') - ln_state = LN_BO_XB; - else - { - /* - * Exit boldface mode. - * We have to shuffle the chars a bit - * to make this work. - */ - curr[0] = curr[-1]; - curr[-1] = BE_CHAR; - column += be_width; - if (be_width > 0 && curr[0] == ' ') - /* - * Another special case for magic - * cookie terminals: if the next - * char is a space, replace it - * with the "exit boldface" sequence. - */ - column--; - else - curr++; - ln_state = LN_NORMAL; - } - break; - } - } - - if (c == '\t') { - /* - * Expand a tab into spaces. - */ - do { - NEW_COLUMN(1); - } while (((column + horiz_off) % tabstop) != 0); - *curr++ = '\t'; - return (0); - } - - if (c == '\b') { - if (ln_state == LN_NORMAL) - NEW_COLUMN(0); - else - column--; - *curr++ = c; - return(0); - } - - switch ((char)c) { - case UL_CHAR: - case UE_CHAR: - case BO_CHAR: - case BE_CHAR: - c &= ~0200; - /* fall through */ - case '\200': - NEW_COLUMN(2); - break; - default: - if (CONTROL_CHAR(c)) - NEW_COLUMN(2); - else - NEW_COLUMN(1); - break; - } - - *curr++ = c; - return (0); -} - -/* - * Analogous to forw_line(), but deals with "raw lines": - * lines which are not split for screen width. - * {{ This is supposed to be more efficient than forw_line(). }} - */ -off_t -forw_raw_line(curr_pos) - off_t curr_pos; -{ - register char *p; - register int c; - off_t new_pos, ch_tell(); - - if (curr_pos == NULL_POSITION || ch_seek(curr_pos) || - (c = ch_forw_get()) == EOI) - return (NULL_POSITION); - - p = linebuf; - - for (;;) - { - if (c == '\n' || c == EOI) - { - new_pos = ch_tell(); - break; - } - if (p >= &linebuf[sizeof(linebuf)-1]) - { - /* - * Overflowed the input buffer. - * Pretend the line ended here. - * {{ The line buffer is supposed to be big - * enough that this never happens, but it's - * statically allocated, so that's really just - * a pipe dream. This causes no end of trouble. - * The line.c needs to be rewritten. }} - */ - new_pos = ch_tell() - 1; - break; - } - *p++ = c; - c = ch_forw_get(); - } - *p = '\0'; - line = linebuf; - return (new_pos); -} - -/* - * Analogous to back_line(), but deals with "raw lines". - * {{ This is supposed to be more efficient than back_line(). }} - */ -off_t -back_raw_line(curr_pos) - off_t curr_pos; -{ - register char *p; - register int c; - off_t new_pos, ch_tell(); - - if (curr_pos == NULL_POSITION || curr_pos <= (off_t)0 || - ch_seek(curr_pos-1)) - return (NULL_POSITION); - - p = &linebuf[sizeof(linebuf)]; - *--p = '\0'; - - for (;;) - { - c = ch_back_get(); - if (c == '\n') - { - /* - * This is the newline ending the previous line. - * We have hit the beginning of the line. - */ - new_pos = ch_tell() + 1; - break; - } - if (c == EOI) - { - /* - * We have hit the beginning of the file. - * This must be the first line in the file. - * This must, of course, be the beginning of the line. - */ - new_pos = (off_t)0; - break; - } - if (p <= linebuf) - { - /* - * Overflowed the input buffer. - * Pretend the line ended here. - */ - new_pos = ch_tell() + 1; - break; - } - *--p = c; - } - line = p; - return (new_pos); -} diff --git a/usr.bin/more/linenum.c b/usr.bin/more/linenum.c deleted file mode 100644 index 84fa04b..0000000 --- a/usr.bin/more/linenum.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Copyright (c) 1988 Mark Nudleman - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char sccsid[] = "@(#)linenum.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ - -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -/* - * Code to handle displaying line numbers. - * - * Finding the line number of a given file position is rather tricky. - * We don't want to just start at the beginning of the file and - * count newlines, because that is slow for large files (and also - * wouldn't work if we couldn't get to the start of the file; e.g. - * if input is a long pipe). - * - * So we use the function add_lnum to cache line numbers. - * We try to be very clever and keep only the more interesting - * line numbers when we run out of space in our table. A line - * number is more interesting than another when it is far from - * other line numbers. For example, we'd rather keep lines - * 100,200,300 than 100,101,300. 200 is more interesting than - * 101 because 101 can be derived very cheaply from 100, while - * 200 is more expensive to derive from 100. - * - * The function currline() returns the line number of a given - * position in the file. As a side effect, it calls add_lnum - * to cache the line number. Therefore currline is occasionally - * called to make sure we cache line numbers often enough. - */ - -#include <sys/types.h> -#include <stdio.h> -#include <less.h> - -/* - * Structure to keep track of a line number and the associated file position. - * A doubly-linked circular list of line numbers is kept ordered by line number. - */ -struct linenum -{ - struct linenum *next; /* Link to next in the list */ - struct linenum *prev; /* Line to previous in the list */ - off_t pos; /* File position */ - off_t gap; /* Gap between prev and next */ - int line; /* Line number */ -}; -/* - * "gap" needs some explanation: the gap of any particular line number - * is the distance between the previous one and the next one in the list. - * ("Distance" means difference in file position.) In other words, the - * gap of a line number is the gap which would be introduced if this - * line number were deleted. It is used to decide which one to replace - * when we have a new one to insert and the table is full. - */ - -#define NPOOL 50 /* Size of line number pool */ - -#define LONGTIME (2) /* In seconds */ - -int lnloop = 0; /* Are we in the line num loop? */ - -static struct linenum anchor; /* Anchor of the list */ -static struct linenum *freelist; /* Anchor of the unused entries */ -static struct linenum pool[NPOOL]; /* The pool itself */ -static struct linenum *spare; /* We always keep one spare entry */ - -extern int linenums; -extern int sigs; - -/* - * Initialize the line number structures. - */ -clr_linenum() -{ - register struct linenum *p; - - /* - * Put all the entries on the free list. - * Leave one for the "spare". - */ - for (p = pool; p < &pool[NPOOL-2]; p++) - p->next = p+1; - pool[NPOOL-2].next = NULL; - freelist = pool; - - spare = &pool[NPOOL-1]; - - /* - * Initialize the anchor. - */ - anchor.next = anchor.prev = &anchor; - anchor.gap = (off_t)0; - anchor.pos = (off_t)0; - anchor.line = 1; -} - -/* - * Calculate the gap for an entry. - */ -static -calcgap(p) - register struct linenum *p; -{ - /* - * Don't bother to compute a gap for the anchor. - * Also don't compute a gap for the last one in the list. - * The gap for that last one should be considered infinite, - * but we never look at it anyway. - */ - if (p == &anchor || p->next == &anchor) - return; - p->gap = p->next->pos - p->prev->pos; -} - -/* - * Add a new line number to the cache. - * The specified position (pos) should be the file position of the - * FIRST character in the specified line. - */ -add_lnum(line, pos) - int line; - off_t pos; -{ - register struct linenum *p; - register struct linenum *new; - register struct linenum *nextp; - register struct linenum *prevp; - register off_t mingap; - - /* - * Find the proper place in the list for the new one. - * The entries are sorted by position. - */ - for (p = anchor.next; p != &anchor && p->pos < pos; p = p->next) - if (p->line == line) - /* We already have this one. */ - return; - nextp = p; - prevp = p->prev; - - if (freelist != NULL) - { - /* - * We still have free (unused) entries. - * Use one of them. - */ - new = freelist; - freelist = freelist->next; - } else - { - /* - * No free entries. - * Use the "spare" entry. - */ - new = spare; - spare = NULL; - } - - /* - * Fill in the fields of the new entry, - * and insert it into the proper place in the list. - */ - new->next = nextp; - new->prev = prevp; - new->pos = pos; - new->line = line; - - nextp->prev = new; - prevp->next = new; - - /* - * Recalculate gaps for the new entry and the neighboring entries. - */ - calcgap(new); - calcgap(nextp); - calcgap(prevp); - - if (spare == NULL) - { - /* - * We have used the spare entry. - * Scan the list to find the one with the smallest - * gap, take it out and make it the spare. - * We should never remove the last one, so stop when - * we get to p->next == &anchor. This also avoids - * looking at the gap of the last one, which is - * not computed by calcgap. - * - * XXX Should also ensure that we can determine the line - * number in the case where we are reading from a pipe - * and we no longer have the first block(s) of data from - * the pipe buffered in ch.c. Further, keeping linenum - * entries for lines in this case that have been thrown- - * out of the buffer is fairly pointless. - */ - mingap = anchor.next->gap; - for (p = anchor.next; p->next != &anchor; p = p->next) - { - if (p->gap <= mingap) - { - spare = p; - mingap = p->gap; - } - } - calcgap(spare->next->prev = spare->prev); - calcgap(spare->prev->next = spare->next); - } -} - -/* - * If we get stuck in a long loop trying to figure out the - * line number, print a message to tell the user what we're doing. - */ -static -longloopmessage() -{ - ierror("Calculating line numbers"); - /* - * Set the lnloop flag here, so if the user interrupts while - * we are calculating line numbers, the signal handler will - * turn off line numbers (linenums=0). - */ - lnloop = 1; -} - -/* - * Find the line number associated with a given position. - * Return 0 if we can't figure it out. - */ -find_linenum(pos) - off_t pos; -{ - register struct linenum *p; - register int lno; - register int loopcount; - off_t cpos, back_raw_line(), forw_raw_line(); - time_t startime, time(); - - if (!linenums) - /* - * We're not using line numbers. - */ - return (0); - if (pos == NULL_POSITION) - /* - * Caller doesn't know what he's talking about. - */ - return (0); - if (pos == (off_t)0) - /* - * Beginning of file is always line number 1. - */ - return (1); - - /* - * Find the entry nearest to the position we want. - */ - for (p = anchor.next; p != &anchor && p->pos < pos; p = p->next) - continue; - if (p->pos == pos) - /* Found it exactly. */ - return (p->line); - - /* - * This is the (possibly) time-consuming part. - * We start at the line we just found and start - * reading the file forward or backward till we - * get to the place we want. - * - * First decide whether we should go forward from the - * previous one or backwards from the next one. - * The decision is based on which way involves - * traversing fewer bytes in the file. - */ - flush(); - (void)time(&startime); - if (p == &anchor || pos - p->prev->pos < p->pos - pos) - { - /* - * Go forward. - */ - p = p->prev; - if (ch_seek(p->pos)) - return (0); - loopcount = 0; - for (lno = p->line, cpos = p->pos; cpos < pos; lno++) - { - /* - * Allow a signal to abort this loop. - */ - cpos = forw_raw_line(cpos); - if (sigs || cpos == NULL_POSITION) - return (0); - if (loopcount >= 0 && ++loopcount > 100) { - loopcount = 0; - if (time((time_t *)NULL) - >= startime + LONGTIME) { - longloopmessage(); - loopcount = -1; - } - } - } - lnloop = 0; - /* - * If the given position is not at the start of a line, - * make sure we return the correct line number. - */ - if (cpos > pos) - lno--; - } else - { - /* - * Go backward. - */ - if (ch_seek(p->pos)) - return (0); - loopcount = 0; - for (lno = p->line, cpos = p->pos; cpos > pos; lno--) - { - /* - * Allow a signal to abort this loop. - */ - cpos = back_raw_line(cpos); - if (sigs || cpos == NULL_POSITION) - return (0); - if (loopcount >= 0 && ++loopcount > 100) { - loopcount = 0; - if (time((time_t *)NULL) - >= startime + LONGTIME) { - longloopmessage(); - loopcount = -1; - } - } - } - lnloop = 0; - } - - /* - * We might as well cache it. - */ - add_lnum(lno, cpos); - return (lno); -} - -/* - * Return the line number of the "current" line. - * The argument "where" tells which line is to be considered - * the "current" line (e.g. TOP, BOTTOM, MIDDLE, etc). - */ -currline(where) - int where; -{ - off_t pos, ch_length(), position(); - - if ((pos = position(where)) == NULL_POSITION) - pos = ch_length(); - return(find_linenum(pos)); -} diff --git a/usr.bin/more/macro.c b/usr.bin/more/macro.c deleted file mode 100644 index 78688fb..0000000 --- a/usr.bin/more/macro.c +++ /dev/null @@ -1,292 +0,0 @@ -/*- - * Copyright (c) 1999 Timmy M. Vanderhoek - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -/* - * Expansion of macros. - */ - -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -#include "less.h" - - -/* - * Used to construct tables of macros. Each macro string expands to command. - * A number N is associated with each execution of a macro. The command - * "set number <N>" will be done before the expansion. The end of the table is - * specified by mactabsize. A NULL entry for command denotes a macro that - * has been marked deleted for some reason. As of this writing, there is no - * code that actually deletes a macro... - */ -struct macro { - char *string; /* characters typed to activate macro */ - char *command; /* command resulting after the macro is activated */ - long defnumber; /* default value of the N number */ - int flags; /* only holds STICKYNUMB for now... */ -}; -/* (struct macro) ->flags */ -#define NOFLAGS 0 -#define STICKYNUMB 1 /* Set defnumber to current number, if current number */ - -/* - * The macro table. - */ -struct macro *mactab = NULL; -int mactabsize = 0; - -static enum runmacro runmacro_(); -static struct macro *matchmac(); - - -/* - * XXX Everything's really just a macro until resolved as a quantum wave - * probability distribution. - */ - - -/* - * Attempts to run the appropriate macro. Returns 0, or OK, if the macro - * was succesfully run. Returns BADMACRO and sets erreur if something is - * horribly wrong with the macro. Returns NOMACRO if the macro has no valid - * expansion. BADMACRO and NOMACRO are almost the same. Returns BADCOMMAND - * and leaves erreur set (hopefully it was set when runmacro() tried to execute - * the command associated with the macro) if the command associated with - * the macro was unsuccessful. Returns TOOMACRO if the macro appears to be - * incomplete (ie. the user has not finished typing it in yet). The erreur - * is not set in this case. - * - * XXX There's no good reason not to just disallow badmacros from within - * setmacro() ... It's not clear what the author was thinking at the time. - */ -enum runmacro -runmacro(macro, number, anyN) - const char *macro; /* the macro string to try and expand */ - long number; /* the number N associated with this execution */ - int anyN; /* FALSE is we should use the default N associated with - * the macro. TRUE if we should use the number argument. */ -{ - struct macro *cur, *matched; - int match, yetmatch; - int s; - - if (!mactab) { - /* Should only happen with really sucky default rc files... */ - SETERR (E_CANTXPND); - return NOMACRO; - } - - match = yetmatch = 0; - for (cur = mactab, s = mactabsize; s; cur++, s--) { - if (!cur->command) - continue; /* deleted macro */ - if (!strcmp(cur->string, macro)) - matched = cur, match++; - else if (!strncmp(cur->string, macro, strlen(macro))) - yetmatch++; - } - - if (match == 1) { - if (yetmatch) { - SETERR (E_AMBIG); - return BADMACRO; - } - - /* XXX it's not clear how to handle error when setting - * the number N --- this is a deficiency in the style of error- - * reporting suggested in command.c and less.h. Could have - * setvar() guarantee success when setting "number". A failure - * must not become fatal or it becomes impossible to do - * any commands at all. */ - if (anyN) { - if (matched->flags & STICKYNUMB) - matched->defnumber = number; - (void) setvari("number", number); - } else - (void) setvari("number", matched->defnumber); - clear_error(); - - if (command(matched->command)) - return BADCOMMAND; - return OK; - } - if (match > 1) { - SETERR (E_AMBIG); - return BADMACRO; - } - if (!match && !yetmatch) { - SETERR (E_CANTXPND); - return NOMACRO; - } - assert(yetmatch); - return TOOMACRO; -} - -/* - * Associates a macro with a given command. Returns -1 if it was unable to - * set the macro. Errors associated with setting a macro may be caught - * either in this function, setmacro(), or in runmacro(). Both macro and - * command are strcpy()'d into their own space. - */ -int -setmacro(macro, command) - const char *macro; - const char *command; -{ - struct macro *cur, *new = NULL; - char *new_mac, *new_com; - int s; - - assert (macro); assert (command); - - /* First, check for any existing macro matches in the custom table */ - s = mactabsize; - for (cur = mactab; s; cur++, s--) { - if (!cur->command) { - /* Hmm... A deleted macro in the table */ - new = cur; - continue; - } - if (!strcmp(cur->string, macro)) { - /* - * An exact match to the new macro already exists. - * Calling realloc() on cur->string and cur->command - * without risking being left in bad state is tricky. - * Just do it the slow but sure way... - */ - new = cur; - break; - } - } - - /* - * Do the allocations here so that we can maintain consistent state - * even if realloc() fails when we try to expand the table (suppose - * the table gets expanded but the next malloc to get space for the - * macro fails). - */ - if (!FMALLOC(strlen(macro) + 1, new_mac)) - return -1; - if (!FMALLOC(strlen(command) + 1, new_com)) - return -1; - - if (!new) { - /* Extend the command table by one record */ - struct macro *t = realloc(mactab, (mactabsize + 1) * - sizeof(struct macro)); - if (!t) { - /* The old mactab is still valid. Just back out. */ - free(new_mac), free(new_com); - SETERR (E_MALLOC); - return -1; - } else - mactab = t; - new = &mactab[mactabsize]; - mactabsize++; - new->string = new->command = NULL; - } - - if (new->string) free(new->string); - if (new->command) free(new->command); - new->string = new_mac; - new->command = new_com; - strcpy(new->string, macro); - strcpy(new->command, command); - - return 0; -} - -/* - * Set the sticky tag on a macro. Returns -1 on failure, 0 on success. - */ -int -stickymac(macro, state) - const char *macro; - int state; /* set it to TRUE or set it to FALSE */ -{ - struct macro *m = matchmac(macro); - if (!m) - return -1; - - if (state) - m->flags |= STICKYNUMB; - else - m->flags &= ~STICKYNUMB; - - return 0; -} - -/* - * Set the default number of a macro. Returns -1 on failure, 0 on success. - */ -int -setmacnumb(macro, N) - const char *macro; - long N; /* The default number */ -{ - struct macro *m = matchmac(macro); - if (!m) - return -1; - - m->defnumber = N; - return 0; -} - -/* - * Tries to find a struct macro matching "macro". Returns NULL if an exact - * match could not be found (eg. ambiguous macro, no macro, etc). - */ -static struct macro * -matchmac(macro) - const char *macro; -{ - struct macro *retr, *cur; - int s; - - retr = NULL; - for (cur = mactab, s = mactabsize; s; cur++, s--) { - if (!cur->command) - continue; - if (!strcmp(cur->string, macro)) { - if (retr) { - SETERR (E_AMBIG); - return NULL; /* matched twice! */ - } else - retr = cur; - } else if (!strncmp(cur->string, macro, strlen(macro))) { - SETERR (E_AMBIG); - return NULL; /* ambiguous macro! */ - } - } - return retr; -} diff --git a/usr.bin/more/main.c b/usr.bin/more/main.c deleted file mode 100644 index de05b18..0000000 --- a/usr.bin/more/main.c +++ /dev/null @@ -1,553 +0,0 @@ -/* - * Copyright (c) 1988 Mark Nudleman - * Copyright (c) 1988, 1993 - * Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -char copyright[] = -"@(#) Copyright (c) 1988 Mark Nudleman.\n\ -@(#) Copyright (c) 1988, 1993 - Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/7/93"; -#endif /* not lint */ - -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -/* - * Entry point, initialization, miscellaneous routines. - */ - -#include <sys/file.h> -#include <sys/param.h> -#include <sys/types.h> - -#include <errno.h> -#include <locale.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#define DEFINEGLOBALS -#include "defrc.h" -#include "less.h" -#include "pathnames.h" - -int ispipe; -char *current_file, *previous_file, *current_name, *next_name; -int any_display; -int ac; -char **av; -int curr_ac; - -extern int file; -extern int cbufs; -extern int errmsgs; - -extern char *tagfile; -extern int tagoption; - -/* - * Edit a new file. - * Filename "-" means standard input. - * No filename means the "current" file, from the command line. If called - * with the same filename in succession, filename will be closed and reopened. - * - * If called with FORCE_OPEN, the file will be re-opened even if it is - * already open. - */ -edit(filename, force_open) - register char *filename; -{ - register int f; - register char *m; - off_t initial_pos, position(); - static off_t prev_pos; - static int didpipe; - char message[MAXPATHLEN + 50], *p; - char *rindex(), *strerror(), *save(), *bad_file(); - extern int horiz_off, wraplines; - - if (force_open == NO_FORCE_OPEN && - current_file && filename && !strcmp(filename, current_file)) - return(1); - - /* Okay since later code in this fcn() always forces redraw() */ - horiz_off = 0; - wraplines = 1; - - initial_pos = NULL_POSITION; - if (filename == NULL || *filename == '\0') { - if (curr_ac >= ac) { - error("No current file"); - return(0); - } - filename = save(av[curr_ac]); - } - else if (strcmp(filename, "#") == 0) { - if (!previous_file || *previous_file == '\0') { - error("no previous file"); - return(0); - } - filename = save(previous_file); - initial_pos = prev_pos; - } else - filename = save(filename); - - /* use standard input. */ - if (!strcmp(filename, "-")) { - if (didpipe) { - error("can view standard input only once"); - return(0); - } - f = 0; - } - else if ((m = bad_file(filename, message, sizeof(message))) != NULL) { - error(m); - free(filename); - return(0); - } - else if ((f = open(filename, O_RDONLY, 0)) < 0) { - (void)snprintf(message, sizeof(message), - "%s: %s", filename, strerror(errno)); - error(message); - free(filename); - return(0); - } - - if (isatty(f)) { - /* - * Not really necessary to call this an error, - * but if the control terminal (for commands) - * and the input file (for data) are the same, - * we get weird results at best. - */ - error("Can't take input from a terminal"); - if (f > 0) - (void)close(f); - (void)free(filename); - return(0); - } - - /* - * We are now committed to using the new file. - * Close the current input file and set up to use the new one. - */ - if (file > 0) - (void)close(file); - if (previous_file != NULL) - free(previous_file); - previous_file = current_file; - current_file = filename; - pos_clear(); - prev_pos = position(TOP); - ispipe = (f == 0); - if (ispipe) { - didpipe = 1; - current_name = "stdin"; - } else - current_name = (p = rindex(filename, '/')) ? p + 1 : filename; - if (curr_ac >= ac) - next_name = NULL; - else - next_name = av[curr_ac + 1]; - file = f; - ch_init(cbufs, 0); - - if (isatty(STDOUT_FILENO)) { - int no_display = !any_display; - any_display = 1; - if (no_display && errmsgs > 0) { - /* - * We displayed some messages on error output - * (file descriptor 2; see error() function). - * Before erasing the screen contents, - * display the file name and wait for a keystroke. - */ - error(filename); - } - /* - * Indicate there is nothing displayed yet. - */ - if (initial_pos != NULL_POSITION) - jump_loc(initial_pos); - clr_linenum(); - } - return(1); -} - -/* - * Edit the next file in the command line list. - */ -next_file(n) - int n; -{ - extern int quit_at_eof; - off_t position(); - - if (curr_ac + n >= ac) { - if (quit_at_eof || position(TOP) == NULL_POSITION) - quit(); - error("No (N-th) next file"); - } - else - (void)edit(av[curr_ac += n], FORCE_OPEN); -} - -/* - * Edit the previous file in the command line list. - */ -prev_file(n) - int n; -{ - if (curr_ac - n < 0) - error("No (N-th) previous file"); - else - (void)edit(av[curr_ac -= n], FORCE_OPEN); -} - -/* - * copy a file directly to standard output; used if stdout is not a tty. - * the only processing is to squeeze multiple blank input lines. - */ -static -cat_file() -{ - extern int squeeze; - register int c, empty; - - if (squeeze) { - empty = 0; - while ((c = ch_forw_get()) != EOI) - if (c != '\n') { - putchr(c); - empty = 0; - } - else if (empty < 2) { - putchr(c); - ++empty; - } - } - else while ((c = ch_forw_get()) != EOI) - putchr(c); - flush(); -} - -main(argc, argv) - int argc; - char **argv; -{ - int envargc, argcnt; - char *envargv[3]; - - (void) setlocale(LC_ALL, ""); - - /* - * Process command line arguments and MORE environment arguments. - * Command line arguments override environment arguments. - */ - if (envargv[1] = getenv("MORE")) { - envargc = 2; - envargv[0] = "more"; - envargv[2] = NULL; - (void)option(envargc, envargv); - } - argcnt = option(argc, argv); - argv += argcnt; - argc -= argcnt; - - /* - * Set up list of files to be examined. - */ - ac = argc; - av = argv; - curr_ac = 0; - - init_mark(); - - /* - * Set up terminal, etc. - */ - if (!isatty(STDOUT_FILENO)) { - /* - * Output is not a tty. - * Just copy the input file(s) to output. - */ - if (ac < 1) { - (void)edit("-", NOFLAGS); - if (file >= 0) - cat_file(); - } else { - do { - (void)edit((char *)NULL, FORCE_OPEN); - if (file >= 0) - cat_file(); - } while (++curr_ac < ac); - } - exit(0); - } - - raw_mode(1); - get_term(); - open_getchr(); - init(); - init_signals(1); - - /* select the first file to examine. */ - if (tagoption) { - /* - * A -t option was given; edit the file selected by the - * "tags" search, and search for the proper line in the file. - */ - if (!tagfile || !edit(tagfile, NOFLAGS) || tagsearch()) - quit(); - } - else if (ac < 1) - (void)edit("-", NOFLAGS); /* Standard input */ - else { - /* - * Try all the files named as command arguments. - * We are simply looking for one which can be - * opened without error. - */ - do { - (void)edit((char *)NULL, NOFLAGS); - } while (file < 0 && ++curr_ac < ac); - } - - if (file >= 0) { - /* - * Don't call rcfiles() until now so that people who put - * wierd things (like "forw_scroll") in their rc file don't - * cause us to SEGV. - */ - rcfiles(); - commands(); - } - quit(); - /*NOTREACHED*/ -} - -/* - * Copy a string to a "safe" place - * (that is, to a buffer allocated by malloc). - */ -char * -save(s) - char *s; -{ - char *p, *strcpy(); - - p = malloc((u_int)strlen(s)+1); - if (p == NULL) - { - error("cannot allocate memory"); - quit(); - } - return(strcpy(p, s)); -} - -/* - * Exit the program. - */ -quit() -{ - /* - * Put cursor at bottom left corner, clear the line, - * reset the terminal modes, and exit. - */ - lower_left(); - clear_eol(); - deinit(); - flush(); - raw_mode(0); - exit(0); -} - -/* - * Read in from each of the three rc files - default, system, user. - * Calls handle_error() directly to report errors. - */ -rcfiles() -{ - FILE *fd; - char fbuf[MAXPATHLEN + 1]; - char *c; - int readrc(); - int savederrno; - static int str_read(); - - /* The default builtin rc file */ - if ((c = getenv("HOME")) && - strlen(c) + strlen(_PATH_DEFRC) + 1 < MAXPATHLEN) { - sprintf(fbuf, "%s/%s", c, _PATH_DEFRC); - fd = fopen(fbuf, "r"); - savederrno = errno; - if (!fd) { - if (!access(_PATH_SYSMORERC, F_OK)) { - SETERRSTR(E_EXTERN, "unable to read %s: %s", - _PATH_SYSMORERC, strerror(savederrno)); - handle_error(); - } - /* We'd better have some type of default keys!! */ - goto use_builtin_defrc; - } else { - readrc(fd); - fclose(fd); - } - } else { -use_builtin_defrc: - fd = fropen(DEFRC, str_read); - readrc(fd); - fclose(fd); - } - - /* The system rc file */ - fd = fopen(_PATH_SYSMORERC, "r"); - savederrno = errno; - if (!fd) { - if (!access(_PATH_SYSMORERC, F_OK)) { - SETERRSTR(E_EXTERN, "unable to read %s: %s", - _PATH_SYSMORERC, strerror(savederrno)); - handle_error(); - } else - ; /* non-existant => non-error */ - } else { - readrc(fd); - fclose(fd); - } - - /* The user rc file */ - if ((c = getenv("HOME")) && - strlen(c) + strlen(_PATH_RC) + 1 < MAXPATHLEN) { - sprintf(fbuf, "%s/%s", c, _PATH_RC); - fd = fopen(fbuf, "r"); - savederrno = errno; - if (!fd) { - if (!access(fbuf, F_OK)) { - SETERRSTR(E_EXTERN, - "unable to read %s: %s", fbuf, - strerror(savederrno)); - handle_error(); - } else - ; /* non-existant => non-error */ - } else { - readrc(fd); - fclose(fd); - } - } -} - -/* - * Read-in an rc file from a fd. Calls handle_error() directly to handle - * errors. - * - * This really belongs in ncommand.c, but that file is already 33292 bytes - * long. - */ -readrc(fd) - FILE *fd; -{ - char *bufptr, *buf; - size_t len; - int strlenbuf; - - buf = NULL; - strlenbuf = 0; - while (bufptr = fgetln(fd, &len)) { - if (!len) - continue; /* ??? */ - if (*bufptr == '#') - continue; /* skip comments */ - if (!(buf = reallocf(buf, strlenbuf + len + 1))) { - SETERR(E_MALLOC); - handle_error(); - if (strlenbuf + len < 1024) - return; /* major memory shortage... */ - continue; - } - memcpy (buf + strlenbuf, bufptr, len); - buf[len + strlenbuf] = '\0'; - if (len > 1 && buf[strlenbuf + len - 2] == '\\') { - /* line continuation */ - buf[strlenbuf + len - 2] = '\0'; - strlenbuf = strlen(buf); - continue; - } - if (buf[len + strlenbuf - 1] == '\n') - buf[len + strlenbuf - 1] = '\0'; - if (command(buf)) - handle_error(); - free(buf); - buf = NULL; - strlenbuf = 0; - } -} - -/* - * Read from the NUL-terminated cookie. Non-reentrant: keeps a static pointer - * to the current position in the cookie. Used for funopen(). - */ -static int -str_read(cookie, buf, len) - void *cookie; - char *buf; - size_t len; -{ - static char *curpos; - static int cooklen; - static char *lastcook; - - if (lastcook != cookie) { - /* begin working on a new cookie */ - curpos = cookie; - lastcook = cookie; - cooklen = strlen(cookie); - } - - if (curpos + len > lastcook + cooklen) { - ssize_t r; - memcpy(buf, curpos, r = (cooklen - (curpos - lastcook))); - curpos = cookie + cooklen; - return (int) r; - } else { - memcpy(buf, curpos, len); - curpos += len; - return (int) len; - } -} diff --git a/usr.bin/more/more.1 b/usr.bin/more/more.1 deleted file mode 100644 index cf5ff95..0000000 --- a/usr.bin/more/more.1 +++ /dev/null @@ -1,358 +0,0 @@ -.\" Copyright (c) 1988, 1990, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)more.1 8.2 (Berkeley) 4/18/94 -.\" $FreeBSD$ -.\" -.Dd April 18, 1994 -.Dt MORE 1 -.Os -.Sh NAME -.Nm more -.Nd file perusal filter for crt viewing -.Sh SYNOPSIS -.Nm -.Op Fl ceinsu -.Op Fl t Ar tag -.Op Fl x Ar tabs -.Op Fl / Ar pattern -.Op Ar -.Sh DESCRIPTION -The -.Nm -command is a filter for paging through text one screenful at a time. -It -uses -.Xr termcap 3 -so it can run on a variety of terminals, -including hardcopy terminals. -On a hardcopy terminal, lines which should be -printed at the top of the screen are prefixed with an up-arrow. -A -.Ar file -may be specified as -.Pa /dev/stdin -to view stdin. -.Sh OPTIONS -Command line options are described below. -Options are also taken from the environment variable -.Ev MORE -(make sure to precede them with a dash (``-'')) but command -line options will override them. -.Bl -tag -width flag -.It Fl c -Normally, -.Nm -will repaint the screen by scrolling from the bottom of the screen. -If the -.Fl c -option is set, when -.Nm -needs to change the entire display, it will paint from the top line down. -.It Fl e -Normally, if displaying a single file, -.Nm -exits as soon as it reaches end-of-file. The -.Fl e -option tells -.Nm -to -exit if it reaches end-of-file twice without an intervening operation. -.It Fl i -The -.Fl i -option causes searches to ignore case; that is, -uppercase and lowercase are considered identical. -.It Fl n -The -.Fl n -flag suppresses line numbers. -The default (to use line numbers) may cause -.Nm -to run more slowly in some cases, especially with a very large input file. -Suppressing line numbers with the -.Fl n -flag will avoid this problem. -Using line numbers means: the line number will be displayed in the -.Cm = -command, and the -.Cm v -command will pass the current line number to the editor. -.It Fl s -The -.Fl s -option causes -consecutive blank lines to be squeezed into a single blank line. -.It Fl t -The -.Fl t -option, followed immediately by a tag, will edit the file -containing that tag. -For more information, see -.Xr ctags 1 -and -.Xr gtags 1 . -.It Fl u -By default, -.Nm -treats backspaces and -.Dv CR-LF -sequences specially. Backspaces which appear -adjacent to an underscore character are displayed as underlined text. -Backspaces which appear between two identical characters are displayed -as emboldened text. -.\" Actually, backspaces are never displayed, either higlighted or underlined, -.\" when -u isn't specified. -.Dv CR-LF -sequences are compressed to a single newline -character. The -.Fl u -option causes backspaces to always be displayed as -control characters, i.e. as the two character sequence ``^H'', and -.Dv CR-LF -to be left alone. -.It Fl x -The -.Fl x -option sets tab stops every -.Ar N -positions. -The default for -.Ar N -is 8. -.It Fl / -The -.Fl / -option specifies a string that will be searched for before -each file is displayed. -.Sh COMMANDS -Interactive commands for -.Nm -are based on -.Xr vi 1 . -Some commands may be preceded by a decimal number, called N in the -descriptions below. -In the following descriptions, ^X means control-X. -.Pp -.Bl -tag -width Ic -.It Ic h -Help: display a summary of these commands. -If you forget all the other commands, remember this one. -.It Xo -.Ic SPACE -.No or -.Ic f -.No or -.Ic \&^F -.Xc -Scroll forward N lines, default one window. -If N is more than the screen size, only the final screenful is displayed. -.It Ic b No or Ic \&^B -Scroll backward N lines, default one window (see option -z below). -If N is more than the screen size, only the final screenful is displayed. -.It Xo -.Ic j -.No or -.Ic RETURN -.No or -.Ic DOWN-ARROW -.Xc -Scroll forward N lines, default 1. -The entire N lines are displayed, even if N is more than the screen size. -.It Ic k No or Ic UP-ARROW -Scroll backward N lines, default 1. -The entire N lines are displayed, even if N is more than the screen size. -.It Ic LEFT-ARROW -Scroll leftwards N columns, default 1, or turn on line-wrapping if the -screen is cannot be scrolled leftwards. -.It Ic RIGHT-ARROW -Turn off line-wrapping or scroll rightwards N columns, default 1, -if line wrapping is already off. -.It Ic TAB -Turn off line-wrapping or scroll rightwards N * 8 columns, default 8, -if line-wrapping is already off. -.It Ic HOME -Toggle horizontal scrolling and associated line-wrapping on and off. -.It Ic d No or Ic \&^D -Scroll forward N lines, default one half of the screen size. -If N is specified, it becomes the new default for -subsequent d and u commands. -The entire N lines are displayed, even if N is more than the screen size. -.It Ic u No or Ic \&^U -Scroll backward N lines, default one half of the screen size. -If N is specified, it becomes the new default for -subsequent d and u commands. -The entire N lines are displayed, even if N is more than the screen size. -.It Ic g -Go to line N in the file, default 1 (beginning of file). -.It Ic G -Go to line N in the file, default the end of the file. -.It Ic p No or Ic \&% -Go to a position N percent into the file. N should be between 0 -and 100. -This does work if standard input is being read, but only if -.Nm -has already read to the end of the file. It is always fast, but -not always useful. -.It Ic r No or Ic \&^L -Repaint the screen. -.It Ic R -Repaint the screen, discarding any buffered input. -Useful if the file is changing while it is being viewed. -.It Ic m -Followed by any lowercase letter, -marks the current position with that letter. -.It Ic \&' -(single quote) -Followed by any lowercase letter, returns to the position which -was previously marked with that letter. -Followed by another single quote, returns to the position at -which the last -.Qq large -movement command was executed, or the -beginning of the file if no such movements have occurred. -.It Ic \&/ Ns Ar pattern -Search forward in the file for the N-th line containing the pattern. -N defaults to 1. -The pattern is a -.St -p1003.2 -.Dq extended format -regular expression, as described in -.Xr re_format 7 . -The search starts at the second line displayed. -.It Ic \&? Ns Ar pattern -Search backward in the file for the N-th line containing the pattern. -The search starts at the line immediately before the top line displayed. -.It Ic \&/\&! Ns Ar pattern -Like /, but the search is for the N-th line -which does NOT contain the pattern. -.It Ic \&?\&! Ns Ar pattern -Like ?, but the search is for the N-th line -which does NOT contain the pattern. -.It Ic n No and Ic N -Repeat previous search, -in same or opposite direction respectively, -for N-th line containing the last pattern -(or -.Tn NOT -containing the last pattern, if the previous search -was /! or ?!). -.It Ic E Ns Op Ar filename -Examine a new file. -If the filename is missing, the current file (see the N and P commands -below) from the list of files in the command line is re-examined. -If the filename is a pound sign (#), the previously examined file is -re-examined. -.It Ic \&:n -Examine the next file (from the list of files given in the command line). -If a number N is specified (not to be confused with the command N), -the N-th next file is examined. -.It Ic \&:p -Examine the previous file. -If a number N is specified, the N-th previous file is examined. -.It Ic \&:t -Go to supplied tag. -.It Ic t -Go forward in tag queue [gtags only]. -.It Ic T -Go backward in tag queue [gtags only]. -.It Ic v -Invokes an editor to edit the current file being viewed. -The editor is taken from the environment variable -.Ev EDITOR , -or defaults to -.Xr vi 1 . -.It Ic \&= No or Ic \&^G -These options print out the number of the file currently being displayed -relative to the total number of files there are to display, the current -line number, the current byte number and the total bytes to display, and -what percentage of the file has been displayed. If -.Nm -is reading from stdin, or the file is shorter than a single screen, some -of these items may not be available. Note, all of these items reference -the first byte of the last line displayed on the screen. -.It Xo -.Ic q -.No or -.Ic \&:q -.No or -.Ic ZZ -.Xc -Exits -.Nm more . -.El -.Sh ENVIRONMENT -The following environment variables are used, -if they exist: -.Bl -tag -width Fl -.It Ev MORE -Specifies default option flags to -.Nm more . -Options must be preceeded by a -.Dq - -as if they were specified on the command line. -.It Ev EDITOR -Specifies default editor. -.It Ev SHELL -Specifies current shell in use. -This is normally set by the shell at login time. -.It Ev TERM -Specifies terminal type. -This is used by -.Nm -to get the terminal -characteristics necessary to manipulate the screen. -.El -.Sh SEE ALSO -.Xr ctags 1 , -.Xr global 1 , -.Xr gtags 1 , -.Xr vi 1 -.Sh BUGS -Reading files with long lines is slow. -.Pp -CRLF-terminated 80 character lines are proceeded by an extraneous blank line. -.Pp -Immediate transitions from bold text to underlined text cause the -underlining to be not existing. -.Pp -Sometimes searches match lines that do not contain the pattern being -searched for. -.Sh AUTHORS -This software is derived from software contributed to Berkeley -by -.An Mark Nudleman . -.Sh HISTORY -The -.Nm -command appeared in -.Bx 3.0 . diff --git a/usr.bin/more/more.help b/usr.bin/more/more.help deleted file mode 100644 index 1fdaf92..0000000 --- a/usr.bin/more/more.help +++ /dev/null @@ -1,45 +0,0 @@ - Commands flagged with an asterisk (``*'') may be preceeded by a number. - Commands of the form ``^X'' are control characters, i.e. control-X. The - arrow keys and page-up/down keys act as expected. Additional keys are, - - h Display this help. - - f, ^F, SPACE * Forward N lines, default one screen. - b, ^B * Backward N lines, default one screen. - j, CR * Forward N lines, default 1 line. - k * Backward N lines, default 1 line. - d, ^D * Forward N lines, default half screen or last N to d/u. - u, ^U * Backward N lines, default half screen or last N to d/u. - g * Go to line N, default 1. - G * Go to line N, default the end of the file. - p, % * Position to N percent into the file. - HOME Toggle horizontal scroll and line-wrap on and off - tab * Tab N x 8 columns to the right - - r, ^L Repaint screen. - R Repaint screen, discarding buffered input. - - m[a-z] Mark the current position with the supplied letter. - '[a-z] Return to the position previously marked by this letter. - '' Return to previous position. - - /pattern * Search forward for N-th line containing the pattern. - /!pattern * Search forward for N-th line NOT containing the pattern. - ?pattern * Search backward for N-th line containing the pattern. - ?!pattern * Search backward for N-th line NOT containing the pattern. - n * Repeat previous search (for N-th occurence). - N * Repeat previous search (for N-th occurence), switching - the direction of the search. - - :a Display the list of files. - E [file] Examine a new file. - :n * Examine the next file. - :p * Examine the previous file. - :t [tag] Examine the tag. - t, T Move forward or backward N tags in the gtags queue. - v Run an editor on the current file. - - =, ^G Print current file name and stats. - - q, :q, or ZZ Exit. - diff --git a/usr.bin/more/most.morerc b/usr.bin/more/most.morerc deleted file mode 100644 index 781f735..0000000 --- a/usr.bin/more/most.morerc +++ /dev/null @@ -1,86 +0,0 @@ -# -# This sample .morerc causes more to emulate the default most(1) -# keys, in so far as more(1) is capable (which is not very far at the -# moment). -# -# $FreeBSD$ -# -# BUGS: It's extremely unlikely that more(1) will ever support multiple -# windows as most(1) does. Multiple windows is an editor function, -# isn't it? -# - -macro 1 "" 'forw (${_sc_height} * ${number})' -macro 1 v 'forw ${number}' -macro 1 V 'forw ${number}' -macro 1 "" 'forw ${number}' -macro 1 "" 'back ${number}' -macro 1 ^ 'back ${number}' -macro 0 T 'goline 1' -macro 0 "\e<" 'goline 1' -macro 0 B 'goend' -macro 0 "\e>" 'goend' -# Doesn't match most(1) documentation -macro 1 "\e[C" 'rscroll ${number}' -macro 1 "\t" 'rscroll (60 * ${number})' -macro 1 > 'rscroll (60 * ${number})' -# Doesn't match most(1) documentation -macro 1 "\e[D" 'lscroll ${number}' -# Doesn't really do much, being ^B and all... -macro 1 "" 'lscroll (60 * ${number})' -macro 1 < 'lscroll (60 * ${number})' -macro 1 u 'back (${_sc_height} * ${number})' -macro 1 U 'back (${_sc_height} * ${number})' -macro 1 "" 'back (${_sc_height} * ${number})' -macro 1 "" 'back (${_sc_height} * ${number})' -macro 0 R 'repaint' -macro 0 r 'repaint' -macro 0 "" 'repaint' -macro 0 j 'condition (${number} == 0); \ - error "prompt for line-number not supported"; \ - condition (${number} != 0); \ - goline ${number}; \ - condition true;' -macro 0 J 'condition (${number} == 0); \ - error "prompt for line-number not supported"; \ - condition (${number} != 0); \ - goline ${number}; \ - condition true;' -macro 0 g 'condition (${number} == 0); \ - error "prompt for line-number not supported"; \ - condition (${number} != 0); \ - goline ${number}; \ - condition true;' -macro 0 G 'condition (${number} == 0); \ - error "prompt for line-number not supported"; \ - condition (${number} != 0); \ - goline ${number}; \ - condition true;' -macro 0 % 'condition (${number} == 0); \ - error "prompt for percent not supported"; \ - condition_toggle; \ - gopercent ${number}; \ - condition true;' -macro 0 q 'quit' -macro 0 Q 'quit' -macro 0 "E" 'quit' -macro 0 h 'help' -macro 0 H 'help' -macro 0 "" 'help' -macro 0 "\e[N" 'help' -macro 1 f 'magicasksearch forw ${number}' -macro 1 / 'magicasksearch forw ${number}' -macro 1 "" 'magicasksearch forw ${number}' -macro 1 ? 'magicasksearch back ${number}' -macro 1 n 'research ${_ls_direction_n} ${number}' -macro 1 N 'research ${_ls_direction_n} ${number}' -# The mark stuff could be more effeciently done with a temp var, of course... :) -# These are nice enough that I'm tempted to bring them into default.morerc -macro 0 m 'setmark z' -macro 0 "M" 'setmark z' -macro 0 "." 'setmark z' -macro 0 "" 'setmark y; gomark z; setmark x; gomark y; setmark z; gomark x;' -macro 0 "," 'setmark y; gomark z; setmark x; gomark y; setmark z; gomark x;' -macro 0 e 'edit' -macro 0 E 'edit' -macro 0 :n 'file next ${number}' diff --git a/usr.bin/more/ncommand.c b/usr.bin/more/ncommand.c deleted file mode 100644 index b46d9ee..0000000 --- a/usr.bin/more/ncommand.c +++ /dev/null @@ -1,1505 +0,0 @@ -/*- - * Copyright (c) 1999 Timmy M. Vanderhoek - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -/* - * These functions handle evaluation of primitive commands. In general, - * commands either come from macro.h as it expands user input, or - * directly from a .morerc file (in which case only a limited set of - * commands is valid. - * - * Commands are matched by command() against a command table. The rest - * of the command line string passed to command() is then passed to a - * function corresponding to the given command. The specific command - * function evaluates the remainder of the command string with the help - * of getstr() and getint(), both of which also handle variable expansion - * into a single word. Specific command functions should not try grokking - * the command string by themselves. - * - * A command and its arguments are terminated by either a NUL or a ';'. - * This is recognized by both getstr() and getint(). Specific command - * functions return a pointer to the end of the command (and its arguments) - * thus allowing command() to accept commands that are chained together - * by semicolons. If a specific command fails, it returns NULL preventing - * any proceeding commands (chained together with ';') from being parsed. - * This can be considered as a feature. - * - * All variable-access functions and variable state are internal to - * ncommand.c. The sole exceptions are setvar() and setvari(). - */ - -#include <sys/param.h> - -#include <assert.h> -#include <ctype.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -#include "less.h" -#include "pathnames.h" - -static int getint __P((long *numb, const char **line)); - -static getstr_free(); -static void **getstr_raisectxt(); - -/* The internal command table. */ - -static const char *cscroll(), *cquit(), *cerror(), *ceval(), *cset(), - *cflush(), *cmacro(), *caskfile(), *cusercom(), - *ctags(), *chscroll(), *cgomisc(), *cgoend(), *csearch(), - *cstat(), *cdeftog(), *ccondition(), *chelp(), *cfile(), - *cfile_list(), *cedit(), *cmark(), *creadrc(); - -/* An enum identifying each command */ -enum cident { - DEFTOG, /* Initialize toggle values */ - EVAL, /* Evaluate a subexpression */ - SET, /* Set a variable */ - MACRO, /* Create a new macro */ - ERROR, /* Print a notification message */ - CONDITION, /* Condition evaluation of (almost) _all_ commands */ - CONDITION_N, /* CONDITION with an inverse truth table */ - CONDITION_TOGGLE,/* Switch to the reverse sense of the last condition */ - USERCOM, /* Get the user to type in a direct command */ - READRC, /* Read-in a named rc file */ - QUIT, /* Quit */ - HELP, /* Help */ - FLUSH, /* Flush file buffer and friends */ - REPAINT, /* Redraw the screen (useful if it got trashed) */ - FORW_SCROLL, /* Scroll forward N lines */ - BACK_SCROLL, /* Scroll backward N lines */ - FORW, /* Jump or scroll forward N lines */ - BACK, /* Jump or scroll backwards N lines */ - LSCROLL, /* Scroll horizontally leftwards */ - RSCROLL, /* Scroll horizontally to the right */ - GOLINE, /* Goto line number N */ - GOPERCENT, /* Goto percent N of the file */ - GOEND, /* Goto the end of the file */ - EDIT, /* Edit the current file, using getenv(EDITOR) */ - ASKFILE, /* Ask for a different, new file */ - CFILE, /* Page/view the N'th next or prev file */ - FILE_LIST, /* List the files that CFILE moves around in */ - STAT, /* List detailed file statistics in prompt */ - MAGICASKSEARCH, /* Ask for a regexp search string */ - SEARCH, /* Search for a regexp */ - RESEARCH, /* Search for the next N'th occurrence */ - SETMARK, /* Set a bookmark to the current position */ - GOMARK, /* Goto a previously set bookmark */ - ASKFTAG, /* Ask for a tag to goto */ - NEXTFTAG, /* Move forward N in the tag queue */ - PREVFTAG, /* Move backwards N in the tag queue */ -}; - -static struct ctable { - const char *cname; - enum cident cident; - const char * (*cfunc)(enum cident, const char *args); -} ctable[] = { - { "deftog", DEFTOG, cdeftog }, - { "eval", EVAL, ceval }, - { "set", SET, cset }, - { "macro", MACRO, cmacro }, - { "error", ERROR, cerror }, - { "condition", CONDITION, ccondition }, - { "condition_!", CONDITION_N, ccondition }, - { "condition_toggle", CONDITION_TOGGLE, ccondition }, - { "condition_else", CONDITION_TOGGLE, ccondition }, - { "usercom", USERCOM, cusercom }, - { "readrc", READRC, creadrc }, - { "quit", QUIT, cquit }, - { "help", HELP, chelp }, - { "flush", FLUSH, cflush }, - { "repaint", REPAINT, cflush }, - { "forw_scroll", FORW_SCROLL, cscroll }, - { "back_scroll", BACK_SCROLL, cscroll }, - { "forw", FORW, cscroll }, - { "back", BACK, cscroll }, - { "rscroll", RSCROLL, chscroll }, - { "lscroll", LSCROLL, chscroll }, - { "goline", GOLINE, cgomisc }, - { "gopercent", GOPERCENT, cgomisc }, - { "goend", GOEND, cgoend }, - { "edit", EDIT, cedit }, - { "askfile", ASKFILE, caskfile }, - { "file", CFILE, cfile }, - { "file_list", FILE_LIST, cfile_list }, - { "stat", STAT, cstat }, - { "magicasksearch", MAGICASKSEARCH, csearch }, - { "search", SEARCH, csearch }, - { "research", RESEARCH, csearch }, - { "setmark", SETMARK, cmark }, - { "gomark", GOMARK, cmark }, - { "asktag", ASKFTAG, ctags }, - { "nexttag", NEXTFTAG, ctags }, - { "prevtag", PREVFTAG, ctags }, -}; - - -/* I believe this is just for cosmetic purposes. */ -#define CMD_EXEC lower_left(); flush() - - -/* - * Prototypes are for people who can't program. - */ - - -/* - * The main command string evaluator. Returns -1 if an error occurred - * in the command or in executing the command, returns 0 otherwise. If an - * error occurs while evaluating a command line containing multiple commands, - * commands after the error are not processed. Multiple commands may be - * separated by ';' or '\n'. (Multiple commands may also be separated by - * a ' ', but this is really a bug...) - */ -int -command(line) - const char *line; -{ - struct ctable *i; - -donextcommand: - - while (isspace(*line) || *line == ';' || *line == '\n') line++; - if (!*line) - return 0; - - for (i = ctable; i != ctable + sizeof(ctable) / sizeof(struct ctable); - i++) { - if (!strncmp(i->cname, line, strlen(i->cname)) && - (line[strlen(i->cname)] == ' ' || - line[strlen(i->cname)] == ';' || - line[strlen(i->cname)] == '\0')) { - /* Found a match! */ - void **ctxt; - CMD_EXEC; - ctxt = getstr_raisectxt(); - line = i->cfunc (i->cident, line + strlen(i->cname)); - getstr_free(ctxt); - if (!line) - return -1; /* error evaluating command */ - goto donextcommand; - } - } - - SETERRSTR(E_BOGCOM, "invalid command: ``%s''", line); - (void) command("condition true"); - return -1; -} - - -/***************************************************************************** - * - * Functions to help specific command functions to parse their arguments. - * - * The three functions here, getstr(), getint(), and gettog() could in theory - * have vastly different concepts of what a number is, and what a string is, - * etc., but in practice they don't. - */ - -static char *readvar(); - -#define NCTXTS 128 -void *getstr_ctxts[NCTXTS]; /* could easily be made dynamic... */ -void **getstr_curctxt = getstr_ctxts; - -/* - * Read a single argument string from a command string. This understands - * $variables, "double quotes", 'single quotes', and backslash escapes - * for \\, \$, \n, \e, \t, and \". A string may be delimited by double - * quotes or spaces, not both (duh). It may be worthwhile to add - * another quotation style in which arithmetic expressions are expanded. - * Currently an arithmetic expression is expanded iff it is the only - * component of the string. - * - * Returns a pointer to the beginning of the string or NULL if it was unable to - * read a string. The line is modified to point somewhere between the end of - * the command argument just read-in and the beginning of the next command - * argument (if any). The returned pointer will be free()'d by calling - * getstr_free(). - */ -static char * -getstr(line) - const char **line; /* Where to look for the return string */ -{ - int doquotes = 0; /* Doing a double-quote string */ - char *retr; - - if (getstr_curctxt - getstr_ctxts == NCTXTS) { - SETERRSTR(E_COMPLIM, - "compile-time limit exceeded: command contexts"); - return NULL; /* wouldn't be able to register return pointer */ - } - - while (isspace(**line)) (*line)++; - if (**line == '\'') { - /* Read until closing quote or '\0'. */ - char *nextw = retr = malloc(1); - const char *c = ++(*line); - int l; - for (; *c; c++) { - if (*c == '\'') { - if (c[-1] == '\\') { - nextw[-1] = '\''; - continue; - } else { - *nextw = '\0'; - *line = c + 1; - *getstr_curctxt = retr; - getstr_curctxt++; - return retr; - } - } - l = nextw - retr; - /* XXX How many realloc()'s can you make per second? */ - if (!(retr = reallocf(retr, c - *line + 250))) { - SETERR (E_MALLOC); - return NULL; - } - nextw = retr + l; - *nextw = *c; - nextw++; - } - SETERR(E_CANTPARSE); - return NULL; - } - if (**line == '"') { - doquotes = 1; - (*line)++; - } - if (**line == '(') { - /* An arithmetic expression instead of a string... Well, I - * guess this is valid. See comment leading this function. */ - long n; - if (getint(&n, line)) - return NULL; - retr = NULL; - asprintf(&retr, "%ld", n); - if (!retr) - SETERR (E_MALLOC); - *getstr_curctxt = retr; - getstr_curctxt++; - return retr; - } - - if (!FMALLOC(1, retr)) - return NULL; - *retr = '\0'; - for (;;) { - char *c, hack[2]; - - switch (**line) { - case '\\': - switch (*(*line + 1)) { - case '\\': case '$': case '\'': - case ' ': case ';': - hack[0] = *(*line + 1); - hack[1] = '\0'; - c = hack; - (*line) += 2; - break; - case 't': - c = "\t"; - (*line) += 2; - break; - case 'n': - c = "\n"; - (*line) += 2; - break; - case 'e': - c = "\e"; - (*line) += 2; - break; - case '"': - if (doquotes) { - c = "\""; - (*line) += 2; - break; - } else - ; /* fallthrough */ - default: - c = "\\"; - (*line)++; - break; - } - break; - case '$': - (*line)++; - if (!(c = readvar(line))) { - free (retr); - return NULL; - } - break; - case ' ': case '\t': case ';': - if (!doquotes) { - doquotes = 1; - case '"': - if (doquotes) { - /* The end of the string */ - (*line)++; - case '\0': - *getstr_curctxt = retr; - getstr_curctxt++; - return retr; - } - } - /* fallthrough */ - default: - hack[0] = **line; - hack[1] = '\0'; - c = hack; - (*line)++; - break; - } - - retr = reallocf(retr, strlen(retr) + strlen(c) + 1); - if (!retr) { - SETERR (E_MALLOC); - return NULL; - } - strcat(retr, c); - } -} - -/* - * Returns a new context that should be passed to getstr_free() so that - * getstr_free() only free()'s memory from that particular context. - */ -static void ** -getstr_raisectxt() -{ - return getstr_curctxt; -} - -/* - * Calls free() on all memory from context or higher. - */ -static -getstr_free(context) - void **context; -{ - while (getstr_curctxt != context) { - getstr_curctxt--; - free (*getstr_curctxt); - } -} - -/* - * Reads an integer value from a command string. Typed numbers must be - * in base10. If a '(' is found as the first character of the integer value, - * then getint() will read until a closing ')' unless interupted by an - * end-of-command marker (error). The parentheses are expected to contain a - * simple arithmetic statement involving only one '*', '/', etc. operation. The - * rightmost digit or the closing parenthesis should be followed by either a - * space or an end-of-command marker. - * - * Returns 0 on success, -1 on failure. The line will be modified to just - * after the last piece of text parsed. - * - * XXX We may add support for negative numbers, someday... - */ -static int -getint(numb, line) - long *numb; /* The read-in number is returned through this */ - const char **line; /* The command line from which to read numb */ -{ - long n; - int j; - char *p; - const char *t; - - while (isspace(**line)) (*line)++; - - switch (**line) { - case '(': - (*line)++; - if (getint(numb, line)) - return -1; - while (isspace(**line)) (*line)++; - j = **line; - (*line)++; - if (j == ')') - return 0; - if (**line == '=' && (j == '!' || j == '=') - || j == '&' && **line == '&' || j == '|' && **line == '|') - j = (j << 8) + *((*line)++); - if (getint(&n, line)) - return -1; - while (isspace(**line)) (*line)++; - if (**line != ')') { - SETERRSTR (E_BADMATH, - "missing arithmetic close parenthesis"); - return -1; - } else - (*line)++; - switch (j) { - case ('!' << 8) + '=': - *numb = *numb != n; - return 0; - case ('=' << 8) + '=': - *numb = *numb == n; - return 0; - case ('&' << 8) + '&': - *numb = *numb && n; - return 0; - case ('|' << 8) + '|': - *numb = *numb || n; - return 0; - case '+': - *numb += n; - return 0; - case '-': - *numb -= n; - return 0; - case '*': - *numb *= n; - return 0; - case '/': - if (n == 0) - *numb = 1; - else - *numb /= n; - return 0; - default: - SETERRSTR (E_BADMATH, - "bad arithmetic operator: ``%c''", j); - return -1; - } - case '$': - t = (*line)++; - if (!(p = readvar(line))) - return -1; - if (!isdigit(*p)) { - SETERRSTR (E_BADMATH, - "non-number found (``%s'') " - "after expanding variable at ``%s''", p, t); - return -1; - } - *numb = atol(p); - return 0; - case '9': case '0': case '8': case '1': case '7': case '2': case '6': - case '3': case '5': case '4': - *numb = atol(*line); - while (isdigit(**line)) (*line)++; - return 0; - case '"': case '\'': - /* Uh-oh. It's really a string. We'll go through getstr() - * and hope for the best, but this isn't looking good. */ - if (!(p = getstr(line))) - return -1; - *numb = atol(p); - return 0; - default: - SETERRSTR (E_BADMATH, - "non-number found, number expected, before parsing ``%s''", - *line); - return -1; - } -} - -/* - * Read an argument from the command string and match that argument against - * a series of legitimate values. For example, - * - * command <<opt0|opt1|opt2>> - * - * This command by be given to the command() processor as a variant of either - * "command opt1" or "command 4", both of which will cause this function to - * return the value 1. This function returns -1 on failure. - * - * Note that an option (eg. "opt1") must _not_ start with a digit!! - */ -static int -gettog(const char **line, int nopts, ...) -{ - char *str; - int n; - va_list opts; - - if (!(str = getstr(line))) - return -1; - - if (isdigit(*str)) { - n = atol(str) % nopts; - return n; - } - - va_start(opts, nopts); - for (n=0; n < nopts; n++) { - if (!strcasecmp(str, va_arg(opts, const char *))) { - va_end(opts); - return n; - } - } - va_end(opts); - SETERR (E_NOTOG); /* XXX would be nice to list valid toggles... */ - return -1; -} - -/* - * A companion function for gettog(). Example, - * - * optnumb = gettog(&args, 3, "opt1", "opt2", "opt3"); - * settog("_lastoptnumb", optnumb, "opt1", "opt2", "opt3"); - * - * And the variable named _lastoptnumb_s will be set to one of "opt1", "opt2", - * or "opt3" as per the value of optnumb. The variable _lastoptnumb_n will - * also be set to a corresponding value. The optnumb argument had better - * be within the correct range (between 0 and 2 in the above example)!! - */ -settog(const char *varname, int optval, int nargs, ...) -{ - va_list opts; - char *s; - int optval_orig = optval; - - assert(optval < nargs); assert(optval >= 0); - if (!(s = malloc(strlen(varname) + 3))) - return; - strcpy (s, varname); - va_start(opts, nargs); - for (; optval; optval--) va_arg(opts, const char *); - s[strlen(varname)] = '_'; - s[strlen(varname) + 1] = 's'; - s[strlen(varname) + 2] = '\0'; - (void) setvar(s, va_arg(opts, const char *)); - s[strlen(varname) + 1] = 'n'; - (void) setvari(s, (long) optval_orig); - clear_error(); - va_end(opts); - free(s); -} - -/* - * Read {text} and return the string associated with the variable named - * <<text>>. Returns NULL on failure. - */ -static char * -readvar(line) - char **line; -{ - int vlength; - char *vstart; - static char *getvar(); - - if (**line != '{') { - SETERR (E_BADVAR); - return NULL; - } - (*line)++; - for (vlength = 0, vstart = *line; **line && - (isprint(**line) && **line != '{' && **line != '}'); (*line)++) - vlength++; - if (**line != '}' || vlength == 0) { - SETERRSTR (E_BADVAR, - "bad character ``%c'' in variable ``%.*s''", **line, - vlength, vstart); - return NULL; - } - (*line)++; - return getvar(vstart, vlength); -} - - -/***************************************************************************** - * - * Track variables. - * - */ - -static struct vble { - struct vble *next; - char *name; - char *value; -} *vble_l; /* linked-list of existing variables */ - -/* - * Return a pointer to the string that variable var represents. Returns - * NULL if a match could not be found and sets erreur. The returned - * pointer is valid until any calls to setvar() or until a call to - * getstr_free() frees the current context. - */ -static const char * -getvar(var, len) - char *var; - int len; /* strncmp(var, varmatch, len); is used to match variables */ -{ - struct vble *i; - char tcap[3]; - char *s, *retr; - char *gettermcap(); - - if (sscanf (var, "_termcap_%2s", tcap) == 1 && - len == sizeof "_termcap_XX" - 1) { - /* Magic termcap variable */ - if ((s = gettermcap(tcap))) { - if (getstr_curctxt - getstr_ctxts == NCTXTS) { - SETERRSTR(E_COMPLIM, - "compile-time limit exceeded: " - "command contexts"); - return NULL; - } - if (!FMALLOC(strlen(s) + 1, retr)) - return NULL; - strcpy (retr, s); - *getstr_curctxt = retr; - getstr_curctxt++; - return retr; - } else { - return ""; - } - } - - for (i = vble_l; i; i = i->next) { - if (!strncasecmp (i->name, var, len)) - return i->value; - } - - SETERRSTR (E_BADVAR, "variable ``%.*s'' not set", len, var); - return NULL; -} - -/* - * Set variable var to val. Both var and val may be destroyed by the - * caller after setvar(). - * - * Returns -1 on failure, 0 on success. - */ -int -setvar(var, val) - char *var; /* variable to set */ - char *val; /* value to set variable to */ -{ - struct vble *i, *last; - char *var_n, *val_n; - char *c; - - for (c = var; *c && (isprint(*c) && *c != '{' && *c != '}'); c++) ; - if (*c) { - SETERRSTR (E_BADVAR, - "bad character ``%c'' in variable ``%s''", *c, var); - return -1; - } - - for (i = vble_l; i; last = i, i = i->next) { - if (!strcasecmp (i->name, var)) { - if (!FMALLOC(strlen(val) + 1, val_n)) - return -1; - free(i->value); - i->value = val_n; - strcpy(i->value, val); - return 0; - } - } - - /* Need to add another variable to the list vble_l */ - if (!FMALLOC(strlen(var) + 1, var_n)) - return -1; - if (!FMALLOC(strlen(val) + 1, val_n)) { - free(var_n); - return -1; - } - if (!vble_l) { - if (!FMALLOC(sizeof(struct vble), vble_l)) { - free(var_n), free(val_n); - return -1; - } - i = vble_l; - } else { - if (!FMALLOC(sizeof(struct vble), last->next)) { - free(var_n), free(val_n); - return -1; - } - i = last->next; - } - i->next = NULL; - i->name = var_n; strcpy(i->name, var); - i->value = val_n; strcpy(i->value, val); - return 0; -} - -/* - * Set or reset, as appropriate, variable var to val. - */ -int -setvari(var, val) - const char *var; - long val; -{ - char n[21]; /* XXX */ - snprintf(n, sizeof(n), "%ld", val); - n[20] = '\0'; - setvar(var, n); -} - - -/***************************************************************************** - * - * Specific command functions. These aren't actually individual functions, - * since using a gigantic switch statement is faster to type, but they - * pretend to be individual functions. - * - */ - -int condition_eval = 1; /* false if we just parse commands, but do nothing */ - -#define ARGSTR(v) do { \ - if (!((v) = getstr(&args))) return NULL; \ - } while (0) -#define ARGNUM(v) do { \ - if (getint(&(v), &args)) return NULL; \ - } while (0) -/* semi-gratuitous use of GNU cpp extension */ -#define ARGTOG(v, n, togs...) do { \ - if (((v) = gettog(&args, n, togs)) == -1) \ - return NULL; \ - } while (0) -#define ENDPARSE do { \ - if (!condition_eval) return args; \ - } while (0) - -/* - * deftog - * - * Set all toggle options to their default values, provided the toggle option - * is registered with this function. This command is meant to be used at the - * beginning of the startup command list. - */ -static const char * -cdeftog(cident, args) - enum cident cident; - const char *args; -{ - extern int horiz_off, wraplines; - - ENDPARSE; - settog("_statprompt", 1, 2, "on", "off"); - settog("_ls_direction", 0, 2, "forw", "back"); - settog("_ls_sense", 0, 2, "noinvert", "invert"); - setvari("_curhscroll", (long) horiz_off); - settog("_wraplines", wraplines, 2, "off", "on"); - setvar("_ls_regexp", ""); - /* - * not present: _file_direction - */ - return args; -} - -/* - * eval <<string>> - * - * Passes string back into the command evaluator. - */ -static const char * -ceval(cident, args) - enum cident cident; - const char *args; -{ - const char *com; - - ARGSTR(com); /* The command line to evaluate */ - ENDPARSE; - - /* It's not clear what to do with the command() return code */ - (void) command(com); - - return args; -} - -/* - * set <<variablename>> <<variablestring>> - * - * Sets variable variablename to string variablestring. - */ -static const char * -cset(cident, args) - enum cident cident; - const char *args; -{ - const char *str, *var; - - ARGSTR(var); /* name of variable to set */ - ARGSTR(str); /* value to set variable to */ - ENDPARSE; - - if (*var == '_') { - SETERRSTR (E_BADVAR, - "variables beginning with '_' are reserved"); - return NULL; - } - if (setvar(var, str)) - return NULL; - - return args; -} - -/* - * macro <<default_number>> <<keys>> <<command>> - * - * Associates the macro keys with command. - */ -static const char * -cmacro(cident, args) - enum cident cident; - const char *args; -{ - const char *keys, *com; - long num; - - ARGNUM(num); /* the default number N for this macro */ - ARGSTR(keys); /* string of keys representing a macro */ - ARGSTR(com); /* command line to associate with macro */ - ENDPARSE; - - if (setmacro(keys, com)) - return NULL; - if (setmacnumb(keys, num)) - return NULL; - - return args; -} - -/* - * error <<string>> - * - * Prints a notification message. - */ -static const char * -cerror(cident, args) - enum cident cident; - const char *args; -{ - char *s; - - ARGSTR(s); /* error message */ - ENDPARSE; - error(s); - return args; -} - -/* - * condition <<boolean>> - * condition_! <<boolean>> - * - * If boolean is false, causes all commands except for other condition - * commands to be ignored. The <<boolean>> may be specified as a number - * (in which case even numbers are true, odd numbers are false), or one - * of "on", "off", "true", and "false". - */ -static const char * -ccondition(cident, args) - enum cident cident; - const char *args; -{ - /* ENDPARSE; */ - - if (cident == CONDITION_TOGGLE) { - condition_eval = !condition_eval; - return args; - } - - switch (gettog(&args, 4, "off", "on", "false", "true")) { - case 0: case 2: - condition_eval = 0; - break; - case 1: case 3: - condition_eval = 1; - break; - case -1: - return NULL; - } - if (cident == CONDITION_N) - condition_eval = !condition_eval; - return args; -} - -/* - * usercom - * - * Accept a direct command from the user's terminal. - */ -static const char * -cusercom(cident, args) - enum cident cident; - const char *args; -{ - char buf[125]; /* XXX should avoid static buffer... */ - - ENDPARSE; - if (getinput("Command: ", buf, sizeof(buf))) - return args; /* abort the command */ - if (command(buf)) - return NULL; - - return args; -} - -/* - * readrc <<filename>> - * - * Read-in rc commands from the named file. - */ -static const char * -creadrc(cident, args) - enum cident cident; - const char *args; -{ - const char *file; - FILE *fd; - - ARGSTR(file); - ENDPARSE; - - if (!*file) - return args; - /* - * Should perhaps warn user if file perms or ownership look suspicious. - */ - fd = fopen(file, "r"); - if (!fd) { - SETERRSTR (E_NULL, "could not open file ``%s''", file); - return NULL; - } - readrc(fd); - fclose(fd); - - return args; -} - -/* - * quit - * - * Performs as advertised. - */ -static const char * -cquit(cident, args) - enum cident cident; - const char *args; -{ - ENDPARSE; - quit(); - return NULL; /* oh boy... */ -} - -/* - * help - * - * Doesn't do much. - */ -static const char * -chelp(cident, args) - enum cident cident; - const char *args; -{ - extern int ac, curr_ac; - extern char **av; - - ENDPARSE; - if (ac > 0 && !strcmp(_PATH_HELPFILE, av[curr_ac])) { - SETERRSTR(E_NULL, "already viewing help"); - return NULL; - } - help(); - return args; -} - -/* - * flush - * repaint - * - * Flushes the file buffer, provided we are not reading from a pipe. - * Frees any other memory that I can get my hands on from here. - */ -static const char * -cflush(cident, args) - enum cident cident; - const char *args; -{ - extern int ispipe; - - ENDPARSE; - if (cident == FLUSH && !ispipe) { - ch_init(0, 0); /* XXX should this be ch_init(ctags,0) */ - clr_linenum(); - } - repaint(); - - return args; -} - -/* - * forw_scroll <<n>> - * back_scroll <<n>> - * forw <<n>> - * back <<n>> - * - * Move forward number n lines. The _scroll variants force a scroll, the - * others may scroll or may just redraw the screen at the appropriate location, - * whichever is faster. - */ -static const char * -cscroll(cident, args) - enum cident cident; - const char *args; -{ - long n; - char *retr; - - ARGNUM(n); /* number of lines to move by */ - ENDPARSE; - - switch (cident) { - case FORW_SCROLL: - forward(n, 0); - break; - case BACK_SCROLL: - backward(n, 0); - break; - case FORW: - forward(n, 1); - break; - case BACK: - backward(n, 1); - break; - } - - return args; -} - -/* - * rscroll <<n>> - * lscroll <<n>> - * - * Scroll left or right by n lines. - */ -static const char * -chscroll(cident, args) - enum cident cident; - const char *args; -{ - long n; - char *retr; - extern int horiz_off, wraplines; - - ARGNUM(n); /* Number of columns to scroll by */ - ENDPARSE; - - if (n == 0) - return args; - - switch (cident) { - case RSCROLL: - if (wraplines) { - wraplines = 0; - assert (horiz_off == 0); - } else { - horiz_off += n; - if (horiz_off < 0) - horiz_off = INT_MAX; /* disaster control */ - } - break; - case LSCROLL: - if (horiz_off != 0) { - horiz_off -= n; - if (horiz_off < 0) - horiz_off = 0; - } else - wraplines = 1; - break; - } - repaint(); /* screen_trashed = 1 */ - setvari("_curhscroll", (long) horiz_off); - settog("_wraplines", wraplines, 2, "off", "on"); - - return args; -} - -/* - * goline <<line>> - * gopercent <<percent>> - * - * Goto the line numbered <<line>>, if possible. Goto <<percent>> percent of - * the file. Whole-numbered percents only, of course. - */ -static const char * -cgomisc(cident, args) - enum cident cident; - const char *args; -{ - long n; - - ARGNUM(n); /* number N */ - ENDPARSE; - - switch (cident) { - case GOLINE: - jump_back(n); - break; - case GOPERCENT: - if (n > 100) - n = 100; - jump_percent(n); - break; - } - return args; -} - -/* - * goend - * - * Goto the end of the file. Future variation should include the GNU less(1)- - * style follow a-la tail(1). - */ -static const char * -cgoend(cident, args) - enum cident cident; - const char *args; -{ - ENDPARSE; - jump_forw(); - return args; -} - -/* - * edit - * - * Edits the current file with a word editor. This command is just begging - * to be extended to allow the user to specify an editor. Additionally, this - * would require some kind of getenv command or similar change. - */ -static const char * -cedit(cident, args) - enum cident cident; - const char *args; -{ - extern ispipe; - - ENDPARSE; - if (ispipe) { - SETERRSTR(E_NULL, "cannot edit standard input"); - return NULL; - } - editfile(); - /* - * XXX less-than brilliant things happen if the user while editing - * deletes a large section at the end of the file where we think we - * are currently viewing... - */ - ch_init(0, 0); /* Clear the internal file buffer */ - clr_linenum(); - return args; -} - -/* - * askfile - * - * Loads a new file. Queries the user for the name of the new file. - */ -static const char * -caskfile(cident, args) - enum cident cident; - const char *args; -{ - char buf[MAXPATHLEN + 1]; - - ENDPARSE; - if (getinput("Examine: ", buf, sizeof(buf))) - return args; /* abort */ - /* Abort is different from a "" answer in that "" causes the current - * file to be re-opened. */ - /* XXX should modify this() or edit() to handle lists of file, ie. - * the type of lists that I get if I try to glob("*") */ - (void)edit(glob(buf), FORCE_OPEN); - - return args; -} - -/* - * file <<next|previous>> <<N>> - * - * Loads the N'th next or previous file, typically from the list of files - * given on the command line. - */ -static const char * -cfile(cident, args) - enum cident cident; - const char *args; -{ - enum { FORW=0, BACK=1 } direction; - long N; - - ARGTOG(direction, 10, "next", "previous", "forward", "backward", - "forwards", "backwards", "next", "prev", "forw", "back"); - ARGNUM(N); - ENDPARSE; - direction %= 2; - - /* next_file() and prev_file() call error() directly (bad) */ - switch (direction) { - case FORW: - next_file(N); - break; - case BACK: - prev_file(N); - break; - } - settog("_file_direction", direction, 2, "next", "previous"); - return args; -} - -/* - * file_list - * - * Lists the files the "file next" and "file prev" are moving around in. - */ -static const char * -cfile_list(cident, args) - enum cident cident; - const char *args; -{ - ENDPARSE; - showlist(); - repaint(); /* screen_trashed = 1; */ - return args; -} - -/* - * stat <<on|off>> - * - * Display the detailed statistics as part of the prompt. The toggle option - * variable is called _statprompt (giving ${_statprompt_s} and - * ${_statprompt_n}). - */ -static const char * -cstat(cident, args) - enum cident cident; - const char *args; -{ - int onoff; - - ARGTOG(onoff, 2, "on", "off"); - ENDPARSE; - statprompt(onoff); - settog("_statprompt", onoff, 2, "on", "off"); - return args; -} - -/* - * magicasksearch <<forw|back>> <<n>> - * search <<forw|back>> <<n>> <<<noinvert|invert>> <searchstring>> - * research <<forw|back>> <<n>> - * - * Arguments specifying an option (ie. <<forw|back>> and <<noinvert|invert>> - * may be specified either as text (eg. "forw"), or as a number, in which case - * even numbers specify the former setting and odd numbers the latter setting. - * - * The magicasksearch will ask the user for a regexp and intuit whether they - * want to invert the sense of matching or not: if the first character of the - * regexp is a '!', it is removed and the sense is inverted. If the regexp - * entered is null, then we will use ${_ls_regexp} (error if not set). - * - * The toggle options are called _ls_direction and _ls_sense. In addition, - * ${_ls_regexp} is set to the regexp used. These variables are only set - * when the search and magicsearch commands are used. - */ -static const char * -csearch(cident, args) - enum cident cident; - const char *args; -{ - char buf[100], *str; - enum { FORW=0, BACK=1 } direction; - static enum { NOINVERT=0, INVERT=1 } sense; - long N; - int abrt = 0; - - ARGTOG(direction, 6, "forw", "back", "forward", "backward", - "forwards", "backwards"); - ARGNUM(N); - if (cident == SEARCH) { - ARGTOG(sense, 2, "noinvert", "invert"); - ARGSTR(str); - } - ENDPARSE; - direction %= 2; - - /* Get the search string, one way or another */ - switch (cident) { - case MAGICASKSEARCH: - biggetinputhack(); /* It's magic, boys */ - if (direction == FORW) - abrt = getinput("Search: /", buf, 2); - else - abrt = getinput("Search: ?", buf, 2); - switch (*buf) { - case '!': - /* Magic */ - if (direction == FORW) - abrt = getinput("Search: !/", buf, sizeof(buf)); - else - abrt = getinput("Search: !?", buf, sizeof(buf)); - sense = INVERT; - break; - default: - /* No magic */ - ungetcc(*buf); - if (direction == FORW) - abrt = getinput("Search: /", buf, sizeof(buf)); - else - abrt = getinput("Search: ?", buf, sizeof(buf)); - case '\0': - sense = NOINVERT; - break; - } - str = buf; - break; - case SEARCH: - break; - case RESEARCH: - str = NULL; - break; - } - - if (abrt) - return args; - - if (cident == SEARCH || cident == MAGICASKSEARCH) { - settog("_ls_direction", direction, 2, "forw", "back"); - settog("_ls_sense", sense, 2, "noinvert", "invert"); - if (*str) - setvar("_ls_regexp", str); - } - /* - * XXX Currently search() contains magic to deal with (*str=='\0'). - * This magic should be moved into this function so that we can work - * as described in the function comment header. - */ - search(!direction, str, N, !sense); - return args; -} - -/* - * setmark <<character>> - * gomark <<character>> - * - * Set a marker at the current position, or goto a previously set marker. - * Character may be a-z, or '?' to ask the user to enter a character. The - * special mark '\'' may not be set, but may be the target of a goto. - */ -static const char * -cmark(cident, args) - enum cident cident; - const char *args; -{ - char smark[2]; - const char *mark; - - ARGSTR(mark); - ENDPARSE; - - /* gomark() and setmark() will further check mark's validity */ - if (!*mark || mark[1]) { - SETERRSTR(E_NULL, "bad mark character"); - return NULL; - } - - if (*mark == '?') { - biggetinputhack(); /* so getinput() returns after one char */ - switch (cident) { - case GOMARK: - getinput("goto mark: ", smark, sizeof smark); - break; - case SETMARK: - getinput("set mark: ", smark, sizeof smark); - break; - } - if (!*smark) - return args; - mark = smark; - } - - switch (cident) { - case GOMARK: - gomark(*mark); - break; - case SETMARK: - setmark(*mark); - break; - } - return args; -} - -/* - * asktag - * nexttag <<number>> - * prevtag <<number>> - * - * Asks the user for a tag, or moves around the tag queue. - */ -static const char * -ctags(cident, args) - enum cident cident; - const char *args; -{ - extern char *tagfile; /* XXX No reason for this to be a global... */ - long n; - - if (cident != ASKFTAG) - ARGNUM(n); - ENDPARSE; - - if (cident == ASKFTAG) { - char buf[100]; /* XXX should do something else... */ - getinput("Tag: ", buf, sizeof(buf)); - if (!*buf) - return args; - findtag(buf); - } else { - switch (cident) { - case NEXTFTAG: - nexttag(n); - break; - case PREVFTAG: - prevtag(n); - break; - } - } - - /* Load the tagfile and position ourselves. */ - if (tagfile == NULL) - return NULL; - if (edit(tagfile, NO_FORCE_OPEN)) - tagsearch(); - return args; /* tag stuff still calls error() on its own */ -} diff --git a/usr.bin/more/option.c b/usr.bin/more/option.c deleted file mode 100644 index 1bb2202..0000000 --- a/usr.bin/more/option.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 1988 Mark Nudleman - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)option.c 8.1 (Berkeley) 6/6/93"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include <stdio.h> -#include <less.h> - -int top_scroll; /* Repaint screen from top */ -int bs_mode; /* How to process backspaces */ -int caseless; /* Do "caseless" searches */ -int cbufs = 10; /* Current number of buffers */ -int linenums = 1; /* Use line numbers */ -int quit_at_eof; -int squeeze; /* Squeeze multiple blank lines into one */ -int tabstop = 8; /* Tab settings */ -int tagoption; - -char *firstsearch; - -static void usage __P((void)); - -option(argc, argv) - int argc; - char **argv; -{ - extern char *optarg; - extern int optind; - static int sc_window_set = 0; - int ch; - char *p; - - /* backward compatible processing for "+/search" */ - char **a; - for (a = argv; *a; ++a) - if ((*a)[0] == '+' && (*a)[1] == '/') - (*a)[0] = '-'; - - optind = 1; /* called twice, re-init getopt. */ - while ((ch = getopt(argc, argv, "/:ceinst:ux:f")) != -1) - switch((char)ch) { - case '/': - /* - * Might be interesting to make this option search - * through the whole list of files on the command line - * until a match is found. Prior to this commit adding - * the new comand interpreter, it would sort-of do - * this, provided all the files listed on the command - * line were of length zero bytes (well, with the - * exception of the file actually containing a match, - * I suppose). - */ - firstsearch = optarg; - break; - case 'c': - top_scroll = 1; - break; - case 'e': - quit_at_eof = 1; - break; - case 'i': - caseless = 1; - break; - case 'n': - linenums = 0; - break; - case 's': - squeeze = 1; - break; - case 't': - tagoption = 1; - findtag(optarg); - break; - case 'u': - bs_mode = 1; - break; - case 'x': - tabstop = atoi(optarg); - if (tabstop <= 0) - tabstop = 8; - break; - case 'f': /* ignore -f, compatability with old more */ - break; - case '?': - default: - usage(); - } - return(optind); -} - -static void -usage() -{ - fprintf(stderr, - "usage: more [-ceinsu] [-t tag] [-x tabs] [-/ pattern] [file ...]\n"); - exit(1); -} diff --git a/usr.bin/more/os.c b/usr.bin/more/os.c deleted file mode 100644 index 5ae3b75..0000000 --- a/usr.bin/more/os.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (c) 1988 Mark Nudleman - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char sccsid[] = "@(#)os.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ - -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -/* - * Operating system dependent routines. - * - * Most of the stuff in here is based on Unix, but an attempt - * has been made to make things work on other operating systems. - * This will sometimes result in a loss of functionality, unless - * someone rewrites code specifically for the new operating system. - * - * The makefile provides defines to decide whether various - * Unix features are present. - */ - -#include <sys/file.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/types.h> - -#include <errno.h> -#include <setjmp.h> -#include <signal.h> -#include <stdio.h> -#include <string.h> - -#include "less.h" -#include "pathnames.h" - -volatile int reading; - -extern int screen_trashed; - -static jmp_buf read_label; - -/* - * Pass the specified command to a shell to be executed. - * Like plain "system()", but handles resetting terminal modes, etc. - */ -lsystem(cmd) - char *cmd; -{ - int inp; - char cmdbuf[256]; - char *shell, *getenv(); - - /* - * Print the command which is to be executed, - * unless the command starts with a "-". - */ - if (cmd[0] == '-') - cmd++; - else - { - lower_left(); - clear_eol(); - putstr("!"); - putstr(cmd); - putstr("\n"); - } - - /* - * De-initialize the terminal and take out of raw mode. - */ - deinit(); - flush(); - raw_mode(0); - - /* - * Restore signals to their defaults. - */ - init_signals(0); - - /* - * Force standard input to be the terminal, "/dev/tty", - * even if less's standard input is coming from a pipe. - */ - inp = dup(0); - (void)close(0); - if (open(_PATH_TTY, O_RDONLY, 0) < 0) - (void)dup(inp); - - /* - * Pass the command to the system to be executed. - * If we have a SHELL environment variable, use - * <$SHELL -c "command"> instead of just <command>. - * If the command is empty, just invoke a shell. - */ - if ((shell = getenv("SHELL")) != NULL && *shell != '\0') - { - if (*cmd == '\0') - cmd = shell; - else - { - (void)snprintf(cmdbuf, sizeof(cmdbuf), - "%s -c \"%s\"", shell, cmd); - cmd = cmdbuf; - } - } - if (*cmd == '\0') - cmd = "sh"; - - (void)system(cmd); - - /* - * Restore standard input, reset signals, raw mode, etc. - */ - (void)close(0); - (void)dup(inp); - (void)close(inp); - - init_signals(1); - raw_mode(1); - init(); - screen_trashed = 1; -#if defined(SIGWINCH) || defined(SIGWIND) - /* - * Since we were ignoring window change signals while we executed - * the system command, we must assume the window changed. - */ - winch(); -#endif -} - -/* - * Like read() system call, but is deliberately interruptable. - * A call to intread() from a signal handler will interrupt - * any pending iread(). - */ -iread(fd, buf, len) - int fd; - char *buf; - int len; -{ - register int n; - static int neofs; - - if (setjmp(read_label)) - /* - * We jumped here from intread. - */ - return (READ_INTR); - - flush(); - reading = 1; - n = read(fd, buf, len); - /* - * XXX This is a hack. We do want to exit if we read a couple EOFs - * from the terminal (to avoid spinning on input if the user - * leaves us hanging), but we should be comparing against the - * tty variable from ttyin.c. - * - * We wait for two successive EOFs just to give any potential - * oddities the benefit of the doubt. - */ - if (fd == 2) { - if (n == 0) - neofs++; - else - neofs = 0; - } - if (neofs > 2) kill(getpid(), SIGHUP); - - reading = 0; - if (n < 0) - return (-1); - return (n); -} - -intread() -{ - reading = 0; - (void)sigsetmask(0L); - longjmp(read_label, 1); -} - -/* - * Expand a filename, substituting any environment variables, etc. - * The implementation of this is necessarily very operating system - * dependent. This implementation is unabashedly only for Unix systems. - */ -FILE *popen(); - -char * -glob(filename) - char *filename; -{ - FILE *f; - char *p; - int ch; - char *cmd, *malloc(), *getenv(); - static char buffer[MAXPATHLEN]; - - if (filename[0] == '#') - return (filename); - - /* - * We get the shell to expand the filename for us by passing - * an "echo" command to the shell and reading its output. - */ - p = getenv("SHELL"); - if (p == NULL || *p == '\0') - { - /* - * Read the output of <echo filename>. - */ - (void)asprintf(&cmd, "echo \"%s\"", filename); - if (cmd == NULL) - return (filename); - } else - { - /* - * Read the output of <$SHELL -c "echo filename">. - */ - (void)asprintf(&cmd, "%s -c \"echo %s\"", p, filename); - if (cmd == NULL) - return (filename); - } - - if ((f = popen(cmd, "r")) == NULL) - return (filename); - free(cmd); - - for (p = buffer; p < &buffer[sizeof(buffer)-1]; p++) - { - if ((ch = getc(f)) == '\n' || ch == EOF) - break; - *p = ch; - } - *p = '\0'; - (void)pclose(f); - return(buffer); -} - -char * -bad_file(filename, message, len) - char *filename, *message; - u_int len; -{ - struct stat statbuf; - char *strcat(), *strerror(); - - if (stat(filename, &statbuf) < 0) { - (void)snprintf(message, len, - "%s: %s", filename, strerror(errno)); - return(message); - } - if ((statbuf.st_mode & S_IFMT) == S_IFDIR) { - static char is_dir[] = " is a directory"; - - strtcpy(message, filename, (int)(len-sizeof(is_dir)-1)); - (void)strcat(message, is_dir); - return(message); - } - return((char *)NULL); -} - -/* - * Copy a string, truncating to the specified length if necessary. - * Unlike strncpy(), the resulting string is guaranteed to be null-terminated. - */ -strtcpy(to, from, len) - char *to, *from; - int len; -{ - char *strncpy(); - - (void)strncpy(to, from, (int)len); - to[len-1] = '\0'; -} - diff --git a/usr.bin/more/output.c b/usr.bin/more/output.c deleted file mode 100644 index cf07f09..0000000 --- a/usr.bin/more/output.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright (c) 1988 Mark Nudleman - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char sccsid[] = "@(#)output.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ - -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -/* - * High level routines dealing with the output to the screen. - */ - -#include <ctype.h> -#include <stdio.h> -#include <string.h> - -#include "less.h" - -extern int bs_mode; -extern int sigs; -extern int sc_width, sc_height; -extern int ul_width, ue_width; -extern int so_width, se_width; -extern int bo_width, be_width; -extern int tabstop; -extern int screen_trashed; -extern char *line; -extern int horiz_off; -extern int mode_flags; - -static int last_pos_highlighted = 0; - -/* static markup() - * - * Output correct markup char; return number of columns eaten-up. - * Called by put_line() just before doing any actual output. - */ -#define ENTER 1 -#define ACQUIESCE 0 /* XXX Check actual def'n... */ -#define EXIT -1 - -static -markup(ent_ul, ent_bo) - int *ent_ul, *ent_bo; -{ - int retr; - - retr = 0; - switch (*ent_ul) { - case ENTER: - ul_enter(); - retr += ul_width; - break; - case EXIT: - ul_exit(); - retr += ue_width; - break; - } - switch (*ent_bo) { - case ENTER: - bo_enter(); - retr += bo_width; - break; - case EXIT: - bo_exit(); - retr += be_width; - break; - } - *ent_ul = *ent_bo = ACQUIESCE; - return retr; -} - -/* put_line() - * - * Display the line which is in the line buffer. The number of output - * characters in the line buffer cannot exceed screen columns available. - * Output characters in the line buffer that precede horiz_off are skipped. - * The caller may depend on this behaviour to ensure that the number of output - * characters in the line buffer does not exceed the screen columns - * available. - * - * This routine will get confused if the line buffer has non-sensical - * UL_CHAR, UE_CHAR, BO_CHAR, BE_CHAR markups. - */ -#define MAYPUTCHR(char) \ - if (column >= horiz_off) { \ - column += markup(&ent_ul, &ent_bo); \ - putchr(char); \ - } - -put_line() -{ - register char *p; - register int c; - register int column; - extern int auto_wrap, ignaw; - int ent_ul, ent_bo; /* enter or exit ul|bo mode for next char */ - - if (sigs) - { - /* - * Don't output if a signal is pending. - */ - screen_trashed = 1; - return; - } - - if (line == NULL) - line = ""; - - if (last_pos_highlighted) - { - clear_eol(); - last_pos_highlighted = 0; - } - column = 0; - ent_ul = ent_bo = ACQUIESCE; - for (p = line; *p != '\0'; p++) - { - /* - * XXX line.c needs to be rewritten to store markup - * information as metadata associated with each character. - * This will make several things much nicer, fixing problems, - * etc. Until then, this kludge will hold the fort well - * enough. - */ - switch ((char)(c = (unsigned char)*p)) - { - case UL_CHAR: - ent_ul = ENTER; - break; - case UE_CHAR: - if (ent_ul != ENTER) - ent_ul = EXIT; - else - ent_ul = ACQUIESCE; - break; - case BO_CHAR: - ent_bo = ENTER; - break; - case BE_CHAR: - if (ent_bo != ENTER) - ent_bo = EXIT; - else - ent_bo = ACQUIESCE; - break; - case '\t': - do - { - MAYPUTCHR(' '); - column++; - } while ((column % tabstop) != 0); - break; - case '\b': - /* - * column must be at least one greater than - * horiz_off (ie. we must be in the second or - * beyond screen column) or we'll just end-up - * backspacing up to the previous line. - */ - if (column > horiz_off) { - column += markup(&ent_ul, &ent_bo); - putbs(); - column--; - } - break; - case '\r': - /* treat \r\n sequences like \n if -u flag not set. */ - if (bs_mode || p[1] != '\0') - { - /* -u was set, or this CR is not a CRLF, so - * treat this CR like any other control_char */ - MAYPUTCHR('^'); - column++; - MAYPUTCHR(CARAT_CHAR(c)); - column++; - } - break; - default: - if (c == 0200 || CONTROL_CHAR(c)) - { - c &= ~0200; - MAYPUTCHR('^'); - column++; - MAYPUTCHR(CARAT_CHAR(c)); - column++; - } else - { - MAYPUTCHR(c); - column++; - } - } - if (column == sc_width + horiz_off && mode_flags) - last_pos_highlighted = 1; - } - column += markup(&ent_ul, &ent_bo); - if (column < sc_width + horiz_off || !auto_wrap || ignaw) - putchr('\n'); -} - -static char obuf[2048]; /* just large enough for a full 25*80 screen */ -static char *ob = obuf; - -/* - * Flush buffered output. - */ -flush() -{ - register int n; - - n = ob - obuf; - if (n == 0) - return; - if (write(1, obuf, n) != n) - screen_trashed = 1; - ob = obuf; -} - -/* - * Purge any pending output. - */ -purge() -{ - - ob = obuf; -} - -/* - * Output a character. - */ -putchr(c) - int c; -{ - if (ob >= &obuf[sizeof(obuf)]) - flush(); - *ob++ = c; -} - -/* - * Output a string. - */ -putstr(s) - register char *s; -{ - while (*s != '\0') - putchr(*s++); -} - -/* - * Output a string, expanding control characters into printable sequences. - * Returns the number of characters printed. - */ -int -putxstr(s) - char *s; -{ - int c; - int retr = 0; - - for (; c = *s; s++) { - if (CONTROL_CHAR(c)) { - putchr('^'); - retr++; - c &= ~0200; - c = CARAT_CHAR(c); - } - putchr(c); - } - - return(retr); -} - -static char intr_to_abort[] = "... (interrupt to abort)"; - -ierror(s) - char *s; -{ - lower_left(); - clear_eol(); - so_enter(); - putstr(s); - putstr(intr_to_abort); - so_exit(); - flush(); -} diff --git a/usr.bin/more/pathnames.h b/usr.bin/more/pathnames.h deleted file mode 100644 index 647ade6..0000000 --- a/usr.bin/more/pathnames.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)pathnames.h 8.1 (Berkeley) 6/6/93 - * - * $FreeBSD$ - */ - -#include <paths.h> - -#define _PATH_HELPFILE "/usr/share/misc/more.help" -#define _PATH_RC ".morerc" -#define _PATH_DEFRC ".defmorerc" -#define _PATH_SYSMORERC "/etc/dot.morerc" -/* Should have a /etc/dot.defmorerc, too... */ diff --git a/usr.bin/more/position.c b/usr.bin/more/position.c deleted file mode 100644 index d9d8183..0000000 --- a/usr.bin/more/position.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 1988 Mark Nudleman - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char sccsid[] = "@(#)position.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ - -/* - * Routines dealing with the "position" table. - * This is a table which tells the position (in the input file) of the - * first char on each currently displayed line. - * - * {{ The position table is scrolled by moving all the entries. - * Would be better to have a circular table - * and just change a couple of pointers. }} - */ - -#include <sys/types.h> -#include <less.h> - -static off_t *table; /* The position table */ -static int tablesize; - -extern int sc_height; - -/* - * Return the starting file position of a line displayed on the screen. - * The line may be specified as a line number relative to the top - * of the screen, but is usually one of these special cases: - * the top (first) line on the screen - * the second line on the screen - * the bottom line on the screen - * the line after the bottom line on the screen - */ -off_t -position(where) - int where; -{ - switch (where) - { - case BOTTOM: - where = sc_height - 2; - break; - case BOTTOM_PLUS_ONE: - where = sc_height - 1; - break; - case MIDDLE: - where = sc_height / 2; - } - return (table[where]); -} - -/* - * Add a new file position to the bottom of the position table. - */ -add_forw_pos(pos) - off_t pos; -{ - register int i; - - /* - * Scroll the position table up. - */ - for (i = 1; i < sc_height; i++) - table[i-1] = table[i]; - table[sc_height - 1] = pos; -} - -/* - * Add a new file position to the top of the position table. - */ -add_back_pos(pos) - off_t pos; -{ - register int i; - - /* - * Scroll the position table down. - */ - for (i = sc_height - 1; i > 0; i--) - table[i] = table[i-1]; - table[0] = pos; -} - -/* - * Remove any NULL_POSITION markers from the top of the table, moving - * the bottom part up, if necessary. - */ -copytable() -{ - register int a, b; - - for (a = 0; a < sc_height && table[a] == NULL_POSITION; a++); - for (b = 0; a < sc_height; a++, b++) { - table[b] = table[a]; - table[a] = NULL_POSITION; - } -} - -/* - * Initialize the position table, done whenever we clear the screen. - */ -pos_clear() -{ - register int i; - extern char *malloc(), *realloc(); - - if (table == 0) { - tablesize = sc_height > 25 ? sc_height : 25; - table = (off_t *)malloc(tablesize * sizeof *table); - } else if (sc_height >= tablesize) { - tablesize = sc_height; - table = (off_t *)realloc(table, tablesize * sizeof *table); - } - - for (i = 0; i < sc_height; i++) - table[i] = NULL_POSITION; -} - -/* - * See if the byte at a specified position is currently on the screen. - * Check the position table to see if the position falls within its range. - * Return the position table entry if found, -1 if not. - * - * This function doesn't really work when horizontal scrolling is enabled. - * I suspect it may not work in a few other cases, too. - */ -onscreen(pos) - off_t pos; -{ - register int i; - - if (pos < table[0]) - return (-1); - for (i = 1; i < sc_height; i++) - if (pos < table[i]) - return (i-1); - return (-1); -} diff --git a/usr.bin/more/prim.c b/usr.bin/more/prim.c deleted file mode 100644 index 30e020b..0000000 --- a/usr.bin/more/prim.c +++ /dev/null @@ -1,842 +0,0 @@ -/* - * Copyright (c) 1988 Mark Nudleman - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char sccsid[] = "@(#)prim.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ - -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -/* - * Primitives for displaying the file on the screen. - */ - -#include <sys/types.h> - -#include <assert.h> -#include <ctype.h> -#include <limits.h> -#include <regex.h> -#include <stdio.h> - -#include "less.h" - -int back_scroll = -1; -int hit_eof; /* true if we're displaying the end of the input */ -int screen_trashed; - -static int squished; - -extern int sigs; -extern int top_scroll; -extern int sc_width, sc_height; -extern int horiz_off; -extern int wraplines; -extern int caseless; -extern int linenums; -extern int tagoption; -extern char *line; -extern int retain_below; - -off_t position(), forw_line(), back_line(), forw_raw_line(), back_raw_line(); -off_t ch_length(), ch_tell(); - -/* - * Check to see if the end of file is currently "displayed". - */ -static -eof_check() -{ - off_t pos; - - if (sigs) - return; - /* - * If the bottom line is empty, we are at EOF. - * If the bottom line ends at the file length, - * we must be just at EOF. - */ - pos = position(BOTTOM_PLUS_ONE); - if (pos == NULL_POSITION || pos == ch_length()) - hit_eof++; -} - -/* - * If the screen is "squished", repaint it. - * "Squished" means the first displayed line is not at the top - * of the screen; this can happen when we display a short file - * for the first time. - */ -static -squish_check() -{ - if (squished) { - squished = 0; - repaint(); - } -} - -/* - * Display n lines, scrolling forward, starting at position pos in the - * input file. "only_last" means display only the last screenful if - * n > screen size. - */ -static -forw(n, pos, only_last) - register int n; - off_t pos; - int only_last; -{ - extern int short_file; - static int first_time = 1; - int eof = 0, do_repaint; - - squish_check(); - - /* - * do_repaint tells us not to display anything till the end, - * then just repaint the entire screen. - */ - do_repaint = (only_last && n > sc_height-1); - - if (!do_repaint) { - if (top_scroll && n >= sc_height - 1) { - /* - * Start a new screen. - * {{ This is not really desirable if we happen - * to hit eof in the middle of this screen, - * but we don't yet know if that will happen. }} - */ - clear(); - home(); - } else { - lower_left(); - clear_eol(); - } - - /* - * This is not contiguous with what is currently displayed. - * Clear the screen image (position table) and start a new - * screen. - */ - if (pos != position(BOTTOM_PLUS_ONE)) { - pos_clear(); - add_forw_pos(pos); - if (top_scroll) { - clear(); - home(); - } - } - } - - for (short_file = 0; --n >= 0;) { - /* - * Read the next line of input. - */ - pos = forw_line(pos); - if (pos == NULL_POSITION) { - /* - * end of file; copy the table if the file was - * too small for an entire screen. - */ - eof = 1; - if (position(TOP) == NULL_POSITION) { - copytable(); - if (!position(TOP)) - short_file = 1; - } - break; - } - /* - * Add the position of the next line to the position table. - * Display the current line on the screen. - */ - add_forw_pos(pos); - if (do_repaint) - continue; - /* - * If this is the first screen displayed and we hit an early - * EOF (i.e. before the requested number of lines), we - * "squish" the display down at the bottom of the screen. - * But don't do this if a -t option was given; it can cause - * us to start the display after the beginning of the file, - * and it is not appropriate to squish in that case. - */ - if (first_time && line == NULL && !top_scroll && !tagoption) { - squished = 1; - continue; - } - put_line(); - } - - if (eof && !sigs) - hit_eof++; - else - eof_check(); - if (do_repaint) - repaint(); - first_time = 0; - (void) currline(BOTTOM); -} - -/* - * Display n lines, scrolling backward. - */ -static -back(n, pos, only_last) - register int n; - off_t pos; - int only_last; -{ - int do_repaint; - - squish_check(); - do_repaint = (n > get_back_scroll() || (only_last && n > sc_height-1)); - hit_eof = 0; - while (--n >= 0) - { - /* - * Get the previous line of input. - */ - pos = back_line(pos); - if (pos == NULL_POSITION) - break; - /* - * Add the position of the previous line to the position table. - * Display the line on the screen. - */ - add_back_pos(pos); - if (!do_repaint) - { - if (retain_below) - { - lower_left(); - clear_eol(); - } - home(); - add_line(); - put_line(); - } - } - - eof_check(); - if (do_repaint) - repaint(); - (void) currline(BOTTOM); -} - -/* - * Display n more lines, forward. - * Start just after the line currently displayed at the bottom of the screen. - */ -forward(n, only_last) - int n; - int only_last; -{ - off_t pos; - - if (hit_eof) { - /* - * If we're trying to go forward from end-of-file, - * go on to the next file. - */ - next_file(1); - return; - } - - pos = position(BOTTOM_PLUS_ONE); - if (pos == NULL_POSITION) - { - hit_eof++; - return; - } - forw(n, pos, only_last); -} - -/* - * Display n more lines, backward. - * Start just before the line currently displayed at the top of the screen. - */ -backward(n, only_last) - int n; - int only_last; -{ - off_t pos; - - pos = position(TOP); - /* - * This will almost never happen, because the top line is almost - * never empty. - */ - if (pos == NULL_POSITION) - return; - back(n, pos, only_last); -} - -/* - * Repaint the screen, starting from a specified position. - */ -prepaint(pos) - off_t pos; -{ - hit_eof = 0; - forw(sc_height - 1, pos, 0); - screen_trashed = 0; -} - -/* - * Repaint the screen. - */ -repaint() -{ - /* - * Start at the line currently at the top of the screen - * and redisplay the screen. - */ - prepaint(position(TOP)); -} - -/* - * Jump to the end of the file. - * It is more convenient to paint the screen backward, - * from the end of the file toward the beginning. - */ -jump_forw() -{ - off_t pos; - - if (ch_end_seek()) - { - error("Cannot seek to end of file"); - return; - } - lastmark(); - pos = ch_tell(); - clear(); - pos_clear(); - add_back_pos(pos); - back(sc_height - 1, pos, 0); -} - -/* - * Jump to line n in the file. - */ -jump_back(n) - register int n; -{ - register int c, nlines; - - /* - * This is done the slow way, by starting at the beginning - * of the file and counting newlines. - * - * {{ Now that we have line numbering (in linenum.c), - * we could improve on this by starting at the - * nearest known line rather than at the beginning. }} - */ - if (ch_seek((off_t)0)) { - /* - * Probably a pipe with beginning of file no longer buffered. - * If he wants to go to line 1, we do the best we can, - * by going to the first line which is still buffered. - */ - if (n <= 1 && ch_beg_seek() == 0) - jump_loc(ch_tell()); - error("Cannot get to beginning of file"); - return; - } - - /* - * Start counting lines. - */ - for (nlines = 1; nlines < n; nlines++) - while ((c = ch_forw_get()) != '\n') - if (c == EOI) { - char message[40]; - (void)snprintf(message, sizeof(message), - "File has only %d lines", nlines - 1); - error(message); - return; - } - jump_loc(ch_tell()); -} - -/* - * Jump to a specified percentage into the file. - * This is a poor compensation for not being able to - * quickly jump to a specific line number. - */ -jump_percent(percent) - int percent; -{ - off_t pos, len, ch_length(); - register int c; - - /* - * Determine the position in the file - * (the specified percentage of the file's length). - */ - if ((len = ch_length()) == NULL_POSITION) - { - error("Don't know length of file"); - return; - } - pos = (percent * len) / 100; - - /* - * Back up to the beginning of the line. - */ - if (ch_seek(pos) == 0) - { - while ((c = ch_back_get()) != '\n' && c != EOI) - ; - if (c == '\n') - (void) ch_forw_get(); - pos = ch_tell(); - } - jump_loc(pos); -} - -/* - * Jump to a specified position in the file. - */ -jump_loc(pos) - off_t pos; -{ - register int nline; - off_t tpos; - - if ((nline = onscreen(pos)) >= 0) { - /* - * The line is currently displayed. - * Just scroll there. - */ - forw(nline, position(BOTTOM_PLUS_ONE), 0); - return; - } - - /* - * Line is not on screen. - * Seek to the desired location. - */ - if (ch_seek(pos)) { - error("Cannot seek to that position"); - return; - } - - /* - * See if the desired line is BEFORE the currently displayed screen. - * If so, then move forward far enough so the line we're on will be - * at the bottom of the screen, in order to be able to call back() - * to make the screen scroll backwards & put the line at the top of - * the screen. - * {{ This seems inefficient, but it's not so bad, - * since we can never move forward more than a - * screenful before we stop to redraw the screen. }} - */ - tpos = position(TOP); - if (tpos != NULL_POSITION && pos < tpos) { - off_t npos = pos; - /* - * Note that we can't forw_line() past tpos here, - * so there should be no EOI at this stage. - */ - for (nline = 0; npos < tpos && nline < sc_height - 1; nline++) - npos = forw_line(npos); - - if (npos < tpos) { - /* - * More than a screenful back. - */ - lastmark(); - clear(); - pos_clear(); - add_back_pos(npos); - } - - /* - * Note that back() will repaint() if nline > back_scroll. - */ - back(nline, npos, 0); - return; - } - /* - * Remember where we were; clear and paint the screen. - */ - lastmark(); - prepaint(pos); -} - -/* - * The table of marks. - * A mark is simply a position in the file. - */ -#define NMARKS (27) /* 26 for a-z plus one for quote */ -#define LASTMARK (NMARKS-1) /* For quote */ -static struct mark { - int horiz_off; - int wraplines; - off_t pos; - char *file; -} marks[NMARKS]; - -/* - * Initialize the mark table to show no marks are set. - */ -init_mark() -{ - int i; - - for (i = 0; i < NMARKS; i++) - marks[i].pos = NULL_POSITION, marks[i].file = NULL; -} - -/* - * See if a mark letter is valid (between a and z). - */ -static int -badmark(c) - int c; -{ - if (c < 'a' || c > 'z') - { - error("Choose a letter between 'a' and 'z'"); - return (1); - } - return (0); -} - -/* - * Set a mark. - */ -setmark(c) - int c; -{ - extern char *current_file; - - if (badmark(c)) - return; - marks[c-'a'].pos = position(TOP); - marks[c-'a'].horiz_off = horiz_off; - marks[c-'a'].wraplines = wraplines; - if (marks[c-'a'].file) free(marks[c-'a'].file); - asprintf(&marks[c-'a'].file, "%s", current_file); -} - -/* - * This function should be called whenever the file position we are viewing - * is changed by a significant amount. The function will record the current - * position and remember it for the user. - */ -lastmark() -{ - extern char *current_file; - - marks[LASTMARK].pos = position(TOP); - marks[LASTMARK].horiz_off = horiz_off; - marks[LASTMARK].wraplines = wraplines; - if (marks[LASTMARK].file) free(marks[LASTMARK].file); - asprintf(&marks[LASTMARK].file, "%s", current_file); -} - -/* - * Go to a previously set mark. - */ -gomark(c) - int c; -{ - off_t pos; - char *file; - int new_horiz_off, new_wraplines; - extern char *current_file; - - if (c == '\'') { - pos = marks[LASTMARK].pos; - if (pos == NULL_POSITION) - pos = 0; - file = marks[LASTMARK].file; - new_horiz_off = marks[LASTMARK].horiz_off; - new_wraplines = marks[LASTMARK].wraplines; - } else { - if (badmark(c)) - return; - pos = marks[c-'a'].pos; - if (pos == NULL_POSITION) { - error("mark not set"); - return; - } - file = marks[c-'a'].file; - new_horiz_off = marks[c-'a'].horiz_off; - new_wraplines = marks[c-'a'].wraplines; - } - - /* - * This can only fail if gomark('\'') is called before lastmark() - * is called, which is in turn impossible since both edit() and - * jump_back() call jump_loc() which calls lastmark() to start - * all files. - */ - assert (file); - - /* - * This can only fail if gomark() is called before any file has - * been opened. Calling gomark() before any file has been - * opened would be non-sensical. - */ - assert (current_file); - - /* - * XXX The edit() needs to return success or failure so that we - * can abort at this point if edit() fails. - */ - edit(file, NO_FORCE_OPEN); - - /* Try to be nice about changing the horizontal scroll and wrapping */ - if (new_horiz_off > horiz_off + sc_width / 3 || - new_horiz_off < horiz_off - sc_width / 3 || - wraplines != new_wraplines || strcmp(file, current_file)) { - /* - * We should change horiz_off: if we don't change horiz_off - * the bookmarked location won't be readily visible. - */ - - /* - * A prepaint() doesn't call lastmark() (jump_loc() does), - * but we need to call repaint() somewhere since we've - * changed the horizontal offset. We don't want to call - * jump_loc() followed by repaint() since that represents - * more unnecessary screen redrawing than I'm comfortable - * with. Manually calling lastmark() here means, however, - * that lastmark() is always called even if we scroll only - * a few lines --- unlike letting jump_loc() call lastmark() - * where lastmark() is only called for jumps of more than - * a screenful. A better interface is needed. - */ - lastmark(); - - horiz_off = new_horiz_off; - wraplines = new_wraplines; - prepaint(pos); - } else { - /* - * We can honour the bookmark request without doing any - * horizontal scrolling. - */ - jump_loc(pos); - } -} - -/* - * Get the backwards scroll limit. - * Must call this function instead of just using the value of - * back_scroll, because the default case depends on sc_height and - * top_scroll, as well as back_scroll. - */ -get_back_scroll() -{ - if (back_scroll >= 0) - return (back_scroll); - if (top_scroll) - return (sc_height - 2); - return (sc_height - 1); -} - -/* - * Search for the n-th occurence of a specified pattern, - * either forward or backward. - */ -search(search_forward, pattern, n, wantmatch) - register int search_forward; - register char *pattern; - register int n; - int wantmatch; -{ - off_t pos, linepos; - register char *p; - register char *q; - int linenum; - int linematch; - static regex_t rx; - static int oncethru; - int regerr; - char errbuf[_POSIX2_LINE_MAX]; - - if (pattern && pattern[0]) { - if (oncethru) { - regfree(&rx); - } - - regerr = regcomp(&rx, pattern, (REG_EXTENDED | REG_NOSUB - | (caseless ? REG_ICASE : 0))); - - if (regerr) { - regerror(regerr, &rx, errbuf, sizeof errbuf); - error(errbuf); - oncethru = 0; - regfree(&rx); - return (0); - } - oncethru = 1; - } else if (!oncethru) { - error("No previous regular expression"); - return (0); - } - - /* - * Figure out where to start the search. - * - * XXX This should probably be adapted to handle horizontal - * scrolling. Consider a long line at the top of the screen - * that might be hiding more matches to its right (when doing - * successive searches). - */ - - if (position(TOP) == NULL_POSITION) { - /* - * Nothing is currently displayed. Start at the beginning - * of the file. (This case is mainly for searches from the - * command line. - */ - pos = (off_t)0; - } else if (!search_forward) { - /* - * Backward search: start just before the top line - * displayed on the screen. - */ - pos = position(TOP); - } else { - /* - * Start at the second screen line displayed on the screen. - */ - pos = position(TOP_PLUS_ONE); - } - - if (pos == NULL_POSITION) - { - /* - * Can't find anyplace to start searching from. - */ - error("Nothing to search"); - return(0); - } - - linenum = find_linenum(pos); - for (;;) - { - /* - * Get lines until we find a matching one or - * until we hit end-of-file (or beginning-of-file - * if we're going backwards). - */ - if (sigs) - /* - * A signal aborts the search. - */ - return(0); - - if (search_forward) - { - /* - * Read the next line, and save the - * starting position of that line in linepos. - */ - linepos = pos; - pos = forw_raw_line(pos); - if (linenum != 0) - linenum++; - } else - { - /* - * Read the previous line and save the - * starting position of that line in linepos. - */ - pos = back_raw_line(pos); - linepos = pos; - if (linenum != 0) - linenum--; - } - - if (pos == NULL_POSITION) - { - /* - * We hit EOF/BOF without a match. - */ - error("Pattern not found"); - return(0); - } - - /* - * If we're using line numbers, we might as well - * remember the information we have now (the position - * and line number of the current line). - */ - if (linenums) - add_lnum(linenum, pos); - - /* - * Remove any backspaces along with the preceeding char. - * This allows us to match text which is underlined or - * overstruck. - */ - for (p = q = line; *p; p++, q++) - if (q > line && *p == '\b') - /* Delete BS and preceeding char. */ - q -= 2; - else - /* Otherwise, just copy. */ - *q = *p; - - /* - * Test the next line to see if we have a match. - */ - linematch = !regexec(&rx, line, 0, 0, 0); - - /* - * We are successful if wantmatch and linematch are - * both true (want a match and got it), - * or both false (want a non-match and got it). - */ - if (((wantmatch && linematch) || (!wantmatch && !linematch)) && - --n <= 0) - /* - * Found the line. - */ - break; - } - jump_loc(linepos); - return(1); -} diff --git a/usr.bin/more/screen.c b/usr.bin/more/screen.c deleted file mode 100644 index 0746e66..0000000 --- a/usr.bin/more/screen.c +++ /dev/null @@ -1,662 +0,0 @@ -/* - * Copyright (c) 1988 Mark Nudleman - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char sccsid[] = "@(#)screen.c 8.2 (Berkeley) 4/20/94"; -#endif /* not lint */ - -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -/* - * Routines which deal with the characteristics of the terminal. - * Uses termcap to be as terminal-independent as possible. - * - * {{ Someday this should be rewritten to use curses. }} - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <termcap.h> -#include <unistd.h> - -#include "less.h" - -#define TERMIOS 1 - -#if TERMIO -#include <termio.h> -#else -#if TERMIOS -#include <termios.h> -#define TAB3 0 -#include <sys/ioctl.h> -#else -#include <sgtty.h> -#endif -#endif - -#ifdef TIOCGWINSZ -#include <sys/ioctl.h> -#else -/* - * For the Unix PC (ATT 7300 & 3B1): - * Since WIOCGETD is defined in sys/window.h, we can't use that to decide - * whether to include sys/window.h. Use SIGPHONE from sys/signal.h instead. - */ -#include <sys/signal.h> -#ifdef SIGPHONE -#include <sys/window.h> -#endif -#endif - -/* - * Strings passed to tputs() to do various terminal functions. - */ -static char - *sc_pad, /* Pad string */ - *sc_home, /* Cursor home */ - *sc_addline, /* Add line, scroll down following lines */ - *sc_lower_left, /* Cursor to last line, first column */ - *sc_move, /* General cursor positioning */ - *sc_clear, /* Clear screen */ - *sc_eol_clear, /* Clear to end of line */ - *sc_s_in, /* Enter standout (highlighted) mode */ - *sc_s_out, /* Exit standout mode */ - *sc_u_in, /* Enter underline mode */ - *sc_u_out, /* Exit underline mode */ - *sc_b_in, /* Enter bold mode */ - *sc_b_out, /* Exit bold mode */ - *sc_backspace, /* Backspace cursor */ - *sc_init, /* Startup terminal initialization */ - *sc_deinit, /* Exit terminal de-intialization */ - *sc_keypad_on, /* Enter keypad mode */ - *sc_keypad_off; /* Exit keypad mode */ - -int auto_wrap; /* Terminal does \r\n when write past margin */ -int ignaw; /* Terminal ignores \n immediately after wrap */ - /* The user's erase and line-kill chars */ -int retain_below; /* Terminal retains text below the screen */ -int erase_char, kill_char, werase_char; -int sc_width, sc_height = -1; /* Height & width of screen */ -int bo_width, be_width; /* Printing width of boldface sequences */ -int ul_width, ue_width; /* Printing width of underline sequences */ -int so_width, se_width; /* Printing width of standout sequences */ - -int mode_flags = 0; -#define M_SO 1 -#define M_UL 2 -#define M_BO 4 - -/* - * These two variables are sometimes defined in, - * and needed by, the termcap library. - * It may be necessary on some systems to declare them extern here. - */ -/*extern*/ speed_t ospeed; /* Terminal output baud rate */ -/*extern*/ char PC; /* Pad character */ - -extern int back_scroll; - -/* - * Change terminal to "raw mode", or restore to "normal" mode. - * "Raw mode" means - * 1. An outstanding read will complete on receipt of a single keystroke. - * 2. Input is not echoed. - * 3. On output, \n is mapped to \r\n. - * 4. \t is NOT expanded into spaces. - * 5. Signal-causing characters such as ctrl-C (interrupt), - * etc. are NOT disabled. - * It doesn't matter whether an input \n is mapped to \r, or vice versa. - */ -raw_mode(on) - int on; -{ -#if TERMIO || TERMIOS - -#if TERMIO - struct termio s; - static struct termio save_term; -#else - struct termios s; - static struct termios save_term; -#endif - - if (on) - { - /* - * Get terminal modes. - */ -#if TERMIO - (void)ioctl(2, TCGETA, &s); -#else - tcgetattr(2, &s); -#endif - - /* - * Save modes and set certain variables dependent on modes. - */ - save_term = s; -#if TERMIO - ospeed = s.c_cflag & CBAUD; -#else - /* more work needed here */ -#endif - erase_char = s.c_cc[VERASE]; - kill_char = s.c_cc[VKILL]; - werase_char = s.c_cc[VWERASE]; - - /* - * Set the modes to the way we want them. - */ - s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL); - s.c_oflag |= (OPOST|ONLCR|TAB3); -#if TERMIO - s.c_oflag &= ~(OCRNL|ONOCR|ONLRET); -#endif - s.c_cc[VMIN] = 1; - s.c_cc[VTIME] = 0; - } else - { - /* - * Restore saved modes. - */ - s = save_term; - } -#if TERMIO - (void)ioctl(STDERR_FILENO, TCSETAW, &s); -#else - tcsetattr(STDERR_FILENO, TCSADRAIN, &s); -#endif -#else - struct sgttyb s; - struct ltchars l; - static struct sgttyb save_term; - - if (on) - { - /* - * Get terminal modes. - */ - (void)ioctl(STDERR_FILENO, TIOCGETP, &s); - (void)ioctl(STDERR_FILENO, TIOCGLTC, &l); - - /* - * Save modes and set certain variables dependent on modes. - */ - save_term = s; - ospeed = s.sg_ospeed; - erase_char = s.sg_erase; - kill_char = s.sg_kill; - werase_char = l.t_werasc; - - /* - * Set the modes to the way we want them. - */ - s.sg_flags |= CBREAK; - s.sg_flags &= ~(ECHO|XTABS); - } else - { - /* - * Restore saved modes. - */ - s = save_term; - } - (void)ioctl(STDERR_FILENO, TIOCSETN, &s); -#endif -} - -/* - * Get terminal capabilities via termcap. - */ -get_term() -{ - char termbuf[2048]; - char *sp; - char *term; - int hard; -#ifdef TIOCGWINSZ - struct winsize w; -#else -#ifdef WIOCGETD - struct uwdata w; -#endif -#endif - static char sbuf[1024]; - - /* - * Find out what kind of terminal this is. - */ - if ((term = getenv("TERM")) == NULL) - term = "unknown"; - if (tgetent(termbuf, term) <= 0) - (void)strcpy(termbuf, "dumb:co#80:hc:"); - - /* - * Get size of the screen. - */ -#ifdef TIOCGWINSZ - if (ioctl(STDERR_FILENO, TIOCGWINSZ, &w) == 0 && w.ws_row > 0) - sc_height = w.ws_row; - else -#else -#ifdef WIOCGETD - if (ioctl(STDERR_FILENO, WIOCGETD, &w) == 0 && w.uw_height > 0) - sc_height = w.uw_height/w.uw_vs; - else -#endif -#endif - sc_height = tgetnum("li"); - hard = (sc_height < 0 || tgetflag("hc")); - if (hard) { - /* Oh no, this is a hardcopy terminal. */ - sc_height = 24; - } - -#ifdef TIOCGWINSZ - if (ioctl(STDERR_FILENO, TIOCGWINSZ, &w) == 0 && w.ws_col > 0) - sc_width = w.ws_col; - else -#ifdef WIOCGETD - if (ioctl(STDERR_FILENO, WIOCGETD, &w) == 0 && w.uw_width > 0) - sc_width = w.uw_width/w.uw_hs; - else -#endif -#endif - sc_width = tgetnum("co"); - if (sc_width < 0) - sc_width = 80; - (void) setvari("_sc_height", (long) sc_height - 1); - (void) setvari("_sc_width", (long) sc_width); - - auto_wrap = tgetflag("am"); - ignaw = tgetflag("xn"); - retain_below = tgetflag("db"); - - /* - * Assumes termcap variable "sg" is the printing width of - * the standout sequence, the end standout sequence, - * the underline sequence, the end underline sequence, - * the boldface sequence, and the end boldface sequence. - */ - if ((so_width = tgetnum("sg")) < 0) - so_width = 0; - be_width = bo_width = ue_width = ul_width = se_width = so_width; - - /* - * Get various string-valued capabilities. - */ - sp = sbuf; - - sc_pad = tgetstr("pc", &sp); - if (sc_pad != NULL) - PC = *sc_pad; - - sc_init = tgetstr("ti", &sp); - if (sc_init == NULL) - sc_init = ""; - - sc_deinit = tgetstr("te", &sp); - if (sc_deinit == NULL) - sc_deinit = ""; - - sc_keypad_on = tgetstr("ks", &sp); - if (sc_keypad_on == NULL) - sc_keypad_on = ""; - - sc_keypad_off = tgetstr("ke", &sp); - if (sc_keypad_off == NULL) - sc_keypad_off = ""; - - sc_eol_clear = tgetstr("ce", &sp); - if (hard || sc_eol_clear == NULL || *sc_eol_clear == '\0') - { - sc_eol_clear = ""; - } - - sc_clear = tgetstr("cl", &sp); - if (hard || sc_clear == NULL || *sc_clear == '\0') - { - sc_clear = "\n\n"; - } - - sc_move = tgetstr("cm", &sp); - if (hard || sc_move == NULL || *sc_move == '\0') - { - /* - * This is not an error here, because we don't - * always need sc_move. - * We need it only if we don't have home or lower-left. - */ - sc_move = ""; - } - - sc_s_in = tgetstr("so", &sp); - if (hard || sc_s_in == NULL) - sc_s_in = ""; - - sc_s_out = tgetstr("se", &sp); - if (hard || sc_s_out == NULL) - sc_s_out = ""; - - sc_u_in = tgetstr("us", &sp); - if (hard || sc_u_in == NULL) - sc_u_in = sc_s_in; - - sc_u_out = tgetstr("ue", &sp); - if (hard || sc_u_out == NULL) - sc_u_out = sc_s_out; - - sc_b_in = tgetstr("md", &sp); - if (hard || sc_b_in == NULL) - { - sc_b_in = sc_s_in; - sc_b_out = sc_s_out; - } else - { - sc_b_out = tgetstr("me", &sp); - if (hard || sc_b_out == NULL) - sc_b_out = ""; - } - - sc_home = tgetstr("ho", &sp); - if (hard || sc_home == NULL || *sc_home == '\0') - { - if (*sc_move == '\0') - { - /* - * This last resort for sc_home is supposed to - * be an up-arrow suggesting moving to the - * top of the "virtual screen". (The one in - * your imagination as you try to use this on - * a hard copy terminal.) - */ - sc_home = "|\b^"; - } else - { - /* - * No "home" string, - * but we can use "move(0,0)". - */ - (void)strcpy(sp, tgoto(sc_move, 0, 0)); - sc_home = sp; - sp += strlen(sp) + 1; - } - } - - sc_lower_left = tgetstr("ll", &sp); - if (hard || sc_lower_left == NULL || *sc_lower_left == '\0') - { - if (*sc_move == '\0') - { - sc_lower_left = "\r"; - } else - { - /* - * No "lower-left" string, - * but we can use "move(0,last-line)". - */ - (void)strcpy(sp, tgoto(sc_move, 0, sc_height-1)); - sc_lower_left = sp; - sp += strlen(sp) + 1; - } - } - - /* - * To add a line at top of screen and scroll the display down, - * we use "al" (add line) or "sr" (scroll reverse). - */ - if ((sc_addline = tgetstr("al", &sp)) == NULL || - *sc_addline == '\0') - sc_addline = tgetstr("sr", &sp); - - if (hard || sc_addline == NULL || *sc_addline == '\0') - { - sc_addline = ""; - /* Force repaint on any backward movement */ - back_scroll = 0; - } - - if (tgetflag("bs")) - sc_backspace = "\b"; - else - { - sc_backspace = tgetstr("bc", &sp); - if (sc_backspace == NULL || *sc_backspace == '\0') - sc_backspace = "\b"; - } -} - -/* - * Retrieves string (if any) associated with tcap from the termcap. If the - * capability is not a string capability, an ascii approximation of the - * capability will be returned. Returns NULL if tcap cannot be found. - * The returned string is valid until the next call to gettermcap(). - */ -const char * -gettermcap(tcap) - char *tcap; -{ - char termbuf[2048]; - char *term; - static char sbuf[1024]; - char *sp = sbuf; - int i; - - /* - * Find out what kind of terminal this is. - */ - if ((term = getenv("TERM")) == NULL) - term = "unknown"; - if (tgetent(termbuf, term) <= 0) - (void)strcpy(termbuf, "dumb:co#80:hc:"); - - sp = tgetstr(tcap, &sp); - if (sp == NULL || !*sp) { - sprintf (sbuf, "%d", i=tgetnum(tcap)); - if (i == -1) - sprintf (sbuf, "%d", tgetflag(tcap)); - } - return sbuf; -} - -/* - * Below are the functions which perform all the - * terminal-specific screen manipulation. - */ - -int putchr(); - -/* - * Initialize terminal - */ -init() -{ - tputs(sc_init, sc_height, putchr); - tputs(sc_keypad_on, 1, putchr); -} - -/* - * Deinitialize terminal - */ -deinit() -{ - tputs(sc_deinit, sc_height, putchr); - tputs(sc_keypad_off, 1, putchr); -} - -/* - * Home cursor (move to upper left corner of screen). - */ -home() -{ - tputs(sc_home, 1, putchr); -} - -/* - * Add a blank line (called with cursor at home). - * Should scroll the display down. - */ -add_line() -{ - tputs(sc_addline, sc_height, putchr); -} - -int short_file; /* if file less than a screen */ -lower_left() -{ - if (short_file) { - putchr('\r'); - flush(); - } - else - tputs(sc_lower_left, 1, putchr); -} - -/* - * Ring the terminal bell. - */ -bell() -{ - putchr('\7'); -} - -/* - * Clear the screen. - */ -clear() -{ - if (mode_flags & M_SO) - so_exit(); - if (mode_flags & M_UL) - ul_exit(); - if (mode_flags & M_BO) - bo_exit(); - tputs(sc_clear, sc_height, putchr); -} - -/* - * Clear from the cursor to the end of the cursor's line. - * {{ This must not move the cursor. }} - */ -clear_eol() -{ - if (mode_flags & M_SO) - so_exit(); - if (mode_flags & M_UL) - ul_exit(); - if (mode_flags & M_BO) - bo_exit(); - tputs(sc_eol_clear, 1, putchr); -} - -/* - * Begin "standout" (bold, underline, or whatever). - */ -so_enter() -{ - tputs(sc_s_in, 1, putchr); - mode_flags |= M_SO; -} - -/* - * End "standout". - */ -so_exit() -{ - tputs(sc_s_out, 1, putchr); - mode_flags &= ~M_SO; -} - -/* - * Begin "underline" (hopefully real underlining, - * otherwise whatever the terminal provides). - */ -ul_enter() -{ - tputs(sc_u_in, 1, putchr); - mode_flags |= M_UL; -} - -/* - * End "underline". - */ -ul_exit() -{ - tputs(sc_u_out, 1, putchr); - mode_flags &= ~M_UL; -} - -/* - * Begin "bold" - */ -bo_enter() -{ - tputs(sc_b_in, 1, putchr); - mode_flags |= M_BO; -} - -/* - * End "bold". - */ -bo_exit() -{ - tputs(sc_b_out, 1, putchr); - mode_flags &= ~M_BO; -} - -/* - * Erase the character to the left of the cursor - * and move the cursor left. - */ -backspace() -{ - /* - * Try to erase the previous character by overstriking with a space. - */ - tputs(sc_backspace, 1, putchr); - putchr(' '); - tputs(sc_backspace, 1, putchr); -} - -/* - * Output a plain backspace, without erasing the previous char. - */ -putbs() -{ - tputs(sc_backspace, 1, putchr); -} diff --git a/usr.bin/more/signal.c b/usr.bin/more/signal.c deleted file mode 100644 index c8be3af..0000000 --- a/usr.bin/more/signal.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) 1988 Mark Nudleman - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char sccsid[] = "@(#)signal.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ - -/* - * Routines dealing with signals. - * - * A signal usually merely causes a bit to be set in the "signals" word. - * At some convenient time, the mainline code checks to see if any - * signals need processing by calling psignal(). - * If we happen to be reading from a file [in iread()] at the time - * the signal is received, we call intread to interrupt the iread. - */ - -#include <less.h> -#include <signal.h> - -/* - * "sigs" contains bits indicating signals which need to be processed. - */ -int sigs; - -#ifdef SIGTSTP -#define S_STOP 02 -#endif -#if defined(SIGWINCH) || defined(SIGWIND) -#define S_WINCH 04 -#endif - -extern int sc_width, sc_height; -extern int screen_trashed; -extern int lnloop; -extern int linenums; -extern volatile int reading; - -#ifdef SIGTSTP -/* - * "Stop" (^Z) signal handler. - */ -static void -stop() -{ - (void)signal(SIGTSTP, stop); - sigs |= S_STOP; - if (reading) - intread(); -} -#endif - -#ifdef SIGWINCH -/* - * "Window" change handler - */ -void -winch() -{ - (void)signal(SIGWINCH, winch); - sigs |= S_WINCH; - if (reading) - intread(); -} -#else -#ifdef SIGWIND -/* - * "Window" change handler - */ -winch() -{ - (void)signal(SIGWIND, winch); - sigs |= S_WINCH; - if (reading) - intread(); -} -#endif -#endif - -static void -purgeandquit() -{ - - purge(); /* purge buffered output */ - quit(); -} - -/* - * Set up the signal handlers. - */ -init_signals(on) - int on; -{ - if (on) - { - /* - * Set signal handlers. - */ - (void)signal(SIGINT, purgeandquit); -#ifdef SIGTSTP - (void)signal(SIGTSTP, stop); -#endif -#ifdef SIGWINCH - (void)signal(SIGWINCH, winch); -#else -#ifdef SIGWIND - (void)signal(SIGWIND, winch); -#endif -#endif - } else - { - /* - * Restore signals to defaults. - */ - (void)signal(SIGINT, SIG_DFL); -#ifdef SIGTSTP - (void)signal(SIGTSTP, SIG_DFL); -#endif -#ifdef SIGWINCH - (void)signal(SIGWINCH, SIG_IGN); -#endif -#ifdef SIGWIND - (void)signal(SIGWIND, SIG_IGN); -#endif - } -} - -/* - * Process any signals we have received. - * A received signal cause a bit to be set in "sigs". - */ -psignals() -{ - register int tsignals; - - if ((tsignals = sigs) == 0) - return; - sigs = 0; - -#ifdef S_WINCH - if (tsignals & S_WINCH) - { - int old_width, old_height; - /* - * Re-execute get_term() to read the new window size. - */ - old_width = sc_width; - old_height = sc_height; - get_term(); - if (sc_width != old_width || sc_height != old_height) - { - (void) setvari("_sc_width", (long) sc_width); - (void) setvari("_sc_height", (long) sc_height - 1); - screen_trashed = 1; - } - } -#endif -#ifdef SIGTSTP - if (tsignals & S_STOP) - { - /* - * Clean up the terminal. - */ -#ifdef SIGTTOU - (void)signal(SIGTTOU, SIG_IGN); -#endif - lower_left(); - clear_eol(); - deinit(); - (void)flush(); - raw_mode(0); -#ifdef SIGTTOU - (void)signal(SIGTTOU, SIG_DFL); -#endif - (void)signal(SIGTSTP, SIG_DFL); - (void)kill(getpid(), SIGTSTP); - /* - * ... Bye bye. ... - * Hopefully we'll be back later and resume here... - * Reset the terminal and arrange to repaint the - * screen when we get back to the main command loop. - */ - if (sigs & S_STOP) sigs &= ~(S_STOP); - (void)signal(SIGTSTP, stop); - raw_mode(1); - init(); - screen_trashed = 1; - } -#endif -} diff --git a/usr.bin/more/tags.c b/usr.bin/more/tags.c deleted file mode 100644 index 4a082e4..0000000 --- a/usr.bin/more/tags.c +++ /dev/null @@ -1,595 +0,0 @@ -/* - * Copyright (c) 1988 Mark Nudleman - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char sccsid[] = "@(#)tags.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ - -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include <sys/types.h> -#include <sys/queue.h> - -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "less.h" - -#define WHITESP(c) ((c)==' ' || (c)=='\t') - -extern int sigs; -char *tagfile; /* Name of source file containing current tag */ - -static enum { CTAGS, GTAGS } tagstyle = GTAGS; -static char *findctag(), *findgtag(), *nextgtag(), *prevgtag(); -static ctagsearch(), gtagsearch(); - -/* - * Load information about the tag. The global variable tagfile will point to - * the file that contains the tag, or will be NULL if information could not be - * found (in which case an error message will have been printed). After - * loading the file named by tagfile, tagsearch() should be called to - * set the current position to the tag. - */ -findtag(tag) - char *tag; /* The tag to load */ -{ - /* - * Try using gtags or ctags first, as indicated by tagstyle. If - * that fails, try the other. Someday there may even be a way to - * assert a certain tagstyle... - */ - switch(tagstyle) { - case CTAGS: - tagfile = findctag(tag); - if (!tagfile && (tagfile = findgtag(tag))) tagstyle = GTAGS; - if (tagfile) return; - break; - case GTAGS: - /* Would be nice to print the number of tag references - * we found (for nexttag() and prevtag()) in a (not-)error() - * message. */ - tagfile = findgtag(tag); - if (!tagfile && (tagfile = findctag(tag))) tagstyle = CTAGS; - if (tagfile) return; - break; - } - - error("could not find relevent tag information"); -} - -/* - * Load information about the next number'th tag, if the last findtag() call - * found multiple tag references. The global variable tagfile will point to the - * file that contains the tag, or will be NULL if information could not be - * found (in which case an error message will have been printed). After - * loading the file named by tagfile, tagsearch() should be called to set - * the current position to the tag. - */ -nexttag(number) - int number; /* How many tags to go forward by */ -{ - if (number < 0) number = -number; /* positive only, please */ - - switch(tagstyle) { - case CTAGS: - break; - case GTAGS: - while (number--) tagfile = nextgtag(); - break; - } - if (!tagfile) - error("no next tag"); -} - -/* - * The antithesis to nexttag(). - */ -prevtag(number) - int number; /* How many tags to go backwards by */ -{ - if (number < 0) number = -number; /* positive only, please */ - - switch(tagstyle) { - case CTAGS: - break; - case GTAGS: - while (number--) tagfile = prevgtag(); - break; - } - if (!tagfile) - error("no previous tag"); -} - -/* - * Try and position the currently loaded file at the last tag that was - * succesfully passed to findtag() or chosen with nexttag() and prevtag(). - * An error message will be printed if unsuccessful. - */ -tagsearch() -{ - switch(tagstyle) { - case CTAGS: - if (ctagsearch()) - error("could not locate ctag"); - return; - case GTAGS: - if (gtagsearch()) - error("could not locate gtag"); - return; - } -} - - -/******************************************************************************* - * - * ctags - * - */ - -extern int linenums; -extern char *line; - -static char *ctagpattern; -static int ctagflags; - -/* ctag flags */ -#define START_OF_LINE 0x01 -#define END_OF_LINE 0x02 - -/* - * Find specified tag in the ctags(1)-format tag file ctagfile. Returns - * pointer to a static buffer holding the name of the file containing - * the tag. Returns NULL on failure. The next call to ctagsearch() will - * position the currently loaded file at the tag. - */ -static char * -findctag(tag) - register char *tag; /* tag to search for */ -{ - register char *p; - register FILE *f; - register int taglen; - int search_char; - static char tline[200]; /* XXX should be dynamic */ - const char *ctagfile = "tags"; - char *retr; - - if ((f = fopen(ctagfile, "r")) == NULL) - return (NULL); - - taglen = strlen(tag); - - /* - * Search the tags file for the desired tag. - */ - while (fgets(tline, sizeof(tline), f) != NULL) - { - if (sigs) - break; /* abandon */ - - if (strncmp(tag, tline, taglen) != 0 || !WHITESP(tline[taglen])) - continue; - - /* - * Found it. - * The line contains the tag, the filename and the - * pattern, separated by white space. - * The pattern is surrounded by a pair of identical - * search characters. - * Parse the line and extract these parts. - */ - - /* - * Skip over the tag and the whitespace after the tag name. - */ - for (p = tline; !WHITESP(*p) && *p != '\0'; p++) - continue; - while (WHITESP(*p)) - p++; - if (*p == '\0') - /* File name is missing! */ - continue; - - /* - * Save the file name. - * Skip over the filename and whitespace after the file name. - */ - retr = p; - while (!WHITESP(*p) && *p != '\0') - p++; - *p++ = '\0'; - while (WHITESP(*p)) - p++; - if (*p == '\0') - /* Pattern is missing! */ - continue; - - /* - * Save the pattern. - * Skip to the end of the pattern. - * Delete the initial "^" and the final "$" from the pattern. - */ - search_char = *p++; - if (*p == '^') { - p++; - ctagflags |= START_OF_LINE; - } else { - ctagflags &= ~START_OF_LINE; - } - ctagpattern = p; /* cock ctagsearch() */ - while (*p != search_char && *p != '\0') - p++; - if (p[-1] == '\n') - p--; - if (p[-1] == '$') { - p--; - ctagflags |= END_OF_LINE; - } else { - ctagflags &= ~END_OF_LINE; - } - *p = '\0'; - - (void)fclose(f); - return (retr); - } - (void)fclose(f); - return (NULL); -} - -/* - * Locate the tag that was loaded by findctag(). - * This is a stripped-down version of search(). - * We don't use search() for several reasons: - * - We don't want to blow away any search string we may have saved. - * - The various regular-expression functions (from different systems: - * regcmp vs. re_comp) behave differently in the presence of - * parentheses (which are almost always found in a tag). - * - * Returns -1 if it was unable to position at the requested pattern, - * 0 otherwise. - */ -static -ctagsearch() -{ - off_t pos, linepos, forw_raw_line(); - int linenum; - - pos = (off_t)0; - linenum = find_linenum(pos); - - for (;;) - { - /* - * Get lines until we find a matching one or - * until we hit end-of-file. - */ - if (sigs) - return (-1); - - /* - * Read the next line, and save the - * starting position of that line in linepos. - */ - linepos = pos; - pos = forw_raw_line(pos); - if (linenum != 0) - linenum++; - - if (pos == NULL_POSITION) - return (-1); /* Tag not found. */ - - /* - * If we're using line numbers, we might as well - * remember the information we have now (the position - * and line number of the current line). - */ - if (linenums) - add_lnum(linenum, pos); - - /* - * Test the line to see if we have a match. I don't know of - * any tags program that would use START_OF_LINE but not - * END_OF_LINE, or vice-a-versa, but we handle this case anyway. - */ - switch (ctagflags) { - case 0: /* !START_OF_LINE and !END_OF_LINE */ - if (strstr(line, ctagpattern)) - goto found; - break; - case START_OF_LINE: /* !END_OF_LINE */ - if (!strncmp(ctagpattern, line, strlen(ctagpattern))) - goto found; - break; - case END_OF_LINE: /* !START_OF_LINE */ - { - char *x = strstr(line, ctagpattern); - if (!x) - break; - if (x[strlen(ctagpattern)] != '\0') - break; - goto found; - } - case START_OF_LINE | END_OF_LINE: - if (!strcmp(ctagpattern, line)) - goto found; - break; - } - } - -found: - jump_loc(linepos); - return (0); -} - - -/******************************************************************************* - * - * gtags - * - */ - -/* - * The findgtag() and getentry() functions are stolen, more or less, from the - * patches to nvi-1.79 included in Shigio Yamaguchi's global-3.42 distribution. - */ - -/* - * The queue of tags generated by the last findgtag() call. - */ -static CIRCLEQ_HEAD(gtag_q, gtag) gtag_q; -struct gtag { - CIRCLEQ_ENTRY(gtag) ptrs; - char *file; /* source file containing the tag */ - int line; /* appropriate line number of source file */ -}; -static struct gtag *curgtag; -static getentry(); - -/* - * The findgtag() will try and load information about the requested tag. - * It does this by calling "global -x tag; global -xr tag;" and storing the - * parsed output for future use by gtagsearch_f() and gtagsearch_b(). A - * pointer to a static buffer containing the name of the source file will - * be returned, or NULL on failure. The first filename printed by global is - * returned (hopefully the function definition) and the other filenames may - * be accessed by nextgtag() and prevgtag(). - */ -static char * -findgtag(tag) - char *tag; /* tag to load */ -{ - struct gtag *gtag_p1, *gtag_p2; - char command[512]; - char buf[256]; - FILE *fp; - - if (!tag) return (NULL); /* Sanity check */ - - /* Clear any existing tag circle queue */ - /* XXX Ideally, we wouldn't do this until after we know that we - * can load some other tag information. */ - curgtag = NULL; - gtag_p1 = gtag_q.cqh_first; - if (gtag_p1) while (gtag_p1 != (void *)>ag_q) { - gtag_p2 = gtag_p1->ptrs.cqe_next; - free(gtag_p1); - gtag_p1 = gtag_p2; - } - - /* Allocate and initialize the tag queue structure. */ - CIRCLEQ_INIT(>ag_q); - - /* Get our data from global(1) */ - snprintf(command, sizeof(command), - "(global -x '%s'; global -xr '%s') 2>/dev/null", tag, tag); - if (fp = popen(command, "r")) { - while (fgets(buf, sizeof(buf), fp)) { - char *name, *file, *line; - - if (sigs) { - pclose(fp); - return (NULL); - } - - /* chop(buf) */ - if (buf[strlen(buf) - 1] == '\n') - buf[strlen(buf) - 1] = 0; - else - while (fgetc(fp) != '\n') - ; - - if (getentry(buf, &name, &file, &line)) { - /* - * Couldn't parse this line for some reason. - * We'll just pretend it never happened. - */ - break; - } - - /* Add to queue */ - gtag_p1 = malloc(sizeof(struct gtag)); - if (!gtag_p1) { - pclose(fp); - error("malloc() failed"); - return (NULL); - } - gtag_p1->file = malloc(strlen(file) + 1); - if (!gtag_p1->file) { - pclose(fp); - error("malloc() failed"); - return (NULL); - } - strcpy(gtag_p1->file, file); - gtag_p1->line = atoi(line); - CIRCLEQ_INSERT_TAIL(>ag_q, gtag_p1, ptrs); - } - pclose(fp); - } - - /* Check to see if we found anything. */ - if (gtag_q.cqh_first == (void *)>ag_q) - return (NULL); /* Nope! */ - - curgtag = gtag_q.cqh_first; - return (curgtag->file); -} - -/* - * Return the filename required for the next gtag in the queue that was setup - * by findgtag(). The next call to gtagsearch() will try to position at the - * appropriate tag. - */ -static char * -nextgtag() -{ - if (!curgtag) { - /* No tag stack loaded */ - return (NULL); - } - - curgtag = curgtag->ptrs.cqe_next; - if (curgtag == (void *)>ag_q) { - /* Wrapped around to the head of the queue */ - curgtag = ((struct gtag_q *)curgtag)->cqh_first; - } - - return (curgtag->file); -} - -/* - * Return the filename required for the previous gtag in the queue that was - * setup by findgtat(). The next call to gtagsearch() will try to position - * at the appropriate tag. - */ -static char * -prevgtag() -{ - if (!curgtag) { - /* No tag stack loaded */ - return (NULL); - } - - curgtag = curgtag->ptrs.cqe_prev; - if (curgtag == (void *)>ag_q) { - /* Wrapped around to the head of the queue */ - curgtag = ((struct gtag_q *)curgtag)->cqh_last; - } - - return (curgtag->file); -} - -/* - * Position the current file at at what is hopefully the tag that was chosen - * using either findtag() or one of nextgtag() and prevgtag(). Returns -1 - * if it was unable to position at the tag, 0 if succesful. - */ -static -gtagsearch() -{ - if (!curgtag) - return (-1); /* No gtags loaded! */ - - jump_back(curgtag->line); - - /* - * XXX We'll assume we were successful --- jump_back() will call error() - * if it fails, so the user will receive some kind of notification. - * Eventually, jump_back() should do its work silently and let us - * perform the error notification, eventually allowing our caller - * (presumably tagsearch()) to go error("Could not locate tag."); - */ - return (0); -} - -/* - * The getentry() parses output from the global(1) command. The output - * must be in the format described below. Returns 0 on success, -1 on - * error. The tag, file, and line will each be NUL-terminated pointers - * into buf. - * - * gtags temporary file format. - * <tag> <lineno> <file> <image> - * - * sample. - * +------------------------------------------------ - * |main 30 main.c main(argc, argv) - * |func 21 subr.c func(arg) - */ -static -getentry(buf, tag, file, line) - char *buf; /* output from global -x */ - char **tag; /* name of the tag we actually found */ - char **file; /* file in which to find this tag */ - char **line; /* line number of file where this tag is found */ -{ - char *p = buf; - - for (*tag = p; *p && !isspace(*p); p++) /* tag name */ - ; - if (*p == 0) - goto err; - *p++ = 0; - for (; *p && isspace(*p); p++) /* (skip blanks) */ - ; - if (*p == 0) - goto err; - *line = p; /* line no */ - for (*line = p; *p && !isspace(*p); p++) - ; - if (*p == 0) - goto err; - *p++ = 0; - for (; *p && isspace(*p); p++) /* (skip blanks) */ - ; - if (*p == 0) - goto err; - *file = p; /* file name */ - for (*file = p; *p && !isspace(*p); p++) - ; - if (*p == 0) - goto err; - *p = 0; - - /* value check */ - if (strlen(*tag) && strlen(*line) && strlen(*file) && atoi(*line) > 0) - return (0); /* OK */ -err: - return (-1); /* ERROR */ -} diff --git a/usr.bin/more/ttyin.c b/usr.bin/more/ttyin.c deleted file mode 100644 index 26f8f96..0000000 --- a/usr.bin/more/ttyin.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 1988 Mark Nudleman - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char sccsid[] = "@(#)ttyin.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ - -/* - * Routines dealing with getting input from the keyboard (i.e. from the user). - */ - -#include <less.h> - -static int tty; - -/* - * Open keyboard for input. - * (Just use file descriptor 2.) - */ -open_getchr() -{ - tty = 2; -} - -/* - * Get a character from the keyboard. - */ -getchr() -{ - char c; - int result; - - do - { - result = iread(tty, &c, 1); - if (result == READ_INTR) - return (READ_INTR); - if (result < 0) - { - /* - * Don't call error() here, - * because error calls getchr! - */ - quit(); - } - } while (result != 1 || c == 0); - return ((unsigned char)c); -} |