diff --git a/Makefile b/Makefile index 45efc3b3f..6d18ce053 100644 --- a/Makefile +++ b/Makefile @@ -226,6 +226,7 @@ include third_party/mbedtls/BUILD.mk # │ include third_party/ncurses/BUILD.mk # │ include third_party/libcxx/BUILD.mk # │ include third_party/pcre/BUILD.mk # │ +include third_party/less/BUILD.mk # │ include net/https/BUILD.mk # │ include third_party/regex/BUILD.mk #─┘ include third_party/tidy/BUILD.mk diff --git a/third_party/BUILD.mk b/third_party/BUILD.mk index 95d481df7..eed3b36bf 100644 --- a/third_party/BUILD.mk +++ b/third_party/BUILD.mk @@ -14,6 +14,7 @@ o/$(MODE)/third_party: \ o/$(MODE)/third_party/gdtoa \ o/$(MODE)/third_party/getopt \ o/$(MODE)/third_party/hiredis \ + o/$(MODE)/third_party/less \ o/$(MODE)/third_party/libcxx \ o/$(MODE)/third_party/linenoise \ o/$(MODE)/third_party/lua \ diff --git a/third_party/less/BUILD.mk b/third_party/less/BUILD.mk new file mode 100644 index 000000000..b2663447b --- /dev/null +++ b/third_party/less/BUILD.mk @@ -0,0 +1,86 @@ +#-*-mode:lessfile-gless;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=less ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += THIRD_PARTY_LESS + +THIRD_PARTY_LESS_A = o/$(MODE)/third_party/less/less.a +THIRD_PARTY_LESS_FILES := $(wildcard third_party/less/*) +THIRD_PARTY_LESS_HDRS = $(filter %.h,$(THIRD_PARTY_LESS_FILES)) +THIRD_PARTY_LESS_INCS = $(filter %.inc,$(THIRD_PARTY_LESS_FILES)) +THIRD_PARTY_LESS_SRCS = $(filter %.c,$(THIRD_PARTY_LESS_FILES)) +THIRD_PARTY_LESS_OBJS = $(THIRD_PARTY_LESS_SRCS:%.c=o/$(MODE)/%.o) +THIRD_PARTY_LESS_COMS = o/$(MODE)/third_party/less/less.com +THIRD_PARTY_LESS_CHECKS = $(THIRD_PARTY_LESS_A).pkg + +THIRD_PARTY_LESS_BINS = \ + $(THIRD_PARTY_LESS_COMS) \ + $(THIRD_PARTY_LESS_COMS:%=%.dbg) + +THIRD_PARTY_LESS_DIRECTDEPS = \ + LIBC_CALLS \ + LIBC_FMT \ + LIBC_INTRIN \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_PROC \ + LIBC_RUNTIME \ + LIBC_STDIO \ + LIBC_STR \ + LIBC_SYSV \ + THIRD_PARTY_NCURSES \ + THIRD_PARTY_PCRE + +THIRD_PARTY_LESS_DEPS := \ + $(call uniq,$(foreach x,$(THIRD_PARTY_LESS_DIRECTDEPS),$($(x)))) + +$(THIRD_PARTY_LESS_A).pkg: \ + $(THIRD_PARTY_LESS_OBJS) \ + $(foreach x,$(THIRD_PARTY_LESS_DIRECTDEPS),$($(x)_A).pkg) + +$(THIRD_PARTY_LESS_A): \ + third_party/less/ \ + $(THIRD_PARTY_LESS_A).pkg \ + $(filter-out %main.o,$(THIRD_PARTY_LESS_OBJS)) + +o/$(MODE)/third_party/less/less.com.dbg: \ + $(THIRD_PARTY_LESS_DEPS) \ + $(THIRD_PARTY_LESS_A) \ + $(THIRD_PARTY_LESS_A).pkg \ + o/$(MODE)/third_party/less/main.o \ + $(CRT) \ + $(APE_NO_MODIFY_SELF) + @$(APELINK) + +o/$(MODE)/third_party/less/lesskey.com.dbg: \ + $(THIRD_PARTY_LESS_DEPS) \ + $(THIRD_PARTY_LESS_A) \ + $(THIRD_PARTY_LESS_A).pkg \ + o/$(MODE)/third_party/less/lesskey.o \ + $(CRT) \ + $(APE_NO_MODIFY_SELF) + @$(APELINK) + +o/$(MODE)/third_party/less/lessecho.com.dbg: \ + $(THIRD_PARTY_LESS_DEPS) \ + $(THIRD_PARTY_LESS_A) \ + $(THIRD_PARTY_LESS_A).pkg \ + o/$(MODE)/third_party/less/lessecho.o \ + $(CRT) \ + $(APE_NO_MODIFY_SELF) + @$(APELINK) + +o/$(MODE)/third_party/less/screen.o: private \ + CFLAGS += \ + -fportcosmo + +$(THIRD_PARTY_LESS_OBJS): private \ + CPPFLAGS += \ + -DBINDIR=\"/opt/cosmos/bin\" \ + -DSYSDIR=\"/opt/cosmos/etc\" + +$(THIRD_PARTY_LESS_OBJS): third_party/less/BUILD.mk + +.PHONY: o/$(MODE)/third_party/less +o/$(MODE)/third_party/less: \ + $(THIRD_PARTY_LESS_BINS) \ + $(THIRD_PARTY_LESS_CHECKS) diff --git a/third_party/less/LICENSE b/third_party/less/LICENSE new file mode 100644 index 000000000..d22cc6070 --- /dev/null +++ b/third_party/less/LICENSE @@ -0,0 +1,27 @@ + Less License + ------------ + +Less +Copyright (C) 1984-2023 Mark Nudelman + +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 in the documentation and/or other materials provided with + the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. + diff --git a/third_party/less/README.cosmo b/third_party/less/README.cosmo new file mode 100644 index 000000000..6bd18dfbc --- /dev/null +++ b/third_party/less/README.cosmo @@ -0,0 +1,15 @@ +DESCRIPTION + + less is a text paginator for the terminal + +LICENSE + + BSD-2 license + +ORIGIN + + https://ftp.gnu.org/gnu/less/less-643.tar.gz + +LOCAL CHANGES + + None. diff --git a/third_party/less/brac.c b/third_party/less/brac.c new file mode 100644 index 000000000..da4efab86 --- /dev/null +++ b/third_party/less/brac.c @@ -0,0 +1,99 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * Routines to perform bracket matching functions. + */ + +#include "less.h" +#include "position.h" + +/* + * Try to match the n-th open bracket + * which appears in the top displayed line (forwdir), + * or the n-th close bracket + * which appears in the bottom displayed line (!forwdir). + * The characters which serve as "open bracket" and + * "close bracket" are given. + */ +public void match_brac(char obrac, char cbrac, int forwdir, int n) +{ + int c; + int nest; + POSITION pos; + int (*chget)(); + + extern int ch_forw_get(), ch_back_get(); + + /* + * Seek to the line containing the open bracket. + * This is either the top or bottom line on the screen, + * depending on the type of bracket. + */ + pos = position((forwdir) ? TOP : BOTTOM); + if (pos == NULL_POSITION || ch_seek(pos)) + { + if (forwdir) + error("Nothing in top line", NULL_PARG); + else + error("Nothing in bottom line", NULL_PARG); + return; + } + + /* + * Look thru the line to find the open bracket to match. + */ + do + { + if ((c = ch_forw_get()) == '\n' || c == EOI) + { + if (forwdir) + error("No bracket in top line", NULL_PARG); + else + error("No bracket in bottom line", NULL_PARG); + return; + } + } while (c != obrac || --n > 0); + + /* + * Position the file just "after" the open bracket + * (in the direction in which we will be searching). + * If searching forward, we are already after the bracket. + * If searching backward, skip back over the open bracket. + */ + if (!forwdir) + (void) ch_back_get(); + + /* + * Search the file for the matching bracket. + */ + chget = (forwdir) ? ch_forw_get : ch_back_get; + nest = 0; + while ((c = (*chget)()) != EOI) + { + if (c == obrac) + { + if (nest == INT_MAX) + break; + nest++; + } + else if (c == cbrac && --nest < 0) + { + /* + * Found the matching bracket. + * If searching backward, put it on the top line. + * If searching forward, put it on the bottom line. + */ + jump_line_loc(ch_tell(), forwdir ? -1 : 1); + return; + } + } + error("No matching bracket", NULL_PARG); +} diff --git a/third_party/less/ch.c b/third_party/less/ch.c new file mode 100644 index 000000000..abf3d6f5a --- /dev/null +++ b/third_party/less/ch.c @@ -0,0 +1,939 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * 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 "less.h" +#if MSDOS_COMPILER==WIN32C +#include +/* #include */ +#endif + +#if HAVE_PROCFS +#include +#if HAVE_LINUX_MAGIC_H +#include +#endif +#endif + +typedef POSITION BLOCKNUM; + +public int ignore_eoi; + +/* + * Pool of buffers holding the most recently used blocks of the input file. + * The buffer pool is kept as a doubly-linked circular list, + * in order from most- to least-recently used. + * The circular list is anchored by the file state "thisfile". + */ +struct bufnode { + struct bufnode *next, *prev; + struct bufnode *hnext, *hprev; +}; + +#define LBUFSIZE 8192 +struct buf { + struct bufnode node; + BLOCKNUM block; + unsigned int datasize; + unsigned char data[LBUFSIZE]; +}; +#define bufnode_buf(bn) ((struct buf *) bn) + +/* + * The file state is maintained in a filestate structure. + * A pointer to the filestate is kept in the ifile structure. + */ +#define BUFHASH_SIZE 1024 +struct filestate { + struct bufnode buflist; + struct bufnode hashtbl[BUFHASH_SIZE]; + int file; + int flags; + POSITION fpos; + int nbufs; + BLOCKNUM block; + unsigned int offset; + POSITION fsize; +}; + +#define ch_bufhead thisfile->buflist.next +#define ch_buftail thisfile->buflist.prev +#define ch_nbufs thisfile->nbufs +#define ch_block thisfile->block +#define ch_offset thisfile->offset +#define ch_fpos thisfile->fpos +#define ch_fsize thisfile->fsize +#define ch_flags thisfile->flags +#define ch_file thisfile->file + +#define END_OF_CHAIN (&thisfile->buflist) +#define END_OF_HCHAIN(h) (&thisfile->hashtbl[h]) +#define BUFHASH(blk) ((blk) & (BUFHASH_SIZE-1)) + +/* + * Macros to manipulate the list of buffers in thisfile->buflist. + */ +#define FOR_BUFS(bn) \ + for (bn = ch_bufhead; bn != END_OF_CHAIN; bn = bn->next) + +#define BUF_RM(bn) \ + (bn)->next->prev = (bn)->prev; \ + (bn)->prev->next = (bn)->next; + +#define BUF_INS_HEAD(bn) \ + (bn)->next = ch_bufhead; \ + (bn)->prev = END_OF_CHAIN; \ + ch_bufhead->prev = (bn); \ + ch_bufhead = (bn); + +#define BUF_INS_TAIL(bn) \ + (bn)->next = END_OF_CHAIN; \ + (bn)->prev = ch_buftail; \ + ch_buftail->next = (bn); \ + ch_buftail = (bn); + +/* + * Macros to manipulate the list of buffers in thisfile->hashtbl[n]. + */ +#define FOR_BUFS_IN_CHAIN(h,bn) \ + for (bn = thisfile->hashtbl[h].hnext; \ + bn != END_OF_HCHAIN(h); bn = bn->hnext) + +#define BUF_HASH_RM(bn) \ + (bn)->hnext->hprev = (bn)->hprev; \ + (bn)->hprev->hnext = (bn)->hnext; + +#define BUF_HASH_INS(bn,h) \ + (bn)->hnext = thisfile->hashtbl[h].hnext; \ + (bn)->hprev = END_OF_HCHAIN(h); \ + thisfile->hashtbl[h].hnext->hprev = (bn); \ + thisfile->hashtbl[h].hnext = (bn); + +static struct filestate *thisfile; +static int ch_ungotchar = -1; +static int maxbufs = -1; + +extern int autobuf; +extern int sigs; +extern int secure; +extern int screen_trashed; +extern int follow_mode; +extern int waiting_for_data; +extern constant char helpdata[]; +extern constant int size_helpdata; +extern IFILE curr_ifile; +#if LOGFILE +extern int logfile; +extern char *namelogfile; +#endif + +static int ch_addbuf(); + + +/* + * Get the character pointed to by the read pointer. + */ +static int ch_get(void) +{ + struct buf *bp; + struct bufnode *bn; + int n; + int read_again; + int h; + POSITION pos; + POSITION len; + + if (thisfile == NULL) + return (EOI); + + /* + * Quick check for the common case where + * the desired char is in the head buffer. + */ + if (ch_bufhead != END_OF_CHAIN) + { + bp = bufnode_buf(ch_bufhead); + if (ch_block == bp->block && ch_offset < bp->datasize) + return bp->data[ch_offset]; + } + + /* + * Look for a buffer holding the desired block. + */ + waiting_for_data = FALSE; + h = BUFHASH(ch_block); + FOR_BUFS_IN_CHAIN(h, bn) + { + bp = bufnode_buf(bn); + if (bp->block == ch_block) + { + if (ch_offset >= bp->datasize) + /* + * Need more data in this buffer. + */ + break; + goto found; + } + } + if (bn == END_OF_HCHAIN(h)) + { + /* + * Block is not in a buffer. + * Take the least recently used buffer + * and read the desired block into it. + * If the LRU buffer has data in it, + * then maybe allocate a new buffer. + */ + if (ch_buftail == END_OF_CHAIN || + bufnode_buf(ch_buftail)->block != -1) + { + /* + * There is no empty buffer to use. + * Allocate a new buffer if: + * 1. We can't seek on this file and -b is not in effect; or + * 2. We haven't allocated the max buffers for this file yet. + */ + if ((autobuf && !(ch_flags & CH_CANSEEK)) || + (maxbufs < 0 || ch_nbufs < maxbufs)) + if (ch_addbuf()) + /* + * Allocation failed: turn off autobuf. + */ + autobuf = OPT_OFF; + } + bn = ch_buftail; + bp = bufnode_buf(bn); + BUF_HASH_RM(bn); /* Remove from old hash chain. */ + bp->block = ch_block; + bp->datasize = 0; + BUF_HASH_INS(bn, h); /* Insert into new hash chain. */ + } + + for (;;) + { + pos = (ch_block * LBUFSIZE) + bp->datasize; + if ((len = ch_length()) != NULL_POSITION && pos >= len) + /* + * At end of file. + */ + return (EOI); + + if (pos != ch_fpos) + { + /* + * Not at the correct position: must seek. + * If input is a pipe, we're in trouble (can't seek on a pipe). + * Some data has been lost: just return "?". + */ + if (!(ch_flags & CH_CANSEEK)) + return ('?'); + if (lseek(ch_file, (off_t)pos, SEEK_SET) == BAD_LSEEK) + { + error("seek error", NULL_PARG); + clear_eol(); + return (EOI); + } + ch_fpos = pos; + } + + /* + * Read the block. + * If we read less than a full block, that's ok. + * We use partial block and pick up the rest next time. + */ + if (ch_ungotchar != -1) + { + bp->data[bp->datasize] = ch_ungotchar; + n = 1; + ch_ungotchar = -1; + } else if (ch_flags & CH_HELPFILE) + { + bp->data[bp->datasize] = helpdata[ch_fpos]; + n = 1; + } else + { + n = iread(ch_file, &bp->data[bp->datasize], + (unsigned int)(LBUFSIZE - bp->datasize)); + } + + read_again = FALSE; + if (n == READ_INTR) + { + ch_fsize = pos; + return (EOI); + } + if (n == READ_AGAIN) + { + read_again = TRUE; + n = 0; + } + if (n < 0) + { +#if MSDOS_COMPILER==WIN32C + if (errno != EPIPE) +#endif + { + error("read error", NULL_PARG); + clear_eol(); + } + n = 0; + } + +#if LOGFILE + /* + * If we have a log file, write the new data to it. + */ + if (!secure && logfile >= 0 && n > 0) + write(logfile, (char *) &bp->data[bp->datasize], n); +#endif + + ch_fpos += n; + bp->datasize += n; + + if (n == 0) + { + /* Either end of file or no data available. + * read_again indicates the latter. */ + if (!read_again) + ch_fsize = pos; + if (ignore_eoi || read_again) + { + /* Wait a while, then try again. */ + if (!waiting_for_data) + { + PARG parg; + parg.p_string = wait_message(); + ixerror("%s", &parg); + waiting_for_data = TRUE; + } + sleep_ms(50); /* Reduce system load */ + } + if (ignore_eoi && follow_mode == FOLLOW_NAME && curr_ifile_changed()) + { + /* screen_trashed=2 causes make_display to reopen the file. */ + screen_trashed = 2; + return (EOI); + } + if (sigs) + return (EOI); + } + + found: + if (ch_bufhead != bn) + { + /* + * Move the buffer to the head of the buffer chain. + * This orders the buffer chain, most- to least-recently used. + */ + BUF_RM(bn); + BUF_INS_HEAD(bn); + + /* + * Move to head of hash chain too. + */ + BUF_HASH_RM(bn); + BUF_HASH_INS(bn, h); + } + + if (ch_offset < bp->datasize) + break; + /* + * After all that, we still don't have enough data. + * Go back and try again. + */ + } + return (bp->data[ch_offset]); +} + +/* + * ch_ungetchar is a rather kludgy and limited way to push + * a single char onto an input file descriptor. + */ +public void ch_ungetchar(int c) +{ + if (c != -1 && ch_ungotchar != -1) + error("ch_ungetchar overrun", NULL_PARG); + ch_ungotchar = c; +} + +#if LOGFILE +/* + * Close the logfile. + * If we haven't read all of standard input into it, do that now. + */ +public void end_logfile(void) +{ + static int tried = FALSE; + + if (logfile < 0) + return; + if (!tried && ch_fsize == NULL_POSITION) + { + tried = TRUE; + ierror("Finishing logfile", NULL_PARG); + while (ch_forw_get() != EOI) + if (ABORT_SIGS()) + break; + } + close(logfile); + logfile = -1; + free(namelogfile); + namelogfile = NULL; +} + +/* + * Start a log file AFTER less has already been running. + * Invoked from the - command; see toggle_option(). + * Write all the existing buffered data to the log file. + */ +public void sync_logfile(void) +{ + struct buf *bp; + struct bufnode *bn; + int warned = FALSE; + BLOCKNUM block; + BLOCKNUM nblocks; + + if (logfile < 0) + return; + nblocks = (ch_fpos + LBUFSIZE - 1) / LBUFSIZE; + for (block = 0; block < nblocks; block++) + { + int wrote = FALSE; + FOR_BUFS(bn) + { + bp = bufnode_buf(bn); + if (bp->block == block) + { + write(logfile, (char *) bp->data, bp->datasize); + wrote = TRUE; + break; + } + } + if (!wrote && !warned) + { + error("Warning: log file is incomplete", + NULL_PARG); + warned = TRUE; + } + } +} + +#endif + +/* + * Determine if a specific block is currently in one of the buffers. + */ +static int buffered(BLOCKNUM block) +{ + struct buf *bp; + struct bufnode *bn; + int h; + + h = BUFHASH(block); + FOR_BUFS_IN_CHAIN(h, bn) + { + bp = bufnode_buf(bn); + if (bp->block == block) + return (TRUE); + } + return (FALSE); +} + +/* + * Seek to a specified position in the file. + * Return 0 if successful, non-zero if can't seek there. + */ +public int ch_seek(POSITION pos) +{ + BLOCKNUM new_block; + POSITION len; + + if (thisfile == NULL) + return (0); + + len = ch_length(); + if (pos < ch_zero() || (len != NULL_POSITION && pos > len)) + return (1); + + new_block = pos / LBUFSIZE; + if (!(ch_flags & CH_CANSEEK) && pos != ch_fpos && !buffered(new_block)) + { + if (ch_fpos > pos) + return (1); + while (ch_fpos < pos) + { + if (ch_forw_get() == EOI) + return (1); + if (ABORT_SIGS()) + return (1); + } + return (0); + } + /* + * Set read pointer. + */ + ch_block = new_block; + ch_offset = pos % LBUFSIZE; + return (0); +} + +/* + * Seek to the end of the file. + */ +public int ch_end_seek(void) +{ + POSITION len; + + if (thisfile == NULL) + return (0); + + if (ch_flags & CH_CANSEEK) + ch_fsize = filesize(ch_file); + + len = ch_length(); + if (len != NULL_POSITION) + return (ch_seek(len)); + + /* + * Do it the slow way: read till end of data. + */ + while (ch_forw_get() != EOI) + if (ABORT_SIGS()) + return (1); + return (0); +} + +/* + * Seek to the last position in the file that is currently buffered. + */ +public int ch_end_buffer_seek(void) +{ + struct buf *bp; + struct bufnode *bn; + POSITION buf_pos; + POSITION end_pos; + + if (thisfile == NULL || (ch_flags & CH_CANSEEK)) + return (ch_end_seek()); + + end_pos = 0; + FOR_BUFS(bn) + { + bp = bufnode_buf(bn); + buf_pos = (bp->block * LBUFSIZE) + bp->datasize; + if (buf_pos > end_pos) + end_pos = buf_pos; + } + + return (ch_seek(end_pos)); +} + +/* + * 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. + */ +public int ch_beg_seek(void) +{ + struct bufnode *bn; + struct bufnode *firstbn; + + /* + * Try a plain ch_seek first. + */ + if (ch_seek(ch_zero()) == 0) + return (0); + + /* + * Can't get to position 0. + * Look thru the buffers for the one closest to position 0. + */ + firstbn = ch_bufhead; + if (firstbn == END_OF_CHAIN) + return (1); + FOR_BUFS(bn) + { + if (bufnode_buf(bn)->block < bufnode_buf(firstbn)->block) + firstbn = bn; + } + ch_block = bufnode_buf(firstbn)->block; + ch_offset = 0; + return (0); +} + +/* + * Return the length of the file, if known. + */ +public POSITION ch_length(void) +{ + if (thisfile == NULL) + return (NULL_POSITION); + if (ignore_eoi) + return (NULL_POSITION); + if (ch_flags & CH_HELPFILE) + return (size_helpdata); + if (ch_flags & CH_NODATA) + return (0); + return (ch_fsize); +} + +/* + * Return the current position in the file. + */ +public POSITION ch_tell(void) +{ + if (thisfile == NULL) + return (NULL_POSITION); + return (ch_block * LBUFSIZE) + ch_offset; +} + +/* + * Get the current char and post-increment the read pointer. + */ +public int ch_forw_get(void) +{ + int c; + + if (thisfile == NULL) + return (EOI); + c = ch_get(); + if (c == EOI) + return (EOI); + if (ch_offset < LBUFSIZE-1) + ch_offset++; + else + { + ch_block ++; + ch_offset = 0; + } + return (c); +} + +/* + * Pre-decrement the read pointer and get the new current char. + */ +public int ch_back_get(void) +{ + if (thisfile == NULL) + return (EOI); + if (ch_offset > 0) + ch_offset --; + else + { + if (ch_block <= 0) + return (EOI); + if (!(ch_flags & CH_CANSEEK) && !buffered(ch_block-1)) + return (EOI); + ch_block--; + ch_offset = LBUFSIZE-1; + } + return (ch_get()); +} + +/* + * Set max amount of buffer space. + * bufspace is in units of 1024 bytes. -1 mean no limit. + */ +public void ch_setbufspace(int bufspace) +{ + if (bufspace < 0) + maxbufs = -1; + else + { + int lbufk = LBUFSIZE / 1024; + maxbufs = bufspace / lbufk + (bufspace % lbufk != 0); + if (maxbufs < 1) + maxbufs = 1; + } +} + +/* + * Flush (discard) any saved file state, including buffer contents. + */ +public void ch_flush(void) +{ + struct bufnode *bn; + + if (thisfile == NULL) + return; + + if (!(ch_flags & CH_CANSEEK)) + { + /* + * If input is a pipe, we don't flush buffer contents, + * since the contents can't be recovered. + */ + ch_fsize = NULL_POSITION; + return; + } + + /* + * Initialize all the buffers. + */ + FOR_BUFS(bn) + { + bufnode_buf(bn)->block = -1; + } + + /* + * Figure out the size of the file, if we can. + */ + ch_fsize = filesize(ch_file); + + /* + * Seek to a known position: the beginning of the file. + */ + ch_fpos = 0; + ch_block = 0; /* ch_fpos / LBUFSIZE; */ + ch_offset = 0; /* ch_fpos % LBUFSIZE; */ + +#if HAVE_PROCFS + /* + * This is a kludge to workaround a Linux kernel bug: files in + * /proc have a size of 0 according to fstat() but have readable + * data. They are sometimes, but not always, seekable. + * Force them to be non-seekable here. + */ + if (ch_fsize == 0) + { + struct statfs st; + if (fstatfs(ch_file, &st) == 0) + { + if (st.f_type == PROC_SUPER_MAGIC) + { + ch_fsize = NULL_POSITION; + ch_flags &= ~CH_CANSEEK; + } + } + } +#endif + + if (lseek(ch_file, (off_t)0, SEEK_SET) == BAD_LSEEK) + { + /* + * Warning only; even if the seek fails for some reason, + * there's a good chance we're at the beginning anyway. + * {{ I think this is bogus reasoning. }} + */ + error("seek error to 0", NULL_PARG); + } +} + +/* + * Allocate a new buffer. + * The buffer is added to the tail of the buffer chain. + */ +static int ch_addbuf(void) +{ + struct buf *bp; + struct bufnode *bn; + + /* + * Allocate and initialize a new buffer and link it + * onto the tail of the buffer list. + */ + bp = (struct buf *) calloc(1, sizeof(struct buf)); + if (bp == NULL) + return (1); + ch_nbufs++; + bp->block = -1; + bn = &bp->node; + + BUF_INS_TAIL(bn); + BUF_HASH_INS(bn, 0); + return (0); +} + +/* + * + */ +static void init_hashtbl(void) +{ + int h; + + for (h = 0; h < BUFHASH_SIZE; h++) + { + thisfile->hashtbl[h].hnext = END_OF_HCHAIN(h); + thisfile->hashtbl[h].hprev = END_OF_HCHAIN(h); + } +} + +/* + * Delete all buffers for this file. + */ +static void ch_delbufs(void) +{ + struct bufnode *bn; + + while (ch_bufhead != END_OF_CHAIN) + { + bn = ch_bufhead; + BUF_RM(bn); + free(bufnode_buf(bn)); + } + ch_nbufs = 0; + init_hashtbl(); +} + +/* + * Is it possible to seek on a file descriptor? + */ +public int seekable(int f) +{ +#if MSDOS_COMPILER + extern int fd0; + if (f == fd0 && !isatty(fd0)) + { + /* + * In MS-DOS, pipes are seekable. Check for + * standard input, and pretend it is not seekable. + */ + return (0); + } +#endif + return (lseek(f, (off_t)1, SEEK_SET) != BAD_LSEEK); +} + +/* + * Force EOF to be at the current read position. + * This is used after an ignore_eof read, during which the EOF may change. + */ +public void ch_set_eof(void) +{ + if (ch_fsize != NULL_POSITION && ch_fsize < ch_fpos) + ch_fsize = ch_fpos; +} + + +/* + * Initialize file state for a new file. + */ +public void ch_init(int f, int flags) +{ + /* + * See if we already have a filestate for this file. + */ + thisfile = (struct filestate *) get_filestate(curr_ifile); + if (thisfile == NULL) + { + /* + * Allocate and initialize a new filestate. + */ + thisfile = (struct filestate *) + ecalloc(1, sizeof(struct filestate)); + thisfile->buflist.next = thisfile->buflist.prev = END_OF_CHAIN; + thisfile->nbufs = 0; + thisfile->flags = flags; + thisfile->fpos = 0; + thisfile->block = 0; + thisfile->offset = 0; + thisfile->file = -1; + thisfile->fsize = NULL_POSITION; + init_hashtbl(); + /* + * Try to seek; set CH_CANSEEK if it works. + */ + if ((flags & CH_CANSEEK) && !seekable(f)) + ch_flags &= ~CH_CANSEEK; + set_filestate(curr_ifile, (void *) thisfile); + } + if (thisfile->file == -1) + thisfile->file = f; + ch_flush(); +} + +/* + * Close a filestate. + */ +public void ch_close(void) +{ + int keepstate = FALSE; + + if (thisfile == NULL) + return; + + if ((ch_flags & (CH_CANSEEK|CH_POPENED|CH_HELPFILE)) && !(ch_flags & CH_KEEPOPEN)) + { + /* + * We can seek or re-open, so we don't need to keep buffers. + */ + ch_delbufs(); + } else + keepstate = TRUE; + if (!(ch_flags & CH_KEEPOPEN)) + { + /* + * We don't need to keep the file descriptor open + * (because we can re-open it.) + * But don't really close it if it was opened via popen(), + * because pclose() wants to close it. + */ + if (!(ch_flags & (CH_POPENED|CH_HELPFILE))) + close(ch_file); + ch_file = -1; + } else + keepstate = TRUE; + if (!keepstate) + { + /* + * We don't even need to keep the filestate structure. + */ + free(thisfile); + thisfile = NULL; + set_filestate(curr_ifile, (void *) NULL); + } +} + +/* + * Return ch_flags for the current file. + */ +public int ch_getflags(void) +{ + if (thisfile == NULL) + return (0); + return (ch_flags); +} + +#if 0 +static void ch_dump(struct filestate *fs) +{ + struct buf *bp; + struct bufnode *bn; + unsigned char *s; + + if (fs == NULL) + { + printf(" --no filestate\n"); + return; + } + printf(" file %d, flags %x, fpos %x, fsize %x, blk/off %x/%x\n", + fs->file, fs->flags, fs->fpos, + fs->fsize, fs->block, fs->offset); + printf(" %d bufs:\n", fs->nbufs); + for (bn = fs->next; bn != &fs->buflist; bn = bn->next) + { + bp = bufnode_buf(bn); + printf("%x: blk %x, size %x \"", + bp, bp->block, bp->datasize); + for (s = bp->data; s < bp->data + 30; s++) + if (*s >= ' ' && *s < 0x7F) + printf("%c", *s); + else + printf("."); + printf("\"\n"); + } +} +#endif diff --git a/third_party/less/charset.c b/third_party/less/charset.c new file mode 100644 index 000000000..27a3c0a4c --- /dev/null +++ b/third_party/less/charset.c @@ -0,0 +1,905 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * Functions to define the character set + * and do things specific to the character set. + */ + +#include "less.h" +#if HAVE_LOCALE +#include +#include +#include +#endif + +#include "charset.h" +#include "xbuf.h" + +#if MSDOS_COMPILER==WIN32C +#define WIN32_LEAN_AND_MEAN +/* #include */ +#endif + +extern int bs_mode; + +public int utf_mode = 0; + +/* + * Predefined character sets, + * selected by the LESSCHARSET environment variable. + */ +struct charset { + char *name; + int *p_flag; + char *desc; +} charsets[] = { + { "ascii", NULL, "8bcccbcc18b95.b" }, + { "utf-8", &utf_mode, "8bcccbcc18b95.b126.bb" }, + { "iso8859", NULL, "8bcccbcc18b95.33b." }, + { "latin3", NULL, "8bcccbcc18b95.33b5.b8.b15.b4.b12.b18.b12.b." }, + { "arabic", NULL, "8bcccbcc18b95.33b.3b.7b2.13b.3b.b26.5b19.b" }, + { "greek", NULL, "8bcccbcc18b95.33b4.2b4.b3.b35.b44.b" }, + { "greek2005", NULL, "8bcccbcc18b95.33b14.b35.b44.b" }, + { "hebrew", NULL, "8bcccbcc18b95.33b.b29.32b28.2b2.b" }, + { "koi8-r", NULL, "8bcccbcc18b95.b." }, + { "KOI8-T", NULL, "8bcccbcc18b95.b8.b6.b8.b.b.5b7.3b4.b4.b3.b.b.3b." }, + { "georgianps", NULL, "8bcccbcc18b95.3b11.4b12.2b." }, + { "tcvn", NULL, "b..b...bcccbccbbb7.8b95.b48.5b." }, + { "TIS-620", NULL, "8bcccbcc18b95.b.4b.11b7.8b." }, + { "next", NULL, "8bcccbcc18b95.bb125.bb" }, + { "dos", NULL, "8bcccbcc12bc5b95.b." }, + { "windows-1251", NULL, "8bcccbcc12bc5b95.b24.b." }, + { "windows-1252", NULL, "8bcccbcc12bc5b95.b.b11.b.2b12.b." }, + { "windows-1255", NULL, "8bcccbcc12bc5b95.b.b8.b.5b9.b.4b." }, + { "ebcdic", NULL, "5bc6bcc7bcc41b.9b7.9b5.b..8b6.10b6.b9.7b9.8b8.17b3.3b9.7b9.8b8.6b10.b.b.b." }, + { "IBM-1047", NULL, "4cbcbc3b9cbccbccbb4c6bcc5b3cbbc4bc4bccbc191.b" }, + { NULL, NULL, NULL } +}; + +/* + * Support "locale charmap"/nl_langinfo(CODESET) values, as well as others. + */ +struct cs_alias { + char *name; + char *oname; +} cs_aliases[] = { + { "UTF-8", "utf-8" }, + { "utf8", "utf-8" }, + { "UTF8", "utf-8" }, + { "ANSI_X3.4-1968", "ascii" }, + { "US-ASCII", "ascii" }, + { "latin1", "iso8859" }, + { "ISO-8859-1", "iso8859" }, + { "latin9", "iso8859" }, + { "ISO-8859-15", "iso8859" }, + { "latin2", "iso8859" }, + { "ISO-8859-2", "iso8859" }, + { "ISO-8859-3", "latin3" }, + { "latin4", "iso8859" }, + { "ISO-8859-4", "iso8859" }, + { "cyrillic", "iso8859" }, + { "ISO-8859-5", "iso8859" }, + { "ISO-8859-6", "arabic" }, + { "ISO-8859-7", "greek" }, + { "IBM9005", "greek2005" }, + { "ISO-8859-8", "hebrew" }, + { "latin5", "iso8859" }, + { "ISO-8859-9", "iso8859" }, + { "latin6", "iso8859" }, + { "ISO-8859-10", "iso8859" }, + { "latin7", "iso8859" }, + { "ISO-8859-13", "iso8859" }, + { "latin8", "iso8859" }, + { "ISO-8859-14", "iso8859" }, + { "latin10", "iso8859" }, + { "ISO-8859-16", "iso8859" }, + { "IBM437", "dos" }, + { "EBCDIC-US", "ebcdic" }, + { "IBM1047", "IBM-1047" }, + { "KOI8-R", "koi8-r" }, + { "KOI8-U", "koi8-r" }, + { "GEORGIAN-PS", "georgianps" }, + { "TCVN5712-1", "tcvn" }, + { "NEXTSTEP", "next" }, + { "windows", "windows-1252" }, /* backward compatibility */ + { "CP1251", "windows-1251" }, + { "CP1252", "windows-1252" }, + { "CP1255", "windows-1255" }, + { NULL, NULL } +}; + +#define IS_BINARY_CHAR 01 +#define IS_CONTROL_CHAR 02 + +static char chardef[256]; +static char *binfmt = NULL; +static char *utfbinfmt = NULL; +public int binattr = AT_STANDOUT|AT_COLOR_BIN; + +static struct xbuffer user_wide_array; +static struct xbuffer user_ubin_array; +static struct xbuffer user_compose_array; +static struct xbuffer user_prt_array; +static struct wchar_range_table user_wide_table; +static struct wchar_range_table user_ubin_table; +static struct wchar_range_table user_compose_table; +static struct wchar_range_table user_prt_table; + +/* + * Set a wchar_range_table to the table in an xbuffer. + */ +static void wchar_range_table_set(struct wchar_range_table *tbl, struct xbuffer *arr) +{ + tbl->table = (struct wchar_range *) arr->data; + tbl->count = arr->end / sizeof(struct wchar_range); +} + +/* + * Skip over a "U" or "U+" prefix before a hex codepoint. + */ +static char * skip_uprefix(char *s) +{ + if (*s == 'U' || *s == 'u') + if (*++s == '+') ++s; + return s; +} + +/* + * Parse a dash-separated range of hex values. + */ +static void wchar_range_get(char **ss, struct wchar_range *range) +{ + char *s = skip_uprefix(*ss); + range->first = lstrtoul(s, &s, 16); + if (s[0] == '-') + { + s = skip_uprefix(&s[1]); + range->last = lstrtoul(s, &s, 16); + } else + { + range->last = range->first; + } + *ss = s; +} + +/* + * Parse the LESSUTFCHARDEF variable. + */ +static void ichardef_utf(char *s) +{ + xbuf_init(&user_wide_array); + xbuf_init(&user_ubin_array); + xbuf_init(&user_compose_array); + xbuf_init(&user_prt_array); + + if (s != NULL) + { + while (s[0] != '\0') + { + struct wchar_range range; + wchar_range_get(&s, &range); + if (range.last == 0) + { + error("invalid hex number(s) in LESSUTFCHARDEF", NULL_PARG); + quit(QUIT_ERROR); + } + if (*s++ != ':') + { + error("missing colon in LESSUTFCHARDEF", NULL_PARG); + quit(QUIT_ERROR); + } + switch (*s++) + { + case 'b': + xbuf_add_data(&user_ubin_array, (unsigned char *) &range, sizeof(range)); + break; + case 'c': + xbuf_add_data(&user_compose_array, (unsigned char *) &range, sizeof(range)); + break; + case 'w': + xbuf_add_data(&user_wide_array, (unsigned char *) &range, sizeof(range)); + xbuf_add_data(&user_prt_array, (unsigned char *) &range, sizeof(range)); + break; + case 'p': case '.': + xbuf_add_data(&user_prt_array, (unsigned char *) &range, sizeof(range)); + break; + case '\0': + s--; + break; + default: + /* Ignore unknown character attribute. */ + break; + } + if (s[0] == ',') ++s; + } + } + wchar_range_table_set(&user_wide_table, &user_wide_array); + wchar_range_table_set(&user_ubin_table, &user_ubin_array); + wchar_range_table_set(&user_compose_table, &user_compose_array); + wchar_range_table_set(&user_prt_table, &user_prt_array); +} + +/* + * Define a charset, given a description string. + * The string consists of 256 letters, + * one for each character in the charset. + * If the string is shorter than 256 letters, missing letters + * are taken to be identical to the last one. + * A decimal number followed by a letter is taken to be a + * repetition of the letter. + * + * Each letter is one of: + * . normal character + * b binary character + * c control character + */ +static void ichardef(char *s) +{ + char *cp; + int n; + char v; + + n = 0; + v = 0; + cp = chardef; + while (*s != '\0') + { + switch (*s++) + { + case '.': + v = 0; + break; + case 'c': + v = IS_CONTROL_CHAR; + break; + case 'b': + v = IS_BINARY_CHAR|IS_CONTROL_CHAR; + break; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + if (ckd_mul(&n, n, 10) || ckd_add(&n, n, s[-1] - '0')) + goto invalid_chardef; + continue; + + default: + invalid_chardef: + error("invalid chardef", NULL_PARG); + quit(QUIT_ERROR); + /*NOTREACHED*/ + } + + do + { + if (cp >= chardef + sizeof(chardef)) + { + error("chardef longer than 256", NULL_PARG); + quit(QUIT_ERROR); + /*NOTREACHED*/ + } + *cp++ = v; + } while (--n > 0); + n = 0; + } + + while (cp < chardef + sizeof(chardef)) + *cp++ = v; +} + +/* + * Define a charset, given a charset name. + * The valid charset names are listed in the "charsets" array. + */ +static int icharset(char *name, int no_error) +{ + struct charset *p; + struct cs_alias *a; + + if (name == NULL || *name == '\0') + return (0); + + /* First see if the name is an alias. */ + for (a = cs_aliases; a->name != NULL; a++) + { + if (strcmp(name, a->name) == 0) + { + name = a->oname; + break; + } + } + + for (p = charsets; p->name != NULL; p++) + { + if (strcmp(name, p->name) == 0) + { + ichardef(p->desc); + if (p->p_flag != NULL) + { +#if MSDOS_COMPILER==WIN32C + *(p->p_flag) = 1 + (GetConsoleOutputCP() != CP_UTF8); +#else + *(p->p_flag) = 1; +#endif + } + return (1); + } + } + + if (!no_error) { + error("invalid charset name", NULL_PARG); + quit(QUIT_ERROR); + } + return (0); +} + +#if HAVE_LOCALE +/* + * Define a charset, given a locale name. + */ +static void ilocale(void) +{ + int c; + + for (c = 0; c < (int) sizeof(chardef); c++) + { + if (isprint(c)) + chardef[c] = 0; + else if (iscntrl(c)) + chardef[c] = IS_CONTROL_CHAR; + else + chardef[c] = IS_BINARY_CHAR|IS_CONTROL_CHAR; + } +} +#endif + +/* + * Define the printing format for control (or binary utf) chars. + */ +public void setfmt(char *s, char **fmtvarptr, int *attrptr, char *default_fmt, int for_printf) +{ + if (s && utf_mode) + { + /* It would be too hard to account for width otherwise. */ + char constant *t = s; + while (*t) + { + if (*t < ' ' || *t > '~') + { + s = default_fmt; + goto attr; + } + t++; + } + } + + if (s == NULL || *s == '\0') + s = default_fmt; + else if (for_printf && + ((*s == '*' && (s[1] == '\0' || s[2] == '\0' || strchr(s + 2, 'n'))) || + (*s != '*' && strchr(s, 'n')))) + /* %n is evil */ + s = default_fmt; + + /* + * Select the attributes if it starts with "*". + */ + attr: + if (*s == '*' && s[1] != '\0') + { + switch (s[1]) + { + case 'd': *attrptr = AT_BOLD; break; + case 'k': *attrptr = AT_BLINK; break; + case 's': *attrptr = AT_STANDOUT; break; + case 'u': *attrptr = AT_UNDERLINE; break; + default: *attrptr = AT_NORMAL; break; + } + s += 2; + } + *fmtvarptr = s; +} + +/* + * + */ +static void set_charset(void) +{ + char *s; + +#if MSDOS_COMPILER==WIN32C + /* + * If the Windows console is using UTF-8, we'll use it too. + */ + if (GetConsoleOutputCP() == CP_UTF8) + if (icharset("utf-8", 1)) + return; +#endif + + ichardef_utf(lgetenv("LESSUTFCHARDEF")); + + /* + * See if environment variable LESSCHARSET is defined. + */ + s = lgetenv("LESSCHARSET"); + if (icharset(s, 0)) + return; + + /* + * LESSCHARSET is not defined: try LESSCHARDEF. + */ + s = lgetenv("LESSCHARDEF"); + if (!isnullenv(s)) + { + ichardef(s); + return; + } + +#if HAVE_LOCALE +#ifdef CODESET + /* + * Try using the codeset name as the charset name. + */ + s = nl_langinfo(CODESET); + if (icharset(s, 1)) + return; +#endif +#endif + +#if HAVE_STRSTR + /* + * Check whether LC_ALL, LC_CTYPE or LANG look like UTF-8 is used. + */ + if ((s = lgetenv("LC_ALL")) != NULL || + (s = lgetenv("LC_CTYPE")) != NULL || + (s = lgetenv("LANG")) != NULL) + { + if ( strstr(s, "UTF-8") != NULL || strstr(s, "utf-8") != NULL + || strstr(s, "UTF8") != NULL || strstr(s, "utf8") != NULL) + if (icharset("utf-8", 1)) + return; + } +#endif + +#if HAVE_LOCALE + /* + * Get character definitions from locale functions, + * rather than from predefined charset entry. + */ + ilocale(); +#else +#if MSDOS_COMPILER + /* + * Default to "dos". + */ + (void) icharset("dos", 1); +#else + /* + * Default to "latin1". + */ + (void) icharset("latin1", 1); +#endif +#endif +} + +/* + * Initialize charset data structures. + */ +public void init_charset(void) +{ + char *s; + +#if HAVE_LOCALE + setlocale(LC_ALL, ""); +#endif + + set_charset(); + + s = lgetenv("LESSBINFMT"); + setfmt(s, &binfmt, &binattr, "*s<%02X>", TRUE); + + s = lgetenv("LESSUTFBINFMT"); + setfmt(s, &utfbinfmt, &binattr, "", TRUE); +} + +/* + * Is a given character a "binary" character? + */ +public int binary_char(LWCHAR c) +{ + if (utf_mode) + return (is_ubin_char(c)); + c &= 0377; + return (chardef[c] & IS_BINARY_CHAR); +} + +/* + * Is a given character a "control" character? + */ +public int control_char(LWCHAR c) +{ + c &= 0377; + return (chardef[c] & IS_CONTROL_CHAR); +} + +/* + * Return the printable form of a character. + * For example, in the "ascii" charset '\3' is printed as "^C". + */ +public char * prchar(LWCHAR c) +{ + /* {{ This buffer can be overrun if LESSBINFMT is a long string. }} */ + static char buf[MAX_PRCHAR_LEN+1]; + + c &= 0377; + if ((c < 128 || !utf_mode) && !control_char(c)) + SNPRINTF1(buf, sizeof(buf), "%c", (int) c); + else if (c == ESC) + strcpy(buf, "ESC"); +#if IS_EBCDIC_HOST + else if (!binary_char(c) && c < 64) + SNPRINTF1(buf, sizeof(buf), "^%c", + /* + * This array roughly inverts CONTROL() #defined in less.h, + * and should be kept in sync with CONTROL() and IBM-1047. + */ + "@ABC.I.?...KLMNO" + "PQRS.JH.XY.." + "\\]^_" + "......W[.....EFG" + "..V....D....TU.Z"[c]); +#else + else if (c < 128 && !control_char(c ^ 0100)) + SNPRINTF1(buf, sizeof(buf), "^%c", (int) (c ^ 0100)); +#endif + else + SNPRINTF1(buf, sizeof(buf), binfmt, c); + return (buf); +} + +/* + * Return the printable form of a UTF-8 character. + */ +public char * prutfchar(LWCHAR ch) +{ + static char buf[MAX_PRCHAR_LEN+1]; + + if (ch == ESC) + strcpy(buf, "ESC"); + else if (ch < 128 && control_char(ch)) + { + if (!control_char(ch ^ 0100)) + SNPRINTF1(buf, sizeof(buf), "^%c", ((char) ch) ^ 0100); + else + SNPRINTF1(buf, sizeof(buf), binfmt, (char) ch); + } else if (is_ubin_char(ch)) + { + SNPRINTF1(buf, sizeof(buf), utfbinfmt, ch); + } else + { + char *p = buf; + if (ch >= 0x80000000) + ch = 0xFFFD; /* REPLACEMENT CHARACTER */ + put_wchar(&p, ch); + *p = '\0'; + } + return (buf); +} + +/* + * Get the length of a UTF-8 character in bytes. + */ +public int utf_len(int ch) +{ + if ((ch & 0x80) == 0) + return 1; + if ((ch & 0xE0) == 0xC0) + return 2; + if ((ch & 0xF0) == 0xE0) + return 3; + if ((ch & 0xF8) == 0xF0) + return 4; + if ((ch & 0xFC) == 0xF8) + return 5; + if ((ch & 0xFE) == 0xFC) + return 6; + /* Invalid UTF-8 encoding. */ + return 1; +} + +/* + * Does the parameter point to the lead byte of a well-formed UTF-8 character? + */ +public int is_utf8_well_formed(char *ss, int slen) +{ + int i; + int len; + unsigned char *s = (unsigned char *) ss; + + if (IS_UTF8_INVALID(s[0])) + return (0); + + len = utf_len(s[0]); + if (len > slen) + return (0); + if (len == 1) + return (1); + if (len == 2) + { + if (s[0] < 0xC2) + return (0); + } else + { + unsigned char mask; + mask = (~((1 << (8-len)) - 1)) & 0xFF; + if (s[0] == mask && (s[1] & mask) == 0x80) + return (0); + } + + for (i = 1; i < len; i++) + if (!IS_UTF8_TRAIL(s[i])) + return (0); + return (1); +} + +/* + * Skip bytes until a UTF-8 lead byte (11xxxxxx) or ASCII byte (0xxxxxxx) is found. + */ +public void utf_skip_to_lead(char **pp, char *limit) +{ + do { + ++(*pp); + } while (*pp < limit && !IS_UTF8_LEAD((*pp)[0] & 0377) && !IS_ASCII_OCTET((*pp)[0])); +} + + +/* + * Get the value of a UTF-8 character. + */ +public LWCHAR get_wchar(constant char *p) +{ + switch (utf_len(p[0])) + { + case 1: + default: + /* 0xxxxxxx */ + return (LWCHAR) + (p[0] & 0xFF); + case 2: + /* 110xxxxx 10xxxxxx */ + return (LWCHAR) ( + ((p[0] & 0x1F) << 6) | + (p[1] & 0x3F)); + case 3: + /* 1110xxxx 10xxxxxx 10xxxxxx */ + return (LWCHAR) ( + ((p[0] & 0x0F) << 12) | + ((p[1] & 0x3F) << 6) | + (p[2] & 0x3F)); + case 4: + /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ + return (LWCHAR) ( + ((p[0] & 0x07) << 18) | + ((p[1] & 0x3F) << 12) | + ((p[2] & 0x3F) << 6) | + (p[3] & 0x3F)); + case 5: + /* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + return (LWCHAR) ( + ((p[0] & 0x03) << 24) | + ((p[1] & 0x3F) << 18) | + ((p[2] & 0x3F) << 12) | + ((p[3] & 0x3F) << 6) | + (p[4] & 0x3F)); + case 6: + /* 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + return (LWCHAR) ( + ((p[0] & 0x01) << 30) | + ((p[1] & 0x3F) << 24) | + ((p[2] & 0x3F) << 18) | + ((p[3] & 0x3F) << 12) | + ((p[4] & 0x3F) << 6) | + (p[5] & 0x3F)); + } +} + +/* + * Store a character into a UTF-8 string. + */ +public void put_wchar(char **pp, LWCHAR ch) +{ + if (!utf_mode || ch < 0x80) + { + /* 0xxxxxxx */ + *(*pp)++ = (char) ch; + } else if (ch < 0x800) + { + /* 110xxxxx 10xxxxxx */ + *(*pp)++ = (char) (0xC0 | ((ch >> 6) & 0x1F)); + *(*pp)++ = (char) (0x80 | (ch & 0x3F)); + } else if (ch < 0x10000) + { + /* 1110xxxx 10xxxxxx 10xxxxxx */ + *(*pp)++ = (char) (0xE0 | ((ch >> 12) & 0x0F)); + *(*pp)++ = (char) (0x80 | ((ch >> 6) & 0x3F)); + *(*pp)++ = (char) (0x80 | (ch & 0x3F)); + } else if (ch < 0x200000) + { + /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ + *(*pp)++ = (char) (0xF0 | ((ch >> 18) & 0x07)); + *(*pp)++ = (char) (0x80 | ((ch >> 12) & 0x3F)); + *(*pp)++ = (char) (0x80 | ((ch >> 6) & 0x3F)); + *(*pp)++ = (char) (0x80 | (ch & 0x3F)); + } else if (ch < 0x4000000) + { + /* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + *(*pp)++ = (char) (0xF0 | ((ch >> 24) & 0x03)); + *(*pp)++ = (char) (0x80 | ((ch >> 18) & 0x3F)); + *(*pp)++ = (char) (0x80 | ((ch >> 12) & 0x3F)); + *(*pp)++ = (char) (0x80 | ((ch >> 6) & 0x3F)); + *(*pp)++ = (char) (0x80 | (ch & 0x3F)); + } else + { + /* 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + *(*pp)++ = (char) (0xF0 | ((ch >> 30) & 0x01)); + *(*pp)++ = (char) (0x80 | ((ch >> 24) & 0x3F)); + *(*pp)++ = (char) (0x80 | ((ch >> 18) & 0x3F)); + *(*pp)++ = (char) (0x80 | ((ch >> 12) & 0x3F)); + *(*pp)++ = (char) (0x80 | ((ch >> 6) & 0x3F)); + *(*pp)++ = (char) (0x80 | (ch & 0x3F)); + } +} + +/* + * Step forward or backward one character in a string. + */ +public LWCHAR step_char(char **pp, signed int dir, constant char *limit) +{ + LWCHAR ch; + int len; + char *p = *pp; + + if (!utf_mode) + { + /* It's easy if chars are one byte. */ + if (dir > 0) + ch = (LWCHAR) (unsigned char) ((p < limit) ? *p++ : 0); + else + ch = (LWCHAR) (unsigned char) ((p > limit) ? *--p : 0); + } else if (dir > 0) + { + len = utf_len(*p); + if (p + len > limit) + { + ch = 0; + p = (char *) limit; + } else + { + ch = get_wchar(p); + p += len; + } + } else + { + while (p > limit && IS_UTF8_TRAIL(p[-1])) + p--; + if (p > limit) + ch = get_wchar(--p); + else + ch = 0; + } + *pp = p; + return ch; +} + +/* + * Unicode characters data + * Actual data is in the generated *.uni files. + */ + +#define DECLARE_RANGE_TABLE_START(name) \ + static struct wchar_range name##_array[] = { +#define DECLARE_RANGE_TABLE_END(name) \ + }; struct wchar_range_table name##_table = { name##_array, sizeof(name##_array)/sizeof(*name##_array) }; + +DECLARE_RANGE_TABLE_START(compose) +#include "compose.inc" +DECLARE_RANGE_TABLE_END(compose) + +DECLARE_RANGE_TABLE_START(ubin) +#include "ubin.inc" +DECLARE_RANGE_TABLE_END(ubin) + +DECLARE_RANGE_TABLE_START(wide) +#include "wide.inc" +DECLARE_RANGE_TABLE_END(wide) + +DECLARE_RANGE_TABLE_START(fmt) +#include "fmt.inc" +DECLARE_RANGE_TABLE_END(fmt) + +/* comb_table is special pairs, not ranges. */ +static struct wchar_range comb_table[] = { + {0x0644,0x0622}, {0x0644,0x0623}, {0x0644,0x0625}, {0x0644,0x0627}, +}; + + +static int is_in_table(LWCHAR ch, struct wchar_range_table *table) +{ + int hi; + int lo; + + /* Binary search in the table. */ + if (table->table == NULL || table->count == 0 || ch < table->table[0].first) + return 0; + lo = 0; + hi = table->count - 1; + while (lo <= hi) + { + int mid = (lo + hi) / 2; + if (ch > table->table[mid].last) + lo = mid + 1; + else if (ch < table->table[mid].first) + hi = mid - 1; + else + return 1; + } + return 0; +} + +/* + * Is a character a UTF-8 composing character? + * If a composing character follows any char, the two combine into one glyph. + */ +public int is_composing_char(LWCHAR ch) +{ + if (is_in_table(ch, &user_prt_table)) return 0; + return is_in_table(ch, &user_compose_table) || + is_in_table(ch, &compose_table) || + (bs_mode != BS_CONTROL && is_in_table(ch, &fmt_table)); +} + +/* + * Should this UTF-8 character be treated as binary? + */ +public int is_ubin_char(LWCHAR ch) +{ + if (is_in_table(ch, &user_prt_table)) return 0; + return is_in_table(ch, &user_ubin_table) || + is_in_table(ch, &ubin_table) || + (bs_mode == BS_CONTROL && is_in_table(ch, &fmt_table)); +} + +/* + * Is this a double width UTF-8 character? + */ +public int is_wide_char(LWCHAR ch) +{ + return is_in_table(ch, &user_wide_table) || + is_in_table(ch, &wide_table); +} + +/* + * Is a character a UTF-8 combining character? + * A combining char acts like an ordinary char, but if it follows + * a specific char (not any char), the two combine into one glyph. + */ +public int is_combining_char(LWCHAR ch1, LWCHAR ch2) +{ + /* The table is small; use linear search. */ + int i; + for (i = 0; i < sizeof(comb_table)/sizeof(*comb_table); i++) + { + if (ch1 == comb_table[i].first && + ch2 == comb_table[i].last) + return 1; + } + return 0; +} + diff --git a/third_party/less/charset.h b/third_party/less/charset.h new file mode 100644 index 000000000..4312113a5 --- /dev/null +++ b/third_party/less/charset.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + +#define IS_ASCII_OCTET(c) (((c) & 0x80) == 0) +#define IS_UTF8_TRAIL(c) (((c) & 0xC0) == 0x80) +#define IS_UTF8_LEAD2(c) (((c) & 0xE0) == 0xC0) +#define IS_UTF8_LEAD3(c) (((c) & 0xF0) == 0xE0) +#define IS_UTF8_LEAD4(c) (((c) & 0xF8) == 0xF0) +#define IS_UTF8_LEAD5(c) (((c) & 0xFC) == 0xF8) +#define IS_UTF8_LEAD6(c) (((c) & 0xFE) == 0xFC) +#define IS_UTF8_INVALID(c) (((c) & 0xFE) == 0xFE) +#define IS_UTF8_LEAD(c) (((c) & 0xC0) == 0xC0 && !IS_UTF8_INVALID(c)) diff --git a/third_party/less/cmd.h b/third_party/less/cmd.h new file mode 100644 index 000000000..a927a3d36 --- /dev/null +++ b/third_party/less/cmd.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +#define MAX_USERCMD 1000 +#define MAX_CMDLEN 16 + +#define A_B_LINE 2 +#define A_B_SCREEN 3 +#define A_B_SCROLL 4 +#define A_B_SEARCH 5 +#define A_DIGIT 6 +#define A_DISP_OPTION 7 +#define A_DEBUG 8 +#define A_EXAMINE 9 +#define A_FIRSTCMD 10 +#define A_FREPAINT 11 +#define A_F_LINE 12 +#define A_F_SCREEN 13 +#define A_F_SCROLL 14 +#define A_F_SEARCH 15 +#define A_GOEND 16 +#define A_GOLINE 17 +#define A_GOMARK 18 +#define A_HELP 19 +#define A_NEXT_FILE 20 +#define A_PERCENT 21 +#define A_PREV_FILE 23 +#define A_QUIT 24 +#define A_REPAINT 25 +#define A_SETMARK 26 +#define A_SHELL 27 +#define A_STAT 28 +#define A_FF_LINE 29 +#define A_BF_LINE 30 +#define A_VERSION 31 +#define A_VISUAL 32 +#define A_F_WINDOW 33 +#define A_B_WINDOW 34 +#define A_F_BRACKET 35 +#define A_B_BRACKET 36 +#define A_PIPE 37 +#define A_INDEX_FILE 38 +#define A_UNDO_SEARCH 39 +#define A_FF_SCREEN 40 +#define A_LSHIFT 41 +#define A_RSHIFT 42 +#define A_AGAIN_SEARCH 43 +#define A_T_AGAIN_SEARCH 44 +#define A_REVERSE_SEARCH 45 +#define A_T_REVERSE_SEARCH 46 +#define A_OPT_TOGGLE 47 +#define A_OPT_SET 48 +#define A_OPT_UNSET 49 +#define A_F_FOREVER 50 +#define A_GOPOS 51 +#define A_REMOVE_FILE 52 +#define A_NEXT_TAG 53 +#define A_PREV_TAG 54 +#define A_FILTER 55 +#define A_F_UNTIL_HILITE 56 +#define A_GOEND_BUF 57 +#define A_LLSHIFT 58 +#define A_RRSHIFT 59 +#define A_CLRMARK 62 +#define A_SETMARKBOT 63 +#define A_X11MOUSE_IN 64 +#define A_F_MOUSE 66 +#define A_B_MOUSE 67 +/* Note "X116" refers to extended (1006) X11 mouse reporting. */ +#define A_X116MOUSE_IN 68 +#define A_PSHELL 69 +#define A_CLR_SEARCH 70 + +/* These values must not conflict with any A_* or EC_* value. */ +#define A_INVALID 100 +#define A_NOACTION 101 +#define A_UINVALID 102 +#define A_END_LIST 103 +#define A_SPECIAL_KEY 104 +#define A_PREFIX 105 +#define A_SKIP 127 + +#define A_EXTRA 0200 + + +/* Line editing characters */ + +#define EC_BACKSPACE 1 +#define EC_LINEKILL 2 +#define EC_RIGHT 3 +#define EC_LEFT 4 +#define EC_W_LEFT 5 +#define EC_W_RIGHT 6 +#define EC_INSERT 7 +#define EC_DELETE 8 +#define EC_HOME 9 +#define EC_END 10 +#define EC_W_BACKSPACE 11 +#define EC_W_DELETE 12 +#define EC_UP 13 +#define EC_DOWN 14 +#define EC_EXPAND 15 +#define EC_F_COMPLETE 17 +#define EC_B_COMPLETE 18 +#define EC_LITERAL 19 +#define EC_ABORT 20 +#define EC_X11MOUSE 21 +#define EC_X116MOUSE 22 + +#define EC_UINVALID 102 + +/* Flags for editchar() */ +#define ECF_PEEK 01 +#define ECF_NOHISTORY 02 +#define ECF_NOCOMPLETE 04 +#define ECF_NORIGHTLEFT 010 + +/* Environment variable stuff */ +#define EV_OK 01 + +/* Special keys (keys which output different strings on different terminals) */ +#define SK_SPECIAL_KEY CONTROL('K') +#define SK_RIGHT_ARROW 1 +#define SK_LEFT_ARROW 2 +#define SK_UP_ARROW 3 +#define SK_DOWN_ARROW 4 +#define SK_PAGE_UP 5 +#define SK_PAGE_DOWN 6 +#define SK_HOME 7 +#define SK_END 8 +#define SK_DELETE 9 +#define SK_INSERT 10 +#define SK_CTL_LEFT_ARROW 11 +#define SK_CTL_RIGHT_ARROW 12 +#define SK_CTL_DELETE 13 +#define SK_F1 14 +#define SK_BACKTAB 15 +#define SK_CTL_BACKSPACE 16 +#define SK_BACKSPACE 17 +#define SK_CONTROL_K 40 diff --git a/third_party/less/cmdbuf.c b/third_party/less/cmdbuf.c new file mode 100644 index 000000000..c81328387 --- /dev/null +++ b/third_party/less/cmdbuf.c @@ -0,0 +1,1677 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * Functions which manipulate the command buffer. + * Used only by command() and related functions. + */ + +#include "less.h" +#include "cmd.h" +#include "charset.h" +#if HAVE_STAT +#include +#endif + +extern int sc_width; +extern int utf_mode; +extern int no_hist_dups; +extern int marks_modified; +extern int secure; + +static char cmdbuf[CMDBUF_SIZE]; /* Buffer for holding a multi-char command */ +static int cmd_col; /* Current column of the cursor */ +static int prompt_col; /* Column of cursor just after prompt */ +static char *cp; /* Pointer into cmdbuf */ +static int cmd_offset; /* Index into cmdbuf of first displayed char */ +static int literal; /* Next input char should not be interpreted */ +public int updown_match = -1; /* Prefix length in up/down movement */ + +#if TAB_COMPLETE_FILENAME +static int cmd_complete(int action); +/* + * These variables are statics used by cmd_complete. + */ +static int in_completion = 0; +static char *tk_text; +static char *tk_original; +static char *tk_ipoint; +static char *tk_trial = NULL; +static struct textlist tk_tlist; +#endif + +static int cmd_left(); +static int cmd_right(); + +#if SPACES_IN_FILENAMES +public char openquote = '"'; +public char closequote = '"'; +#endif + +#if CMD_HISTORY + +/* History file */ +#define HISTFILE_FIRST_LINE ".less-history-file:" +#define HISTFILE_SEARCH_SECTION ".search" +#define HISTFILE_SHELL_SECTION ".shell" +#define HISTFILE_MARK_SECTION ".mark" + +/* + * A mlist structure represents a command history. + */ +struct mlist +{ + struct mlist *next; + struct mlist *prev; + struct mlist *curr_mp; + char *string; + int modified; +}; + +/* + * These are the various command histories that exist. + */ +struct mlist mlist_search = + { &mlist_search, &mlist_search, &mlist_search, NULL, 0 }; +public void *ml_search = (void *) &mlist_search; + +struct mlist mlist_examine = + { &mlist_examine, &mlist_examine, &mlist_examine, NULL, 0 }; +public void *ml_examine = (void *) &mlist_examine; + +#if SHELL_ESCAPE || PIPEC +struct mlist mlist_shell = + { &mlist_shell, &mlist_shell, &mlist_shell, NULL, 0 }; +public void *ml_shell = (void *) &mlist_shell; +#endif + +#else /* CMD_HISTORY */ + +/* If CMD_HISTORY is off, these are just flags. */ +public void *ml_search = (void *)1; +public void *ml_examine = (void *)2; +#if SHELL_ESCAPE || PIPEC +public void *ml_shell = (void *)3; +#endif + +#endif /* CMD_HISTORY */ + +/* + * History for the current command. + */ +static struct mlist *curr_mlist = NULL; +static int curr_cmdflags; + +static char cmd_mbc_buf[MAX_UTF_CHAR_LEN]; +static int cmd_mbc_buf_len; +static int cmd_mbc_buf_index; + + +/* + * Reset command buffer (to empty). + */ +public void cmd_reset(void) +{ + cp = cmdbuf; + *cp = '\0'; + cmd_col = 0; + cmd_offset = 0; + literal = 0; + cmd_mbc_buf_len = 0; + updown_match = -1; +} + +/* + * Clear command line. + */ +public void clear_cmd(void) +{ + cmd_col = prompt_col = 0; + cmd_mbc_buf_len = 0; + updown_match = -1; +} + +/* + * Display a string, usually as a prompt for input into the command buffer. + */ +public void cmd_putstr(constant char *s) +{ + LWCHAR prev_ch = 0; + LWCHAR ch; + constant char *endline = s + strlen(s); + while (*s != '\0') + { + char *ns = (char *) s; + int width; + ch = step_char(&ns, +1, endline); + while (s < ns) + putchr(*s++); + if (!utf_mode) + width = 1; + else if (is_composing_char(ch) || is_combining_char(prev_ch, ch)) + width = 0; + else + width = is_wide_char(ch) ? 2 : 1; + cmd_col += width; + prompt_col += width; + prev_ch = ch; + } +} + +/* + * How many characters are in the command buffer? + */ +public int len_cmdbuf(void) +{ + char *s = cmdbuf; + char *endline = s + strlen(s); + int len = 0; + + while (*s != '\0') + { + step_char(&s, +1, endline); + len++; + } + return (len); +} + +/* + * Common part of cmd_step_right() and cmd_step_left(). + * {{ Returning pwidth and bswidth separately is a historical artifact + * since they're always the same. Maybe clean this up someday. }} + */ +static char * cmd_step_common(char *p, LWCHAR ch, int len, int *pwidth, int *bswidth) +{ + char *pr; + int width; + + if (len == 1) + { + pr = prchar((int) ch); + width = (int) strlen(pr); + } else + { + pr = prutfchar(ch); + if (is_composing_char(ch)) + width = 0; + else if (is_ubin_char(ch)) + width = (int) strlen(pr); + else + { + LWCHAR prev_ch = step_char(&p, -1, cmdbuf); + if (is_combining_char(prev_ch, ch)) + width = 0; + else + width = is_wide_char(ch) ? 2 : 1; + } + } + if (pwidth != NULL) + *pwidth = width; + if (bswidth != NULL) + *bswidth = width; + return (pr); +} + +/* + * Step a pointer one character right in the command buffer. + */ +static char * cmd_step_right(char **pp, int *pwidth, int *bswidth) +{ + char *p = *pp; + LWCHAR ch = step_char(pp, +1, p + strlen(p)); + + return cmd_step_common(p, ch, *pp - p, pwidth, bswidth); +} + +/* + * Step a pointer one character left in the command buffer. + */ +static char * cmd_step_left(char **pp, int *pwidth, int *bswidth) +{ + char *p = *pp; + LWCHAR ch = step_char(pp, -1, cmdbuf); + + return cmd_step_common(*pp, ch, p - *pp, pwidth, bswidth); +} + +/* + * Put the cursor at "home" (just after the prompt), + * and set cp to the corresponding char in cmdbuf. + */ +static void cmd_home(void) +{ + while (cmd_col > prompt_col) + { + int width, bswidth; + + cmd_step_left(&cp, &width, &bswidth); + while (bswidth-- > 0) + putbs(); + cmd_col -= width; + } + + cp = &cmdbuf[cmd_offset]; +} + +/* + * Repaint the line from cp onwards. + * Then position the cursor just after the char old_cp (a pointer into cmdbuf). + */ +public void cmd_repaint(constant char *old_cp) +{ + /* + * Repaint the line from the current position. + */ + if (old_cp == NULL) + { + old_cp = cp; + cmd_home(); + } + clear_eol(); + while (*cp != '\0') + { + char *np = cp; + int width; + char *pr = cmd_step_right(&np, &width, NULL); + if (cmd_col + width >= sc_width) + break; + cp = np; + putstr(pr); + cmd_col += width; + } + while (*cp != '\0') + { + char *np = cp; + int width; + char *pr = cmd_step_right(&np, &width, NULL); + if (width > 0) + break; + cp = np; + putstr(pr); + } + + /* + * Back up the cursor to the correct position. + */ + while (cp > old_cp) + cmd_left(); +} + +/* + * Shift the cmdbuf display left a half-screen. + */ +static void cmd_lshift(void) +{ + char *s; + char *save_cp; + int cols; + + /* + * Start at the first displayed char, count how far to the + * right we'd have to move to reach the center of the screen. + */ + s = cmdbuf + cmd_offset; + cols = 0; + while (cols < (sc_width - prompt_col) / 2 && *s != '\0') + { + int width; + cmd_step_right(&s, &width, NULL); + cols += width; + } + while (*s != '\0') + { + int width; + char *ns = s; + cmd_step_right(&ns, &width, NULL); + if (width > 0) + break; + s = ns; + } + + cmd_offset = (int) (s - cmdbuf); + save_cp = cp; + cmd_home(); + cmd_repaint(save_cp); +} + +/* + * Shift the cmdbuf display right a half-screen. + */ +static void cmd_rshift(void) +{ + char *s; + char *save_cp; + int cols; + + /* + * Start at the first displayed char, count how far to the + * left we'd have to move to traverse a half-screen width + * of displayed characters. + */ + s = cmdbuf + cmd_offset; + cols = 0; + while (cols < (sc_width - prompt_col) / 2 && s > cmdbuf) + { + int width; + cmd_step_left(&s, &width, NULL); + cols += width; + } + + cmd_offset = (int) (s - cmdbuf); + save_cp = cp; + cmd_home(); + cmd_repaint(save_cp); +} + +/* + * Move cursor right one character. + */ +static int cmd_right(void) +{ + char *pr; + char *ncp; + int width; + + if (*cp == '\0') + { + /* Already at the end of the line. */ + return (CC_OK); + } + ncp = cp; + pr = cmd_step_right(&ncp, &width, NULL); + if (cmd_col + width >= sc_width) + cmd_lshift(); + else if (cmd_col + width == sc_width - 1 && cp[1] != '\0') + cmd_lshift(); + cp = ncp; + cmd_col += width; + putstr(pr); + while (*cp != '\0') + { + pr = cmd_step_right(&ncp, &width, NULL); + if (width > 0) + break; + putstr(pr); + cp = ncp; + } + return (CC_OK); +} + +/* + * Move cursor left one character. + */ +static int cmd_left(void) +{ + char *ncp; + int width = 0; + int bswidth = 0; + + if (cp <= cmdbuf) + { + /* Already at the beginning of the line */ + return (CC_OK); + } + ncp = cp; + while (ncp > cmdbuf) + { + cmd_step_left(&ncp, &width, &bswidth); + if (width > 0) + break; + } + if (cmd_col < prompt_col + width) + cmd_rshift(); + cp = ncp; + cmd_col -= width; + while (bswidth-- > 0) + putbs(); + return (CC_OK); +} + +/* + * Insert a char into the command buffer, at the current position. + */ +static int cmd_ichar(char *cs, int clen) +{ + char *s; + + if (strlen(cmdbuf) + clen >= sizeof(cmdbuf)-1) + { + /* No room in the command buffer for another char. */ + bell(); + return (CC_ERROR); + } + + /* + * Make room for the new character (shift the tail of the buffer right). + */ + for (s = &cmdbuf[strlen(cmdbuf)]; s >= cp; s--) + s[clen] = s[0]; + /* + * Insert the character into the buffer. + */ + for (s = cp; s < cp + clen; s++) + *s = *cs++; + /* + * Reprint the tail of the line from the inserted char. + */ + updown_match = -1; + cmd_repaint(cp); + cmd_right(); + return (CC_OK); +} + +/* + * Backspace in the command buffer. + * Delete the char to the left of the cursor. + */ +static int cmd_erase(void) +{ + char *s; + int clen; + + if (cp == cmdbuf) + { + /* + * Backspace past beginning of the buffer: + * this usually means abort the command. + */ + return (CC_QUIT); + } + /* + * Move cursor left (to the char being erased). + */ + s = cp; + cmd_left(); + clen = (int) (s - cp); + + /* + * Remove the char from the buffer (shift the buffer left). + */ + for (s = cp; ; s++) + { + s[0] = s[clen]; + if (s[0] == '\0') + break; + } + + /* + * Repaint the buffer after the erased char. + */ + updown_match = -1; + cmd_repaint(cp); + + /* + * We say that erasing the entire command string causes us + * to abort the current command, if CF_QUIT_ON_ERASE is set. + */ + if ((curr_cmdflags & CF_QUIT_ON_ERASE) && cp == cmdbuf && *cp == '\0') + return (CC_QUIT); + return (CC_OK); +} + +/* + * Delete the char under the cursor. + */ +static int cmd_delete(void) +{ + if (*cp == '\0') + { + /* At end of string; there is no char under the cursor. */ + return (CC_OK); + } + /* + * Move right, then use cmd_erase. + */ + cmd_right(); + cmd_erase(); + return (CC_OK); +} + +/* + * Delete the "word" to the left of the cursor. + */ +static int cmd_werase(void) +{ + if (cp > cmdbuf && cp[-1] == ' ') + { + /* + * If the char left of cursor is a space, + * erase all the spaces left of cursor (to the first non-space). + */ + while (cp > cmdbuf && cp[-1] == ' ') + (void) cmd_erase(); + } else + { + /* + * If the char left of cursor is not a space, + * erase all the nonspaces left of cursor (the whole "word"). + */ + while (cp > cmdbuf && cp[-1] != ' ') + (void) cmd_erase(); + } + return (CC_OK); +} + +/* + * Delete the "word" under the cursor. + */ +static int cmd_wdelete(void) +{ + if (*cp == ' ') + { + /* + * If the char under the cursor is a space, + * delete it and all the spaces right of cursor. + */ + while (*cp == ' ') + (void) cmd_delete(); + } else + { + /* + * If the char under the cursor is not a space, + * delete it and all nonspaces right of cursor (the whole word). + */ + while (*cp != ' ' && *cp != '\0') + (void) cmd_delete(); + } + return (CC_OK); +} + +/* + * Delete all chars in the command buffer. + */ +static int cmd_kill(void) +{ + if (cmdbuf[0] == '\0') + { + /* Buffer is already empty; abort the current command. */ + return (CC_QUIT); + } + cmd_offset = 0; + cmd_home(); + *cp = '\0'; + updown_match = -1; + cmd_repaint(cp); + + /* + * We say that erasing the entire command string causes us + * to abort the current command, if CF_QUIT_ON_ERASE is set. + */ + if (curr_cmdflags & CF_QUIT_ON_ERASE) + return (CC_QUIT); + return (CC_OK); +} + +/* + * Select an mlist structure to be the current command history. + */ +public void set_mlist(void *mlist, int cmdflags) +{ +#if CMD_HISTORY + curr_mlist = (struct mlist *) mlist; + curr_cmdflags = cmdflags; + + /* Make sure the next up-arrow moves to the last string in the mlist. */ + if (curr_mlist != NULL) + curr_mlist->curr_mp = curr_mlist; +#endif +} + +#if CMD_HISTORY +/* + * Move up or down in the currently selected command history list. + * Only consider entries whose first updown_match chars are equal to + * cmdbuf's corresponding chars. + */ +static int cmd_updown(int action) +{ + constant char *s; + struct mlist *ml; + + if (curr_mlist == NULL) + { + /* + * The current command has no history list. + */ + bell(); + return (CC_OK); + } + + if (updown_match < 0) + { + updown_match = (int) (cp - cmdbuf); + } + + /* + * Find the next history entry which matches. + */ + for (ml = curr_mlist->curr_mp;;) + { + ml = (action == EC_UP) ? ml->prev : ml->next; + if (ml == curr_mlist) + { + /* + * We reached the end (or beginning) of the list. + */ + break; + } + if (strncmp(cmdbuf, ml->string, updown_match) == 0) + { + /* + * This entry matches; stop here. + * Copy the entry into cmdbuf and echo it on the screen. + */ + curr_mlist->curr_mp = ml; + s = ml->string; + if (s == NULL) + s = ""; + cmd_offset = 0; + cmd_home(); + clear_eol(); + strcpy(cmdbuf, s); + for (cp = cmdbuf; *cp != '\0'; ) + cmd_right(); + return (CC_OK); + } + } + /* + * We didn't find a history entry that matches. + */ + bell(); + return (CC_OK); +} +#endif + +/* + * + */ +static void ml_link(struct mlist *mlist, struct mlist *ml) +{ + ml->next = mlist; + ml->prev = mlist->prev; + mlist->prev->next = ml; + mlist->prev = ml; +} + +/* + * + */ +static void ml_unlink(struct mlist *ml) +{ + ml->prev->next = ml->next; + ml->next->prev = ml->prev; +} + +/* + * Add a string to an mlist. + */ +public void cmd_addhist(struct mlist *mlist, constant char *cmd, int modified) +{ +#if CMD_HISTORY + struct mlist *ml; + + /* + * Don't save a trivial command. + */ + if (strlen(cmd) == 0) + return; + + if (no_hist_dups) + { + struct mlist *next = NULL; + for (ml = mlist->next; ml->string != NULL; ml = next) + { + next = ml->next; + if (strcmp(ml->string, cmd) == 0) + { + ml_unlink(ml); + free(ml->string); + free(ml); + } + } + } + + /* + * Save the command unless it's a duplicate of the + * last command in the history. + */ + ml = mlist->prev; + if (ml == mlist || strcmp(ml->string, cmd) != 0) + { + /* + * Did not find command in history. + * Save the command and put it at the end of the history list. + */ + ml = (struct mlist *) ecalloc(1, sizeof(struct mlist)); + ml->string = save(cmd); + ml->modified = modified; + ml_link(mlist, ml); + } + /* + * Point to the cmd just after the just-accepted command. + * Thus, an UPARROW will always retrieve the previous command. + */ + mlist->curr_mp = ml->next; +#endif +} + +/* + * Accept the command in the command buffer. + * Add it to the currently selected history list. + */ +public void cmd_accept(void) +{ +#if CMD_HISTORY + /* + * Nothing to do if there is no currently selected history list. + */ + if (curr_mlist == NULL || curr_mlist == ml_examine) + return; + cmd_addhist(curr_mlist, cmdbuf, 1); + curr_mlist->modified = 1; +#endif +} + +/* + * Try to perform a line-edit function on the command buffer, + * using a specified char as a line-editing command. + * Returns: + * CC_PASS The char does not invoke a line edit function. + * CC_OK Line edit function done. + * CC_QUIT The char requests the current command to be aborted. + */ +static int cmd_edit(int c) +{ + int action; + int flags; + +#if TAB_COMPLETE_FILENAME +#define not_in_completion() in_completion = 0 +#else +#define not_in_completion(void) +#endif + + /* + * See if the char is indeed a line-editing command. + */ + flags = 0; +#if CMD_HISTORY + if (curr_mlist == NULL) + /* + * No current history; don't accept history manipulation cmds. + */ + flags |= ECF_NOHISTORY; +#endif +#if TAB_COMPLETE_FILENAME + if (curr_mlist == ml_search || curr_mlist == NULL) + /* + * Don't accept file-completion cmds in contexts + * such as search pattern, digits, long option name, etc. + */ + flags |= ECF_NOCOMPLETE; +#endif + + action = editchar(c, flags); + + switch (action) + { + case A_NOACTION: + return (CC_OK); + case EC_RIGHT: + not_in_completion(); + return (cmd_right()); + case EC_LEFT: + not_in_completion(); + return (cmd_left()); + case EC_W_RIGHT: + not_in_completion(); + while (*cp != '\0' && *cp != ' ') + cmd_right(); + while (*cp == ' ') + cmd_right(); + return (CC_OK); + case EC_W_LEFT: + not_in_completion(); + while (cp > cmdbuf && cp[-1] == ' ') + cmd_left(); + while (cp > cmdbuf && cp[-1] != ' ') + cmd_left(); + return (CC_OK); + case EC_HOME: + not_in_completion(); + cmd_offset = 0; + cmd_home(); + cmd_repaint(cp); + return (CC_OK); + case EC_END: + not_in_completion(); + while (*cp != '\0') + cmd_right(); + return (CC_OK); + case EC_INSERT: + not_in_completion(); + return (CC_OK); + case EC_BACKSPACE: + not_in_completion(); + return (cmd_erase()); + case EC_LINEKILL: + not_in_completion(); + return (cmd_kill()); + case EC_ABORT: + not_in_completion(); + (void) cmd_kill(); + return (CC_QUIT); + case EC_W_BACKSPACE: + not_in_completion(); + return (cmd_werase()); + case EC_DELETE: + not_in_completion(); + return (cmd_delete()); + case EC_W_DELETE: + not_in_completion(); + return (cmd_wdelete()); + case EC_LITERAL: + literal = 1; + return (CC_OK); +#if CMD_HISTORY + case EC_UP: + case EC_DOWN: + not_in_completion(); + return (cmd_updown(action)); +#endif +#if TAB_COMPLETE_FILENAME + case EC_F_COMPLETE: + case EC_B_COMPLETE: + case EC_EXPAND: + return (cmd_complete(action)); +#endif + default: + not_in_completion(); + return (CC_PASS); + } +} + +#if TAB_COMPLETE_FILENAME +/* + * Insert a string into the command buffer, at the current position. + */ +static int cmd_istr(char *str) +{ + char *s; + int action; + char *endline = str + strlen(str); + + for (s = str; *s != '\0'; ) + { + char *os = s; + step_char(&s, +1, endline); + action = cmd_ichar(os, s - os); + if (action != CC_OK) + return (action); + } + return (CC_OK); +} + +/* + * Find the beginning and end of the "current" word. + * This is the word which the cursor (cp) is inside or at the end of. + * Return pointer to the beginning of the word and put the + * cursor at the end of the word. + */ +static char * delimit_word(void) +{ + char *word; +#if SPACES_IN_FILENAMES + char *p; + int delim_quoted = 0; + int meta_quoted = 0; + constant char *esc = get_meta_escape(); + int esclen = (int) strlen(esc); +#endif + + /* + * Move cursor to end of word. + */ + if (*cp != ' ' && *cp != '\0') + { + /* + * Cursor is on a nonspace. + * Move cursor right to the next space. + */ + while (*cp != ' ' && *cp != '\0') + cmd_right(); + } else if (cp > cmdbuf && cp[-1] != ' ') + { + /* + * Cursor is on a space, and char to the left is a nonspace. + * We're already at the end of the word. + */ + ; +#if 0 + } else + { + /* + * Cursor is on a space and char to the left is a space. + * Huh? There's no word here. + */ + return (NULL); +#endif + } + /* + * Find the beginning of the word which the cursor is in. + */ + if (cp == cmdbuf) + return (NULL); +#if SPACES_IN_FILENAMES + /* + * If we have an unbalanced quote (that is, an open quote + * without a corresponding close quote), we return everything + * from the open quote, including spaces. + */ + for (word = cmdbuf; word < cp; word++) + if (*word != ' ') + break; + if (word >= cp) + return (cp); + for (p = cmdbuf; p < cp; p++) + { + if (meta_quoted) + { + meta_quoted = 0; + } else if (esclen > 0 && p + esclen < cp && + strncmp(p, esc, esclen) == 0) + { + meta_quoted = 1; + p += esclen - 1; + } else if (delim_quoted) + { + if (*p == closequote) + delim_quoted = 0; + } else /* (!delim_quoted) */ + { + if (*p == openquote) + delim_quoted = 1; + else if (*p == ' ') + word = p+1; + } + } +#endif + return (word); +} + +/* + * Set things up to enter completion mode. + * Expand the word under the cursor into a list of filenames + * which start with that word, and set tk_text to that list. + */ +static void init_compl(void) +{ + char *word; + char c; + + /* + * Get rid of any previous tk_text. + */ + if (tk_text != NULL) + { + free(tk_text); + tk_text = NULL; + } + /* + * Find the original (uncompleted) word in the command buffer. + */ + word = delimit_word(); + if (word == NULL) + return; + /* + * Set the insertion point to the point in the command buffer + * where the original (uncompleted) word now sits. + */ + tk_ipoint = word; + /* + * Save the original (uncompleted) word + */ + if (tk_original != NULL) + free(tk_original); + tk_original = (char *) ecalloc(cp-word+1, sizeof(char)); + strncpy(tk_original, word, cp-word); + /* + * Get the expanded filename. + * This may result in a single filename, or + * a blank-separated list of filenames. + */ + c = *cp; + *cp = '\0'; + if (*word != openquote) + { + tk_text = fcomplete(word); + } else + { +#if MSDOS_COMPILER + char *qword = NULL; +#else + char *qword = shell_quote(word+1); +#endif + if (qword == NULL) + tk_text = fcomplete(word+1); + else + { + tk_text = fcomplete(qword); + free(qword); + } + } + *cp = c; +} + +/* + * Return the next word in the current completion list. + */ +static char * next_compl(int action, char *prev) +{ + switch (action) + { + case EC_F_COMPLETE: + return (forw_textlist(&tk_tlist, prev)); + case EC_B_COMPLETE: + return (back_textlist(&tk_tlist, prev)); + } + /* Cannot happen */ + return ("?"); +} + +/* + * Complete the filename before (or under) the cursor. + * cmd_complete may be called multiple times. The global in_completion + * remembers whether this call is the first time (create the list), + * or a subsequent time (step thru the list). + */ +static int cmd_complete(int action) +{ + char *s; + + if (!in_completion || action == EC_EXPAND) + { + /* + * Expand the word under the cursor and + * use the first word in the expansion + * (or the entire expansion if we're doing EC_EXPAND). + */ + init_compl(); + if (tk_text == NULL) + { + bell(); + return (CC_OK); + } + if (action == EC_EXPAND) + { + /* + * Use the whole list. + */ + tk_trial = tk_text; + } else + { + /* + * Use the first filename in the list. + */ + in_completion = 1; + init_textlist(&tk_tlist, tk_text); + tk_trial = next_compl(action, (char*)NULL); + } + } else + { + /* + * We already have a completion list. + * Use the next/previous filename from the list. + */ + tk_trial = next_compl(action, tk_trial); + } + + /* + * Remove the original word, or the previous trial completion. + */ + while (cp > tk_ipoint) + (void) cmd_erase(); + + if (tk_trial == NULL) + { + /* + * There are no more trial completions. + * Insert the original (uncompleted) filename. + */ + in_completion = 0; + if (cmd_istr(tk_original) != CC_OK) + goto fail; + } else + { + /* + * Insert trial completion. + */ + if (cmd_istr(tk_trial) != CC_OK) + goto fail; + /* + * If it is a directory, append a slash. + */ + if (is_dir(tk_trial)) + { + if (cp > cmdbuf && cp[-1] == closequote) + (void) cmd_erase(); + s = lgetenv("LESSSEPARATOR"); + if (s == NULL) + s = PATHNAME_SEP; + if (cmd_istr(s) != CC_OK) + goto fail; + } + } + + return (CC_OK); + +fail: + in_completion = 0; + bell(); + return (CC_OK); +} + +#endif /* TAB_COMPLETE_FILENAME */ + +/* + * Process a single character of a multi-character command, such as + * a number, or the pattern of a search command. + * Returns: + * CC_OK The char was accepted. + * CC_QUIT The char requests the command to be aborted. + * CC_ERROR The char could not be accepted due to an error. + */ +public int cmd_char(int c) +{ + int action; + int len; + + if (!utf_mode) + { + cmd_mbc_buf[0] = c; + len = 1; + } else + { + /* Perform strict validation in all possible cases. */ + if (cmd_mbc_buf_len == 0) + { + retry: + cmd_mbc_buf_index = 1; + *cmd_mbc_buf = c; + if (IS_ASCII_OCTET(c)) + cmd_mbc_buf_len = 1; +#if MSDOS_COMPILER || OS2 + else if (c == (unsigned char) '\340' && IS_ASCII_OCTET(peekcc())) + { + /* Assume a special key. */ + cmd_mbc_buf_len = 1; + } +#endif + else if (IS_UTF8_LEAD(c)) + { + cmd_mbc_buf_len = utf_len(c); + return (CC_OK); + } else + { + /* UTF8_INVALID or stray UTF8_TRAIL */ + bell(); + return (CC_ERROR); + } + } else if (IS_UTF8_TRAIL(c)) + { + cmd_mbc_buf[cmd_mbc_buf_index++] = c; + if (cmd_mbc_buf_index < cmd_mbc_buf_len) + return (CC_OK); + if (!is_utf8_well_formed(cmd_mbc_buf, cmd_mbc_buf_index)) + { + /* complete, but not well formed (non-shortest form), sequence */ + cmd_mbc_buf_len = 0; + bell(); + return (CC_ERROR); + } + } else + { + /* Flush incomplete (truncated) sequence. */ + cmd_mbc_buf_len = 0; + bell(); + /* Handle new char. */ + goto retry; + } + + len = cmd_mbc_buf_len; + cmd_mbc_buf_len = 0; + } + + if (literal) + { + /* + * Insert the char, even if it is a line-editing char. + */ + literal = 0; + return (cmd_ichar(cmd_mbc_buf, len)); + } + + /* + * See if it is a line-editing character. + */ + if (in_mca() && len == 1) + { + action = cmd_edit(c); + switch (action) + { + case CC_OK: + case CC_QUIT: + return (action); + case CC_PASS: + break; + } + } + + /* + * Insert the char into the command buffer. + */ + return (cmd_ichar(cmd_mbc_buf, len)); +} + +/* + * Return the number currently in the command buffer. + */ +public LINENUM cmd_int(long *frac) +{ + char *p; + LINENUM n = 0; + int err; + + for (p = cmdbuf; *p >= '0' && *p <= '9'; p++) + { + if (ckd_mul(&n, n, 10) || ckd_add(&n, n, *p - '0')) + { + error("Integer is too big", NULL_PARG); + return (0); + } + } + *frac = 0; + if (*p++ == '.') + { + *frac = getfraction(&p, NULL, &err); + /* {{ do something if err is set? }} */ + } + return (n); +} + +/* + * Return a pointer to the command buffer. + */ +public char * get_cmdbuf(void) +{ + if (cmd_mbc_buf_index < cmd_mbc_buf_len) + /* Don't return buffer containing an incomplete multibyte char. */ + return (NULL); + return (cmdbuf); +} + +#if CMD_HISTORY +/* + * Return the last (most recent) string in the current command history. + */ +public char * cmd_lastpattern(void) +{ + if (curr_mlist == NULL) + return (NULL); + return (curr_mlist->curr_mp->prev->string); +} +#endif + +#if CMD_HISTORY +/* + */ +static int mlist_size(struct mlist *ml) +{ + int size = 0; + for (ml = ml->next; ml->string != NULL; ml = ml->next) + ++size; + return size; +} + +/* + * Get the name of the history file. + */ +static char * histfile_find(int must_exist) +{ + char *home = lgetenv("HOME"); + char *name = NULL; + + /* Try in $XDG_STATE_HOME, then in $HOME/.local/state, then in $XDG_DATA_HOME, then in $HOME. */ +#if OS2 + if (isnullenv(home)) + home = lgetenv("INIT"); +#endif + name = dirfile(lgetenv("XDG_STATE_HOME"), &LESSHISTFILE[1], must_exist); + if (name == NULL) + { + char *dir = dirfile(home, ".local/state", 1); + if (dir != NULL) + { + name = dirfile(dir, &LESSHISTFILE[1], must_exist); + free(dir); + } + } + if (name == NULL) + name = dirfile(lgetenv("XDG_DATA_HOME"), &LESSHISTFILE[1], must_exist); + if (name == NULL) + name = dirfile(home, LESSHISTFILE, must_exist); + return (name); +} + +static char * histfile_name(int must_exist) +{ + char *name; + + /* See if filename is explicitly specified by $LESSHISTFILE. */ + name = lgetenv("LESSHISTFILE"); + if (!isnullenv(name)) + { + if (strcmp(name, "-") == 0 || strcmp(name, "/dev/null") == 0) + /* $LESSHISTFILE == "-" means don't use a history file. */ + return (NULL); + return (save(name)); + } + + /* See if history file is disabled in the build. */ + if (strcmp(LESSHISTFILE, "") == 0 || strcmp(LESSHISTFILE, "-") == 0) + return (NULL); + + name = NULL; + if (!must_exist) + { + /* If we're writing the file and the file already exists, use it. */ + name = histfile_find(1); + } + if (name == NULL) + name = histfile_find(must_exist); + return (name); +} + +/* + * Read a .lesshst file and call a callback for each line in the file. + */ +static void read_cmdhist2(void (*action)(void*,struct mlist*,char*), void *uparam, int skip_search, int skip_shell) +{ + struct mlist *ml = NULL; + char line[CMDBUF_SIZE]; + char *filename; + FILE *f; + char *p; + int *skip = NULL; + + filename = histfile_name(1); + if (filename == NULL) + return; + f = fopen(filename, "r"); + free(filename); + if (f == NULL) + return; + if (fgets(line, sizeof(line), f) == NULL || + strncmp(line, HISTFILE_FIRST_LINE, strlen(HISTFILE_FIRST_LINE)) != 0) + { + fclose(f); + return; + } + while (fgets(line, sizeof(line), f) != NULL) + { + for (p = line; *p != '\0'; p++) + { + if (*p == '\n' || *p == '\r') + { + *p = '\0'; + break; + } + } + if (strcmp(line, HISTFILE_SEARCH_SECTION) == 0) + { + ml = &mlist_search; + skip = &skip_search; + } else if (strcmp(line, HISTFILE_SHELL_SECTION) == 0) + { +#if SHELL_ESCAPE || PIPEC + ml = &mlist_shell; + skip = &skip_shell; +#else + ml = NULL; + skip = NULL; +#endif + } else if (strcmp(line, HISTFILE_MARK_SECTION) == 0) + { + ml = NULL; + } else if (*line == '"') + { + if (ml != NULL) + { + if (skip != NULL && *skip > 0) + --(*skip); + else + (*action)(uparam, ml, line+1); + } + } else if (*line == 'm') + { + (*action)(uparam, NULL, line); + } + } + fclose(f); +} + +static void read_cmdhist(void (*action)(void*,struct mlist*,char*), void *uparam, int skip_search, int skip_shell) +{ + if (secure) + return; + read_cmdhist2(action, uparam, skip_search, skip_shell); + (*action)(uparam, NULL, NULL); /* signal end of file */ +} + +static void addhist_init(void *uparam, struct mlist *ml, char *string) +{ + if (ml != NULL) + cmd_addhist(ml, string, 0); + else if (string != NULL) + restore_mark((char*)string); /* stupid const cast */ +} +#endif /* CMD_HISTORY */ + +/* + * Initialize history from a .lesshist file. + */ +public void init_cmdhist(void) +{ +#if CMD_HISTORY + read_cmdhist(&addhist_init, NULL, 0, 0); +#endif /* CMD_HISTORY */ +} + +/* + * Write the header for a section of the history file. + */ +#if CMD_HISTORY +static void write_mlist_header(struct mlist *ml, FILE *f) +{ + if (ml == &mlist_search) + fprintf(f, "%s\n", HISTFILE_SEARCH_SECTION); +#if SHELL_ESCAPE || PIPEC + else if (ml == &mlist_shell) + fprintf(f, "%s\n", HISTFILE_SHELL_SECTION); +#endif +} + +/* + * Write all modified entries in an mlist to the history file. + */ +static void write_mlist(struct mlist *ml, FILE *f) +{ + for (ml = ml->next; ml->string != NULL; ml = ml->next) + { + if (!ml->modified) + continue; + fprintf(f, "\"%s\n", ml->string); + ml->modified = 0; + } + ml->modified = 0; /* entire mlist is now unmodified */ +} + +/* + * Make a temp name in the same directory as filename. + */ +static char * make_tempname(char *filename) +{ + char lastch; + char *tempname = ecalloc(1, strlen(filename)+1); + strcpy(tempname, filename); + lastch = tempname[strlen(tempname)-1]; + tempname[strlen(tempname)-1] = (lastch == 'Q') ? 'Z' : 'Q'; + return tempname; +} + +struct save_ctx +{ + struct mlist *mlist; + FILE *fout; +}; + +/* + * Copy entries from the saved history file to a new file. + * At the end of each mlist, append any new entries + * created during this session. + */ +static void copy_hist(void *uparam, struct mlist *ml, char *string) +{ + struct save_ctx *ctx = (struct save_ctx *) uparam; + + if (ml != NULL && ml != ctx->mlist) { + /* We're changing mlists. */ + if (ctx->mlist) + /* Append any new entries to the end of the current mlist. */ + write_mlist(ctx->mlist, ctx->fout); + /* Write the header for the new mlist. */ + ctx->mlist = ml; + write_mlist_header(ctx->mlist, ctx->fout); + } + + if (string == NULL) /* End of file */ + { + /* Write any sections that were not in the original file. */ + if (mlist_search.modified) + { + write_mlist_header(&mlist_search, ctx->fout); + write_mlist(&mlist_search, ctx->fout); + } +#if SHELL_ESCAPE || PIPEC + if (mlist_shell.modified) + { + write_mlist_header(&mlist_shell, ctx->fout); + write_mlist(&mlist_shell, ctx->fout); + } +#endif + } else if (ml != NULL) + { + /* Copy mlist entry. */ + fprintf(ctx->fout, "\"%s\n", string); + } + /* Skip marks */ +} +#endif /* CMD_HISTORY */ + +/* + * Make a file readable only by its owner. + */ +static void make_file_private(FILE *f) +{ +#if HAVE_FCHMOD + int do_chmod = 1; +#if HAVE_STAT + struct stat statbuf; + int r = fstat(fileno(f), &statbuf); + if (r < 0 || !S_ISREG(statbuf.st_mode)) + /* Don't chmod if not a regular file. */ + do_chmod = 0; +#endif + if (do_chmod) + fchmod(fileno(f), 0600); +#endif +} + +/* + * Does the history file need to be updated? + */ +#if CMD_HISTORY +static int histfile_modified(void) +{ + if (mlist_search.modified) + return 1; +#if SHELL_ESCAPE || PIPEC + if (mlist_shell.modified) + return 1; +#endif + if (marks_modified) + return 1; + return 0; +} +#endif + +/* + * Update the .lesshst file. + */ +public void save_cmdhist(void) +{ +#if CMD_HISTORY + char *histname; + char *tempname; + int skip_search; + int skip_shell; + struct save_ctx ctx; + char *s; + FILE *fout = NULL; + int histsize = 0; + + if (secure || !histfile_modified()) + return; + histname = histfile_name(0); + if (histname == NULL) + return; + tempname = make_tempname(histname); + fout = fopen(tempname, "w"); + if (fout != NULL) + { + make_file_private(fout); + s = lgetenv("LESSHISTSIZE"); + if (s != NULL) + histsize = atoi(s); + if (histsize <= 0) + histsize = 100; + skip_search = mlist_size(&mlist_search) - histsize; +#if SHELL_ESCAPE || PIPEC + skip_shell = mlist_size(&mlist_shell) - histsize; +#endif + fprintf(fout, "%s\n", HISTFILE_FIRST_LINE); + ctx.fout = fout; + ctx.mlist = NULL; + read_cmdhist(©_hist, &ctx, skip_search, skip_shell); + save_marks(fout, HISTFILE_MARK_SECTION); + fclose(fout); +#if MSDOS_COMPILER==WIN32C + /* + * Windows rename doesn't remove an existing file, + * making it useless for atomic operations. Sigh. + */ + remove(histname); +#endif + rename(tempname, histname); + } + free(tempname); + free(histname); +#endif /* CMD_HISTORY */ +} diff --git a/third_party/less/command.c b/third_party/less/command.c new file mode 100644 index 000000000..b22c811a2 --- /dev/null +++ b/third_party/less/command.c @@ -0,0 +1,2090 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * User-level command processor. + */ + +#include "less.h" +#if MSDOS_COMPILER==WIN32C +/* #include */ +#endif +#include "position.h" +#include "option.h" +#include "cmd.h" + +extern int erase_char, erase2_char, kill_char; +extern int sigs; +extern int quit_if_one_screen; +extern int one_screen; +extern int squished; +extern int sc_width; +extern int sc_height; +extern char *kent; +extern int swindow; +extern int jump_sline; +extern int quitting; +extern int wscroll; +extern int top_scroll; +extern int ignore_eoi; +extern int secure; +extern int hshift; +extern int bs_mode; +extern int proc_backspace; +extern int show_attn; +extern int status_col; +extern POSITION highest_hilite; +extern POSITION start_attnpos; +extern POSITION end_attnpos; +extern char *every_first_cmd; +extern char version[]; +extern struct scrpos initial_scrpos; +extern IFILE curr_ifile; +extern void *ml_search; +extern void *ml_examine; +extern int wheel_lines; +extern int header_lines; +extern int def_search_type; +extern int updown_match; +#if SHELL_ESCAPE || PIPEC +extern void *ml_shell; +#endif +#if EDITOR +extern char *editor; +extern char *editproto; +#endif +extern int screen_trashed; /* The screen has been overwritten */ +extern int shift_count; +extern int oldbot; +extern int forw_prompt; +extern int incr_search; +extern int full_screen; +#if MSDOS_COMPILER==WIN32C +extern int utf_mode; +#endif + +#if SHELL_ESCAPE +static char *shellcmd = NULL; /* For holding last shell command for "!!" */ +#endif +static int mca; /* The multicharacter command (action) */ +static int search_type; /* The previous type of search */ +static int last_search_type; /* Type of last executed search */ +static LINENUM number; /* The number typed by the user */ +static long fraction; /* The fractional part of the number */ +static struct loption *curropt; +static int opt_lower; +static int optflag; +static int optgetname; +static POSITION bottompos; +static int save_hshift; +static int save_bs_mode; +static int save_proc_backspace; +#if PIPEC +static char pipec; +#endif + +/* Stack of ungotten chars (via ungetcc) */ +struct ungot { + struct ungot *ug_next; + LWCHAR ug_char; +}; +static struct ungot* ungot = NULL; + +static void multi_search (char *pattern, int n, int silent); + +/* + * Move the cursor to start of prompt line before executing a command. + * This looks nicer if the command takes a long time before + * updating the screen. + */ +static void cmd_exec(void) +{ + clear_attn(); + clear_bot(); + flush(); +} + +/* + * Indicate we are reading a multi-character command. + */ +static void set_mca(int action) +{ + mca = action; + clear_bot(); + clear_cmd(); +} + +/* + * Indicate we are not reading a multi-character command. + */ +static void clear_mca(void) +{ + if (mca == 0) + return; + mca = 0; +} + +/* + * Set up the display to start a new multi-character command. + */ +static void start_mca(int action, constant char *prompt, void *mlist, int cmdflags) +{ + set_mca(action); + cmd_putstr(prompt); + set_mlist(mlist, cmdflags); +} + +public int in_mca(void) +{ + return (mca != 0 && mca != A_PREFIX); +} + +/* + * Set up the display to start a new search command. + */ +static void mca_search1(void) +{ + int i; + +#if HILITE_SEARCH + if (search_type & SRCH_FILTER) + set_mca(A_FILTER); + else +#endif + if (search_type & SRCH_FORW) + set_mca(A_F_SEARCH); + else + set_mca(A_B_SEARCH); + + if (search_type & SRCH_NO_MATCH) + cmd_putstr("Non-match "); + if (search_type & SRCH_FIRST_FILE) + cmd_putstr("First-file "); + if (search_type & SRCH_PAST_EOF) + cmd_putstr("EOF-ignore "); + if (search_type & SRCH_NO_MOVE) + cmd_putstr("Keep-pos "); + if (search_type & SRCH_NO_REGEX) + cmd_putstr("Regex-off "); + if (search_type & SRCH_WRAP) + cmd_putstr("Wrap "); + for (i = 1; i <= NUM_SEARCH_COLORS; i++) + { + if (search_type & SRCH_SUBSEARCH(i)) + { + char buf[INT_STRLEN_BOUND(int)+8]; + SNPRINTF1(buf, sizeof(buf), "Sub-%d ", i); + cmd_putstr(buf); + } + } + +#if HILITE_SEARCH + if (search_type & SRCH_FILTER) + cmd_putstr("&/"); + else +#endif + if (search_type & SRCH_FORW) + cmd_putstr("/"); + else + cmd_putstr("?"); + forw_prompt = 0; +} + +static void mca_search(void) +{ + mca_search1(); + set_mlist(ml_search, 0); +} + +/* + * Set up the display to start a new toggle-option command. + */ +static void mca_opt_toggle(void) +{ + int no_prompt; + int flag; + char *dash; + + no_prompt = (optflag & OPT_NO_PROMPT); + flag = (optflag & ~OPT_NO_PROMPT); + dash = (flag == OPT_NO_TOGGLE) ? "_" : "-"; + + set_mca(A_OPT_TOGGLE); + cmd_putstr(dash); + if (optgetname) + cmd_putstr(dash); + if (no_prompt) + cmd_putstr("(P)"); + switch (flag) + { + case OPT_UNSET: + cmd_putstr("+"); + break; + case OPT_SET: + cmd_putstr("!"); + break; + } + forw_prompt = 0; + set_mlist(NULL, 0); +} + +/* + * Execute a multicharacter command. + */ +static void exec_mca(void) +{ + char *cbuf; + + cmd_exec(); + cbuf = get_cmdbuf(); + if (cbuf == NULL) + return; + + switch (mca) + { + case A_F_SEARCH: + case A_B_SEARCH: + multi_search(cbuf, (int) number, 0); + break; +#if HILITE_SEARCH + case A_FILTER: + search_type ^= SRCH_NO_MATCH; + set_filter_pattern(cbuf, search_type); + break; +#endif + case A_FIRSTCMD: + /* + * Skip leading spaces or + signs in the string. + */ + while (*cbuf == '+' || *cbuf == ' ') + cbuf++; + if (every_first_cmd != NULL) + free(every_first_cmd); + if (*cbuf == '\0') + every_first_cmd = NULL; + else + every_first_cmd = save(cbuf); + break; + case A_OPT_TOGGLE: + toggle_option(curropt, opt_lower, cbuf, optflag); + curropt = NULL; + break; + case A_F_BRACKET: + match_brac(cbuf[0], cbuf[1], 1, (int) number); + break; + case A_B_BRACKET: + match_brac(cbuf[1], cbuf[0], 0, (int) number); + break; +#if EXAMINE + case A_EXAMINE: + if (secure) + break; + edit_list(cbuf); +#if TAGS + /* If tag structure is loaded then clean it up. */ + cleantags(); +#endif + break; +#endif +#if SHELL_ESCAPE + case A_SHELL: + /* + * !! just uses whatever is in shellcmd. + * Otherwise, copy cmdbuf to shellcmd, + * expanding any special characters ("%" or "#"). + */ + if (*cbuf != '!') + { + if (shellcmd != NULL) + free(shellcmd); + shellcmd = fexpand(cbuf); + } + + if (secure) + break; + if (shellcmd == NULL) + lsystem("", "!done"); + else + lsystem(shellcmd, "!done"); + break; + case A_PSHELL: + if (secure) + break; + lsystem(pr_expand(cbuf), "#done"); + break; +#endif +#if PIPEC + case A_PIPE: + if (secure) + break; + (void) pipe_mark(pipec, cbuf); + error("|done", NULL_PARG); + break; +#endif + } +} + +/* + * Is a character an erase or kill char? + */ +static int is_erase_char(int c) +{ + return (c == erase_char || c == erase2_char || c == kill_char); +} + +/* + * Is a character a carriage return or newline? + */ +static int is_newline_char(int c) +{ + return (c == '\n' || c == '\r'); +} + +/* + * Handle the first char of an option (after the initial dash). + */ +static int mca_opt_first_char(int c) +{ + int no_prompt = (optflag & OPT_NO_PROMPT); + int flag = (optflag & ~OPT_NO_PROMPT); + if (flag == OPT_NO_TOGGLE) + { + switch (c) + { + case '_': + /* "__" = long option name. */ + optgetname = TRUE; + mca_opt_toggle(); + return (MCA_MORE); + } + } else + { + switch (c) + { + case '+': + /* "-+" = UNSET. */ + optflag = no_prompt | ((flag == OPT_UNSET) ? + OPT_TOGGLE : OPT_UNSET); + mca_opt_toggle(); + return (MCA_MORE); + case '!': + /* "-!" = SET */ + optflag = no_prompt | ((flag == OPT_SET) ? + OPT_TOGGLE : OPT_SET); + mca_opt_toggle(); + return (MCA_MORE); + case CONTROL('P'): + optflag ^= OPT_NO_PROMPT; + mca_opt_toggle(); + return (MCA_MORE); + case '-': + /* "--" = long option name. */ + optgetname = TRUE; + mca_opt_toggle(); + return (MCA_MORE); + } + } + /* Char was not handled here. */ + return (NO_MCA); +} + +/* + * Add a char to a long option name. + * See if we've got a match for an option name yet. + * If so, display the complete name and stop + * accepting chars until user hits RETURN. + */ +static int mca_opt_nonfirst_char(int c) +{ + char *p; + char *oname; + int err; + + if (curropt != NULL) + { + /* + * Already have a match for the name. + * Don't accept anything but erase/kill. + */ + if (is_erase_char(c)) + return (MCA_DONE); + return (MCA_MORE); + } + /* + * Add char to cmd buffer and try to match + * the option name. + */ + if (cmd_char(c) == CC_QUIT) + return (MCA_DONE); + p = get_cmdbuf(); + if (p == NULL) + return (MCA_MORE); + opt_lower = ASCII_IS_LOWER(p[0]); + err = 0; + curropt = findopt_name(&p, &oname, &err); + if (curropt != NULL) + { + /* + * Got a match. + * Remember the option and + * display the full option name. + */ + cmd_reset(); + mca_opt_toggle(); + for (p = oname; *p != '\0'; p++) + { + c = *p; + if (!opt_lower && ASCII_IS_LOWER(c)) + c = ASCII_TO_UPPER(c); + if (cmd_char(c) != CC_OK) + return (MCA_DONE); + } + } else if (err != OPT_AMBIG) + { + bell(); + } + return (MCA_MORE); +} + +/* + * Handle a char of an option toggle command. + */ +static int mca_opt_char(int c) +{ + PARG parg; + + /* + * This may be a short option (single char), + * or one char of a long option name, + * or one char of the option parameter. + */ + if (curropt == NULL && len_cmdbuf() == 0) + { + int ret = mca_opt_first_char(c); + if (ret != NO_MCA) + return (ret); + } + if (optgetname) + { + /* We're getting a long option name. */ + if (!is_newline_char(c) && c != '=') + return (mca_opt_nonfirst_char(c)); + if (curropt == NULL) + { + parg.p_string = get_cmdbuf(); + if (parg.p_string == NULL) + return (MCA_MORE); + error("There is no --%s option", &parg); + return (MCA_DONE); + } + optgetname = FALSE; + cmd_reset(); + } else + { + if (is_erase_char(c)) + return (NO_MCA); + if (curropt != NULL) + /* We're getting the option parameter. */ + return (NO_MCA); + curropt = findopt(c); + if (curropt == NULL) + { + parg.p_string = propt(c); + error("There is no %s option", &parg); + return (MCA_DONE); + } + opt_lower = ASCII_IS_LOWER(c); + } + /* + * If the option which was entered does not take a + * parameter, toggle the option immediately, + * so user doesn't have to hit RETURN. + */ + if ((optflag & ~OPT_NO_PROMPT) != OPT_TOGGLE || + !opt_has_param(curropt)) + { + toggle_option(curropt, opt_lower, "", optflag); + return (MCA_DONE); + } + /* + * Display a prompt appropriate for the option parameter. + */ + start_mca(A_OPT_TOGGLE, opt_prompt(curropt), (void*)NULL, 0); + return (MCA_MORE); +} + +/* + * Normalize search type. + */ +public int norm_search_type(int st) +{ + /* WRAP and PAST_EOF are mutually exclusive. */ + if ((st & (SRCH_PAST_EOF|SRCH_WRAP)) == (SRCH_PAST_EOF|SRCH_WRAP)) + st ^= SRCH_PAST_EOF; + return st; +} + +/* + * Handle a char of a search command. + */ +static int mca_search_char(int c) +{ + int flag = 0; + + /* + * Certain characters as the first char of + * the pattern have special meaning: + * ! Toggle the NO_MATCH flag + * * Toggle the PAST_EOF flag + * @ Toggle the FIRST_FILE flag + */ + if (len_cmdbuf() > 0) + return (NO_MCA); + + switch (c) + { + case CONTROL('E'): /* ignore END of file */ + case '*': + if (mca != A_FILTER) + flag = SRCH_PAST_EOF; + search_type &= ~SRCH_WRAP; + break; + case CONTROL('F'): /* FIRST file */ + case '@': + if (mca != A_FILTER) + flag = SRCH_FIRST_FILE; + break; + case CONTROL('K'): /* KEEP position */ + if (mca != A_FILTER) + flag = SRCH_NO_MOVE; + break; + case CONTROL('S'): { /* SUBSEARCH */ + char buf[INT_STRLEN_BOUND(int)+24]; + SNPRINTF1(buf, sizeof(buf), "Sub-pattern (1-%d):", NUM_SEARCH_COLORS); + clear_bot(); + cmd_putstr(buf); + flush(); + c = getcc(); + if (c >= '1' && c <= '0'+NUM_SEARCH_COLORS) + flag = SRCH_SUBSEARCH(c-'0'); + else + flag = -1; /* calls mca_search() below to repaint */ + break; } + case CONTROL('W'): /* WRAP around */ + if (mca != A_FILTER) + flag = SRCH_WRAP; + break; + case CONTROL('R'): /* Don't use REGULAR EXPRESSIONS */ + flag = SRCH_NO_REGEX; + break; + case CONTROL('N'): /* NOT match */ + case '!': + flag = SRCH_NO_MATCH; + break; + } + + if (flag != 0) + { + if (flag != -1) + search_type = norm_search_type(search_type ^ flag); + mca_search(); + return (MCA_MORE); + } + return (NO_MCA); +} + +/* + * Handle a character of a multi-character command. + */ +static int mca_char(int c) +{ + int ret; + + switch (mca) + { + case 0: + /* + * We're not in a multicharacter command. + */ + return (NO_MCA); + + case A_PREFIX: + /* + * In the prefix of a command. + * This not considered a multichar command + * (even tho it uses cmdbuf, etc.). + * It is handled in the commands() switch. + */ + return (NO_MCA); + + case A_DIGIT: + /* + * Entering digits of a number. + * Terminated by a non-digit. + */ + if ((c >= '0' && c <= '9') || c == '.') + break; + switch (editchar(c, ECF_PEEK|ECF_NOHISTORY|ECF_NOCOMPLETE|ECF_NORIGHTLEFT)) + { + case A_NOACTION: + /* + * Ignore this char and get another one. + */ + return (MCA_MORE); + case A_INVALID: + /* + * Not part of the number. + * End the number and treat this char + * as a normal command character. + */ + number = cmd_int(&fraction); + clear_mca(); + cmd_accept(); + return (NO_MCA); + } + break; + + case A_OPT_TOGGLE: + ret = mca_opt_char(c); + if (ret != NO_MCA) + return (ret); + break; + + case A_F_SEARCH: + case A_B_SEARCH: + case A_FILTER: + ret = mca_search_char(c); + if (ret != NO_MCA) + return (ret); + break; + + default: + /* Other multicharacter command. */ + break; + } + + /* + * The multichar command is terminated by a newline. + */ + if (is_newline_char(c)) + { + /* + * Execute the command. + */ + exec_mca(); + return (MCA_DONE); + } + + /* + * Append the char to the command buffer. + */ + if (cmd_char(c) == CC_QUIT) + /* + * Abort the multi-char command. + */ + return (MCA_DONE); + + switch (mca) + { + case A_F_BRACKET: + case A_B_BRACKET: + if (len_cmdbuf() >= 2) + { + /* + * Special case for the bracket-matching commands. + * Execute the command after getting exactly two + * characters from the user. + */ + exec_mca(); + return (MCA_DONE); + } + break; + case A_F_SEARCH: + case A_B_SEARCH: + if (incr_search) + { + /* Incremental search: do a search after every input char. */ + int st = (search_type & (SRCH_FORW|SRCH_BACK|SRCH_NO_MATCH|SRCH_NO_REGEX|SRCH_NO_MOVE|SRCH_WRAP|SRCH_SUBSEARCH_ALL)); + char *pattern = get_cmdbuf(); + if (pattern == NULL) + return (MCA_MORE); + /* + * Must save updown_match because mca_search + * reinits it. That breaks history scrolling. + * {{ This is ugly. mca_search probably shouldn't call set_mlist. }} + */ + int save_updown_match = updown_match; + cmd_exec(); + if (*pattern == '\0') + { + /* User has backspaced to an empty pattern. */ + undo_search(1); + } else + { + if (search(st | SRCH_INCR, pattern, 1) != 0) + /* No match, invalid pattern, etc. */ + undo_search(1); + } + /* Redraw the search prompt and search string. */ + if (!full_screen) + { + clear(); + repaint(); + } + mca_search1(); + updown_match = save_updown_match; + cmd_repaint(NULL); + } + break; + } + + /* + * Need another character. + */ + return (MCA_MORE); +} + +/* + * Discard any buffered file data. + */ +static void clear_buffers(void) +{ + if (!(ch_getflags() & CH_CANSEEK)) + return; + ch_flush(); + clr_linenum(); +#if HILITE_SEARCH + clr_hilite(); +#endif +} + +/* + * Make sure the screen is displayed. + */ +static void make_display(void) +{ + /* + * If not full_screen, we can't rely on scrolling to fill the screen. + * We need to clear and repaint screen before any change. + */ + if (!full_screen && !(quit_if_one_screen && one_screen)) + clear(); + /* + * If nothing is displayed yet, display starting from initial_scrpos. + */ + if (empty_screen()) + { + if (initial_scrpos.pos == NULL_POSITION) + jump_loc(ch_zero(), 1); + else + jump_loc(initial_scrpos.pos, initial_scrpos.ln); + } else if (screen_trashed || !full_screen) + { + int save_top_scroll = top_scroll; + int save_ignore_eoi = ignore_eoi; + top_scroll = 1; + ignore_eoi = 0; + if (screen_trashed == 2) + { + /* Special case used by ignore_eoi: re-open the input file + * and jump to the end of the file. */ + reopen_curr_ifile(); + jump_forw(); + } + repaint(); + top_scroll = save_top_scroll; + ignore_eoi = save_ignore_eoi; + } +} + +/* + * Display the appropriate prompt. + */ +static void prompt(void) +{ + constant char *p; + + if (ungot != NULL && ungot->ug_char != CHAR_END_COMMAND) + { + /* + * No prompt necessary if commands are from + * ungotten chars rather than from the user. + */ + return; + } + + /* + * Make sure the screen is displayed. + */ + make_display(); + bottompos = position(BOTTOM_PLUS_ONE); + + /* + * If we've hit EOF on the last file and the -E flag is set, quit. + */ + if (get_quit_at_eof() == OPT_ONPLUS && + eof_displayed() && !(ch_getflags() & CH_HELPFILE) && + next_ifile(curr_ifile) == NULL_IFILE) + quit(QUIT_OK); + + /* + * If the entire file is displayed and the -F flag is set, quit. + */ + if (quit_if_one_screen && + entire_file_displayed() && !(ch_getflags() & CH_HELPFILE) && + next_ifile(curr_ifile) == NULL_IFILE) + quit(QUIT_OK); + quit_if_one_screen = FALSE; /* only get one chance at this */ + +#if MSDOS_COMPILER==WIN32C + /* + * In Win32, display the file name in the window title. + */ + if (!(ch_getflags() & CH_HELPFILE)) + { + WCHAR w[MAX_PATH+16]; + p = pr_expand("Less?f - %f."); + MultiByteToWideChar(CP_ACP, 0, p, -1, w, sizeof(w)/sizeof(*w)); + SetConsoleTitleW(w); + } +#endif + + /* + * Select the proper prompt and display it. + */ + /* + * If the previous action was a forward movement, + * don't clear the bottom line of the display; + * just print the prompt since the forward movement guarantees + * that we're in the right position to display the prompt. + * Clearing the line could cause a problem: for example, if the last + * line displayed ended at the right screen edge without a newline, + * then clearing would clear the last displayed line rather than + * the prompt line. + */ + if (!forw_prompt) + clear_bot(); + clear_cmd(); + forw_prompt = 0; + p = pr_string(); +#if HILITE_SEARCH + if (is_filtering()) + putstr("& "); +#endif + if (p == NULL || *p == '\0') + { + at_enter(AT_NORMAL|AT_COLOR_PROMPT); + putchr(':'); + at_exit(); + } else + { +#if MSDOS_COMPILER==WIN32C + WCHAR w[MAX_PATH*2]; + char a[MAX_PATH*2]; + MultiByteToWideChar(CP_ACP, 0, p, -1, w, sizeof(w)/sizeof(*w)); + WideCharToMultiByte(utf_mode ? CP_UTF8 : GetConsoleOutputCP(), + 0, w, -1, a, sizeof(a), NULL, NULL); + p = a; +#endif + load_line(p); + put_line(); + } + clear_eol(); +} + +/* + * Display the less version message. + */ +public void dispversion(void) +{ + PARG parg; + + parg.p_string = version; + error("less %s", &parg); +} + +/* + * Return a character to complete a partial command, if possible. + */ +static LWCHAR getcc_end_command(void) +{ + switch (mca) + { + case A_DIGIT: + /* We have a number but no command. Treat as #g. */ + return ('g'); + case A_F_SEARCH: + case A_B_SEARCH: + case A_FILTER: + /* We have "/string" but no newline. Add the \n. */ + return ('\n'); + default: + /* Some other incomplete command. Let user complete it. */ + return ((ungot == NULL) ? getchr() : 0); + } +} + +/* + * Get command character. + * The character normally comes from the keyboard, + * but may come from ungotten characters + * (characters previously given to ungetcc or ungetsc). + */ +static LWCHAR getccu(void) +{ + LWCHAR c = 0; + while (c == 0) + { + if (ungot == NULL) + { + /* Normal case: no ungotten chars. + * Get char from the user. */ + c = getchr(); + } else + { + /* Ungotten chars available: + * Take the top of stack (most recent). */ + struct ungot *ug = ungot; + c = ug->ug_char; + ungot = ug->ug_next; + free(ug); + + if (c == CHAR_END_COMMAND) + c = getcc_end_command(); + } + } + return (c); +} + +/* + * Get a command character, but if we receive the orig sequence, + * convert it to the repl sequence. + */ +static LWCHAR getcc_repl(char constant *orig, char constant *repl, LWCHAR (*gr_getc)(void), void (*gr_ungetc)(LWCHAR)) +{ + LWCHAR c; + LWCHAR keys[16]; + int ki = 0; + + c = (*gr_getc)(); + if (orig == NULL || orig[0] == '\0') + return c; + for (;;) + { + keys[ki] = c; + if (c != orig[ki] || ki >= sizeof(keys)-1) + { + /* This is not orig we have been receiving. + * If we have stashed chars in keys[], + * unget them and return the first one. */ + while (ki > 0) + (*gr_ungetc)(keys[ki--]); + return keys[0]; + } + if (orig[++ki] == '\0') + { + /* We've received the full orig sequence. + * Return the repl sequence. */ + ki = strlen(repl)-1; + while (ki > 0) + (*gr_ungetc)(repl[ki--]); + return repl[0]; + } + /* We've received a partial orig sequence (ki chars of it). + * Get next char and see if it continues to match orig. */ + c = (*gr_getc)(); + } +} + +/* + * Get command character. + */ +public int getcc(void) +{ + /* Replace kent (keypad Enter) with a newline. */ + return getcc_repl(kent, "\n", getccu, ungetcc); +} + +/* + * "Unget" a command character. + * The next getcc() will return this character. + */ +public void ungetcc(LWCHAR c) +{ + struct ungot *ug = (struct ungot *) ecalloc(1, sizeof(struct ungot)); + + ug->ug_char = c; + ug->ug_next = ungot; + ungot = ug; +} + +/* + * "Unget" a command character. + * If any other chars are already ungotten, put this one after those. + */ +public void ungetcc_back(LWCHAR c) +{ + struct ungot *ug = (struct ungot *) ecalloc(1, sizeof(struct ungot)); + ug->ug_char = c; + ug->ug_next = NULL; + if (ungot == NULL) + ungot = ug; + else + { + struct ungot *pu; + for (pu = ungot; pu->ug_next != NULL; pu = pu->ug_next) + continue; + pu->ug_next = ug; + } +} + +/* + * Unget a whole string of command characters. + * The next sequence of getcc()'s will return this string. + */ +public void ungetsc(char *s) +{ + while (*s != '\0') + ungetcc_back(*s++); +} + +/* + * Peek the next command character, without consuming it. + */ +public LWCHAR peekcc(void) +{ + LWCHAR c = getcc(); + ungetcc(c); + return c; +} + +/* + * Search for a pattern, possibly in multiple files. + * If SRCH_FIRST_FILE is set, begin searching at the first file. + * If SRCH_PAST_EOF is set, continue the search thru multiple files. + */ +static void multi_search(char *pattern, int n, int silent) +{ + int nomore; + IFILE save_ifile; + int changed_file; + + changed_file = 0; + save_ifile = save_curr_ifile(); + + if ((search_type & (SRCH_FORW|SRCH_BACK)) == 0) + search_type |= SRCH_FORW; + if (search_type & SRCH_FIRST_FILE) + { + /* + * Start at the first (or last) file + * in the command line list. + */ + if (search_type & SRCH_FORW) + nomore = edit_first(); + else + nomore = edit_last(); + if (nomore) + { + unsave_ifile(save_ifile); + return; + } + changed_file = 1; + search_type &= ~SRCH_FIRST_FILE; + } + + for (;;) + { + n = search(search_type, pattern, n); + /* + * The SRCH_NO_MOVE flag doesn't "stick": it gets cleared + * after being used once. This allows "n" to work after + * using a /@@ search. + */ + search_type &= ~SRCH_NO_MOVE; + last_search_type = search_type; + if (n == 0) + { + /* + * Found it. + */ + unsave_ifile(save_ifile); + return; + } + + if (n < 0) + /* + * Some kind of error in the search. + * Error message has been printed by search(). + */ + break; + + if ((search_type & SRCH_PAST_EOF) == 0) + /* + * We didn't find a match, but we're + * supposed to search only one file. + */ + break; + /* + * Move on to the next file. + */ + if (search_type & SRCH_FORW) + nomore = edit_next(1); + else + nomore = edit_prev(1); + if (nomore) + break; + changed_file = 1; + } + + /* + * Didn't find it. + * Print an error message if we haven't already. + */ + if (n > 0 && !silent) + error("Pattern not found", NULL_PARG); + + if (changed_file) + { + /* + * Restore the file we were originally viewing. + */ + reedit_ifile(save_ifile); + } else + { + unsave_ifile(save_ifile); + } +} + +/* + * Forward forever, or until a highlighted line appears. + */ +static int forw_loop(int until_hilite) +{ + POSITION curr_len; + + if (ch_getflags() & CH_HELPFILE) + return (A_NOACTION); + + cmd_exec(); + jump_forw_buffered(); + curr_len = ch_length(); + highest_hilite = until_hilite ? curr_len : NULL_POSITION; + ignore_eoi = 1; + while (!sigs) + { + if (until_hilite && highest_hilite > curr_len) + { + bell(); + break; + } + make_display(); + forward(1, 0, 0); + } + ignore_eoi = 0; + ch_set_eof(); + + /* + * This gets us back in "F mode" after processing + * a non-abort signal (e.g. window-change). + */ + if (sigs && !ABORT_SIGS()) + return (until_hilite ? A_F_UNTIL_HILITE : A_F_FOREVER); + + return (A_NOACTION); +} + +/* + * Main command processor. + * Accept and execute commands until a quit command. + */ +public void commands(void) +{ + int c; + int action; + char *cbuf; + int newaction; + int save_jump_sline; + int save_search_type; + char *extra; + char tbuf[2]; + PARG parg; + IFILE old_ifile; + IFILE new_ifile; + char *tagfile; + + search_type = SRCH_FORW; + wscroll = (sc_height + 1) / 2; + newaction = A_NOACTION; + + for (;;) + { + clear_mca(); + cmd_accept(); + number = 0; + curropt = NULL; + + /* + * See if any signals need processing. + */ + if (sigs) + { + psignals(); + if (quitting) + quit(QUIT_SAVED_STATUS); + } + + /* + * See if window size changed, for systems that don't + * generate SIGWINCH. + */ + check_winch(); + + /* + * Display prompt and accept a character. + */ + cmd_reset(); + prompt(); + if (sigs) + continue; + if (newaction == A_NOACTION) + c = getcc(); + + again: + if (sigs) + continue; + + if (newaction != A_NOACTION) + { + action = newaction; + newaction = A_NOACTION; + } else + { + /* + * If we are in a multicharacter command, call mca_char. + * Otherwise we call fcmd_decode to determine the + * action to be performed. + */ + if (mca) + switch (mca_char(c)) + { + case MCA_MORE: + /* + * Need another character. + */ + c = getcc(); + goto again; + case MCA_DONE: + /* + * Command has been handled by mca_char. + * Start clean with a prompt. + */ + continue; + case NO_MCA: + /* + * Not a multi-char command + * (at least, not anymore). + */ + break; + } + + /* + * Decode the command character and decide what to do. + */ + if (mca) + { + /* + * We're in a multichar command. + * Add the character to the command buffer + * and display it on the screen. + * If the user backspaces past the start + * of the line, abort the command. + */ + if (cmd_char(c) == CC_QUIT || len_cmdbuf() == 0) + continue; + cbuf = get_cmdbuf(); + if (cbuf == NULL) + continue; + } else + { + /* + * Don't use cmd_char if we're starting fresh + * at the beginning of a command, because we + * don't want to echo the command until we know + * it is a multichar command. We also don't + * want erase_char/kill_char to be treated + * as line editing characters. + */ + tbuf[0] = c; + tbuf[1] = '\0'; + cbuf = tbuf; + } + extra = NULL; + action = fcmd_decode(cbuf, &extra); + /* + * If an "extra" string was returned, + * process it as a string of command characters. + */ + if (extra != NULL) + ungetsc(extra); + } + /* + * Clear the cmdbuf string. + * (But not if we're in the prefix of a command, + * because the partial command string is kept there.) + */ + if (action != A_PREFIX) + cmd_reset(); + + switch (action) + { + case A_DIGIT: + /* + * First digit of a number. + */ + start_mca(A_DIGIT, ":", (void*)NULL, CF_QUIT_ON_ERASE); + goto again; + + case A_F_WINDOW: + /* + * Forward one window (and set the window size). + */ + if (number > 0) + swindow = (int) number; + /* FALLTHRU */ + case A_F_SCREEN: + /* + * Forward one screen. + */ + if (number <= 0) + number = get_swindow(); + cmd_exec(); + if (show_attn) + set_attnpos(bottompos); + forward((int) number, 0, 1); + break; + + case A_B_WINDOW: + /* + * Backward one window (and set the window size). + */ + if (number > 0) + swindow = (int) number; + /* FALLTHRU */ + case A_B_SCREEN: + /* + * Backward one screen. + */ + if (number <= 0) + number = get_swindow(); + cmd_exec(); + backward((int) number, 0, 1); + break; + + case A_F_LINE: + /* + * Forward N (default 1) line. + */ + if (number <= 0) + number = 1; + cmd_exec(); + if (show_attn == OPT_ONPLUS && number > 1) + set_attnpos(bottompos); + forward((int) number, 0, 0); + break; + + case A_B_LINE: + /* + * Backward N (default 1) line. + */ + if (number <= 0) + number = 1; + cmd_exec(); + backward((int) number, 0, 0); + break; + + case A_F_MOUSE: + /* + * Forward wheel_lines lines. + */ + cmd_exec(); + forward(wheel_lines, 0, 0); + break; + + case A_B_MOUSE: + /* + * Backward wheel_lines lines. + */ + cmd_exec(); + backward(wheel_lines, 0, 0); + break; + + case A_FF_LINE: + /* + * Force forward N (default 1) line. + */ + if (number <= 0) + number = 1; + cmd_exec(); + if (show_attn == OPT_ONPLUS && number > 1) + set_attnpos(bottompos); + forward((int) number, 1, 0); + break; + + case A_BF_LINE: + /* + * Force backward N (default 1) line. + */ + if (number <= 0) + number = 1; + cmd_exec(); + backward((int) number, 1, 0); + break; + + case A_FF_SCREEN: + /* + * Force forward one screen. + */ + if (number <= 0) + number = get_swindow(); + cmd_exec(); + if (show_attn == OPT_ONPLUS) + set_attnpos(bottompos); + forward((int) number, 1, 0); + break; + + case A_F_FOREVER: + /* + * Forward forever, ignoring EOF. + */ + if (show_attn) + set_attnpos(bottompos); + newaction = forw_loop(0); + break; + + case A_F_UNTIL_HILITE: + newaction = forw_loop(1); + break; + + case A_F_SCROLL: + /* + * Forward N lines + * (default same as last 'd' or 'u' command). + */ + if (number > 0) + wscroll = (int) number; + cmd_exec(); + if (show_attn == OPT_ONPLUS) + set_attnpos(bottompos); + forward(wscroll, 0, 0); + break; + + case A_B_SCROLL: + /* + * Forward N lines + * (default same as last 'd' or 'u' command). + */ + if (number > 0) + wscroll = (int) number; + cmd_exec(); + backward(wscroll, 0, 0); + break; + + case A_FREPAINT: + /* + * Flush buffers, then repaint screen. + * Don't flush the buffers on a pipe! + */ + clear_buffers(); + /* FALLTHRU */ + case A_REPAINT: + /* + * Repaint screen. + */ + cmd_exec(); + repaint(); + break; + + case A_GOLINE: + /* + * Go to line N, default beginning of file. + * If N <= 0, ignore jump_sline in order to avoid + * empty lines before the beginning of the file. + */ + save_jump_sline = jump_sline; + if (number <= 0) + { + number = 1; + jump_sline = 0; + } + cmd_exec(); + jump_back(number); + jump_sline = save_jump_sline; + break; + + case A_PERCENT: + /* + * Go to a specified percentage into the file. + */ + if (number < 0) + { + number = 0; + fraction = 0; + } + if (number > 100 || (number == 100 && fraction != 0)) + { + number = 100; + fraction = 0; + } + cmd_exec(); + jump_percent((int) number, fraction); + break; + + case A_GOEND: + /* + * Go to line N, default end of file. + */ + cmd_exec(); + if (number <= 0) + jump_forw(); + else + jump_back(number); + break; + + case A_GOEND_BUF: + /* + * Go to line N, default last buffered byte. + */ + cmd_exec(); + if (number <= 0) + jump_forw_buffered(); + else + jump_back(number); + break; + + case A_GOPOS: + /* + * Go to a specified byte position in the file. + */ + cmd_exec(); + if (number < 0) + number = 0; + jump_line_loc((POSITION) number, jump_sline); + break; + + case A_STAT: + /* + * Print file name, etc. + */ + if (ch_getflags() & CH_HELPFILE) + break; + cmd_exec(); + parg.p_string = eq_message(); + error("%s", &parg); + break; + + case A_VERSION: + /* + * Print version number. + */ + cmd_exec(); + dispversion(); + break; + + case A_QUIT: + /* + * Exit. + */ + if (curr_ifile != NULL_IFILE && + ch_getflags() & CH_HELPFILE) + { + /* + * Quit while viewing the help file + * just means return to viewing the + * previous file. + */ + hshift = save_hshift; + bs_mode = save_bs_mode; + proc_backspace = save_proc_backspace; + if (edit_prev(1) == 0) + break; + } + if (extra != NULL) + quit(*extra); + quit(QUIT_OK); + break; + +/* + * Define abbreviation for a commonly used sequence below. + */ +#define DO_SEARCH() \ + if (number <= 0) number = 1; \ + mca_search(); \ + cmd_exec(); \ + multi_search((char *)NULL, (int) number, 0); + + case A_F_SEARCH: + /* + * Search forward for a pattern. + * Get the first char of the pattern. + */ + search_type = SRCH_FORW | def_search_type; + if (number <= 0) + number = 1; + mca_search(); + c = getcc(); + goto again; + + case A_B_SEARCH: + /* + * Search backward for a pattern. + * Get the first char of the pattern. + */ + search_type = SRCH_BACK | def_search_type; + if (number <= 0) + number = 1; + mca_search(); + c = getcc(); + goto again; + + case A_FILTER: +#if HILITE_SEARCH + search_type = SRCH_FORW | SRCH_FILTER; + mca_search(); + c = getcc(); + goto again; +#else + error("Command not available", NULL_PARG); + break; +#endif + + case A_AGAIN_SEARCH: + /* + * Repeat previous search. + */ + search_type = last_search_type; + DO_SEARCH(); + break; + + case A_T_AGAIN_SEARCH: + /* + * Repeat previous search, multiple files. + */ + search_type = last_search_type | SRCH_PAST_EOF; + DO_SEARCH(); + break; + + case A_REVERSE_SEARCH: + /* + * Repeat previous search, in reverse direction. + */ + save_search_type = search_type = last_search_type; + search_type = SRCH_REVERSE(search_type); + DO_SEARCH(); + last_search_type = save_search_type; + break; + + case A_T_REVERSE_SEARCH: + /* + * Repeat previous search, + * multiple files in reverse direction. + */ + save_search_type = search_type = last_search_type; + search_type = SRCH_REVERSE(search_type) | SRCH_PAST_EOF; + DO_SEARCH(); + last_search_type = save_search_type; + break; + + case A_UNDO_SEARCH: + case A_CLR_SEARCH: + /* + * Clear search string highlighting. + */ + undo_search(action == A_CLR_SEARCH); + break; + + case A_HELP: + /* + * Help. + */ + if (ch_getflags() & CH_HELPFILE) + break; + cmd_exec(); + save_hshift = hshift; + hshift = 0; + save_bs_mode = bs_mode; + bs_mode = BS_SPECIAL; + save_proc_backspace = proc_backspace; + proc_backspace = OPT_OFF; + (void) edit(FAKE_HELPFILE); + break; + + case A_EXAMINE: + /* + * Edit a new file. Get the filename. + */ +#if EXAMINE + if (!secure) + { + start_mca(A_EXAMINE, "Examine: ", ml_examine, 0); + c = getcc(); + goto again; + } +#endif + error("Command not available", NULL_PARG); + break; + + case A_VISUAL: + /* + * Invoke an editor on the input file. + */ +#if EDITOR + if (!secure) + { + if (ch_getflags() & CH_HELPFILE) + break; + if (strcmp(get_filename(curr_ifile), "-") == 0) + { + error("Cannot edit standard input", NULL_PARG); + break; + } + if (get_altfilename(curr_ifile) != NULL) + { + error("WARNING: This file was viewed via LESSOPEN", + NULL_PARG); + } + start_mca(A_SHELL, "!", ml_shell, 0); + /* + * Expand the editor prototype string + * and pass it to the system to execute. + * (Make sure the screen is displayed so the + * expansion of "+%lm" works.) + */ + make_display(); + cmd_exec(); + lsystem(pr_expand(editproto), (char*)NULL); + break; + } +#endif + error("Command not available", NULL_PARG); + break; + + case A_NEXT_FILE: + /* + * Examine next file. + */ +#if TAGS + if (ntags()) + { + error("No next file", NULL_PARG); + break; + } +#endif + if (number <= 0) + number = 1; + if (edit_next((int) number)) + { + if (get_quit_at_eof() && eof_displayed() && + !(ch_getflags() & CH_HELPFILE)) + quit(QUIT_OK); + parg.p_string = (number > 1) ? "(N-th) " : ""; + error("No %snext file", &parg); + } + break; + + case A_PREV_FILE: + /* + * Examine previous file. + */ +#if TAGS + if (ntags()) + { + error("No previous file", NULL_PARG); + break; + } +#endif + if (number <= 0) + number = 1; + if (edit_prev((int) number)) + { + parg.p_string = (number > 1) ? "(N-th) " : ""; + error("No %sprevious file", &parg); + } + break; + + case A_NEXT_TAG: + /* + * Jump to the next tag in the current tag list. + */ +#if TAGS + if (number <= 0) + number = 1; + tagfile = nexttag((int) number); + if (tagfile == NULL) + { + error("No next tag", NULL_PARG); + break; + } + cmd_exec(); + if (edit(tagfile) == 0) + { + POSITION pos = tagsearch(); + if (pos != NULL_POSITION) + jump_loc(pos, jump_sline); + } +#else + error("Command not available", NULL_PARG); +#endif + break; + + case A_PREV_TAG: + /* + * Jump to the previous tag in the current tag list. + */ +#if TAGS + if (number <= 0) + number = 1; + tagfile = prevtag((int) number); + if (tagfile == NULL) + { + error("No previous tag", NULL_PARG); + break; + } + cmd_exec(); + if (edit(tagfile) == 0) + { + POSITION pos = tagsearch(); + if (pos != NULL_POSITION) + jump_loc(pos, jump_sline); + } +#else + error("Command not available", NULL_PARG); +#endif + break; + + case A_INDEX_FILE: + /* + * Examine a particular file. + */ + if (number <= 0) + number = 1; + if (edit_index((int) number)) + error("No such file", NULL_PARG); + break; + + case A_REMOVE_FILE: + /* + * Remove a file from the input file list. + */ + if (ch_getflags() & CH_HELPFILE) + break; + old_ifile = curr_ifile; + new_ifile = getoff_ifile(curr_ifile); + if (new_ifile == NULL_IFILE) + { + bell(); + break; + } + if (edit_ifile(new_ifile) != 0) + { + reedit_ifile(old_ifile); + break; + } + del_ifile(old_ifile); + break; + + case A_OPT_TOGGLE: + /* + * Change the setting of an option. + */ + optflag = OPT_TOGGLE; + optgetname = FALSE; + mca_opt_toggle(); + c = getcc(); + cbuf = opt_toggle_disallowed(c); + if (cbuf != NULL) + { + error(cbuf, NULL_PARG); + break; + } + goto again; + + case A_DISP_OPTION: + /* + * Report the setting of an option. + */ + optflag = OPT_NO_TOGGLE; + optgetname = FALSE; + mca_opt_toggle(); + c = getcc(); + goto again; + + case A_FIRSTCMD: + /* + * Set an initial command for new files. + */ + start_mca(A_FIRSTCMD, "+", (void*)NULL, 0); + c = getcc(); + goto again; + + case A_SHELL: + case A_PSHELL: + /* + * Shell escape. + */ +#if SHELL_ESCAPE + if (!secure) + { + start_mca(action, (action == A_SHELL) ? "!" : "#", ml_shell, 0); + c = getcc(); + goto again; + } +#endif + error("Command not available", NULL_PARG); + break; + + case A_SETMARK: + case A_SETMARKBOT: + /* + * Set a mark. + */ + if (ch_getflags() & CH_HELPFILE) + break; + start_mca(A_SETMARK, "set mark: ", (void*)NULL, 0); + c = getcc(); + if (is_erase_char(c) || is_newline_char(c)) + break; + setmark(c, action == A_SETMARKBOT ? BOTTOM : TOP); + repaint(); + break; + + case A_CLRMARK: + /* + * Clear a mark. + */ + start_mca(A_CLRMARK, "clear mark: ", (void*)NULL, 0); + c = getcc(); + if (is_erase_char(c) || is_newline_char(c)) + break; + clrmark(c); + repaint(); + break; + + case A_GOMARK: + /* + * Jump to a marked position. + */ + start_mca(A_GOMARK, "goto mark: ", (void*)NULL, 0); + c = getcc(); + if (is_erase_char(c) || is_newline_char(c)) + break; + cmd_exec(); + gomark(c); + break; + + case A_PIPE: + /* + * Write part of the input to a pipe to a shell command. + */ +#if PIPEC + if (!secure) + { + start_mca(A_PIPE, "|mark: ", (void*)NULL, 0); + c = getcc(); + if (is_erase_char(c)) + break; + if (is_newline_char(c)) + c = '.'; + if (badmark(c)) + break; + pipec = c; + start_mca(A_PIPE, "!", ml_shell, 0); + c = getcc(); + goto again; + } +#endif + error("Command not available", NULL_PARG); + break; + + case A_B_BRACKET: + case A_F_BRACKET: + start_mca(action, "Brackets: ", (void*)NULL, 0); + c = getcc(); + goto again; + + case A_LSHIFT: + /* + * Shift view left. + */ + if (number > 0) + shift_count = number; + else + number = (shift_count > 0) ? + shift_count : sc_width / 2; + if (number > hshift) + number = hshift; + hshift -= number; + screen_trashed = 1; + break; + + case A_RSHIFT: + /* + * Shift view right. + */ + if (number > 0) + shift_count = number; + else + number = (shift_count > 0) ? + shift_count : sc_width / 2; + hshift += number; + screen_trashed = 1; + break; + + case A_LLSHIFT: + /* + * Shift view left to margin. + */ + hshift = 0; + screen_trashed = 1; + break; + + case A_RRSHIFT: + /* + * Shift view right to view rightmost char on screen. + */ + hshift = rrshift(); + screen_trashed = 1; + break; + + case A_PREFIX: + /* + * The command is incomplete (more chars are needed). + * Display the current char, so the user knows + * what's going on, and get another character. + */ + if (mca != A_PREFIX) + { + cmd_reset(); + start_mca(A_PREFIX, " ", (void*)NULL, + CF_QUIT_ON_ERASE); + (void) cmd_char(c); + } + c = getcc(); + goto again; + + case A_NOACTION: + break; + + default: + bell(); + break; + } + } +} diff --git a/third_party/less/compose.inc b/third_party/less/compose.inc new file mode 100644 index 000000000..d65001693 --- /dev/null +++ b/third_party/less/compose.inc @@ -0,0 +1,355 @@ +/* Generated by "./mkutable -f2 Mn Me -- unicode/UnicodeData.txt" on Mon Nov 14 18:19:23 PST 2022 */ + { 0x0300, 0x036f }, /* Mn */ + { 0x0483, 0x0487 }, /* Mn */ + { 0x0488, 0x0489 }, /* Me */ + { 0x0591, 0x05bd }, /* Mn */ + { 0x05bf, 0x05bf }, /* Mn */ + { 0x05c1, 0x05c2 }, /* Mn */ + { 0x05c4, 0x05c5 }, /* Mn */ + { 0x05c7, 0x05c7 }, /* Mn */ + { 0x0610, 0x061a }, /* Mn */ + { 0x064b, 0x065f }, /* Mn */ + { 0x0670, 0x0670 }, /* Mn */ + { 0x06d6, 0x06dc }, /* Mn */ + { 0x06df, 0x06e4 }, /* Mn */ + { 0x06e7, 0x06e8 }, /* Mn */ + { 0x06ea, 0x06ed }, /* Mn */ + { 0x0711, 0x0711 }, /* Mn */ + { 0x0730, 0x074a }, /* Mn */ + { 0x07a6, 0x07b0 }, /* Mn */ + { 0x07eb, 0x07f3 }, /* Mn */ + { 0x07fd, 0x07fd }, /* Mn */ + { 0x0816, 0x0819 }, /* Mn */ + { 0x081b, 0x0823 }, /* Mn */ + { 0x0825, 0x0827 }, /* Mn */ + { 0x0829, 0x082d }, /* Mn */ + { 0x0859, 0x085b }, /* Mn */ + { 0x0898, 0x089f }, /* Mn */ + { 0x08ca, 0x08e1 }, /* Mn */ + { 0x08e3, 0x0902 }, /* Mn */ + { 0x093a, 0x093a }, /* Mn */ + { 0x093c, 0x093c }, /* Mn */ + { 0x0941, 0x0948 }, /* Mn */ + { 0x094d, 0x094d }, /* Mn */ + { 0x0951, 0x0957 }, /* Mn */ + { 0x0962, 0x0963 }, /* Mn */ + { 0x0981, 0x0981 }, /* Mn */ + { 0x09bc, 0x09bc }, /* Mn */ + { 0x09c1, 0x09c4 }, /* Mn */ + { 0x09cd, 0x09cd }, /* Mn */ + { 0x09e2, 0x09e3 }, /* Mn */ + { 0x09fe, 0x09fe }, /* Mn */ + { 0x0a01, 0x0a02 }, /* Mn */ + { 0x0a3c, 0x0a3c }, /* Mn */ + { 0x0a41, 0x0a42 }, /* Mn */ + { 0x0a47, 0x0a48 }, /* Mn */ + { 0x0a4b, 0x0a4d }, /* Mn */ + { 0x0a51, 0x0a51 }, /* Mn */ + { 0x0a70, 0x0a71 }, /* Mn */ + { 0x0a75, 0x0a75 }, /* Mn */ + { 0x0a81, 0x0a82 }, /* Mn */ + { 0x0abc, 0x0abc }, /* Mn */ + { 0x0ac1, 0x0ac5 }, /* Mn */ + { 0x0ac7, 0x0ac8 }, /* Mn */ + { 0x0acd, 0x0acd }, /* Mn */ + { 0x0ae2, 0x0ae3 }, /* Mn */ + { 0x0afa, 0x0aff }, /* Mn */ + { 0x0b01, 0x0b01 }, /* Mn */ + { 0x0b3c, 0x0b3c }, /* Mn */ + { 0x0b3f, 0x0b3f }, /* Mn */ + { 0x0b41, 0x0b44 }, /* Mn */ + { 0x0b4d, 0x0b4d }, /* Mn */ + { 0x0b55, 0x0b56 }, /* Mn */ + { 0x0b62, 0x0b63 }, /* Mn */ + { 0x0b82, 0x0b82 }, /* Mn */ + { 0x0bc0, 0x0bc0 }, /* Mn */ + { 0x0bcd, 0x0bcd }, /* Mn */ + { 0x0c00, 0x0c00 }, /* Mn */ + { 0x0c04, 0x0c04 }, /* Mn */ + { 0x0c3c, 0x0c3c }, /* Mn */ + { 0x0c3e, 0x0c40 }, /* Mn */ + { 0x0c46, 0x0c48 }, /* Mn */ + { 0x0c4a, 0x0c4d }, /* Mn */ + { 0x0c55, 0x0c56 }, /* Mn */ + { 0x0c62, 0x0c63 }, /* Mn */ + { 0x0c81, 0x0c81 }, /* Mn */ + { 0x0cbc, 0x0cbc }, /* Mn */ + { 0x0cbf, 0x0cbf }, /* Mn */ + { 0x0cc6, 0x0cc6 }, /* Mn */ + { 0x0ccc, 0x0ccd }, /* Mn */ + { 0x0ce2, 0x0ce3 }, /* Mn */ + { 0x0d00, 0x0d01 }, /* Mn */ + { 0x0d3b, 0x0d3c }, /* Mn */ + { 0x0d41, 0x0d44 }, /* Mn */ + { 0x0d4d, 0x0d4d }, /* Mn */ + { 0x0d62, 0x0d63 }, /* Mn */ + { 0x0d81, 0x0d81 }, /* Mn */ + { 0x0dca, 0x0dca }, /* Mn */ + { 0x0dd2, 0x0dd4 }, /* Mn */ + { 0x0dd6, 0x0dd6 }, /* Mn */ + { 0x0e31, 0x0e31 }, /* Mn */ + { 0x0e34, 0x0e3a }, /* Mn */ + { 0x0e47, 0x0e4e }, /* Mn */ + { 0x0eb1, 0x0eb1 }, /* Mn */ + { 0x0eb4, 0x0ebc }, /* Mn */ + { 0x0ec8, 0x0ece }, /* Mn */ + { 0x0f18, 0x0f19 }, /* Mn */ + { 0x0f35, 0x0f35 }, /* Mn */ + { 0x0f37, 0x0f37 }, /* Mn */ + { 0x0f39, 0x0f39 }, /* Mn */ + { 0x0f71, 0x0f7e }, /* Mn */ + { 0x0f80, 0x0f84 }, /* Mn */ + { 0x0f86, 0x0f87 }, /* Mn */ + { 0x0f8d, 0x0f97 }, /* Mn */ + { 0x0f99, 0x0fbc }, /* Mn */ + { 0x0fc6, 0x0fc6 }, /* Mn */ + { 0x102d, 0x1030 }, /* Mn */ + { 0x1032, 0x1037 }, /* Mn */ + { 0x1039, 0x103a }, /* Mn */ + { 0x103d, 0x103e }, /* Mn */ + { 0x1058, 0x1059 }, /* Mn */ + { 0x105e, 0x1060 }, /* Mn */ + { 0x1071, 0x1074 }, /* Mn */ + { 0x1082, 0x1082 }, /* Mn */ + { 0x1085, 0x1086 }, /* Mn */ + { 0x108d, 0x108d }, /* Mn */ + { 0x109d, 0x109d }, /* Mn */ + { 0x1160, 0x11ff }, /* Mn */ + { 0x135d, 0x135f }, /* Mn */ + { 0x1712, 0x1714 }, /* Mn */ + { 0x1732, 0x1733 }, /* Mn */ + { 0x1752, 0x1753 }, /* Mn */ + { 0x1772, 0x1773 }, /* Mn */ + { 0x17b4, 0x17b5 }, /* Mn */ + { 0x17b7, 0x17bd }, /* Mn */ + { 0x17c6, 0x17c6 }, /* Mn */ + { 0x17c9, 0x17d3 }, /* Mn */ + { 0x17dd, 0x17dd }, /* Mn */ + { 0x180b, 0x180d }, /* Mn */ + { 0x180f, 0x180f }, /* Mn */ + { 0x1885, 0x1886 }, /* Mn */ + { 0x18a9, 0x18a9 }, /* Mn */ + { 0x1920, 0x1922 }, /* Mn */ + { 0x1927, 0x1928 }, /* Mn */ + { 0x1932, 0x1932 }, /* Mn */ + { 0x1939, 0x193b }, /* Mn */ + { 0x1a17, 0x1a18 }, /* Mn */ + { 0x1a1b, 0x1a1b }, /* Mn */ + { 0x1a56, 0x1a56 }, /* Mn */ + { 0x1a58, 0x1a5e }, /* Mn */ + { 0x1a60, 0x1a60 }, /* Mn */ + { 0x1a62, 0x1a62 }, /* Mn */ + { 0x1a65, 0x1a6c }, /* Mn */ + { 0x1a73, 0x1a7c }, /* Mn */ + { 0x1a7f, 0x1a7f }, /* Mn */ + { 0x1ab0, 0x1abd }, /* Mn */ + { 0x1abe, 0x1abe }, /* Me */ + { 0x1abf, 0x1ace }, /* Mn */ + { 0x1b00, 0x1b03 }, /* Mn */ + { 0x1b34, 0x1b34 }, /* Mn */ + { 0x1b36, 0x1b3a }, /* Mn */ + { 0x1b3c, 0x1b3c }, /* Mn */ + { 0x1b42, 0x1b42 }, /* Mn */ + { 0x1b6b, 0x1b73 }, /* Mn */ + { 0x1b80, 0x1b81 }, /* Mn */ + { 0x1ba2, 0x1ba5 }, /* Mn */ + { 0x1ba8, 0x1ba9 }, /* Mn */ + { 0x1bab, 0x1bad }, /* Mn */ + { 0x1be6, 0x1be6 }, /* Mn */ + { 0x1be8, 0x1be9 }, /* Mn */ + { 0x1bed, 0x1bed }, /* Mn */ + { 0x1bef, 0x1bf1 }, /* Mn */ + { 0x1c2c, 0x1c33 }, /* Mn */ + { 0x1c36, 0x1c37 }, /* Mn */ + { 0x1cd0, 0x1cd2 }, /* Mn */ + { 0x1cd4, 0x1ce0 }, /* Mn */ + { 0x1ce2, 0x1ce8 }, /* Mn */ + { 0x1ced, 0x1ced }, /* Mn */ + { 0x1cf4, 0x1cf4 }, /* Mn */ + { 0x1cf8, 0x1cf9 }, /* Mn */ + { 0x1dc0, 0x1dff }, /* Mn */ + { 0x20d0, 0x20dc }, /* Mn */ + { 0x20dd, 0x20e0 }, /* Me */ + { 0x20e1, 0x20e1 }, /* Mn */ + { 0x20e2, 0x20e4 }, /* Me */ + { 0x20e5, 0x20f0 }, /* Mn */ + { 0x2cef, 0x2cf1 }, /* Mn */ + { 0x2d7f, 0x2d7f }, /* Mn */ + { 0x2de0, 0x2dff }, /* Mn */ + { 0x302a, 0x302d }, /* Mn */ + { 0x3099, 0x309a }, /* Mn */ + { 0xa66f, 0xa66f }, /* Mn */ + { 0xa670, 0xa672 }, /* Me */ + { 0xa674, 0xa67d }, /* Mn */ + { 0xa69e, 0xa69f }, /* Mn */ + { 0xa6f0, 0xa6f1 }, /* Mn */ + { 0xa802, 0xa802 }, /* Mn */ + { 0xa806, 0xa806 }, /* Mn */ + { 0xa80b, 0xa80b }, /* Mn */ + { 0xa825, 0xa826 }, /* Mn */ + { 0xa82c, 0xa82c }, /* Mn */ + { 0xa8c4, 0xa8c5 }, /* Mn */ + { 0xa8e0, 0xa8f1 }, /* Mn */ + { 0xa8ff, 0xa8ff }, /* Mn */ + { 0xa926, 0xa92d }, /* Mn */ + { 0xa947, 0xa951 }, /* Mn */ + { 0xa980, 0xa982 }, /* Mn */ + { 0xa9b3, 0xa9b3 }, /* Mn */ + { 0xa9b6, 0xa9b9 }, /* Mn */ + { 0xa9bc, 0xa9bd }, /* Mn */ + { 0xa9e5, 0xa9e5 }, /* Mn */ + { 0xaa29, 0xaa2e }, /* Mn */ + { 0xaa31, 0xaa32 }, /* Mn */ + { 0xaa35, 0xaa36 }, /* Mn */ + { 0xaa43, 0xaa43 }, /* Mn */ + { 0xaa4c, 0xaa4c }, /* Mn */ + { 0xaa7c, 0xaa7c }, /* Mn */ + { 0xaab0, 0xaab0 }, /* Mn */ + { 0xaab2, 0xaab4 }, /* Mn */ + { 0xaab7, 0xaab8 }, /* Mn */ + { 0xaabe, 0xaabf }, /* Mn */ + { 0xaac1, 0xaac1 }, /* Mn */ + { 0xaaec, 0xaaed }, /* Mn */ + { 0xaaf6, 0xaaf6 }, /* Mn */ + { 0xabe5, 0xabe5 }, /* Mn */ + { 0xabe8, 0xabe8 }, /* Mn */ + { 0xabed, 0xabed }, /* Mn */ + { 0xd7b0, 0xd7c6 }, /* Mn */ + { 0xd7cb, 0xd7fb }, /* Mn */ + { 0xfb1e, 0xfb1e }, /* Mn */ + { 0xfe00, 0xfe0f }, /* Mn */ + { 0xfe20, 0xfe2f }, /* Mn */ + { 0x101fd, 0x101fd }, /* Mn */ + { 0x102e0, 0x102e0 }, /* Mn */ + { 0x10376, 0x1037a }, /* Mn */ + { 0x10a01, 0x10a03 }, /* Mn */ + { 0x10a05, 0x10a06 }, /* Mn */ + { 0x10a0c, 0x10a0f }, /* Mn */ + { 0x10a38, 0x10a3a }, /* Mn */ + { 0x10a3f, 0x10a3f }, /* Mn */ + { 0x10ae5, 0x10ae6 }, /* Mn */ + { 0x10d24, 0x10d27 }, /* Mn */ + { 0x10eab, 0x10eac }, /* Mn */ + { 0x10efd, 0x10eff }, /* Mn */ + { 0x10f46, 0x10f50 }, /* Mn */ + { 0x10f82, 0x10f85 }, /* Mn */ + { 0x11001, 0x11001 }, /* Mn */ + { 0x11038, 0x11046 }, /* Mn */ + { 0x11070, 0x11070 }, /* Mn */ + { 0x11073, 0x11074 }, /* Mn */ + { 0x1107f, 0x11081 }, /* Mn */ + { 0x110b3, 0x110b6 }, /* Mn */ + { 0x110b9, 0x110ba }, /* Mn */ + { 0x110c2, 0x110c2 }, /* Mn */ + { 0x11100, 0x11102 }, /* Mn */ + { 0x11127, 0x1112b }, /* Mn */ + { 0x1112d, 0x11134 }, /* Mn */ + { 0x11173, 0x11173 }, /* Mn */ + { 0x11180, 0x11181 }, /* Mn */ + { 0x111b6, 0x111be }, /* Mn */ + { 0x111c9, 0x111cc }, /* Mn */ + { 0x111cf, 0x111cf }, /* Mn */ + { 0x1122f, 0x11231 }, /* Mn */ + { 0x11234, 0x11234 }, /* Mn */ + { 0x11236, 0x11237 }, /* Mn */ + { 0x1123e, 0x1123e }, /* Mn */ + { 0x11241, 0x11241 }, /* Mn */ + { 0x112df, 0x112df }, /* Mn */ + { 0x112e3, 0x112ea }, /* Mn */ + { 0x11300, 0x11301 }, /* Mn */ + { 0x1133b, 0x1133c }, /* Mn */ + { 0x11340, 0x11340 }, /* Mn */ + { 0x11366, 0x1136c }, /* Mn */ + { 0x11370, 0x11374 }, /* Mn */ + { 0x11438, 0x1143f }, /* Mn */ + { 0x11442, 0x11444 }, /* Mn */ + { 0x11446, 0x11446 }, /* Mn */ + { 0x1145e, 0x1145e }, /* Mn */ + { 0x114b3, 0x114b8 }, /* Mn */ + { 0x114ba, 0x114ba }, /* Mn */ + { 0x114bf, 0x114c0 }, /* Mn */ + { 0x114c2, 0x114c3 }, /* Mn */ + { 0x115b2, 0x115b5 }, /* Mn */ + { 0x115bc, 0x115bd }, /* Mn */ + { 0x115bf, 0x115c0 }, /* Mn */ + { 0x115dc, 0x115dd }, /* Mn */ + { 0x11633, 0x1163a }, /* Mn */ + { 0x1163d, 0x1163d }, /* Mn */ + { 0x1163f, 0x11640 }, /* Mn */ + { 0x116ab, 0x116ab }, /* Mn */ + { 0x116ad, 0x116ad }, /* Mn */ + { 0x116b0, 0x116b5 }, /* Mn */ + { 0x116b7, 0x116b7 }, /* Mn */ + { 0x1171d, 0x1171f }, /* Mn */ + { 0x11722, 0x11725 }, /* Mn */ + { 0x11727, 0x1172b }, /* Mn */ + { 0x1182f, 0x11837 }, /* Mn */ + { 0x11839, 0x1183a }, /* Mn */ + { 0x1193b, 0x1193c }, /* Mn */ + { 0x1193e, 0x1193e }, /* Mn */ + { 0x11943, 0x11943 }, /* Mn */ + { 0x119d4, 0x119d7 }, /* Mn */ + { 0x119da, 0x119db }, /* Mn */ + { 0x119e0, 0x119e0 }, /* Mn */ + { 0x11a01, 0x11a0a }, /* Mn */ + { 0x11a33, 0x11a38 }, /* Mn */ + { 0x11a3b, 0x11a3e }, /* Mn */ + { 0x11a47, 0x11a47 }, /* Mn */ + { 0x11a51, 0x11a56 }, /* Mn */ + { 0x11a59, 0x11a5b }, /* Mn */ + { 0x11a8a, 0x11a96 }, /* Mn */ + { 0x11a98, 0x11a99 }, /* Mn */ + { 0x11c30, 0x11c36 }, /* Mn */ + { 0x11c38, 0x11c3d }, /* Mn */ + { 0x11c3f, 0x11c3f }, /* Mn */ + { 0x11c92, 0x11ca7 }, /* Mn */ + { 0x11caa, 0x11cb0 }, /* Mn */ + { 0x11cb2, 0x11cb3 }, /* Mn */ + { 0x11cb5, 0x11cb6 }, /* Mn */ + { 0x11d31, 0x11d36 }, /* Mn */ + { 0x11d3a, 0x11d3a }, /* Mn */ + { 0x11d3c, 0x11d3d }, /* Mn */ + { 0x11d3f, 0x11d45 }, /* Mn */ + { 0x11d47, 0x11d47 }, /* Mn */ + { 0x11d90, 0x11d91 }, /* Mn */ + { 0x11d95, 0x11d95 }, /* Mn */ + { 0x11d97, 0x11d97 }, /* Mn */ + { 0x11ef3, 0x11ef4 }, /* Mn */ + { 0x11f00, 0x11f01 }, /* Mn */ + { 0x11f36, 0x11f3a }, /* Mn */ + { 0x11f40, 0x11f40 }, /* Mn */ + { 0x11f42, 0x11f42 }, /* Mn */ + { 0x13440, 0x13440 }, /* Mn */ + { 0x13447, 0x13455 }, /* Mn */ + { 0x16af0, 0x16af4 }, /* Mn */ + { 0x16b30, 0x16b36 }, /* Mn */ + { 0x16f4f, 0x16f4f }, /* Mn */ + { 0x16f8f, 0x16f92 }, /* Mn */ + { 0x16fe4, 0x16fe4 }, /* Mn */ + { 0x1bc9d, 0x1bc9e }, /* Mn */ + { 0x1cf00, 0x1cf2d }, /* Mn */ + { 0x1cf30, 0x1cf46 }, /* Mn */ + { 0x1d167, 0x1d169 }, /* Mn */ + { 0x1d17b, 0x1d182 }, /* Mn */ + { 0x1d185, 0x1d18b }, /* Mn */ + { 0x1d1aa, 0x1d1ad }, /* Mn */ + { 0x1d242, 0x1d244 }, /* Mn */ + { 0x1da00, 0x1da36 }, /* Mn */ + { 0x1da3b, 0x1da6c }, /* Mn */ + { 0x1da75, 0x1da75 }, /* Mn */ + { 0x1da84, 0x1da84 }, /* Mn */ + { 0x1da9b, 0x1da9f }, /* Mn */ + { 0x1daa1, 0x1daaf }, /* Mn */ + { 0x1e000, 0x1e006 }, /* Mn */ + { 0x1e008, 0x1e018 }, /* Mn */ + { 0x1e01b, 0x1e021 }, /* Mn */ + { 0x1e023, 0x1e024 }, /* Mn */ + { 0x1e026, 0x1e02a }, /* Mn */ + { 0x1e08f, 0x1e08f }, /* Mn */ + { 0x1e130, 0x1e136 }, /* Mn */ + { 0x1e2ae, 0x1e2ae }, /* Mn */ + { 0x1e2ec, 0x1e2ef }, /* Mn */ + { 0x1e4ec, 0x1e4ef }, /* Mn */ + { 0x1e8d0, 0x1e8d6 }, /* Mn */ + { 0x1e944, 0x1e94a }, /* Mn */ + { 0xe0100, 0xe01ef }, /* Mn */ diff --git a/third_party/less/cvt.c b/third_party/less/cvt.c new file mode 100644 index 000000000..b9997ffbc --- /dev/null +++ b/third_party/less/cvt.c @@ -0,0 +1,107 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + +/* + * Routines to convert text in various ways. Used by search. + */ + +#include "less.h" +#include "charset.h" + +extern int utf_mode; + +/* + * Get the length of a buffer needed to convert a string. + */ +public int cvt_length(int len, int ops) +{ + if (utf_mode) + /* + * Just copying a string in UTF-8 mode can cause it to grow + * in length. + * Four output bytes for one input byte is the worst case. + */ + len *= 4; + return (len + 1); +} + +/* + * Allocate a chpos array for use by cvt_text. + */ +public int * cvt_alloc_chpos(int len) +{ + int i; + int *chpos = (int *) ecalloc(sizeof(int), len); + /* Initialize all entries to an invalid position. */ + for (i = 0; i < len; i++) + chpos[i] = -1; + return (chpos); +} + +/* + * Convert text. Perform the transformations specified by ops. + * Returns converted text in odst. The original offset of each + * odst character (when it was in osrc) is returned in the chpos array. + */ +public void cvt_text(char *odst, char *osrc, int *chpos, int *lenp, int ops) +{ + char *dst; + char *edst = odst; + char *src; + char *src_end; + LWCHAR ch; + + if (lenp != NULL) + src_end = osrc + *lenp; + else + src_end = osrc + strlen(osrc); + + for (src = osrc, dst = odst; src < src_end; ) + { + int src_pos = (int) (src - osrc); + int dst_pos = (int) (dst - odst); + struct ansi_state *pansi; + ch = step_char(&src, +1, src_end); + if ((ops & CVT_BS) && ch == '\b' && dst > odst) + { + /* Delete backspace and preceding char. */ + do { + dst--; + } while (dst > odst && utf_mode && + !IS_ASCII_OCTET(*dst) && !IS_UTF8_LEAD(*dst)); + } else if ((ops & CVT_ANSI) && (pansi = ansi_start(ch)) != NULL) + { + /* Skip to end of ANSI escape sequence. */ + while (src < src_end) + { + if (ansi_step(pansi, ch) != ANSI_MID) + break; + ch = *src++; + } + ansi_done(pansi); + } else + { + /* Just copy the char to the destination buffer. */ + if ((ops & CVT_TO_LC) && IS_UPPER(ch)) + ch = TO_LOWER(ch); + put_wchar(&dst, ch); + /* Record the original position of the char. */ + if (chpos != NULL) + chpos[dst_pos] = src_pos; + } + if (dst > edst) + edst = dst; + } + if ((ops & CVT_CRLF) && edst > odst && edst[-1] == '\r') + edst--; + *edst = '\0'; + if (lenp != NULL) + *lenp = (int) (edst - odst); + /* FIXME: why was this here? if (chpos != NULL) chpos[dst - odst] = src - osrc; */ +} diff --git a/third_party/less/decode.c b/third_party/less/decode.c new file mode 100644 index 000000000..e7969a886 --- /dev/null +++ b/third_party/less/decode.c @@ -0,0 +1,1017 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * Routines to decode user commands. + * + * This is all table driven. + * A command table is a sequence of command descriptors. + * Each command descriptor is a sequence of bytes with the following format: + * ...<0> + * The characters c1,c2,...,cN are the command string; that is, + * the characters which the user must type. + * It is terminated by a null <0> byte. + * The byte after the null byte is the action code associated + * with the command string. + * If an action byte is OR-ed with A_EXTRA, this indicates + * that the option byte is followed by an extra string. + * + * There may be many command tables. + * The first (default) table is built-in. + * Other tables are read in from "lesskey" files. + * All the tables are linked together and are searched in order. + */ + +#include "less.h" +#include "cmd.h" +#include "lesskey.h" + +extern int erase_char, erase2_char, kill_char; +extern int secure; +extern int mousecap; +extern int screen_trashed; +extern int sc_height; + +#define SK(k) \ + SK_SPECIAL_KEY, (k), 6, 1, 1, 1 +/* + * Command table is ordered roughly according to expected + * frequency of use, so the common commands are near the beginning. + */ + +static unsigned char cmdtable[] = +{ + '\r',0, A_F_LINE, + '\n',0, A_F_LINE, + 'e',0, A_F_LINE, + 'j',0, A_F_LINE, + SK(SK_DOWN_ARROW),0, A_F_LINE, + CONTROL('E'),0, A_F_LINE, + CONTROL('N'),0, A_F_LINE, + 'k',0, A_B_LINE, + 'y',0, A_B_LINE, + CONTROL('Y'),0, A_B_LINE, + SK(SK_CONTROL_K),0, A_B_LINE, + CONTROL('P'),0, A_B_LINE, + SK(SK_UP_ARROW),0, A_B_LINE, + 'J',0, A_FF_LINE, + 'K',0, A_BF_LINE, + 'Y',0, A_BF_LINE, + 'd',0, A_F_SCROLL, + CONTROL('D'),0, A_F_SCROLL, + 'u',0, A_B_SCROLL, + CONTROL('U'),0, A_B_SCROLL, + ESC,'[','M',0, A_X11MOUSE_IN, + ESC,'[','<',0, A_X116MOUSE_IN, + ' ',0, A_F_SCREEN, + 'f',0, A_F_SCREEN, + CONTROL('F'),0, A_F_SCREEN, + CONTROL('V'),0, A_F_SCREEN, + SK(SK_PAGE_DOWN),0, A_F_SCREEN, + 'b',0, A_B_SCREEN, + CONTROL('B'),0, A_B_SCREEN, + ESC,'v',0, A_B_SCREEN, + SK(SK_PAGE_UP),0, A_B_SCREEN, + 'z',0, A_F_WINDOW, + 'w',0, A_B_WINDOW, + ESC,' ',0, A_FF_SCREEN, + 'F',0, A_F_FOREVER, + ESC,'F',0, A_F_UNTIL_HILITE, + 'R',0, A_FREPAINT, + 'r',0, A_REPAINT, + CONTROL('R'),0, A_REPAINT, + CONTROL('L'),0, A_REPAINT, + ESC,'u',0, A_UNDO_SEARCH, + ESC,'U',0, A_CLR_SEARCH, + 'g',0, A_GOLINE, + SK(SK_HOME),0, A_GOLINE, + '<',0, A_GOLINE, + ESC,'<',0, A_GOLINE, + 'p',0, A_PERCENT, + '%',0, A_PERCENT, + ESC,'[',0, A_LSHIFT, + ESC,']',0, A_RSHIFT, + ESC,'(',0, A_LSHIFT, + ESC,')',0, A_RSHIFT, + ESC,'{',0, A_LLSHIFT, + ESC,'}',0, A_RRSHIFT, + SK(SK_RIGHT_ARROW),0, A_RSHIFT, + SK(SK_LEFT_ARROW),0, A_LSHIFT, + SK(SK_CTL_RIGHT_ARROW),0, A_RRSHIFT, + SK(SK_CTL_LEFT_ARROW),0, A_LLSHIFT, + '{',0, A_F_BRACKET|A_EXTRA, '{','}',0, + '}',0, A_B_BRACKET|A_EXTRA, '{','}',0, + '(',0, A_F_BRACKET|A_EXTRA, '(',')',0, + ')',0, A_B_BRACKET|A_EXTRA, '(',')',0, + '[',0, A_F_BRACKET|A_EXTRA, '[',']',0, + ']',0, A_B_BRACKET|A_EXTRA, '[',']',0, + ESC,CONTROL('F'),0, A_F_BRACKET, + ESC,CONTROL('B'),0, A_B_BRACKET, + 'G',0, A_GOEND, + ESC,'G',0, A_GOEND_BUF, + ESC,'>',0, A_GOEND, + '>',0, A_GOEND, + SK(SK_END),0, A_GOEND, + 'P',0, A_GOPOS, + + '0',0, A_DIGIT, + '1',0, A_DIGIT, + '2',0, A_DIGIT, + '3',0, A_DIGIT, + '4',0, A_DIGIT, + '5',0, A_DIGIT, + '6',0, A_DIGIT, + '7',0, A_DIGIT, + '8',0, A_DIGIT, + '9',0, A_DIGIT, + '.',0, A_DIGIT, + + '=',0, A_STAT, + CONTROL('G'),0, A_STAT, + ':','f',0, A_STAT, + '/',0, A_F_SEARCH, + '?',0, A_B_SEARCH, + ESC,'/',0, A_F_SEARCH|A_EXTRA, '*',0, + ESC,'?',0, A_B_SEARCH|A_EXTRA, '*',0, + 'n',0, A_AGAIN_SEARCH, + ESC,'n',0, A_T_AGAIN_SEARCH, + 'N',0, A_REVERSE_SEARCH, + ESC,'N',0, A_T_REVERSE_SEARCH, + '&',0, A_FILTER, + 'm',0, A_SETMARK, + 'M',0, A_SETMARKBOT, + ESC,'m',0, A_CLRMARK, + '\'',0, A_GOMARK, + CONTROL('X'),CONTROL('X'),0, A_GOMARK, + 'E',0, A_EXAMINE, + ':','e',0, A_EXAMINE, + CONTROL('X'),CONTROL('V'),0, A_EXAMINE, + ':','n',0, A_NEXT_FILE, + ':','p',0, A_PREV_FILE, + 't',0, A_NEXT_TAG, + 'T',0, A_PREV_TAG, + ':','x',0, A_INDEX_FILE, + ':','d',0, A_REMOVE_FILE, + '-',0, A_OPT_TOGGLE, + ':','t',0, A_OPT_TOGGLE|A_EXTRA, 't',0, + 's',0, A_OPT_TOGGLE|A_EXTRA, 'o',0, + '_',0, A_DISP_OPTION, + '|',0, A_PIPE, + 'v',0, A_VISUAL, + '!',0, A_SHELL, + '#',0, A_PSHELL, + '+',0, A_FIRSTCMD, + + 'H',0, A_HELP, + 'h',0, A_HELP, + SK(SK_F1),0, A_HELP, + 'V',0, A_VERSION, + 'q',0, A_QUIT, + 'Q',0, A_QUIT, + ':','q',0, A_QUIT, + ':','Q',0, A_QUIT, + 'Z','Z',0, A_QUIT +}; + +static unsigned char edittable[] = +{ + '\t',0, EC_F_COMPLETE, /* TAB */ + '\17',0, EC_B_COMPLETE, /* BACKTAB */ + SK(SK_BACKTAB),0, EC_B_COMPLETE, /* BACKTAB */ + ESC,'\t',0, EC_B_COMPLETE, /* ESC TAB */ + CONTROL('L'),0, EC_EXPAND, /* CTRL-L */ + CONTROL('V'),0, EC_LITERAL, /* BACKSLASH */ + CONTROL('A'),0, EC_LITERAL, /* BACKSLASH */ + ESC,'l',0, EC_RIGHT, /* ESC l */ + SK(SK_RIGHT_ARROW),0, EC_RIGHT, /* RIGHTARROW */ + ESC,'h',0, EC_LEFT, /* ESC h */ + SK(SK_LEFT_ARROW),0, EC_LEFT, /* LEFTARROW */ + ESC,'b',0, EC_W_LEFT, /* ESC b */ + ESC,SK(SK_LEFT_ARROW),0, EC_W_LEFT, /* ESC LEFTARROW */ + SK(SK_CTL_LEFT_ARROW),0, EC_W_LEFT, /* CTRL-LEFTARROW */ + ESC,'w',0, EC_W_RIGHT, /* ESC w */ + ESC,SK(SK_RIGHT_ARROW),0, EC_W_RIGHT, /* ESC RIGHTARROW */ + SK(SK_CTL_RIGHT_ARROW),0, EC_W_RIGHT, /* CTRL-RIGHTARROW */ + ESC,'i',0, EC_INSERT, /* ESC i */ + SK(SK_INSERT),0, EC_INSERT, /* INSERT */ + ESC,'x',0, EC_DELETE, /* ESC x */ + SK(SK_DELETE),0, EC_DELETE, /* DELETE */ + ESC,'X',0, EC_W_DELETE, /* ESC X */ + ESC,SK(SK_DELETE),0, EC_W_DELETE, /* ESC DELETE */ + SK(SK_CTL_DELETE),0, EC_W_DELETE, /* CTRL-DELETE */ + SK(SK_CTL_BACKSPACE),0, EC_W_BACKSPACE, /* CTRL-BACKSPACE */ + ESC,SK(SK_BACKSPACE),0, EC_W_BACKSPACE, /* ESC BACKSPACE */ + ESC,'0',0, EC_HOME, /* ESC 0 */ + SK(SK_HOME),0, EC_HOME, /* HOME */ + ESC,'$',0, EC_END, /* ESC $ */ + SK(SK_END),0, EC_END, /* END */ + ESC,'k',0, EC_UP, /* ESC k */ + SK(SK_UP_ARROW),0, EC_UP, /* UPARROW */ + ESC,'j',0, EC_DOWN, /* ESC j */ + SK(SK_DOWN_ARROW),0, EC_DOWN, /* DOWNARROW */ + CONTROL('G'),0, EC_ABORT, /* CTRL-G */ + ESC,'[','M',0, EC_X11MOUSE, /* X11 mouse report */ + ESC,'[','<',0, EC_X116MOUSE, /* X11 1006 mouse report */ +}; + +/* + * Structure to support a list of command tables. + */ +struct tablelist +{ + struct tablelist *t_next; + char *t_start; + char *t_end; +}; + +/* + * List of command tables and list of line-edit tables. + */ +static struct tablelist *list_fcmd_tables = NULL; +static struct tablelist *list_ecmd_tables = NULL; +static struct tablelist *list_var_tables = NULL; +static struct tablelist *list_sysvar_tables = NULL; + + +/* + * Expand special key abbreviations in a command table. + */ +static void expand_special_keys(char *table, int len) +{ + char *fm; + char *to; + int a; + char *repl; + int klen; + + for (fm = table; fm < table + len; ) + { + /* + * Rewrite each command in the table with any + * special key abbreviations expanded. + */ + for (to = fm; *fm != '\0'; ) + { + if (*fm != SK_SPECIAL_KEY) + { + *to++ = *fm++; + continue; + } + /* + * After SK_SPECIAL_KEY, next byte is the type + * of special key (one of the SK_* constants), + * and the byte after that is the number of bytes, + * N, reserved by the abbreviation (including the + * SK_SPECIAL_KEY and key type bytes). + * Replace all N bytes with the actual bytes + * output by the special key on this terminal. + */ + repl = special_key_str(fm[1]); + klen = fm[2] & 0377; + fm += klen; + if (repl == NULL || (int) strlen(repl) > klen) + repl = "\377"; + while (*repl != '\0') + *to++ = *repl++; + } + *to++ = '\0'; + /* + * Fill any unused bytes between end of command and + * the action byte with A_SKIP. + */ + while (to <= fm) + *to++ = A_SKIP; + fm++; + a = *fm++ & 0377; + if (a & A_EXTRA) + { + while (*fm++ != '\0') + continue; + } + } +} + +/* + * Expand special key abbreviations in a list of command tables. + */ +static void expand_cmd_table(struct tablelist *tlist) +{ + struct tablelist *t; + for (t = tlist; t != NULL; t = t->t_next) + { + expand_special_keys(t->t_start, t->t_end - t->t_start); + } +} + +/* + * Expand special key abbreviations in all command tables. + */ +public void expand_cmd_tables(void) +{ + expand_cmd_table(list_fcmd_tables); + expand_cmd_table(list_ecmd_tables); + expand_cmd_table(list_var_tables); + expand_cmd_table(list_sysvar_tables); +} + + +/* + * Initialize the command lists. + */ +public void init_cmds(void) +{ + /* + * Add the default command tables. + */ + add_fcmd_table((char*)cmdtable, sizeof(cmdtable)); + add_ecmd_table((char*)edittable, sizeof(edittable)); +#if USERFILE +#ifdef BINDIR /* For backwards compatibility */ + /* Try to add tables in the OLD system lesskey file. */ + add_hometable(lesskey, NULL, BINDIR "/.sysless", 1); +#endif + /* + * Try to load lesskey source file or binary file. + * If the source file succeeds, don't load binary file. + * The binary file is likely to have been generated from + * a (possibly out of date) copy of the src file, + * so loading it is at best redundant. + */ + /* + * Try to add tables in system lesskey src file. + */ +#if HAVE_LESSKEYSRC + if (add_hometable(lesskey_src, "LESSKEYIN_SYSTEM", LESSKEYINFILE_SYS, 1) != 0) +#endif + { + /* + * Try to add the tables in the system lesskey binary file. + */ + add_hometable(lesskey, "LESSKEY_SYSTEM", LESSKEYFILE_SYS, 1); + } + /* + * Try to add tables in the lesskey src file "$HOME/.lesskey". + */ +#if HAVE_LESSKEYSRC + if (add_hometable(lesskey_src, "LESSKEYIN", DEF_LESSKEYINFILE, 0) != 0) +#endif + { + /* + * Try to add the tables in the standard lesskey binary file "$HOME/.less". + */ + add_hometable(lesskey, "LESSKEY", LESSKEYFILE, 0); + } +#endif +} + +/* + * Add a command table. + */ +static int add_cmd_table(struct tablelist **tlist, char *buf, int len) +{ + struct tablelist *t; + + if (len == 0) + return (0); + /* + * Allocate a tablelist structure, initialize it, + * and link it into the list of tables. + */ + if ((t = (struct tablelist *) + calloc(1, sizeof(struct tablelist))) == NULL) + { + return (-1); + } + t->t_start = buf; + t->t_end = buf + len; + t->t_next = *tlist; + *tlist = t; + return (0); +} + +/* + * Add a command table. + */ +public void add_fcmd_table(char *buf, int len) +{ + if (add_cmd_table(&list_fcmd_tables, buf, len) < 0) + error("Warning: some commands disabled", NULL_PARG); +} + +/* + * Add an editing command table. + */ +public void add_ecmd_table(char *buf, int len) +{ + if (add_cmd_table(&list_ecmd_tables, buf, len) < 0) + error("Warning: some edit commands disabled", NULL_PARG); +} + +/* + * Add an environment variable table. + */ +static void add_var_table(struct tablelist **tlist, char *buf, int len) +{ + if (add_cmd_table(tlist, buf, len) < 0) + error("Warning: environment variables from lesskey file unavailable", NULL_PARG); +} + +/* + * Return action for a mouse wheel down event. + */ +static int mouse_wheel_down(void) +{ + return ((mousecap == OPT_ONPLUS) ? A_B_MOUSE : A_F_MOUSE); +} + +/* + * Return action for a mouse wheel up event. + */ +static int mouse_wheel_up(void) +{ + return ((mousecap == OPT_ONPLUS) ? A_F_MOUSE : A_B_MOUSE); +} + +/* + * Return action for a mouse button release event. + */ +static int mouse_button_rel(int x, int y) +{ + /* + * {{ It would be better to return an action and then do this + * in commands() but it's nontrivial to pass y to it. }} + */ + if (y < sc_height-1) + { + setmark('#', y); + screen_trashed = 1; + } + return (A_NOACTION); +} + +/* + * Read a decimal integer. Return the integer and set *pterm to the terminating char. + */ +static int getcc_int(char *pterm) +{ + int num = 0; + int digits = 0; + for (;;) + { + char ch = getcc(); + if (ch < '0' || ch > '9') + { + if (pterm != NULL) *pterm = ch; + if (digits == 0) + return (-1); + return (num); + } + if (ckd_mul(&num, num, 10) || ckd_add(&num, num, ch - '0')) + return -1; + ++digits; + } +} + +/* + * Read suffix of mouse input and return the action to take. + * The prefix ("\e[M") has already been read. + */ +static int x11mouse_action(int skip) +{ + int b = getcc() - X11MOUSE_OFFSET; + int x = getcc() - X11MOUSE_OFFSET-1; + int y = getcc() - X11MOUSE_OFFSET-1; + if (skip) + return (A_NOACTION); + switch (b) { + default: + return (A_NOACTION); + case X11MOUSE_WHEEL_DOWN: + return mouse_wheel_down(); + case X11MOUSE_WHEEL_UP: + return mouse_wheel_up(); + case X11MOUSE_BUTTON_REL: + return mouse_button_rel(x, y); + } +} + +/* + * Read suffix of mouse input and return the action to take. + * The prefix ("\e[<") has already been read. + */ +static int x116mouse_action(int skip) +{ + char ch; + int x, y; + int b = getcc_int(&ch); + if (b < 0 || ch != ';') return (A_NOACTION); + x = getcc_int(&ch) - 1; + if (x < 0 || ch != ';') return (A_NOACTION); + y = getcc_int(&ch) - 1; + if (y < 0) return (A_NOACTION); + if (skip) + return (A_NOACTION); + switch (b) { + case X11MOUSE_WHEEL_DOWN: + return mouse_wheel_down(); + case X11MOUSE_WHEEL_UP: + return mouse_wheel_up(); + default: + if (ch != 'm') return (A_NOACTION); + return mouse_button_rel(x, y); + } +} + +/* + * Search a single command table for the command string in cmd. + */ +static int cmd_search(char *cmd, char *table, char *endtable, char **sp) +{ + char *p; + char *q; + int a; + + *sp = NULL; + for (p = table, q = cmd; p < endtable; p++, q++) + { + if (*p == *q) + { + /* + * Current characters match. + * If we're at the end of the string, we've found it. + * Return the action code, which is the character + * after the null at the end of the string + * in the command table. + */ + if (*p == '\0') + { + a = *++p & 0377; + while (a == A_SKIP) + a = *++p & 0377; + if (a == A_END_LIST) + { + /* + * We get here only if the original + * cmd string passed in was empty (""). + * I don't think that can happen, + * but just in case ... + */ + return (A_UINVALID); + } + /* + * Check for an "extra" string. + */ + if (a & A_EXTRA) + { + *sp = ++p; + a &= ~A_EXTRA; + } + if (a == A_X11MOUSE_IN) + a = x11mouse_action(0); + else if (a == A_X116MOUSE_IN) + a = x116mouse_action(0); + return (a); + } + } else if (*q == '\0') + { + /* + * Hit the end of the user's command, + * but not the end of the string in the command table. + * The user's command is incomplete. + */ + return (A_PREFIX); + } else + { + /* + * Not a match. + * Skip ahead to the next command in the + * command table, and reset the pointer + * to the beginning of the user's command. + */ + if (*p == '\0' && p[1] == A_END_LIST) + { + /* + * A_END_LIST is a special marker that tells + * us to abort the cmd search. + */ + return (A_UINVALID); + } + while (*p++ != '\0') + continue; + while (*p == A_SKIP) + p++; + if (*p & A_EXTRA) + while (*++p != '\0') + continue; + q = cmd-1; + } + } + /* + * No match found in the entire command table. + */ + return (A_INVALID); +} + +/* + * Decode a command character and return the associated action. + * The "extra" string, if any, is returned in sp. + */ +static int cmd_decode(struct tablelist *tlist, char *cmd, char **sp) +{ + struct tablelist *t; + int action = A_INVALID; + + /* + * Search thru all the command tables. + * Stop when we find an action which is not A_INVALID. + */ + for (t = tlist; t != NULL; t = t->t_next) + { + action = cmd_search(cmd, t->t_start, t->t_end, sp); + if (action != A_INVALID) + break; + } + if (action == A_UINVALID) + action = A_INVALID; + return (action); +} + +/* + * Decode a command from the cmdtables list. + */ +public int fcmd_decode(char *cmd, char **sp) +{ + return (cmd_decode(list_fcmd_tables, cmd, sp)); +} + +/* + * Decode a command from the edittables list. + */ +public int ecmd_decode(char *cmd, char **sp) +{ + return (cmd_decode(list_ecmd_tables, cmd, sp)); +} + +/* + * Get the value of an environment variable. + * Looks first in the lesskey file, then in the real environment. + */ +public char * lgetenv(char *var) +{ + int a; + char *s; + + a = cmd_decode(list_var_tables, var, &s); + if (a == EV_OK) + return (s); + s = getenv(var); + if (s != NULL && *s != '\0') + return (s); + a = cmd_decode(list_sysvar_tables, var, &s); + if (a == EV_OK) + return (s); + return (NULL); +} + +/* + * Is a string null or empty? + */ +public int isnullenv(char *s) +{ + return (s == NULL || *s == '\0'); +} + +#if USERFILE +/* + * Get an "integer" from a lesskey file. + * Integers are stored in a funny format: + * two bytes, low order first, in radix KRADIX. + */ +static int gint(char **sp) +{ + int n; + + n = *(*sp)++; + n += *(*sp)++ * KRADIX; + return (n); +} + +/* + * Process an old (pre-v241) lesskey file. + */ +static int old_lesskey(char *buf, int len) +{ + /* + * Old-style lesskey file. + * The file must end with either + * ...,cmd,0,action + * or ...,cmd,0,action|A_EXTRA,string,0 + * So the last byte or the second to last byte must be zero. + */ + if (buf[len-1] != '\0' && buf[len-2] != '\0') + return (-1); + add_fcmd_table(buf, len); + return (0); +} + +/* + * Process a new (post-v241) lesskey file. + */ +static int new_lesskey(char *buf, int len, int sysvar) +{ + char *p; + char *end; + int c; + int n; + + /* + * New-style lesskey file. + * Extract the pieces. + */ + if (buf[len-3] != C0_END_LESSKEY_MAGIC || + buf[len-2] != C1_END_LESSKEY_MAGIC || + buf[len-1] != C2_END_LESSKEY_MAGIC) + return (-1); + p = buf + 4; + end = buf + len; + for (;;) + { + c = *p++; + switch (c) + { + case CMD_SECTION: + n = gint(&p); + if (n < 0 || p+n >= end) + return (-1); + add_fcmd_table(p, n); + p += n; + break; + case EDIT_SECTION: + n = gint(&p); + if (n < 0 || p+n >= end) + return (-1); + add_ecmd_table(p, n); + p += n; + break; + case VAR_SECTION: + n = gint(&p); + if (n < 0 || p+n >= end) + return (-1); + add_var_table((sysvar) ? + &list_sysvar_tables : &list_var_tables, p, n); + p += n; + break; + case END_SECTION: + return (0); + default: + /* + * Unrecognized section type. + */ + return (-1); + } + } +} + +/* + * Set up a user command table, based on a "lesskey" file. + */ +public int lesskey(char *filename, int sysvar) +{ + char *buf; + POSITION len; + long n; + int f; + + if (secure) + return (1); + /* + * Try to open the lesskey file. + */ + f = open(filename, OPEN_READ); + if (f < 0) + return (1); + + /* + * Read the file into a buffer. + * We first figure out the size of the file and allocate space for it. + * {{ Minimal error checking is done here. + * A garbage .less file will produce strange results. + * To avoid a large amount of error checking code here, we + * rely on the lesskey program to generate a good .less file. }} + */ + len = filesize(f); + if (len == NULL_POSITION || len < 3) + { + /* + * Bad file (valid file must have at least 3 chars). + */ + close(f); + return (-1); + } + if ((buf = (char *) calloc((int)len, sizeof(char))) == NULL) + { + close(f); + return (-1); + } + if (lseek(f, (off_t)0, SEEK_SET) == BAD_LSEEK) + { + free(buf); + close(f); + return (-1); + } + n = read(f, buf, (unsigned int) len); + close(f); + if (n != len) + { + free(buf); + return (-1); + } + + /* + * Figure out if this is an old-style (before version 241) + * or new-style lesskey file format. + */ + if (len < 4 || + buf[0] != C0_LESSKEY_MAGIC || buf[1] != C1_LESSKEY_MAGIC || + buf[2] != C2_LESSKEY_MAGIC || buf[3] != C3_LESSKEY_MAGIC) + return (old_lesskey(buf, (int)len)); + return (new_lesskey(buf, (int)len, sysvar)); +} + +#if HAVE_LESSKEYSRC +public int lesskey_src(char *filename, int sysvar) +{ + static struct lesskey_tables tables; + int r = parse_lesskey(filename, &tables); + if (r != 0) + return (r); + add_fcmd_table(xbuf_char_data(&tables.cmdtable.buf), tables.cmdtable.buf.end); + add_ecmd_table(xbuf_char_data(&tables.edittable.buf), tables.edittable.buf.end); + add_var_table(sysvar ? &list_sysvar_tables : &list_var_tables, + xbuf_char_data(&tables.vartable.buf), tables.vartable.buf.end); + return (0); +} + +void lesskey_parse_error(char *s) +{ + PARG parg; + parg.p_string = s; + error("%s", &parg); +} +#endif /* HAVE_LESSKEYSRC */ + +/* + * Add a lesskey file. + */ +public int add_hometable(int (*call_lesskey)(char *, int), char *envname, char *def_filename, int sysvar) +{ + char *filename; + int r; + + if (envname != NULL && (filename = lgetenv(envname)) != NULL) + filename = save(filename); + else if (sysvar) /* def_filename is full path */ + filename = save(def_filename); + else /* def_filename is just basename */ + { + /* Remove first char (normally a dot) unless stored in $HOME. */ + char *xdg = lgetenv("XDG_CONFIG_HOME"); + if (!isnullenv(xdg)) + filename = dirfile(xdg, &def_filename[1], 1); + if (filename == NULL) + { + char *home = lgetenv("HOME"); + if (!isnullenv(home)) + { + char *cfg_dir = dirfile(home, ".config", 0); + filename = dirfile(cfg_dir, &def_filename[1], 1); + free(cfg_dir); + } + } + if (filename == NULL) + filename = homefile(def_filename); + } + if (filename == NULL) + return -1; + r = (*call_lesskey)(filename, sysvar); + free(filename); + return (r); +} +#endif + +/* + * See if a char is a special line-editing command. + */ +public int editchar(int c, int flags) +{ + int action; + int nch; + char *s; + char usercmd[MAX_CMDLEN+1]; + + /* + * An editing character could actually be a sequence of characters; + * for example, an escape sequence sent by pressing the uparrow key. + * To match the editing string, we use the command decoder + * but give it the edit-commands command table + * This table is constructed to match the user's keyboard. + */ + if (c == erase_char || c == erase2_char) + return (EC_BACKSPACE); + if (c == kill_char) + { +#if MSDOS_COMPILER==WIN32C + if (!win32_kbhit()) +#endif + return (EC_LINEKILL); + } + + /* + * Collect characters in a buffer. + * Start with the one we have, and get more if we need them. + */ + nch = 0; + do { + if (nch > 0) + c = getcc(); + usercmd[nch] = c; + usercmd[nch+1] = '\0'; + nch++; + action = ecmd_decode(usercmd, &s); + } while (action == A_PREFIX && nch < MAX_CMDLEN); + + if (action == EC_X11MOUSE) + return (x11mouse_action(1)); + if (action == EC_X116MOUSE) + return (x116mouse_action(1)); + + if (flags & ECF_NORIGHTLEFT) + { + switch (action) + { + case EC_RIGHT: + case EC_LEFT: + action = A_INVALID; + break; + } + } +#if CMD_HISTORY + if (flags & ECF_NOHISTORY) + { + /* + * The caller says there is no history list. + * Reject any history-manipulation action. + */ + switch (action) + { + case EC_UP: + case EC_DOWN: + action = A_INVALID; + break; + } + } +#endif +#if TAB_COMPLETE_FILENAME + if (flags & ECF_NOCOMPLETE) + { + /* + * The caller says we don't want any filename completion cmds. + * Reject them. + */ + switch (action) + { + case EC_F_COMPLETE: + case EC_B_COMPLETE: + case EC_EXPAND: + action = A_INVALID; + break; + } + } +#endif + if ((flags & ECF_PEEK) || action == A_INVALID) + { + /* + * We're just peeking, or we didn't understand the command. + * Unget all the characters we read in the loop above. + * This does NOT include the original character that was + * passed in as a parameter. + */ + while (nch > 1) + { + ungetcc(usercmd[--nch]); + } + } else + { + if (s != NULL) + ungetsc(s); + } + return action; +} + diff --git a/third_party/less/defines.h b/third_party/less/defines.h new file mode 100644 index 000000000..b738cf8fb --- /dev/null +++ b/third_party/less/defines.h @@ -0,0 +1,475 @@ +/* defines.h. Generated from defines.h.in by configure. */ +/* defines.h.in. Generated from configure.ac by autoheader. */ + + +/* Unix definition file for less. -*- C -*- + * + * This file has 3 sections: + * User preferences. + * Settings always true on Unix. + * Settings automatically determined by configure. + * + * * * * * * WARNING * * * * * * + * If you edit defines.h by hand, do "touch stamp-h" before you run make + * so config.status doesn't overwrite your changes. + */ + +/* User preferences. */ + +/* + * SECURE is 1 if you wish to disable a bunch of features in order to + * be safe to run by unprivileged users. + * SECURE_COMPILE is set by the --with-secure configure option. + */ +#define SECURE SECURE_COMPILE + +/* + * SHELL_ESCAPE is 1 if you wish to allow shell escapes. + * (This is possible only if your system supplies the system() function.) + */ +#define SHELL_ESCAPE (!SECURE) + +/* + * EXAMINE is 1 if you wish to allow examining files by name from within less. + */ +#define EXAMINE (!SECURE) + +/* + * TAB_COMPLETE_FILENAME is 1 if you wish to allow the TAB key + * to complete filenames at prompts. + */ +#define TAB_COMPLETE_FILENAME (!SECURE) + +/* + * CMD_HISTORY is 1 if you wish to allow keys to cycle through + * previous commands at prompts. + */ +#define CMD_HISTORY 1 + +/* + * HILITE_SEARCH is 1 if you wish to have search targets to be + * displayed in standout mode. + */ +#define HILITE_SEARCH 1 + +/* + * EDITOR is 1 if you wish to allow editor invocation (the "v" command). + * (This is possible only if your system supplies the system() function.) + * EDIT_PGM is the name of the (default) editor to be invoked. + */ +#define EDITOR (!SECURE) + +/* + * TAGS is 1 if you wish to support tag files. + */ +#define TAGS (!SECURE) + +/* + * USERFILE is 1 if you wish to allow a .less file to specify + * user-defined key bindings. + */ +#define USERFILE (!SECURE) + +/* + * GLOB is 1 if you wish to have shell metacharacters expanded in filenames. + * This will generally work if your system provides the "popen" function + * and the "echo" shell command. + */ +#define GLOB (!SECURE) + +/* + * PIPEC is 1 if you wish to have the "|" command + * which allows the user to pipe data into a shell command. + */ +#define PIPEC (!SECURE && HAVE_POPEN) + +/* + * LOGFILE is 1 if you wish to allow the -o option (to create log files). + */ +#define LOGFILE (!SECURE) + +/* + * GNU_OPTIONS is 1 if you wish to support the GNU-style command + * line options --help and --version. + */ +#define GNU_OPTIONS 1 + +/* + * ONLY_RETURN is 1 if you want RETURN to be the only input which + * will continue past an error message. + * Otherwise, any key will continue past an error message. + */ +#define ONLY_RETURN 0 + +/* + * LESSKEYFILE is the filename of the default lesskey output file + * (in the HOME directory). + * LESSKEYFILE_SYS is the filename of the system-wide lesskey output file. + * DEF_LESSKEYINFILE is the filename of the default lesskey input + * (in the HOME directory). + * LESSHISTFILE is the filename of the history file + * (in the HOME directory). + */ +#define LESSKEYFILE ".less" +#define LESSKEYFILE_SYS SYSDIR "/sysless" +#define DEF_LESSKEYINFILE ".lesskey" +#define LESSKEYINFILE_SYS SYSDIR "/syslesskey" +#define LESSHISTFILE ".lesshst" + + +/* Settings always true on Unix. */ + +/* + * Define MSDOS_COMPILER if compiling under Microsoft C. + */ +#define MSDOS_COMPILER 0 + +/* + * Pathname separator character. + */ +#define PATHNAME_SEP "/" + +/* + * The value returned from tgetent on success. + * Some HP-UX systems return 0 on success. + */ +#define TGETENT_OK 1 + +/* + * HAVE_ANSI_PROTOS is 1 if your compiler supports ANSI function prototypes. + */ +#define HAVE_ANSI_PROTOS 1 + +/* + * HAVE_SYS_TYPES_H is 1 if your system has . + */ +#define HAVE_SYS_TYPES_H 1 + +/* + * Define if you have the header file. + */ +/* #undef HAVE_SGSTAT_H */ + +/* + * HAVE_PERROR is 1 if your system has the perror() call. + * (Actually, if it has sys_errlist, sys_nerr and errno.) + */ +#define HAVE_PERROR 1 + +/* + * HAVE_TIME is 1 if your system has the time() call. + */ +#define HAVE_TIME 1 + +/* + * HAVE_SHELL is 1 if your system supports a SHELL command interpreter. + */ +#define HAVE_SHELL 1 + +/* + * Default shell metacharacters and meta-escape character. + */ +#define DEF_METACHARS "; *?\t\n'\"()<>[]|&^`#\\$%=~{}," +#define DEF_METAESCAPE "\\" + +/* + * HAVE_DUP is 1 if your system has the dup() call. + */ +#define HAVE_DUP 1 + +/* Define to 1 if you have the memcpy() function. */ +#define HAVE_MEMCPY 1 + +/* Define to 1 if you have the strchr() function. */ +#define HAVE_STRCHR 1 + +/* Define to 1 if you have the strstr() function. */ +#define HAVE_STRSTR 1 + +/* Define to 1 to support reading lesskey source files (not just binary). */ +#define HAVE_LESSKEYSRC 1 + +/* + * Sizes of various buffers. + */ +#if 0 /* old sizes for small memory machines */ +#define CMDBUF_SIZE 512 /* Buffer for multichar commands */ +#define UNGOT_SIZE 100 /* Max chars to unget() */ +#define LINEBUF_SIZE 1024 /* Max size of line in input file */ +#define OUTBUF_SIZE 1024 /* Output buffer */ +#define PROMPT_SIZE 200 /* Max size of prompt string */ +#define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */ +#define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */ +#define TAGLINE_SIZE 512 /* Max size of line in tags file */ +#define TABSTOP_MAX 32 /* Max number of custom tab stops */ +#else /* more reasonable sizes for modern machines */ +#define CMDBUF_SIZE 2048 /* Buffer for multichar commands */ +#define UNGOT_SIZE 200 /* Max chars to unget() */ +#define LINEBUF_SIZE 1024 /* Initial max size of line in input file */ +#define OUTBUF_SIZE 1024 /* Output buffer */ +#define PROMPT_SIZE 2048 /* Max size of prompt string */ +#define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */ +#define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */ +#define TAGLINE_SIZE 1024 /* Max size of line in tags file */ +#define TABSTOP_MAX 128 /* Max number of custom tab stops */ +#endif + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Settings automatically determined by configure. */ + + +/* Define EDIT_PGM to your editor. */ +#define EDIT_PGM "vi" + +/* Define HAVE_CONST if your compiler supports the "const" modifier. */ +#define HAVE_CONST 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_CTYPE_H 1 + +/* Define HAVE_ERRNO if you have the errno variable. */ +#define HAVE_ERRNO 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the `fchmod' function. */ +#define HAVE_FCHMOD 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define HAVE_FILENO if you have the fileno() macro. */ +#define HAVE_FILENO 1 + +/* Define to 1 if you have the `fsync' function. */ +#define HAVE_FSYNC 1 + +/* GNU regex library */ +/* #undef HAVE_GNU_REGEX */ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LINUX_MAGIC_H */ + +/* Define HAVE_LOCALE if you have locale.h and setlocale. */ +#define HAVE_LOCALE 1 + +/* Define to 1 if you have the `nanosleep' function. */ +#define HAVE_NANOSLEEP 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_NCURSESW_TERMCAP_H */ + +/* Define to 1 if you have the "third_party/ncurses/termcap.h" header file. */ +#define HAVE_NCURSES_TERMCAP_H 1 + +/* Define HAVE_OSPEED if your termcap library has the ospeed variable. */ +#define HAVE_OSPEED 1 + +/* PCRE (Perl-compatible regular expression) library */ +/* #undef HAVE_PCRE */ + +/* PCRE2 (Perl-compatible regular expression) library */ +#define HAVE_PCRE2 1 + +/* Define to 1 if you have the `poll' function. */ +#define HAVE_POLL 1 + +/* Define to 1 if you have the `popen' function. */ +#define HAVE_POPEN 1 + +/* POSIX regcomp() and regex.h */ +/* #undef HAVE_POSIX_REGCOMP */ + +/* Define HAVE_PROCFS if have have fstatfs with f_type and PROC_SUPER_MAGIC. + */ +/* #undef HAVE_PROCFS */ + +/* Define to 1 if you have the `realpath' function. */ +#define HAVE_REALPATH 1 + +/* System V regcmp() */ +/* #undef HAVE_REGCMP */ + +/* */ +/* #undef HAVE_REGEXEC2 */ + +/* BSD re_comp() */ +/* #undef HAVE_RE_COMP */ + +/* Define HAVE_SIGEMPTYSET if you have the sigemptyset macro. */ +#define HAVE_SIGEMPTYSET 1 + +/* Define to 1 if you have the `sigprocmask' function. */ +#define HAVE_SIGPROCMASK 1 + +/* Define to 1 if you have the `sigsetmask' function. */ +/* #undef HAVE_SIGSETMASK */ + +/* Define to 1 if the system has the type `sigset_t'. */ +#define HAVE_SIGSET_T 1 + +/* Define to 1 if you have the `snprintf' function. */ +#define HAVE_SNPRINTF 1 + +/* Define to 1 if you have the `stat' function. */ +#define HAVE_STAT 1 + +/* Define HAVE_STAT_INO if your struct stat has st_ino and st_dev. */ +#define HAVE_STAT_INO 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDCKDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define HAVE_STRERROR if you have the strerror() function. */ +#define HAVE_STRERROR 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strsignal' function. */ +#define HAVE_STRSIGNAL 1 + +/* Define to 1 if you have the `system' function. */ +#define HAVE_SYSTEM 1 + +/* Define HAVE_SYS_ERRLIST if you have the sys_errlist[] variable. */ +#define HAVE_SYS_ERRLIST 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_STREAM_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_TERMCAP_H */ + +/* Define HAVE_TERMIOS_FUNCS if you have tcgetattr/tcsetattr. */ +#define HAVE_TERMIOS_FUNCS 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_TERMIO_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_TIME_H 1 + +/* Define HAVE_TIME_T if your system supports the "time_t" type. */ +#define HAVE_TIME_T 1 + +/* Define to 1 if you have the `ttyname' function. */ +#define HAVE_TTYNAME 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define HAVE_UPPER_LOWER if you have isupper, islower, toupper, tolower. */ +#define HAVE_UPPER_LOWER 1 + +/* Define to 1 if you have the `usleep' function. */ +#define HAVE_USLEEP 1 + +/* Henry Spencer V8 regcomp() and regexp.h */ +/* #undef HAVE_V8_REGCOMP */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_VALUES_H */ + +/* Define HAVE_VOID if your compiler supports the "void" type. */ +#define HAVE_VOID 1 + +/* Define HAVE_WCTYPE if you have iswupper, iswlower, towupper, towlower. */ +#define HAVE_WCTYPE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_WCTYPE_H 1 + +/* Define to 1 if you have the `_setjmp' function. */ +#define HAVE__SETJMP 1 + +/* Define MUST_DEFINE_ERRNO if you have errno but it is not define in errno.h. + */ +/* #undef MUST_DEFINE_ERRNO */ + +/* Define MUST_DEFINE_OSPEED if you have ospeed but it is not defined in + termcap.h. */ +#define MUST_DEFINE_OSPEED 1 + +/* pattern matching is supported, but without metacharacters. */ +/* #undef NO_REGEX */ + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "less" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "less 1" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "less" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "1" + +/* Define SECURE_COMPILE=1 to build a secure version of less. */ +#define SECURE_COMPILE 0 + +/* Define to 1 if the `S_IS*' macros in do not work properly. */ +/* #undef STAT_MACROS_BROKEN */ + +/* Define to 1 if all of the C90 standard headers exist (not just the ones + required in a freestanding environment). This macro is provided for + backward compatibility; new code need not use it. */ +#define STDC_HEADERS 1 + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `long int' if does not define. */ +/* #undef off_t */ + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ diff --git a/third_party/less/edit.c b/third_party/less/edit.c new file mode 100644 index 000000000..3ca5e4cc7 --- /dev/null +++ b/third_party/less/edit.c @@ -0,0 +1,1017 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +#include "less.h" +#include "position.h" +#if HAVE_STAT +#include +#endif +#if HAVE_SYS_WAIT_H +#include +#endif +#include + +public int fd0 = 0; + +extern int new_file; +extern int cbufs; +extern char *every_first_cmd; +extern int force_open; +extern int is_tty; +extern int sigs; +extern int hshift; +extern int want_filesize; +extern int consecutive_nulls; +extern int modelines; +extern int show_preproc_error; +extern IFILE curr_ifile; +extern IFILE old_ifile; +extern struct scrpos initial_scrpos; +extern void *ml_examine; +#if SPACES_IN_FILENAMES +extern char openquote; +extern char closequote; +#endif + +#if LOGFILE +extern int logfile; +extern int force_logfile; +extern char *namelogfile; +#endif + +#if HAVE_STAT_INO +public dev_t curr_dev; +public ino_t curr_ino; +#endif + +/* + * Textlist functions deal with a list of words separated by spaces. + * init_textlist sets up a textlist structure. + * forw_textlist uses that structure to iterate thru the list of + * words, returning each one as a standard null-terminated string. + * back_textlist does the same, but runs thru the list backwards. + */ +public void init_textlist(struct textlist *tlist, char *str) +{ + char *s; +#if SPACES_IN_FILENAMES + int meta_quoted = 0; + int delim_quoted = 0; + char *esc = get_meta_escape(); + int esclen = (int) strlen(esc); +#endif + + tlist->string = skipsp(str); + tlist->endstring = tlist->string + strlen(tlist->string); + for (s = str; s < tlist->endstring; s++) + { +#if SPACES_IN_FILENAMES + if (meta_quoted) + { + meta_quoted = 0; + } else if (esclen > 0 && s + esclen < tlist->endstring && + strncmp(s, esc, esclen) == 0) + { + meta_quoted = 1; + s += esclen - 1; + } else if (delim_quoted) + { + if (*s == closequote) + delim_quoted = 0; + } else /* (!delim_quoted) */ + { + if (*s == openquote) + delim_quoted = 1; + else if (*s == ' ') + *s = '\0'; + } +#else + if (*s == ' ') + *s = '\0'; +#endif + } +} + +public char * forw_textlist(struct textlist *tlist, char *prev) +{ + char *s; + + /* + * prev == NULL means return the first word in the list. + * Otherwise, return the word after "prev". + */ + if (prev == NULL) + s = tlist->string; + else + s = prev + strlen(prev); + if (s >= tlist->endstring) + return (NULL); + while (*s == '\0') + s++; + if (s >= tlist->endstring) + return (NULL); + return (s); +} + +public char * back_textlist(struct textlist *tlist, char *prev) +{ + char *s; + + /* + * prev == NULL means return the last word in the list. + * Otherwise, return the word before "prev". + */ + if (prev == NULL) + s = tlist->endstring; + else if (prev <= tlist->string) + return (NULL); + else + s = prev - 1; + while (*s == '\0') + s--; + if (s <= tlist->string) + return (NULL); + while (s[-1] != '\0' && s > tlist->string) + s--; + return (s); +} + +/* + * Parse a single option setting in a modeline. + */ +static void modeline_option(char *str, int opt_len) +{ + struct mloption { char *opt_name; void (*opt_func)(char*,int); }; + struct mloption options[] = { + { "ts=", set_tabs }, + { "tabstop=", set_tabs }, + { NULL, NULL } + }; + struct mloption *opt; + for (opt = options; opt->opt_name != NULL; opt++) + { + int name_len = strlen(opt->opt_name); + if (opt_len > name_len && strncmp(str, opt->opt_name, name_len) == 0) + { + (*opt->opt_func)(str + name_len, opt_len - name_len); + break; + } + } +} + +/* + * String length, terminated by option separator (space or colon). + * Space/colon can be escaped with backspace. + */ +static int modeline_option_len(char *str) +{ + int esc = FALSE; + char *s; + for (s = str; *s != '\0'; s++) + { + if (esc) + esc = FALSE; + else if (*s == '\\') + esc = TRUE; + else if (*s == ' ' || *s == ':') /* separator */ + break; + } + return (s - str); +} + +/* + * Parse colon- or space-separated option settings in a modeline. + */ +static void modeline_options(char *str, char end_char) +{ + for (;;) + { + int opt_len; + str = skipsp(str); + if (*str == '\0' || *str == end_char) + break; + opt_len = modeline_option_len(str); + modeline_option(str, opt_len); + str += opt_len; + if (*str != '\0') + str += 1; /* skip past the separator */ + } +} + +/* + * See if there is a modeline string in a line. + */ +static void check_modeline(char *line) +{ +#if HAVE_STRSTR + static char *pgms[] = { "less:", "vim:", "vi:", "ex:", NULL }; + char **pgm; + for (pgm = pgms; *pgm != NULL; ++pgm) + { + char *pline = line; + for (;;) + { + char *str; + pline = strstr(pline, *pgm); + if (pline == NULL) /* pgm is not in this line */ + break; + str = skipsp(pline + strlen(*pgm)); + if (pline == line || pline[-1] == ' ') + { + if (strncmp(str, "set ", 4) == 0) + modeline_options(str+4, ':'); + else if (pgm != &pgms[0]) /* "less:" requires "set" */ + modeline_options(str, '\0'); + break; + } + /* Continue searching the rest of the line. */ + pline = str; + } + } +#endif /* HAVE_STRSTR */ +} + +/* + * Read lines from start of file and check if any are modelines. + */ +static void check_modelines(void) +{ + POSITION pos = ch_zero(); + int i; + for (i = 0; i < modelines; i++) + { + char *line; + int line_len; + if (ABORT_SIGS()) + return; + pos = forw_raw_line(pos, &line, &line_len); + if (pos == NULL_POSITION) + break; + check_modeline(line); + } +} + +/* + * Close a pipe opened via popen. + */ +static void close_pipe(FILE *pipefd) +{ + int status; + PARG parg; + + if (pipefd == NULL) + return; +#if OS2 + /* + * The pclose function of OS/2 emx sometimes fails. + * Send SIGINT to the piped process before closing it. + */ + kill(pipefd->_pid, SIGINT); +#endif + status = pclose(pipefd); + if (status == -1) + { + /* An internal error in 'less', not a preprocessor error. */ + parg.p_string = errno_message("pclose"); + error("%s", &parg); + free(parg.p_string); + return; + } + if (!show_preproc_error) + return; +#if defined WIFEXITED && defined WEXITSTATUS + if (WIFEXITED(status)) + { + int s = WEXITSTATUS(status); + if (s != 0) + { + parg.p_int = s; + error("Input preprocessor failed (status %d)", &parg); + } + return; + } +#endif +#if defined WIFSIGNALED && defined WTERMSIG && HAVE_STRSIGNAL + if (WIFSIGNALED(status)) + { + int sig = WTERMSIG(status); + if (sig != SIGPIPE || ch_length() != NULL_POSITION) + { + parg.p_string = signal_message(sig); + error("Input preprocessor terminated: %s", &parg); + } + return; + } +#endif + if (status != 0) + { + parg.p_int = status; + error("Input preprocessor exited with status %x", &parg); + } +} + +/* + * Drain and close an input pipe if needed. + */ +public void close_altpipe(IFILE ifile) +{ + FILE *altpipe = get_altpipe(ifile); + if (altpipe != NULL && !(ch_getflags() & CH_KEEPOPEN)) + { + close_pipe(altpipe); + set_altpipe(ifile, NULL); + } +} + +/* + * Check for error status from the current altpipe. + * May or may not close the pipe. + */ +public void check_altpipe_error(void) +{ + if (!show_preproc_error) + return; + if (curr_ifile != NULL_IFILE && get_altfilename(curr_ifile) != NULL) + close_altpipe(curr_ifile); +} + +/* + * Close the current input file. + */ +static void close_file(void) +{ + struct scrpos scrpos; + char *altfilename; + + if (curr_ifile == NULL_IFILE) + return; + + /* + * Save the current position so that we can return to + * the same position if we edit this file again. + */ + get_scrpos(&scrpos, TOP); + if (scrpos.pos != NULL_POSITION) + { + store_pos(curr_ifile, &scrpos); + lastmark(); + } + /* + * Close the file descriptor, unless it is a pipe. + */ + ch_close(); + /* + * If we opened a file using an alternate name, + * do special stuff to close it. + */ + altfilename = get_altfilename(curr_ifile); + if (altfilename != NULL) + { + close_altpipe(curr_ifile); + close_altfile(altfilename, get_filename(curr_ifile)); + set_altfilename(curr_ifile, NULL); + } + curr_ifile = NULL_IFILE; +#if HAVE_STAT_INO + curr_ino = curr_dev = 0; +#endif +} + +/* + * Edit a new file (given its name). + * Filename == "-" means standard input. + * Filename == NULL means just close the current file. + */ +public int edit(char *filename) +{ + if (filename == NULL) + return (edit_ifile(NULL_IFILE)); + return (edit_ifile(get_ifile(filename, curr_ifile))); +} + +/* + * Clean up what edit_ifile did before error return. + */ +static int edit_error(char *filename, char *alt_filename, void *altpipe, IFILE ifile, IFILE was_curr_ifile) +{ + if (alt_filename != NULL) + { + close_pipe(altpipe); + close_altfile(alt_filename, filename); + free(alt_filename); + } + del_ifile(ifile); + free(filename); + /* + * Re-open the current file. + */ + if (was_curr_ifile == ifile) + { + /* + * Whoops. The "current" ifile is the one we just deleted. + * Just give up. + */ + quit(QUIT_ERROR); + } + reedit_ifile(was_curr_ifile); + return (1); +} + +/* + * Edit a new file (given its IFILE). + * ifile == NULL means just close the current file. + */ +public int edit_ifile(IFILE ifile) +{ + int f; + int answer; + int chflags; + char *filename; + char *open_filename; + char *alt_filename; + void *altpipe; + IFILE was_curr_ifile; + PARG parg; + + if (ifile == curr_ifile) + { + /* + * Already have the correct file open. + */ + return (0); + } + + /* + * We must close the currently open file now. + * This is necessary to make the open_altfile/close_altfile pairs + * nest properly (or rather to avoid nesting at all). + * {{ Some stupid implementations of popen() mess up if you do: + * fA = popen("A"); fB = popen("B"); pclose(fA); pclose(fB); }} + */ +#if LOGFILE + end_logfile(); +#endif + was_curr_ifile = save_curr_ifile(); + if (curr_ifile != NULL_IFILE) + { + chflags = ch_getflags(); + close_file(); + if ((chflags & CH_HELPFILE) && held_ifile(was_curr_ifile) <= 1) + { + /* + * Don't keep the help file in the ifile list. + */ + del_ifile(was_curr_ifile); + was_curr_ifile = old_ifile; + } + } + + if (ifile == NULL_IFILE) + { + /* + * No new file to open. + * (Don't set old_ifile, because if you call edit_ifile(NULL), + * you're supposed to have saved curr_ifile yourself, + * and you'll restore it if necessary.) + */ + unsave_ifile(was_curr_ifile); + return (0); + } + + filename = save(get_filename(ifile)); + + /* + * See if LESSOPEN specifies an "alternate" file to open. + */ + altpipe = get_altpipe(ifile); + if (altpipe != NULL) + { + /* + * File is already open. + * chflags and f are not used by ch_init if ifile has + * filestate which should be the case if we're here. + * Set them here to avoid uninitialized variable warnings. + */ + chflags = 0; + f = -1; + alt_filename = get_altfilename(ifile); + open_filename = (alt_filename != NULL) ? alt_filename : filename; + } else + { + if (strcmp(filename, FAKE_HELPFILE) == 0 || + strcmp(filename, FAKE_EMPTYFILE) == 0) + alt_filename = NULL; + else + alt_filename = open_altfile(filename, &f, &altpipe); + + open_filename = (alt_filename != NULL) ? alt_filename : filename; + + chflags = 0; + if (altpipe != NULL) + { + /* + * The alternate "file" is actually a pipe. + * f has already been set to the file descriptor of the pipe + * in the call to open_altfile above. + * Keep the file descriptor open because it was opened + * via popen(), and pclose() wants to close it. + */ + chflags |= CH_POPENED; + if (strcmp(filename, "-") == 0) + chflags |= CH_KEEPOPEN; + } else if (strcmp(filename, "-") == 0) + { + /* + * Use standard input. + * Keep the file descriptor open because we can't reopen it. + */ + f = fd0; + chflags |= CH_KEEPOPEN; + /* + * Must switch stdin to BINARY mode. + */ + SET_BINARY(f); +#if MSDOS_COMPILER==DJGPPC + /* + * Setting stdin to binary by default causes + * Ctrl-C to not raise SIGINT. We must undo + * that side-effect. + */ + __djgpp_set_ctrl_c(1); +#endif + } else if (strcmp(open_filename, FAKE_EMPTYFILE) == 0) + { + f = -1; + chflags |= CH_NODATA; + } else if (strcmp(open_filename, FAKE_HELPFILE) == 0) + { + f = -1; + chflags |= CH_HELPFILE; + } else if ((parg.p_string = bad_file(open_filename)) != NULL) + { + /* + * It looks like a bad file. Don't try to open it. + */ + error("%s", &parg); + free(parg.p_string); + return edit_error(filename, alt_filename, altpipe, ifile, was_curr_ifile); + } else if ((f = open(open_filename, OPEN_READ)) < 0) + { + /* + * Got an error trying to open it. + */ + parg.p_string = errno_message(filename); + error("%s", &parg); + free(parg.p_string); + return edit_error(filename, alt_filename, altpipe, ifile, was_curr_ifile); + } else + { + chflags |= CH_CANSEEK; + if (!force_open && !opened(ifile) && bin_file(f)) + { + /* + * Looks like a binary file. + * Ask user if we should proceed. + */ + parg.p_string = filename; + answer = query("\"%s\" may be a binary file. See it anyway? ", + &parg); + if (answer != 'y' && answer != 'Y') + { + close(f); + return edit_error(filename, alt_filename, altpipe, ifile, was_curr_ifile); + } + } + } + } + if (!force_open && f >= 0 && isatty(f)) + { + PARG parg; + parg.p_string = filename; + error("%s is a terminal (use -f to open it)", &parg); + return edit_error(filename, alt_filename, altpipe, ifile, was_curr_ifile); + } + + /* + * Get the new ifile. + * Get the saved position for the file. + */ + if (was_curr_ifile != NULL_IFILE) + { + old_ifile = was_curr_ifile; + unsave_ifile(was_curr_ifile); + } + curr_ifile = ifile; + set_altfilename(curr_ifile, alt_filename); + set_altpipe(curr_ifile, altpipe); + set_open(curr_ifile); /* File has been opened */ + get_pos(curr_ifile, &initial_scrpos); + new_file = TRUE; + ch_init(f, chflags); + consecutive_nulls = 0; + check_modelines(); + + if (!(chflags & CH_HELPFILE)) + { +#if LOGFILE + if (namelogfile != NULL && is_tty) + use_logfile(namelogfile); +#endif +#if HAVE_STAT_INO + /* Remember the i-number and device of the opened file. */ + if (strcmp(open_filename, "-") != 0) + { + struct stat statbuf; + int r = stat(open_filename, &statbuf); + if (r == 0) + { + curr_ino = statbuf.st_ino; + curr_dev = statbuf.st_dev; + } + } +#endif + if (every_first_cmd != NULL) + { + ungetsc(every_first_cmd); + ungetcc_back(CHAR_END_COMMAND); + } + } + + flush(); + + if (is_tty) + { + /* + * Output is to a real tty. + */ + + /* + * Indicate there is nothing displayed yet. + */ + pos_clear(); + clr_linenum(); +#if HILITE_SEARCH + clr_hilite(); +#endif + hshift = 0; + if (strcmp(filename, FAKE_HELPFILE) && strcmp(filename, FAKE_EMPTYFILE)) + { + char *qfilename = shell_quote(filename); + cmd_addhist(ml_examine, qfilename, 1); + free(qfilename); + } + if (want_filesize) + scan_eof(); + } + free(filename); + return (0); +} + +/* + * Edit a space-separated list of files. + * For each filename in the list, enter it into the ifile list. + * Then edit the first one. + */ +public int edit_list(char *filelist) +{ + IFILE save_ifile; + char *good_filename; + char *filename; + char *gfilelist; + char *gfilename; + char *qfilename; + struct textlist tl_files; + struct textlist tl_gfiles; + + save_ifile = save_curr_ifile(); + good_filename = NULL; + + /* + * Run thru each filename in the list. + * Try to glob the filename. + * If it doesn't expand, just try to open the filename. + * If it does expand, try to open each name in that list. + */ + init_textlist(&tl_files, filelist); + filename = NULL; + while ((filename = forw_textlist(&tl_files, filename)) != NULL) + { + gfilelist = lglob(filename); + init_textlist(&tl_gfiles, gfilelist); + gfilename = NULL; + while ((gfilename = forw_textlist(&tl_gfiles, gfilename)) != NULL) + { + qfilename = shell_unquote(gfilename); + if (edit(qfilename) == 0 && good_filename == NULL) + good_filename = get_filename(curr_ifile); + free(qfilename); + } + free(gfilelist); + } + /* + * Edit the first valid filename in the list. + */ + if (good_filename == NULL) + { + unsave_ifile(save_ifile); + return (1); + } + if (get_ifile(good_filename, curr_ifile) == curr_ifile) + { + /* + * Trying to edit the current file; don't reopen it. + */ + unsave_ifile(save_ifile); + return (0); + } + reedit_ifile(save_ifile); + return (edit(good_filename)); +} + +/* + * Edit the first file in the command line (ifile) list. + */ +public int edit_first(void) +{ + if (nifile() == 0) + return (edit_stdin()); + curr_ifile = NULL_IFILE; + return (edit_next(1)); +} + +/* + * Edit the last file in the command line (ifile) list. + */ +public int edit_last(void) +{ + curr_ifile = NULL_IFILE; + return (edit_prev(1)); +} + + +/* + * Edit the n-th next or previous file in the command line (ifile) list. + */ +static int edit_istep(IFILE h, int n, int dir) +{ + IFILE next; + + /* + * Skip n filenames, then try to edit each filename. + */ + for (;;) + { + next = (dir > 0) ? next_ifile(h) : prev_ifile(h); + if (--n < 0) + { + if (edit_ifile(h) == 0) + break; + } + if (next == NULL_IFILE) + { + /* + * Reached end of the ifile list. + */ + return (1); + } + if (ABORT_SIGS()) + { + /* + * Interrupt breaks out, if we're in a long + * list of files that can't be opened. + */ + return (1); + } + h = next; + } + /* + * Found a file that we can edit. + */ + return (0); +} + +static int edit_inext(IFILE h, int n) +{ + return (edit_istep(h, n, +1)); +} + +public int edit_next(int n) +{ + return edit_istep(curr_ifile, n, +1); +} + +static int edit_iprev(IFILE h, int n) +{ + return (edit_istep(h, n, -1)); +} + +public int edit_prev(int n) +{ + return edit_istep(curr_ifile, n, -1); +} + +/* + * Edit a specific file in the command line (ifile) list. + */ +public int edit_index(int n) +{ + IFILE h; + + h = NULL_IFILE; + do + { + if ((h = next_ifile(h)) == NULL_IFILE) + { + /* + * Reached end of the list without finding it. + */ + return (1); + } + } while (get_index(h) != n); + + return (edit_ifile(h)); +} + +public IFILE save_curr_ifile(void) +{ + if (curr_ifile != NULL_IFILE) + hold_ifile(curr_ifile, 1); + return (curr_ifile); +} + +public void unsave_ifile(IFILE save_ifile) +{ + if (save_ifile != NULL_IFILE) + hold_ifile(save_ifile, -1); +} + +/* + * Reedit the ifile which was previously open. + */ +public void reedit_ifile(IFILE save_ifile) +{ + IFILE next; + IFILE prev; + + /* + * Try to reopen the ifile. + * Note that opening it may fail (maybe the file was removed), + * in which case the ifile will be deleted from the list. + * So save the next and prev ifiles first. + */ + unsave_ifile(save_ifile); + next = next_ifile(save_ifile); + prev = prev_ifile(save_ifile); + if (edit_ifile(save_ifile) == 0) + return; + /* + * If can't reopen it, open the next input file in the list. + */ + if (next != NULL_IFILE && edit_inext(next, 0) == 0) + return; + /* + * If can't open THAT one, open the previous input file in the list. + */ + if (prev != NULL_IFILE && edit_iprev(prev, 0) == 0) + return; + /* + * If can't even open that, we're stuck. Just quit. + */ + quit(QUIT_ERROR); +} + +public void reopen_curr_ifile(void) +{ + IFILE save_ifile = save_curr_ifile(); + close_file(); + reedit_ifile(save_ifile); +} + +/* + * Edit standard input. + */ +public int edit_stdin(void) +{ + if (isatty(fd0)) + { + error("Missing filename (\"less --help\" for help)", NULL_PARG); + quit(QUIT_OK); + } + return (edit("-")); +} + +/* + * Copy a file directly to standard output. + * Used if standard output is not a tty. + */ +public void cat_file(void) +{ + int c; + + while ((c = ch_forw_get()) != EOI) + putchr(c); + flush(); +} + +#if LOGFILE + +#define OVERWRITE_OPTIONS "Overwrite, Append, Don't log, or Quit?" + +/* + * If the user asked for a log file and our input file + * is standard input, create the log file. + * We take care not to blindly overwrite an existing file. + */ +public void use_logfile(char *filename) +{ + int exists; + int answer; + PARG parg; + + if (ch_getflags() & CH_CANSEEK) + /* + * Can't currently use a log file on a file that can seek. + */ + return; + + /* + * {{ We could use access() here. }} + */ + exists = open(filename, OPEN_READ); + if (exists >= 0) + close(exists); + exists = (exists >= 0); + + /* + * Decide whether to overwrite the log file or append to it. + * If it doesn't exist we "overwrite" it. + */ + if (!exists || force_logfile) + { + /* + * Overwrite (or create) the log file. + */ + answer = 'O'; + } else + { + /* + * Ask user what to do. + */ + parg.p_string = filename; + answer = query("Warning: \"%s\" exists; "OVERWRITE_OPTIONS" ", &parg); + } + +loop: + switch (answer) + { + case 'O': case 'o': + /* + * Overwrite: create the file. + */ + logfile = creat(filename, CREAT_RW); + break; + case 'A': case 'a': + /* + * Append: open the file and seek to the end. + */ + logfile = open(filename, OPEN_APPEND); + if (lseek(logfile, (off_t)0, SEEK_END) == BAD_LSEEK) + { + close(logfile); + logfile = -1; + } + break; + case 'D': case 'd': + /* + * Don't do anything. + */ + return; + default: + /* + * Eh? + */ + + answer = query(OVERWRITE_OPTIONS" (Type \"O\", \"A\", \"D\" or \"Q\") ", NULL_PARG); + goto loop; + } + + if (logfile < 0) + { + /* + * Error in opening logfile. + */ + parg.p_string = filename; + error("Cannot write to \"%s\"", &parg); + return; + } + SET_BINARY(logfile); +} + +#endif diff --git a/third_party/less/filename.c b/third_party/less/filename.c new file mode 100644 index 000000000..a8726dc26 --- /dev/null +++ b/third_party/less/filename.c @@ -0,0 +1,1118 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * Routines to mess around with filenames (and files). + * Much of this is very OS dependent. + */ + +#include "less.h" +#include "lglob.h" +#if MSDOS_COMPILER +#include +#if MSDOS_COMPILER==WIN32C && !defined(_MSC_VER) +#include +#endif +#if MSDOS_COMPILER==DJGPPC +#include +#include +#define _MAX_PATH PATH_MAX +#endif +#endif +#ifdef _OSK +#include +#ifndef _OSK_MWC32 +#include +#endif +#endif + +#if HAVE_STAT +#include +#ifndef S_ISDIR +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#endif +#ifndef S_ISREG +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#endif +#endif + +extern int force_open; +extern int secure; +extern int use_lessopen; +extern int ctldisp; +extern int utf_mode; +extern IFILE curr_ifile; +extern IFILE old_ifile; +#if SPACES_IN_FILENAMES +extern char openquote; +extern char closequote; +#endif +#if HAVE_STAT_INO +extern ino_t curr_ino; +extern dev_t curr_dev; +#endif + +/* + * Remove quotes around a filename. + */ +public char * shell_unquote(char *str) +{ + char *name; + char *p; + + name = p = (char *) ecalloc(strlen(str)+1, sizeof(char)); + if (*str == openquote) + { + str++; + while (*str != '\0') + { + if (*str == closequote) + { + if (str[1] != closequote) + break; + str++; + } + *p++ = *str++; + } + } else + { + char *esc = get_meta_escape(); + int esclen = (int) strlen(esc); + while (*str != '\0') + { + if (esclen > 0 && strncmp(str, esc, esclen) == 0) + str += esclen; + *p++ = *str++; + } + } + *p = '\0'; + return (name); +} + +/* + * Get the shell's escape character. + */ +public char * get_meta_escape(void) +{ + char *s; + + s = lgetenv("LESSMETAESCAPE"); + if (s == NULL) + s = DEF_METAESCAPE; + return (s); +} + +/* + * Get the characters which the shell considers to be "metacharacters". + */ +static char * metachars(void) +{ + static char *mchars = NULL; + + if (mchars == NULL) + { + mchars = lgetenv("LESSMETACHARS"); + if (mchars == NULL) + mchars = DEF_METACHARS; + } + return (mchars); +} + +/* + * Is this a shell metacharacter? + */ +static int metachar(char c) +{ + return (strchr(metachars(), c) != NULL); +} + +/* + * Insert a backslash before each metacharacter in a string. + */ +public char * shell_quote(char *s) +{ + char *p; + char *newstr; + int len; + char *esc = get_meta_escape(); + int esclen = (int) strlen(esc); + int use_quotes = 0; + int have_quotes = 0; + + /* + * Determine how big a string we need to allocate. + */ + len = 1; /* Trailing null byte */ + for (p = s; *p != '\0'; p++) + { + len++; + if (*p == openquote || *p == closequote) + have_quotes = 1; + if (metachar(*p)) + { + if (esclen == 0) + { + /* + * We've got a metachar, but this shell + * doesn't support escape chars. Use quotes. + */ + use_quotes = 1; + } else + { + /* + * Allow space for the escape char. + */ + len += esclen; + } + } + } + if (use_quotes) + { + if (have_quotes) + /* + * We can't quote a string that contains quotes. + */ + return (NULL); + len = (int) strlen(s) + 3; + } + /* + * Allocate and construct the new string. + */ + newstr = p = (char *) ecalloc(len, sizeof(char)); + if (use_quotes) + { + SNPRINTF3(newstr, len, "%c%s%c", openquote, s, closequote); + } else + { + while (*s != '\0') + { + if (metachar(*s)) + { + /* + * Add the escape char. + */ + strcpy(p, esc); + p += esclen; + } + *p++ = *s++; + } + *p = '\0'; + } + return (newstr); +} + +/* + * Return a pathname that points to a specified file in a specified directory. + * Return NULL if the file does not exist in the directory. + */ +public char * dirfile(char *dirname, char *filename, int must_exist) +{ + char *pathname; + int len; + int f; + + if (dirname == NULL || *dirname == '\0') + return (NULL); + /* + * Construct the full pathname. + */ + len = (int) (strlen(dirname) + strlen(filename) + 2); + pathname = (char *) calloc(len, sizeof(char)); + if (pathname == NULL) + return (NULL); + SNPRINTF3(pathname, len, "%s%s%s", dirname, PATHNAME_SEP, filename); + if (must_exist) + { + /* + * Make sure the file exists. + */ + f = open(pathname, OPEN_READ); + if (f < 0) + { + free(pathname); + pathname = NULL; + } else + { + close(f); + } + } + return (pathname); +} + +/* + * Return the full pathname of the given file in the "home directory". + */ +public char * homefile(char *filename) +{ + char *pathname; + + /* Try $HOME/filename. */ + pathname = dirfile(lgetenv("HOME"), filename, 1); + if (pathname != NULL) + return (pathname); +#if OS2 + /* Try $INIT/filename. */ + pathname = dirfile(lgetenv("INIT"), filename, 1); + if (pathname != NULL) + return (pathname); +#endif +#if MSDOS_COMPILER || OS2 + /* Look for the file anywhere on search path. */ + pathname = (char *) ecalloc(_MAX_PATH, sizeof(char)); +#if MSDOS_COMPILER==DJGPPC + { + char *res = searchpath(filename); + if (res == 0) + *pathname = '\0'; + else + strcpy(pathname, res); + } +#else + _searchenv(filename, "PATH", pathname); +#endif + if (*pathname != '\0') + return (pathname); + free(pathname); +#endif + return (NULL); +} + +/* + * Expand a string, substituting any "%" with the current filename, + * and any "#" with the previous filename. + * But a string of N "%"s is just replaced with N-1 "%"s. + * Likewise for a string of N "#"s. + * {{ This is a lot of work just to support % and #. }} + */ +public char * fexpand(char *s) +{ + char *fr, *to; + int n; + char *e; + IFILE ifile; + +#define fchar_ifile(c) \ + ((c) == '%' ? curr_ifile : \ + (c) == '#' ? old_ifile : NULL_IFILE) + + /* + * Make one pass to see how big a buffer we + * need to allocate for the expanded string. + */ + n = 0; + for (fr = s; *fr != '\0'; fr++) + { + switch (*fr) + { + case '%': + case '#': + if (fr > s && fr[-1] == *fr) + { + /* + * Second (or later) char in a string + * of identical chars. Treat as normal. + */ + n++; + } else if (fr[1] != *fr) + { + /* + * Single char (not repeated). Treat specially. + */ + ifile = fchar_ifile(*fr); + if (ifile == NULL_IFILE) + n++; + else + n += (int) strlen(get_filename(ifile)); + } + /* + * Else it is the first char in a string of + * identical chars. Just discard it. + */ + break; + default: + n++; + break; + } + } + + e = (char *) ecalloc(n+1, sizeof(char)); + + /* + * Now copy the string, expanding any "%" or "#". + */ + to = e; + for (fr = s; *fr != '\0'; fr++) + { + switch (*fr) + { + case '%': + case '#': + if (fr > s && fr[-1] == *fr) + { + *to++ = *fr; + } else if (fr[1] != *fr) + { + ifile = fchar_ifile(*fr); + if (ifile == NULL_IFILE) + *to++ = *fr; + else + { + strcpy(to, get_filename(ifile)); + to += strlen(to); + } + } + break; + default: + *to++ = *fr; + break; + } + } + *to = '\0'; + return (e); +} + + +#if TAB_COMPLETE_FILENAME + +/* + * Return a blank-separated list of filenames which "complete" + * the given string. + */ +public char * fcomplete(char *s) +{ + char *fpat; + char *qs; + + if (secure) + return (NULL); + /* + * Complete the filename "s" by globbing "s*". + */ +#if MSDOS_COMPILER && (MSDOS_COMPILER == MSOFTC || MSDOS_COMPILER == BORLANDC) + /* + * But in DOS, we have to glob "s*.*". + * But if the final component of the filename already has + * a dot in it, just do "s*". + * (Thus, "FILE" is globbed as "FILE*.*", + * but "FILE.A" is globbed as "FILE.A*"). + */ + { + char *slash; + int len; + for (slash = s+strlen(s)-1; slash > s; slash--) + if (*slash == *PATHNAME_SEP || *slash == '/') + break; + len = (int) strlen(s) + 4; + fpat = (char *) ecalloc(len, sizeof(char)); + if (strchr(slash, '.') == NULL) + SNPRINTF1(fpat, len, "%s*.*", s); + else + SNPRINTF1(fpat, len, "%s*", s); + } +#else + { + int len = (int) strlen(s) + 2; + fpat = (char *) ecalloc(len, sizeof(char)); + SNPRINTF1(fpat, len, "%s*", s); + } +#endif + qs = lglob(fpat); + s = shell_unquote(qs); + if (strcmp(s,fpat) == 0) + { + /* + * The filename didn't expand. + */ + free(qs); + qs = NULL; + } + free(s); + free(fpat); + return (qs); +} +#endif + +/* + * Try to determine if a file is "binary". + * This is just a guess, and we need not try too hard to make it accurate. + */ +public int bin_file(int f) +{ + int n; + int bin_count = 0; + char data[256]; + char* p; + char* edata; + + if (!seekable(f)) + return (0); + if (lseek(f, (off_t)0, SEEK_SET) == BAD_LSEEK) + return (0); + n = read(f, data, sizeof(data)); + if (n <= 0) + return (0); + edata = &data[n]; + for (p = data; p < edata; ) + { + if (utf_mode && !is_utf8_well_formed(p, edata-p)) + { + bin_count++; + utf_skip_to_lead(&p, edata); + } else + { + LWCHAR c = step_char(&p, +1, edata); + struct ansi_state *pansi; + if (ctldisp == OPT_ONPLUS && (pansi = ansi_start(c)) != NULL) + { + skip_ansi(pansi, &p, edata); + ansi_done(pansi); + } else if (binary_char(c)) + bin_count++; + } + } + /* + * Call it a binary file if there are more than 5 binary characters + * in the first 256 bytes of the file. + */ + return (bin_count > 5); +} + +/* + * Try to determine the size of a file by seeking to the end. + */ +static POSITION seek_filesize(int f) +{ + off_t spos; + + spos = lseek(f, (off_t)0, SEEK_END); + if (spos == BAD_LSEEK) + return (NULL_POSITION); + return ((POSITION) spos); +} + +#if HAVE_POPEN +/* + * Read a string from a file. + * Return a pointer to the string in memory. + */ +static char * readfd(FILE *fd) +{ + int len; + int ch; + char *buf; + char *p; + + /* + * Make a guess about how many chars in the string + * and allocate a buffer to hold it. + */ + len = 100; + buf = (char *) ecalloc(len, sizeof(char)); + for (p = buf; ; p++) + { + if ((ch = getc(fd)) == '\n' || ch == EOF) + break; + if (p - buf >= len-1) + { + /* + * The string is too big to fit in the buffer we have. + * Allocate a new buffer, twice as big. + */ + len *= 2; + *p = '\0'; + p = (char *) ecalloc(len, sizeof(char)); + strcpy(p, buf); + free(buf); + buf = p; + p = buf + strlen(buf); + } + *p = ch; + } + *p = '\0'; + return (buf); +} + +/* + * Execute a shell command. + * Return a pointer to a pipe connected to the shell command's standard output. + */ +static FILE * shellcmd(char *cmd) +{ + FILE *fd; + +#if HAVE_SHELL + char *shell; + + shell = lgetenv("SHELL"); + if (!isnullenv(shell)) + { + char *scmd; + char *esccmd; + + /* + * Read the output of <$SHELL -c cmd>. + * Escape any metacharacters in the command. + */ + esccmd = shell_quote(cmd); + if (esccmd == NULL) + { + fd = popen(cmd, "r"); + } else + { + int len = (int) (strlen(shell) + strlen(esccmd) + 5); + scmd = (char *) ecalloc(len, sizeof(char)); + SNPRINTF3(scmd, len, "%s %s %s", shell, shell_coption(), esccmd); + free(esccmd); + fd = popen(scmd, "r"); + free(scmd); + } + } else +#endif + { + fd = popen(cmd, "r"); + } + /* + * Redirection in `popen' might have messed with the + * standard devices. Restore binary input mode. + */ + SET_BINARY(0); + return (fd); +} + +#endif /* HAVE_POPEN */ + + +/* + * Expand a filename, doing any system-specific metacharacter substitutions. + */ +public char * lglob(char *filename) +{ + char *gfilename; + + filename = fexpand(filename); + if (secure) + return (filename); + +#ifdef DECL_GLOB_LIST +{ + /* + * The globbing function returns a list of names. + */ + int length; + char *p; + char *qfilename; + DECL_GLOB_LIST(list) + + GLOB_LIST(filename, list); + if (GLOB_LIST_FAILED(list)) + { + return (filename); + } + length = 1; /* Room for trailing null byte */ + for (SCAN_GLOB_LIST(list, p)) + { + INIT_GLOB_LIST(list, p); + qfilename = shell_quote(p); + if (qfilename != NULL) + { + length += strlen(qfilename) + 1; + free(qfilename); + } + } + gfilename = (char *) ecalloc(length, sizeof(char)); + for (SCAN_GLOB_LIST(list, p)) + { + INIT_GLOB_LIST(list, p); + qfilename = shell_quote(p); + if (qfilename != NULL) + { + sprintf(gfilename + strlen(gfilename), "%s ", qfilename); + free(qfilename); + } + } + /* + * Overwrite the final trailing space with a null terminator. + */ + *--p = '\0'; + GLOB_LIST_DONE(list); +} +#else +#ifdef DECL_GLOB_NAME +{ + /* + * The globbing function returns a single name, and + * is called multiple times to walk thru all names. + */ + char *p; + int len; + int n; + char *pfilename; + char *qfilename; + DECL_GLOB_NAME(fnd,drive,dir,fname,ext,handle) + + GLOB_FIRST_NAME(filename, &fnd, handle); + if (GLOB_FIRST_FAILED(handle)) + { + return (filename); + } + + _splitpath(filename, drive, dir, fname, ext); + len = 100; + gfilename = (char *) ecalloc(len, sizeof(char)); + p = gfilename; + do { + n = (int) (strlen(drive) + strlen(dir) + strlen(fnd.GLOB_NAME) + 1); + pfilename = (char *) ecalloc(n, sizeof(char)); + SNPRINTF3(pfilename, n, "%s%s%s", drive, dir, fnd.GLOB_NAME); + qfilename = shell_quote(pfilename); + free(pfilename); + if (qfilename != NULL) + { + n = (int) strlen(qfilename); + while (p - gfilename + n + 2 >= len) + { + /* + * No room in current buffer. + * Allocate a bigger one. + */ + len *= 2; + *p = '\0'; + p = (char *) ecalloc(len, sizeof(char)); + strcpy(p, gfilename); + free(gfilename); + gfilename = p; + p = gfilename + strlen(gfilename); + } + strcpy(p, qfilename); + free(qfilename); + p += n; + *p++ = ' '; + } + } while (GLOB_NEXT_NAME(handle, &fnd) == 0); + + /* + * Overwrite the final trailing space with a null terminator. + */ + *--p = '\0'; + GLOB_NAME_DONE(handle); +} +#else +#if HAVE_POPEN +{ + /* + * We get the shell to glob the filename for us by passing + * an "echo" command to the shell and reading its output. + */ + FILE *fd; + char *s; + char *lessecho; + char *cmd; + char *esc; + int len; + + esc = get_meta_escape(); + if (strlen(esc) == 0) + esc = "-"; + esc = shell_quote(esc); + if (esc == NULL) + { + return (filename); + } + lessecho = lgetenv("LESSECHO"); + if (isnullenv(lessecho)) + lessecho = "lessecho"; + /* + * Invoke lessecho, and read its output (a globbed list of filenames). + */ + len = (int) (strlen(lessecho) + strlen(filename) + (7*strlen(metachars())) + 24); + cmd = (char *) ecalloc(len, sizeof(char)); + SNPRINTF4(cmd, len, "%s -p0x%x -d0x%x -e%s ", lessecho, + (unsigned char) openquote, (unsigned char) closequote, esc); + free(esc); + for (s = metachars(); *s != '\0'; s++) + sprintf(cmd + strlen(cmd), "-n0x%x ", (unsigned char) *s); + sprintf(cmd + strlen(cmd), "-- %s", filename); + fd = shellcmd(cmd); + free(cmd); + if (fd == NULL) + { + /* + * Cannot create the pipe. + * Just return the original (fexpanded) filename. + */ + return (filename); + } + gfilename = readfd(fd); + pclose(fd); + if (*gfilename == '\0') + { + free(gfilename); + return (filename); + } +} +#else + /* + * No globbing functions at all. Just use the fexpanded filename. + */ + gfilename = save(filename); +#endif +#endif +#endif + free(filename); + return (gfilename); +} + +/* + * Does path not represent something in the file system? + */ +public int is_fake_pathname(char *path) +{ + return (strcmp(path, "-") == 0 || + strcmp(path, FAKE_HELPFILE) == 0 || strcmp(path, FAKE_EMPTYFILE) == 0); +} + +/* + * Return canonical pathname. + */ +public char * lrealpath(char *path) +{ + if (!is_fake_pathname(path)) + { +#if HAVE_REALPATH + char rpath[PATH_MAX]; + if (realpath(path, rpath) != NULL) + return (save(rpath)); +#endif + } + return (save(path)); +} + +#if HAVE_POPEN +/* + * Return number of %s escapes in a string. + * Return a large number if there are any other % escapes besides %s. + */ +static int num_pct_s(char *lessopen) +{ + int num = 0; + + while (*lessopen != '\0') + { + if (*lessopen == '%') + { + if (lessopen[1] == '%') + ++lessopen; + else if (lessopen[1] == 's') + ++num; + else + return (999); + } + ++lessopen; + } + return (num); +} +#endif + +/* + * See if we should open a "replacement file" + * instead of the file we're about to open. + */ +public char * open_altfile(char *filename, int *pf, void **pfd) +{ +#if !HAVE_POPEN + return (NULL); +#else + char *lessopen; + char *qfilename; + char *cmd; + int len; + FILE *fd; +#if HAVE_FILENO + int returnfd = 0; +#endif + + if (!use_lessopen || secure) + return (NULL); + ch_ungetchar(-1); + if ((lessopen = lgetenv("LESSOPEN")) == NULL) + return (NULL); + while (*lessopen == '|') + { + /* + * If LESSOPEN starts with a |, it indicates + * a "pipe preprocessor". + */ +#if !HAVE_FILENO + error("LESSOPEN pipe is not supported", NULL_PARG); + return (NULL); +#else + lessopen++; + returnfd++; +#endif + } + if (*lessopen == '-') + { + /* + * Lessopen preprocessor will accept "-" as a filename. + */ + lessopen++; + } else + { + if (strcmp(filename, "-") == 0) + return (NULL); + } + if (num_pct_s(lessopen) != 1) + { + error("LESSOPEN ignored: must contain exactly one %%s", NULL_PARG); + return (NULL); + } + + qfilename = shell_quote(filename); + len = (int) (strlen(lessopen) + strlen(qfilename) + 2); + cmd = (char *) ecalloc(len, sizeof(char)); + SNPRINTF1(cmd, len, lessopen, qfilename); + free(qfilename); + fd = shellcmd(cmd); + free(cmd); + if (fd == NULL) + { + /* + * Cannot create the pipe. + */ + return (NULL); + } +#if HAVE_FILENO + if (returnfd) + { + char c; + int f; + + /* + * The alt file is a pipe. Read one char + * to see if the pipe will produce any data. + * If it does, push the char back on the pipe. + */ + f = fileno(fd); + SET_BINARY(f); + if (read(f, &c, 1) != 1) + { + /* + * Pipe is empty. + * If more than 1 pipe char was specified, + * the exit status tells whether the file itself + * is empty, or if there is no alt file. + * If only one pipe char, just assume no alt file. + */ + int status = pclose(fd); + if (returnfd > 1 && status == 0) { + /* File is empty. */ + *pfd = NULL; + *pf = -1; + return (save(FAKE_EMPTYFILE)); + } + /* No alt file. */ + return (NULL); + } + /* Alt pipe contains data, so use it. */ + ch_ungetchar(c); + *pfd = (void *) fd; + *pf = f; + return (save("-")); + } +#endif + /* The alt file is a regular file. Read its name from LESSOPEN. */ + cmd = readfd(fd); + pclose(fd); + if (*cmd == '\0') + { + /* + * Pipe is empty. This means there is no alt file. + */ + free(cmd); + return (NULL); + } + return (cmd); +#endif /* HAVE_POPEN */ +} + +/* + * Close a replacement file. + */ +public void close_altfile(char *altfilename, char *filename) +{ +#if HAVE_POPEN + char *lessclose; + char *qfilename; + char *qaltfilename; + FILE *fd; + char *cmd; + int len; + + if (secure) + return; + ch_ungetchar(-1); + if ((lessclose = lgetenv("LESSCLOSE")) == NULL) + return; + if (num_pct_s(lessclose) > 2) + { + error("LESSCLOSE ignored; must contain no more than 2 %%s", NULL_PARG); + return; + } + qfilename = shell_quote(filename); + qaltfilename = shell_quote(altfilename); + len = (int) (strlen(lessclose) + strlen(qfilename) + strlen(qaltfilename) + 2); + cmd = (char *) ecalloc(len, sizeof(char)); + SNPRINTF2(cmd, len, lessclose, qfilename, qaltfilename); + free(qaltfilename); + free(qfilename); + fd = shellcmd(cmd); + free(cmd); + if (fd != NULL) + pclose(fd); +#endif +} + +/* + * Is the specified file a directory? + */ +public int is_dir(char *filename) +{ + int isdir = 0; + +#if HAVE_STAT +{ + int r; + struct stat statbuf; + + r = stat(filename, &statbuf); + isdir = (r >= 0 && S_ISDIR(statbuf.st_mode)); +} +#else +#ifdef _OSK +{ + int f; + + f = open(filename, S_IREAD | S_IFDIR); + if (f >= 0) + close(f); + isdir = (f >= 0); +} +#endif +#endif + return (isdir); +} + +/* + * Returns NULL if the file can be opened and + * is an ordinary file, otherwise an error message + * (if it cannot be opened or is a directory, etc.) + */ +public char * bad_file(char *filename) +{ + char *m = NULL; + + if (!force_open && is_dir(filename)) + { + static char is_a_dir[] = " is a directory"; + + m = (char *) ecalloc(strlen(filename) + sizeof(is_a_dir), + sizeof(char)); + strcpy(m, filename); + strcat(m, is_a_dir); + } else + { +#if HAVE_STAT + int r; + struct stat statbuf; + + r = stat(filename, &statbuf); + if (r < 0) + { + m = errno_message(filename); + } else if (force_open) + { + m = NULL; + } else if (!S_ISREG(statbuf.st_mode)) + { + static char not_reg[] = " is not a regular file (use -f to see it)"; + m = (char *) ecalloc(strlen(filename) + sizeof(not_reg), + sizeof(char)); + strcpy(m, filename); + strcat(m, not_reg); + } +#endif + } + return (m); +} + +/* + * Return the size of a file, as cheaply as possible. + * In Unix, we can stat the file. + */ +public POSITION filesize(int f) +{ +#if HAVE_STAT + struct stat statbuf; + + if (fstat(f, &statbuf) >= 0) + return ((POSITION) statbuf.st_size); +#else +#ifdef _OSK + long size; + + if ((size = (long) _gs_size(f)) >= 0) + return ((POSITION) size); +#endif +#endif + return (seek_filesize(f)); +} + +public int curr_ifile_changed(void) +{ +#if HAVE_STAT_INO + /* + * If the file's i-number or device has changed, + * or if the file is smaller than it previously was, + * the file must be different. + */ + struct stat st; + POSITION curr_pos = ch_tell(); + int r = stat(get_filename(curr_ifile), &st); + if (r == 0 && (st.st_ino != curr_ino || + st.st_dev != curr_dev || + (curr_pos != NULL_POSITION && st.st_size < curr_pos))) + return (TRUE); +#endif + return (FALSE); +} + +/* + * + */ +public char * shell_coption(void) +{ + return ("-c"); +} + +/* + * Return last component of a pathname. + */ +public char * last_component(char *name) +{ + char *slash; + + for (slash = name + strlen(name); slash > name; ) + { + --slash; + if (*slash == *PATHNAME_SEP || *slash == '/') + return (slash + 1); + } + return (name); +} diff --git a/third_party/less/fmt.inc b/third_party/less/fmt.inc new file mode 100644 index 000000000..d873c7d27 --- /dev/null +++ b/third_party/less/fmt.inc @@ -0,0 +1,22 @@ +/* Generated by "./mkutable -f2 Cf -- unicode/UnicodeData.txt" on Mon Nov 14 18:19:23 PST 2022 */ + { 0x00ad, 0x00ad }, /* Cf */ + { 0x0600, 0x0605 }, /* Cf */ + { 0x061c, 0x061c }, /* Cf */ + { 0x06dd, 0x06dd }, /* Cf */ + { 0x070f, 0x070f }, /* Cf */ + { 0x0890, 0x0891 }, /* Cf */ + { 0x08e2, 0x08e2 }, /* Cf */ + { 0x180e, 0x180e }, /* Cf */ + { 0x200b, 0x200f }, /* Cf */ + { 0x202a, 0x202e }, /* Cf */ + { 0x2060, 0x2064 }, /* Cf */ + { 0x2066, 0x206f }, /* Cf */ + { 0xfeff, 0xfeff }, /* Cf */ + { 0xfff9, 0xfffb }, /* Cf */ + { 0x110bd, 0x110bd }, /* Cf */ + { 0x110cd, 0x110cd }, /* Cf */ + { 0x13430, 0x1343f }, /* Cf */ + { 0x1bca0, 0x1bca3 }, /* Cf */ + { 0x1d173, 0x1d17a }, /* Cf */ + { 0xe0001, 0xe0001 }, /* Cf */ + { 0xe0020, 0xe007f }, /* Cf */ diff --git a/third_party/less/forwback.c b/third_party/less/forwback.c new file mode 100644 index 000000000..d1f90e2ce --- /dev/null +++ b/third_party/less/forwback.c @@ -0,0 +1,549 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * Primitives for displaying the file on the screen, + * scrolling either forward or backward. + */ + +#include "less.h" +#include "position.h" + +public int screen_trashed; +public int squished; +public int no_back_scroll = 0; +public int forw_prompt; +public int first_time = 1; + +extern int sigs; +extern int top_scroll; +extern int quiet; +extern int sc_width, sc_height; +extern int hshift; +extern int auto_wrap; +extern int plusoption; +extern int forw_scroll; +extern int back_scroll; +extern int ignore_eoi; +extern int clear_bg; +extern int final_attr; +extern int header_lines; +extern int header_cols; +extern int full_screen; +#if HILITE_SEARCH +extern int size_linebuf; +extern int hilite_search; +extern int status_col; +#endif +#if TAGS +extern char *tagoption; +#endif + +/* + * Sound the bell to indicate user is trying to move past end of file. + */ +public void eof_bell(void) +{ +#if HAVE_TIME + static time_type last_eof_bell = 0; + time_type now = get_time(); + if (now == last_eof_bell) /* max once per second */ + return; + last_eof_bell = now; +#endif + if (quiet == NOT_QUIET) + bell(); + else + vbell(); +} + +/* + * Check to see if the end of file is currently displayed. + */ +public int eof_displayed(void) +{ + POSITION pos; + + if (ignore_eoi) + return (0); + + if (ch_length() == NULL_POSITION) + /* + * If the file length is not known, + * we can't possibly be displaying EOF. + */ + return (0); + + /* + * 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); + return (pos == NULL_POSITION || pos == ch_length()); +} + +/* + * Check to see if the entire file is currently displayed. + */ +public int entire_file_displayed(void) +{ + POSITION pos; + + /* Make sure last line of file is displayed. */ + if (!eof_displayed()) + return (0); + + /* Make sure first line of file is displayed. */ + pos = position(0); + return (pos == NULL_POSITION || pos == 0); +} + +/* + * 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. + */ +public void squish_check(void) +{ + if (!squished) + return; + squished = 0; + repaint(); +} + +/* + * Read the first pfx columns of the next line. + * If skipeol==0 stop there, otherwise read and discard chars to end of line. + */ +static POSITION forw_line_pfx(POSITION pos, int pfx, int skipeol) +{ + int save_sc_width = sc_width; + int save_auto_wrap = auto_wrap; + int save_hshift = hshift; + /* Set fake sc_width to force only pfx chars to be read. */ + sc_width = pfx + line_pfx_width(); + auto_wrap = 0; + hshift = 0; + pos = forw_line_seg(pos, skipeol, FALSE, FALSE); + sc_width = save_sc_width; + auto_wrap = save_auto_wrap; + hshift = save_hshift; + return pos; +} + +/* + * Set header text color. + * Underline last line of headers, but not at beginning of file + * (where there is no gap between the last header line and the next line). + */ +static void set_attr_header(int ln) +{ + set_attr_line(AT_COLOR_HEADER); + if (ln+1 == header_lines && position(0) != ch_zero()) + set_attr_line(AT_UNDERLINE); +} + +/* + * Display file headers, overlaying text already drawn + * at top and left of screen. + */ +public int overlay_header(void) +{ + POSITION pos = ch_zero(); /* header lines are at beginning of file */ + int ln; + int moved = FALSE; + + if (header_lines > 0) + { + /* Draw header_lines lines from start of file at top of screen. */ + home(); + for (ln = 0; ln < header_lines; ++ln) + { + pos = forw_line(pos); + set_attr_header(ln); + clear_eol(); + put_line(); + } + moved = TRUE; + } + if (header_cols > 0) + { + /* Draw header_cols columns at left of each line. */ + home(); + pos = ch_zero(); + for (ln = 0; ln < sc_height-1; ++ln) + { + if (ln >= header_lines) /* switch from header lines to normal lines */ + pos = position(ln); + if (pos == NULL_POSITION) + putchr('\n'); + else + { + /* Need skipeol for all header lines except the last one. */ + pos = forw_line_pfx(pos, header_cols, ln+1 < header_lines); + set_attr_header(ln); + put_line(); + } + } + moved = TRUE; + } + if (moved) + lower_left(); + return moved; +} + +/* + * Display n lines, scrolling forward, + * starting at position pos in the input file. + * "force" means display the n lines even if we hit end of file. + * "only_last" means display only the last screenful if n > screen size. + * "nblank" is the number of blank lines to draw before the first + * real line. If nblank > 0, the pos must be NULL_POSITION. + * The first real line after the blanks will start at ch_zero(). + */ +public void forw(int n, POSITION pos, int force, int only_last, int nblank) +{ + int nlines = 0; + int do_repaint; + + squish_check(); + + /* + * do_repaint tells us not to display anything till the end, + * then just repaint the entire screen. + * We repaint if we are supposed to display only the last + * screenful and the request is for more than a screenful. + * Also if the request exceeds the forward scroll limit + * (but not if the request is for exactly a screenful, since + * repainting itself involves scrolling forward a screenful). + */ + do_repaint = (only_last && n > sc_height-1) || + (forw_scroll >= 0 && n > forw_scroll && n != sc_height-1); + +#if HILITE_SEARCH + if (pos != NULL_POSITION && (hilite_search == OPT_ONPLUS || is_filtering() || status_col)) { + prep_hilite(pos, pos + 4*size_linebuf, ignore_eoi ? 1 : -1); + pos = next_unfiltered(pos); + } +#endif + + if (!do_repaint) + { + if (top_scroll && n >= sc_height - 1 && pos != ch_length()) + { + /* + * 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. }} + */ + pos_clear(); + add_forw_pos(pos); + force = 1; + clear(); + home(); + } + + if (pos != position(BOTTOM_PLUS_ONE) || empty_screen()) + { + /* + * This is not contiguous with what is + * currently displayed. Clear the screen image + * (position table) and start a new screen. + */ + pos_clear(); + add_forw_pos(pos); + force = 1; + if (top_scroll) + { + clear(); + home(); + } else if (!first_time && !is_filtering() && full_screen) + { + putstr("...skipping...\n"); + } + } + } + + while (--n >= 0) + { + /* + * Read the next line of input. + */ + if (nblank > 0) + { + /* + * Still drawing blanks; don't get a line + * from the file yet. + * If this is the last blank line, get ready to + * read a line starting at ch_zero() next time. + */ + if (--nblank == 0) + pos = ch_zero(); + } else + { + /* + * Get the next line from the file. + */ + pos = forw_line(pos); +#if HILITE_SEARCH + pos = next_unfiltered(pos); +#endif + if (pos == NULL_POSITION) + { + /* + * End of file: stop here unless the top line + * is still empty, or "force" is true. + * Even if force is true, stop when the last + * line in the file reaches the top of screen. + */ + if (!force && position(TOP) != NULL_POSITION) + break; + if (!empty_lines(0, 0) && + !empty_lines(1, 1) && + empty_lines(2, sc_height-1)) + break; + } + } + /* + * Add the position of the next line to the position table. + * Display the current line on the screen. + */ + add_forw_pos(pos); + nlines++; + 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 + option or a -t option + * was given. These options 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 && pos == NULL_POSITION && !top_scroll && + header_lines == 0 && header_cols == 0 && +#if TAGS + tagoption == NULL && +#endif + !plusoption) + { + squished = 1; + continue; + } + put_line(); +#if 0 + /* {{ + * Can't call clear_eol here. The cursor might be at end of line + * on an ignaw terminal, so clear_eol would clear the last char + * of the current line instead of all of the next line. + * If we really need to do this on clear_bg terminals, we need + * to find a better way. + * }} + */ + if (clear_bg && apply_at_specials(final_attr) != AT_NORMAL) + { + /* + * Writing the last character on the last line + * of the display may have scrolled the screen. + * If we were in standout mode, clear_bg terminals + * will fill the new line with the standout color. + * Now we're in normal mode again, so clear the line. + */ + clear_eol(); + } +#endif + forw_prompt = 1; + } + + if (header_lines > 0) + { + /* + * Don't allow ch_zero to appear on screen except at top of screen. + * Otherwise duplicate header lines may be displayed. + */ + if (onscreen(ch_zero()) > 0) + { + jump_loc(ch_zero(), 0); /* {{ yuck }} */ + return; + } + } + if (nlines == 0 && !ignore_eoi) + eof_bell(); + else if (do_repaint) + repaint(); + else + { + overlay_header(); + /* lower_left(); {{ considered harmful? }} */ + } + first_time = 0; + (void) currline(BOTTOM); +} + +/* + * Display n lines, scrolling backward. + */ +public void back(int n, POSITION pos, int force, int only_last) +{ + int nlines = 0; + int do_repaint; + + squish_check(); + do_repaint = (n > get_back_scroll() || (only_last && n > sc_height-1) || header_lines > 0); +#if HILITE_SEARCH + if (pos != NULL_POSITION && (hilite_search == OPT_ONPLUS || is_filtering() || status_col)) { + prep_hilite((pos < 3*size_linebuf) ? 0 : pos - 3*size_linebuf, pos, -1); + } +#endif + while (--n >= 0) + { + /* + * Get the previous line of input. + */ +#if HILITE_SEARCH + pos = prev_unfiltered(pos); +#endif + + pos = back_line(pos); + if (pos == NULL_POSITION) + { + /* + * Beginning of file: stop here unless "force" is true. + */ + if (!force) + break; + } + /* + * Add the position of the previous line to the position table. + * Display the line on the screen. + */ + add_back_pos(pos); + nlines++; + if (!do_repaint) + { + home(); + add_line(); + put_line(); + } + } + if (nlines == 0) + eof_bell(); + else if (do_repaint) + repaint(); + else + { + overlay_header(); + lower_left(); + } + (void) currline(BOTTOM); +} + +/* + * Display n more lines, forward. + * Start just after the line currently displayed at the bottom of the screen. + */ +public void forward(int n, int force, int only_last) +{ + POSITION pos; + + if (get_quit_at_eof() && eof_displayed() && !(ch_getflags() & CH_HELPFILE)) + { + /* + * If the -e flag is set and we're trying to go + * forward from end-of-file, go on to the next file. + */ + if (edit_next(1)) + quit(QUIT_OK); + return; + } + + pos = position(BOTTOM_PLUS_ONE); + if (pos == NULL_POSITION && (!force || empty_lines(2, sc_height-1))) + { + if (ignore_eoi) + { + /* + * ignore_eoi is to support A_F_FOREVER. + * Back up until there is a line at the bottom + * of the screen. + */ + if (empty_screen()) + pos = ch_zero(); + else + { + do + { + back(1, position(TOP), 1, 0); + pos = position(BOTTOM_PLUS_ONE); + } while (pos == NULL_POSITION && !ABORT_SIGS()); + } + } else + { + eof_bell(); + return; + } + } + forw(n, pos, force, only_last, 0); +} + +/* + * Display n more lines, backward. + * Start just before the line currently displayed at the top of the screen. + */ +public void backward(int n, int force, int only_last) +{ + POSITION pos; + + pos = position(TOP); + if (pos == NULL_POSITION && (!force || position(BOTTOM) == 0)) + { + eof_bell(); + return; + } + back(n, pos, force, only_last); +} + +/* + * 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. + */ +public int get_back_scroll(void) +{ + if (no_back_scroll) + return (0); + if (back_scroll >= 0) + return (back_scroll); + if (top_scroll) + return (sc_height - 2); + return (10000); /* infinity */ +} + +/* + * Will the entire file fit on one screen? + */ +public int get_one_screen(void) +{ + int nlines; + POSITION pos = ch_zero(); + + for (nlines = 0; nlines < sc_height; nlines++) + { + pos = forw_line(pos); + if (pos == NULL_POSITION) break; + } + return (nlines < sc_height); +} diff --git a/third_party/less/funcs.h b/third_party/less/funcs.h new file mode 100644 index 000000000..1c9b181c0 --- /dev/null +++ b/third_party/less/funcs.h @@ -0,0 +1,385 @@ +public char * save(constant char *s); +public void out_of_memory(void); +public void * ecalloc(int count, unsigned int size); +public char * skipsp(char *s); +public int sprefix(char *ps, char *s, int uppercase); +public void quit(int status); +public void raw_mode(int on); +public void scrsize(void); +public char * special_key_str(int key); +public void get_term(void); +public void init_mouse(void); +public void deinit_mouse(void); +public void init(void); +public void deinit(void); +public int interactive(void); +public void home(void); +public void dump_screen(void); +public void add_line(void); +public void remove_top(int n); +public void win32_scroll_up(int n); +public void lower_left(void); +public void line_left(void); +public void check_winch(void); +public void goto_line(int sindex); +public void vbell(void); +public void bell(void); +public void clear(void); +public void clear_eol(void); +public void clear_bot(void); +public COLOR_TYPE parse_color(char *str, int *p_fg, int *p_bg); +public void at_enter(int attr); +public void at_exit(void); +public void at_switch(int attr); +public int is_at_equiv(int attr1, int attr2); +public int apply_at_specials(int attr); +public void putbs(void); +public int win32_kbhit(void); +public char WIN32getch(void); +public void WIN32ungetch(int ch); +public void WIN32setcolors(int fg, int bg); +public void WIN32textout(char *text, int len); +public void match_brac(char obrac, char cbrac, int forwdir, int n); +public void ch_ungetchar(int c); +public void end_logfile(void); +public void sync_logfile(void); +public int ch_seek(POSITION pos); +public int ch_end_seek(void); +public int ch_end_buffer_seek(void); +public int ch_beg_seek(void); +public POSITION ch_length(void); +public POSITION ch_tell(void); +public int ch_forw_get(void); +public int ch_back_get(void); +public void ch_setbufspace(int bufspace); +public void ch_flush(void); +public int seekable(int f); +public void ch_set_eof(void); +public void ch_init(int f, int flags); +public void ch_close(void); +public int ch_getflags(void); +public void setfmt(char *s, char **fmtvarptr, int *attrptr, char *default_fmt, int for_printf); +public void init_charset(void); +public int binary_char(LWCHAR c); +public int control_char(LWCHAR c); +public char * prchar(LWCHAR c); +public char * prutfchar(LWCHAR ch); +public int utf_len(int ch); +public int is_utf8_well_formed(char *ss, int slen); +public void utf_skip_to_lead(char **pp, char *limit); +public LWCHAR get_wchar(constant char *p); +public void put_wchar(char **pp, LWCHAR ch); +public LWCHAR step_char(char **pp, signed int dir, constant char *limit); +public int is_composing_char(LWCHAR ch); +public int is_ubin_char(LWCHAR ch); +public int is_wide_char(LWCHAR ch); +public int is_combining_char(LWCHAR ch1, LWCHAR ch2); +public void cmd_reset(void); +public void clear_cmd(void); +public void cmd_putstr(constant char *s); +public int len_cmdbuf(void); +public void cmd_repaint(constant char *old_cp); +public void set_mlist(void *mlist, int cmdflags); +public void cmd_addhist(struct mlist *mlist, constant char *cmd, int modified); +public void cmd_accept(void); +public int cmd_char(int c); +public LINENUM cmd_int(long *frac); +public char * get_cmdbuf(void); +public char * cmd_lastpattern(void); +public void init_cmdhist(void); +public void save_cmdhist(void); +public int in_mca(void); +public int norm_search_type(int st); +public void dispversion(void); +public int getcc(void); +public void ungetcc(LWCHAR c); +public void ungetcc_back(LWCHAR c); +public void ungetsc(char *s); +public LWCHAR peekcc(void); +public void commands(void); +public int cvt_length(int len, int ops); +public int * cvt_alloc_chpos(int len); +public void cvt_text(char *odst, char *osrc, int *chpos, int *lenp, int ops); +public void expand_cmd_tables(void); +public void init_cmds(void); +public void add_fcmd_table(char *buf, int len); +public void add_ecmd_table(char *buf, int len); +public int fcmd_decode(char *cmd, char **sp); +public int ecmd_decode(char *cmd, char **sp); +public char * lgetenv(char *var); +public int isnullenv(char *s); +public int lesskey(char *filename, int sysvar); +public int lesskey_src(char *filename, int sysvar); +public int add_hometable(int (*call_lesskey)(char *, int), char *envname, char *def_filename, int sysvar); +public int editchar(int c, int flags); +public void init_textlist(struct textlist *tlist, char *str); +public char * forw_textlist(struct textlist *tlist, char *prev); +public char * back_textlist(struct textlist *tlist, char *prev); +public void close_altpipe(IFILE ifile); +public void check_altpipe_error(void); +public int edit(char *filename); +public int edit_ifile(IFILE ifile); +public int edit_list(char *filelist); +public int edit_first(void); +public int edit_last(void); +public int edit_next(int n); +public int edit_prev(int n); +public int edit_index(int n); +public IFILE save_curr_ifile(void); +public void unsave_ifile(IFILE save_ifile); +public void reedit_ifile(IFILE save_ifile); +public void reopen_curr_ifile(void); +public int edit_stdin(void); +public void cat_file(void); +public void use_logfile(char *filename); +public char * shell_unquote(char *str); +public char * get_meta_escape(void); +public char * shell_quote(char *s); +public char * dirfile(char *dirname, char *filename, int must_exist); +public char * homefile(char *filename); +public char * fexpand(char *s); +public char * fcomplete(char *s); +public int bin_file(int f); +public char * lglob(char *filename); +public int is_fake_pathname(char *path); +public char * lrealpath(char *path); +public char * open_altfile(char *filename, int *pf, void **pfd); +public void close_altfile(char *altfilename, char *filename); +public int is_dir(char *filename); +public char * bad_file(char *filename); +public POSITION filesize(int f); +public int curr_ifile_changed(void); +public char * shell_coption(void); +public char * last_component(char *name); +public void eof_bell(void); +public int eof_displayed(void); +public int entire_file_displayed(void); +public void squish_check(void); +public int overlay_header(void); +public void forw(int n, POSITION pos, int force, int only_last, int nblank); +public void back(int n, POSITION pos, int force, int only_last); +public void forward(int n, int force, int only_last); +public void backward(int n, int force, int only_last); +public int get_back_scroll(void); +public int get_one_screen(void); +public void del_ifile(IFILE h); +public IFILE next_ifile(IFILE h); +public IFILE prev_ifile(IFILE h); +public IFILE getoff_ifile(IFILE ifile); +public int nifile(void); +public IFILE get_ifile(char *filename, IFILE prev); +public char * get_filename(IFILE ifile); +public char * get_real_filename(IFILE ifile); +public int get_index(IFILE ifile); +public void store_pos(IFILE ifile, struct scrpos *scrpos); +public void get_pos(IFILE ifile, struct scrpos *scrpos); +public void set_open(IFILE ifile); +public int opened(IFILE ifile); +public void hold_ifile(IFILE ifile, int incr); +public int held_ifile(IFILE ifile); +public void * get_filestate(IFILE ifile); +public void set_filestate(IFILE ifile, void *filestate); +public void set_altpipe(IFILE ifile, void *p); +public void *get_altpipe(IFILE ifile); +public void set_altfilename(IFILE ifile, char *altfilename); +public char * get_altfilename(IFILE ifile); +public void if_dump(void); +public POSITION forw_line_seg(POSITION curr_pos, int skipeol, int rscroll, int nochop); +public POSITION forw_line(POSITION curr_pos); +public POSITION back_line(POSITION curr_pos); +public void set_attnpos(POSITION pos); +public void jump_forw(void); +public void jump_forw_buffered(void); +public void jump_back(LINENUM linenum); +public void repaint(void); +public void jump_percent(int percent, long fraction); +public void jump_line_loc(POSITION pos, int sline); +public void jump_loc(POSITION pos, int sline); +public void init_line(void); +public int is_ascii_char(LWCHAR ch); +public POSITION line_position(void); +public void prewind(void); +public void plinestart(POSITION pos); +public int line_pfx_width(void); +public void pshift_all(void); +public int pwidth(LWCHAR ch, int a, LWCHAR prev_ch, int prev_a); +public void savec(void); +public void loadc(void); +public int is_ansi_end(LWCHAR ch); +public int is_ansi_middle(LWCHAR ch); +public void skip_ansi(struct ansi_state *pansi, char **pp, constant char *limit); +public struct ansi_state * ansi_start(LWCHAR ch); +public int ansi_step(struct ansi_state *pansi, LWCHAR ch); +public void ansi_done(struct ansi_state *pansi); +public int pappend(int c, POSITION pos); +public int pflushmbc(void); +public void pdone(int endline, int chopped, int forw); +public void set_attr_line(int a); +public void set_status_col(char c, int attr); +public int gline(int i, int *ap); +public void null_line(void); +public POSITION forw_raw_line(POSITION curr_pos, char **linep, int *line_lenp); +public POSITION back_raw_line(POSITION curr_pos, char **linep, int *line_lenp); +public int skip_columns(int cols, char **linep, int *line_lenp); +public void load_line(constant char *str); +public int rrshift(void); +public int set_color_map(int attr, char *colorstr); +public char * get_color_map(int attr); +public void clr_linenum(void); +public void add_lnum(LINENUM linenum, POSITION pos); +public LINENUM find_linenum(POSITION pos); +public POSITION find_pos(LINENUM linenum); +public LINENUM currline(int where); +public void scan_eof(void); +public LINENUM vlinenum(LINENUM linenum); +public void lsystem(char *cmd, char *donemsg); +public int pipe_mark(int c, char *cmd); +public int pipe_data(char *cmd, POSITION spos, POSITION epos); +public void init_mark(void); +public int badmark(LWCHAR c); +public void setmark(LWCHAR c, int where); +public void clrmark(LWCHAR c); +public void lastmark(void); +public void gomark(LWCHAR c); +public POSITION markpos(LWCHAR c); +public char posmark(POSITION pos); +public void unmark(IFILE ifile); +public void mark_check_ifile(IFILE ifile); +public void save_marks(FILE *fout, char *hdr); +public void restore_mark(char *line); +public void opt_o(int type, char *s); +public void opt__O(int type, char *s); +public void opt_j(int type, char *s); +public void calc_jump_sline(void); +public void opt_shift(int type, char *s); +public void calc_shift_count(void); +public void opt_k(int type, char *s); +public void opt_ks(int type, char *s); +public void opt_t(int type, char *s); +public void opt__T(int type, char *s); +public void opt_p(int type, char *s); +public void opt__P(int type, char *s); +public void opt_b(int type, char *s); +public void opt_i(int type, char *s); +public void opt__V(int type, char *s); +public void opt_D(int type, char *s); +public void set_tabs(char *s, int len); +public void opt_x(int type, char *s); +public void opt_quote(int type, char *s); +public void opt_rscroll(int type, char *s); +public void opt_query(int type, char *s); +public void opt_mousecap(int type, char *s); +public void opt_wheel_lines(int type, char *s); +public void opt_linenum_width(int type, char *s); +public void opt_status_col_width(int type, char *s); +public void opt_filesize(int type, char *s); +public void opt_intr(int type, char *s); +public void opt_header(int type, char *s); +public void opt_search_type(int type, char *s); +public void opt_ttyin_name(int type, char *s); +public int chop_line(void); +public int get_swindow(void); +public char * propt(int c); +public void scan_option(char *s); +public void toggle_option(struct loption *o, int lower, char *s, int how_toggle); +public int opt_has_param(struct loption *o); +public char * opt_prompt(struct loption *o); +public char * opt_toggle_disallowed(int c); +public int isoptpending(void); +public void nopendopt(void); +public int getnum(char **sp, char *printopt, int *errp); +public long getfraction(char **sp, char *printopt, int *errp); +public int get_quit_at_eof(void); +public void init_option(void); +public struct loption * findopt(int c); +public struct loption * findopt_name(char **p_optname, char **p_oname, int *p_err); +public void init_poll(void); +public int supports_ctrl_x(void); +public int iread(int fd, unsigned char *buf, unsigned int len); +public void intread(void); +public time_type get_time(void); +public char * errno_message(char *filename); +public char * signal_message(int sig); +public uintmax muldiv(uintmax val, uintmax num, uintmax den); +public int percentage(POSITION num, POSITION den); +public POSITION percent_pos(POSITION pos, int percent, long fraction); +public int os9_signal(int type, RETSIGTYPE (*handler)()); +public void sleep_ms(int ms); +public void put_line(void); +public void flush(void); +public void set_output(int fd); +public int putchr(int c); +public void clear_bot_if_needed(void); +public void putstr(constant char *s); +public int less_printf(char *fmt, PARG *parg); +public void get_return(void); +public void error(char *fmt, PARG *parg); +public void ierror(char *fmt, PARG *parg); +public void ixerror(char *fmt, PARG *parg); +public int query(char *fmt, PARG *parg); +public int compile_pattern(char *pattern, int search_type, int show_error, PATTERN_TYPE *comp_pattern); +public void uncompile_pattern(PATTERN_TYPE *pattern); +public int valid_pattern(char *pattern); +public int is_null_pattern(PATTERN_TYPE pattern); +public int match_pattern(PATTERN_TYPE pattern, char *tpattern, char *line, int line_len, char **sp, char **ep, int nsp, int notbol, int search_type); +public char * pattern_lib_name(void); +public POSITION position(int sindex); +public void add_forw_pos(POSITION pos); +public void add_back_pos(POSITION pos); +public void pos_clear(void); +public void pos_init(void); +public int onscreen(POSITION pos); +public int empty_screen(void); +public int empty_lines(int s, int e); +public void get_scrpos(struct scrpos *scrpos, int where); +public int sindex_from_sline(int sline); +public void init_prompt(void); +public char * pr_expand(constant char *proto); +public char * eq_message(void); +public char * pr_string(void); +public char * wait_message(void); +public void init_search(void); +public void repaint_hilite(int on); +public void clear_attn(void); +public void undo_search(int clear); +public void clr_hlist(struct hilite_tree *anchor); +public void clr_hilite(void); +public void clr_filter(void); +public int is_filtered(POSITION pos); +public POSITION next_unfiltered(POSITION pos); +public POSITION prev_unfiltered(POSITION pos); +public int is_hilited_attr(POSITION pos, POSITION epos, int nohide, int *p_matches); +public void chg_hilite(void); +public void chg_caseless(void); +public int search(int search_type, char *pattern, int n); +public void prep_hilite(POSITION spos, POSITION epos, int maxlines); +public void set_filter_pattern(char *pattern, int search_type); +public int is_filtering(void); +public RETSIGTYPE winch(int type); +public void init_signals(int on); +public void psignals(void); +public void cleantags(void); +public int gettagtype(void); +public void findtag(char *tag); +public POSITION tagsearch(void); +public char * nexttag(int n); +public char * prevtag(int n); +public int ntags(void); +public int curr_tag(void); +public int edit_tagfile(void); +public int open_tty(void); +public void open_getchr(void); +public void close_getchr(void); +public int pclose(FILE *f); +public int default_wheel_lines(void); +public int getchr(void); +public void xbuf_init(struct xbuffer *xbuf); +public void xbuf_deinit(struct xbuffer *xbuf); +public void xbuf_reset(struct xbuffer *xbuf); +public void xbuf_add_byte(struct xbuffer *xbuf, unsigned char b); +public void xbuf_add_data(struct xbuffer *xbuf, unsigned char *data, int len); +public int xbuf_pop(struct xbuffer *buf); +public void xbuf_set(struct xbuffer *dst, struct xbuffer *src); +public char * xbuf_char_data(struct xbuffer *xbuf); +public int help_ckd_add(void *r, uintmax a, uintmax b, int rsize, int rsigned); +public int help_ckd_mul(void *r, uintmax a, uintmax b, int rsize, int rsigned); diff --git a/third_party/less/help.c b/third_party/less/help.c new file mode 100644 index 000000000..423e0393e --- /dev/null +++ b/third_party/less/help.c @@ -0,0 +1,303 @@ +/* This file was generated by mkhelp.pl from less.hlp at 22:43 on 2023/7/20 */ +#include "less.h" +constant char helpdata[] = { +'\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','\b','S','U','\b','U','M','\b','M','M','\b','M','A','\b','A','R','\b','R','Y','\b','Y',' ','O','\b','O','F','\b','F',' ','L','\b','L','E','\b','E','S','\b','S','S','\b','S',' ','C','\b','C','O','\b','O','M','\b','M','M','\b','M','A','\b','A','N','\b','N','D','\b','D','S','\b','S','\n', +'\n', +' ',' ',' ',' ',' ',' ','C','o','m','m','a','n','d','s',' ','m','a','r','k','e','d',' ','w','i','t','h',' ','*',' ','m','a','y',' ','b','e',' ','p','r','e','c','e','d','e','d',' ','b','y',' ','a',' ','n','u','m','b','e','r',',',' ','_','\b','N','.','\n', +' ',' ',' ',' ',' ',' ','N','o','t','e','s',' ','i','n',' ','p','a','r','e','n','t','h','e','s','e','s',' ','i','n','d','i','c','a','t','e',' ','t','h','e',' ','b','e','h','a','v','i','o','r',' ','i','f',' ','_','\b','N',' ','i','s',' ','g','i','v','e','n','.','\n', +' ',' ',' ',' ',' ',' ','A',' ','k','e','y',' ','p','r','e','c','e','d','e','d',' ','b','y',' ','a',' ','c','a','r','e','t',' ','i','n','d','i','c','a','t','e','s',' ','t','h','e',' ','C','t','r','l',' ','k','e','y',';',' ','t','h','u','s',' ','^','K',' ','i','s',' ','c','t','r','l','-','K','.','\n', +'\n', +' ',' ','h',' ',' ','H',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','t','h','i','s',' ','h','e','l','p','.','\n', +' ',' ','q',' ',' ',':','q',' ',' ','Q',' ',' ',':','Q',' ',' ','Z','Z',' ',' ',' ',' ',' ','E','x','i','t','.','\n', +' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n', +'\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','M','\b','M','O','\b','O','V','\b','V','I','\b','I','N','\b','N','G','\b','G','\n', +'\n', +' ',' ','e',' ',' ','^','E',' ',' ','j',' ',' ','^','N',' ',' ','C','R',' ',' ','*',' ',' ','F','o','r','w','a','r','d',' ',' ','o','n','e',' ','l','i','n','e',' ',' ',' ','(','o','r',' ','_','\b','N',' ','l','i','n','e','s',')','.','\n', +' ',' ','y',' ',' ','^','Y',' ',' ','k',' ',' ','^','K',' ',' ','^','P',' ',' ','*',' ',' ','B','a','c','k','w','a','r','d',' ','o','n','e',' ','l','i','n','e',' ',' ',' ','(','o','r',' ','_','\b','N',' ','l','i','n','e','s',')','.','\n', +' ',' ','f',' ',' ','^','F',' ',' ','^','V',' ',' ','S','P','A','C','E',' ',' ','*',' ',' ','F','o','r','w','a','r','d',' ',' ','o','n','e',' ','w','i','n','d','o','w',' ','(','o','r',' ','_','\b','N',' ','l','i','n','e','s',')','.','\n', +' ',' ','b',' ',' ','^','B',' ',' ','E','S','C','-','v',' ',' ',' ',' ',' ',' ','*',' ',' ','B','a','c','k','w','a','r','d',' ','o','n','e',' ','w','i','n','d','o','w',' ','(','o','r',' ','_','\b','N',' ','l','i','n','e','s',')','.','\n', +' ',' ','z',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','F','o','r','w','a','r','d',' ',' ','o','n','e',' ','w','i','n','d','o','w',' ','(','a','n','d',' ','s','e','t',' ','w','i','n','d','o','w',' ','t','o',' ','_','\b','N',')','.','\n', +' ',' ','w',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','B','a','c','k','w','a','r','d',' ','o','n','e',' ','w','i','n','d','o','w',' ','(','a','n','d',' ','s','e','t',' ','w','i','n','d','o','w',' ','t','o',' ','_','\b','N',')','.','\n', +' ',' ','E','S','C','-','S','P','A','C','E',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','F','o','r','w','a','r','d',' ',' ','o','n','e',' ','w','i','n','d','o','w',',',' ','b','u','t',' ','d','o','n','\'','t',' ','s','t','o','p',' ','a','t',' ','e','n','d','-','o','f','-','f','i','l','e','.','\n', +' ',' ','d',' ',' ','^','D',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','F','o','r','w','a','r','d',' ',' ','o','n','e',' ','h','a','l','f','-','w','i','n','d','o','w',' ','(','a','n','d',' ','s','e','t',' ','h','a','l','f','-','w','i','n','d','o','w',' ','t','o',' ','_','\b','N',')','.','\n', +' ',' ','u',' ',' ','^','U',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','B','a','c','k','w','a','r','d',' ','o','n','e',' ','h','a','l','f','-','w','i','n','d','o','w',' ','(','a','n','d',' ','s','e','t',' ','h','a','l','f','-','w','i','n','d','o','w',' ','t','o',' ','_','\b','N',')','.','\n', +' ',' ','E','S','C','-',')',' ',' ','R','i','g','h','t','A','r','r','o','w',' ','*',' ',' ','R','i','g','h','t',' ','o','n','e',' ','h','a','l','f',' ','s','c','r','e','e','n',' ','w','i','d','t','h',' ','(','o','r',' ','_','\b','N',' ','p','o','s','i','t','i','o','n','s',')','.','\n', +' ',' ','E','S','C','-','(',' ',' ','L','e','f','t','A','r','r','o','w',' ',' ','*',' ',' ','L','e','f','t',' ',' ','o','n','e',' ','h','a','l','f',' ','s','c','r','e','e','n',' ','w','i','d','t','h',' ','(','o','r',' ','_','\b','N',' ','p','o','s','i','t','i','o','n','s',')','.','\n', +' ',' ','E','S','C','-','}',' ',' ','^','R','i','g','h','t','A','r','r','o','w',' ',' ',' ','R','i','g','h','t',' ','t','o',' ','l','a','s','t',' ','c','o','l','u','m','n',' ','d','i','s','p','l','a','y','e','d','.','\n', +' ',' ','E','S','C','-','{',' ',' ','^','L','e','f','t','A','r','r','o','w',' ',' ',' ',' ','L','e','f','t',' ',' ','t','o',' ','f','i','r','s','t',' ','c','o','l','u','m','n','.','\n', +' ',' ','F',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','F','o','r','w','a','r','d',' ','f','o','r','e','v','e','r',';',' ','l','i','k','e',' ','"','t','a','i','l',' ','-','f','"','.','\n', +' ',' ','E','S','C','-','F',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','L','i','k','e',' ','F',' ','b','u','t',' ','s','t','o','p',' ','w','h','e','n',' ','s','e','a','r','c','h',' ','p','a','t','t','e','r','n',' ','i','s',' ','f','o','u','n','d','.','\n', +' ',' ','r',' ',' ','^','R',' ',' ','^','L',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','p','a','i','n','t',' ','s','c','r','e','e','n','.','\n', +' ',' ','R',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','p','a','i','n','t',' ','s','c','r','e','e','n',',',' ','d','i','s','c','a','r','d','i','n','g',' ','b','u','f','f','e','r','e','d',' ','i','n','p','u','t','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n', +' ',' ',' ',' ',' ',' ',' ',' ','D','e','f','a','u','l','t',' ','"','w','i','n','d','o','w','"',' ','i','s',' ','t','h','e',' ','s','c','r','e','e','n',' ','h','e','i','g','h','t','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ','D','e','f','a','u','l','t',' ','"','h','a','l','f','-','w','i','n','d','o','w','"',' ','i','s',' ','h','a','l','f',' ','o','f',' ','t','h','e',' ','s','c','r','e','e','n',' ','h','e','i','g','h','t','.','\n', +' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n', +'\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','\b','S','E','\b','E','A','\b','A','R','\b','R','C','\b','C','H','\b','H','I','\b','I','N','\b','N','G','\b','G','\n', +'\n', +' ',' ','/','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','S','e','a','r','c','h',' ','f','o','r','w','a','r','d',' ','f','o','r',' ','(','_','\b','N','-','t','h',')',' ','m','a','t','c','h','i','n','g',' ','l','i','n','e','.','\n', +' ',' ','?','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','S','e','a','r','c','h',' ','b','a','c','k','w','a','r','d',' ','f','o','r',' ','(','_','\b','N','-','t','h',')',' ','m','a','t','c','h','i','n','g',' ','l','i','n','e','.','\n', +' ',' ','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','R','e','p','e','a','t',' ','p','r','e','v','i','o','u','s',' ','s','e','a','r','c','h',' ','(','f','o','r',' ','_','\b','N','-','t','h',' ','o','c','c','u','r','r','e','n','c','e',')','.','\n', +' ',' ','N',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','R','e','p','e','a','t',' ','p','r','e','v','i','o','u','s',' ','s','e','a','r','c','h',' ','i','n',' ','r','e','v','e','r','s','e',' ','d','i','r','e','c','t','i','o','n','.','\n', +' ',' ','E','S','C','-','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','R','e','p','e','a','t',' ','p','r','e','v','i','o','u','s',' ','s','e','a','r','c','h',',',' ','s','p','a','n','n','i','n','g',' ','f','i','l','e','s','.','\n', +' ',' ','E','S','C','-','N',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','R','e','p','e','a','t',' ','p','r','e','v','i','o','u','s',' ','s','e','a','r','c','h',',',' ','r','e','v','e','r','s','e',' ','d','i','r','.',' ','&',' ','s','p','a','n','n','i','n','g',' ','f','i','l','e','s','.','\n', +' ',' ','E','S','C','-','u',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','n','d','o',' ','(','t','o','g','g','l','e',')',' ','s','e','a','r','c','h',' ','h','i','g','h','l','i','g','h','t','i','n','g','.','\n', +' ',' ','E','S','C','-','U',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','l','e','a','r',' ','s','e','a','r','c','h',' ','h','i','g','h','l','i','g','h','t','i','n','g','.','\n', +' ',' ','&','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','D','i','s','p','l','a','y',' ','o','n','l','y',' ','m','a','t','c','h','i','n','g',' ','l','i','n','e','s','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n', +' ',' ',' ',' ',' ',' ',' ',' ','A',' ','s','e','a','r','c','h',' ','p','a','t','t','e','r','n',' ','m','a','y',' ','b','e','g','i','n',' ','w','i','t','h',' ','o','n','e',' ','o','r',' ','m','o','r','e',' ','o','f',':','\n', +' ',' ',' ',' ',' ',' ',' ',' ','^','N',' ','o','r',' ','!',' ',' ','S','e','a','r','c','h',' ','f','o','r',' ','N','O','N','-','m','a','t','c','h','i','n','g',' ','l','i','n','e','s','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ','^','E',' ','o','r',' ','*',' ',' ','S','e','a','r','c','h',' ','m','u','l','t','i','p','l','e',' ','f','i','l','e','s',' ','(','p','a','s','s',' ','t','h','r','u',' ','E','N','D',' ','O','F',' ','F','I','L','E',')','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ','^','F',' ','o','r',' ','@',' ',' ','S','t','a','r','t',' ','s','e','a','r','c','h',' ','a','t',' ','F','I','R','S','T',' ','f','i','l','e',' ','(','f','o','r',' ','/',')',' ','o','r',' ','l','a','s','t',' ','f','i','l','e',' ','(','f','o','r',' ','?',')','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ','^','K',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','m','a','t','c','h','e','s',',',' ','b','u','t',' ','d','o','n','\'','t',' ','m','o','v','e',' ','(','K','E','E','P',' ','p','o','s','i','t','i','o','n',')','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ','^','R',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','u','s','e',' ','R','E','G','U','L','A','R',' ','E','X','P','R','E','S','S','I','O','N','S','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ','^','S',' ','_','\b','n',' ',' ',' ',' ',' ','S','e','a','r','c','h',' ','f','o','r',' ','m','a','t','c','h',' ','i','n',' ','_','\b','n','-','t','h',' ','p','a','r','e','n','t','h','e','s','i','z','e','d',' ','s','u','b','p','a','t','t','e','r','n','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ','^','W',' ',' ',' ',' ',' ',' ',' ','W','R','A','P',' ','s','e','a','r','c','h',' ','i','f',' ','n','o',' ','m','a','t','c','h',' ','f','o','u','n','d','.','\n', +' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n', +'\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','J','\b','J','U','\b','U','M','\b','M','P','\b','P','I','\b','I','N','\b','N','G','\b','G','\n', +'\n', +' ',' ','g',' ',' ','<',' ',' ','E','S','C','-','<',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','G','o',' ','t','o',' ','f','i','r','s','t',' ','l','i','n','e',' ','i','n',' ','f','i','l','e',' ','(','o','r',' ','l','i','n','e',' ','_','\b','N',')','.','\n', +' ',' ','G',' ',' ','>',' ',' ','E','S','C','-','>',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','G','o',' ','t','o',' ','l','a','s','t',' ','l','i','n','e',' ','i','n',' ','f','i','l','e',' ','(','o','r',' ','l','i','n','e',' ','_','\b','N',')','.','\n', +' ',' ','p',' ',' ','%',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','G','o',' ','t','o',' ','b','e','g','i','n','n','i','n','g',' ','o','f',' ','f','i','l','e',' ','(','o','r',' ','_','\b','N',' ','p','e','r','c','e','n','t',' ','i','n','t','o',' ','f','i','l','e',')','.','\n', +' ',' ','t',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','G','o',' ','t','o',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','n','e','x','t',' ','t','a','g','.','\n', +' ',' ','T',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','G','o',' ','t','o',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','p','r','e','v','i','o','u','s',' ','t','a','g','.','\n', +' ',' ','{',' ',' ','(',' ',' ','[',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','F','i','n','d',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t',' ','}',' ',')',' ',']','.','\n', +' ',' ','}',' ',' ',')',' ',' ',']',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','F','i','n','d',' ','o','p','e','n',' ','b','r','a','c','k','e','t',' ','{',' ','(',' ','[','.','\n', +' ',' ','E','S','C','-','^','F',' ','_','\b','<','_','\b','c','_','\b','1','_','\b','>',' ','_','\b','<','_','\b','c','_','\b','2','_','\b','>',' ',' ','*',' ',' ','F','i','n','d',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t',' ','_','\b','<','_','\b','c','_','\b','2','_','\b','>','.','\n', +' ',' ','E','S','C','-','^','B',' ','_','\b','<','_','\b','c','_','\b','1','_','\b','>',' ','_','\b','<','_','\b','c','_','\b','2','_','\b','>',' ',' ','*',' ',' ','F','i','n','d',' ','o','p','e','n',' ','b','r','a','c','k','e','t',' ','_','\b','<','_','\b','c','_','\b','1','_','\b','>','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n', +' ',' ',' ',' ',' ',' ',' ',' ','E','a','c','h',' ','"','f','i','n','d',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t','"',' ','c','o','m','m','a','n','d',' ','g','o','e','s',' ','f','o','r','w','a','r','d',' ','t','o',' ','t','h','e',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t',' ','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','m','a','t','c','h','i','n','g',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','o','p','e','n',' ','b','r','a','c','k','e','t',' ','i','n',' ','t','h','e',' ','t','o','p',' ','l','i','n','e','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ','E','a','c','h',' ','"','f','i','n','d',' ','o','p','e','n',' ','b','r','a','c','k','e','t','"',' ','c','o','m','m','a','n','d',' ','g','o','e','s',' ','b','a','c','k','w','a','r','d',' ','t','o',' ','t','h','e',' ','o','p','e','n',' ','b','r','a','c','k','e','t',' ','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','m','a','t','c','h','i','n','g',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t',' ','i','n',' ','t','h','e',' ','b','o','t','t','o','m',' ','l','i','n','e','.','\n', +'\n', +' ',' ','m','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','M','a','r','k',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','t','o','p',' ','l','i','n','e',' ','w','i','t','h',' ','<','l','e','t','t','e','r','>','.','\n', +' ',' ','M','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','M','a','r','k',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','b','o','t','t','o','m',' ','l','i','n','e',' ','w','i','t','h',' ','<','l','e','t','t','e','r','>','.','\n', +' ',' ','\'','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','G','o',' ','t','o',' ','a',' ','p','r','e','v','i','o','u','s','l','y',' ','m','a','r','k','e','d',' ','p','o','s','i','t','i','o','n','.','\n', +' ',' ','\'','\'',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','G','o',' ','t','o',' ','t','h','e',' ','p','r','e','v','i','o','u','s',' ','p','o','s','i','t','i','o','n','.','\n', +' ',' ','^','X','^','X',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','a','m','e',' ','a','s',' ','\'','.','\n', +' ',' ','E','S','C','-','m','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ','C','l','e','a','r',' ','a',' ','m','a','r','k','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n', +' ',' ',' ',' ',' ',' ',' ',' ','A',' ','m','a','r','k',' ','i','s',' ','a','n','y',' ','u','p','p','e','r','-','c','a','s','e',' ','o','r',' ','l','o','w','e','r','-','c','a','s','e',' ','l','e','t','t','e','r','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ','C','e','r','t','a','i','n',' ','m','a','r','k','s',' ','a','r','e',' ','p','r','e','d','e','f','i','n','e','d',':','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','^',' ',' ','m','e','a','n','s',' ',' ','b','e','g','i','n','n','i','n','g',' ','o','f',' ','t','h','e',' ','f','i','l','e','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','$',' ',' ','m','e','a','n','s',' ',' ','e','n','d',' ','o','f',' ','t','h','e',' ','f','i','l','e','\n', +' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n', +'\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','\b','C','H','\b','H','A','\b','A','N','\b','N','G','\b','G','I','\b','I','N','\b','N','G','\b','G',' ','F','\b','F','I','\b','I','L','\b','L','E','\b','E','S','\b','S','\n', +'\n', +' ',' ',':','e',' ','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','a','m','i','n','e',' ','a',' ','n','e','w',' ','f','i','l','e','.','\n', +' ',' ','^','X','^','V',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','a','m','e',' ','a','s',' ',':','e','.','\n', +' ',' ',':','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','E','x','a','m','i','n','e',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','n','e','x','t',' ','f','i','l','e',' ','f','r','o','m',' ','t','h','e',' ','c','o','m','m','a','n','d',' ','l','i','n','e','.','\n', +' ',' ',':','p',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','E','x','a','m','i','n','e',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','p','r','e','v','i','o','u','s',' ','f','i','l','e',' ','f','r','o','m',' ','t','h','e',' ','c','o','m','m','a','n','d',' ','l','i','n','e','.','\n', +' ',' ',':','x',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','E','x','a','m','i','n','e',' ','t','h','e',' ','f','i','r','s','t',' ','(','o','r',' ','_','\b','N','-','t','h',')',' ','f','i','l','e',' ','f','r','o','m',' ','t','h','e',' ','c','o','m','m','a','n','d',' ','l','i','n','e','.','\n', +' ',' ',':','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','e','l','e','t','e',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','f','i','l','e',' ','f','r','o','m',' ','t','h','e',' ','c','o','m','m','a','n','d',' ','l','i','n','e',' ','l','i','s','t','.','\n', +' ',' ','=',' ',' ','^','G',' ',' ',':','f',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','P','r','i','n','t',' ','c','u','r','r','e','n','t',' ','f','i','l','e',' ','n','a','m','e','.','\n', +' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n', +'\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','M','\b','M','I','\b','I','S','\b','S','C','\b','C','E','\b','E','L','\b','L','L','\b','L','A','\b','A','N','\b','N','E','\b','E','O','\b','O','U','\b','U','S','\b','S',' ','C','\b','C','O','\b','O','M','\b','M','M','\b','M','A','\b','A','N','\b','N','D','\b','D','S','\b','S','\n', +'\n', +' ',' ','-','_','\b','<','_','\b','f','_','\b','l','_','\b','a','_','\b','g','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','T','o','g','g','l','e',' ','a',' ','c','o','m','m','a','n','d',' ','l','i','n','e',' ','o','p','t','i','o','n',' ','[','s','e','e',' ','O','P','T','I','O','N','S',' ','b','e','l','o','w',']','.','\n', +' ',' ','-','-','_','\b','<','_','\b','n','_','\b','a','_','\b','m','_','\b','e','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','T','o','g','g','l','e',' ','a',' ','c','o','m','m','a','n','d',' ','l','i','n','e',' ','o','p','t','i','o','n',',',' ','b','y',' ','n','a','m','e','.','\n', +' ',' ','_','_','\b','<','_','\b','f','_','\b','l','_','\b','a','_','\b','g','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','t','h','e',' ','s','e','t','t','i','n','g',' ','o','f',' ','a',' ','c','o','m','m','a','n','d',' ','l','i','n','e',' ','o','p','t','i','o','n','.','\n', +' ',' ','_','_','_','\b','<','_','\b','n','_','\b','a','_','\b','m','_','\b','e','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','t','h','e',' ','s','e','t','t','i','n','g',' ','o','f',' ','a','n',' ','o','p','t','i','o','n',',',' ','b','y',' ','n','a','m','e','.','\n', +' ',' ','+','_','\b','c','_','\b','m','_','\b','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','e','c','u','t','e',' ','t','h','e',' ','l','e','s','s',' ','c','m','d',' ','e','a','c','h',' ','t','i','m','e',' ','a',' ','n','e','w',' ','f','i','l','e',' ','i','s',' ','e','x','a','m','i','n','e','d','.','\n', +'\n', +' ',' ','!','_','\b','c','_','\b','o','_','\b','m','_','\b','m','_','\b','a','_','\b','n','_','\b','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','e','c','u','t','e',' ','t','h','e',' ','s','h','e','l','l',' ','c','o','m','m','a','n','d',' ','w','i','t','h',' ','$','S','H','E','L','L','.','\n', +' ',' ','#','_','\b','c','_','\b','o','_','\b','m','_','\b','m','_','\b','a','_','\b','n','_','\b','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','e','c','u','t','e',' ','t','h','e',' ','s','h','e','l','l',' ','c','o','m','m','a','n','d',',',' ','e','x','p','a','n','d','e','d',' ','l','i','k','e',' ','a',' ','p','r','o','m','p','t','.','\n', +' ',' ','|','X','\b','X','_','\b','c','_','\b','o','_','\b','m','_','\b','m','_','\b','a','_','\b','n','_','\b','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','P','i','p','e',' ','f','i','l','e',' ','b','e','t','w','e','e','n',' ','c','u','r','r','e','n','t',' ','p','o','s',' ','&',' ','m','a','r','k',' ','X','\b','X',' ','t','o',' ','s','h','e','l','l',' ','c','o','m','m','a','n','d','.','\n', +' ',' ','s',' ','_','\b','f','_','\b','i','_','\b','l','_','\b','e',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','a','v','e',' ','i','n','p','u','t',' ','t','o',' ','a',' ','f','i','l','e','.','\n', +' ',' ','v',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','d','i','t',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','f','i','l','e',' ','w','i','t','h',' ','$','V','I','S','U','A','L',' ','o','r',' ','$','E','D','I','T','O','R','.','\n', +' ',' ','V',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','P','r','i','n','t',' ','v','e','r','s','i','o','n',' ','n','u','m','b','e','r',' ','o','f',' ','"','l','e','s','s','"','.','\n', +' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n', +'\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','O','\b','O','P','\b','P','T','\b','T','I','\b','I','O','\b','O','N','\b','N','S','\b','S','\n', +'\n', +' ',' ',' ',' ',' ',' ',' ',' ','M','o','s','t',' ','o','p','t','i','o','n','s',' ','m','a','y',' ','b','e',' ','c','h','a','n','g','e','d',' ','e','i','t','h','e','r',' ','o','n',' ','t','h','e',' ','c','o','m','m','a','n','d',' ','l','i','n','e',',','\n', +' ',' ',' ',' ',' ',' ',' ',' ','o','r',' ','f','r','o','m',' ','w','i','t','h','i','n',' ','l','e','s','s',' ','b','y',' ','u','s','i','n','g',' ','t','h','e',' ','-',' ','o','r',' ','-','-',' ','c','o','m','m','a','n','d','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ','O','p','t','i','o','n','s',' ','m','a','y',' ','b','e',' ','g','i','v','e','n',' ','i','n',' ','o','n','e',' ','o','f',' ','t','w','o',' ','f','o','r','m','s',':',' ','e','i','t','h','e','r',' ','a',' ','s','i','n','g','l','e','\n', +' ',' ',' ',' ',' ',' ',' ',' ','c','h','a','r','a','c','t','e','r',' ','p','r','e','c','e','d','e','d',' ','b','y',' ','a',' ','-',',',' ','o','r',' ','a',' ','n','a','m','e',' ','p','r','e','c','e','d','e','d',' ','b','y',' ','-','-','.','\n', +'\n', +' ',' ','-','?',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','h','e','l','p','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','h','e','l','p',' ','(','f','r','o','m',' ','c','o','m','m','a','n','d',' ','l','i','n','e',')','.','\n', +' ',' ','-','a',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','s','e','a','r','c','h','-','s','k','i','p','-','s','c','r','e','e','n','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','a','r','c','h',' ','s','k','i','p','s',' ','c','u','r','r','e','n','t',' ','s','c','r','e','e','n','.','\n', +' ',' ','-','A',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','S','E','A','R','C','H','-','S','K','I','P','-','S','C','R','E','E','N','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','a','r','c','h',' ','s','t','a','r','t','s',' ','j','u','s','t',' ','a','f','t','e','r',' ','t','a','r','g','e','t',' ','l','i','n','e','.','\n', +' ',' ','-','b',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','b','u','f','f','e','r','s','=','[','_','\b','N',']','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','N','u','m','b','e','r',' ','o','f',' ','b','u','f','f','e','r','s','.','\n', +' ',' ','-','B',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','a','u','t','o','-','b','u','f','f','e','r','s','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','a','u','t','o','m','a','t','i','c','a','l','l','y',' ','a','l','l','o','c','a','t','e',' ','b','u','f','f','e','r','s',' ','f','o','r',' ','p','i','p','e','s','.','\n', +' ',' ','-','c',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','c','l','e','a','r','-','s','c','r','e','e','n','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','p','a','i','n','t',' ','b','y',' ','c','l','e','a','r','i','n','g',' ','r','a','t','h','e','r',' ','t','h','a','n',' ','s','c','r','o','l','l','i','n','g','.','\n', +' ',' ','-','d',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','d','u','m','b','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','u','m','b',' ','t','e','r','m','i','n','a','l','.','\n', +' ',' ','-','D',' ','x','\b','x','_','\b','c','_','\b','o','_','\b','l','_','\b','o','_','\b','r',' ',' ','.',' ',' ','-','-','c','o','l','o','r','=','x','\b','x','_','\b','c','_','\b','o','_','\b','l','_','\b','o','_','\b','r','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','s','c','r','e','e','n',' ','c','o','l','o','r','s','.','\n', +' ',' ','-','e',' ',' ','-','E',' ',' ','.','.','.','.',' ',' ','-','-','q','u','i','t','-','a','t','-','e','o','f',' ',' ','-','-','Q','U','I','T','-','A','T','-','E','O','F','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','Q','u','i','t',' ','a','t',' ','e','n','d',' ','o','f',' ','f','i','l','e','.','\n', +' ',' ','-','f',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','f','o','r','c','e','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','F','o','r','c','e',' ','o','p','e','n',' ','n','o','n','-','r','e','g','u','l','a','r',' ','f','i','l','e','s','.','\n', +' ',' ','-','F',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','q','u','i','t','-','i','f','-','o','n','e','-','s','c','r','e','e','n','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','Q','u','i','t',' ','i','f',' ','e','n','t','i','r','e',' ','f','i','l','e',' ','f','i','t','s',' ','o','n',' ','f','i','r','s','t',' ','s','c','r','e','e','n','.','\n', +' ',' ','-','g',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','h','i','l','i','t','e','-','s','e','a','r','c','h','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','o','n','l','y',' ','l','a','s','t',' ','m','a','t','c','h',' ','f','o','r',' ','s','e','a','r','c','h','e','s','.','\n', +' ',' ','-','G',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','H','I','L','I','T','E','-','S','E','A','R','C','H','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','h','i','g','h','l','i','g','h','t',' ','a','n','y',' ','m','a','t','c','h','e','s',' ','f','o','r',' ','s','e','a','r','c','h','e','s','.','\n', +' ',' ','-','h',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','m','a','x','-','b','a','c','k','-','s','c','r','o','l','l','=','[','_','\b','N',']','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','B','a','c','k','w','a','r','d',' ','s','c','r','o','l','l',' ','l','i','m','i','t','.','\n', +' ',' ','-','i',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','i','g','n','o','r','e','-','c','a','s','e','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','I','g','n','o','r','e',' ','c','a','s','e',' ','i','n',' ','s','e','a','r','c','h','e','s',' ','t','h','a','t',' ','d','o',' ','n','o','t',' ','c','o','n','t','a','i','n',' ','u','p','p','e','r','c','a','s','e','.','\n', +' ',' ','-','I',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','I','G','N','O','R','E','-','C','A','S','E','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','I','g','n','o','r','e',' ','c','a','s','e',' ','i','n',' ','a','l','l',' ','s','e','a','r','c','h','e','s','.','\n', +' ',' ','-','j',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','j','u','m','p','-','t','a','r','g','e','t','=','[','_','\b','N',']','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','c','r','e','e','n',' ','p','o','s','i','t','i','o','n',' ','o','f',' ','t','a','r','g','e','t',' ','l','i','n','e','s','.','\n', +' ',' ','-','J',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','s','t','a','t','u','s','-','c','o','l','u','m','n','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','a',' ','s','t','a','t','u','s',' ','c','o','l','u','m','n',' ','a','t',' ','l','e','f','t',' ','e','d','g','e',' ','o','f',' ','s','c','r','e','e','n','.','\n', +' ',' ','-','k',' ','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ',' ','.',' ',' ','-','-','l','e','s','s','k','e','y','-','f','i','l','e','=','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','a',' ','l','e','s','s','k','e','y',' ','f','i','l','e','.','\n', +' ',' ','-','K',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','q','u','i','t','-','o','n','-','i','n','t','r','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','i','t',' ','l','e','s','s',' ','i','n',' ','r','e','s','p','o','n','s','e',' ','t','o',' ','c','t','r','l','-','C','.','\n', +' ',' ','-','L',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','n','o','-','l','e','s','s','o','p','e','n','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','I','g','n','o','r','e',' ','t','h','e',' ','L','E','S','S','O','P','E','N',' ','e','n','v','i','r','o','n','m','e','n','t',' ','v','a','r','i','a','b','l','e','.','\n', +' ',' ','-','m',' ',' ','-','M',' ',' ','.','.','.','.',' ',' ','-','-','l','o','n','g','-','p','r','o','m','p','t',' ',' ','-','-','L','O','N','G','-','P','R','O','M','P','T','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','p','r','o','m','p','t',' ','s','t','y','l','e','.','\n', +' ',' ','-','n',' ','.','.','.','.','.','.','.','.','.',' ',' ','-','-','l','i','n','e','-','n','u','m','b','e','r','s','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','u','p','p','r','e','s','s',' ','l','i','n','e',' ','n','u','m','b','e','r','s',' ','i','n',' ','p','r','o','m','p','t','s',' ','a','n','d',' ','m','e','s','s','a','g','e','s','.','\n', +' ',' ','-','N',' ','.','.','.','.','.','.','.','.','.',' ',' ','-','-','L','I','N','E','-','N','U','M','B','E','R','S','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','l','i','n','e',' ','n','u','m','b','e','r',' ','a','t',' ','s','t','a','r','t',' ','o','f',' ','e','a','c','h',' ','l','i','n','e','.','\n', +' ',' ','-','o',' ','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ',' ','.',' ',' ','-','-','l','o','g','-','f','i','l','e','=','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','o','p','y',' ','t','o',' ','l','o','g',' ','f','i','l','e',' ','(','s','t','a','n','d','a','r','d',' ','i','n','p','u','t',' ','o','n','l','y',')','.','\n', +' ',' ','-','O',' ','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ',' ','.',' ',' ','-','-','L','O','G','-','F','I','L','E','=','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','o','p','y',' ','t','o',' ','l','o','g',' ','f','i','l','e',' ','(','u','n','c','o','n','d','i','t','i','o','n','a','l','l','y',' ','o','v','e','r','w','r','i','t','e',')','.','\n', +' ',' ','-','p',' ','[','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',']',' ',' ','-','-','p','a','t','t','e','r','n','=','[','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',']','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','t','a','r','t',' ','a','t',' ','p','a','t','t','e','r','n',' ','(','f','r','o','m',' ','c','o','m','m','a','n','d',' ','l','i','n','e',')','.','\n', +' ',' ','-','P',' ','[','_','\b','p','_','\b','r','_','\b','o','_','\b','m','_','\b','p','_','\b','t',']',' ',' ',' ','-','-','p','r','o','m','p','t','=','[','_','\b','p','_','\b','r','_','\b','o','_','\b','m','_','\b','p','_','\b','t',']','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','e','f','i','n','e',' ','n','e','w',' ','p','r','o','m','p','t','.','\n', +' ',' ','-','q',' ',' ','-','Q',' ',' ','.','.','.','.',' ',' ','-','-','q','u','i','e','t',' ',' ','-','-','Q','U','I','E','T',' ',' ','-','-','s','i','l','e','n','t',' ','-','-','S','I','L','E','N','T','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','Q','u','i','e','t',' ','t','h','e',' ','t','e','r','m','i','n','a','l',' ','b','e','l','l','.','\n', +' ',' ','-','r',' ',' ','-','R',' ',' ','.','.','.','.',' ',' ','-','-','r','a','w','-','c','o','n','t','r','o','l','-','c','h','a','r','s',' ',' ','-','-','R','A','W','-','C','O','N','T','R','O','L','-','C','H','A','R','S','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','O','u','t','p','u','t',' ','"','r','a','w','"',' ','c','o','n','t','r','o','l',' ','c','h','a','r','a','c','t','e','r','s','.','\n', +' ',' ','-','s',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','s','q','u','e','e','z','e','-','b','l','a','n','k','-','l','i','n','e','s','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','q','u','e','e','z','e',' ','m','u','l','t','i','p','l','e',' ','b','l','a','n','k',' ','l','i','n','e','s','.','\n', +' ',' ','-','S',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','c','h','o','p','-','l','o','n','g','-','l','i','n','e','s','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','h','o','p',' ','(','t','r','u','n','c','a','t','e',')',' ','l','o','n','g',' ','l','i','n','e','s',' ','r','a','t','h','e','r',' ','t','h','a','n',' ','w','r','a','p','p','i','n','g','.','\n', +' ',' ','-','t',' ','[','_','\b','t','_','\b','a','_','\b','g',']',' ',' ','.','.',' ',' ','-','-','t','a','g','=','[','_','\b','t','_','\b','a','_','\b','g',']','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','F','i','n','d',' ','a',' ','t','a','g','.','\n', +' ',' ','-','T',' ','[','_','\b','t','_','\b','a','_','\b','g','_','\b','s','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ','-','-','t','a','g','-','f','i','l','e','=','[','_','\b','t','_','\b','a','_','\b','g','_','\b','s','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','a','n',' ','a','l','t','e','r','n','a','t','e',' ','t','a','g','s',' ','f','i','l','e','.','\n', +' ',' ','-','u',' ',' ','-','U',' ',' ','.','.','.','.',' ',' ','-','-','u','n','d','e','r','l','i','n','e','-','s','p','e','c','i','a','l',' ',' ','-','-','U','N','D','E','R','L','I','N','E','-','S','P','E','C','I','A','L','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','h','a','n','g','e',' ','h','a','n','d','l','i','n','g',' ','o','f',' ','b','a','c','k','s','p','a','c','e','s',',',' ','t','a','b','s',' ','a','n','d',' ','c','a','r','r','i','a','g','e',' ','r','e','t','u','r','n','s','.','\n', +' ',' ','-','V',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','v','e','r','s','i','o','n','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','t','h','e',' ','v','e','r','s','i','o','n',' ','n','u','m','b','e','r',' ','o','f',' ','"','l','e','s','s','"','.','\n', +' ',' ','-','w',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','h','i','l','i','t','e','-','u','n','r','e','a','d','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','f','i','r','s','t',' ','n','e','w',' ','l','i','n','e',' ','a','f','t','e','r',' ','f','o','r','w','a','r','d','-','s','c','r','e','e','n','.','\n', +' ',' ','-','W',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','H','I','L','I','T','E','-','U','N','R','E','A','D','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','f','i','r','s','t',' ','n','e','w',' ','l','i','n','e',' ','a','f','t','e','r',' ','a','n','y',' ','f','o','r','w','a','r','d',' ','m','o','v','e','m','e','n','t','.','\n', +' ',' ','-','x',' ','[','_','\b','N','[',',','.','.','.',']',']',' ',' ','-','-','t','a','b','s','=','[','_','\b','N','[',',','.','.','.',']',']','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','t','a','b',' ','s','t','o','p','s','.','\n', +' ',' ','-','X',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','n','o','-','i','n','i','t','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','u','s','e',' ','t','e','r','m','c','a','p',' ','i','n','i','t','/','d','e','i','n','i','t',' ','s','t','r','i','n','g','s','.','\n', +' ',' ','-','y',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','m','a','x','-','f','o','r','w','-','s','c','r','o','l','l','=','[','_','\b','N',']','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','F','o','r','w','a','r','d',' ','s','c','r','o','l','l',' ','l','i','m','i','t','.','\n', +' ',' ','-','z',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','w','i','n','d','o','w','=','[','_','\b','N',']','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','s','i','z','e',' ','o','f',' ','w','i','n','d','o','w','.','\n', +' ',' ','-','"',' ','[','_','\b','c','[','_','\b','c',']',']',' ',' ','.',' ',' ','-','-','q','u','o','t','e','s','=','[','_','\b','c','[','_','\b','c',']',']','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','s','h','e','l','l',' ','q','u','o','t','e',' ','c','h','a','r','a','c','t','e','r','s','.','\n', +' ',' ','-','~',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','t','i','l','d','e','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','d','i','s','p','l','a','y',' ','t','i','l','d','e','s',' ','a','f','t','e','r',' ','e','n','d',' ','o','f',' ','f','i','l','e','.','\n', +' ',' ','-','#',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','s','h','i','f','t','=','[','_','\b','N',']','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','h','o','r','i','z','o','n','t','a','l',' ','s','c','r','o','l','l',' ','a','m','o','u','n','t',' ','(','0',' ','=',' ','o','n','e',' ','h','a','l','f',' ','s','c','r','e','e','n',' ','w','i','d','t','h',')','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','e','x','i','t','-','f','o','l','l','o','w','-','o','n','-','c','l','o','s','e','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','i','t',' ','F',' ','c','o','m','m','a','n','d',' ','o','n',' ','a',' ','p','i','p','e',' ','w','h','e','n',' ','w','r','i','t','e','r',' ','c','l','o','s','e','s',' ','p','i','p','e','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','f','i','l','e','-','s','i','z','e','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','A','u','t','o','m','a','t','i','c','a','l','l','y',' ','d','e','t','e','r','m','i','n','e',' ','t','h','e',' ','s','i','z','e',' ','o','f',' ','t','h','e',' ','i','n','p','u','t',' ','f','i','l','e','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','f','o','l','l','o','w','-','n','a','m','e','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','T','h','e',' ','F',' ','c','o','m','m','a','n','d',' ','c','h','a','n','g','e','s',' ','f','i','l','e','s',' ','i','f',' ','t','h','e',' ','i','n','p','u','t',' ','f','i','l','e',' ','i','s',' ','r','e','n','a','m','e','d','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','h','e','a','d','e','r','=','[','_','\b','N','[',',','_','\b','M',']',']','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','N',' ','l','i','n','e','s',' ','a','n','d',' ','M',' ','c','o','l','u','m','n','s',' ','t','o',' ','d','i','s','p','l','a','y',' ','f','i','l','e',' ','h','e','a','d','e','r','s','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','i','n','c','s','e','a','r','c','h','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','a','r','c','h',' ','f','i','l','e',' ','a','s',' ','e','a','c','h',' ','p','a','t','t','e','r','n',' ','c','h','a','r','a','c','t','e','r',' ','i','s',' ','t','y','p','e','d',' ','i','n','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','i','n','t','r','=','_','\b','C','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','_','\b','C',' ','i','n','s','t','e','a','d',' ','o','f',' ','^','X',' ','t','o',' ','i','n','t','e','r','r','u','p','t',' ','a',' ','r','e','a','d','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','l','i','n','e','-','n','u','m','-','w','i','d','t','h','=','_','\b','N','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','t','h','e',' ','w','i','d','t','h',' ','o','f',' ','t','h','e',' ','-','N',' ','l','i','n','e',' ','n','u','m','b','e','r',' ','f','i','e','l','d',' ','t','o',' ','_','\b','N',' ','c','h','a','r','a','c','t','e','r','s','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','m','o','d','e','l','i','n','e','s','=','_','\b','N','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','a','d',' ','_','\b','N',' ','l','i','n','e','s',' ','f','r','o','m',' ','t','h','e',' ','i','n','p','u','t',' ','f','i','l','e',' ','a','n','d',' ','l','o','o','k',' ','f','o','r',' ','v','i','m',' ','m','o','d','e','l','i','n','e','s','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','m','o','u','s','e','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','n','a','b','l','e',' ','m','o','u','s','e',' ','i','n','p','u','t','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','n','o','-','k','e','y','p','a','d','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','s','e','n','d',' ','t','e','r','m','c','a','p',' ','k','e','y','p','a','d',' ','i','n','i','t','/','d','e','i','n','i','t',' ','s','t','r','i','n','g','s','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','n','o','-','h','i','s','t','d','u','p','s','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','m','o','v','e',' ','d','u','p','l','i','c','a','t','e','s',' ','f','r','o','m',' ','c','o','m','m','a','n','d',' ','h','i','s','t','o','r','y','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','n','o','-','n','u','m','b','e','r','-','h','e','a','d','e','r','s','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','g','i','v','e',' ','l','i','n','e',' ','n','u','m','b','e','r','s',' ','t','o',' ','h','e','a','d','e','r',' ','l','i','n','e','s','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','n','o','-','s','e','a','r','c','h','-','h','e','a','d','e','r','s','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','s','e','a','r','c','h',' ','i','n',' ','h','e','a','d','e','r',' ','l','i','n','e','s',' ','o','r',' ','c','o','l','u','m','n','s','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','n','o','-','v','b','e','l','l','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','a','b','l','e',' ','t','h','e',' ','t','e','r','m','i','n','a','l','\'','s',' ','v','i','s','u','a','l',' ','b','e','l','l','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','r','e','d','r','a','w','-','o','n','-','q','u','i','t','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','d','r','a','w',' ','f','i','n','a','l',' ','s','c','r','e','e','n',' ','w','h','e','n',' ','q','u','i','t','t','i','n','g','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','r','s','c','r','o','l','l','=','_','\b','C','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','t','h','e',' ','c','h','a','r','a','c','t','e','r',' ','u','s','e','d',' ','t','o',' ','m','a','r','k',' ','t','r','u','n','c','a','t','e','d',' ','l','i','n','e','s','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','s','a','v','e','-','m','a','r','k','s','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','t','a','i','n',' ','m','a','r','k','s',' ','a','c','r','o','s','s',' ','i','n','v','o','c','a','t','i','o','n','s',' ','o','f',' ','l','e','s','s','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','s','e','a','r','c','h','-','o','p','t','i','o','n','s','=','[','E','F','K','N','R','W','-',']','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','d','e','f','a','u','l','t',' ','o','p','t','i','o','n','s',' ','f','o','r',' ','e','v','e','r','y',' ','s','e','a','r','c','h','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','s','h','o','w','-','p','r','e','p','r','o','c','-','e','r','r','o','r','s','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','a',' ','m','e','s','s','a','g','e',' ','i','f',' ','p','r','e','p','r','o','c','e','s','s','o','r',' ','e','x','i','t','s',' ','w','i','t','h',' ','a','n',' ','e','r','r','o','r',' ','s','t','a','t','u','s','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','p','r','o','c','-','b','a','c','k','s','p','a','c','e','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','P','r','o','c','e','s','s',' ','b','a','c','k','s','p','a','c','e','s',' ','f','o','r',' ','b','o','l','d','/','u','n','d','e','r','l','i','n','e','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','S','P','E','C','I','A','L','-','B','A','C','K','S','P','A','C','E','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','T','r','e','a','t',' ','b','a','c','k','s','p','a','c','e','s',' ','a','s',' ','c','o','n','t','r','o','l',' ','c','h','a','r','a','c','t','e','r','s','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','p','r','o','c','-','r','e','t','u','r','n','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','e','l','e','t','e',' ','c','a','r','r','i','a','g','e',' ','r','e','t','u','r','n','s',' ','b','e','f','o','r','e',' ','n','e','w','l','i','n','e','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','S','P','E','C','I','A','L','-','R','E','T','U','R','N','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','T','r','e','a','t',' ','c','a','r','r','i','a','g','e',' ','r','e','t','u','r','n','s',' ','a','s',' ','c','o','n','t','r','o','l',' ','c','h','a','r','a','c','t','e','r','s','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','p','r','o','c','-','t','a','b','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','p','a','n','d',' ','t','a','b','s',' ','t','o',' ','s','p','a','c','e','s','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','S','P','E','C','I','A','L','-','T','A','B','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','T','r','e','a','t',' ','t','a','b','s',' ','a','s',' ','c','o','n','t','r','o','l',' ','c','h','a','r','a','c','t','e','r','s','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','s','t','a','t','u','s','-','c','o','l','-','w','i','d','t','h','=','_','\b','N','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','t','h','e',' ','w','i','d','t','h',' ','o','f',' ','t','h','e',' ','-','J',' ','s','t','a','t','u','s',' ','c','o','l','u','m','n',' ','t','o',' ','_','\b','N',' ','c','h','a','r','a','c','t','e','r','s','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','s','t','a','t','u','s','-','l','i','n','e','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','o','r',' ','c','o','l','o','r',' ','t','h','e',' ','e','n','t','i','r','e',' ','l','i','n','e',' ','c','o','n','t','a','i','n','i','n','g',' ','a',' ','m','a','r','k','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','u','s','e','-','b','a','c','k','s','l','a','s','h','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','u','b','s','e','q','u','e','n','t',' ','o','p','t','i','o','n','s',' ','u','s','e',' ','b','a','c','k','s','l','a','s','h',' ','a','s',' ','e','s','c','a','p','e',' ','c','h','a','r','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','u','s','e','-','c','o','l','o','r','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','n','a','b','l','e','s',' ','c','o','l','o','r','e','d',' ','t','e','x','t','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','w','h','e','e','l','-','l','i','n','e','s','=','_','\b','N','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','a','c','h',' ','c','l','i','c','k',' ','o','f',' ','t','h','e',' ','m','o','u','s','e',' ','w','h','e','e','l',' ','m','o','v','e','s',' ','_','\b','N',' ','l','i','n','e','s','.','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','w','o','r','d','w','r','a','p','\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','W','r','a','p',' ','l','i','n','e','s',' ','a','t',' ','s','p','a','c','e','s','.','\n', +'\n', +'\n', +' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n', +'\n', +' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','L','\b','L','I','\b','I','N','\b','N','E','\b','E',' ','E','\b','E','D','\b','D','I','\b','I','T','\b','T','I','\b','I','N','\b','N','G','\b','G','\n', +'\n', +' ',' ',' ',' ',' ',' ',' ',' ','T','h','e','s','e',' ','k','e','y','s',' ','c','a','n',' ','b','e',' ','u','s','e','d',' ','t','o',' ','e','d','i','t',' ','t','e','x','t',' ','b','e','i','n','g',' ','e','n','t','e','r','e','d',' ','\n', +' ',' ',' ',' ',' ',' ',' ',' ','o','n',' ','t','h','e',' ','"','c','o','m','m','a','n','d',' ','l','i','n','e','"',' ','a','t',' ','t','h','e',' ','b','o','t','t','o','m',' ','o','f',' ','t','h','e',' ','s','c','r','e','e','n','.','\n', +'\n', +' ','R','i','g','h','t','A','r','r','o','w',' ','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',' ','E','S','C','-','l',' ','.','.','.',' ','M','o','v','e',' ','c','u','r','s','o','r',' ','r','i','g','h','t',' ','o','n','e',' ','c','h','a','r','a','c','t','e','r','.','\n', +' ','L','e','f','t','A','r','r','o','w',' ','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',' ','E','S','C','-','h',' ','.','.','.',' ','M','o','v','e',' ','c','u','r','s','o','r',' ','l','e','f','t',' ','o','n','e',' ','c','h','a','r','a','c','t','e','r','.','\n', +' ','c','t','r','l','-','R','i','g','h','t','A','r','r','o','w',' ',' ','E','S','C','-','R','i','g','h','t','A','r','r','o','w',' ',' ','E','S','C','-','w',' ','.','.','.',' ','M','o','v','e',' ','c','u','r','s','o','r',' ','r','i','g','h','t',' ','o','n','e',' ','w','o','r','d','.','\n', +' ','c','t','r','l','-','L','e','f','t','A','r','r','o','w',' ',' ',' ','E','S','C','-','L','e','f','t','A','r','r','o','w',' ',' ',' ','E','S','C','-','b',' ','.','.','.',' ','M','o','v','e',' ','c','u','r','s','o','r',' ','l','e','f','t',' ','o','n','e',' ','w','o','r','d','.','\n', +' ','H','O','M','E',' ','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',' ','E','S','C','-','0',' ','.','.','.',' ','M','o','v','e',' ','c','u','r','s','o','r',' ','t','o',' ','s','t','a','r','t',' ','o','f',' ','l','i','n','e','.','\n', +' ','E','N','D',' ','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',' ','E','S','C','-','$',' ','.','.','.',' ','M','o','v','e',' ','c','u','r','s','o','r',' ','t','o',' ','e','n','d',' ','o','f',' ','l','i','n','e','.','\n', +' ','B','A','C','K','S','P','A','C','E',' ','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',' ','D','e','l','e','t','e',' ','c','h','a','r',' ','t','o',' ','l','e','f','t',' ','o','f',' ','c','u','r','s','o','r','.','\n', +' ','D','E','L','E','T','E',' ','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',' ','E','S','C','-','x',' ','.','.','.',' ','D','e','l','e','t','e',' ','c','h','a','r',' ','u','n','d','e','r',' ','c','u','r','s','o','r','.','\n', +' ','c','t','r','l','-','B','A','C','K','S','P','A','C','E',' ',' ',' ','E','S','C','-','B','A','C','K','S','P','A','C','E',' ','.','.','.','.','.','.','.','.','.','.','.',' ','D','e','l','e','t','e',' ','w','o','r','d',' ','t','o',' ','l','e','f','t',' ','o','f',' ','c','u','r','s','o','r','.','\n', +' ','c','t','r','l','-','D','E','L','E','T','E',' ','.','.','.','.',' ','E','S','C','-','D','E','L','E','T','E',' ','.','.','.','.',' ','E','S','C','-','X',' ','.','.','.',' ','D','e','l','e','t','e',' ','w','o','r','d',' ','u','n','d','e','r',' ','c','u','r','s','o','r','.','\n', +' ','c','t','r','l','-','U',' ','.','.','.','.','.','.','.','.','.',' ','E','S','C',' ','(','M','S','-','D','O','S',' ','o','n','l','y',')',' ','.','.','.','.','.','.','.',' ','D','e','l','e','t','e',' ','e','n','t','i','r','e',' ','l','i','n','e','.','\n', +' ','U','p','A','r','r','o','w',' ','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',' ','E','S','C','-','k',' ','.','.','.',' ','R','e','t','r','i','e','v','e',' ','p','r','e','v','i','o','u','s',' ','c','o','m','m','a','n','d',' ','l','i','n','e','.','\n', +' ','D','o','w','n','A','r','r','o','w',' ','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',' ','E','S','C','-','j',' ','.','.','.',' ','R','e','t','r','i','e','v','e',' ','n','e','x','t',' ','c','o','m','m','a','n','d',' ','l','i','n','e','.','\n', +' ','T','A','B',' ','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',' ','C','o','m','p','l','e','t','e',' ','f','i','l','e','n','a','m','e',' ','&',' ','c','y','c','l','e','.','\n', +' ','S','H','I','F','T','-','T','A','B',' ','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',' ','E','S','C','-','T','A','B',' ',' ',' ','C','o','m','p','l','e','t','e',' ','f','i','l','e','n','a','m','e',' ','&',' ','r','e','v','e','r','s','e',' ','c','y','c','l','e','.','\n', +' ','c','t','r','l','-','L',' ','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',' ','C','o','m','p','l','e','t','e',' ','f','i','l','e','n','a','m','e',',',' ','l','i','s','t',' ','a','l','l','.','\n', + 0 }; +constant int size_helpdata = sizeof(helpdata) - 1; diff --git a/third_party/less/ifile.c b/third_party/less/ifile.c new file mode 100644 index 000000000..adbe82b0e --- /dev/null +++ b/third_party/less/ifile.c @@ -0,0 +1,358 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * An IFILE represents an input file. + * + * It is actually a pointer to an ifile structure, + * but is opaque outside this module. + * Ifile structures are kept in a linked list in the order they + * appear on the command line. + * Any new file which does not already appear in the list is + * inserted after the current file. + */ + +#include "less.h" + +extern IFILE curr_ifile; + +struct ifile { + struct ifile *h_next; /* Links for command line list */ + struct ifile *h_prev; + char *h_filename; /* Name of the file */ + char *h_rfilename; /* Canonical name of the file */ + void *h_filestate; /* File state (used in ch.c) */ + int h_index; /* Index within command line list */ + int h_hold; /* Hold count */ + char h_opened; /* Has this ifile been opened? */ + struct scrpos h_scrpos; /* Saved position within the file */ + void *h_altpipe; /* Alt pipe */ + char *h_altfilename; /* Alt filename */ +}; + +/* + * Convert an IFILE (external representation) + * to a struct file (internal representation), and vice versa. + */ +#define int_ifile(h) ((struct ifile *)(h)) +#define ext_ifile(h) ((IFILE)(h)) + +/* + * Anchor for linked list. + */ +static struct ifile anchor = { &anchor, &anchor, NULL, NULL, NULL, 0, 0, '\0', + { NULL_POSITION, 0 } }; +static int ifiles = 0; + +static void incr_index(struct ifile *p, int incr) +{ + for (; p != &anchor; p = p->h_next) + p->h_index += incr; +} + +/* + * Link an ifile into the ifile list. + */ +static void link_ifile(struct ifile *p, struct ifile *prev) +{ + /* + * Link into list. + */ + if (prev == NULL) + prev = &anchor; + p->h_next = prev->h_next; + p->h_prev = prev; + prev->h_next->h_prev = p; + prev->h_next = p; + /* + * Calculate index for the new one, + * and adjust the indexes for subsequent ifiles in the list. + */ + p->h_index = prev->h_index + 1; + incr_index(p->h_next, 1); + ifiles++; +} + +/* + * Unlink an ifile from the ifile list. + */ +static void unlink_ifile(struct ifile *p) +{ + p->h_next->h_prev = p->h_prev; + p->h_prev->h_next = p->h_next; + incr_index(p->h_next, -1); + ifiles--; +} + +/* + * Allocate a new ifile structure and stick a filename in it. + * It should go after "prev" in the list + * (or at the beginning of the list if "prev" is NULL). + * Return a pointer to the new ifile structure. + */ +static struct ifile * new_ifile(char *filename, struct ifile *prev) +{ + struct ifile *p; + + /* + * Allocate and initialize structure. + */ + p = (struct ifile *) ecalloc(1, sizeof(struct ifile)); + p->h_filename = save(filename); + p->h_rfilename = lrealpath(filename); + p->h_scrpos.pos = NULL_POSITION; + p->h_opened = 0; + p->h_hold = 0; + p->h_filestate = NULL; + p->h_altfilename = NULL; + p->h_altpipe = NULL; + link_ifile(p, prev); + /* + * {{ It's dodgy to call mark.c functions from here; + * there is potentially dangerous recursion. + * Probably need to revisit this design. }} + */ + mark_check_ifile(ext_ifile(p)); + return (p); +} + +/* + * Delete an existing ifile structure. + */ +public void del_ifile(IFILE h) +{ + struct ifile *p; + + if (h == NULL_IFILE) + return; + /* + * If the ifile we're deleting is the currently open ifile, + * move off it. + */ + unmark(h); + if (h == curr_ifile) + curr_ifile = getoff_ifile(curr_ifile); + p = int_ifile(h); + unlink_ifile(p); + free(p->h_rfilename); + free(p->h_filename); + free(p); +} + +/* + * Get the ifile after a given one in the list. + */ +public IFILE next_ifile(IFILE h) +{ + struct ifile *p; + + p = (h == NULL_IFILE) ? &anchor : int_ifile(h); + if (p->h_next == &anchor) + return (NULL_IFILE); + return (ext_ifile(p->h_next)); +} + +/* + * Get the ifile before a given one in the list. + */ +public IFILE prev_ifile(IFILE h) +{ + struct ifile *p; + + p = (h == NULL_IFILE) ? &anchor : int_ifile(h); + if (p->h_prev == &anchor) + return (NULL_IFILE); + return (ext_ifile(p->h_prev)); +} + +/* + * Return a different ifile from the given one. + */ +public IFILE getoff_ifile(IFILE ifile) +{ + IFILE newifile; + + if ((newifile = prev_ifile(ifile)) != NULL_IFILE) + return (newifile); + if ((newifile = next_ifile(ifile)) != NULL_IFILE) + return (newifile); + return (NULL_IFILE); +} + +/* + * Return the number of ifiles. + */ +public int nifile(void) +{ + return (ifiles); +} + +/* + * Find an ifile structure, given a filename. + */ +static struct ifile * find_ifile(char *filename) +{ + struct ifile *p; + char *rfilename = lrealpath(filename); + + for (p = anchor.h_next; p != &anchor; p = p->h_next) + { + if (strcmp(rfilename, p->h_rfilename) == 0) + { + /* + * If given name is shorter than the name we were + * previously using for this file, adopt shorter name. + */ + if (strlen(filename) < strlen(p->h_filename)) + { + free(p->h_filename); + p->h_filename = save(filename); + } + break; + } + } + free(rfilename); + if (p == &anchor) + p = NULL; + return (p); +} + +/* + * Get the ifile associated with a filename. + * If the filename has not been seen before, + * insert the new ifile after "prev" in the list. + */ +public IFILE get_ifile(char *filename, IFILE prev) +{ + struct ifile *p; + + if ((p = find_ifile(filename)) == NULL) + p = new_ifile(filename, int_ifile(prev)); + return (ext_ifile(p)); +} + +/* + * Get the display filename associated with a ifile. + */ +public char * get_filename(IFILE ifile) +{ + if (ifile == NULL) + return (NULL); + return (int_ifile(ifile)->h_filename); +} + +/* + * Get the canonical filename associated with a ifile. + */ +public char * get_real_filename(IFILE ifile) +{ + if (ifile == NULL) + return (NULL); + return (int_ifile(ifile)->h_rfilename); +} + +/* + * Get the index of the file associated with a ifile. + */ +public int get_index(IFILE ifile) +{ + return (int_ifile(ifile)->h_index); +} + +/* + * Save the file position to be associated with a given file. + */ +public void store_pos(IFILE ifile, struct scrpos *scrpos) +{ + int_ifile(ifile)->h_scrpos = *scrpos; +} + +/* + * Recall the file position associated with a file. + * If no position has been associated with the file, return NULL_POSITION. + */ +public void get_pos(IFILE ifile, struct scrpos *scrpos) +{ + *scrpos = int_ifile(ifile)->h_scrpos; +} + +/* + * Mark the ifile as "opened". + */ +public void set_open(IFILE ifile) +{ + int_ifile(ifile)->h_opened = 1; +} + +/* + * Return whether the ifile has been opened previously. + */ +public int opened(IFILE ifile) +{ + return (int_ifile(ifile)->h_opened); +} + +public void hold_ifile(IFILE ifile, int incr) +{ + int_ifile(ifile)->h_hold += incr; +} + +public int held_ifile(IFILE ifile) +{ + return (int_ifile(ifile)->h_hold); +} + +public void * get_filestate(IFILE ifile) +{ + return (int_ifile(ifile)->h_filestate); +} + +public void set_filestate(IFILE ifile, void *filestate) +{ + int_ifile(ifile)->h_filestate = filestate; +} + +public void set_altpipe(IFILE ifile, void *p) +{ + int_ifile(ifile)->h_altpipe = p; +} + +public void *get_altpipe(IFILE ifile) +{ + return (int_ifile(ifile)->h_altpipe); +} + +public void set_altfilename(IFILE ifile, char *altfilename) +{ + struct ifile *p = int_ifile(ifile); + if (p->h_altfilename != NULL && p->h_altfilename != altfilename) + free(p->h_altfilename); + p->h_altfilename = altfilename; +} + +public char * get_altfilename(IFILE ifile) +{ + return (int_ifile(ifile)->h_altfilename); +} + +#if 0 +public void if_dump(void) +{ + struct ifile *p; + + for (p = anchor.h_next; p != &anchor; p = p->h_next) + { + printf("%x: %d. <%s> pos %d,%x\n", + p, p->h_index, p->h_filename, + p->h_scrpos.ln, p->h_scrpos.pos); + ch_dump(p->h_filestate); + } +} +#endif diff --git a/third_party/less/input.c b/third_party/less/input.c new file mode 100644 index 000000000..7e9968147 --- /dev/null +++ b/third_party/less/input.c @@ -0,0 +1,624 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + +/* + * 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 "less.h" + +extern int squeeze; +extern int hshift; +extern int quit_if_one_screen; +extern int sigs; +extern int ignore_eoi; +extern int status_col; +extern int wordwrap; +extern POSITION start_attnpos; +extern POSITION end_attnpos; +#if HILITE_SEARCH +extern int hilite_search; +extern int size_linebuf; +extern int show_attn; +#endif + +/* + * Set the status column. + * base Position of first char in line. + * disp First visible char. + * Different than base_pos if line is shifted. + * edisp Last visible char. + * eol End of line. Normally the newline. + * Different than edisp if line is chopped. + */ +static void init_status_col(POSITION base_pos, POSITION disp_pos, POSITION edisp_pos, POSITION eol_pos) +{ + int hl_before = (chop_line() && disp_pos != NULL_POSITION) ? + is_hilited_attr(base_pos, disp_pos, TRUE, NULL) : 0; + int hl_after = (chop_line()) ? + is_hilited_attr(edisp_pos, eol_pos, TRUE, NULL) : 0; + int attr; + char ch; + + if (hl_before && hl_after) + { + attr = hl_after; + ch = '='; + } else if (hl_before) + { + attr = hl_before; + ch = '<'; + } else if (hl_after) + { + attr = hl_after; + ch = '>'; + } else + { + attr = is_hilited_attr(base_pos, eol_pos, TRUE, NULL); + ch = '*'; + } + if (attr) + set_status_col(ch, attr); +} + +/* + * Get the next 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. + */ +public POSITION forw_line_seg(POSITION curr_pos, int skipeol, int rscroll, int nochop) +{ + POSITION base_pos; + POSITION new_pos; + POSITION edisp_pos = 0; + int c; + int blankline; + int endline; + int chopped; + int backchars; + POSITION wrap_pos; + int skipped_leading; + +get_forw_line: + if (curr_pos == NULL_POSITION) + { + null_line(); + return (NULL_POSITION); + } +#if HILITE_SEARCH + if (hilite_search == OPT_ONPLUS || is_filtering() || status_col) + { + /* + * If we are ignoring EOI (command F), only prepare + * one line ahead, to avoid getting stuck waiting for + * slow data without displaying the data we already have. + * If we're not ignoring EOI, we *could* do the same, but + * for efficiency we prepare several lines ahead at once. + */ + prep_hilite(curr_pos, curr_pos + 3*size_linebuf, + ignore_eoi ? 1 : -1); + curr_pos = next_unfiltered(curr_pos); + } +#endif + if (ch_seek(curr_pos)) + { + null_line(); + return (NULL_POSITION); + } + + /* + * Step back to the beginning of the line. + */ + base_pos = curr_pos; + for (;;) + { + if (ABORT_SIGS()) + { + null_line(); + return (NULL_POSITION); + } + c = ch_back_get(); + if (c == EOI) + break; + if (c == '\n') + { + (void) ch_forw_get(); + break; + } + --base_pos; + } + + /* + * Read forward again to the position we should start at. + */ + prewind(); + plinestart(base_pos); + (void) ch_seek(base_pos); + new_pos = base_pos; + while (new_pos < curr_pos) + { + if (ABORT_SIGS()) + { + null_line(); + return (NULL_POSITION); + } + c = ch_forw_get(); + backchars = pappend(c, new_pos); + new_pos++; + if (backchars > 0) + { + pshift_all(); + if (wordwrap && (c == ' ' || c == '\t')) + { + do + { + new_pos++; + c = ch_forw_get(); + } while (c == ' ' || c == '\t'); + backchars = 1; + } + new_pos -= backchars; + while (--backchars >= 0) + (void) ch_back_get(); + } + } + (void) pflushmbc(); + pshift_all(); + + /* + * Read the first character to display. + */ + c = ch_forw_get(); + if (c == EOI) + { + null_line(); + return (NULL_POSITION); + } + blankline = (c == '\n' || c == '\r'); + wrap_pos = NULL_POSITION; + skipped_leading = FALSE; + + /* + * Read each character in the line and append to the line buffer. + */ + chopped = FALSE; + for (;;) + { + if (ABORT_SIGS()) + { + null_line(); + return (NULL_POSITION); + } + if (c == '\n' || c == EOI) + { + /* + * End of the line. + */ + backchars = pflushmbc(); + new_pos = ch_tell(); + if (backchars > 0 && (nochop || !chop_line()) && hshift == 0) + { + new_pos -= backchars + 1; + endline = FALSE; + } else + endline = TRUE; + edisp_pos = new_pos; + break; + } + if (c != '\r') + blankline = 0; + + /* + * Append the char to the line and get the next char. + */ + backchars = pappend(c, ch_tell()-1); + if (backchars > 0) + { + /* + * The char won't fit in the line; the line + * is too long to print in the screen width. + * End the line here. + */ + if (skipeol) + { + /* Read to end of line. */ + edisp_pos = ch_tell(); + do + { + if (ABORT_SIGS()) + { + null_line(); + return (NULL_POSITION); + } + c = ch_forw_get(); + } while (c != '\n' && c != EOI); + new_pos = ch_tell(); + endline = TRUE; + quit_if_one_screen = FALSE; + chopped = TRUE; + } else + { + if (!wordwrap) + new_pos = ch_tell() - backchars; + else + { + /* + * We're word-wrapping, so go back to the last space. + * However, if it's the space itself that couldn't fit, + * simply ignore it and any subsequent spaces. + */ + if (c == ' ' || c == '\t') + { + do + { + new_pos = ch_tell(); + c = ch_forw_get(); + } while (c == ' ' || c == '\t'); + if (c == '\r') + c = ch_forw_get(); + if (c == '\n') + new_pos = ch_tell(); + } else if (wrap_pos == NULL_POSITION) + new_pos = ch_tell() - backchars; + else + { + new_pos = wrap_pos; + loadc(); + } + } + endline = FALSE; + } + break; + } + if (wordwrap) + { + if (c == ' ' || c == '\t') + { + if (skipped_leading) + { + wrap_pos = ch_tell(); + savec(); + } + } else + skipped_leading = TRUE; + } + c = ch_forw_get(); + } + +#if HILITE_SEARCH + if (blankline && show_attn) + { + /* Add spurious space to carry possible attn hilite. */ + pappend(' ', ch_tell()-1); + } +#endif + pdone(endline, rscroll && chopped, 1); + +#if HILITE_SEARCH + if (is_filtered(base_pos)) + { + /* + * We don't want to display this line. + * Get the next line. + */ + curr_pos = new_pos; + goto get_forw_line; + } + if (status_col) + init_status_col(base_pos, line_position(), edisp_pos, new_pos); +#endif + + if (squeeze && blankline) + { + /* + * 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' || c == '\r') + if (ABORT_SIGS()) + { + null_line(); + return (NULL_POSITION); + } + if (c != EOI) + (void) ch_back_get(); + new_pos = ch_tell(); + } + + return (new_pos); +} + +public POSITION forw_line(POSITION curr_pos) +{ + + return forw_line_seg(curr_pos, (chop_line() || hshift > 0), TRUE, FALSE); +} + +/* + * 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. + */ +public POSITION back_line(POSITION curr_pos) +{ + POSITION base_pos; + POSITION new_pos; + POSITION edisp_pos = 0; + POSITION begin_new_pos; + int c; + int endline; + int chopped; + int backchars; + POSITION wrap_pos; + int skipped_leading; + +get_back_line: + if (curr_pos == NULL_POSITION || curr_pos <= ch_zero()) + { + null_line(); + return (NULL_POSITION); + } +#if HILITE_SEARCH + if (hilite_search == OPT_ONPLUS || is_filtering() || status_col) + prep_hilite((curr_pos < 3*size_linebuf) ? + 0 : curr_pos - 3*size_linebuf, curr_pos, -1); +#endif + if (ch_seek(curr_pos-1)) + { + null_line(); + 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' || c == '\r') + { + /* + * The "current" line was blank. + * Skip over any preceding blank lines, + * since we skipped them in forw_line(). + */ + while ((c = ch_back_get()) == '\n' || c == '\r') + if (ABORT_SIGS()) + { + null_line(); + return (NULL_POSITION); + } + if (c == EOI) + { + null_line(); + return (NULL_POSITION); + } + (void) ch_forw_get(); + } + } + + /* + * Scan backwards until we hit the beginning of the line. + */ + for (;;) + { + if (ABORT_SIGS()) + { + null_line(); + 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. + */ + base_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. + */ + base_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. }} + */ + new_pos = base_pos; + if (ch_seek(new_pos)) + { + null_line(); + return (NULL_POSITION); + } + endline = FALSE; + prewind(); + plinestart(new_pos); + loop: + wrap_pos = NULL_POSITION; + skipped_leading = FALSE; + begin_new_pos = new_pos; + (void) ch_seek(new_pos); + chopped = FALSE; + + for (;;) + { + c = ch_forw_get(); + if (c == EOI || ABORT_SIGS()) + { + null_line(); + return (NULL_POSITION); + } + new_pos++; + if (c == '\n') + { + backchars = pflushmbc(); + if (backchars > 0 && !chop_line() && hshift == 0) + { + backchars++; + goto shift; + } + endline = TRUE; + edisp_pos = new_pos; + break; + } + backchars = pappend(c, ch_tell()-1); + if (backchars > 0) + { + /* + * Got a full printable line, but we haven't + * reached our curr_pos yet. Discard the line + * and start a new one. + */ + if (chop_line() || hshift > 0) + { + endline = TRUE; + chopped = TRUE; + quit_if_one_screen = FALSE; + edisp_pos = new_pos; + break; + } + shift: + if (!wordwrap) + { + pshift_all(); + new_pos -= backchars; + } else + { + if (c == ' ' || c == '\t') + { + for (;;) + { + c = ch_forw_get(); + if (c == ' ' || c == '\t') + new_pos++; + else + { + if (c == '\r') + { + c = ch_forw_get(); + if (c == '\n') + new_pos++; + } + if (c == '\n') + new_pos++; + break; + } + } + if (new_pos >= curr_pos) + break; + pshift_all(); + } else + { + pshift_all(); + if (wrap_pos == NULL_POSITION) + new_pos -= backchars; + else + new_pos = wrap_pos; + } + } + goto loop; + } + if (wordwrap) + { + if (c == ' ' || c == '\t') + { + if (skipped_leading) + wrap_pos = new_pos; + } else + skipped_leading = TRUE; + } + if (new_pos >= curr_pos) + { + edisp_pos = new_pos; + break; + } + } + + pdone(endline, chopped, 0); + +#if HILITE_SEARCH + if (is_filtered(base_pos)) + { + /* + * We don't want to display this line. + * Get the previous line. + */ + curr_pos = begin_new_pos; + goto get_back_line; + } + if (status_col) + init_status_col(base_pos, line_position(), edisp_pos, new_pos); +#endif + + return (begin_new_pos); +} + +/* + * Set attnpos. + */ +public void set_attnpos(POSITION pos) +{ + int c; + + if (pos != NULL_POSITION) + { + if (ch_seek(pos)) + return; + for (;;) + { + c = ch_forw_get(); + if (c == EOI) + break; + if (c == '\n' || c == '\r') + { + (void) ch_back_get(); + break; + } + pos++; + } + end_attnpos = pos; + for (;;) + { + c = ch_back_get(); + if (c == EOI || c == '\n' || c == '\r') + break; + pos--; + } + } + start_attnpos = pos; +} diff --git a/third_party/less/jump.c b/third_party/less/jump.c new file mode 100644 index 000000000..2bb4abbc1 --- /dev/null +++ b/third_party/less/jump.c @@ -0,0 +1,325 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * Routines which jump to a new location in the file. + */ + +#include "less.h" +#include "position.h" + +extern int jump_sline; +extern int squished; +extern int screen_trashed; +extern int sc_width, sc_height; +extern int show_attn; +extern int top_scroll; + +/* + * Jump to the end of the file. + */ +public void jump_forw(void) +{ + POSITION pos; + POSITION end_pos; + + if (ch_end_seek()) + { + error("Cannot seek to end of file", NULL_PARG); + return; + } + end_pos = ch_tell(); + if (position(sc_height-1) == end_pos) + { + eof_bell(); + return; + } + /* + * Note; lastmark will be called later by jump_loc, but it fails + * because the position table has been cleared by pos_clear below. + * So call it here before calling pos_clear. + */ + lastmark(); + /* + * Position the last line in the file at the last screen line. + * Go back one line from the end of the file + * to get to the beginning of the last line. + */ + pos_clear(); + pos = back_line(end_pos); + if (pos == NULL_POSITION) + jump_loc(ch_zero(), sc_height-1); + else + { + jump_loc(pos, sc_height-1); + if (position(sc_height-1) != end_pos) + repaint(); + } +} + +/* + * Jump to the last buffered line in the file. + */ +public void jump_forw_buffered(void) +{ + POSITION end; + + if (ch_end_buffer_seek()) + { + error("Cannot seek to end of buffers", NULL_PARG); + return; + } + end = ch_tell(); + if (end != NULL_POSITION && end > 0) + jump_line_loc(end-1, sc_height-1); +} + +/* + * Jump to line n in the file. + */ +public void jump_back(LINENUM linenum) +{ + POSITION pos; + PARG parg; + + /* + * Find the position of the specified line. + * If we can seek there, just jump to it. + * If we can't seek, but we're trying to go to line number 1, + * use ch_beg_seek() to get as close as we can. + */ + pos = find_pos(linenum); + if (pos != NULL_POSITION && ch_seek(pos) == 0) + { + if (show_attn) + set_attnpos(pos); + jump_loc(pos, jump_sline); + } else if (linenum <= 1 && ch_beg_seek() == 0) + { + jump_loc(ch_tell(), jump_sline); + error("Cannot seek to beginning of file", NULL_PARG); + } else + { + parg.p_linenum = linenum; + error("Cannot seek to line number %n", &parg); + } +} + +/* + * Repaint the screen. + */ +public void repaint(void) +{ + struct scrpos scrpos; + /* + * Start at the line currently at the top of the screen + * and redisplay the screen. + */ + get_scrpos(&scrpos, TOP); + pos_clear(); + if (scrpos.pos == NULL_POSITION) + /* Screen hasn't been drawn yet. */ + jump_loc(ch_zero(), 1); + else + jump_loc(scrpos.pos, scrpos.ln); +} + +/* + * Jump to a specified percentage into the file. + */ +public void jump_percent(int percent, long fraction) +{ + POSITION pos, len; + + /* + * Determine the position in the file + * (the specified percentage of the file's length). + */ + if ((len = ch_length()) == NULL_POSITION) + { + ierror("Determining length of file", NULL_PARG); + ch_end_seek(); + } + if ((len = ch_length()) == NULL_POSITION) + { + error("Don't know length of file", NULL_PARG); + return; + } + pos = percent_pos(len, percent, fraction); + if (pos >= len) + pos = len-1; + + jump_line_loc(pos, jump_sline); +} + +/* + * Jump to a specified position in the file. + * Like jump_loc, but the position need not be + * the first character in a line. + */ +public void jump_line_loc(POSITION pos, int sline) +{ + int c; + + if (ch_seek(pos) == 0) + { + /* + * Back up to the beginning of the line. + */ + while ((c = ch_back_get()) != '\n' && c != EOI) + ; + if (c == '\n') + (void) ch_forw_get(); + pos = ch_tell(); + } + if (show_attn) + set_attnpos(pos); + jump_loc(pos, sline); +} + +/* + * Jump to a specified position in the file. + * The position must be the first character in a line. + * Place the target line on a specified line on the screen. + */ +public void jump_loc(POSITION pos, int sline) +{ + int nline; + int sindex; + POSITION tpos; + POSITION bpos; + + /* + * Normalize sline. + */ + sindex = sindex_from_sline(sline); + + if ((nline = onscreen(pos)) >= 0) + { + /* + * The line is currently displayed. + * Just scroll there. + */ + nline -= sindex; + if (nline > 0) + forw(nline, position(BOTTOM_PLUS_ONE), 1, 0, 0); + else + back(-nline, position(TOP), 1, 0); +#if HILITE_SEARCH + if (show_attn) + repaint_hilite(1); +#endif + return; + } + + /* + * Line is not on screen. + * Seek to the desired location. + */ + if (ch_seek(pos)) + { + error("Cannot seek to that file position", NULL_PARG); + return; + } + + /* + * See if the desired line is before or after + * the currently displayed screen. + */ + tpos = position(TOP); + bpos = position(BOTTOM_PLUS_ONE); + if (tpos == NULL_POSITION || pos >= tpos) + { + /* + * The desired line is after the current screen. + * Move back in the file far enough so that we can + * call forw() and put the desired line at the + * sline-th line on the screen. + */ + for (nline = 0; nline < sindex; nline++) + { + if (bpos != NULL_POSITION && pos <= bpos) + { + /* + * Surprise! The desired line is + * close enough to the current screen + * that we can just scroll there after all. + */ + forw(sc_height-sindex+nline-1, bpos, 1, 0, 0); +#if HILITE_SEARCH + if (show_attn) + repaint_hilite(1); +#endif + return; + } + pos = back_line(pos); + if (pos == NULL_POSITION) + { + /* + * Oops. Ran into the beginning of the file. + * Exit the loop here and rely on forw() + * below to draw the required number of + * blank lines at the top of the screen. + */ + break; + } + } + lastmark(); + squished = 0; + screen_trashed = 0; + forw(sc_height-1, pos, 1, 0, sindex-nline); + } else + { + /* + * The desired line is before the current screen. + * Move forward in the file far enough so that we + * can call back() and put the desired line at the + * sindex-th line on the screen. + */ + for (nline = sindex; nline < sc_height - 1; nline++) + { + pos = forw_line(pos); + if (pos == NULL_POSITION) + { + /* + * Ran into end of file. + * This shouldn't normally happen, + * but may if there is some kind of read error. + */ + break; + } +#if HILITE_SEARCH + pos = next_unfiltered(pos); +#endif + if (pos >= tpos) + { + /* + * Surprise! The desired line is + * close enough to the current screen + * that we can just scroll there after all. + */ + back(nline+1, tpos, 1, 0); +#if HILITE_SEARCH + if (show_attn) + repaint_hilite(1); +#endif + return; + } + } + lastmark(); + if (!top_scroll) + clear(); + else + home(); + screen_trashed = 0; + add_back_pos(pos); + back(sc_height-1, pos, 1, 0); + } +} diff --git a/third_party/less/less.h b/third_party/less/less.h new file mode 100644 index 000000000..946839461 --- /dev/null +++ b/third_party/less/less.h @@ -0,0 +1,635 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + +#define NEWBOT 1 + +/* + * Standard include file for "less". + */ + +/* + * Defines for MSDOS_COMPILER. + */ +#define MSOFTC 1 /* Microsoft C */ +#define BORLANDC 2 /* Borland C */ +#define WIN32C 3 /* Windows (Borland C or Microsoft C) */ +#define DJGPPC 4 /* DJGPP C */ + +/* + * Include the file of compile-time options. + * The <> make cc search for it in -I., not srcdir. + */ +#include "defines.h" + +#ifdef _SEQUENT_ +/* + * Kludge for Sequent Dynix systems that have sigsetmask, but + * it's not compatible with the way less calls it. + * {{ Do other systems need this? }} + */ +#undef HAVE_SIGSETMASK +#endif + +/* + * Language details. + */ +#if HAVE_CONST +#define constant const +#else +#define constant +#endif + +#define public /* PUBLIC FUNCTION */ + +/* Library function declarations */ + +#if HAVE_SYS_TYPES_H +#include +#endif +#if HAVE_STDIO_H +#include +#endif +#if HAVE_FCNTL_H +#include +#endif +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_CTYPE_H +#include +#endif +#if HAVE_WCTYPE_H +#include +#endif +#if HAVE_LIMITS_H +#include +#endif +#if HAVE_STDINT_H +#include +#endif +#if HAVE_STDLIB_H +#include +#endif +#if HAVE_STRING_H +#include +#endif + +#if HAVE_STDCKDINT_H +#include +#else +/* + * These substitutes for C23 stdckdint macros do not set *R on overflow, + * and they assume A and B are nonnegative. That is good enough for us. + */ +#define ckd_add(r, a, b) help_ckd_add(r, a, b, sizeof *(r), signed_expr(*(r))) +#define ckd_mul(r, a, b) help_ckd_mul(r, a, b, sizeof *(r), signed_expr(*(r))) +/* True if the integer expression E, after promotion, is signed. */ +#define signed_expr(e) ((TRUE ? 0 : e) - 1 < 0) +#endif + +#if defined UINTMAX_MAX +typedef uintmax_t uintmax; +#elif defined ULLONG_MAX +typedef unsigned long long uintmax; +#else +typedef unsigned long uintmax; +#endif + +/* OS-specific includes */ +#ifdef _OSK +#include +#include +#endif + +#ifdef __TANDEM +#include +#endif + +#if MSDOS_COMPILER==WIN32C || OS2 +#include +#endif + +#if MSDOS_COMPILER==DJGPPC +#include +#include +#include +#include +#endif + +#if !HAVE_STDLIB_H +char *getenv(); +off_t lseek(); +void *calloc(); +void free(); +#endif + +/* + * Simple lowercase test which can be used during option processing + * (before options are parsed which might tell us what charset to use). + */ +#define ASCII_IS_UPPER(c) ((c) >= 'A' && (c) <= 'Z') +#define ASCII_IS_LOWER(c) ((c) >= 'a' && (c) <= 'z') +#define ASCII_TO_UPPER(c) ((c) - 'a' + 'A') +#define ASCII_TO_LOWER(c) ((c) - 'A' + 'a') + +#undef IS_UPPER +#undef IS_LOWER +#undef TO_UPPER +#undef TO_LOWER +#undef IS_SPACE +#undef IS_DIGIT + +#if HAVE_WCTYPE +#define IS_UPPER(c) iswupper(c) +#define IS_LOWER(c) iswlower(c) +#define TO_UPPER(c) towupper(c) +#define TO_LOWER(c) towlower(c) +#else +#if HAVE_UPPER_LOWER +#define IS_UPPER(c) isupper((unsigned char) (c)) +#define IS_LOWER(c) islower((unsigned char) (c)) +#define TO_UPPER(c) toupper((unsigned char) (c)) +#define TO_LOWER(c) tolower((unsigned char) (c)) +#else +#define IS_UPPER(c) ASCII_IS_UPPER(c) +#define IS_LOWER(c) ASCII_IS_LOWER(c) +#define TO_UPPER(c) ASCII_TO_UPPER(c) +#define TO_LOWER(c) ASCII_TO_LOWER(c) +#endif +#endif + +#ifdef isspace +#define IS_SPACE(c) isspace((unsigned char)(c)) +#else +#define IS_SPACE(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\r' || (c) == '\f') +#endif + +#ifdef isdigit +#define IS_DIGIT(c) isdigit((unsigned char)(c)) +#else +#define IS_DIGIT(c) ((c) >= '0' && (c) <= '9') +#endif + +#define IS_CSI_START(c) (((LWCHAR)(c)) == ESC || (((LWCHAR)(c)) == CSI)) + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#define OPT_OFF 0 +#define OPT_ON 1 +#define OPT_ONPLUS 2 + +#if !HAVE_MEMCPY +#ifndef memcpy +#define memcpy(to,from,len) bcopy((from),(to),(len)) +#endif +#endif + +#if HAVE_SNPRINTF +#define SNPRINTF1(str, size, fmt, v1) snprintf((str), (size), (fmt), (v1)) +#define SNPRINTF2(str, size, fmt, v1, v2) snprintf((str), (size), (fmt), (v1), (v2)) +#define SNPRINTF3(str, size, fmt, v1, v2, v3) snprintf((str), (size), (fmt), (v1), (v2), (v3)) +#define SNPRINTF4(str, size, fmt, v1, v2, v3, v4) snprintf((str), (size), (fmt), (v1), (v2), (v3), (v4)) +#else +/* Use unsafe sprintf if we don't have snprintf. */ +#define SNPRINTF1(str, size, fmt, v1) sprintf((str), (fmt), (v1)) +#define SNPRINTF2(str, size, fmt, v1, v2) sprintf((str), (fmt), (v1), (v2)) +#define SNPRINTF3(str, size, fmt, v1, v2, v3) sprintf((str), (fmt), (v1), (v2), (v3)) +#define SNPRINTF4(str, size, fmt, v1, v2, v3, v4) sprintf((str), (fmt), (v1), (v2), (v3), (v4)) +#endif + +#define BAD_LSEEK ((off_t)-1) + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif + +/* + * Upper bound on the string length of an integer converted to string. + * 302 / 1000 is ceil (log10 (2.0)). Subtract 1 for the sign bit; + * add 1 for integer division truncation; add 1 more for a minus sign. + */ +#define INT_STRLEN_BOUND(t) ((sizeof(t) * CHAR_BIT - 1) * 302 / 1000 + 1 + 1) + +/* + * Special types and constants. + */ +typedef unsigned long LWCHAR; +typedef off_t POSITION; +typedef off_t LINENUM; +#define MIN_LINENUM_WIDTH 7 /* Default min printing width of a line number */ +#define MAX_LINENUM_WIDTH 16 /* Max width of a line number */ +#define MAX_STATUSCOL_WIDTH 4 /* Max width of the status column */ +#define MAX_UTF_CHAR_LEN 6 /* Max bytes in one UTF-8 char */ +#define MAX_PRCHAR_LEN 31 /* Max chars in prchar() result */ + +#define NULL_POSITION ((POSITION)(-1)) + +/* + * Flags for open() + */ +#if MSDOS_COMPILER || OS2 +#define OPEN_READ (O_RDONLY|O_BINARY) +#else +#ifdef _OSK +#define OPEN_READ (S_IREAD) +#else +#ifdef O_RDONLY +#define OPEN_READ (O_RDONLY) +#else +#define OPEN_READ (0) +#endif +#endif +#endif + +#if defined(O_WRONLY) && defined(O_APPEND) +#define OPEN_APPEND (O_APPEND|O_WRONLY) +#else +#ifdef _OSK +#define OPEN_APPEND (S_IWRITE) +#else +#define OPEN_APPEND (1) +#endif +#endif + +/* + * Flags for creat() + */ +#if MSDOS_COMPILER +#define CREAT_RW (S_IREAD|S_IWRITE) +#else +#define CREAT_RW 0644 +#endif + +/* + * Set a file descriptor to binary mode. + */ +#if MSDOS_COMPILER==MSOFTC +#define SET_BINARY(f) _setmode(f, _O_BINARY); +#else +#if MSDOS_COMPILER || OS2 +#define SET_BINARY(f) setmode(f, O_BINARY) +#else +#define SET_BINARY(f) +#endif +#endif + +/* + * Does the shell treat "?" as a metacharacter? + */ +#if MSDOS_COMPILER || OS2 || _OSK +#define SHELL_META_QUEST 0 +#else +#define SHELL_META_QUEST 1 +#endif + +#define SPACES_IN_FILENAMES 1 + +/* + * An IFILE represents an input file. + */ +#define IFILE void* +#define NULL_IFILE ((IFILE)NULL) + +/* + * The structure used to represent a "screen position". + * This consists of a file position, and a screen line number. + * The meaning is that the line starting at the given file + * position is displayed on the ln-th line of the screen. + * (Screen lines before ln are empty.) + */ +struct scrpos +{ + POSITION pos; + int ln; +}; + +typedef union parg +{ + char *p_string; + int p_int; + LINENUM p_linenum; + char p_char; +} PARG; + +#define NULL_PARG ((PARG *)NULL) + +struct textlist +{ + char *string; + char *endstring; +}; + +struct wchar_range +{ + LWCHAR first, last; +}; + +struct wchar_range_table +{ + struct wchar_range *table; + int count; +}; + +#if HAVE_POLL +typedef short POLL_EVENTS; +#endif + +#define EOI (-1) + +#define READ_ERR (-1) +#define READ_INTR (-2) +#define READ_AGAIN (-3) + +/* + * A fraction is represented by a long n; the fraction is n/NUM_FRAC_DENOM. + * To avoid overflow problems, 0 <= n < NUM_FRAC_DENUM <= LONG_MAX/100. + */ +#define NUM_FRAC_DENOM 1000000 +#define NUM_LOG_FRAC_DENOM 6 + +/* How quiet should we be? */ +#define NOT_QUIET 0 /* Ring bell at eof and for errors */ +#define LITTLE_QUIET 1 /* Ring bell only for errors */ +#define VERY_QUIET 2 /* Never ring bell */ + +/* How should we prompt? */ +#define PR_SHORT 0 /* Prompt with colon */ +#define PR_MEDIUM 1 /* Prompt with message */ +#define PR_LONG 2 /* Prompt with longer message */ + +/* How should we handle backspaces? */ +#define BS_SPECIAL 0 /* Do special things for underlining and bold */ +#define BS_NORMAL 1 /* \b treated as normal char; actually output */ +#define BS_CONTROL 2 /* \b treated as control char; prints as ^H */ + +/* How should we search? */ +#define SRCH_FORW (1 << 0) /* Search forward from current position */ +#define SRCH_BACK (1 << 1) /* Search backward from current position */ +#define SRCH_NO_MOVE (1 << 2) /* Highlight, but don't move */ +#define SRCH_INCR (1 << 3) /* Incremental search */ +#define SRCH_FIND_ALL (1 << 4) /* Find and highlight all matches */ +#define SRCH_NO_MATCH (1 << 8) /* Search for non-matching lines */ +#define SRCH_PAST_EOF (1 << 9) /* Search past end-of-file, into next file */ +#define SRCH_FIRST_FILE (1 << 10) /* Search starting at the first file */ +#define SRCH_NO_REGEX (1 << 12) /* Don't use regular expressions */ +#define SRCH_FILTER (1 << 13) /* Search is for '&' (filter) command */ +#define SRCH_AFTER_TARGET (1 << 14) /* Start search after the target line */ +#define SRCH_WRAP (1 << 15) /* Wrap-around search (continue at BOF/EOF) */ +#define SRCH_SUBSEARCH(i) (1 << (16+(i))) /* Search for subpattern */ +/* {{ Depends on NUM_SEARCH_COLORS==5 }} */ +#define SRCH_SUBSEARCH_ALL (SRCH_SUBSEARCH(1)|SRCH_SUBSEARCH(2)|SRCH_SUBSEARCH(3)|SRCH_SUBSEARCH(4)|SRCH_SUBSEARCH(5)) + +#define SRCH_REVERSE(t) (((t) & SRCH_FORW) ? \ + (((t) & ~SRCH_FORW) | SRCH_BACK) : \ + (((t) & ~SRCH_BACK) | SRCH_FORW)) + +/* */ +#define NO_MCA 0 +#define MCA_DONE 1 +#define MCA_MORE 2 + +#define CC_OK 0 /* Char was accepted & processed */ +#define CC_QUIT 1 /* Char was a request to abort current cmd */ +#define CC_ERROR 2 /* Char could not be accepted due to error */ +#define CC_PASS 3 /* Char was rejected (internal) */ + +#define CF_QUIT_ON_ERASE 0001 /* Abort cmd if its entirely erased */ + +/* Special char bit-flags used to tell put_line() to do something special */ +#define AT_NORMAL (0) +#define AT_UNDERLINE (1 << 0) +#define AT_BOLD (1 << 1) +#define AT_BLINK (1 << 2) +#define AT_STANDOUT (1 << 3) +#define AT_ANSI (1 << 4) /* Content-supplied "ANSI" escape sequence */ +#define AT_BINARY (1 << 5) /* LESS*BINFMT representation */ +#define AT_HILITE (1 << 6) /* Internal highlights (e.g., for search) */ + +#define AT_COLOR_SHIFT 8 +#define AT_NUM_COLORS 16 +#define AT_COLOR ((AT_NUM_COLORS-1) << AT_COLOR_SHIFT) +#define AT_COLOR_ATTN (1 << AT_COLOR_SHIFT) +#define AT_COLOR_BIN (2 << AT_COLOR_SHIFT) +#define AT_COLOR_CTRL (3 << AT_COLOR_SHIFT) +#define AT_COLOR_ERROR (4 << AT_COLOR_SHIFT) +#define AT_COLOR_LINENUM (5 << AT_COLOR_SHIFT) +#define AT_COLOR_MARK (6 << AT_COLOR_SHIFT) +#define AT_COLOR_PROMPT (7 << AT_COLOR_SHIFT) +#define AT_COLOR_RSCROLL (8 << AT_COLOR_SHIFT) +#define AT_COLOR_HEADER (9 << AT_COLOR_SHIFT) +#define AT_COLOR_SEARCH (10 << AT_COLOR_SHIFT) +#define AT_COLOR_SUBSEARCH(i) ((10+(i)) << AT_COLOR_SHIFT) +#define NUM_SEARCH_COLORS (AT_NUM_COLORS-10-1) + +typedef enum { CT_NULL, CT_4BIT, CT_6BIT } COLOR_TYPE; + +typedef enum { + CV_BLUE = 1, + CV_GREEN = 2, + CV_RED = 4, + CV_BRIGHT = 8, + CV_NOCHANGE = -2, + CV_ERROR = -1 +} COLOR_VALUE; + +/* ANSI states */ +#define ANSI_MID 1 +#define ANSI_ERR 2 +#define ANSI_END 3 + +#if '0' == 240 +#define IS_EBCDIC_HOST 1 +#endif + +#if IS_EBCDIC_HOST +/* + * Long definition for EBCDIC. + * Since the argument is usually a constant, this macro normally compiles + * into a constant. + */ +#define CONTROL(c) ( \ + (c)=='[' ? '\047' : \ + (c)=='a' ? '\001' : \ + (c)=='b' ? '\002' : \ + (c)=='c' ? '\003' : \ + (c)=='d' ? '\067' : \ + (c)=='e' ? '\055' : \ + (c)=='f' ? '\056' : \ + (c)=='g' ? '\057' : \ + (c)=='h' ? '\026' : \ + (c)=='i' ? '\005' : \ + (c)=='j' ? '\025' : \ + (c)=='k' ? '\013' : \ + (c)=='l' ? '\014' : \ + (c)=='m' ? '\015' : \ + (c)=='n' ? '\016' : \ + (c)=='o' ? '\017' : \ + (c)=='p' ? '\020' : \ + (c)=='q' ? '\021' : \ + (c)=='r' ? '\022' : \ + (c)=='s' ? '\023' : \ + (c)=='t' ? '\074' : \ + (c)=='u' ? '\075' : \ + (c)=='v' ? '\062' : \ + (c)=='w' ? '\046' : \ + (c)=='x' ? '\030' : \ + (c)=='y' ? '\031' : \ + (c)=='z' ? '\077' : \ + (c)=='A' ? '\001' : \ + (c)=='B' ? '\002' : \ + (c)=='C' ? '\003' : \ + (c)=='D' ? '\067' : \ + (c)=='E' ? '\055' : \ + (c)=='F' ? '\056' : \ + (c)=='G' ? '\057' : \ + (c)=='H' ? '\026' : \ + (c)=='I' ? '\005' : \ + (c)=='J' ? '\025' : \ + (c)=='K' ? '\013' : \ + (c)=='L' ? '\014' : \ + (c)=='M' ? '\015' : \ + (c)=='N' ? '\016' : \ + (c)=='O' ? '\017' : \ + (c)=='P' ? '\020' : \ + (c)=='Q' ? '\021' : \ + (c)=='R' ? '\022' : \ + (c)=='S' ? '\023' : \ + (c)=='T' ? '\074' : \ + (c)=='U' ? '\075' : \ + (c)=='V' ? '\062' : \ + (c)=='W' ? '\046' : \ + (c)=='X' ? '\030' : \ + (c)=='Y' ? '\031' : \ + (c)=='Z' ? '\077' : \ + (c)=='|' ? '\031' : \ + (c)=='\\' ? '\034' : \ + (c)=='^' ? '\036' : \ + (c)&077) +#else +#define CONTROL(c) ((c)&037) +#endif /* IS_EBCDIC_HOST */ + +#define ESC CONTROL('[') +#define ESCS "\33" +#define CSI ((unsigned char)'\233') +#define CHAR_END_COMMAND 0x40000000 + +#if _OSK_MWC32 +#define LSIGNAL(sig,func) os9_signal(sig,func) +#else +#define LSIGNAL(sig,func) signal(sig,func) +#endif + +#if HAVE_SIGPROCMASK +#if HAVE_SIGSET_T +#else +#undef HAVE_SIGPROCMASK +#endif +#endif +#if HAVE_SIGPROCMASK +#if HAVE_SIGEMPTYSET +#else +#undef sigemptyset +#define sigemptyset(mp) *(mp) = 0 +#endif +#endif + +#define S_INTERRUPT 01 +#define S_STOP 02 +#define S_WINCH 04 +#define ABORT_SIGS() (sigs & (S_INTERRUPT|S_STOP)) + +#ifdef EXIT_SUCCESS +#define QUIT_OK EXIT_SUCCESS +#else +#define QUIT_OK 0 +#endif +#ifdef EXIT_FAILURE +#define QUIT_ERROR EXIT_FAILURE +#define QUIT_INTERRUPT (EXIT_FAILURE+1) +#else +#define QUIT_ERROR 1 +#define QUIT_INTERRUPT 2 +#endif +#define QUIT_SAVED_STATUS (-1) + +#define FOLLOW_DESC 0 +#define FOLLOW_NAME 1 + +/* filestate flags */ +#define CH_CANSEEK 001 +#define CH_KEEPOPEN 002 +#define CH_POPENED 004 +#define CH_HELPFILE 010 +#define CH_NODATA 020 /* Special case for zero length files */ + +#define ch_zero() ((POSITION)0) + +#define FAKE_HELPFILE "@/\\less/\\help/\\file/\\@" +#define FAKE_EMPTYFILE "@/\\less/\\empty/\\file/\\@" + +/* Flags for cvt_text */ +#define CVT_TO_LC 01 /* Convert upper-case to lower-case */ +#define CVT_BS 02 /* Do backspace processing */ +#define CVT_CRLF 04 /* Remove CR after LF */ +#define CVT_ANSI 010 /* Remove ANSI escape sequences */ + +#if HAVE_TIME_T +#define time_type time_t +#else +#define time_type long +#endif + +/* X11 mouse reporting definitions */ +#define X11MOUSE_BUTTON1 0 /* Left button press */ +#define X11MOUSE_BUTTON2 1 /* Middle button press */ +#define X11MOUSE_BUTTON3 2 /* Right button press */ +#define X11MOUSE_BUTTON_REL 3 /* Button release */ +#define X11MOUSE_WHEEL_UP 0x40 /* Wheel scroll up */ +#define X11MOUSE_WHEEL_DOWN 0x41 /* Wheel scroll down */ +#define X11MOUSE_OFFSET 0x20 /* Added to button & pos bytes to create a char */ + +#if LESSTEST +#define LESS_DUMP_CHAR CONTROL(']') +#endif + +struct mlist; +struct loption; +struct hilite_tree; +struct ansi_state; +#include "pattern.h" +#include "xbuf.h" +#include "funcs.h" + +/* Functions not included in funcs.h */ +void postoa(POSITION, char*, int); +void linenumtoa(LINENUM, char*, int); +void inttoa(int, char*, int); +int lstrtoi(char*, char**, int); +POSITION lstrtopos(char*, char**, int); +unsigned long lstrtoul(char*, char**, int); +#if MSDOS_COMPILER==WIN32C +int pclose(FILE*); +#endif diff --git a/third_party/less/lessecho.c b/third_party/less/lessecho.c new file mode 100644 index 000000000..67bdf9c71 --- /dev/null +++ b/third_party/less/lessecho.c @@ -0,0 +1,282 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * lessecho [-ox] [-cx] [-pn] [-dn] [-a] file ... + * Simply echos its filename arguments on standard output. + * But any argument containing spaces is enclosed in quotes. + * + * -ox Specifies "x" to be the open quote character. + * -cx Specifies "x" to be the close quote character. + * -pn Specifies "n" to be the open quote character, as an integer. + * -dn Specifies "n" to be the close quote character, as an integer. + * -mx Specifies "x" to be a metachar. + * -nn Specifies "n" to be a metachar, as an integer. + * -ex Specifies "x" to be the escape char for metachars. + * -fn Specifies "x" to be the escape char for metachars, as an integer. + * -a Specifies that all arguments are to be quoted. + * The default is that only arguments containing spaces are quoted. + */ + +#include "less.h" + +static char *version = "$Revision: 1.15 $"; + +static int quote_all = 0; +static char openquote = '"'; +static char closequote = '"'; +static char *meta_escape = "\\"; +static char meta_escape_buf[2]; +static char* metachars = NULL; +static int num_metachars = 0; +static int size_metachars = 0; + +static void pr_usage(void) +{ + fprintf(stderr, + "usage: lessecho [-ox] [-cx] [-pn] [-dn] [-mx] [-nn] [-ex] [-fn] [-a] file ...\n"); +} + +static void pr_version(void) +{ + char *p; + char buf[10]; + char *pbuf = buf; + + for (p = version; *p != ' '; p++) + if (*p == '\0') + return; + for (p++; *p != '$' && *p != ' ' && *p != '\0'; p++) + *pbuf++ = *p; + *pbuf = '\0'; + printf("%s\n", buf); +} + +static void pr_error(char *s) +{ + fprintf(stderr, "%s\n", s); + exit(1); +} + +static long lstrtol(char *s, char **pend, int radix) +{ + int v; + int neg = 0; + long n = 0; + + /* Skip leading white space. */ + while (*s == ' ' || *s == '\t') + s++; + + /* Check for a leading + or -. */ + if (*s == '-') + { + neg = 1; + s++; + } else if (*s == '+') + { + s++; + } + + /* Determine radix if caller does not specify. */ + if (radix == 0) + { + radix = 10; + if (*s == '0') + { + switch (*++s) + { + case 'x': + radix = 16; + s++; + break; + default: + radix = 8; + break; + } + } + } + + /* Parse the digits of the number. */ + for (;;) + { + if (*s >= '0' && *s <= '9') + v = *s - '0'; + else if (*s >= 'a' && *s <= 'f') + v = *s - 'a' + 10; + else if (*s >= 'A' && *s <= 'F') + v = *s - 'A' + 10; + else + break; + if (v >= radix) + break; + n = n * radix + v; + s++; + } + + if (pend != NULL) + { + /* Skip trailing white space. */ + while (*s == ' ' || *s == '\t') + s++; + *pend = s; + } + if (neg) + return (-n); + return (n); +} + +static void add_metachar(int ch) +{ + if (num_metachars+1 >= size_metachars) + { + char *p; + size_metachars = (size_metachars > 0) ? size_metachars*2 : 16; + p = (char *) malloc(size_metachars); + if (p == NULL) + pr_error("Cannot allocate memory"); + + if (metachars != NULL) + { + strcpy(p, metachars); + free(metachars); + } + metachars = p; + } + metachars[num_metachars++] = ch; + metachars[num_metachars] = '\0'; +} + +static int is_metachar(int ch) +{ + return (metachars != NULL && strchr(metachars, ch) != NULL); +} + +#if !HAVE_STRCHR +char * strchr(char *s, char c) +{ + for ( ; *s != '\0'; s++) + if (*s == c) + return (s); + if (c == '\0') + return (s); + return (NULL); +} +#endif + +int main(int argc, char *argv[]) +{ + char *arg; + char *s; + int no_more_options; + + no_more_options = 0; + while (--argc > 0) + { + arg = *++argv; + if (*arg != '-' || no_more_options) + break; + switch (*++arg) + { + case 'a': + quote_all = 1; + break; + case 'c': + closequote = *++arg; + break; + case 'd': + closequote = lstrtol(++arg, &s, 0); + if (s == arg) + pr_error("Missing number after -d"); + break; + case 'e': + if (strcmp(++arg, "-") == 0) + meta_escape = ""; + else + meta_escape = arg; + break; + case 'f': + meta_escape_buf[0] = lstrtol(++arg, &s, 0); + meta_escape_buf[1] = '\0'; + meta_escape = meta_escape_buf; + if (s == arg) + pr_error("Missing number after -f"); + break; + case 'o': + openquote = *++arg; + break; + case 'p': + openquote = lstrtol(++arg, &s, 0); + if (s == arg) + pr_error("Missing number after -p"); + break; + case 'm': + add_metachar(*++arg); + break; + case 'n': + add_metachar(lstrtol(++arg, &s, 0)); + if (s == arg) + pr_error("Missing number after -n"); + break; + case '?': + pr_usage(); + return (0); + case '-': + if (*++arg == '\0') + { + no_more_options = 1; + break; + } + if (strcmp(arg, "version") == 0) + { + pr_version(); + return (0); + } + if (strcmp(arg, "help") == 0) + { + pr_usage(); + return (0); + } + pr_error("Invalid option after --"); + default: + pr_error("Invalid option letter"); + } + } + + while (argc-- > 0) + { + int has_meta = 0; + arg = *argv++; + for (s = arg; *s != '\0'; s++) + { + if (is_metachar(*s)) + { + has_meta = 1; + break; + } + } + if (quote_all || (has_meta && strlen(meta_escape) == 0)) + printf("%c%s%c", openquote, arg, closequote); + else + { + for (s = arg; *s != '\0'; s++) + { + if (is_metachar(*s)) + printf("%s", meta_escape); + printf("%c", *s); + } + } + if (argc > 0) + printf(" "); + else + printf("\n"); + } + return (0); +} diff --git a/third_party/less/lesskey.c b/third_party/less/lesskey.c new file mode 100644 index 000000000..61311c7ef --- /dev/null +++ b/third_party/less/lesskey.c @@ -0,0 +1,357 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * lesskey [-o output] [input] + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Make a .less file. + * If no input file is specified, standard input is used. + * If no output file is specified, $HOME/.less is used. + * + * The .less file is used to specify (to "less") user-defined + * key bindings. Basically any sequence of 1 to MAX_CMDLEN + * keystrokes may be bound to an existing less function. + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * The input file is an ascii file consisting of a + * sequence of lines of the form: + * string action [chars] + * + * "string" is a sequence of command characters which form + * the new user-defined command. The command + * characters may be: + * 1. The actual character itself. + * 2. A character preceded by ^ to specify a + * control character (e.g. ^X means control-X). + * 3. A backslash followed by one to three octal digits + * to specify a character by its octal value. + * 4. A backslash followed by b, e, n, r or t + * to specify \b, ESC, \n, \r or \t, respectively. + * 5. Any character (other than those mentioned above) preceded + * by a \ to specify the character itself (characters which + * must be preceded by \ include ^, \, and whitespace. + * "action" is the name of a "less" action, from the table below. + * "chars" is an optional sequence of characters which is treated + * as keyboard input after the command is executed. + * + * Blank lines and lines which start with # are ignored, + * except for the special control lines: + * #command Signals the beginning of the command + * keys section. + * #line-edit Signals the beginning of the line-editing + * keys section. + * #env Signals the beginning of the environment + * variable section. + * #stop Stops command parsing in less; + * causes all default keys to be disabled. + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * The output file is a non-ascii file, consisting of a header, + * one or more sections, and a trailer. + * Each section begins with a section header, a section length word + * and the section data. Normally there are three sections: + * CMD_SECTION Definition of command keys. + * EDIT_SECTION Definition of editing keys. + * END_SECTION A special section header, with no + * length word or section data. + * + * Section data consists of zero or more byte sequences of the form: + * string <0> + * or + * string <0> chars <0> + * + * "string" is the command string. + * "<0>" is one null byte. + * "" is one byte containing the action code (the A_xxx value). + * If action is ORed with A_EXTRA, the action byte is followed + * by the null-terminated "chars" string. + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + */ + +#include "defines.h" +#include +#include +#include +#include "lesskey.h" +#include "cmd.h" + +char fileheader[] = { + C0_LESSKEY_MAGIC, + C1_LESSKEY_MAGIC, + C2_LESSKEY_MAGIC, + C3_LESSKEY_MAGIC +}; +char filetrailer[] = { + C0_END_LESSKEY_MAGIC, + C1_END_LESSKEY_MAGIC, + C2_END_LESSKEY_MAGIC +}; +char cmdsection[1] = { CMD_SECTION }; +char editsection[1] = { EDIT_SECTION }; +char varsection[1] = { VAR_SECTION }; +char endsection[1] = { END_SECTION }; + +char *infile = NULL; +char *outfile = NULL ; + +extern char version[]; + +static void usage(void) +{ + fprintf(stderr, "usage: lesskey [-o output] [input]\n"); + exit(1); +} + +void lesskey_parse_error(char *s) +{ + fprintf(stderr, "%s\n", s); +} + +int lstrtoi(char *buf, char **ebuf, int radix) +{ + return (int) strtol(buf, ebuf, radix); +} + +void out_of_memory(void) +{ + fprintf(stderr, "lesskey: cannot allocate memory\n"); + exit(1); +} + +void * ecalloc(int count, unsigned int size) +{ + void *p; + + p = calloc(count, size); + if (p == NULL) + out_of_memory(); + return (p); +} + +static char * mkpathname(char *dirname, char *filename) +{ + char *pathname; + + pathname = ecalloc(strlen(dirname) + strlen(filename) + 2, sizeof(char)); + strcpy(pathname, dirname); + strcat(pathname, PATHNAME_SEP); + strcat(pathname, filename); + return (pathname); +} + +/* + * Figure out the name of a default file (in the user's HOME directory). + */ +char * homefile(char *filename) +{ + char *p; + char *pathname; + + if ((p = getenv("HOME")) != NULL && *p != '\0') + pathname = mkpathname(p, filename); +#if OS2 + else if ((p = getenv("INIT")) != NULL && *p != '\0') + pathname = mkpathname(p, filename); +#endif + else + { + fprintf(stderr, "cannot find $HOME - using current directory\n"); + pathname = mkpathname(".", filename); + } + return (pathname); +} + +/* + * Parse command line arguments. + */ +static void parse_args(int argc, char **argv) +{ + char *arg; + + outfile = NULL; + while (--argc > 0) + { + arg = *++argv; + if (arg[0] != '-') + /* Arg does not start with "-"; it's not an option. */ + break; + if (arg[1] == '\0') + /* "-" means standard input. */ + break; + if (arg[1] == '-' && arg[2] == '\0') + { + /* "--" means end of options. */ + argc--; + argv++; + break; + } + switch (arg[1]) + { + case '-': + if (strncmp(arg, "--output", 8) == 0) + { + if (arg[8] == '\0') + outfile = &arg[8]; + else if (arg[8] == '=') + outfile = &arg[9]; + else + usage(); + goto opt_o; + } + if (strcmp(arg, "--version") == 0) + { + goto opt_V; + } + usage(); + break; + case 'o': + outfile = &argv[0][2]; + opt_o: + if (*outfile == '\0') + { + if (--argc <= 0) + usage(); + outfile = *(++argv); + } + break; + case 'V': + opt_V: + printf("lesskey version %s\n", version); + exit(0); + default: + usage(); + } + } + if (argc > 1) + usage(); + /* + * Open the input file, or use DEF_LESSKEYINFILE if none specified. + */ + if (argc > 0) + infile = *argv; +} + +/* + * Output some bytes. + */ +static void fputbytes(FILE *fd, char *buf, int len) +{ + while (len-- > 0) + { + fwrite(buf, sizeof(char), 1, fd); + buf++; + } +} + +/* + * Output an integer, in special KRADIX form. + */ +static void fputint(FILE *fd, unsigned int val) +{ + char c; + + if (val >= KRADIX*KRADIX) + { + fprintf(stderr, "error: cannot write %d, max %d\n", + val, KRADIX*KRADIX); + exit(1); + } + c = val % KRADIX; + fwrite(&c, sizeof(char), 1, fd); + c = val / KRADIX; + fwrite(&c, sizeof(char), 1, fd); +} + +int main(int argc, char *argv[]) +{ + struct lesskey_tables tables; + FILE *out; + int errors; + +#ifdef WIN32 + if (getenv("HOME") == NULL) + { + /* + * If there is no HOME environment variable, + * try the concatenation of HOMEDRIVE + HOMEPATH. + */ + char *drive = getenv("HOMEDRIVE"); + char *path = getenv("HOMEPATH"); + if (drive != NULL && path != NULL) + { + char *env = (char *) ecalloc(strlen(drive) + + strlen(path) + 6, sizeof(char)); + strcpy(env, "HOME="); + strcat(env, drive); + strcat(env, path); + putenv(env); + } + } +#endif /* WIN32 */ + + /* + * Process command line arguments. + */ + parse_args(argc, argv); + errors = parse_lesskey(infile, &tables); + if (errors) + { + fprintf(stderr, "%d errors; no output produced\n", errors); + return (1); + } + + fprintf(stderr, "NOTE: lesskey is deprecated.\n It is no longer necessary to run lesskey,\n when using less version 582 and later.\n"); + + /* + * Write the output file. + * If no output file was specified, use "$HOME/.less" + */ + if (outfile == NULL) + outfile = getenv("LESSKEY"); + if (outfile == NULL) + outfile = homefile(LESSKEYFILE); + if ((out = fopen(outfile, "wb")) == NULL) + { +#if HAVE_PERROR + perror(outfile); +#else + fprintf(stderr, "Cannot open %s\n", outfile); +#endif + return (1); + } + + /* File header */ + fputbytes(out, fileheader, sizeof(fileheader)); + + /* Command key section */ + fputbytes(out, cmdsection, sizeof(cmdsection)); + fputint(out, tables.cmdtable.buf.end); + fputbytes(out, (char *)tables.cmdtable.buf.data, tables.cmdtable.buf.end); + /* Edit key section */ + fputbytes(out, editsection, sizeof(editsection)); + fputint(out, tables.edittable.buf.end); + fputbytes(out, (char *)tables.edittable.buf.data, tables.edittable.buf.end); + + /* Environment variable section */ + fputbytes(out, varsection, sizeof(varsection)); + fputint(out, tables.vartable.buf.end); + fputbytes(out, (char *)tables.vartable.buf.data, tables.vartable.buf.end); + + /* File trailer */ + fputbytes(out, endsection, sizeof(endsection)); + fputbytes(out, filetrailer, sizeof(filetrailer)); + fclose(out); + return (0); +} diff --git a/third_party/less/lesskey.h b/third_party/less/lesskey.h new file mode 100644 index 000000000..4a8459ada --- /dev/null +++ b/third_party/less/lesskey.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + +#include "xbuf.h" + +/* + * Format of a lesskey file: + * + * LESSKEY_MAGIC (4 bytes) + * sections... + * END_LESSKEY_MAGIC (4 bytes) + * + * Each section is: + * + * section_MAGIC (1 byte) + * section_length (2 bytes) + * key table (section_length bytes) + */ +#define C0_LESSKEY_MAGIC '\0' +#define C1_LESSKEY_MAGIC 'M' +#define C2_LESSKEY_MAGIC '+' +#define C3_LESSKEY_MAGIC 'G' + +#define CMD_SECTION 'c' +#define EDIT_SECTION 'e' +#define VAR_SECTION 'v' +#define END_SECTION 'x' + +#define C0_END_LESSKEY_MAGIC 'E' +#define C1_END_LESSKEY_MAGIC 'n' +#define C2_END_LESSKEY_MAGIC 'd' + +/* */ +#define KRADIX 64 + +struct lesskey_cmdname +{ + char *cn_name; + int cn_action; +}; + +struct lesskey_table +{ + struct lesskey_cmdname *names; + struct xbuffer buf; + int is_var; +}; + +struct lesskey_tables +{ + struct lesskey_table *currtable; + struct lesskey_table cmdtable; + struct lesskey_table edittable; + struct lesskey_table vartable; +}; + +extern int parse_lesskey(char *infile, struct lesskey_tables *tables); diff --git a/third_party/less/lesskey_parse.c b/third_party/less/lesskey_parse.c new file mode 100644 index 000000000..3f528aa87 --- /dev/null +++ b/third_party/less/lesskey_parse.c @@ -0,0 +1,651 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + +#include "defines.h" +#include +#include +#include +#include "lesskey.h" +#include "cmd.h" +#include "xbuf.h" + +#define CONTROL(c) ((c)&037) +#define ESC CONTROL('[') + +extern void lesskey_parse_error(char *msg); +extern char *homefile(char *filename); +extern void *ecalloc(int count, unsigned int size); +extern int lstrtoi(char *str, char **end, int radix); +extern char version[]; + +static int linenum; +static int errors; +static int less_version = 0; +static char *lesskey_file; + +static struct lesskey_cmdname cmdnames[] = +{ + { "back-bracket", A_B_BRACKET }, + { "back-line", A_B_LINE }, + { "back-line-force", A_BF_LINE }, + { "back-screen", A_B_SCREEN }, + { "back-scroll", A_B_SCROLL }, + { "back-search", A_B_SEARCH }, + { "back-window", A_B_WINDOW }, + { "clear-mark", A_CLRMARK }, + { "debug", A_DEBUG }, + { "digit", A_DIGIT }, + { "display-flag", A_DISP_OPTION }, + { "display-option", A_DISP_OPTION }, + { "end", A_GOEND }, + { "end-scroll", A_RRSHIFT }, + { "examine", A_EXAMINE }, + { "filter", A_FILTER }, + { "first-cmd", A_FIRSTCMD }, + { "firstcmd", A_FIRSTCMD }, + { "flush-repaint", A_FREPAINT }, + { "forw-bracket", A_F_BRACKET }, + { "forw-forever", A_F_FOREVER }, + { "forw-until-hilite", A_F_UNTIL_HILITE }, + { "forw-line", A_F_LINE }, + { "forw-line-force", A_FF_LINE }, + { "forw-screen", A_F_SCREEN }, + { "forw-screen-force", A_FF_SCREEN }, + { "forw-scroll", A_F_SCROLL }, + { "forw-search", A_F_SEARCH }, + { "forw-window", A_F_WINDOW }, + { "goto-end", A_GOEND }, + { "goto-end-buffered", A_GOEND_BUF }, + { "goto-line", A_GOLINE }, + { "goto-mark", A_GOMARK }, + { "help", A_HELP }, + { "index-file", A_INDEX_FILE }, + { "invalid", A_UINVALID }, + { "left-scroll", A_LSHIFT }, + { "next-file", A_NEXT_FILE }, + { "next-tag", A_NEXT_TAG }, + { "noaction", A_NOACTION }, + { "no-scroll", A_LLSHIFT }, + { "percent", A_PERCENT }, + { "pipe", A_PIPE }, + { "prev-file", A_PREV_FILE }, + { "prev-tag", A_PREV_TAG }, + { "quit", A_QUIT }, + { "remove-file", A_REMOVE_FILE }, + { "repaint", A_REPAINT }, + { "repaint-flush", A_FREPAINT }, + { "repeat-search", A_AGAIN_SEARCH }, + { "repeat-search-all", A_T_AGAIN_SEARCH }, + { "reverse-search", A_REVERSE_SEARCH }, + { "reverse-search-all", A_T_REVERSE_SEARCH }, + { "right-scroll", A_RSHIFT }, + { "set-mark", A_SETMARK }, + { "set-mark-bottom", A_SETMARKBOT }, + { "shell", A_SHELL }, + { "pshell", A_PSHELL }, + { "status", A_STAT }, + { "toggle-flag", A_OPT_TOGGLE }, + { "toggle-option", A_OPT_TOGGLE }, + { "undo-hilite", A_UNDO_SEARCH }, + { "clear-search", A_CLR_SEARCH }, + { "version", A_VERSION }, + { "visual", A_VISUAL }, + { NULL, 0 } +}; + +static struct lesskey_cmdname editnames[] = +{ + { "back-complete", EC_B_COMPLETE }, + { "backspace", EC_BACKSPACE }, + { "delete", EC_DELETE }, + { "down", EC_DOWN }, + { "end", EC_END }, + { "expand", EC_EXPAND }, + { "forw-complete", EC_F_COMPLETE }, + { "home", EC_HOME }, + { "insert", EC_INSERT }, + { "invalid", EC_UINVALID }, + { "kill-line", EC_LINEKILL }, + { "abort", EC_ABORT }, + { "left", EC_LEFT }, + { "literal", EC_LITERAL }, + { "right", EC_RIGHT }, + { "up", EC_UP }, + { "word-backspace", EC_W_BACKSPACE }, + { "word-delete", EC_W_DELETE }, + { "word-left", EC_W_LEFT }, + { "word-right", EC_W_RIGHT }, + { NULL, 0 } +}; + +/* + * Print a parse error message. + */ +static void parse_error(char *fmt, char *arg1) +{ + char buf[1024]; + int n = snprintf(buf, sizeof(buf), "%s: line %d: ", lesskey_file, linenum); + if (n >= 0 && n < sizeof(buf)) + snprintf(buf+n, sizeof(buf)-n, fmt, arg1); + ++errors; + lesskey_parse_error(buf); +} + +/* + * Initialize lesskey_tables. + */ +static void init_tables(struct lesskey_tables *tables) +{ + tables->currtable = &tables->cmdtable; + + tables->cmdtable.names = cmdnames; + tables->cmdtable.is_var = 0; + xbuf_init(&tables->cmdtable.buf); + + tables->edittable.names = editnames; + tables->edittable.is_var = 0; + xbuf_init(&tables->edittable.buf); + + tables->vartable.names = NULL; + tables->vartable.is_var = 1; + xbuf_init(&tables->vartable.buf); +} + +#define CHAR_STRING_LEN 8 + +static char * char_string(char *buf, int ch, int lit) +{ + if (lit || (ch >= 0x20 && ch < 0x7f)) + { + buf[0] = ch; + buf[1] = '\0'; + } else + { + snprintf(buf, CHAR_STRING_LEN, "\\x%02x", ch); + } + return buf; +} + +/* + * Increment char pointer by one up to terminating nul byte. + */ +static char * increment_pointer(char *p) +{ + if (*p == '\0') + return p; + return p+1; +} + +/* + * Parse one character of a string. + */ +static char * tstr(char **pp, int xlate) +{ + char *p; + char ch; + int i; + static char buf[CHAR_STRING_LEN]; + static char tstr_control_k[] = + { SK_SPECIAL_KEY, SK_CONTROL_K, 6, 1, 1, 1, '\0' }; + + p = *pp; + switch (*p) + { + case '\\': + ++p; + switch (*p) + { + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + /* + * Parse an octal number. + */ + ch = 0; + i = 0; + do + ch = 8*ch + (*p - '0'); + while (*++p >= '0' && *p <= '7' && ++i < 3); + *pp = p; + if (xlate && ch == CONTROL('K')) + return tstr_control_k; + return char_string(buf, ch, 1); + case 'b': + *pp = p+1; + return ("\b"); + case 'e': + *pp = p+1; + return char_string(buf, ESC, 1); + case 'n': + *pp = p+1; + return ("\n"); + case 'r': + *pp = p+1; + return ("\r"); + case 't': + *pp = p+1; + return ("\t"); + case 'k': + if (xlate) + { + switch (*++p) + { + case 'b': ch = SK_BACKSPACE; break; + case 'B': ch = SK_CTL_BACKSPACE; break; + case 'd': ch = SK_DOWN_ARROW; break; + case 'D': ch = SK_PAGE_DOWN; break; + case 'e': ch = SK_END; break; + case 'h': ch = SK_HOME; break; + case 'i': ch = SK_INSERT; break; + case 'l': ch = SK_LEFT_ARROW; break; + case 'L': ch = SK_CTL_LEFT_ARROW; break; + case 'r': ch = SK_RIGHT_ARROW; break; + case 'R': ch = SK_CTL_RIGHT_ARROW; break; + case 't': ch = SK_BACKTAB; break; + case 'u': ch = SK_UP_ARROW; break; + case 'U': ch = SK_PAGE_UP; break; + case 'x': ch = SK_DELETE; break; + case 'X': ch = SK_CTL_DELETE; break; + case '1': ch = SK_F1; break; + default: + parse_error("invalid escape sequence \"\\k%s\"", char_string(buf, *p, 0)); + *pp = increment_pointer(p); + return (""); + } + *pp = p+1; + buf[0] = SK_SPECIAL_KEY; + buf[1] = ch; + buf[2] = 6; + buf[3] = 1; + buf[4] = 1; + buf[5] = 1; + buf[6] = '\0'; + return (buf); + } + /* FALLTHRU */ + default: + /* + * Backslash followed by any other char + * just means that char. + */ + *pp = increment_pointer(p); + char_string(buf, *p, 1); + if (xlate && buf[0] == CONTROL('K')) + return tstr_control_k; + return (buf); + } + case '^': + /* + * Caret means CONTROL. + */ + *pp = increment_pointer(p+1); + char_string(buf, CONTROL(p[1]), 1); + if (xlate && buf[0] == CONTROL('K')) + return tstr_control_k; + return (buf); + } + *pp = increment_pointer(p); + char_string(buf, *p, 1); + if (xlate && buf[0] == CONTROL('K')) + return tstr_control_k; + return (buf); +} + +static int issp(char ch) +{ + return (ch == ' ' || ch == '\t'); +} + +/* + * Skip leading spaces in a string. + */ +static char * skipsp(char *s) +{ + while (issp(*s)) + s++; + return (s); +} + +/* + * Skip non-space characters in a string. + */ +static char * skipnsp(char *s) +{ + while (*s != '\0' && !issp(*s)) + s++; + return (s); +} + +/* + * Clean up an input line: + * strip off the trailing newline & any trailing # comment. + */ +static char * clean_line(char *s) +{ + int i; + + s = skipsp(s); + for (i = 0; s[i] != '\0' && s[i] != '\n' && s[i] != '\r'; i++) + if (s[i] == '#' && (i == 0 || s[i-1] != '\\')) + break; + s[i] = '\0'; + return (s); +} + +/* + * Add a byte to the output command table. + */ +static void add_cmd_char(unsigned char c, struct lesskey_tables *tables) +{ + xbuf_add_byte(&tables->currtable->buf, c); +} + +static void erase_cmd_char(struct lesskey_tables *tables) +{ + xbuf_pop(&tables->currtable->buf); +} + +/* + * Add a string to the output command table. + */ +static void add_cmd_str(char *s, struct lesskey_tables *tables) +{ + for ( ; *s != '\0'; s++) + add_cmd_char(*s, tables); +} + +/* + * Does a given version number match the running version? + * Operator compares the running version to the given version. + */ +static int match_version(char op, int ver) +{ + switch (op) + { + case '>': return less_version > ver; + case '<': return less_version < ver; + case '+': return less_version >= ver; + case '-': return less_version <= ver; + case '=': return less_version == ver; + case '!': return less_version != ver; + default: return 0; /* cannot happen */ + } +} + +/* + * Handle a #version line. + * If the version matches, return the part of the line that should be executed. + * Otherwise, return NULL. + */ +static char * version_line(char *s, struct lesskey_tables *tables) +{ + char op; + int ver; + char *e; + char buf[CHAR_STRING_LEN]; + + s += strlen("#version"); + s = skipsp(s); + op = *s++; + /* Simplify 2-char op to one char. */ + switch (op) + { + case '<': if (*s == '=') { s++; op = '-'; } break; + case '>': if (*s == '=') { s++; op = '+'; } break; + case '=': if (*s == '=') { s++; } break; + case '!': if (*s == '=') { s++; } break; + default: + parse_error("invalid operator '%s' in #version line", char_string(buf, op, 0)); + return (NULL); + } + s = skipsp(s); + ver = lstrtoi(s, &e, 10); + if (e == s) + { + parse_error("non-numeric version number in #version line", ""); + return (NULL); + } + if (!match_version(op, ver)) + return (NULL); + return (e); +} + +/* + * See if we have a special "control" line. + */ +static char * control_line(char *s, struct lesskey_tables *tables) +{ +#define PREFIX(str,pat) (strncmp(str,pat,strlen(pat)) == 0) + + if (PREFIX(s, "#line-edit")) + { + tables->currtable = &tables->edittable; + return (NULL); + } + if (PREFIX(s, "#command")) + { + tables->currtable = &tables->cmdtable; + return (NULL); + } + if (PREFIX(s, "#env")) + { + tables->currtable = &tables->vartable; + return (NULL); + } + if (PREFIX(s, "#stop")) + { + add_cmd_char('\0', tables); + add_cmd_char(A_END_LIST, tables); + return (NULL); + } + if (PREFIX(s, "#version")) + { + return (version_line(s, tables)); + } + return (s); +} + +/* + * Find an action, given the name of the action. + */ +static int findaction(char *actname, struct lesskey_tables *tables) +{ + int i; + + for (i = 0; tables->currtable->names[i].cn_name != NULL; i++) + if (strcmp(tables->currtable->names[i].cn_name, actname) == 0) + return (tables->currtable->names[i].cn_action); + parse_error("unknown action: \"%s\"", actname); + return (A_INVALID); +} + +/* + * Parse a line describing one key binding, of the form + * KEY ACTION [EXTRA] + * where KEY is the user key sequence, ACTION is the + * resulting less action, and EXTRA is an "extra" user + * key sequence injected after the action. + */ +static void parse_cmdline(char *p, struct lesskey_tables *tables) +{ + char *actname; + int action; + char *s; + char c; + + /* + * Parse the command string and store it in the current table. + */ + do + { + s = tstr(&p, 1); + add_cmd_str(s, tables); + } while (*p != '\0' && !issp(*p)); + /* + * Terminate the command string with a null byte. + */ + add_cmd_char('\0', tables); + + /* + * Skip white space between the command string + * and the action name. + * Terminate the action name with a null byte. + */ + p = skipsp(p); + if (*p == '\0') + { + parse_error("missing action", ""); + return; + } + actname = p; + p = skipnsp(p); + c = *p; + *p = '\0'; + + /* + * Parse the action name and store it in the current table. + */ + action = findaction(actname, tables); + + /* + * See if an extra string follows the action name. + */ + *p = c; + p = skipsp(p); + if (*p == '\0') + { + add_cmd_char((unsigned char) action, tables); + } else + { + /* + * OR the special value A_EXTRA into the action byte. + * Put the extra string after the action byte. + */ + add_cmd_char((unsigned char) (action | A_EXTRA), tables); + while (*p != '\0') + add_cmd_str(tstr(&p, 0), tables); + add_cmd_char('\0', tables); + } +} + +/* + * Parse a variable definition line, of the form + * NAME = VALUE + */ +static void parse_varline(char *line, struct lesskey_tables *tables) +{ + char *s; + char *p = line; + char *eq; + + eq = strchr(line, '='); + if (eq != NULL && eq > line && eq[-1] == '+') + { + /* + * Rather ugly way of handling a += line. + * {{ Note that we ignore the variable name and + * just append to the previously defined variable. }} + */ + erase_cmd_char(tables); /* backspace over the final null */ + p = eq+1; + } else + { + do + { + s = tstr(&p, 0); + add_cmd_str(s, tables); + } while (*p != '\0' && !issp(*p) && *p != '='); + /* + * Terminate the variable name with a null byte. + */ + add_cmd_char('\0', tables); + p = skipsp(p); + if (*p++ != '=') + { + parse_error("missing = in variable definition", ""); + return; + } + add_cmd_char(EV_OK|A_EXTRA, tables); + } + p = skipsp(p); + while (*p != '\0') + { + s = tstr(&p, 0); + add_cmd_str(s, tables); + } + add_cmd_char('\0', tables); +} + +/* + * Parse a line from the lesskey file. + */ +static void parse_line(char *line, struct lesskey_tables *tables) +{ + char *p; + + /* + * See if it is a control line. + */ + p = control_line(line, tables); + if (p == NULL) + return; + /* + * Skip leading white space. + * Replace the final newline with a null byte. + * Ignore blank lines and comments. + */ + p = clean_line(p); + if (*p == '\0') + return; + + if (tables->currtable->is_var) + parse_varline(p, tables); + else + parse_cmdline(p, tables); +} + +/* + * Parse a lesskey source file and store result in tables. + */ +int parse_lesskey(char *infile, struct lesskey_tables *tables) +{ + FILE *desc; + char line[1024]; + + if (infile == NULL) + infile = homefile(DEF_LESSKEYINFILE); + lesskey_file = infile; + + init_tables(tables); + errors = 0; + linenum = 0; + if (less_version == 0) + less_version = lstrtoi(version, NULL, 10); + + /* + * Open the input file. + */ + if (strcmp(infile, "-") == 0) + desc = stdin; + else if ((desc = fopen(infile, "r")) == NULL) + { + /* parse_error("cannot open lesskey file %s", infile); */ + return (-1); + } + + /* + * Read and parse the input file, one line at a time. + */ + while (fgets(line, sizeof(line), desc) != NULL) + { + ++linenum; + parse_line(line, tables); + } + fclose(desc); + return (errors); +} diff --git a/third_party/less/lglob.h b/third_party/less/lglob.h new file mode 100644 index 000000000..45597945f --- /dev/null +++ b/third_party/less/lglob.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * Macros to define the method of doing filename "globbing". + * There are three possible mechanisms: + * 1. GLOB_LIST + * This defines a function that returns a list of matching filenames. + * 2. GLOB_NAME + * This defines a function that steps thru the list of matching + * filenames, returning one name each time it is called. + * 3. GLOB_STRING + * This defines a function that returns the complete list of + * matching filenames as a single space-separated string. + */ + +#if OS2 + +#define DECL_GLOB_LIST(list) char **list; char **pp; +#define GLOB_LIST(filename,list) list = _fnexplode(filename) +#define GLOB_LIST_FAILED(list) list == NULL +#define SCAN_GLOB_LIST(list,p) pp = list; *pp != NULL; pp++ +#define INIT_GLOB_LIST(list,p) p = *pp +#define GLOB_LIST_DONE(list) _fnexplodefree(list) + +#else +#if MSDOS_COMPILER==DJGPPC + +#define DECL_GLOB_LIST(list) glob_t list; int i; +#define GLOB_LIST(filename,list) glob(filename,GLOB_NOCHECK,0,&list) +#define GLOB_LIST_FAILED(list) 0 +#define SCAN_GLOB_LIST(list,p) i = 0; i < list.gl_pathc; i++ +#define INIT_GLOB_LIST(list,p) p = list.gl_pathv[i] +#define GLOB_LIST_DONE(list) globfree(&list) + +#else +#if MSDOS_COMPILER==MSOFTC || MSDOS_COMPILER==BORLANDC + +#define GLOB_FIRST_NAME(filename,fndp,h) h = _dos_findfirst(filename, ~_A_VOLID, fndp) +#define GLOB_FIRST_FAILED(handle) ((handle) != 0) +#define GLOB_NEXT_NAME(handle,fndp) _dos_findnext(fndp) +#define GLOB_NAME_DONE(handle) +#define GLOB_NAME name +#define DECL_GLOB_NAME(fnd,drive,dir,fname,ext,handle) \ + struct find_t fnd; \ + char drive[_MAX_DRIVE]; \ + char dir[_MAX_DIR]; \ + char fname[_MAX_FNAME]; \ + char ext[_MAX_EXT]; \ + int handle; +#else +#if MSDOS_COMPILER==WIN32C && (defined(_MSC_VER) || defined(MINGW)) + +#define GLOB_FIRST_NAME(filename,fndp,h) h = _findfirst(filename, fndp) +#define GLOB_FIRST_FAILED(handle) ((handle) == -1) +#define GLOB_NEXT_NAME(handle,fndp) _findnext(handle, fndp) +#define GLOB_NAME_DONE(handle) _findclose(handle) +#define GLOB_NAME name +#define DECL_GLOB_NAME(fnd,drive,dir,fname,ext,handle) \ + struct _finddata_t fnd; \ + char drive[_MAX_DRIVE]; \ + char dir[_MAX_DIR]; \ + char fname[_MAX_FNAME]; \ + char ext[_MAX_EXT]; \ + intptr_t handle; + +#else +#if MSDOS_COMPILER==WIN32C && !defined(_MSC_VER) /* Borland C for Windows */ + +#define GLOB_FIRST_NAME(filename,fndp,h) h = findfirst(filename, fndp, ~FA_LABEL) +#define GLOB_FIRST_FAILED(handle) ((handle) != 0) +#define GLOB_NEXT_NAME(handle,fndp) findnext(fndp) +#define GLOB_NAME_DONE(handle) +#define GLOB_NAME ff_name +#define DECL_GLOB_NAME(fnd,drive,dir,fname,ext,handle) \ + struct ffblk fnd; \ + char drive[MAXDRIVE]; \ + char dir[MAXDIR]; \ + char fname[MAXFILE]; \ + char ext[MAXEXT]; \ + int handle; + +#endif +#endif +#endif +#endif +#endif diff --git a/third_party/less/line.c b/third_party/less/line.c new file mode 100644 index 000000000..6c463068a --- /dev/null +++ b/third_party/less/line.c @@ -0,0 +1,1593 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + +/* + * 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. + */ + +#include "less.h" +#include "charset.h" +#include "position.h" + +#if MSDOS_COMPILER==WIN32C +#define WIN32_LEAN_AND_MEAN +/* #include */ +#endif + +#define MAX_PFX_WIDTH (MAX_LINENUM_WIDTH + MAX_STATUSCOL_WIDTH + 1) +static struct { + char *buf; /* Buffer which holds the current output line */ + int *attr; /* Parallel to buf, to hold attributes */ + int print; /* Index in buf of first printable char */ + int end; /* Number of chars in buf */ + char pfx[MAX_PFX_WIDTH]; /* Holds status column and line number */ + int pfx_attr[MAX_PFX_WIDTH]; + int pfx_end; /* Number of chars in pfx */ +} linebuf; + +/* + * Buffer of ansi sequences which have been shifted off the left edge + * of the screen. + */ +static struct xbuffer shifted_ansi; + +/* + * Ring buffer of last ansi sequences sent. + * While sending a line, these will be resent at the end + * of any highlighted string, to restore text modes. + * {{ Not ideal, since we don't really know how many to resend. }} + */ +#define NUM_LAST_ANSIS 3 +static struct xbuffer last_ansi; +static struct xbuffer last_ansis[NUM_LAST_ANSIS]; +static int curr_last_ansi; + +public int size_linebuf = 0; /* Size of line buffer (and attr buffer) */ +static struct ansi_state *line_ansi = NULL; +static int ansi_in_line; +static int hlink_in_line; +static int line_mark_attr; +static int cshift; /* Current left-shift of output line buffer */ +public int hshift; /* Desired left-shift of output line buffer */ +public int tabstops[TABSTOP_MAX] = { 0 }; /* Custom tabstops */ +public int ntabstops = 1; /* Number of tabstops */ +public int tabdefault = 8; /* Default repeated tabstops */ +public POSITION highest_hilite; /* Pos of last hilite in file found so far */ +static POSITION line_pos; + +static int end_column; /* Printable length, accounting for backspaces, etc. */ +static int right_curr; +static int right_column; +static int overstrike; /* Next char should overstrike previous char */ +static int last_overstrike = AT_NORMAL; +static int is_null_line; /* There is no current line */ +static LWCHAR pendc; +static POSITION pendpos; +static char *end_ansi_chars; +static char *mid_ansi_chars; +static int in_hilite; + +static int attr_swidth(int a); +static int attr_ewidth(int a); +static int do_append(LWCHAR ch, char *rep, POSITION pos); + +extern int sigs; +extern int bs_mode; +extern int proc_backspace; +extern int proc_tab; +extern int proc_return; +extern int linenums; +extern int ctldisp; +extern int twiddle; +extern int binattr; +extern int status_col; +extern int status_col_width; +extern int linenum_width; +extern int auto_wrap, ignaw; +extern int bo_s_width, bo_e_width; +extern int ul_s_width, ul_e_width; +extern int bl_s_width, bl_e_width; +extern int so_s_width, so_e_width; +extern int sc_width, sc_height; +extern int utf_mode; +extern POSITION start_attnpos; +extern POSITION end_attnpos; +extern char rscroll_char; +extern int rscroll_attr; +extern int use_color; +extern int status_line; + +static char mbc_buf[MAX_UTF_CHAR_LEN]; +static int mbc_buf_len = 0; +static int mbc_buf_index = 0; +static POSITION mbc_pos; +static int saved_line_end; +static int saved_end_column; + +/* Configurable color map */ +struct color_map { int attr; char color[12]; }; +static struct color_map color_map[] = { + { AT_UNDERLINE, "" }, + { AT_BOLD, "" }, + { AT_BLINK, "" }, + { AT_STANDOUT, "" }, + { AT_COLOR_ATTN, "Wm" }, + { AT_COLOR_BIN, "kR" }, + { AT_COLOR_CTRL, "kR" }, + { AT_COLOR_ERROR, "kY" }, + { AT_COLOR_LINENUM, "c" }, + { AT_COLOR_MARK, "Wb" }, + { AT_COLOR_PROMPT, "kC" }, + { AT_COLOR_RSCROLL, "kc" }, + { AT_COLOR_HEADER, "" }, + { AT_COLOR_SEARCH, "kG" }, + { AT_COLOR_SUBSEARCH(1), "ky" }, + { AT_COLOR_SUBSEARCH(2), "wb" }, + { AT_COLOR_SUBSEARCH(3), "YM" }, + { AT_COLOR_SUBSEARCH(4), "Yr" }, + { AT_COLOR_SUBSEARCH(5), "Wc" }, +}; + +/* State while processing an ANSI escape sequence */ +struct ansi_state { + int hindex; /* Index into hyperlink prefix */ + int hlink; /* Processing hyperlink address? */ + int prev_esc; /* Prev char was ESC (to detect ESC-\ seq) */ +}; + +/* + * Initialize from environment variables. + */ +public void init_line(void) +{ + int ax; + + end_ansi_chars = lgetenv("LESSANSIENDCHARS"); + if (isnullenv(end_ansi_chars)) + end_ansi_chars = "m"; + + mid_ansi_chars = lgetenv("LESSANSIMIDCHARS"); + if (isnullenv(mid_ansi_chars)) + mid_ansi_chars = "0123456789:;[?!\"'#%()*+ "; + + linebuf.buf = (char *) ecalloc(LINEBUF_SIZE, sizeof(char)); + linebuf.attr = (int *) ecalloc(LINEBUF_SIZE, sizeof(int)); + size_linebuf = LINEBUF_SIZE; + xbuf_init(&shifted_ansi); + xbuf_init(&last_ansi); + for (ax = 0; ax < NUM_LAST_ANSIS; ax++) + xbuf_init(&last_ansis[ax]); + curr_last_ansi = 0; +} + +/* + * Expand the line buffer. + */ +static int expand_linebuf(void) +{ + /* Double the size of the line buffer. */ + int new_size = size_linebuf * 2; + char *new_buf = (char *) calloc(new_size, sizeof(char)); + int *new_attr = (int *) calloc(new_size, sizeof(int)); + if (new_buf == NULL || new_attr == NULL) + { + if (new_attr != NULL) + free(new_attr); + if (new_buf != NULL) + free(new_buf); + return 1; + } + /* + * We just calloc'd the buffers; copy the old contents. + */ + memcpy(new_buf, linebuf.buf, size_linebuf * sizeof(char)); + memcpy(new_attr, linebuf.attr, size_linebuf * sizeof(int)); + free(linebuf.attr); + free(linebuf.buf); + linebuf.buf = new_buf; + linebuf.attr = new_attr; + size_linebuf = new_size; + return 0; +} + +/* + * Is a character ASCII? + */ +public int is_ascii_char(LWCHAR ch) +{ + return (ch <= 0x7F); +} + +/* + */ +static void inc_end_column(int w) +{ + if (end_column > right_column && w > 0) + { + right_column = end_column; + right_curr = linebuf.end; + } + end_column += w; +} + +public POSITION line_position(void) +{ + return line_pos; +} + +/* + * Rewind the line buffer. + */ +public void prewind(void) +{ + int ax; + + linebuf.print = 6; /* big enough for longest UTF-8 sequence */ + linebuf.pfx_end = 0; + for (linebuf.end = 0; linebuf.end < linebuf.print; linebuf.end++) + { + linebuf.buf[linebuf.end] = '\0'; + linebuf.attr[linebuf.end] = 0; + } + + end_column = 0; + right_curr = 0; + right_column = 0; + cshift = 0; + overstrike = 0; + last_overstrike = AT_NORMAL; + mbc_buf_len = 0; + is_null_line = 0; + pendc = '\0'; + in_hilite = 0; + ansi_in_line = 0; + hlink_in_line = 0; + line_mark_attr = 0; + line_pos = NULL_POSITION; + xbuf_reset(&shifted_ansi); + xbuf_reset(&last_ansi); + for (ax = 0; ax < NUM_LAST_ANSIS; ax++) + xbuf_reset(&last_ansis[ax]); + curr_last_ansi = 0; +} + +/* + * Set a character in the line buffer. + */ +static void set_linebuf(int n, char ch, int attr) +{ + if (n >= size_linebuf) + { + /* + * Won't fit in line buffer. + * Try to expand it. + */ + if (expand_linebuf()) + return; + } + linebuf.buf[n] = ch; + linebuf.attr[n] = attr; +} + +/* + * Append a character to the line buffer. + */ +static void add_linebuf(char ch, int attr, int w) +{ + set_linebuf(linebuf.end++, ch, attr); + inc_end_column(w); +} + +/* + * Append a string to the line buffer. + */ +static void addstr_linebuf(char *s, int attr, int cw) +{ + for ( ; *s != '\0'; s++) + add_linebuf(*s, attr, cw); +} + +/* + * Set a character in the line prefix buffer. + */ +static void set_pfx(int n, char ch, int attr) +{ + linebuf.pfx[n] = ch; + linebuf.pfx_attr[n] = attr; +} + +/* + * Append a character to the line prefix buffer. + */ +static void add_pfx(char ch, int attr) +{ + set_pfx(linebuf.pfx_end++, ch, attr); +} + +/* + * Insert the status column and line number into the line buffer. + */ +public void plinestart(POSITION pos) +{ + LINENUM linenum = 0; + int i; + + if (linenums == OPT_ONPLUS) + { + /* + * Get the line number and put it in the current line. + * {{ Note: since find_linenum calls forw_raw_line, + * it may seek in the input file, requiring the caller + * of plinestart to re-seek if necessary. }} + * {{ Since forw_raw_line modifies linebuf, we must + * do this first, before storing anything in linebuf. }} + */ + linenum = find_linenum(pos); + } + + /* + * Display a status column if the -J option is set. + */ + if (status_col || status_line) + { + char c = posmark(pos); + if (c != 0) + line_mark_attr = AT_HILITE|AT_COLOR_MARK; + else if (start_attnpos != NULL_POSITION && + pos >= start_attnpos && pos <= end_attnpos) + line_mark_attr = AT_HILITE|AT_COLOR_ATTN; + if (status_col) + { + add_pfx(c ? c : ' ', line_mark_attr); /* column 0: status */ + while (linebuf.pfx_end < status_col_width) + add_pfx(' ', AT_NORMAL); + } + } + + /* + * Display the line number at the start of each line + * if the -N option is set. + */ + if (linenums == OPT_ONPLUS) + { + char buf[INT_STRLEN_BOUND(linenum) + 2]; + int len; + + linenum = vlinenum(linenum); + if (linenum == 0) + len = 0; + else + { + linenumtoa(linenum, buf, 10); + len = (int) strlen(buf); + } + for (i = 0; i < linenum_width - len; i++) + add_pfx(' ', AT_NORMAL); + for (i = 0; i < len; i++) + add_pfx(buf[i], AT_BOLD|AT_COLOR_LINENUM); + add_pfx(' ', AT_NORMAL); + } + end_column = linebuf.pfx_end; +} + +/* + * Return the width of the line prefix (status column and line number). + * {{ Actual line number can be wider than linenum_width. }} + */ +public int line_pfx_width(void) +{ + int width = 0; + if (status_col) + width += status_col_width; + if (linenums == OPT_ONPLUS) + width += linenum_width + 1; + return width; +} + +/* + * Shift line left so that the last char is just to the left + * of the first visible column. + */ +public void pshift_all(void) +{ + int i; + for (i = linebuf.print; i < linebuf.end; i++) + if (linebuf.attr[i] == AT_ANSI) + xbuf_add_byte(&shifted_ansi, (unsigned char) linebuf.buf[i]); + linebuf.end = linebuf.print; + end_column = linebuf.pfx_end; +} + +/* + * Return the printing width of the start (enter) sequence + * for a given character attribute. + */ +static int attr_swidth(int a) +{ + int w = 0; + + a = apply_at_specials(a); + + if (a & AT_UNDERLINE) + w += ul_s_width; + if (a & AT_BOLD) + w += bo_s_width; + if (a & AT_BLINK) + w += bl_s_width; + if (a & AT_STANDOUT) + w += so_s_width; + + return w; +} + +/* + * Return the printing width of the end (exit) sequence + * for a given character attribute. + */ +static int attr_ewidth(int a) +{ + int w = 0; + + a = apply_at_specials(a); + + if (a & AT_UNDERLINE) + w += ul_e_width; + if (a & AT_BOLD) + w += bo_e_width; + if (a & AT_BLINK) + w += bl_e_width; + if (a & AT_STANDOUT) + w += so_e_width; + + return w; +} + +/* + * Return the printing width of a given character and attribute, + * if the character were added after prev_ch. + * Adding a character with a given attribute may cause an enter or exit + * attribute sequence to be inserted, so this must be taken into account. + */ +public int pwidth(LWCHAR ch, int a, LWCHAR prev_ch, int prev_a) +{ + int w; + + if (ch == '\b') + { + /* + * Backspace moves backwards one or two positions. + */ + if (prev_a & (AT_ANSI|AT_BINARY)) + return strlen(prchar('\b')); + return (utf_mode && is_wide_char(prev_ch)) ? -2 : -1; + } + + if (!utf_mode || is_ascii_char(ch)) + { + if (control_char((char)ch)) + { + /* + * Control characters do unpredictable things, + * so we don't even try to guess; say it doesn't move. + * This can only happen if the -r flag is in effect. + */ + return (0); + } + } else + { + if (is_composing_char(ch) || is_combining_char(prev_ch, ch)) + { + /* + * Composing and combining chars take up no space. + * + * Some terminals, upon failure to compose a + * composing character with the character(s) that + * precede(s) it will actually take up one end_column + * for the composing character; there isn't much + * we could do short of testing the (complex) + * composition process ourselves and printing + * a binary representation when it fails. + */ + return (0); + } + } + + /* + * Other characters take one or two columns, + * plus the width of any attribute enter/exit sequence. + */ + w = 1; + if (is_wide_char(ch)) + w++; + if (linebuf.end > 0 && !is_at_equiv(linebuf.attr[linebuf.end-1], a)) + w += attr_ewidth(linebuf.attr[linebuf.end-1]); + if (apply_at_specials(a) != AT_NORMAL && + (linebuf.end == 0 || !is_at_equiv(linebuf.attr[linebuf.end-1], a))) + w += attr_swidth(a); + return (w); +} + +/* + * Delete to the previous base character in the line buffer. + */ +static int backc(void) +{ + LWCHAR ch; + char *p; + + if (linebuf.end == 0) + return (0); + p = &linebuf.buf[linebuf.end]; + ch = step_char(&p, -1, linebuf.buf); + /* Skip back to the next nonzero-width char. */ + while (p > linebuf.buf) + { + LWCHAR prev_ch; + int width; + linebuf.end = (int) (p - linebuf.buf); + prev_ch = step_char(&p, -1, linebuf.buf); + width = pwidth(ch, linebuf.attr[linebuf.end], prev_ch, linebuf.attr[linebuf.end-1]); + end_column -= width; + /* {{ right_column? }} */ + if (width > 0) + break; + ch = prev_ch; + } + return (1); +} + +/* + * Preserve the current position in the line buffer (for word wrapping). + */ +public void savec(void) +{ + saved_line_end = linebuf.end; + saved_end_column = end_column; +} + +/* + * Restore the position in the line buffer (start of line for word wrapping). + */ +public void loadc(void) +{ + linebuf.end = saved_line_end; + end_column = saved_end_column; +} + +/* + * Is a character the end of an ANSI escape sequence? + */ +public int is_ansi_end(LWCHAR ch) +{ + if (!is_ascii_char(ch)) + return (0); + return (strchr(end_ansi_chars, (char) ch) != NULL); +} + +/* + * Can a char appear in an ANSI escape sequence, before the end char? + */ +public int is_ansi_middle(LWCHAR ch) +{ + if (!is_ascii_char(ch)) + return (0); + if (is_ansi_end(ch)) + return (0); + return (strchr(mid_ansi_chars, (char) ch) != NULL); +} + +/* + * Skip past an ANSI escape sequence. + * pp is initially positioned just after the CSI_START char. + */ +public void skip_ansi(struct ansi_state *pansi, char **pp, constant char *limit) +{ + LWCHAR c; + do { + c = step_char(pp, +1, limit); + } while (*pp < limit && ansi_step(pansi, c) == ANSI_MID); + /* Note that we discard final char, for which is_ansi_end is true. */ +} + +/* + * Determine if a character starts an ANSI escape sequence. + * If so, return an ansi_state struct; otherwise return NULL. + */ +public struct ansi_state * ansi_start(LWCHAR ch) +{ + struct ansi_state *pansi; + + if (!IS_CSI_START(ch)) + return NULL; + pansi = ecalloc(1, sizeof(struct ansi_state)); + pansi->hindex = 0; + pansi->hlink = 0; + pansi->prev_esc = 0; + return pansi; +} + +/* + * Determine whether the next char in an ANSI escape sequence + * ends the sequence. + */ +public int ansi_step(struct ansi_state *pansi, LWCHAR ch) +{ + if (pansi->hlink) + { + /* Hyperlink ends with \7 or ESC-backslash. */ + if (ch == '\7') + return ANSI_END; + if (pansi->prev_esc) + return (ch == '\\') ? ANSI_END : ANSI_ERR; + pansi->prev_esc = (ch == ESC); + return ANSI_MID; + } + if (pansi->hindex >= 0) + { + static char hlink_prefix[] = ESCS "]8;"; + if (ch == hlink_prefix[pansi->hindex] || + (pansi->hindex == 0 && IS_CSI_START(ch))) + { + pansi->hindex++; + if (hlink_prefix[pansi->hindex] == '\0') + pansi->hlink = 1; /* now processing hyperlink addr */ + return ANSI_MID; + } + pansi->hindex = -1; /* not a hyperlink */ + } + /* Check for SGR sequences */ + if (is_ansi_middle(ch)) + return ANSI_MID; + if (is_ansi_end(ch)) + return ANSI_END; + return ANSI_ERR; +} + +/* + * Free an ansi_state structure. + */ +public void ansi_done(struct ansi_state *pansi) +{ + free(pansi); +} + +/* + * Will w characters in attribute a fit on the screen? + */ +static int fits_on_screen(int w, int a) +{ + if (ctldisp == OPT_ON) + /* We're not counting, so say that everything fits. */ + return 1; + return (end_column - cshift + w + attr_ewidth(a) <= sc_width); +} + +/* + * Append a character and attribute to the line buffer. + */ +#define STORE_CHAR(ch,a,rep,pos) \ + do { \ + if (store_char((ch),(a),(rep),(pos))) return (1); \ + } while (0) + +static int store_char(LWCHAR ch, int a, char *rep, POSITION pos) +{ + int w; + int i; + int replen; + char cs; + + i = (a & (AT_UNDERLINE|AT_BOLD)); + if (i != AT_NORMAL) + last_overstrike = i; + +#if HILITE_SEARCH + { + int matches; + int resend_last = 0; + int hl_attr = 0; + + if (pos == NULL_POSITION) + { + /* Color the prompt unless it has ansi sequences in it. */ + hl_attr = ansi_in_line ? 0 : AT_STANDOUT|AT_COLOR_PROMPT; + } else if (a != AT_ANSI) + { + hl_attr = is_hilited_attr(pos, pos+1, 0, &matches); + if (hl_attr == 0 && status_line) + hl_attr = line_mark_attr; + } + if (hl_attr) + { + /* + * This character should be highlighted. + * Override the attribute passed in. + */ + a |= hl_attr; + if (highest_hilite != NULL_POSITION && pos != NULL_POSITION && pos > highest_hilite) + highest_hilite = pos; + in_hilite = 1; + } else + { + if (in_hilite) + { + /* + * This is the first non-hilited char after a hilite. + * Resend the last ANSI seq to restore color. + */ + resend_last = 1; + } + in_hilite = 0; + } + if (resend_last) + { + int ai; + for (ai = 0; ai < NUM_LAST_ANSIS; ai++) + { + int ax = (curr_last_ansi + ai) % NUM_LAST_ANSIS; + for (i = 0; i < last_ansis[ax].end; i++) + STORE_CHAR(last_ansis[ax].data[i], AT_ANSI, NULL, pos); + } + } + } +#endif + + if (a == AT_ANSI) { + w = 0; + } else { + char *p = &linebuf.buf[linebuf.end]; + LWCHAR prev_ch = (linebuf.end > 0) ? step_char(&p, -1, linebuf.buf) : 0; + int prev_a = (linebuf.end > 0) ? linebuf.attr[linebuf.end-1] : 0; + w = pwidth(ch, a, prev_ch, prev_a); + } + + if (!fits_on_screen(w, a)) + return (1); + + if (rep == NULL) + { + cs = (char) ch; + rep = &cs; + replen = 1; + } else + { + replen = utf_len(rep[0]); + } + + if (cshift == hshift) + { + if (line_pos == NULL_POSITION) + line_pos = pos; + if (shifted_ansi.end > 0) + { + /* Copy shifted ANSI sequences to beginning of line. */ + for (i = 0; i < shifted_ansi.end; i++) + add_linebuf(shifted_ansi.data[i], AT_ANSI, 0); + xbuf_reset(&shifted_ansi); + } + } + + /* Add the char to the buf, even if we will left-shift it next. */ + inc_end_column(w); + for (i = 0; i < replen; i++) + add_linebuf(*rep++, a, 0); + + if (cshift < hshift) + { + /* We haven't left-shifted enough yet. */ + if (a == AT_ANSI) + xbuf_add_byte(&shifted_ansi, (unsigned char) ch); /* Save ANSI attributes */ + if (linebuf.end > linebuf.print) + { + /* Shift left enough to put last byte of this char at print-1. */ + int i; + for (i = 0; i < linebuf.print; i++) + { + linebuf.buf[i] = linebuf.buf[i+replen]; + linebuf.attr[i] = linebuf.attr[i+replen]; + } + linebuf.end -= replen; + cshift += w; + /* + * If the char we just left-shifted was double width, + * the 2 spaces we shifted may be too much. + * Represent the "half char" at start of line with a highlighted space. + */ + while (cshift > hshift) + { + add_linebuf(' ', rscroll_attr, 0); + cshift--; + } + } + } + return (0); +} + +#define STORE_STRING(s,a,pos) \ + do { if (store_string((s),(a),(pos))) return (1); } while (0) + +static int store_string(char *s, int a, POSITION pos) +{ + if (!fits_on_screen(strlen(s), a)) + return 1; + for ( ; *s != 0; s++) + STORE_CHAR(*s, a, NULL, pos); + return 0; +} + +/* + * Append a tab to the line buffer. + * Store spaces to represent the tab. + */ +#define STORE_TAB(a,pos) \ + do { if (store_tab((a),(pos))) return (1); } while (0) + +static int store_tab(int attr, POSITION pos) +{ + int to_tab = end_column - linebuf.pfx_end; + + if (ntabstops < 2 || to_tab >= tabstops[ntabstops-1]) + to_tab = tabdefault - + ((to_tab - tabstops[ntabstops-1]) % tabdefault); + else + { + int i; + for (i = ntabstops - 2; i >= 0; i--) + if (to_tab >= tabstops[i]) + break; + to_tab = tabstops[i+1] - to_tab; + } + + do { + STORE_CHAR(' ', attr, " ", pos); + } while (--to_tab > 0); + return 0; +} + +#define STORE_PRCHAR(c, pos) \ + do { if (store_prchar((c), (pos))) return 1; } while (0) + +static int store_prchar(LWCHAR c, POSITION pos) +{ + /* + * Convert to printable representation. + */ + STORE_STRING(prchar(c), AT_BINARY|AT_COLOR_CTRL, pos); + return 0; +} + +static int flush_mbc_buf(POSITION pos) +{ + int i; + + for (i = 0; i < mbc_buf_index; i++) + if (store_prchar(mbc_buf[i], pos)) + return mbc_buf_index - i; + return 0; +} + +/* + * 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. + */ +public int pappend(int c, POSITION pos) +{ + int r; + + if (pendc) + { + if (c == '\r' && pendc == '\r') + return (0); + if (do_append(pendc, NULL, pendpos)) + /* + * Oops. We've probably lost the char which + * was in pendc, since caller won't back up. + */ + return (1); + pendc = '\0'; + } + + if (c == '\r' && (proc_return == OPT_ON || (bs_mode == BS_SPECIAL && proc_return == OPT_OFF))) + { + if (mbc_buf_len > 0) /* utf_mode must be on. */ + { + /* Flush incomplete (truncated) sequence. */ + r = flush_mbc_buf(mbc_pos); + mbc_buf_index = r + 1; + mbc_buf_len = 0; + if (r) + return (mbc_buf_index); + } + + /* + * Don't put the CR into the buffer until we see + * the next char. If the next char is a newline, + * discard the CR. + */ + pendc = c; + pendpos = pos; + return (0); + } + + if (!utf_mode) + { + r = do_append(c, NULL, pos); + } else + { + /* Perform strict validation in all possible cases. */ + if (mbc_buf_len == 0) + { + retry: + mbc_buf_index = 1; + *mbc_buf = c; + if (IS_ASCII_OCTET(c)) + r = do_append(c, NULL, pos); + else if (IS_UTF8_LEAD(c)) + { + mbc_buf_len = utf_len(c); + mbc_pos = pos; + return (0); + } else + /* UTF8_INVALID or stray UTF8_TRAIL */ + r = flush_mbc_buf(pos); + } else if (IS_UTF8_TRAIL(c)) + { + mbc_buf[mbc_buf_index++] = c; + if (mbc_buf_index < mbc_buf_len) + return (0); + if (is_utf8_well_formed(mbc_buf, mbc_buf_index)) + r = do_append(get_wchar(mbc_buf), mbc_buf, mbc_pos); + else + /* Complete, but not shortest form, sequence. */ + mbc_buf_index = r = flush_mbc_buf(mbc_pos); + mbc_buf_len = 0; + } else + { + /* Flush incomplete (truncated) sequence. */ + r = flush_mbc_buf(mbc_pos); + mbc_buf_index = r + 1; + mbc_buf_len = 0; + /* Handle new char. */ + if (!r) + goto retry; + } + } + if (r) + { + /* How many chars should caller back up? */ + r = (!utf_mode) ? 1 : mbc_buf_index; + } + return (r); +} + +static int store_control_char(LWCHAR ch, char *rep, POSITION pos) +{ + if (ctldisp == OPT_ON) + { + /* Output the character itself. */ + STORE_CHAR(ch, AT_NORMAL, rep, pos); + } else + { + /* Output a printable representation of the character. */ + STORE_PRCHAR((char) ch, pos); + } + return (0); +} + +static int store_ansi(LWCHAR ch, char *rep, POSITION pos) +{ + switch (ansi_step(line_ansi, ch)) + { + case ANSI_MID: + STORE_CHAR(ch, AT_ANSI, rep, pos); + if (line_ansi->hlink) + hlink_in_line = 1; + xbuf_add_byte(&last_ansi, (unsigned char) ch); + break; + case ANSI_END: + STORE_CHAR(ch, AT_ANSI, rep, pos); + ansi_done(line_ansi); + line_ansi = NULL; + xbuf_add_byte(&last_ansi, (unsigned char) ch); + xbuf_set(&last_ansis[curr_last_ansi], &last_ansi); + xbuf_reset(&last_ansi); + curr_last_ansi = (curr_last_ansi + 1) % NUM_LAST_ANSIS; + break; + case ANSI_ERR: + { + /* Remove whole unrecognized sequence. */ + char *start = (cshift < hshift) ? xbuf_char_data(&shifted_ansi): linebuf.buf; + int *end = (cshift < hshift) ? &shifted_ansi.end : &linebuf.end; + char *p = start + *end; + LWCHAR bch; + do { + bch = step_char(&p, -1, start); + } while (p > start && !IS_CSI_START(bch)); + *end = (int) (p - start); + } + xbuf_reset(&last_ansi); + ansi_done(line_ansi); + line_ansi = NULL; + break; + } + return (0); +} + +static int store_bs(LWCHAR ch, char *rep, POSITION pos) +{ + if (proc_backspace == OPT_ONPLUS || (bs_mode == BS_CONTROL && proc_backspace == OPT_OFF)) + return store_control_char(ch, rep, pos); + if (linebuf.end > 0 && + ((linebuf.end <= linebuf.print && linebuf.buf[linebuf.end-1] == '\0') || + (linebuf.end > 0 && linebuf.attr[linebuf.end - 1] & (AT_ANSI|AT_BINARY)))) + STORE_PRCHAR('\b', pos); + else if (proc_backspace == OPT_OFF && bs_mode == BS_NORMAL) + STORE_CHAR(ch, AT_NORMAL, NULL, pos); + else if (proc_backspace == OPT_ON || (bs_mode == BS_SPECIAL && proc_backspace == OPT_OFF)) + overstrike = backc(); + return 0; +} + +static int do_append(LWCHAR ch, char *rep, POSITION pos) +{ + int a = AT_NORMAL; + int in_overstrike = overstrike; + + if (ctldisp == OPT_ONPLUS && line_ansi == NULL) + { + line_ansi = ansi_start(ch); + if (line_ansi != NULL) + ansi_in_line = 1; + } + + overstrike = 0; + if (line_ansi != NULL) + return store_ansi(ch, rep, pos); + + if (ch == '\b') + return store_bs(ch, rep, pos); + + if (in_overstrike > 0) + { + /* + * Overstrike the character at the current position + * in the line buffer. This will cause either + * underline (if a "_" is overstruck), + * bold (if an identical character is overstruck), + * or just replacing the character in the buffer. + */ + LWCHAR prev_ch; + overstrike = utf_mode ? -1 : 0; + if (utf_mode) + { + /* To be correct, this must be a base character. */ + prev_ch = get_wchar(&linebuf.buf[linebuf.end]); + } else + { + prev_ch = (unsigned char) linebuf.buf[linebuf.end]; + } + a = linebuf.attr[linebuf.end]; + if (ch == prev_ch) + { + /* + * Overstriking a char with itself means make it bold. + * But overstriking an underscore with itself is + * ambiguous. It could mean make it bold, or + * it could mean make it underlined. + * Use the previous overstrike to resolve it. + */ + if (ch == '_') + { + if ((a & (AT_BOLD|AT_UNDERLINE)) != AT_NORMAL) + a |= (AT_BOLD|AT_UNDERLINE); + else if (last_overstrike != AT_NORMAL) + a |= last_overstrike; + else + a |= AT_BOLD; + } else + a |= AT_BOLD; + } else if (ch == '_') + { + a |= AT_UNDERLINE; + ch = prev_ch; + rep = &linebuf.buf[linebuf.end]; + } else if (prev_ch == '_') + { + a |= AT_UNDERLINE; + } + /* Else we replace prev_ch, but we keep its attributes. */ + } else if (in_overstrike < 0) + { + if ( is_composing_char(ch) + || is_combining_char(get_wchar(&linebuf.buf[linebuf.end]), ch)) + /* Continuation of the same overstrike. */ + a = last_overstrike; + else + overstrike = 0; + } + + if (ch == '\t') + { + /* + * Expand a tab into spaces. + */ + if (proc_tab == OPT_ONPLUS || (bs_mode == BS_CONTROL && proc_tab == OPT_OFF)) + return store_control_char(ch, rep, pos); + STORE_TAB(a, pos); + return (0); + } + if ((!utf_mode || is_ascii_char(ch)) && control_char((char)ch)) + { + return store_control_char(ch, rep, pos); + } else if (utf_mode && ctldisp != OPT_ON && is_ubin_char(ch)) + { + STORE_STRING(prutfchar(ch), AT_BINARY, pos); + } else + { + STORE_CHAR(ch, a, rep, pos); + } + return (0); +} + +/* + * + */ +public int pflushmbc(void) +{ + int r = 0; + + if (mbc_buf_len > 0) + { + /* Flush incomplete (truncated) sequence. */ + r = flush_mbc_buf(mbc_pos); + mbc_buf_len = 0; + } + return r; +} + +/* + * Switch to normal attribute at end of line. + */ +static void add_attr_normal(void) +{ + if (ctldisp != OPT_ONPLUS || !is_ansi_end('m')) + return; + addstr_linebuf("\033[m", AT_ANSI, 0); + if (hlink_in_line) /* Don't send hyperlink clear if we know we don't need to. */ + addstr_linebuf("\033]8;;\033\\", AT_ANSI, 0); +} + +/* + * Terminate the line in the line buffer. + */ +public void pdone(int endline, int chopped, int forw) +{ + (void) pflushmbc(); + + if (pendc && (pendc != '\r' || !endline)) + /* + * If we had a pending character, put it in the buffer. + * But discard a pending CR if we are at end of line + * (that is, discard the CR in a CR/LF sequence). + */ + (void) do_append(pendc, NULL, pendpos); + + if (chopped && rscroll_char) + { + /* + * Display the right scrolling char. + * If we've already filled the rightmost screen char + * (in the buffer), overwrite it. + */ + if (end_column >= sc_width + cshift) + { + /* We've already written in the rightmost char. */ + end_column = right_column; + linebuf.end = right_curr; + } + add_attr_normal(); + while (end_column < sc_width-1 + cshift) + { + /* + * Space to last (rightmost) char on screen. + * This may be necessary if the char we overwrote + * was double-width. + */ + add_linebuf(' ', rscroll_attr, 1); + } + /* Print rscroll char. It must be single-width. */ + add_linebuf(rscroll_char, rscroll_attr, 1); + } else + { + add_attr_normal(); + } + + /* + * If we're coloring a status line, fill out the line with spaces. + */ + if (status_line && line_mark_attr != 0) { + while (end_column +1 < sc_width + cshift) + add_linebuf(' ', line_mark_attr, 1); + } + + /* + * Add a newline if necessary, + * and append a '\0' to the end of the line. + * We output a newline if we're not at the right edge of the screen, + * or if the terminal doesn't auto wrap, + * or if this is really the end of the line AND the terminal ignores + * a newline at the right edge. + * (In the last case we don't want to output a newline if the terminal + * doesn't ignore it since that would produce an extra blank line. + * But we do want to output a newline if the terminal ignores it in case + * the next line is blank. In that case the single newline output for + * that blank line would be ignored!) + */ + if (end_column < sc_width + cshift || !auto_wrap || (endline && ignaw) || ctldisp == OPT_ON) + { + add_linebuf('\n', AT_NORMAL, 0); + } + else if (ignaw && end_column >= sc_width + cshift && forw) + { + /* + * Terminals with "ignaw" don't wrap until they *really* need + * to, i.e. when the character *after* the last one to fit on a + * line is output. But they are too hard to deal with when they + * get in the state where a full screen width of characters + * have been output but the cursor is sitting on the right edge + * instead of at the start of the next line. + * So we nudge them into wrapping by outputting a space + * character plus a backspace. But do this only if moving + * forward; if we're moving backward and drawing this line at + * the top of the screen, the space would overwrite the first + * char on the next line. We don't need to do this "nudge" + * at the top of the screen anyway. + */ + add_linebuf(' ', AT_NORMAL, 1); + add_linebuf('\b', AT_NORMAL, -1); + } + set_linebuf(linebuf.end, '\0', AT_NORMAL); +} + +/* + * Set an attribute on each char of the line in the line buffer. + */ +public void set_attr_line(int a) +{ + int i; + + for (i = linebuf.print; i < linebuf.end; i++) + if ((linebuf.attr[i] & AT_COLOR) == 0 || (a & AT_COLOR) == 0) + linebuf.attr[i] |= a; +} + +/* + * Set the char to be displayed in the status column. + */ +public void set_status_col(char c, int attr) +{ + set_pfx(0, c, attr); +} + +/* + * Get a character from the current line. + * Return the character as the function return value, + * and the character attribute in *ap. + */ +public int gline(int i, int *ap) +{ + if (is_null_line) + { + /* + * If there is no current line, we pretend the line is + * either "~" or "", depending on the "twiddle" flag. + */ + if (twiddle) + { + if (i == 0) + { + *ap = AT_BOLD; + return '~'; + } + --i; + } + /* Make sure we're back to AT_NORMAL before the '\n'. */ + *ap = AT_NORMAL; + return i ? '\0' : '\n'; + } + + if (i < linebuf.pfx_end) + { + *ap = linebuf.pfx_attr[i]; + return linebuf.pfx[i]; + } + i += linebuf.print - linebuf.pfx_end; + *ap = linebuf.attr[i]; + return (linebuf.buf[i] & 0xFF); +} + +/* + * Indicate that there is no current line. + */ +public void null_line(void) +{ + is_null_line = 1; + cshift = 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(). }} + */ +public POSITION forw_raw_line(POSITION curr_pos, char **linep, int *line_lenp) +{ + int n; + int c; + POSITION new_pos; + + if (curr_pos == NULL_POSITION || ch_seek(curr_pos) || + (c = ch_forw_get()) == EOI) + return (NULL_POSITION); + + n = 0; + for (;;) + { + if (c == '\n' || c == EOI || ABORT_SIGS()) + { + new_pos = ch_tell(); + break; + } + if (n >= size_linebuf-1) + { + if (expand_linebuf()) + { + /* + * Overflowed the input buffer. + * Pretend the line ended here. + */ + new_pos = ch_tell() - 1; + break; + } + } + linebuf.buf[n++] = c; + c = ch_forw_get(); + } + linebuf.buf[n] = '\0'; + if (linep != NULL) + *linep = linebuf.buf; + if (line_lenp != NULL) + *line_lenp = n; + return (new_pos); +} + +/* + * Analogous to back_line(), but deals with "raw lines". + * {{ This is supposed to be more efficient than back_line(). }} + */ +public POSITION back_raw_line(POSITION curr_pos, char **linep, int *line_lenp) +{ + int n; + int c; + POSITION new_pos; + + if (curr_pos == NULL_POSITION || curr_pos <= ch_zero() || + ch_seek(curr_pos-1)) + return (NULL_POSITION); + + n = size_linebuf; + linebuf.buf[--n] = '\0'; + for (;;) + { + c = ch_back_get(); + if (c == '\n' || ABORT_SIGS()) + { + /* + * 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_zero(); + break; + } + if (n <= 0) + { + int old_size_linebuf = size_linebuf; + char *fm; + char *to; + if (expand_linebuf()) + { + /* + * Overflowed the input buffer. + * Pretend the line ended here. + */ + new_pos = ch_tell() + 1; + break; + } + /* + * Shift the data to the end of the new linebuf. + */ + for (fm = linebuf.buf + old_size_linebuf - 1, + to = linebuf.buf + size_linebuf - 1; + fm >= linebuf.buf; fm--, to--) + *to = *fm; + n = size_linebuf - old_size_linebuf; + } + linebuf.buf[--n] = c; + } + if (linep != NULL) + *linep = &linebuf.buf[n]; + if (line_lenp != NULL) + *line_lenp = size_linebuf - 1 - n; + return (new_pos); +} + +/* + * Skip cols printable columns at the start of line. + * Return number of bytes skipped. + */ +public int skip_columns(int cols, char **linep, int *line_lenp) +{ + char *line = *linep; + char *eline = line + *line_lenp; + LWCHAR pch = 0; + int bytes; + + while (cols > 0 && line < eline) + { + LWCHAR ch = step_char(&line, +1, eline); + struct ansi_state *pansi = ansi_start(ch); + if (pansi != NULL) + { + skip_ansi(pansi, &line, eline); + ansi_done(pansi); + pch = 0; + } else + { + int w = pwidth(ch, 0, pch, 0); + cols -= w; + pch = ch; + } + } + bytes = line - *linep; + *linep = line; + *line_lenp -= bytes; + return (bytes); +} + +/* + * Append a string to the line buffer. + */ +static int pappstr(constant char *str) +{ + while (*str != '\0') + { + if (pappend(*str++, NULL_POSITION)) + /* Doesn't fit on screen. */ + return 1; + } + return 0; +} + +/* + * Load a string into the line buffer. + * If the string is too long to fit on the screen, + * truncate the beginning of the string to fit. + */ +public void load_line(constant char *str) +{ + int save_hshift = hshift; + + hshift = 0; + for (;;) + { + prewind(); + if (pappstr(str) == 0) + break; + /* + * Didn't fit on screen; increase left shift by one. + * {{ This gets very inefficient if the string + * is much longer than the screen width. }} + */ + hshift += 1; + } + set_linebuf(linebuf.end, '\0', AT_NORMAL); + hshift = save_hshift; +} + +/* + * Find the shift necessary to show the end of the longest displayed line. + */ +public int rrshift(void) +{ + POSITION pos; + int save_width; + int line; + int longest = 0; + + save_width = sc_width; + sc_width = INT_MAX; + pos = position(TOP); + for (line = 0; line < sc_height && pos != NULL_POSITION; line++) + { + pos = forw_line(pos); + if (end_column > longest) + longest = end_column; + } + sc_width = save_width; + if (longest < sc_width) + return 0; + return longest - sc_width; +} + +/* + * Get the color_map index associated with a given attribute. + */ +static int lookup_color_index(int attr) +{ + int cx; + for (cx = 0; cx < sizeof(color_map)/sizeof(*color_map); cx++) + if (color_map[cx].attr == attr) + return cx; + return -1; +} + +static int color_index(int attr) +{ + if (use_color && (attr & AT_COLOR)) + return lookup_color_index(attr & AT_COLOR); + if (attr & AT_UNDERLINE) + return lookup_color_index(AT_UNDERLINE); + if (attr & AT_BOLD) + return lookup_color_index(AT_BOLD); + if (attr & AT_BLINK) + return lookup_color_index(AT_BLINK); + if (attr & AT_STANDOUT) + return lookup_color_index(AT_STANDOUT); + return -1; +} + +/* + * Set the color string to use for a given attribute. + */ +public int set_color_map(int attr, char *colorstr) +{ + int cx = color_index(attr); + if (cx < 0) + return -1; + if (strlen(colorstr)+1 > sizeof(color_map[cx].color)) + return -1; + if (*colorstr != '\0' && parse_color(colorstr, NULL, NULL) == CT_NULL) + return -1; + strcpy(color_map[cx].color, colorstr); + return 0; +} + +/* + * Get the color string to use for a given attribute. + */ +public char * get_color_map(int attr) +{ + int cx = color_index(attr); + if (cx < 0) + return NULL; + return color_map[cx].color; +} diff --git a/third_party/less/linenum.c b/third_party/less/linenum.c new file mode 100644 index 000000000..7b9fd2363 --- /dev/null +++ b/third_party/less/linenum.c @@ -0,0 +1,498 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * 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 "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_info +{ + struct linenum_info *next; /* Link to next in the list */ + struct linenum_info *prev; /* Line to previous in the list */ + POSITION pos; /* File position */ + POSITION gap; /* Gap between prev and next */ + LINENUM 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 200 /* Size of line number pool */ + +#define LONGTIME (2) /* In seconds */ + +static struct linenum_info anchor; /* Anchor of the list */ +static struct linenum_info *freelist; /* Anchor of the unused entries */ +static struct linenum_info pool[NPOOL]; /* The pool itself */ +static struct linenum_info *spare; /* We always keep one spare entry */ +public int scanning_eof = FALSE; + +extern int linenums; +extern int sigs; +extern int sc_height; +extern int screen_trashed; +extern int header_lines; +extern int nonum_headers; + +/* + * Initialize the line number structures. + */ +public void clr_linenum(void) +{ + struct linenum_info *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 = 0; + anchor.pos = (POSITION)0; + anchor.line = 1; +} + +/* + * Calculate the gap for an entry. + */ +static void calcgap(struct linenum_info *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. + */ +public void add_lnum(LINENUM linenum, POSITION pos) +{ + struct linenum_info *p; + struct linenum_info *new; + struct linenum_info *nextp; + struct linenum_info *prevp; + POSITION 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 == linenum) + /* 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 = linenum; + + 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. + */ + mingap = anchor.next->gap; + for (p = anchor.next; p->next != &anchor; p = p->next) + { + if (p->gap <= mingap) + { + spare = p; + mingap = p->gap; + } + } + spare->next->prev = spare->prev; + 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 void longloopmessage(void) +{ + ierror("Calculating line numbers", NULL_PARG); +} + +static int loopcount; +#if HAVE_TIME +static time_type startime; +#endif + +static void longish(void) +{ +#if HAVE_TIME + if (loopcount >= 0 && ++loopcount > 100) + { + loopcount = 0; + if (get_time() >= startime + LONGTIME) + { + longloopmessage(); + loopcount = -1; + } + } +#else + if (loopcount >= 0 && ++loopcount > LONGLOOP) + { + longloopmessage(); + loopcount = -1; + } +#endif +} + +/* + * Turn off line numbers because the user has interrupted + * a lengthy line number calculation. + */ +static void abort_long(void) +{ + if (loopcount >= 0) + return; + if (linenums == OPT_ONPLUS) + /* + * We were displaying line numbers, so need to repaint. + */ + screen_trashed = 1; + linenums = 0; + error("Line numbers turned off", NULL_PARG); +} + +/* + * Find the line number associated with a given position. + * Return 0 if we can't figure it out. + */ +public LINENUM find_linenum(POSITION pos) +{ + struct linenum_info *p; + LINENUM linenum; + POSITION cpos; + + 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 <= ch_zero()) + /* + * 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. + */ +#if HAVE_TIME + startime = get_time(); +#endif + loopcount = 0; + if (p == &anchor || pos - p->prev->pos < p->pos - pos) + { + /* + * Go forward. + */ + p = p->prev; + if (ch_seek(p->pos)) + return (0); + for (linenum = p->line, cpos = p->pos; cpos < pos; linenum++) + { + /* + * Allow a signal to abort this loop. + */ + cpos = forw_raw_line(cpos, (char **)NULL, (int *)NULL); + if (ABORT_SIGS()) { + abort_long(); + return (0); + } + if (cpos == NULL_POSITION) + return (0); + longish(); + } + /* + * We might as well cache it. + */ + add_lnum(linenum, cpos); + /* + * If the given position is not at the start of a line, + * make sure we return the correct line number. + */ + if (cpos > pos) + linenum--; + } else + { + /* + * Go backward. + */ + if (ch_seek(p->pos)) + return (0); + for (linenum = p->line, cpos = p->pos; cpos > pos; linenum--) + { + /* + * Allow a signal to abort this loop. + */ + cpos = back_raw_line(cpos, (char **)NULL, (int *)NULL); + if (ABORT_SIGS()) { + abort_long(); + return (0); + } + if (cpos == NULL_POSITION) + return (0); + longish(); + } + /* + * We might as well cache it. + */ + add_lnum(linenum, cpos); + } + loopcount = 0; + return (linenum); +} + +/* + * Find the position of a given line number. + * Return NULL_POSITION if we can't figure it out. + */ +public POSITION find_pos(LINENUM linenum) +{ + struct linenum_info *p; + POSITION cpos; + LINENUM clinenum; + + if (linenum <= 1) + /* + * Line number 1 is beginning of file. + */ + return (ch_zero()); + + /* + * Find the entry nearest to the line number we want. + */ + for (p = anchor.next; p != &anchor && p->line < linenum; p = p->next) + continue; + if (p->line == linenum) + /* Found it exactly. */ + return (p->pos); + + if (p == &anchor || linenum - p->prev->line < p->line - linenum) + { + /* + * Go forward. + */ + p = p->prev; + if (ch_seek(p->pos)) + return (NULL_POSITION); + for (clinenum = p->line, cpos = p->pos; clinenum < linenum; clinenum++) + { + /* + * Allow a signal to abort this loop. + */ + cpos = forw_raw_line(cpos, (char **)NULL, (int *)NULL); + if (ABORT_SIGS()) + return (NULL_POSITION); + if (cpos == NULL_POSITION) + return (NULL_POSITION); + } + } else + { + /* + * Go backward. + */ + if (ch_seek(p->pos)) + return (NULL_POSITION); + for (clinenum = p->line, cpos = p->pos; clinenum > linenum; clinenum--) + { + /* + * Allow a signal to abort this loop. + */ + cpos = back_raw_line(cpos, (char **)NULL, (int *)NULL); + if (ABORT_SIGS()) + return (NULL_POSITION); + if (cpos == NULL_POSITION) + return (NULL_POSITION); + } + } + /* + * We might as well cache it. + */ + add_lnum(clinenum, cpos); + return (cpos); +} + +/* + * 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). + */ +public LINENUM currline(int where) +{ + POSITION pos; + POSITION len; + LINENUM linenum; + + pos = position(where); + len = ch_length(); + while (pos == NULL_POSITION && where >= 0 && where < sc_height) + pos = position(++where); + if (pos == NULL_POSITION) + pos = len; + linenum = find_linenum(pos); + if (pos == len) + linenum--; + return (linenum); +} + +/* + * Scan entire file, counting line numbers. + */ +public void scan_eof(void) +{ + POSITION pos = ch_zero(); + LINENUM linenum = 0; + + if (ch_seek(0)) + return; + ierror("Determining length of file", NULL_PARG); + /* + * scanning_eof prevents the "Waiting for data" message from + * overwriting "Determining length of file". + */ + scanning_eof = TRUE; + while (pos != NULL_POSITION) + { + /* For efficiency, only add one every 256 line numbers. */ + if ((linenum++ % 256) == 0) + add_lnum(linenum, pos); + pos = forw_raw_line(pos, (char **)NULL, (int *)NULL); + if (ABORT_SIGS()) + break; + } + scanning_eof = FALSE; +} + +/* + * Return a line number adjusted for display + * (handles the --no-number-headers option). + */ +public LINENUM vlinenum(LINENUM linenum) +{ + if (nonum_headers) + linenum = (linenum < header_lines) ? 0 : linenum - header_lines; + return linenum; +} diff --git a/third_party/less/lsystem.c b/third_party/less/lsystem.c new file mode 100644 index 000000000..ebb249d85 --- /dev/null +++ b/third_party/less/lsystem.c @@ -0,0 +1,364 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * Routines to execute other programs. + * Necessarily very OS dependent. + */ + +#include "less.h" +#include +#include "position.h" + +#if MSDOS_COMPILER +#include +#if MSDOS_COMPILER==WIN32C && defined(MINGW) +#include +#define setdisk(n) _chdrive((n)+1) +#else +#ifdef _MSC_VER +#include +#define setdisk(n) _chdrive((n)+1) +#else +#include +#endif +#endif +#endif + +extern int screen_trashed; +extern IFILE curr_ifile; + + +#if HAVE_SYSTEM + +/* + * Pass the specified command to a shell to be executed. + * Like plain "system()", but handles resetting terminal modes, etc. + */ +public void lsystem(char *cmd, char *donemsg) +{ + int inp; +#if HAVE_SHELL + char *shell; + char *p; +#endif + IFILE save_ifile; +#if MSDOS_COMPILER && MSDOS_COMPILER!=WIN32C + char cwd[FILENAME_MAX+1]; +#endif + + /* + * Print the command which is to be executed, + * unless the command starts with a "-". + */ + if (cmd[0] == '-') + cmd++; + else + { + clear_bot(); + putstr("!"); + putstr(cmd); + putstr("\n"); + } + +#if MSDOS_COMPILER +#if MSDOS_COMPILER==WIN32C + if (*cmd == '\0') + cmd = getenv("COMSPEC"); +#else + /* + * Working directory is global on MSDOS. + * The child might change the working directory, so we + * must save and restore CWD across calls to "system", + * or else we won't find our file when we return and + * try to "reedit_ifile" it. + */ + getcwd(cwd, FILENAME_MAX); +#endif +#endif + + /* + * Close the current input file. + */ + save_ifile = save_curr_ifile(); + (void) edit_ifile(NULL_IFILE); + + /* + * De-initialize the terminal and take out of raw mode. + */ + deinit(); + flush(); /* Make sure the deinit chars get out */ + raw_mode(0); +#if MSDOS_COMPILER==WIN32C + close_getchr(); +#endif + + /* + * Restore signals to their defaults. + */ + init_signals(0); + +#if HAVE_DUP + /* + * Force standard input to be the user's terminal + * (the normal standard input), even if less's standard input + * is coming from a pipe. + */ + inp = dup(0); + close(0); +#if !MSDOS_COMPILER + if (open_tty() < 0) +#endif + dup(inp); +#endif + + /* + * Pass the command to the system to be executed. + * If we have a SHELL environment variable, use + * <$SHELL -c "command"> instead of just . + * If the command is empty, just invoke a shell. + */ +#if HAVE_SHELL + p = NULL; + if ((shell = lgetenv("SHELL")) != NULL && *shell != '\0') + { + if (*cmd == '\0') + p = save(shell); + else + { + char *esccmd = shell_quote(cmd); + if (esccmd != NULL) + { + int len = (int) (strlen(shell) + strlen(esccmd) + 5); + p = (char *) ecalloc(len, sizeof(char)); + SNPRINTF3(p, len, "%s %s %s", shell, shell_coption(), esccmd); + free(esccmd); + } + } + } + if (p == NULL) + { + if (*cmd == '\0') + p = save("sh"); + else + p = save(cmd); + } + system(p); + free(p); +#else +#if MSDOS_COMPILER==DJGPPC + /* + * Make stdin of the child be in cooked mode. + */ + setmode(0, O_TEXT); + /* + * We don't need to catch signals of the child (it + * also makes trouble with some DPMI servers). + */ + __djgpp_exception_toggle(); + system(cmd); + __djgpp_exception_toggle(); +#else + system(cmd); +#endif +#endif + +#if HAVE_DUP + /* + * Restore standard input, reset signals, raw mode, etc. + */ + close(0); + dup(inp); + close(inp); +#endif + +#if MSDOS_COMPILER==WIN32C + open_getchr(); +#endif + init_signals(1); + raw_mode(1); + if (donemsg != NULL) + { + putstr(donemsg); + putstr(" (press RETURN)"); + get_return(); + putchr('\n'); + flush(); + } + init(); + screen_trashed = 1; + +#if MSDOS_COMPILER && MSDOS_COMPILER!=WIN32C + /* + * Restore the previous directory (possibly + * changed by the child program we just ran). + */ + chdir(cwd); +#if MSDOS_COMPILER != DJGPPC + /* + * Some versions of chdir() don't change to the drive + * which is part of CWD. (DJGPP does this in chdir.) + */ + if (cwd[1] == ':') + { + if (cwd[0] >= 'a' && cwd[0] <= 'z') + setdisk(cwd[0] - 'a'); + else if (cwd[0] >= 'A' && cwd[0] <= 'Z') + setdisk(cwd[0] - 'A'); + } +#endif +#endif + + /* + * Reopen the current input file. + */ + reedit_ifile(save_ifile); + +#if defined(SIGWINCH) || defined(SIGWIND) + /* + * Since we were ignoring window change signals while we executed + * the system command, we must assume the window changed. + * Warning: this leaves a signal pending (in "sigs"), + * so psignals() should be called soon after lsystem(). + */ + winch(0); +#endif +} + +#endif + +#if PIPEC + +/* + * Pipe a section of the input file into the given shell command. + * The section to be piped is the section "between" the current + * position and the position marked by the given letter. + * + * If the mark is after the current screen, the section between + * the top line displayed and the mark is piped. + * If the mark is before the current screen, the section between + * the mark and the bottom line displayed is piped. + * If the mark is on the current screen, or if the mark is ".", + * the whole current screen is piped. + */ +public int pipe_mark(int c, char *cmd) +{ + POSITION mpos, tpos, bpos; + + /* + * mpos = the marked position. + * tpos = top of screen. + * bpos = bottom of screen. + */ + mpos = markpos(c); + if (mpos == NULL_POSITION) + return (-1); + tpos = position(TOP); + if (tpos == NULL_POSITION) + tpos = ch_zero(); + bpos = position(BOTTOM); + + if (c == '.') + return (pipe_data(cmd, tpos, bpos)); + else if (mpos <= tpos) + return (pipe_data(cmd, mpos, bpos)); + else if (bpos == NULL_POSITION) + return (pipe_data(cmd, tpos, bpos)); + else + return (pipe_data(cmd, tpos, mpos)); +} + +/* + * Create a pipe to the given shell command. + * Feed it the file contents between the positions spos and epos. + */ +public int pipe_data(char *cmd, POSITION spos, POSITION epos) +{ + FILE *f; + int c; + + /* + * This is structured much like lsystem(). + * Since we're running a shell program, we must be careful + * to perform the necessary deinitialization before running + * the command, and reinitialization after it. + */ + if (ch_seek(spos) != 0) + { + error("Cannot seek to start position", NULL_PARG); + return (-1); + } + + if ((f = popen(cmd, "w")) == NULL) + { + error("Cannot create pipe", NULL_PARG); + return (-1); + } + clear_bot(); + putstr("!"); + putstr(cmd); + putstr("\n"); + + deinit(); + flush(); + raw_mode(0); + init_signals(0); +#if MSDOS_COMPILER==WIN32C + close_getchr(); +#endif +#ifdef SIGPIPE + LSIGNAL(SIGPIPE, SIG_IGN); +#endif + + c = EOI; + while (epos == NULL_POSITION || spos++ <= epos) + { + /* + * Read a character from the file and give it to the pipe. + */ + c = ch_forw_get(); + if (c == EOI) + break; + if (putc(c, f) == EOF) + break; + } + + /* + * Finish up the last line. + */ + while (c != '\n' && c != EOI ) + { + c = ch_forw_get(); + if (c == EOI) + break; + if (putc(c, f) == EOF) + break; + } + + pclose(f); + +#ifdef SIGPIPE + LSIGNAL(SIGPIPE, SIG_DFL); +#endif +#if MSDOS_COMPILER==WIN32C + open_getchr(); +#endif + init_signals(1); + raw_mode(1); + init(); + screen_trashed = 1; +#if defined(SIGWINCH) || defined(SIGWIND) + /* {{ Probably don't need this here. }} */ + winch(0); +#endif + return (0); +} + +#endif diff --git a/third_party/less/main.c b/third_party/less/main.c new file mode 100644 index 000000000..21ed227ca --- /dev/null +++ b/third_party/less/main.c @@ -0,0 +1,457 @@ +asm(".ident\t\"\\n\\n\ +Less\\n\ +Copyright (C) 1984-2023 Mark Nudelman\\n\ +\\n\ +Redistribution and use in source and binary forms, with or without\\n\ +modification, are permitted provided that the following conditions\\n\ +are met:\\n\ +1. Redistributions of source code must retain the above copyright\\n\ + notice, this list of conditions and the following disclaimer.\\n\ +2. Redistributions in binary form must reproduce the above copyright\\n\ + notice in the documentation and/or other materials provided with\\n\ + the distribution.\\n\ +\\n\ +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY\\n\ +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\\n\ +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\\n\ +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE\\n\ +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\\n\ +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\\n\ +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\\n\ +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\\n\ +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\\n\ +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN\\n\ +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\""); + +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * Entry point, initialization, miscellaneous routines. + */ + +#include "less.h" +#if MSDOS_COMPILER==WIN32C +#define WIN32_LEAN_AND_MEAN +/* #include */ +#endif + +public char * every_first_cmd = NULL; +public int new_file; +public int is_tty; +public IFILE curr_ifile = NULL_IFILE; +public IFILE old_ifile = NULL_IFILE; +public struct scrpos initial_scrpos; +public POSITION start_attnpos = NULL_POSITION; +public POSITION end_attnpos = NULL_POSITION; +public int wscroll; +public char * progname; +public int quitting; +public int secure; +public int dohelp; + +#if LOGFILE +public int logfile = -1; +public int force_logfile = FALSE; +public char * namelogfile = NULL; +#endif + +#if EDITOR +public char * editor; +public char * editproto; +#endif + +#if TAGS +extern char * tags; +extern char * tagoption; +extern int jump_sline; +#endif + +#ifdef WIN32 +static char consoleTitle[256]; +#endif + +public int one_screen; +extern int less_is_more; +extern int missing_cap; +extern int know_dumb; +extern int pr_type; +extern int quit_if_one_screen; +extern int no_init; +extern int errmsgs; +extern int redraw_on_quit; +extern int term_init_done; +extern int first_time; + +/* + * Entry point. + */ +int main(int argc, char *argv[]) +{ + IFILE ifile; + char *s; + +#ifdef __EMX__ + _response(&argc, &argv); + _wildcard(&argc, &argv); +#endif + + progname = *argv++; + argc--; + +#if SECURE + secure = 1; +#else + secure = 0; + s = lgetenv("LESSSECURE"); + if (!isnullenv(s)) + secure = 1; +#endif + +#ifdef WIN32 + if (getenv("HOME") == NULL) + { + /* + * If there is no HOME environment variable, + * try the concatenation of HOMEDRIVE + HOMEPATH. + */ + char *drive = getenv("HOMEDRIVE"); + char *path = getenv("HOMEPATH"); + if (drive != NULL && path != NULL) + { + char *env = (char *) ecalloc(strlen(drive) + + strlen(path) + 6, sizeof(char)); + strcpy(env, "HOME="); + strcat(env, drive); + strcat(env, path); + putenv(env); + } + } + GetConsoleTitle(consoleTitle, sizeof(consoleTitle)/sizeof(char)); +#endif /* WIN32 */ + + /* + * Process command line arguments and LESS environment arguments. + * Command line arguments override environment arguments. + */ + is_tty = isatty(1); + init_mark(); + init_cmds(); + init_poll(); + get_term(); + init_charset(); + init_line(); + init_cmdhist(); + init_option(); + init_search(); + + /* + * If the name of the executable program is "more", + * act like LESS_IS_MORE is set. + */ + s = last_component(progname); + if (strcmp(s, "more") == 0) + less_is_more = 1; + + init_prompt(); + + s = lgetenv(less_is_more ? "MORE" : "LESS"); + if (s != NULL) + scan_option(s); + +#define isoptstring(s) (((s)[0] == '-' || (s)[0] == '+') && (s)[1] != '\0') + while (argc > 0 && (isoptstring(*argv) || isoptpending())) + { + s = *argv++; + argc--; + if (strcmp(s, "--") == 0) + break; + scan_option(s); + } +#undef isoptstring + + if (isoptpending()) + { + /* + * Last command line option was a flag requiring a + * following string, but there was no following string. + */ + nopendopt(); + quit(QUIT_OK); + } + + expand_cmd_tables(); + +#if EDITOR + editor = lgetenv("VISUAL"); + if (editor == NULL || *editor == '\0') + { + editor = lgetenv("EDITOR"); + if (isnullenv(editor)) + editor = EDIT_PGM; + } + editproto = lgetenv("LESSEDIT"); + if (isnullenv(editproto)) + editproto = "%E ?lm+%lm. %g"; +#endif + + /* + * Call get_ifile with all the command line filenames + * to "register" them with the ifile system. + */ + ifile = NULL_IFILE; + if (dohelp) + ifile = get_ifile(FAKE_HELPFILE, ifile); + while (argc-- > 0) + { +#if (MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC) + /* + * Because the "shell" doesn't expand filename patterns, + * treat each argument as a filename pattern rather than + * a single filename. + * Expand the pattern and iterate over the expanded list. + */ + struct textlist tlist; + char *filename; + char *gfilename; + char *qfilename; + + gfilename = lglob(*argv++); + init_textlist(&tlist, gfilename); + filename = NULL; + while ((filename = forw_textlist(&tlist, filename)) != NULL) + { + qfilename = shell_unquote(filename); + (void) get_ifile(qfilename, ifile); + free(qfilename); + ifile = prev_ifile(NULL_IFILE); + } + free(gfilename); +#else + (void) get_ifile(*argv++, ifile); + ifile = prev_ifile(NULL_IFILE); +#endif + } + /* + * Set up terminal, etc. + */ + if (!is_tty) + { + /* + * Output is not a tty. + * Just copy the input file(s) to output. + */ + set_output(1); /* write to stdout */ + SET_BINARY(1); + if (edit_first() == 0) + { + do { + cat_file(); + } while (edit_next(1) == 0); + } + quit(QUIT_OK); + } + + if (missing_cap && !know_dumb) + error("WARNING: terminal is not fully functional", NULL_PARG); + open_getchr(); + raw_mode(1); + init_signals(1); + + /* + * Select the first file to examine. + */ +#if TAGS + if (tagoption != NULL || strcmp(tags, "-") == 0) + { + /* + * A -t option was given. + * Verify that no filenames were also given. + * Edit the file selected by the "tags" search, + * and search for the proper line in the file. + */ + if (nifile() > 0) + { + error("No filenames allowed with -t option", NULL_PARG); + quit(QUIT_ERROR); + } + findtag(tagoption); + if (edit_tagfile()) /* Edit file which contains the tag */ + quit(QUIT_ERROR); + /* + * Search for the line which contains the tag. + * Set up initial_scrpos so we display that line. + */ + initial_scrpos.pos = tagsearch(); + if (initial_scrpos.pos == NULL_POSITION) + quit(QUIT_ERROR); + initial_scrpos.ln = jump_sline; + } else +#endif + { + if (edit_first()) + quit(QUIT_ERROR); + /* + * See if file fits on one screen to decide whether + * to send terminal init. But don't need this + * if -X (no_init) overrides this (see init()). + */ + if (quit_if_one_screen) + { + if (nifile() > 1) /* If more than one file, -F cannot be used */ + quit_if_one_screen = FALSE; + else if (!no_init) + one_screen = get_one_screen(); + } + } + + if (errmsgs > 0) + { + /* + * We displayed some messages on error output + * (file descriptor 2; see flush()). + * Before erasing the screen contents, wait for a keystroke. + */ + less_printf("Press RETURN to continue ", NULL_PARG); + get_return(); + putchr('\n'); + } + set_output(1); + init(); + commands(); + quit(QUIT_OK); + /*NOTREACHED*/ + return (0); +} + +/* + * Copy a string to a "safe" place + * (that is, to a buffer allocated by calloc). + */ +public char * save(constant char *s) +{ + char *p; + + p = (char *) ecalloc(strlen(s)+1, sizeof(char)); + strcpy(p, s); + return (p); +} + +public void out_of_memory(void) +{ + error("Cannot allocate memory", NULL_PARG); + quit(QUIT_ERROR); +} + +/* + * Allocate memory. + * Like calloc(), but never returns an error (NULL). + */ +public void * ecalloc(int count, unsigned int size) +{ + void * p; + + p = (void *) calloc(count, size); + if (p == NULL) + out_of_memory(); + return p; +} + +/* + * Skip leading spaces in a string. + */ +public char * skipsp(char *s) +{ + while (*s == ' ' || *s == '\t') + s++; + return (s); +} + +/* + * See how many characters of two strings are identical. + * If uppercase is true, the first string must begin with an uppercase + * character; the remainder of the first string may be either case. + */ +public int sprefix(char *ps, char *s, int uppercase) +{ + int c; + int sc; + int len = 0; + + for ( ; *s != '\0'; s++, ps++) + { + c = *ps; + if (uppercase) + { + if (len == 0 && ASCII_IS_LOWER(c)) + return (-1); + if (ASCII_IS_UPPER(c)) + c = ASCII_TO_LOWER(c); + } + sc = *s; + if (len > 0 && ASCII_IS_UPPER(sc)) + sc = ASCII_TO_LOWER(sc); + if (c != sc) + break; + len++; + } + return (len); +} + +/* + * Exit the program. + */ +public void quit(int status) +{ + static int save_status; + + /* + * Put cursor at bottom left corner, clear the line, + * reset the terminal modes, and exit. + */ + if (status < 0) + status = save_status; + else + save_status = status; + quitting = 1; + check_altpipe_error(); + if (interactive()) + clear_bot(); + deinit(); + flush(); + if (redraw_on_quit && term_init_done) + { + /* + * The last file text displayed might have been on an + * alternate screen, which now (since deinit) cannot be seen. + * redraw_on_quit tells us to redraw it on the main screen. + */ + first_time = 1; /* Don't print "skipping" or tildes */ + repaint(); + flush(); + } + edit((char*)NULL); + save_cmdhist(); + raw_mode(0); +#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC + /* + * If we don't close 2, we get some garbage from + * 2's buffer when it flushes automatically. + * I cannot track this one down RB + * The same bug shows up if we use ^C^C to abort. + */ + close(2); +#endif +#ifdef WIN32 + SetConsoleTitle(consoleTitle); +#endif + close_getchr(); + exit(status); +} diff --git a/third_party/less/mark.c b/third_party/less/mark.c new file mode 100644 index 000000000..1749e01b3 --- /dev/null +++ b/third_party/less/mark.c @@ -0,0 +1,427 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +#include "less.h" +#include "position.h" + +extern IFILE curr_ifile; +extern int sc_height; +extern int jump_sline; +extern int perma_marks; + +/* + * A mark is an ifile (input file) plus a position within the file. + */ +struct mark +{ + /* + * Normally m_ifile != IFILE_NULL and m_filename == NULL. + * For restored marks we set m_filename instead of m_ifile + * because we don't want to create an ifile until the + * user explicitly requests the file (by name or mark). + */ + char m_letter; /* Associated character */ + IFILE m_ifile; /* Input file being marked */ + char *m_filename; /* Name of the input file */ + struct scrpos m_scrpos; /* Position of the mark */ +}; + +/* + * The table of marks. + * Each mark is identified by a lowercase or uppercase letter. + * The final one is lmark, for the "last mark"; addressed by the apostrophe. + */ +#define NMARKS ((2*26)+2) /* a-z, A-Z, mousemark, lastmark */ +#define NUMARKS ((2*26)+1) /* user marks (not lastmark) */ +#define MOUSEMARK (NMARKS-2) +#define LASTMARK (NMARKS-1) +static struct mark marks[NMARKS]; +public int marks_modified = 0; + + +/* + * Initialize a mark struct. + */ +static void cmark(struct mark *m, IFILE ifile, POSITION pos, int ln) +{ + m->m_ifile = ifile; + m->m_scrpos.pos = pos; + m->m_scrpos.ln = ln; + if (m->m_filename != NULL) + /* Normally should not happen but a corrupt lesshst file can do it. */ + free(m->m_filename); + m->m_filename = NULL; +} + +/* + * Initialize the mark table to show no marks are set. + */ +public void init_mark(void) +{ + int i; + + for (i = 0; i < NMARKS; i++) + { + char letter; + switch (i) { + case MOUSEMARK: letter = '#'; break; + case LASTMARK: letter = '\''; break; + default: letter = (i < 26) ? 'a'+i : 'A'+i-26; break; + } + marks[i].m_letter = letter; + cmark(&marks[i], NULL_IFILE, NULL_POSITION, -1); + } +} + +/* + * Set m_ifile and clear m_filename. + */ +static void mark_set_ifile(struct mark *m, IFILE ifile) +{ + m->m_ifile = ifile; + /* With m_ifile set, m_filename is no longer needed. */ + free(m->m_filename); + m->m_filename = NULL; +} + +/* + * Populate the m_ifile member of a mark struct from m_filename. + */ +static void mark_get_ifile(struct mark *m) +{ + if (m->m_ifile != NULL_IFILE) + return; /* m_ifile is already set */ + mark_set_ifile(m, get_ifile(m->m_filename, prev_ifile(NULL_IFILE))); +} + +/* + * Return the user mark struct identified by a character. + */ +static struct mark * getumark(LWCHAR c) +{ + PARG parg; + if (c >= 'a' && c <= 'z') + return (&marks[c-'a']); + if (c >= 'A' && c <= 'Z') + return (&marks[c-'A'+26]); + if (c == '\'') + return (&marks[LASTMARK]); + if (c == '#') + return (&marks[MOUSEMARK]); + parg.p_char = (char) c; + error("Invalid mark letter %c", &parg); + return (NULL); +} + +/* + * Get the mark structure identified by a character. + * The mark struct may either be in the mark table (user mark) + * or may be constructed on the fly for certain characters like ^, $. + */ +static struct mark * getmark(LWCHAR c) +{ + struct mark *m; + static struct mark sm; + + switch (c) + { + case '^': + /* + * Beginning of the current file. + */ + m = &sm; + cmark(m, curr_ifile, ch_zero(), 0); + break; + case '$': + /* + * End of the current file. + */ + if (ch_end_seek()) + { + error("Cannot seek to end of file", NULL_PARG); + return (NULL); + } + m = &sm; + cmark(m, curr_ifile, ch_tell(), sc_height); + break; + case '.': + /* + * Current position in the current file. + */ + m = &sm; + get_scrpos(&m->m_scrpos, TOP); + cmark(m, curr_ifile, m->m_scrpos.pos, m->m_scrpos.ln); + break; + case '\'': + /* + * The "last mark". + */ + m = &marks[LASTMARK]; + break; + default: + /* + * Must be a user-defined mark. + */ + m = getumark(c); + if (m == NULL) + break; + if (m->m_scrpos.pos == NULL_POSITION) + { + error("Mark not set", NULL_PARG); + return (NULL); + } + break; + } + return (m); +} + +/* + * Is a mark letter invalid? + */ +public int badmark(LWCHAR c) +{ + return (getmark(c) == NULL); +} + +/* + * Set a user-defined mark. + */ +public void setmark(LWCHAR c, int where) +{ + struct mark *m; + struct scrpos scrpos; + + m = getumark(c); + if (m == NULL) + return; + get_scrpos(&scrpos, where); + if (scrpos.pos == NULL_POSITION) + { + bell(); + return; + } + cmark(m, curr_ifile, scrpos.pos, scrpos.ln); + marks_modified = 1; +} + +/* + * Clear a user-defined mark. + */ +public void clrmark(LWCHAR c) +{ + struct mark *m; + + m = getumark(c); + if (m == NULL) + return; + if (m->m_scrpos.pos == NULL_POSITION) + { + bell(); + return; + } + m->m_scrpos.pos = NULL_POSITION; + marks_modified = 1; +} + +/* + * Set lmark (the mark named by the apostrophe). + */ +public void lastmark(void) +{ + struct scrpos scrpos; + + if (ch_getflags() & CH_HELPFILE) + return; + get_scrpos(&scrpos, TOP); + if (scrpos.pos == NULL_POSITION) + return; + cmark(&marks[LASTMARK], curr_ifile, scrpos.pos, scrpos.ln); + marks_modified = 1; +} + +/* + * Go to a mark. + */ +public void gomark(LWCHAR c) +{ + struct mark *m; + struct scrpos scrpos; + + m = getmark(c); + if (m == NULL) + return; + + /* + * If we're trying to go to the lastmark and + * it has not been set to anything yet, + * set it to the beginning of the current file. + * {{ Couldn't we instead set marks[LASTMARK] in edit()? }} + */ + if (m == &marks[LASTMARK] && m->m_scrpos.pos == NULL_POSITION) + cmark(m, curr_ifile, ch_zero(), jump_sline); + + mark_get_ifile(m); + + /* Save scrpos; if it's LASTMARK it could change in edit_ifile. */ + scrpos = m->m_scrpos; + if (m->m_ifile != curr_ifile) + { + /* + * Not in the current file; edit the correct file. + */ + if (edit_ifile(m->m_ifile)) + return; + } + + jump_loc(scrpos.pos, scrpos.ln); +} + +/* + * Return the position associated with a given mark letter. + * + * We don't return which screen line the position + * is associated with, but this doesn't matter much, + * because it's always the first non-blank line on the screen. + */ +public POSITION markpos(LWCHAR c) +{ + struct mark *m; + + m = getmark(c); + if (m == NULL) + return (NULL_POSITION); + + if (m->m_ifile != curr_ifile) + { + error("Mark not in current file", NULL_PARG); + return (NULL_POSITION); + } + return (m->m_scrpos.pos); +} + +/* + * Return the mark associated with a given position, if any. + */ +public char posmark(POSITION pos) +{ + int i; + + /* Only user marks */ + for (i = 0; i < NUMARKS; i++) + { + if (marks[i].m_ifile == curr_ifile && marks[i].m_scrpos.pos == pos) + { + if (i < 26) return 'a' + i; + if (i < 26*2) return 'A' + (i - 26); + return '#'; + } + } + return 0; +} + +/* + * Clear the marks associated with a specified ifile. + */ +public void unmark(IFILE ifile) +{ + int i; + + for (i = 0; i < NMARKS; i++) + if (marks[i].m_ifile == ifile) + marks[i].m_scrpos.pos = NULL_POSITION; +} + +/* + * Check if any marks refer to a specified ifile vi m_filename + * rather than m_ifile. + */ +public void mark_check_ifile(IFILE ifile) +{ + int i; + char *filename = get_real_filename(ifile); + + for (i = 0; i < NMARKS; i++) + { + struct mark *m = &marks[i]; + char *mark_filename = m->m_filename; + if (mark_filename != NULL) + { + mark_filename = lrealpath(mark_filename); + if (strcmp(filename, mark_filename) == 0) + mark_set_ifile(m, ifile); + free(mark_filename); + } + } +} + +#if CMD_HISTORY + +/* + * Save marks to history file. + */ +public void save_marks(FILE *fout, char *hdr) +{ + int i; + + if (!perma_marks) + return; + + fprintf(fout, "%s\n", hdr); + for (i = 0; i < NMARKS; i++) + { + char *filename; + struct mark *m = &marks[i]; + char pos_str[INT_STRLEN_BOUND(m->m_scrpos.pos) + 2]; + if (m->m_scrpos.pos == NULL_POSITION) + continue; + postoa(m->m_scrpos.pos, pos_str, 10); + filename = m->m_filename; + if (filename == NULL) + filename = get_real_filename(m->m_ifile); + if (strcmp(filename, "-") != 0) + fprintf(fout, "m %c %d %s %s\n", + m->m_letter, m->m_scrpos.ln, pos_str, filename); + } +} + +/* + * Restore one mark from the history file. + */ +public void restore_mark(char *line) +{ + struct mark *m; + int ln; + POSITION pos; + +#define skip_whitespace while (*line == ' ') line++ + if (*line++ != 'm') + return; + skip_whitespace; + m = getumark(*line++); + if (m == NULL) + return; + skip_whitespace; + ln = lstrtoi(line, &line, 10); + if (ln < 0) + return; + if (ln < 1) + ln = 1; + if (ln > sc_height) + ln = sc_height; + skip_whitespace; + pos = lstrtopos(line, &line, 10); + if (pos < 0) + return; + skip_whitespace; + cmark(m, NULL_IFILE, pos, ln); + m->m_filename = save(line); +} + +#endif /* CMD_HISTORY */ diff --git a/third_party/less/optfunc.c b/third_party/less/optfunc.c new file mode 100644 index 000000000..974a6f6c8 --- /dev/null +++ b/third_party/less/optfunc.c @@ -0,0 +1,1096 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * Handling functions for command line options. + * + * Most options are handled by the generic code in option.c. + * But all string options, and a few non-string options, require + * special handling specific to the particular option. + * This special processing is done by the "handling functions" in this file. + * + * Each handling function is passed a "type" and, if it is a string + * option, the string which should be "assigned" to the option. + * The type may be one of: + * INIT The option is being initialized from the command line. + * TOGGLE The option is being changed from within the program. + * QUERY The setting of the option is merely being queried. + */ + +#include "less.h" +#include "option.h" + +extern int nbufs; +extern int bufspace; +extern int pr_type; +extern int plusoption; +extern int swindow; +extern int sc_width; +extern int sc_height; +extern int secure; +extern int dohelp; +extern int is_tty; +extern char openquote; +extern char closequote; +extern char *prproto[]; +extern char *eqproto; +extern char *hproto; +extern char *wproto; +extern char *every_first_cmd; +extern IFILE curr_ifile; +extern char version[]; +extern int jump_sline; +extern long jump_sline_fraction; +extern int shift_count; +extern long shift_count_fraction; +extern char rscroll_char; +extern int rscroll_attr; +extern int mousecap; +extern int wheel_lines; +extern int less_is_more; +extern int linenum_width; +extern int status_col_width; +extern int use_color; +extern int want_filesize; +extern int header_lines; +extern int header_cols; +extern int def_search_type; +extern int chopline; +extern int tabstops[]; +extern int ntabstops; +extern int tabdefault; +extern char intr_char; +#if LOGFILE +extern char *namelogfile; +extern int force_logfile; +extern int logfile; +#endif +#if TAGS +public char *tagoption = NULL; +extern char *tags; +extern char ztags[]; +#endif +#if LESSTEST +extern char *ttyin_name; +#endif /*LESSTEST*/ +#if MSDOS_COMPILER +extern int nm_fg_color, nm_bg_color; +extern int bo_fg_color, bo_bg_color; +extern int ul_fg_color, ul_bg_color; +extern int so_fg_color, so_bg_color; +extern int bl_fg_color, bl_bg_color; +extern int sgr_mode; +#if MSDOS_COMPILER==WIN32C +#ifndef COMMON_LVB_UNDERSCORE +#define COMMON_LVB_UNDERSCORE 0x8000 +#endif +#endif +#endif + + +#if LOGFILE +/* + * Handler for -o option. + */ +public void opt_o(int type, char *s) +{ + PARG parg; + char *filename; + + if (secure) + { + error("log file support is not available", NULL_PARG); + return; + } + switch (type) + { + case INIT: + namelogfile = save(s); + break; + case TOGGLE: + if (ch_getflags() & CH_CANSEEK) + { + error("Input is not a pipe", NULL_PARG); + return; + } + if (logfile >= 0) + { + error("Log file is already in use", NULL_PARG); + return; + } + s = skipsp(s); + if (namelogfile != NULL) + free(namelogfile); + filename = lglob(s); + namelogfile = shell_unquote(filename); + free(filename); + use_logfile(namelogfile); + sync_logfile(); + break; + case QUERY: + if (logfile < 0) + error("No log file", NULL_PARG); + else + { + parg.p_string = namelogfile; + error("Log file \"%s\"", &parg); + } + break; + } +} + +/* + * Handler for -O option. + */ +public void opt__O(int type, char *s) +{ + force_logfile = TRUE; + opt_o(type, s); +} +#endif + +/* + * Handlers for -j option. + */ +public void opt_j(int type, char *s) +{ + PARG parg; + int len; + int err; + + switch (type) + { + case INIT: + case TOGGLE: + if (*s == '.') + { + s++; + jump_sline_fraction = getfraction(&s, "j", &err); + if (err) + error("Invalid line fraction", NULL_PARG); + else + calc_jump_sline(); + } else + { + int sline = getnum(&s, "j", &err); + if (err) + error("Invalid line number", NULL_PARG); + else + { + jump_sline = sline; + jump_sline_fraction = -1; + } + } + break; + case QUERY: + if (jump_sline_fraction < 0) + { + parg.p_int = jump_sline; + error("Position target at screen line %d", &parg); + } else + { + char buf[INT_STRLEN_BOUND(long)+2]; + SNPRINTF1(buf, sizeof(buf), ".%06ld", jump_sline_fraction); + len = (int) strlen(buf); + while (len > 2 && buf[len-1] == '0') + len--; + buf[len] = '\0'; + parg.p_string = buf; + error("Position target at screen position %s", &parg); + } + break; + } +} + +public void calc_jump_sline(void) +{ + if (jump_sline_fraction < 0) + return; + jump_sline = (int) muldiv(sc_height, jump_sline_fraction, NUM_FRAC_DENOM); +} + +/* + * Handlers for -# option. + */ +public void opt_shift(int type, char *s) +{ + PARG parg; + int len; + int err; + + switch (type) + { + case INIT: + case TOGGLE: + if (*s == '.') + { + s++; + shift_count_fraction = getfraction(&s, "#", &err); + if (err) + error("Invalid column fraction", NULL_PARG); + else + calc_shift_count(); + } else + { + int hs = getnum(&s, "#", &err); + if (err) + error("Invalid column number", NULL_PARG); + else + { + shift_count = hs; + shift_count_fraction = -1; + } + } + break; + case QUERY: + if (shift_count_fraction < 0) + { + parg.p_int = shift_count; + error("Horizontal shift %d columns", &parg); + } else + { + char buf[INT_STRLEN_BOUND(long)+2]; + SNPRINTF1(buf, sizeof(buf), ".%06ld", shift_count_fraction); + len = (int) strlen(buf); + while (len > 2 && buf[len-1] == '0') + len--; + buf[len] = '\0'; + parg.p_string = buf; + error("Horizontal shift %s of screen width", &parg); + } + break; + } +} + +public void calc_shift_count(void) +{ + if (shift_count_fraction < 0) + return; + shift_count = (int) muldiv(sc_width, shift_count_fraction, NUM_FRAC_DENOM); +} + +#if USERFILE +public void opt_k(int type, char *s) +{ + PARG parg; + + switch (type) + { + case INIT: + if (lesskey(s, 0)) + { + parg.p_string = s; + error("Cannot use lesskey file \"%s\"", &parg); + } + break; + } +} + +#if HAVE_LESSKEYSRC +public void opt_ks(int type, char *s) +{ + PARG parg; + + switch (type) + { + case INIT: + if (lesskey_src(s, 0)) + { + parg.p_string = s; + error("Cannot use lesskey source file \"%s\"", &parg); + } + break; + } +} +#endif /* HAVE_LESSKEYSRC */ +#endif /* USERFILE */ + +#if TAGS +/* + * Handler for -t option. + */ +public void opt_t(int type, char *s) +{ + IFILE save_ifile; + POSITION pos; + + switch (type) + { + case INIT: + tagoption = save(s); + /* Do the rest in main() */ + break; + case TOGGLE: + if (secure) + { + error("tags support is not available", NULL_PARG); + break; + } + findtag(skipsp(s)); + save_ifile = save_curr_ifile(); + /* + * Try to open the file containing the tag + * and search for the tag in that file. + */ + if (edit_tagfile() || (pos = tagsearch()) == NULL_POSITION) + { + /* Failed: reopen the old file. */ + reedit_ifile(save_ifile); + break; + } + unsave_ifile(save_ifile); + jump_loc(pos, jump_sline); + break; + } +} + +/* + * Handler for -T option. + */ +public void opt__T(int type, char *s) +{ + PARG parg; + char *filename; + + switch (type) + { + case INIT: + tags = save(s); + break; + case TOGGLE: + s = skipsp(s); + if (tags != NULL && tags != ztags) + free(tags); + filename = lglob(s); + tags = shell_unquote(filename); + free(filename); + break; + case QUERY: + parg.p_string = tags; + error("Tags file \"%s\"", &parg); + break; + } +} +#endif + +/* + * Handler for -p option. + */ +public void opt_p(int type, char *s) +{ + switch (type) + { + case INIT: + /* + * Unget a command for the specified string. + */ + if (less_is_more) + { + /* + * In "more" mode, the -p argument is a command, + * not a search string, so we don't need a slash. + */ + every_first_cmd = save(s); + } else + { + plusoption = TRUE; + /* + * {{ This won't work if the "/" command is + * changed or invalidated by a .lesskey file. }} + */ + ungetsc("/"); + ungetsc(s); + ungetcc_back(CHAR_END_COMMAND); + } + break; + } +} + +/* + * Handler for -P option. + */ +public void opt__P(int type, char *s) +{ + char **proto; + PARG parg; + + switch (type) + { + case INIT: + case TOGGLE: + /* + * Figure out which prototype string should be changed. + */ + switch (*s) + { + case 's': proto = &prproto[PR_SHORT]; s++; break; + case 'm': proto = &prproto[PR_MEDIUM]; s++; break; + case 'M': proto = &prproto[PR_LONG]; s++; break; + case '=': proto = &eqproto; s++; break; + case 'h': proto = &hproto; s++; break; + case 'w': proto = &wproto; s++; break; + default: proto = &prproto[PR_SHORT]; break; + } + free(*proto); + *proto = save(s); + break; + case QUERY: + parg.p_string = prproto[pr_type]; + error("%s", &parg); + break; + } +} + +/* + * Handler for the -b option. + */ + /*ARGSUSED*/ +public void opt_b(int type, char *s) +{ + switch (type) + { + case INIT: + case TOGGLE: + /* + * Set the new number of buffers. + */ + ch_setbufspace(bufspace); + break; + case QUERY: + break; + } +} + +/* + * Handler for the -i option. + */ + /*ARGSUSED*/ +public void opt_i(int type, char *s) +{ + switch (type) + { + case TOGGLE: + chg_caseless(); + break; + case QUERY: + case INIT: + break; + } +} + +/* + * Handler for the -V option. + */ + /*ARGSUSED*/ +public void opt__V(int type, char *s) +{ + switch (type) + { + case TOGGLE: + case QUERY: + dispversion(); + break; + case INIT: + set_output(1); /* Force output to stdout per GNU standard for --version output. */ + putstr("less "); + putstr(version); + putstr(" ("); + putstr(pattern_lib_name()); + putstr(" regular expressions)\n"); + { + char constant *copyright = + "Copyright (C) 1984-2023 Mark Nudelman\n\n"; + putstr(copyright); + } + if (version[strlen(version)-1] == 'x') + { + putstr("** This is an EXPERIMENTAL build of the 'less' software,\n"); + putstr("** and may not function correctly.\n"); + putstr("** Obtain release builds from the web page below.\n\n"); + } +#if LESSTEST + putstr("This build supports LESSTEST.\n"); +#endif /*LESSTEST*/ + putstr("less comes with NO WARRANTY, to the extent permitted by law.\n"); + putstr("For information about the terms of redistribution,\n"); + putstr("see the file named README in the less distribution.\n"); + putstr("Home page: https://greenwoodsoftware.com/less\n"); + quit(QUIT_OK); + break; + } +} + +#if MSDOS_COMPILER +/* + * Parse an MSDOS color descriptor. + */ +static void colordesc(char *s, int *fg_color, int *bg_color) +{ + int fg, bg; +#if MSDOS_COMPILER==WIN32C + int ul = 0; + + if (*s == 'u') + { + ul = COMMON_LVB_UNDERSCORE; + s++; + if (*s == '\0') + { + *fg_color = nm_fg_color | ul; + *bg_color = nm_bg_color; + return; + } + } +#endif + if (parse_color(s, &fg, &bg) == CT_NULL) + { + PARG p; + p.p_string = s; + error("Invalid color string \"%s\"", &p); + } else + { + if (fg == CV_NOCHANGE) + fg = nm_fg_color; + if (bg == CV_NOCHANGE) + bg = nm_bg_color; +#if MSDOS_COMPILER==WIN32C + fg |= ul; +#endif + *fg_color = fg; + *bg_color = bg; + } +} +#endif + +static int color_from_namechar(char namechar) +{ + switch (namechar) + { + case 'B': return AT_COLOR_BIN; + case 'C': return AT_COLOR_CTRL; + case 'E': return AT_COLOR_ERROR; + case 'H': return AT_COLOR_HEADER; + case 'M': return AT_COLOR_MARK; + case 'N': return AT_COLOR_LINENUM; + case 'P': return AT_COLOR_PROMPT; + case 'R': return AT_COLOR_RSCROLL; + case 'S': return AT_COLOR_SEARCH; + case 'W': case 'A': return AT_COLOR_ATTN; + case 'n': return AT_NORMAL; + case 's': return AT_STANDOUT; + case 'd': return AT_BOLD; + case 'u': return AT_UNDERLINE; + case 'k': return AT_BLINK; + default: + if (namechar >= '1' && namechar <= '0'+NUM_SEARCH_COLORS) + return AT_COLOR_SUBSEARCH(namechar-'0'); + return -1; + } +} + +/* + * Handler for the -D option. + */ + /*ARGSUSED*/ +public void opt_D(int type, char *s) +{ + PARG p; + int attr; + + switch (type) + { + case INIT: + case TOGGLE: +#if MSDOS_COMPILER + if (*s == 'a') + { + sgr_mode = !sgr_mode; + break; + } +#endif + attr = color_from_namechar(s[0]); + if (attr < 0) + { + p.p_char = s[0]; + error("Invalid color specifier '%c'", &p); + return; + } + if (!use_color && (attr & AT_COLOR)) + { + error("Set --use-color before changing colors", NULL_PARG); + return; + } + s++; +#if MSDOS_COMPILER + if (!(attr & AT_COLOR)) + { + switch (attr) + { + case AT_NORMAL: + colordesc(s, &nm_fg_color, &nm_bg_color); + break; + case AT_BOLD: + colordesc(s, &bo_fg_color, &bo_bg_color); + break; + case AT_UNDERLINE: + colordesc(s, &ul_fg_color, &ul_bg_color); + break; + case AT_BLINK: + colordesc(s, &bl_fg_color, &bl_bg_color); + break; + case AT_STANDOUT: + colordesc(s, &so_fg_color, &so_bg_color); + break; + } + if (type == TOGGLE) + { + at_enter(AT_STANDOUT); + at_exit(); + } + } else +#endif + if (set_color_map(attr, s) < 0) + { + p.p_string = s; + error("Invalid color string \"%s\"", &p); + return; + } + break; +#if MSDOS_COMPILER + case QUERY: + p.p_string = (sgr_mode) ? "on" : "off"; + error("SGR mode is %s", &p); + break; +#endif + } +} + +/* + */ +public void set_tabs(char *s, int len) +{ + int i; + char *es = s + len; + /* Start at 1 because tabstops[0] is always zero. */ + for (i = 1; i < TABSTOP_MAX; ) + { + int n = 0; + int v = FALSE; + while (s < es && *s == ' ') + s++; + for (; s < es && *s >= '0' && *s <= '9'; s++) + { + v |= ckd_mul(&n, n, 10); + v |= ckd_add(&n, n, *s - '0'); + } + if (!v && n > tabstops[i-1]) + tabstops[i++] = n; + while (s < es && *s == ' ') + s++; + if (s == es || *s++ != ',') + break; + } + if (i < 2) + return; + ntabstops = i; + tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2]; +} + +/* + * Handler for the -x option. + */ +public void opt_x(int type, char *s) +{ + char msg[60+((INT_STRLEN_BOUND(int)+1)*TABSTOP_MAX)]; + int i; + PARG p; + + switch (type) + { + case INIT: + case TOGGLE: + set_tabs(s, strlen(s)); + break; + case QUERY: + strcpy(msg, "Tab stops "); + if (ntabstops > 2) + { + for (i = 1; i < ntabstops; i++) + { + if (i > 1) + strcat(msg, ","); + sprintf(msg+strlen(msg), "%d", tabstops[i]); + } + sprintf(msg+strlen(msg), " and then "); + } + sprintf(msg+strlen(msg), "every %d spaces", + tabdefault); + p.p_string = msg; + error("%s", &p); + break; + } +} + + +/* + * Handler for the -" option. + */ +public void opt_quote(int type, char *s) +{ + char buf[3]; + PARG parg; + + switch (type) + { + case INIT: + case TOGGLE: + if (s[0] == '\0') + { + openquote = closequote = '\0'; + break; + } + if (s[1] != '\0' && s[2] != '\0') + { + error("-\" must be followed by 1 or 2 chars", NULL_PARG); + return; + } + openquote = s[0]; + if (s[1] == '\0') + closequote = openquote; + else + closequote = s[1]; + break; + case QUERY: + buf[0] = openquote; + buf[1] = closequote; + buf[2] = '\0'; + parg.p_string = buf; + error("quotes %s", &parg); + break; + } +} + +/* + * Handler for the --rscroll option. + */ + /*ARGSUSED*/ +public void opt_rscroll(int type, char *s) +{ + PARG p; + + switch (type) + { + case INIT: + case TOGGLE: { + char *fmt; + int attr = AT_STANDOUT; + setfmt(s, &fmt, &attr, "*s>", FALSE); + if (strcmp(fmt, "-") == 0) + { + rscroll_char = 0; + } else + { + rscroll_char = *fmt ? *fmt : '>'; + rscroll_attr = attr|AT_COLOR_RSCROLL; + } + break; } + case QUERY: { + p.p_string = rscroll_char ? prchar(rscroll_char) : "-"; + error("rscroll character is %s", &p); + break; } + } +} + +/* + * "-?" means display a help message. + * If from the command line, exit immediately. + */ + /*ARGSUSED*/ +public void opt_query(int type, char *s) +{ + switch (type) + { + case QUERY: + case TOGGLE: + error("Use \"h\" for help", NULL_PARG); + break; + case INIT: + dohelp = 1; + } +} + +/* + * Handler for the --mouse option. + */ + /*ARGSUSED*/ +public void opt_mousecap(int type, char *s) +{ + switch (type) + { + case TOGGLE: + if (mousecap == OPT_OFF) + deinit_mouse(); + else + init_mouse(); + break; + case INIT: + case QUERY: + break; + } +} + +/* + * Handler for the --wheel-lines option. + */ + /*ARGSUSED*/ +public void opt_wheel_lines(int type, char *s) +{ + switch (type) + { + case INIT: + case TOGGLE: + if (wheel_lines <= 0) + wheel_lines = default_wheel_lines(); + break; + case QUERY: + break; + } +} + +/* + * Handler for the --line-number-width option. + */ + /*ARGSUSED*/ +public void opt_linenum_width(int type, char *s) +{ + PARG parg; + + switch (type) + { + case INIT: + case TOGGLE: + if (linenum_width > MAX_LINENUM_WIDTH) + { + parg.p_int = MAX_LINENUM_WIDTH; + error("Line number width must not be larger than %d", &parg); + linenum_width = MIN_LINENUM_WIDTH; + } + break; + case QUERY: + break; + } +} + +/* + * Handler for the --status-column-width option. + */ + /*ARGSUSED*/ +public void opt_status_col_width(int type, char *s) +{ + PARG parg; + + switch (type) + { + case INIT: + case TOGGLE: + if (status_col_width > MAX_STATUSCOL_WIDTH) + { + parg.p_int = MAX_STATUSCOL_WIDTH; + error("Status column width must not be larger than %d", &parg); + status_col_width = 2; + } + break; + case QUERY: + break; + } +} + +/* + * Handler for the --file-size option. + */ + /*ARGSUSED*/ +public void opt_filesize(int type, char *s) +{ + switch (type) + { + case INIT: + case TOGGLE: + if (want_filesize && curr_ifile != NULL && ch_length() == NULL_POSITION) + scan_eof(); + break; + case QUERY: + break; + } +} + +/* + * Handler for the --intr option. + */ + /*ARGSUSED*/ +public void opt_intr(int type, char *s) +{ + PARG p; + + switch (type) + { + case INIT: + case TOGGLE: + intr_char = *s; + if (intr_char == '^' && s[1] != '\0') + intr_char = CONTROL(s[1]); + break; + case QUERY: { + p.p_string = prchar(intr_char); + error("interrupt character is %s", &p); + break; } + } +} + +/* + * Handler for the --header option. + */ + /*ARGSUSED*/ +public void opt_header(int type, char *s) +{ + int err; + int n; + + switch (type) + { + case INIT: + case TOGGLE: + header_lines = 0; + header_cols = 0; + if (*s != ',') + { + n = getnum(&s, "header", &err); + if (err) + { + error("invalid number of lines", NULL_PARG); + return; + } + header_lines = n; + } + if (*s == ',') + { + ++s; + n = getnum(&s, "header", &err); + if (err) + error("invalid number of columns", NULL_PARG); + else + header_cols = n; + } + break; + case QUERY: + { + char buf[2*INT_STRLEN_BOUND(int)+2]; + PARG parg; + SNPRINTF2(buf, sizeof(buf), "%d,%d", header_lines, header_cols); + parg.p_string = buf; + error("header (lines,columns) is %s", &parg); + } + break; + } +} + +/* + * Handler for the --search-options option. + */ + /*ARGSUSED*/ +public void opt_search_type(int type, char *s) +{ + int st; + PARG parg; + char buf[16]; + char *bp; + int i; + + switch (type) + { + case INIT: + case TOGGLE: + st = 0; + for (; *s != '\0'; s++) + { + switch (*s) + { + case 'E': case 'e': case CONTROL('E'): st |= SRCH_PAST_EOF; break; + case 'F': case 'f': case CONTROL('F'): st |= SRCH_FIRST_FILE; break; + case 'K': case 'k': case CONTROL('K'): st |= SRCH_NO_MOVE; break; + case 'N': case 'n': case CONTROL('N'): st |= SRCH_NO_MATCH; break; + case 'R': case 'r': case CONTROL('R'): st |= SRCH_NO_REGEX; break; + case 'W': case 'w': case CONTROL('W'): st |= SRCH_WRAP; break; + case '-': st = 0; break; + case '^': break; + default: + if (*s >= '1' && *s <= '0'+NUM_SEARCH_COLORS) + { + st |= SRCH_SUBSEARCH(*s-'0'); + break; + } + parg.p_char = *s; + error("invalid search option '%c'", &parg); + return; + } + } + def_search_type = norm_search_type(st); + break; + case QUERY: + bp = buf; + if (def_search_type & SRCH_PAST_EOF) *bp++ = 'E'; + if (def_search_type & SRCH_FIRST_FILE) *bp++ = 'F'; + if (def_search_type & SRCH_NO_MOVE) *bp++ = 'K'; + if (def_search_type & SRCH_NO_MATCH) *bp++ = 'N'; + if (def_search_type & SRCH_NO_REGEX) *bp++ = 'R'; + if (def_search_type & SRCH_WRAP) *bp++ = 'W'; + for (i = 1; i <= NUM_SEARCH_COLORS; i++) + if (def_search_type & SRCH_SUBSEARCH(i)) + *bp++ = '0'+i; + if (bp == buf) + *bp++ = '-'; + *bp = '\0'; + parg.p_string = buf; + error("search options: %s", &parg); + break; + } +} + +#if LESSTEST +/* + * Handler for the --tty option. + */ + /*ARGSUSED*/ +public void opt_ttyin_name(int type, char *s) +{ + switch (type) + { + case INIT: + ttyin_name = s; + is_tty = 1; + break; + } +} +#endif /*LESSTEST*/ + +public int chop_line(void) +{ + return (chopline || header_cols > 0 || header_lines > 0); +} + +/* + * Get the "screen window" size. + */ +public int get_swindow(void) +{ + if (swindow > 0) + return (swindow); + return (sc_height - header_lines + swindow); +} + diff --git a/third_party/less/option.c b/third_party/less/option.c new file mode 100644 index 000000000..c0fbb566c --- /dev/null +++ b/third_party/less/option.c @@ -0,0 +1,688 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * Process command line options. + * + * Each option is a single letter which controls a program variable. + * The options have defaults which may be changed via + * the command line option, toggled via the "-" command, + * or queried via the "_" command. + */ + +#include "less.h" +#include "option.h" + +static struct loption *pendopt; +public int plusoption = FALSE; + +static char *optstring(char *s, char **p_str, char *printopt, char *validchars); +static int flip_triple(int val, int lc); + +extern int screen_trashed; +extern int less_is_more; +extern int quit_at_eof; +extern char *every_first_cmd; +extern int opt_use_backslash; + +/* + * Return a printable description of an option. + */ +static char * opt_desc(struct loption *o) +{ + static char buf[OPTNAME_MAX + 10]; + if (o->oletter == OLETTER_NONE) + SNPRINTF1(buf, sizeof(buf), "--%s", o->onames->oname); + else + SNPRINTF2(buf, sizeof(buf), "-%c (--%s)", o->oletter, o->onames->oname); + return (buf); +} + +/* + * Return a string suitable for printing as the "name" of an option. + * For example, if the option letter is 'x', just return "-x". + */ +public char * propt(int c) +{ + static char buf[MAX_PRCHAR_LEN+2]; + + sprintf(buf, "-%s", prchar(c)); + return (buf); +} + +/* + * Scan an argument (either from the command line or from the + * LESS environment variable) and process it. + */ +public void scan_option(char *s) +{ + struct loption *o; + int optc; + char *optname; + char *printopt; + char *str; + int set_default; + int lc; + int err; + PARG parg; + + if (s == NULL) + return; + + /* + * If we have a pending option which requires an argument, + * handle it now. + * This happens if the previous option was, for example, "-P" + * without a following string. In that case, the current + * option is simply the argument for the previous option. + */ + if (pendopt != NULL) + { + switch (pendopt->otype & OTYPE) + { + case STRING: + (*pendopt->ofunc)(INIT, s); + break; + case NUMBER: + printopt = opt_desc(pendopt); + *(pendopt->ovar) = getnum(&s, printopt, (int*)NULL); + break; + } + pendopt = NULL; + return; + } + + set_default = FALSE; + optname = NULL; + + while (*s != '\0') + { + /* + * Check some special cases first. + */ + switch (optc = *s++) + { + case ' ': + case '\t': + case END_OPTION_STRING: + continue; + case '-': + /* + * "--" indicates an option name instead of a letter. + */ + if (*s == '-') + { + optname = ++s; + break; + } + /* + * "-+" means set these options back to their defaults. + * (They may have been set otherwise by previous + * options.) + */ + set_default = (*s == '+'); + if (set_default) + s++; + continue; + case '+': + /* + * An option prefixed by a "+" is ungotten, so + * that it is interpreted as less commands + * processed at the start of the first input file. + * "++" means process the commands at the start of + * EVERY input file. + */ + plusoption = TRUE; + s = optstring(s, &str, propt('+'), NULL); + if (s == NULL) + return; + if (*str == '+') + { + if (every_first_cmd != NULL) + free(every_first_cmd); + every_first_cmd = save(str+1); + } else + { + ungetsc(str); + ungetcc_back(CHAR_END_COMMAND); + } + free(str); + continue; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + /* + * Special "more" compatibility form "-" + * instead of -z to set the scrolling + * window size. + */ + s--; + optc = 'z'; + break; + case 'n': + if (less_is_more) + optc = 'z'; + break; + } + + /* + * Not a special case. + * Look up the option letter in the option table. + */ + err = 0; + if (optname == NULL) + { + printopt = propt(optc); + lc = ASCII_IS_LOWER(optc); + o = findopt(optc); + } else + { + printopt = optname; + lc = ASCII_IS_LOWER(optname[0]); + o = findopt_name(&optname, NULL, &err); + s = optname; + optname = NULL; + if (*s == '\0' || *s == ' ') + { + /* + * The option name matches exactly. + */ + ; + } else if (*s == '=') + { + /* + * The option name is followed by "=value". + */ + if (o != NULL && + (o->otype & OTYPE) != STRING && + (o->otype & OTYPE) != NUMBER) + { + parg.p_string = printopt; + error("The %s option should not be followed by =", + &parg); + return; + } + s++; + } else + { + /* + * The specified name is longer than the + * real option name. + */ + o = NULL; + } + } + if (o == NULL) + { + parg.p_string = printopt; + if (err == OPT_AMBIG) + error("%s is an ambiguous abbreviation (\"less --help\" for help)", + &parg); + else + error("There is no %s option (\"less --help\" for help)", + &parg); + return; + } + + str = NULL; + switch (o->otype & OTYPE) + { + case BOOL: + if (set_default) + *(o->ovar) = o->odefault; + else + *(o->ovar) = ! o->odefault; + break; + case TRIPLE: + if (set_default) + *(o->ovar) = o->odefault; + else + *(o->ovar) = flip_triple(o->odefault, lc); + break; + case STRING: + if (*s == '\0') + { + /* + * Set pendopt and return. + * We will get the string next time + * scan_option is called. + */ + pendopt = o; + return; + } + /* + * Don't do anything here. + * All processing of STRING options is done by + * the handling function. + */ + while (*s == ' ') + s++; + s = optstring(s, &str, printopt, o->odesc[1]); + if (s == NULL) + return; + break; + case NUMBER: + if (*s == '\0') + { + pendopt = o; + return; + } + *(o->ovar) = getnum(&s, printopt, (int*)NULL); + break; + } + /* + * If the option has a handling function, call it. + */ + if (o->ofunc != NULL) + (*o->ofunc)(INIT, str); + if (str != NULL) + free(str); + } +} + +/* + * Toggle command line flags from within the program. + * Used by the "-" and "_" commands. + * how_toggle may be: + * OPT_NO_TOGGLE just report the current setting, without changing it. + * OPT_TOGGLE invert the current setting + * OPT_UNSET set to the default value + * OPT_SET set to the inverse of the default value + */ +public void toggle_option(struct loption *o, int lower, char *s, int how_toggle) +{ + int num; + int no_prompt; + int err; + PARG parg; + + no_prompt = (how_toggle & OPT_NO_PROMPT); + how_toggle &= ~OPT_NO_PROMPT; + + if (o == NULL) + { + error("No such option", NULL_PARG); + return; + } + + if (how_toggle == OPT_TOGGLE && (o->otype & NO_TOGGLE)) + { + parg.p_string = opt_desc(o); + error("Cannot change the %s option", &parg); + return; + } + + if (how_toggle == OPT_NO_TOGGLE && (o->otype & NO_QUERY)) + { + parg.p_string = opt_desc(o); + error("Cannot query the %s option", &parg); + return; + } + + /* + * Check for something which appears to be a do_toggle + * (because the "-" command was used), but really is not. + * This could be a string option with no string, or + * a number option with no number. + */ + switch (o->otype & OTYPE) + { + case STRING: + case NUMBER: + if (how_toggle == OPT_TOGGLE && *s == '\0') + how_toggle = OPT_NO_TOGGLE; + break; + } + +#if HILITE_SEARCH + if (how_toggle != OPT_NO_TOGGLE && (o->otype & HL_REPAINT)) + repaint_hilite(0); +#endif + + /* + * Now actually toggle (change) the variable. + */ + if (how_toggle != OPT_NO_TOGGLE) + { + switch (o->otype & OTYPE) + { + case BOOL: + /* + * Boolean. + */ + switch (how_toggle) + { + case OPT_TOGGLE: + *(o->ovar) = ! *(o->ovar); + break; + case OPT_UNSET: + *(o->ovar) = o->odefault; + break; + case OPT_SET: + *(o->ovar) = ! o->odefault; + break; + } + break; + case TRIPLE: + /* + * Triple: + * If user gave the lower case letter, then switch + * to 1 unless already 1, in which case make it 0. + * If user gave the upper case letter, then switch + * to 2 unless already 2, in which case make it 0. + */ + switch (how_toggle) + { + case OPT_TOGGLE: + *(o->ovar) = flip_triple(*(o->ovar), lower); + break; + case OPT_UNSET: + *(o->ovar) = o->odefault; + break; + case OPT_SET: + *(o->ovar) = flip_triple(o->odefault, lower); + break; + } + break; + case STRING: + /* + * String: don't do anything here. + * The handling function will do everything. + */ + switch (how_toggle) + { + case OPT_SET: + case OPT_UNSET: + error("Cannot use \"-+\" or \"--\" for a string option", + NULL_PARG); + return; + } + break; + case NUMBER: + /* + * Number: set the variable to the given number. + */ + switch (how_toggle) + { + case OPT_TOGGLE: + num = getnum(&s, NULL, &err); + if (!err) + *(o->ovar) = num; + break; + case OPT_UNSET: + *(o->ovar) = o->odefault; + break; + case OPT_SET: + error("Can't use \"-!\" for a numeric option", + NULL_PARG); + return; + } + break; + } + } + + /* + * Call the handling function for any special action + * specific to this option. + */ + if (o->ofunc != NULL) + (*o->ofunc)((how_toggle==OPT_NO_TOGGLE) ? QUERY : TOGGLE, s); + +#if HILITE_SEARCH + if (how_toggle != OPT_NO_TOGGLE && (o->otype & HL_REPAINT)) + chg_hilite(); +#endif + + if (!no_prompt) + { + /* + * Print a message describing the new setting. + */ + switch (o->otype & OTYPE) + { + case BOOL: + case TRIPLE: + /* + * Print the odesc message. + */ + error(o->odesc[*(o->ovar)], NULL_PARG); + break; + case NUMBER: + /* + * The message is in odesc[1] and has a %d for + * the value of the variable. + */ + parg.p_int = *(o->ovar); + error(o->odesc[1], &parg); + break; + case STRING: + /* + * Message was already printed by the handling function. + */ + break; + } + } + + if (how_toggle != OPT_NO_TOGGLE && (o->otype & REPAINT)) + screen_trashed = TRUE; +} + +/* + * "Toggle" a triple-valued option. + */ +static int flip_triple(int val, int lc) +{ + if (lc) + return ((val == OPT_ON) ? OPT_OFF : OPT_ON); + else + return ((val == OPT_ONPLUS) ? OPT_OFF : OPT_ONPLUS); +} + +/* + * Determine if an option takes a parameter. + */ +public int opt_has_param(struct loption *o) +{ + if (o == NULL) + return (0); + if (o->otype & (BOOL|TRIPLE|NOVAR|NO_TOGGLE)) + return (0); + return (1); +} + +/* + * Return the prompt to be used for a given option letter. + * Only string and number valued options have prompts. + */ +public char * opt_prompt(struct loption *o) +{ + if (o == NULL || (o->otype & (STRING|NUMBER)) == 0) + return ("?"); + return (o->odesc[0]); +} + +/* + * If the specified option can be toggled, return NULL. + * Otherwise return an appropriate error message. + */ +public char * opt_toggle_disallowed(int c) +{ + switch (c) + { + case 'o': + if (ch_getflags() & CH_CANSEEK) + return "Input is not a pipe"; + break; + } + return NULL; +} + +/* + * Return whether or not there is a string option pending; + * that is, if the previous option was a string-valued option letter + * (like -P) without a following string. + * In that case, the current option is taken to be the string for + * the previous option. + */ +public int isoptpending(void) +{ + return (pendopt != NULL); +} + +/* + * Print error message about missing string. + */ +static void nostring(char *printopt) +{ + PARG parg; + parg.p_string = printopt; + error("Value is required after %s", &parg); +} + +/* + * Print error message if a STRING type option is not followed by a string. + */ +public void nopendopt(void) +{ + nostring(opt_desc(pendopt)); +} + +/* + * Scan to end of string or to an END_OPTION_STRING character. + * In the latter case, replace the char with a null char. + * Return a pointer to the remainder of the string, if any. + */ +static char * optstring(char *s, char **p_str, char *printopt, char *validchars) +{ + char *p; + char *out; + + if (*s == '\0') + { + nostring(printopt); + return (NULL); + } + /* Alloc could be more than needed, but not worth trimming. */ + *p_str = (char *) ecalloc(strlen(s)+1, sizeof(char)); + out = *p_str; + + for (p = s; *p != '\0'; p++) + { + if (opt_use_backslash && *p == '\\' && p[1] != '\0') + { + /* Take next char literally. */ + ++p; + } else + { + if (*p == END_OPTION_STRING || + (validchars != NULL && strchr(validchars, *p) == NULL)) + /* End of option string. */ + break; + } + *out++ = *p; + } + *out = '\0'; + return (p); +} + +/* + */ +static int num_error(char *printopt, int *errp, int overflow) +{ + PARG parg; + + if (errp != NULL) + { + *errp = TRUE; + return (-1); + } + if (printopt != NULL) + { + parg.p_string = printopt; + error((overflow + ? "Number too large in '%s'" + : "Number is required after %s"), + &parg); + } + return (-1); +} + +/* + * Translate a string into a number. + * Like atoi(), but takes a pointer to a char *, and updates + * the char * to point after the translated number. + */ +public int getnum(char **sp, char *printopt, int *errp) +{ + char *s; + int n; + int neg; + + s = skipsp(*sp); + neg = FALSE; + if (*s == '-') + { + neg = TRUE; + s++; + } + if (*s < '0' || *s > '9') + return (num_error(printopt, errp, FALSE)); + + n = lstrtoi(s, sp, 10); + if (n < 0) + return (num_error(printopt, errp, TRUE)); + if (errp != NULL) + *errp = FALSE; + if (neg) + n = -n; + return (n); +} + +/* + * Translate a string into a fraction, represented by the part of a + * number which would follow a decimal point. + * The value of the fraction is returned as parts per NUM_FRAC_DENOM. + * That is, if "n" is returned, the fraction intended is n/NUM_FRAC_DENOM. + */ +public long getfraction(char **sp, char *printopt, int *errp) +{ + char *s; + long frac = 0; + int fraclen = 0; + + s = skipsp(*sp); + if (*s < '0' || *s > '9') + return (num_error(printopt, errp, FALSE)); + + for ( ; *s >= '0' && *s <= '9'; s++) + { + if (NUM_LOG_FRAC_DENOM <= fraclen) + continue; + frac = (frac * 10) + (*s - '0'); + fraclen++; + } + while (fraclen++ < NUM_LOG_FRAC_DENOM) + frac *= 10; + *sp = s; + if (errp != NULL) + *errp = FALSE; + return (frac); +} + + +/* + * Get the value of the -e flag. + */ +public int get_quit_at_eof(void) +{ + if (!less_is_more) + return quit_at_eof; + /* When less_is_more is set, the -e flag semantics are different. */ + return quit_at_eof ? OPT_ONPLUS : OPT_ON; +} diff --git a/third_party/less/option.h b/third_party/less/option.h new file mode 100644 index 000000000..afde744c5 --- /dev/null +++ b/third_party/less/option.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +#define END_OPTION_STRING ('$') + +/* + * Types of options. + */ +#define BOOL 01 /* Boolean option: 0 or 1 */ +#define TRIPLE 02 /* Triple-valued option: 0, 1 or 2 */ +#define NUMBER 04 /* Numeric option */ +#define STRING 010 /* String-valued option */ +#define NOVAR 020 /* No associated variable */ +#define REPAINT 040 /* Repaint screen after toggling option */ +#define NO_TOGGLE 0100 /* Option cannot be toggled with "-" cmd */ +#define HL_REPAINT 0200 /* Repaint hilites after toggling option */ +#define NO_QUERY 0400 /* Option cannot be queried with "_" cmd */ +#define INIT_HANDLER 01000 /* Call option handler function at startup */ + +#define OTYPE (BOOL|TRIPLE|NUMBER|STRING|NOVAR) + +#define OLETTER_NONE '\1' /* Invalid option letter */ + +/* + * Argument to a handling function tells what type of activity: + */ +#define INIT 0 /* Initialization (from command line) */ +#define QUERY 1 /* Query (from _ or - command) */ +#define TOGGLE 2 /* Change value (from - command) */ + +/* Flag to toggle_option to specify how to "toggle" */ +#define OPT_NO_TOGGLE 0 +#define OPT_TOGGLE 1 +#define OPT_UNSET 2 +#define OPT_SET 3 +#define OPT_NO_PROMPT 0100 + +/* Error code from findopt_name */ +#define OPT_AMBIG 1 + +struct optname +{ + char *oname; /* Long (GNU-style) option name */ + struct optname *onext; /* List of synonymous option names */ +}; + +#define OPTNAME_MAX 32 /* Max length of long option name */ + +struct loption +{ + char oletter; /* The controlling letter (a-z) */ + struct optname *onames; /* Long (GNU-style) option name */ + int otype; /* Type of the option */ + int odefault; /* Default value */ + int *ovar; /* Pointer to the associated variable */ + void (*ofunc)(int, char*); /* Pointer to special handling function */ + char *odesc[3]; /* Description of each value */ +}; + diff --git a/third_party/less/opttbl.c b/third_party/less/opttbl.c new file mode 100644 index 000000000..9e4aa2aaa --- /dev/null +++ b/third_party/less/opttbl.c @@ -0,0 +1,861 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * The option table. + */ + +#include "less.h" +#include "option.h" + +/* + * Variables controlled by command line options. + */ +public int quiet; /* Should we suppress the audible bell? */ +public int no_vbell; /* Should we suppress the visual bell? */ +public int how_search; /* Where should forward searches start? */ +public int top_scroll; /* Repaint screen from top? + (alternative is scroll from bottom) */ +public int pr_type; /* Type of prompt (short, medium, long) */ +public int bs_mode; /* How to process backspaces */ +public int know_dumb; /* Don't complain about dumb terminals */ +public int quit_at_eof; /* Quit after hitting end of file twice */ +public int quit_if_one_screen; /* Quit if EOF on first screen */ +public int squeeze; /* Squeeze multiple blank lines into one */ +public int tabstop; /* Tab settings */ +public int back_scroll; /* Repaint screen on backwards movement */ +public int forw_scroll; /* Repaint screen on forward movement */ +public int caseless; /* Do "caseless" searches */ +public int linenums; /* Use line numbers */ +public int autobuf; /* Automatically allocate buffers as needed */ +public int bufspace; /* Max buffer space per file (K) */ +public int ctldisp; /* Send control chars to screen untranslated */ +public int force_open; /* Open the file even if not regular file */ +public int swindow; /* Size of scrolling window */ +public int jump_sline; /* Screen line of "jump target" */ +public long jump_sline_fraction = -1; +public long shift_count_fraction = -1; +public int chopline; /* Truncate displayed lines at screen width */ +public int wordwrap; /* Wrap lines at space */ +public int no_init; /* Disable sending ti/te termcap strings */ +public int no_keypad; /* Disable sending ks/ke termcap strings */ +public int twiddle; /* Show tildes after EOF */ +public int show_attn; /* Hilite first unread line */ +public int shift_count; /* Number of positions to shift horizontally */ +public int status_col; /* Display a status column */ +public int use_lessopen; /* Use the LESSOPEN filter */ +public int quit_on_intr; /* Quit on interrupt */ +public int follow_mode; /* F cmd Follows file desc or file name? */ +public int oldbot; /* Old bottom of screen behavior {{REMOVE}} */ +public int opt_use_backslash; /* Use backslash escaping in option parsing */ +public char rscroll_char; /* Char which marks chopped lines with -S */ +public int rscroll_attr; /* Attribute of rscroll_char */ +public int no_hist_dups; /* Remove dups from history list */ +public int mousecap; /* Allow mouse for scrolling */ +public int wheel_lines; /* Number of lines to scroll on mouse wheel scroll */ +public int perma_marks; /* Save marks in history file */ +public int linenum_width; /* Width of line numbers */ +public int status_col_width; /* Width of status column */ +public int incr_search; /* Incremental search */ +public int use_color; /* Use UI color */ +public int want_filesize; /* Scan to EOF if necessary to get file size */ +public int status_line; /* Highlight entire marked lines */ +public int header_lines; /* Freeze header lines at top of screen */ +public int header_cols; /* Freeze header columns at left of screen */ +public int nonum_headers; /* Don't give headers line numbers */ +public int nosearch_headers; /* Don't search in header lines or columns */ +public int redraw_on_quit; /* Redraw last screen after term deinit */ +public int def_search_type; /* */ +public int exit_F_on_close; /* Exit F command when input closes */ +public int modelines; /* Lines to read looking for modelines */ +public int show_preproc_error; /* Display msg when preproc exits with error */ +public int proc_backspace; /* Special handling of backspace */ +public int proc_tab; /* Special handling of tab */ +public int proc_return; /* Special handling of carriage return */ +public char intr_char = CONTROL('X'); /* Char to interrupt reads */ +#if HILITE_SEARCH +public int hilite_search; /* Highlight matched search patterns? */ +#endif + +public int less_is_more = 0; /* Make compatible with POSIX more */ + +/* + * Long option names. + */ +static struct optname a_optname = { "search-skip-screen", NULL }; +static struct optname b_optname = { "buffers", NULL }; +static struct optname B__optname = { "auto-buffers", NULL }; +static struct optname c_optname = { "clear-screen", NULL }; +static struct optname d_optname = { "dumb", NULL }; +static struct optname D__optname = { "color", NULL }; +static struct optname e_optname = { "quit-at-eof", NULL }; +static struct optname f_optname = { "force", NULL }; +static struct optname F__optname = { "quit-if-one-screen", NULL }; +#if HILITE_SEARCH +static struct optname g_optname = { "hilite-search", NULL }; +#endif +static struct optname h_optname = { "max-back-scroll", NULL }; +static struct optname i_optname = { "ignore-case", NULL }; +static struct optname j_optname = { "jump-target", NULL }; +static struct optname J__optname = { "status-column", NULL }; +#if USERFILE +static struct optname k_optname = { "lesskey-file", NULL }; +#if HAVE_LESSKEYSRC +static struct optname ks_optname = { "lesskey-src", NULL }; +#endif /* HAVE_LESSKEYSRC */ +#endif +static struct optname K__optname = { "quit-on-intr", NULL }; +static struct optname L__optname = { "no-lessopen", NULL }; +static struct optname m_optname = { "long-prompt", NULL }; +static struct optname n_optname = { "line-numbers", NULL }; +#if LOGFILE +static struct optname o_optname = { "log-file", NULL }; +static struct optname O__optname = { "LOG-FILE", NULL }; +#endif +static struct optname p_optname = { "pattern", NULL }; +static struct optname P__optname = { "prompt", NULL }; +static struct optname q2_optname = { "silent", NULL }; +static struct optname q_optname = { "quiet", &q2_optname }; +static struct optname r_optname = { "raw-control-chars", NULL }; +static struct optname s_optname = { "squeeze-blank-lines", NULL }; +static struct optname S__optname = { "chop-long-lines", NULL }; +#if TAGS +static struct optname t_optname = { "tag", NULL }; +static struct optname T__optname = { "tag-file", NULL }; +#endif +static struct optname u_optname = { "underline-special", NULL }; +static struct optname V__optname = { "version", NULL }; +static struct optname w_optname = { "hilite-unread", NULL }; +static struct optname x_optname = { "tabs", NULL }; +static struct optname X__optname = { "no-init", NULL }; +static struct optname y_optname = { "max-forw-scroll", NULL }; +static struct optname z_optname = { "window", NULL }; +static struct optname quote_optname = { "quotes", NULL }; +static struct optname tilde_optname = { "tilde", NULL }; +static struct optname query_optname = { "help", NULL }; +static struct optname pound_optname = { "shift", NULL }; +static struct optname keypad_optname = { "no-keypad", NULL }; +static struct optname oldbot_optname = { "old-bot", NULL }; +static struct optname follow_optname = { "follow-name", NULL }; +static struct optname use_backslash_optname = { "use-backslash", NULL }; +static struct optname rscroll_optname = { "rscroll", NULL }; +static struct optname nohistdups_optname = { "no-histdups", NULL }; +static struct optname mousecap_optname = { "mouse", NULL }; +static struct optname wheel_lines_optname = { "wheel-lines", NULL }; +static struct optname perma_marks_optname = { "save-marks", NULL }; +static struct optname linenum_width_optname = { "line-num-width", NULL }; +static struct optname status_col_width_optname = { "status-col-width", NULL }; +static struct optname incr_search_optname = { "incsearch", NULL }; +static struct optname use_color_optname = { "use-color", NULL }; +static struct optname want_filesize_optname = { "file-size", NULL }; +static struct optname status_line_optname = { "status-line", NULL }; +static struct optname header_optname = { "header", NULL }; +static struct optname nonum_headers_optname = { "no-number-headers", NULL }; +static struct optname nosearch_headers_optname = { "no-search-headers", NULL }; +static struct optname redraw_on_quit_optname = { "redraw-on-quit", NULL }; +static struct optname search_type_optname = { "search-options", NULL }; +static struct optname exit_F_on_close_optname = { "exit-follow-on-close", NULL }; +static struct optname modelines_optname = { "modelines", NULL }; +static struct optname no_vbell_optname = { "no-vbell", NULL }; +static struct optname intr_optname = { "intr", NULL }; +static struct optname wordwrap_optname = { "wordwrap", NULL }; +static struct optname show_preproc_error_optname = { "show-preproc-errors", NULL }; +static struct optname proc_backspace_optname = { "proc-backspace", NULL }; +static struct optname proc_tab_optname = { "proc-tab", NULL }; +static struct optname proc_return_optname = { "proc-return", NULL }; +#if LESSTEST +static struct optname ttyin_name_optname = { "tty", NULL }; +#endif /*LESSTEST*/ + + +/* + * Table of all options and their semantics. + * + * For BOOL and TRIPLE options, odesc[0], odesc[1], odesc[2] are + * the description of the option when set to 0, 1 or 2, respectively. + * For NUMBER options, odesc[0] is the prompt to use when entering + * a new value, and odesc[1] is the description, which should contain + * one %d which is replaced by the value of the number. + * For STRING options, odesc[0] is the prompt to use when entering + * a new value, and odesc[1], if not NULL, is the set of characters + * that are valid in the string. + */ +static struct loption option[] = +{ + { 'a', &a_optname, + TRIPLE, OPT_ONPLUS, &how_search, NULL, + { + "Search includes displayed screen", + "Search skips displayed screen", + "Search includes all of displayed screen" + } + }, + + { 'b', &b_optname, + NUMBER|INIT_HANDLER, 64, &bufspace, opt_b, + { + "Max buffer space per file (K): ", + "Max buffer space per file: %dK", + NULL + } + }, + { 'B', &B__optname, + BOOL, OPT_ON, &autobuf, NULL, + { + "Don't automatically allocate buffers", + "Automatically allocate buffers when needed", + NULL + } + }, + { 'c', &c_optname, + TRIPLE, OPT_OFF, &top_scroll, NULL, + { + "Repaint by scrolling from bottom of screen", + "Repaint by painting from top of screen", + "Repaint by painting from top of screen" + } + }, + { 'd', &d_optname, + BOOL|NO_TOGGLE, OPT_OFF, &know_dumb, NULL, + { + "Assume intelligent terminal", + "Assume dumb terminal", + NULL + } + }, + { 'D', &D__optname, + STRING|REPAINT|NO_QUERY, 0, NULL, opt_D, + { + "color desc: ", + NULL, + NULL + } + }, + { 'e', &e_optname, + TRIPLE, OPT_OFF, &quit_at_eof, NULL, + { + "Don't quit at end-of-file", + "Quit at end-of-file", + "Quit immediately at end-of-file" + } + }, + { 'f', &f_optname, + BOOL, OPT_OFF, &force_open, NULL, + { + "Open only regular files", + "Open even non-regular files", + NULL + } + }, + { 'F', &F__optname, + BOOL, OPT_OFF, &quit_if_one_screen, NULL, + { + "Don't quit if end-of-file on first screen", + "Quit if end-of-file on first screen", + NULL + } + }, +#if HILITE_SEARCH + { 'g', &g_optname, + TRIPLE|HL_REPAINT, OPT_ONPLUS, &hilite_search, NULL, + { + "Don't highlight search matches", + "Highlight matches for previous search only", + "Highlight all matches for previous search pattern", + } + }, +#endif + { 'h', &h_optname, + NUMBER, -1, &back_scroll, NULL, + { + "Backwards scroll limit: ", + "Backwards scroll limit is %d lines", + NULL + } + }, + { 'i', &i_optname, + TRIPLE|HL_REPAINT, OPT_OFF, &caseless, opt_i, + { + "Case is significant in searches", + "Ignore case in searches", + "Ignore case in searches and in patterns" + } + }, + { 'j', &j_optname, + STRING, 0, NULL, opt_j, + { + "Target line: ", + "0123456789.-", + NULL + } + }, + { 'J', &J__optname, + BOOL|REPAINT, OPT_OFF, &status_col, NULL, + { + "Don't display a status column", + "Display a status column", + NULL + } + }, +#if USERFILE + { 'k', &k_optname, + STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_k, + { NULL, NULL, NULL } + }, +#if HAVE_LESSKEYSRC + { OLETTER_NONE, &ks_optname, + STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_ks, + { NULL, NULL, NULL } + }, +#endif /* HAVE_LESSKEYSRC */ +#endif + { 'K', &K__optname, + BOOL, OPT_OFF, &quit_on_intr, NULL, + { + "Interrupt (ctrl-C) returns to prompt", + "Interrupt (ctrl-C) exits less", + NULL + } + }, + { 'L', &L__optname, + BOOL, OPT_ON, &use_lessopen, NULL, + { + "Don't use the LESSOPEN filter", + "Use the LESSOPEN filter", + NULL + } + }, + { 'm', &m_optname, + TRIPLE, OPT_OFF, &pr_type, NULL, + { + "Short prompt", + "Medium prompt", + "Long prompt" + } + }, + { 'n', &n_optname, + TRIPLE|REPAINT, OPT_ON, &linenums, NULL, + { + "Don't use line numbers", + "Use line numbers", + "Constantly display line numbers" + } + }, +#if LOGFILE + { 'o', &o_optname, + STRING, 0, NULL, opt_o, + { "log file: ", NULL, NULL } + }, + { 'O', &O__optname, + STRING, 0, NULL, opt__O, + { "Log file: ", NULL, NULL } + }, +#endif + { 'p', &p_optname, + STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_p, + { NULL, NULL, NULL } + }, + { 'P', &P__optname, + STRING, 0, NULL, opt__P, + { "prompt: ", NULL, NULL } + }, + { 'q', &q_optname, + TRIPLE, OPT_OFF, &quiet, NULL, + { + "Ring the bell for errors AND at eof/bof", + "Ring the bell for errors but not at eof/bof", + "Never ring the bell" + } + }, + { 'r', &r_optname, + TRIPLE|REPAINT, OPT_OFF, &ctldisp, NULL, + { + "Display control characters as ^X", + "Display control characters directly (not recommended)", + "Display ANSI sequences directly, other control characters as ^X" + } + }, + { 's', &s_optname, + BOOL|REPAINT, OPT_OFF, &squeeze, NULL, + { + "Display all blank lines", + "Squeeze multiple blank lines", + NULL + } + }, + { 'S', &S__optname, + BOOL|REPAINT, OPT_OFF, &chopline, NULL, + { + "Fold long lines", + "Chop long lines", + NULL + } + }, +#if TAGS + { 't', &t_optname, + STRING|NO_QUERY, 0, NULL, opt_t, + { "tag: ", NULL, NULL } + }, + { 'T', &T__optname, + STRING, 0, NULL, opt__T, + { "tags file: ", NULL, NULL } + }, +#endif + { 'u', &u_optname, + TRIPLE|REPAINT|HL_REPAINT, OPT_OFF, &bs_mode, NULL, + { + "Display underlined text in underline mode", + "Backspaces cause overstrike", + "Print backspace as ^H" + } + }, + { 'V', &V__optname, + NOVAR, 0, NULL, opt__V, + { NULL, NULL, NULL } + }, + { 'w', &w_optname, + TRIPLE|REPAINT, OPT_OFF, &show_attn, NULL, + { + "Don't highlight first unread line", + "Highlight first unread line after forward-screen", + "Highlight first unread line after any forward movement", + } + }, + { 'x', &x_optname, + STRING|REPAINT, 0, NULL, opt_x, + { + "Tab stops: ", + "0123456789,", + NULL + } + }, + { 'X', &X__optname, + BOOL|NO_TOGGLE, OPT_OFF, &no_init, NULL, + { + "Send init/deinit strings to terminal", + "Don't use init/deinit strings", + NULL + } + }, + { 'y', &y_optname, + NUMBER, -1, &forw_scroll, NULL, + { + "Forward scroll limit: ", + "Forward scroll limit is %d lines", + NULL + } + }, + { 'z', &z_optname, + NUMBER, -1, &swindow, NULL, + { + "Scroll window size: ", + "Scroll window size is %d lines", + NULL + } + }, + { '"', "e_optname, + STRING, 0, NULL, opt_quote, + { "quotes: ", NULL, NULL } + }, + { '~', &tilde_optname, + BOOL|REPAINT, OPT_ON, &twiddle, NULL, + { + "Don't show tildes after end of file", + "Show tildes after end of file", + NULL + } + }, + { '?', &query_optname, + NOVAR, 0, NULL, opt_query, + { NULL, NULL, NULL } + }, + { '#', £_optname, + STRING, 0, NULL, opt_shift, + { + "Horizontal shift: ", + "0123456789.", + NULL + } + }, + { OLETTER_NONE, &keypad_optname, + BOOL|NO_TOGGLE, OPT_OFF, &no_keypad, NULL, + { + "Use keypad mode", + "Don't use keypad mode", + NULL + } + }, + { OLETTER_NONE, &oldbot_optname, + BOOL, OPT_OFF, &oldbot, NULL, + { + "Use new bottom of screen behavior", + "Use old bottom of screen behavior", + NULL + } + }, + { OLETTER_NONE, &follow_optname, + BOOL, FOLLOW_DESC, &follow_mode, NULL, + { + "F command follows file descriptor", + "F command follows file name", + NULL + } + }, + { OLETTER_NONE, &use_backslash_optname, + BOOL, OPT_OFF, &opt_use_backslash, NULL, + { + "Use backslash escaping in command line parameters", + "Don't use backslash escaping in command line parameters", + NULL + } + }, + { OLETTER_NONE, &rscroll_optname, + STRING|REPAINT|INIT_HANDLER, 0, NULL, opt_rscroll, + { "rscroll character: ", NULL, NULL } + }, + { OLETTER_NONE, &nohistdups_optname, + BOOL, OPT_OFF, &no_hist_dups, NULL, + { + "Allow duplicates in history list", + "Remove duplicates from history list", + NULL + } + }, + { OLETTER_NONE, &mousecap_optname, + TRIPLE, OPT_OFF, &mousecap, opt_mousecap, + { + "Ignore mouse input", + "Use the mouse for scrolling", + "Use the mouse for scrolling (reverse)" + } + }, + { OLETTER_NONE, &wheel_lines_optname, + NUMBER|INIT_HANDLER, 0, &wheel_lines, opt_wheel_lines, + { + "Lines to scroll on mouse wheel: ", + "Scroll %d line(s) on mouse wheel", + NULL + } + }, + { OLETTER_NONE, &perma_marks_optname, + BOOL, OPT_OFF, &perma_marks, NULL, + { + "Don't save marks in history file", + "Save marks in history file", + NULL + } + }, + { OLETTER_NONE, &linenum_width_optname, + NUMBER|REPAINT, MIN_LINENUM_WIDTH, &linenum_width, opt_linenum_width, + { + "Line number width: ", + "Line number width is %d chars", + NULL + } + }, + { OLETTER_NONE, &status_col_width_optname, + NUMBER|REPAINT, 2, &status_col_width, opt_status_col_width, + { + "Status column width: ", + "Status column width is %d chars", + NULL + } + }, + { OLETTER_NONE, &incr_search_optname, + BOOL, OPT_OFF, &incr_search, NULL, + { + "Incremental search is off", + "Incremental search is on", + NULL + } + }, + { OLETTER_NONE, &use_color_optname, + BOOL|REPAINT, OPT_OFF, &use_color, NULL, + { + "Don't use color", + "Use color", + NULL + } + }, + { OLETTER_NONE, &want_filesize_optname, + BOOL|REPAINT, OPT_OFF, &want_filesize, opt_filesize, + { + "Don't get size of each file", + "Get size of each file", + NULL + } + }, + { OLETTER_NONE, &status_line_optname, + BOOL|REPAINT, OPT_OFF, &status_line, NULL, + { + "Don't color each line with its status column color", + "Color each line with its status column color", + NULL + } + }, + { OLETTER_NONE, &header_optname, + STRING|REPAINT, 0, NULL, opt_header, + { + "Header lines: ", + NULL, + NULL + } + }, + { OLETTER_NONE, &nonum_headers_optname, + BOOL|REPAINT, 0, &nonum_headers, NULL, + { + "Number header lines", + "Don't number header lines", + NULL + } + }, + { OLETTER_NONE, &nosearch_headers_optname, + BOOL|HL_REPAINT, 0, &nosearch_headers, NULL, + { + "Search includes header lines", + "Search does not include header lines", + NULL + } + }, + { OLETTER_NONE, &redraw_on_quit_optname, + BOOL, OPT_OFF, &redraw_on_quit, NULL, + { + "Don't redraw screen when quitting", + "Redraw last screen when quitting", + NULL + } + }, + { OLETTER_NONE, &search_type_optname, + STRING, 0, NULL, opt_search_type, + { + "Search options: ", + NULL, + NULL + } + }, + { OLETTER_NONE, &exit_F_on_close_optname, + BOOL, OPT_OFF, &exit_F_on_close, NULL, + { + "Don't exit F command when input closes", + "Exit F command when input closes", + NULL + } + }, + { OLETTER_NONE, &no_vbell_optname, + BOOL, OPT_OFF, &no_vbell, NULL, + { + "Display visual bell", + "Don't display visual bell", + NULL + } + }, + { OLETTER_NONE, &modelines_optname, + NUMBER, 0, &modelines, NULL, + { + "Lines to read looking for modelines: ", + "Read %d lines looking for modelines", + NULL + } + }, + { OLETTER_NONE, &intr_optname, + STRING, 0, NULL, opt_intr, + { "interrupt character: ", NULL, NULL } + }, + { OLETTER_NONE, &wordwrap_optname, + BOOL|REPAINT, OPT_OFF, &wordwrap, NULL, + { + "Wrap lines at any character", + "Wrap lines at spaces", + NULL + } + }, + { OLETTER_NONE, &show_preproc_error_optname, + BOOL, OPT_OFF, &show_preproc_error, NULL, + { + "Don't show error message if preprocessor fails", + "Show error message if preprocessor fails", + NULL + } + }, + { OLETTER_NONE, &proc_backspace_optname, + TRIPLE|REPAINT|HL_REPAINT, OPT_OFF, &proc_backspace, NULL, + { + "Backspace handling is specified by the -U option", + "Display underline text in underline mode", + "Print backspaces as ^H" + } + }, + { OLETTER_NONE, &proc_tab_optname, + TRIPLE|REPAINT|HL_REPAINT, OPT_OFF, &proc_tab, NULL, + { + "Tab handling is specified by the -U option", + "Expand tabs to spaces", + "Print tabs as ^I" + } + }, + { OLETTER_NONE, &proc_return_optname, + TRIPLE|REPAINT|HL_REPAINT, OPT_OFF, &proc_return, NULL, + { + "Carriage return handling is specified by the -U option", + "Delete carriage return before newline", + "Print carriage return as ^M" + } + }, +#if LESSTEST + { OLETTER_NONE, &ttyin_name_optname, + STRING|NO_TOGGLE, 0, NULL, opt_ttyin_name, + { + NULL, + NULL, + NULL + } + }, +#endif /*LESSTEST*/ + { '\0', NULL, NOVAR, 0, NULL, NULL, { NULL, NULL, NULL } } +}; + + +/* + * Initialize each option to its default value. + */ +public void init_option(void) +{ + struct loption *o; + char *p; + + p = lgetenv("LESS_IS_MORE"); + if (!isnullenv(p)) + less_is_more = 1; + + for (o = option; o->oletter != '\0'; o++) + { + /* + * Set each variable to its default. + */ + if (o->ovar != NULL) + *(o->ovar) = o->odefault; + if (o->otype & INIT_HANDLER) + (*(o->ofunc))(INIT, (char *) NULL); + } +} + +/* + * Find an option in the option table, given its option letter. + */ +public struct loption * findopt(int c) +{ + struct loption *o; + + for (o = option; o->oletter != '\0'; o++) + { + if (o->oletter == c) + return (o); + if ((o->otype & TRIPLE) && ASCII_TO_UPPER(o->oletter) == c) + return (o); + } + return (NULL); +} + +/* + * + */ +static int is_optchar(char c) +{ + if (ASCII_IS_UPPER(c)) + return 1; + if (ASCII_IS_LOWER(c)) + return 1; + if (c == '-') + return 1; + return 0; +} + +/* + * Find an option in the option table, given its option name. + * p_optname is the (possibly partial) name to look for, and + * is updated to point after the matched name. + * p_oname if non-NULL is set to point to the full option name. + */ +public struct loption * findopt_name(char **p_optname, char **p_oname, int *p_err) +{ + char *optname = *p_optname; + struct loption *o; + struct optname *oname; + int len; + int uppercase; + struct loption *maxo = NULL; + struct optname *maxoname = NULL; + int maxlen = 0; + int ambig = 0; + int exact = 0; + + /* + * Check all options. + */ + for (o = option; o->oletter != '\0'; o++) + { + /* + * Check all names for this option. + */ + for (oname = o->onames; oname != NULL; oname = oname->onext) + { + /* + * Try normal match first (uppercase == 0), + * then, then if it's a TRIPLE option, + * try uppercase match (uppercase == 1). + */ + for (uppercase = 0; uppercase <= 1; uppercase++) + { + len = sprefix(optname, oname->oname, uppercase); + if (len <= 0 || is_optchar(optname[len])) + { + /* + * We didn't use all of the option name. + */ + continue; + } + if (!exact && len == maxlen) + /* + * Already had a partial match, + * and now there's another one that + * matches the same length. + */ + ambig = 1; + else if (len > maxlen) + { + /* + * Found a better match than + * the one we had. + */ + maxo = o; + maxoname = oname; + maxlen = len; + ambig = 0; + exact = (len == (int)strlen(oname->oname)); + } + if (!(o->otype & TRIPLE)) + break; + } + } + } + if (ambig) + { + /* + * Name matched more than one option. + */ + if (p_err != NULL) + *p_err = OPT_AMBIG; + return (NULL); + } + *p_optname = optname + maxlen; + if (p_oname != NULL) + *p_oname = maxoname == NULL ? NULL : maxoname->oname; + return (maxo); +} diff --git a/third_party/less/os.c b/third_party/less/os.c new file mode 100644 index 000000000..ce881d7b8 --- /dev/null +++ b/third_party/less/os.c @@ -0,0 +1,507 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * 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 "less.h" +#include +#include +#if MSDOS_COMPILER==WIN32C +/* #include */ +#endif +#if HAVE_TIME_H +#include +#endif +#if HAVE_ERRNO_H +#include +#endif +#if HAVE_VALUES_H +#include +#endif + +#if defined(__APPLE__) +#include +#endif + +#if HAVE_POLL && !MSDOS_COMPILER +#define USE_POLL 1 +static int use_poll = TRUE; +#else +#define USE_POLL 0 +#endif +#if USE_POLL +#include +static int any_data = FALSE; +#endif + +/* + * BSD setjmp() saves (and longjmp() restores) the signal mask. + * This costs a system call or two per setjmp(), so if possible we clear the + * signal mask with sigsetmask(), and use _setjmp()/_longjmp() instead. + * On other systems, setjmp() doesn't affect the signal mask and so + * _setjmp() does not exist; we just use setjmp(). + */ +#if HAVE__SETJMP && HAVE_SIGSETMASK +#define SET_JUMP _setjmp +#define LONG_JUMP _longjmp +#else +#define SET_JUMP setjmp +#define LONG_JUMP longjmp +#endif + +public int reading; +public int waiting_for_data; +public int consecutive_nulls = 0; + +/* Milliseconds to wait for data before displaying "waiting for data" message. */ +static int waiting_for_data_delay = 4000; +static jmp_buf read_label; + +extern int sigs; +extern int ignore_eoi; +extern int exit_F_on_close; +extern int follow_mode; +extern int scanning_eof; +extern char intr_char; +#if !MSDOS_COMPILER +extern int tty; +#endif +#if LESSTEST +extern char *ttyin_name; +#endif /*LESSTEST*/ + +public void init_poll(void) +{ + char *delay = lgetenv("LESS_DATA_DELAY"); + int idelay = (delay == NULL) ? 0 : atoi(delay); + if (idelay > 0) + waiting_for_data_delay = idelay; +#if USE_POLL +#if defined(__APPLE__) + /* In old versions of MacOS, poll() does not work with /dev/tty. */ + struct utsname uts; + if (uname(&uts) < 0 || lstrtoi(uts.release, NULL, 10) < 20) + use_poll = FALSE; +#endif +#endif +} + +#if USE_POLL +/* + * Check whether data is available, either from a file/pipe or from the tty. + * Return READ_AGAIN if no data currently available, but caller should retry later. + * Return READ_INTR to abort F command (forw_loop). + * Return 0 if safe to read from fd. + */ +static int check_poll(int fd, int tty) +{ + struct pollfd poller[2] = { { fd, POLLIN, 0 }, { tty, POLLIN, 0 } }; + int timeout = (waiting_for_data && !(scanning_eof && follow_mode == FOLLOW_NAME)) ? -1 : waiting_for_data_delay; + if (!any_data) + { + /* + * Don't do polling if no data has yet been received, + * to allow a program piping data into less to have temporary + * access to the tty (like sudo asking for a password). + */ + return (0); + } + poll(poller, 2, timeout); +#if LESSTEST + if (ttyin_name == NULL) /* Check for ^X only on a real tty. */ +#endif /*LESSTEST*/ + { + if (poller[1].revents & POLLIN) + { + LWCHAR ch = getchr(); + if (ch == intr_char) + /* Break out of "waiting for data". */ + return (READ_INTR); + ungetcc_back(ch); + } + } + if (ignore_eoi && exit_F_on_close && (poller[0].revents & (POLLHUP|POLLIN)) == POLLHUP) + /* Break out of F loop on HUP due to --exit-follow-on-close. */ + return (READ_INTR); + if ((poller[0].revents & (POLLIN|POLLHUP|POLLERR)) == 0) + /* No data available; let caller take action, then try again. */ + return (READ_AGAIN); + /* There is data (or HUP/ERR) available. Safe to call read() without blocking. */ + return (0); +} +#endif /* USE_POLL */ + +public int supports_ctrl_x(void) +{ +#if USE_POLL + return (use_poll); +#else + return (FALSE); +#endif /* USE_POLL */ +} + +/* + * Like read() system call, but is deliberately interruptible. + * A call to intread() from a signal handler will interrupt + * any pending iread(). + */ +public int iread(int fd, unsigned char *buf, unsigned int len) +{ + int n; + +start: +#if MSDOS_COMPILER==WIN32C + if (ABORT_SIGS()) + return (READ_INTR); +#else +#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC + if (kbhit()) + { + int c; + + c = getch(); + if (c == '\003') + return (READ_INTR); + ungetch(c); + } +#endif +#endif + if (!reading && SET_JUMP(read_label)) + { + /* + * We jumped here from intread. + */ + reading = 0; +#if HAVE_SIGPROCMASK + { + sigset_t mask; + sigemptyset(&mask); + sigprocmask(SIG_SETMASK, &mask, NULL); + } +#else +#if HAVE_SIGSETMASK + sigsetmask(0); +#else +#ifdef _OSK + sigmask(~0); +#endif +#endif +#endif +#if !MSDOS_COMPILER + if (fd != tty && !ABORT_SIGS()) + /* Non-interrupt signal like SIGWINCH. */ + return (READ_AGAIN); +#endif + return (READ_INTR); + } + + flush(); + reading = 1; +#if MSDOS_COMPILER==DJGPPC + if (isatty(fd)) + { + /* + * Don't try reading from a TTY until a character is + * available, because that makes some background programs + * believe DOS is busy in a way that prevents those + * programs from working while "less" waits. + * {{ This code was added 12 Jan 2007; still needed? }} + */ + fd_set readfds; + + FD_ZERO(&readfds); + FD_SET(fd, &readfds); + if (select(fd+1, &readfds, 0, 0, 0) == -1) + { + reading = 0; + return (READ_ERR); + } + } +#endif +#if USE_POLL + if (fd != tty && use_poll) + { + int ret = check_poll(fd, tty); + if (ret != 0) + { + if (ret == READ_INTR) + sigs |= S_INTERRUPT; + reading = 0; + return (ret); + } + } +#else +#if MSDOS_COMPILER==WIN32C + if (win32_kbhit()) + { + int c; + + c = WIN32getch(); + if (c == intr_char) + { + sigs |= S_INTERRUPT; + reading = 0; + return (READ_INTR); + } + WIN32ungetch(c); + } +#endif +#endif + n = read(fd, buf, len); + reading = 0; +#if 1 + /* + * This is a kludge to workaround a problem on some systems + * where terminating a remote tty connection causes read() to + * start returning 0 forever, instead of -1. + */ + { + if (!ignore_eoi) + { + if (n == 0) + consecutive_nulls++; + else + consecutive_nulls = 0; + if (consecutive_nulls > 20) + quit(QUIT_ERROR); + } + } +#endif + if (n < 0) + { +#if HAVE_ERRNO + /* + * Certain values of errno indicate we should just retry the read. + */ +#if MUST_DEFINE_ERRNO + extern int errno; +#endif +#ifdef EINTR + if (errno == EINTR) + goto start; +#endif +#ifdef EAGAIN + if (errno == EAGAIN) + goto start; +#endif +#endif + return (READ_ERR); + } +#if USE_POLL + if (fd != tty && n > 0) + any_data = TRUE; +#endif + return (n); +} + +/* + * Interrupt a pending iread(). + */ +public void intread(void) +{ + LONG_JUMP(read_label, 1); +} + +/* + * Return the current time. + */ +#if HAVE_TIME +public time_type get_time(void) +{ + time_type t; + + time(&t); + return (t); +} +#endif + + +#if !HAVE_STRERROR +/* + * Local version of strerror, if not available from the system. + */ +static char * strerror(int err) +{ + static char buf[INT_STRLEN_BOUND(int)+12]; +#if HAVE_SYS_ERRLIST + extern char *sys_errlist[]; + extern int sys_nerr; + + if (err < sys_nerr) + return sys_errlist[err]; +#endif + sprintf(buf, "Error %d", err); + return buf; +} +#endif + +/* + * errno_message: Return an error message based on the value of "errno". + */ +public char * errno_message(char *filename) +{ + char *p; + char *m; + int len; +#if HAVE_ERRNO +#if MUST_DEFINE_ERRNO + extern int errno; +#endif + p = strerror(errno); +#else + p = "cannot open"; +#endif + len = (int) (strlen(filename) + strlen(p) + 3); + m = (char *) ecalloc(len, sizeof(char)); + SNPRINTF2(m, len, "%s: %s", filename, p); + return (m); +} + +/* + * Return a description of a signal. + * The return value is good until the next call to this function. + */ +public char * signal_message(int sig) +{ + static char sigbuf[sizeof("Signal ") + INT_STRLEN_BOUND(sig) + 1]; +#if HAVE_STRSIGNAL + char *description = strsignal(sig); + if (description) + return description; +#endif + sprintf(sigbuf, "Signal %d", sig); + return sigbuf; +} + +/* + * Return (VAL * NUM) / DEN, where DEN is positive + * and min(VAL, NUM) <= DEN so the result cannot overflow. + * Round to the nearest integer, breaking ties by rounding to even. + */ +public uintmax muldiv(uintmax val, uintmax num, uintmax den) +{ + /* + * Like round(val * (double) num / den), but without rounding error. + * Overflow cannot occur, so there is no need for floating point. + */ + uintmax q = val / den; + uintmax r = val % den; + uintmax qnum = q * num; + uintmax rnum = r * num; + uintmax quot = qnum + rnum / den; + uintmax rem = rnum % den; + return quot + (den / 2 < rem + (quot & ~den & 1)); +} + +/* + * Return the ratio of two POSITIONS, as a percentage. + * {{ Assumes a POSITION is a long int. }} + */ +public int percentage(POSITION num, POSITION den) +{ + return (int) muldiv(num, (POSITION) 100, den); +} + +/* + * Return the specified percentage of a POSITION. + * Assume (0 <= POS && 0 <= PERCENT <= 100 + * && 0 <= FRACTION < (PERCENT == 100 ? 1 : NUM_FRAC_DENOM)), + * so the result cannot overflow. Round to even. + */ +public POSITION percent_pos(POSITION pos, int percent, long fraction) +{ + /* + * Change from percent (parts per 100) + * to pctden (parts per 100 * NUM_FRAC_DENOM). + */ + POSITION pctden = (percent * NUM_FRAC_DENOM) + fraction; + + return (POSITION) muldiv(pos, pctden, 100 * (POSITION) NUM_FRAC_DENOM); +} + +#if !HAVE_STRCHR +/* + * strchr is used by regexp.c. + */ +char * strchr(char *s, char c) +{ + for ( ; *s != '\0'; s++) + if (*s == c) + return (s); + if (c == '\0') + return (s); + return (NULL); +} +#endif + +#if !HAVE_MEMCPY +void * memcpy(void *dst, void *src, int len) +{ + char *dstp = (char *) dst; + char *srcp = (char *) src; + int i; + + for (i = 0; i < len; i++) + dstp[i] = srcp[i]; + return (dst); +} +#endif + +#ifdef _OSK_MWC32 + +/* + * This implements an ANSI-style intercept setup for Microware C 3.2 + */ +public int os9_signal(int type, RETSIGTYPE (*handler)()) +{ + intercept(handler); +} + +#include + +int isatty(int f) +{ + struct sgbuf sgbuf; + + if (_gs_opt(f, &sgbuf) < 0) + return -1; + return (sgbuf.sg_class == 0); +} + +#endif + +public void sleep_ms(int ms) +{ +#if MSDOS_COMPILER==WIN32C + Sleep(ms); +#else +#if HAVE_NANOSLEEP + int sec = ms / 1000; + struct timespec t = { sec, (ms - sec*1000) * 1000000 }; + nanosleep(&t, NULL); +#else +#if HAVE_USLEEP + usleep(ms); +#else + sleep(ms / 1000 + (ms % 1000 != 0)); +#endif +#endif +#endif +} diff --git a/third_party/less/output.c b/third_party/less/output.c new file mode 100644 index 000000000..1127a1056 --- /dev/null +++ b/third_party/less/output.c @@ -0,0 +1,719 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * High level routines dealing with the output to the screen. + */ + +#include "less.h" +#if MSDOS_COMPILER==WIN32C +/* #include "windows.h" */ +#ifndef COMMON_LVB_UNDERSCORE +#define COMMON_LVB_UNDERSCORE 0x8000 +#endif +#endif + +public int errmsgs; /* Count of messages displayed by error() */ +public int need_clr; +public int final_attr; +public int at_prompt; + +extern int sigs; +extern int sc_width; +extern int so_s_width, so_e_width; +extern int screen_trashed; +extern int is_tty; +extern int oldbot; +extern char intr_char; + +#if MSDOS_COMPILER==WIN32C || MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC +extern int ctldisp; +extern int nm_fg_color, nm_bg_color; +extern int bo_fg_color, bo_bg_color; +extern int ul_fg_color, ul_bg_color; +extern int so_fg_color, so_bg_color; +extern int bl_fg_color, bl_bg_color; +extern int sgr_mode; +#if MSDOS_COMPILER==WIN32C +extern int vt_enabled; +#endif +#endif + +/* + * Display the line which is in the line buffer. + */ +public void put_line(void) +{ + int c; + int i; + int a; + + if (ABORT_SIGS()) + { + /* + * Don't output if a signal is pending. + */ + screen_trashed = 1; + return; + } + + final_attr = AT_NORMAL; + + for (i = 0; (c = gline(i, &a)) != '\0'; i++) + { + at_switch(a); + final_attr = a; + if (c == '\b') + putbs(); + else + putchr(c); + } + + at_exit(); +} + +static char obuf[OUTBUF_SIZE]; +static char *ob = obuf; +static int outfd = 2; /* stderr */ + +#if MSDOS_COMPILER==WIN32C || MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC +static void win_flush(void) +{ + if (ctldisp != OPT_ONPLUS || (vt_enabled && sgr_mode)) + WIN32textout(obuf, ob - obuf); + else + { + /* + * Look for SGR escape sequences, and convert them + * to color commands. Replace bold, underline, + * and italic escapes into colors specified via + * the -D command-line option. + */ + char *anchor, *p, *p_next; + static int fg, fgi, bg, bgi; + static int at; + int f, b; +#if MSDOS_COMPILER==WIN32C + /* Screen colors used by 3x and 4x SGR commands. */ + static unsigned char screen_color[] = { + 0, /* BLACK */ + FOREGROUND_RED, + FOREGROUND_GREEN, + FOREGROUND_RED|FOREGROUND_GREEN, + FOREGROUND_BLUE, + FOREGROUND_BLUE|FOREGROUND_RED, + FOREGROUND_BLUE|FOREGROUND_GREEN, + FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED + }; +#else + static enum COLORS screen_color[] = { + BLACK, RED, GREEN, BROWN, + BLUE, MAGENTA, CYAN, LIGHTGRAY + }; +#endif + + if (fg == 0 && bg == 0) + { + fg = nm_fg_color & 7; + fgi = nm_fg_color & 8; + bg = nm_bg_color & 7; + bgi = nm_bg_color & 8; + } + for (anchor = p_next = obuf; + (p_next = memchr(p_next, ESC, ob - p_next)) != NULL; ) + { + p = p_next; + if (p[1] == '[') /* "ESC-[" sequence */ + { + if (p > anchor) + { + /* + * If some chars seen since + * the last escape sequence, + * write them out to the screen. + */ + WIN32textout(anchor, p-anchor); + anchor = p; + } + p += 2; /* Skip the "ESC-[" */ + if (is_ansi_end(*p)) + { + /* + * Handle null escape sequence + * "ESC[m", which restores + * the normal color. + */ + p++; + anchor = p_next = p; + fg = nm_fg_color & 7; + fgi = nm_fg_color & 8; + bg = nm_bg_color & 7; + bgi = nm_bg_color & 8; + at = 0; + WIN32setcolors(nm_fg_color, nm_bg_color); + continue; + } + p_next = p; + at &= ~32; + + /* + * Select foreground/background colors + * based on the escape sequence. + */ + while (!is_ansi_end(*p)) + { + char *q; + long code = strtol(p, &q, 10); + + if (*q == '\0') + { + /* + * Incomplete sequence. + * Leave it unprocessed + * in the buffer. + */ + int slop = (int) (q - anchor); + /* {{ strcpy args overlap! }} */ + strcpy(obuf, anchor); + ob = &obuf[slop]; + return; + } + + if (q == p || + code > 49 || code < 0 || + (!is_ansi_end(*q) && *q != ';')) + { + p_next = q; + break; + } + if (*q == ';') + { + q++; + at |= 32; + } + + switch (code) + { + default: + /* case 0: all attrs off */ + fg = nm_fg_color & 7; + bg = nm_bg_color & 7; + at &= 32; + /* + * \e[0m use normal + * intensities, but + * \e[0;...m resets them + */ + if (at & 32) + { + fgi = 0; + bgi = 0; + } else + { + fgi = nm_fg_color & 8; + bgi = nm_bg_color & 8; + } + break; + case 1: /* bold on */ + fgi = 8; + at |= 1; + break; + case 3: /* italic on */ + case 7: /* inverse on */ + at |= 2; + break; + case 4: /* underline on */ + bgi = 8; + at |= 4; + break; + case 5: /* slow blink on */ + case 6: /* fast blink on */ + bgi = 8; + at |= 8; + break; + case 8: /* concealed on */ + at |= 16; + break; + case 22: /* bold off */ + fgi = 0; + at &= ~1; + break; + case 23: /* italic off */ + case 27: /* inverse off */ + at &= ~2; + break; + case 24: /* underline off */ + bgi = 0; + at &= ~4; + break; + case 28: /* concealed off */ + at &= ~16; + break; + case 30: case 31: case 32: + case 33: case 34: case 35: + case 36: case 37: + fg = screen_color[code - 30]; + at |= 32; + break; + case 39: /* default fg */ + fg = nm_fg_color & 7; + at |= 32; + break; + case 40: case 41: case 42: + case 43: case 44: case 45: + case 46: case 47: + bg = screen_color[code - 40]; + at |= 32; + break; + case 49: /* default bg */ + bg = nm_bg_color & 7; + at |= 32; + break; + } + p = q; + } + if (!is_ansi_end(*p) || p == p_next) + break; + /* + * In SGR mode, the ANSI sequence is + * always honored; otherwise if an attr + * is used by itself ("\e[1m" versus + * "\e[1;33m", for example), set the + * color assigned to that attribute. + */ + if (sgr_mode || (at & 32)) + { + if (at & 2) + { + f = bg | bgi; + b = fg | fgi; + } else + { + f = fg | fgi; + b = bg | bgi; + } + } else + { + if (at & 1) + { + f = bo_fg_color; + b = bo_bg_color; + } else if (at & 2) + { + f = so_fg_color; + b = so_bg_color; + } else if (at & 4) + { + f = ul_fg_color; + b = ul_bg_color; + } else if (at & 8) + { + f = bl_fg_color; + b = bl_bg_color; + } else + { + f = nm_fg_color; + b = nm_bg_color; + } + } + if (at & 16) + f = b ^ 8; +#if MSDOS_COMPILER==WIN32C + f &= 0xf | COMMON_LVB_UNDERSCORE; +#else + f &= 0xf; +#endif + b &= 0xf; + WIN32setcolors(f, b); + p_next = anchor = p + 1; + } else + p_next++; + } + + /* Output what's left in the buffer. */ + WIN32textout(anchor, ob - anchor); + } + ob = obuf; +} +#endif + +/* + * Flush buffered output. + * + * If we haven't displayed any file data yet, + * output messages on error output (file descriptor 2), + * otherwise output on standard output (file descriptor 1). + * + * 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. + */ +public void flush(void) +{ + int n; + + n = (int) (ob - obuf); + if (n == 0) + return; + ob = obuf; + +#if MSDOS_COMPILER==MSOFTC + if (interactive()) + { + obuf[n] = '\0'; + _outtext(obuf); + return; + } +#else +#if MSDOS_COMPILER==WIN32C || MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC + if (interactive()) + { + ob = obuf + n; + *ob = '\0'; + win_flush(); + return; + } +#endif +#endif + + if (write(outfd, obuf, n) != n) + screen_trashed = 1; +} + +/* + * Set the output file descriptor (1=stdout or 2=stderr). + */ +public void set_output(int fd) +{ + flush(); + outfd = fd; +} + +/* + * Output a character. + */ +public int putchr(int c) +{ +#if 0 /* fake UTF-8 output for testing */ + extern int utf_mode; + if (utf_mode) + { + static char ubuf[MAX_UTF_CHAR_LEN]; + static int ubuf_len = 0; + static int ubuf_index = 0; + if (ubuf_len == 0) + { + ubuf_len = utf_len(c); + ubuf_index = 0; + } + ubuf[ubuf_index++] = c; + if (ubuf_index < ubuf_len) + return c; + c = get_wchar(ubuf) & 0xFF; + ubuf_len = 0; + } +#endif + clear_bot_if_needed(); +#if MSDOS_COMPILER + if (c == '\n' && is_tty) + { + /* remove_top(1); */ + putchr('\r'); + } +#else +#ifdef _OSK + if (c == '\n' && is_tty) /* In OS-9, '\n' == 0x0D */ + putchr(0x0A); +#endif +#endif + /* + * Some versions of flush() write to *ob, so we must flush + * when we are still one char from the end of obuf. + */ + if (ob >= &obuf[sizeof(obuf)-1]) + flush(); + *ob++ = c; + at_prompt = 0; + return (c); +} + +public void clear_bot_if_needed(void) +{ + if (!need_clr) + return; + need_clr = 0; + clear_bot(); +} + +/* + * Output a string. + */ +public void putstr(constant char *s) +{ + while (*s != '\0') + putchr(*s++); +} + + +/* + * Convert an integral type to a string. + */ +#define TYPE_TO_A_FUNC(funcname, type) \ +void funcname(type num, char *buf, int radix) \ +{ \ + int neg = (num < 0); \ + char tbuf[INT_STRLEN_BOUND(num)+2]; \ + char *s = tbuf + sizeof(tbuf); \ + if (neg) num = -num; \ + *--s = '\0'; \ + do { \ + *--s = "0123456789ABCDEF"[num % radix]; \ + } while ((num /= radix) != 0); \ + if (neg) *--s = '-'; \ + strcpy(buf, s); \ +} + +TYPE_TO_A_FUNC(postoa, POSITION) +TYPE_TO_A_FUNC(linenumtoa, LINENUM) +TYPE_TO_A_FUNC(inttoa, int) + +/* + * Convert a string to an integral type. Return ((type) -1) on overflow. + */ +#define STR_TO_TYPE_FUNC(funcname, type) \ +type funcname(char *buf, char **ebuf, int radix) \ +{ \ + type val = 0; \ + int v = 0; \ + for (;; buf++) { \ + char c = *buf; \ + int digit = (c >= '0' && c <= '9') ? c - '0' : (c >= 'a' && c <= 'f') ? c - 'a' + 10 : (c >= 'A' && c <= 'F') ? c - 'A' + 10 : -1; \ + if (digit < 0 || digit >= radix) break; \ + v |= ckd_mul(&val, val, radix); \ + v |= ckd_add(&val, val, digit); \ + } \ + if (ebuf != NULL) *ebuf = buf; \ + return v ? -1 : val; \ +} + +STR_TO_TYPE_FUNC(lstrtopos, POSITION) +STR_TO_TYPE_FUNC(lstrtoi, int) +STR_TO_TYPE_FUNC(lstrtoul, unsigned long) + +/* + * Print an integral type. + */ +#define IPRINT_FUNC(funcname, type, typetoa) \ +static int funcname(type num, int radix) \ +{ \ + char buf[INT_STRLEN_BOUND(num)]; \ + typetoa(num, buf, radix); \ + putstr(buf); \ + return (int) strlen(buf); \ +} + +IPRINT_FUNC(iprint_int, int, inttoa) +IPRINT_FUNC(iprint_linenum, LINENUM, linenumtoa) + +/* + * This function implements printf-like functionality + * using a more portable argument list mechanism than printf's. + * + * {{ This paranoia about the portability of printf dates from experiences + * with systems in the 1980s and is of course no longer necessary. }} + */ +public int less_printf(char *fmt, PARG *parg) +{ + char *s; + int col; + + col = 0; + while (*fmt != '\0') + { + if (*fmt != '%') + { + putchr(*fmt++); + col++; + } else + { + ++fmt; + switch (*fmt++) + { + case 's': + s = parg->p_string; + parg++; + while (*s != '\0') + { + putchr(*s++); + col++; + } + break; + case 'd': + col += iprint_int(parg->p_int, 10); + parg++; + break; + case 'x': + col += iprint_int(parg->p_int, 16); + parg++; + break; + case 'n': + col += iprint_linenum(parg->p_linenum, 10); + parg++; + break; + case 'c': + s = prchar(parg->p_char); + parg++; + while (*s != '\0') + { + putchr(*s++); + col++; + } + break; + case '%': + putchr('%'); + break; + } + } + } + return (col); +} + +/* + * Get a RETURN. + * If some other non-trivial char is pressed, unget it, so it will + * become the next command. + */ +public void get_return(void) +{ + int c; + +#if ONLY_RETURN + while ((c = getchr()) != '\n' && c != '\r') + bell(); +#else + c = getchr(); + if (c != '\n' && c != '\r' && c != ' ' && c != READ_INTR) + ungetcc(c); +#endif +} + +/* + * Output a message in the lower left corner of the screen + * and wait for carriage return. + */ +public void error(char *fmt, PARG *parg) +{ + int col = 0; + static char return_to_continue[] = " (press RETURN)"; + + errmsgs++; + + if (!interactive()) + { + less_printf(fmt, parg); + putchr('\n'); + return; + } + + if (!oldbot) + squish_check(); + at_exit(); + clear_bot(); + at_enter(AT_STANDOUT|AT_COLOR_ERROR); + col += so_s_width; + col += less_printf(fmt, parg); + putstr(return_to_continue); + at_exit(); + col += sizeof(return_to_continue) + so_e_width; + + get_return(); + lower_left(); + clear_eol(); + + if (col >= 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. }} + */ + screen_trashed = 1; + + flush(); +} + +/* + * Output a message in the lower left corner of the screen + * and don't wait for carriage return. + * Usually used to warn that we are beginning a potentially + * time-consuming operation. + */ +static void ierror_suffix(char *fmt, PARG *parg, char *suffix1, char *suffix2, char *suffix3) +{ + at_exit(); + clear_bot(); + at_enter(AT_STANDOUT|AT_COLOR_ERROR); + (void) less_printf(fmt, parg); + putstr(suffix1); + putstr(suffix2); + putstr(suffix3); + at_exit(); + flush(); + need_clr = 1; +} + +public void ierror(char *fmt, PARG *parg) +{ + ierror_suffix(fmt, parg, "... (interrupt to abort)", "", ""); +} + +public void ixerror(char *fmt, PARG *parg) +{ + if (!supports_ctrl_x()) + ierror(fmt, parg); + else + ierror_suffix(fmt, parg, + "... (", prchar(intr_char), " or interrupt to abort)"); +} + +/* + * Output a message in the lower left corner of the screen + * and return a single-character response. + */ +public int query(char *fmt, PARG *parg) +{ + int c; + int col = 0; + + if (interactive()) + clear_bot(); + + (void) less_printf(fmt, parg); + c = getchr(); + + if (interactive()) + { + lower_left(); + if (col >= sc_width) + screen_trashed = 1; + flush(); + } else + { + putchr('\n'); + } + + if (c == 'Q') + quit(QUIT_OK); + return (c); +} diff --git a/third_party/less/pattern.c b/third_party/less/pattern.c new file mode 100644 index 000000000..ed453740b --- /dev/null +++ b/third_party/less/pattern.c @@ -0,0 +1,491 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + +/* + * Routines to do pattern matching. + */ + +#include "less.h" + +extern int caseless; +extern int is_caseless; +extern int utf_mode; + +/* + * Compile a search pattern, for future use by match_pattern. + */ +static int compile_pattern2(char *pattern, int search_type, PATTERN_TYPE *comp_pattern, int show_error) +{ + if (search_type & SRCH_NO_REGEX) + return (0); + { +#if HAVE_GNU_REGEX + struct re_pattern_buffer *comp = (struct re_pattern_buffer *) + ecalloc(1, sizeof(struct re_pattern_buffer)); + re_set_syntax(RE_SYNTAX_POSIX_EXTENDED); + if (re_compile_pattern(pattern, strlen(pattern), comp)) + { + free(comp); + if (show_error) + error("Invalid pattern", NULL_PARG); + return (-1); + } + if (*comp_pattern != NULL) + { + regfree(*comp_pattern); + free(*comp_pattern); + } + *comp_pattern = comp; +#endif +#if HAVE_POSIX_REGCOMP + regex_t *comp = (regex_t *) ecalloc(1, sizeof(regex_t)); + if (regcomp(comp, pattern, REGCOMP_FLAG | (is_caseless ? REG_ICASE : 0))) + { + free(comp); + if (show_error) + error("Invalid pattern", NULL_PARG); + return (-1); + } + if (*comp_pattern != NULL) + { + regfree(*comp_pattern); + free(*comp_pattern); + } + *comp_pattern = comp; +#endif +#if HAVE_PCRE + constant char *errstring; + int erroffset; + PARG parg; + pcre *comp = pcre_compile(pattern, + ((utf_mode) ? PCRE_UTF8 | PCRE_NO_UTF8_CHECK : 0) | + (is_caseless ? PCRE_CASELESS : 0), + &errstring, &erroffset, NULL); + if (comp == NULL) + { + parg.p_string = (char *) errstring; + if (show_error) + error("%s", &parg); + return (-1); + } + *comp_pattern = comp; +#endif +#if HAVE_PCRE2 + int errcode; + PCRE2_SIZE erroffset; + PARG parg; + pcre2_code *comp = pcre2_compile((PCRE2_SPTR)pattern, strlen(pattern), + (is_caseless ? PCRE2_CASELESS : 0), + &errcode, &erroffset, NULL); + if (comp == NULL) + { + if (show_error) + { + char msg[160]; + pcre2_get_error_message(errcode, (PCRE2_UCHAR*)msg, sizeof(msg)); + parg.p_string = msg; + error("%s", &parg); + } + return (-1); + } + *comp_pattern = comp; +#endif +#if HAVE_RE_COMP + PARG parg; + if ((parg.p_string = re_comp(pattern)) != NULL) + { + if (show_error) + error("%s", &parg); + return (-1); + } + *comp_pattern = 1; +#endif +#if HAVE_REGCMP + char *comp; + if ((comp = regcmp(pattern, 0)) == NULL) + { + if (show_error) + error("Invalid pattern", NULL_PARG); + return (-1); + } + if (comp_pattern != NULL) + free(*comp_pattern); + *comp_pattern = comp; +#endif +#if HAVE_V8_REGCOMP + struct regexp *comp; + reg_show_error = show_error; + comp = regcomp(pattern); + reg_show_error = 1; + if (comp == NULL) + { + /* + * regcomp has already printed an error message + * via regerror(). + */ + return (-1); + } + if (*comp_pattern != NULL) + free(*comp_pattern); + *comp_pattern = comp; +#endif + } + return (0); +} + +/* + * Like compile_pattern2, but convert the pattern to lowercase if necessary. + */ +public int compile_pattern(char *pattern, int search_type, int show_error, PATTERN_TYPE *comp_pattern) +{ + char *cvt_pattern; + int result; + + if (caseless != OPT_ONPLUS || (re_handles_caseless && !(search_type & SRCH_NO_REGEX))) + cvt_pattern = pattern; + else + { + cvt_pattern = (char*) ecalloc(1, cvt_length(strlen(pattern), CVT_TO_LC)); + cvt_text(cvt_pattern, pattern, (int *)NULL, (int *)NULL, CVT_TO_LC); + } + result = compile_pattern2(cvt_pattern, search_type, comp_pattern, show_error); + if (cvt_pattern != pattern) + free(cvt_pattern); + return (result); +} + +/* + * Forget that we have a compiled pattern. + */ +public void uncompile_pattern(PATTERN_TYPE *pattern) +{ +#if HAVE_GNU_REGEX + if (*pattern != NULL) + { + regfree(*pattern); + free(*pattern); + } + *pattern = NULL; +#endif +#if HAVE_POSIX_REGCOMP + if (*pattern != NULL) + { + regfree(*pattern); + free(*pattern); + } + *pattern = NULL; +#endif +#if HAVE_PCRE + if (*pattern != NULL) + pcre_free(*pattern); + *pattern = NULL; +#endif +#if HAVE_PCRE2 + if (*pattern != NULL) + pcre2_code_free(*pattern); + *pattern = NULL; +#endif +#if HAVE_RE_COMP + *pattern = 0; +#endif +#if HAVE_REGCMP + if (*pattern != NULL) + free(*pattern); + *pattern = NULL; +#endif +#if HAVE_V8_REGCOMP + if (*pattern != NULL) + free(*pattern); + *pattern = NULL; +#endif +} + +#if 0 +/* + * Can a pattern be successfully compiled? + */ +public int valid_pattern(char *pattern) +{ + PATTERN_TYPE comp_pattern; + int result; + + SET_NULL_PATTERN(comp_pattern); + result = compile_pattern2(pattern, 0, &comp_pattern, 0); + if (result != 0) + return (0); + uncompile_pattern(&comp_pattern); + return (1); +} +#endif + +/* + * Is a compiled pattern null? + */ +public int is_null_pattern(PATTERN_TYPE pattern) +{ +#if HAVE_GNU_REGEX + return (pattern == NULL); +#endif +#if HAVE_POSIX_REGCOMP + return (pattern == NULL); +#endif +#if HAVE_PCRE + return (pattern == NULL); +#endif +#if HAVE_PCRE2 + return (pattern == NULL); +#endif +#if HAVE_RE_COMP + return (pattern == 0); +#endif +#if HAVE_REGCMP + return (pattern == NULL); +#endif +#if HAVE_V8_REGCOMP + return (pattern == NULL); +#endif +#if NO_REGEX + return (pattern == NULL); +#endif +} +/* + * Simple pattern matching function. + * It supports no metacharacters like *, etc. + */ +static int match(char *pattern, int pattern_len, char *buf, int buf_len, char ***sp, char ***ep, int nsubs) +{ + char *pp, *lp; + char *pattern_end = pattern + pattern_len; + char *buf_end = buf + buf_len; + + for ( ; buf < buf_end; buf++) + { + for (pp = pattern, lp = buf; ; pp++, lp++) + { + char cp = *pp; + char cl = *lp; + if (caseless == OPT_ONPLUS && ASCII_IS_UPPER(cp)) + cp = ASCII_TO_LOWER(cp); + if (cp != cl) + break; + if (pp == pattern_end || lp == buf_end) + break; + } + if (pp == pattern_end) + { + *(*sp)++ = buf; + *(*ep)++ = lp; + return (1); + } + } + **sp = **ep = NULL; + return (0); +} + +/* + * Perform a pattern match with the previously compiled pattern. + * Set sp[0] and ep[0] to the start and end of the matched string. + * Set sp[i] and ep[i] to the start and end of the i-th matched subpattern. + * Subpatterns are defined by parentheses in the regex language. + */ +static int match_pattern1(PATTERN_TYPE pattern, char *tpattern, char *line, int line_len, char **sp, char **ep, int nsp, int notbol, int search_type) +{ + int matched; + +#if NO_REGEX + search_type |= SRCH_NO_REGEX; +#endif + if (search_type & SRCH_NO_REGEX) + matched = match(tpattern, strlen(tpattern), line, line_len, &sp, &ep, nsp); + else + { +#if HAVE_GNU_REGEX + { + struct re_registers search_regs; + pattern->not_bol = notbol; + pattern->regs_allocated = REGS_UNALLOCATED; + matched = re_search(pattern, line, line_len, 0, line_len, &search_regs) >= 0; + if (matched) + { + *sp++ = line + search_regs.start[0]; + *ep++ = line + search_regs.end[0]; + } + } +#endif +#if HAVE_POSIX_REGCOMP + { + #define RM_COUNT (NUM_SEARCH_COLORS+2) + regmatch_t rm[RM_COUNT]; + int flags = (notbol) ? REG_NOTBOL : 0; +#ifdef REG_STARTEND + flags |= REG_STARTEND; + rm[0].rm_so = 0; + rm[0].rm_eo = line_len; +#endif + matched = !regexec(pattern, line, RM_COUNT, rm, flags); + if (matched) + { + int i; + int ecount; + for (ecount = RM_COUNT; ecount > 0; ecount--) + if (rm[ecount-1].rm_so >= 0) + break; + if (ecount >= nsp) + ecount = nsp-1; + for (i = 0; i < ecount; i++) + { + if (rm[i].rm_so < 0) + { + *sp++ = *ep++ = line; + } else + { +#ifndef __WATCOMC__ + *sp++ = line + rm[i].rm_so; + *ep++ = line + rm[i].rm_eo; +#else + *sp++ = rm[i].rm_sp; + *ep++ = rm[i].rm_ep; +#endif + } + } + } + } +#endif +#if HAVE_PCRE + { + #define OVECTOR_COUNT ((3*NUM_SEARCH_COLORS)+3) + int ovector[OVECTOR_COUNT]; + int flags = (notbol) ? PCRE_NOTBOL : 0; + int i; + int ecount; + int mcount = pcre_exec(pattern, NULL, line, line_len, + 0, flags, ovector, OVECTOR_COUNT); + matched = (mcount > 0); + ecount = nsp-1; + if (ecount > mcount) ecount = mcount; + for (i = 0; i < ecount*2; ) + { + if (ovector[i] < 0 || ovector[i+1] < 0) + { + *sp++ = *ep++ = line; + i += 2; + } else + { + *sp++ = line + ovector[i++]; + *ep++ = line + ovector[i++]; + } + } + } +#endif +#if HAVE_PCRE2 + { + int flags = (notbol) ? PCRE2_NOTBOL : 0; + pcre2_match_data *md = pcre2_match_data_create(nsp-1, NULL); + int mcount = pcre2_match(pattern, (PCRE2_SPTR)line, line_len, + 0, flags, md, NULL); + matched = (mcount > 0); + if (matched) + { + PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(md); + int i; + int ecount = nsp-1; + if (ecount > mcount) ecount = mcount; + for (i = 0; i < ecount*2; ) + { + if (ovector[i] < 0 || ovector[i+1] < 0) + { + *sp++ = *ep++ = line; + i += 2; + } else + { + *sp++ = line + ovector[i++]; + *ep++ = line + ovector[i++]; + } + } + } + pcre2_match_data_free(md); + } +#endif +#if HAVE_RE_COMP + matched = (re_exec(line) == 1); + /* + * re_exec doesn't seem to provide a way to get the matched string. + */ +#endif +#if HAVE_REGCMP + matched = ((*ep++ = regex(pattern, line)) != NULL); + if (matched) + *sp++ = __loc1; +#endif +#if HAVE_V8_REGCOMP +#if HAVE_REGEXEC2 + matched = regexec2(pattern, line, notbol); +#else + matched = regexec(pattern, line); +#endif + if (matched) + { + *sp++ = pattern->startp[0]; + *ep++ = pattern->endp[0]; + } +#endif + } + *sp = *ep = NULL; + matched = (!(search_type & SRCH_NO_MATCH) && matched) || + ((search_type & SRCH_NO_MATCH) && !matched); + return (matched); +} + +public int match_pattern(PATTERN_TYPE pattern, char *tpattern, char *line, int line_len, char **sp, char **ep, int nsp, int notbol, int search_type) +{ + int matched = match_pattern1(pattern, tpattern, line, line_len, sp, ep, nsp, notbol, search_type); + int i; + for (i = 1; i <= NUM_SEARCH_COLORS; i++) + { + if ((search_type & SRCH_SUBSEARCH(i)) && ep[i] == sp[i]) + matched = 0; + } + return matched; +} + +/* + * Return the name of the pattern matching library. + */ +public char * pattern_lib_name(void) +{ +#if HAVE_GNU_REGEX + return ("GNU"); +#else +#if HAVE_POSIX_REGCOMP + return ("POSIX"); +#else +#if HAVE_PCRE2 + return ("PCRE2"); +#else +#if HAVE_PCRE + return ("PCRE"); +#else +#if HAVE_RE_COMP + return ("BSD"); +#else +#if HAVE_REGCMP + return ("V8"); +#else +#if HAVE_V8_REGCOMP + return ("Spencer V8"); +#else + return ("no"); +#endif +#endif +#endif +#endif +#endif +#endif +#endif +} diff --git a/third_party/less/pattern.h b/third_party/less/pattern.h new file mode 100644 index 000000000..036893e75 --- /dev/null +++ b/third_party/less/pattern.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + +#if HAVE_GNU_REGEX +#define __USE_GNU 1 +#include +#define PATTERN_TYPE struct re_pattern_buffer * +#define SET_NULL_PATTERN(name) name = NULL +#endif + +/* ---- POSIX ---- */ +#if HAVE_POSIX_REGCOMP +#include +#ifdef REG_EXTENDED +#define REGCOMP_FLAG REG_EXTENDED +#else +#define REGCOMP_FLAG 0 +#endif +#define PATTERN_TYPE regex_t * +#define SET_NULL_PATTERN(name) name = NULL +#define re_handles_caseless TRUE +#endif + +/* ---- PCRE ---- */ +#if HAVE_PCRE +#include +#define PATTERN_TYPE pcre * +#define SET_NULL_PATTERN(name) name = NULL +#define re_handles_caseless TRUE +#endif + +/* ---- PCRE2 ---- */ +#if HAVE_PCRE2 +#define PCRE2_CODE_UNIT_WIDTH 8 +#include "third_party/pcre/pcre2.h" +#define PATTERN_TYPE pcre2_code * +#define SET_NULL_PATTERN(name) name = NULL +#define re_handles_caseless TRUE +#endif + +/* ---- RE_COMP ---- */ +#if HAVE_RE_COMP +char *re_comp(char*); +int re_exec(char*); +#define PATTERN_TYPE int +#define SET_NULL_PATTERN(name) name = 0 +#endif + +/* ---- REGCMP ---- */ +#if HAVE_REGCMP +char *regcmp(char*); +char *regex(char**, char*); +extern char *__loc1; +#define PATTERN_TYPE char ** +#define SET_NULL_PATTERN(name) name = NULL +#endif + +/* ---- REGCOMP ---- */ +#if HAVE_V8_REGCOMP +#include "regexp.h" +extern int reg_show_error; +#define PATTERN_TYPE struct regexp * +#define SET_NULL_PATTERN(name) name = NULL +#endif + +/* ---- NONE ---- */ +#if NO_REGEX +#define PATTERN_TYPE void * +#define SET_NULL_PATTERN(name) +#endif + +#ifndef re_handles_caseless +#define re_handles_caseless FALSE +#endif diff --git a/third_party/less/pckeys.h b/third_party/less/pckeys.h new file mode 100644 index 000000000..8af659cd8 --- /dev/null +++ b/third_party/less/pckeys.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * Definitions of keys on the PC. + * Special (non-ASCII) keys on the PC send a two-byte sequence, + * where the first byte is 0 and the second is as defined below. + */ +#define PCK_SHIFT_TAB '\017' +#define PCK_ALT_E '\022' +#define PCK_CAPS_LOCK '\072' +#define PCK_F1 '\073' +#define PCK_NUM_LOCK '\105' +#define PCK_HOME '\107' +#define PCK_UP '\110' +#define PCK_PAGEUP '\111' +#define PCK_LEFT '\113' +#define PCK_RIGHT '\115' +#define PCK_END '\117' +#define PCK_DOWN '\120' +#define PCK_PAGEDOWN '\121' +#define PCK_INSERT '\122' +#define PCK_DELETE '\123' +#define PCK_CTL_LEFT '\163' +#define PCK_CTL_RIGHT '\164' +#define PCK_CTL_DELETE '\223' diff --git a/third_party/less/position.c b/third_party/less/position.c new file mode 100644 index 000000000..c0f86614b --- /dev/null +++ b/third_party/less/position.c @@ -0,0 +1,238 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * 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 "less.h" +#include "position.h" + +static POSITION *table = NULL; /* The position table */ +static int table_size = 0; + +extern int sc_width, sc_height; +extern int header_lines; + +/* + * 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 + */ +public POSITION position(int sindex) +{ + switch (sindex) + { + case BOTTOM: + sindex = sc_height - 2; + break; + case BOTTOM_PLUS_ONE: + sindex = sc_height - 1; + break; + case MIDDLE: + sindex = (sc_height - 1) / 2; + break; + } + return (table[sindex]); +} + +/* + * Add a new file position to the bottom of the position table. + */ +public void add_forw_pos(POSITION pos) +{ + 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. + */ +public void add_back_pos(POSITION pos) +{ + int i; + + /* + * Scroll the position table down. + */ + for (i = sc_height - 1; i > 0; i--) + table[i] = table[i-1]; + table[0] = pos; +} + +/* + * Initialize the position table, done whenever we clear the screen. + */ +public void pos_clear(void) +{ + int i; + + for (i = 0; i < sc_height; i++) + table[i] = NULL_POSITION; +} + +/* + * Allocate or reallocate the position table. + */ +public void pos_init(void) +{ + struct scrpos scrpos; + + if (sc_height <= table_size) + return; + /* + * If we already have a table, remember the first line in it + * before we free it, so we can copy that line to the new table. + */ + if (table != NULL) + { + get_scrpos(&scrpos, TOP); + free((char*)table); + } else + scrpos.pos = NULL_POSITION; + table = (POSITION *) ecalloc(sc_height, sizeof(POSITION)); + table_size = sc_height; + pos_clear(); + if (scrpos.pos != NULL_POSITION) + table[scrpos.ln-1] = scrpos.pos; +} + +/* + * 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. + */ +public int onscreen(POSITION pos) +{ + int i; + + if (pos < table[0]) + return (-1); + for (i = 1; i < sc_height; i++) + if (pos < table[i]) + return (i-1); + return (-1); +} + +/* + * See if the entire screen is empty. + */ +public int empty_screen(void) +{ + return (empty_lines(0, sc_height-1)); +} + +public int empty_lines(int s, int e) +{ + int i; + + for (i = s; i <= e; i++) + if (table[i] != NULL_POSITION && table[i] != 0) + return (0); + return (1); +} + +/* + * Get the current screen position. + * The screen position consists of both a file position and + * a screen line number where the file position is placed on the screen. + * Normally the screen line number is 0, but if we are positioned + * such that the top few lines are empty, we may have to set + * the screen line to a number > 0. + */ +public void get_scrpos(struct scrpos *scrpos, int where) +{ + int i; + int dir; + int last; + + switch (where) + { + case TOP: + i = 0; dir = +1; last = sc_height-2; + break; + case BOTTOM: case BOTTOM_PLUS_ONE: + i = sc_height-2; dir = -1; last = 0; + break; + default: + i = where; + if (table[i] == NULL_POSITION) { + scrpos->pos = NULL_POSITION; + return; + } + /* Values of dir and last don't matter after this. */ + break; + } + + /* + * Find the first line on the screen which has something on it, + * and return the screen line number and the file position. + */ + for (;; i += dir) + { + if (table[i] != NULL_POSITION) + { + scrpos->ln = i+1; + scrpos->pos = table[i]; + return; + } + if (i == last) break; + } + /* + * The screen is empty. + */ + scrpos->pos = NULL_POSITION; +} + +/* + * Adjust a screen line number to be a simple positive integer + * in the range { 0 .. sc_height-2 }. + * (The bottom line, sc_height-1, is reserved for prompts, etc.) + * The given "sline" may be in the range { 1 .. sc_height-1 } + * to refer to lines relative to the top of the screen (starting from 1), + * or it may be in { -1 .. -(sc_height-1) } to refer to lines + * relative to the bottom of the screen. + */ +public int sindex_from_sline(int sline) +{ + /* + * Negative screen line number means + * relative to the bottom of the screen. + */ + if (sline < 0) + sline += sc_height; + /* + * Can't be less than 1 or greater than sc_height. + */ + if (sline <= 0) + sline = 1; + if (sline > sc_height) + sline = sc_height; + /* + * Return zero-based line number, not one-based. + */ + return (sline-1); +} diff --git a/third_party/less/position.h b/third_party/less/position.h new file mode 100644 index 000000000..650f47018 --- /dev/null +++ b/third_party/less/position.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * Include file for interfacing to position.c modules. + */ +#define TOP (0) +#define TOP_PLUS_ONE (1) +#define BOTTOM (-1) +#define BOTTOM_PLUS_ONE (-2) +#define MIDDLE (-3) diff --git a/third_party/less/prompt.c b/third_party/less/prompt.c new file mode 100644 index 000000000..01265c27d --- /dev/null +++ b/third_party/less/prompt.c @@ -0,0 +1,556 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * Prompting and other messages. + * There are three flavors of prompts, SHORT, MEDIUM and LONG, + * selected by the -m/-M options. + * There is also the "equals message", printed by the = command. + * A prompt is a message composed of various pieces, such as the + * name of the file being viewed, the percentage into the file, etc. + */ + +#include "less.h" +#include "position.h" + +extern int pr_type; +extern int new_file; +extern int sc_width; +extern int so_s_width, so_e_width; +extern int linenums; +extern int hshift; +extern int sc_height; +extern int jump_sline; +extern int less_is_more; +extern int header_lines; +extern IFILE curr_ifile; +#if EDITOR +extern char *editor; +extern char *editproto; +#endif + +/* + * Prototypes for the three flavors of prompts. + * These strings are expanded by pr_expand(). + */ +static constant char s_proto[] = + "?n?f%f .?m(%T %i of %m) ..?e(END) ?x- Next\\: %x..%t"; +static constant char m_proto[] = + "?n?f%f .?m(%T %i of %m) ..?e(END) ?x- Next\\: %x.:?pB%pB\\%:byte %bB?s/%s...%t"; +static constant char M_proto[] = + "?f%f .?n?m(%T %i of %m) ..?ltlines %lt-%lb?L/%L. :byte %bB?s/%s. .?e(END) ?x- Next\\: %x.:?pB%pB\\%..%t"; +static constant char e_proto[] = + "?f%f .?m(%T %i of %m) .?ltlines %lt-%lb?L/%L. .byte %bB?s/%s. ?e(END) :?pB%pB\\%..%t"; +static constant char h_proto[] = + "HELP -- ?eEND -- Press g to see it again:Press RETURN for more., or q when done"; +static constant char w_proto[] = + "Waiting for data"; +static constant char more_proto[] = + "--More--(?eEND ?x- Next\\: %x.:?pB%pB\\%:byte %bB?s/%s...%t)"; + +public char *prproto[3]; +public char constant *eqproto = e_proto; +public char constant *hproto = h_proto; +public char constant *wproto = w_proto; + +static char message[PROMPT_SIZE]; +static char *mp; + +/* + * Initialize the prompt prototype strings. + */ +public void init_prompt(void) +{ + prproto[0] = save(s_proto); + prproto[1] = save(less_is_more ? more_proto : m_proto); + prproto[2] = save(M_proto); + eqproto = save(e_proto); + hproto = save(h_proto); + wproto = save(w_proto); +} + +/* + * Append a string to the end of the message. + */ +static void ap_str(char *s) +{ + int len; + + len = (int) strlen(s); + if (mp + len >= message + PROMPT_SIZE) + len = (int) (message + PROMPT_SIZE - mp - 1); + strncpy(mp, s, len); + mp += len; + *mp = '\0'; +} + +/* + * Append a character to the end of the message. + */ +static void ap_char(char c) +{ + char buf[2]; + + buf[0] = c; + buf[1] = '\0'; + ap_str(buf); +} + +/* + * Append a POSITION (as a decimal integer) to the end of the message. + */ +static void ap_pos(POSITION pos) +{ + char buf[INT_STRLEN_BOUND(pos) + 2]; + + postoa(pos, buf, 10); + ap_str(buf); +} + +/* + * Append a line number to the end of the message. + */ +static void ap_linenum(LINENUM linenum) +{ + char buf[INT_STRLEN_BOUND(linenum) + 2]; + + linenumtoa(linenum, buf, 10); + ap_str(buf); +} + +/* + * Append an integer to the end of the message. + */ +static void ap_int(int num) +{ + char buf[INT_STRLEN_BOUND(num) + 2]; + + inttoa(num, buf, 10); + ap_str(buf); +} + +/* + * Append a question mark to the end of the message. + */ +static void ap_quest(void) +{ + ap_str("?"); +} + +/* + * Return the "current" byte offset in the file. + */ +static POSITION curr_byte(int where) +{ + POSITION pos; + + pos = position(where); + while (pos == NULL_POSITION && where >= 0 && where < sc_height-1) + pos = position(++where); + if (pos == NULL_POSITION) + pos = ch_length(); + return (pos); +} + +/* + * Return the value of a prototype conditional. + * A prototype string may include conditionals which consist of a + * question mark followed by a single letter. + * Here we decode that letter and return the appropriate boolean value. + */ +static int cond(char c, int where) +{ + POSITION len; + + switch (c) + { + case 'a': /* Anything in the message yet? */ + return (mp > message); + case 'b': /* Current byte offset known? */ + return (curr_byte(where) != NULL_POSITION); + case 'c': + return (hshift != 0); + case 'e': /* At end of file? */ + return (eof_displayed()); + case 'f': /* Filename known? */ + case 'g': + return (strcmp(get_filename(curr_ifile), "-") != 0); + case 'l': /* Line number known? */ + case 'd': /* Same as l */ + if (!linenums) + return 0; + return (currline(where) != 0); + case 'L': /* Final line number known? */ + case 'D': /* Final page number known? */ + return (linenums && ch_length() != NULL_POSITION); + case 'm': /* More than one file? */ +#if TAGS + return (ntags() ? (ntags() > 1) : (nifile() > 1)); +#else + return (nifile() > 1); +#endif + case 'n': /* First prompt in a new file? */ +#if TAGS + return (ntags() ? 1 : new_file); +#else + return (new_file); +#endif + case 'p': /* Percent into file (bytes) known? */ + return (curr_byte(where) != NULL_POSITION && + ch_length() > 0); + case 'P': /* Percent into file (lines) known? */ + return (currline(where) != 0 && + (len = ch_length()) > 0 && + find_linenum(len) != 0); + case 's': /* Size of file known? */ + case 'B': + return (ch_length() != NULL_POSITION); + case 'x': /* Is there a "next" file? */ +#if TAGS + if (ntags()) + return (0); +#endif + return (next_ifile(curr_ifile) != NULL_IFILE); + } + return (0); +} + +/* + * Decode a "percent" prototype character. + * A prototype string may include various "percent" escapes; + * that is, a percent sign followed by a single letter. + * Here we decode that letter and take the appropriate action, + * usually by appending something to the message being built. + */ +static void protochar(int c, int where, int iseditproto) +{ + POSITION pos; + POSITION len; + int n; + LINENUM linenum; + LINENUM last_linenum; + IFILE h; + char *s; + +#undef PAGE_NUM +#define PAGE_NUM(linenum) ((((linenum) - 1) / (sc_height - header_lines - 1)) + 1) + + switch (c) + { + case 'b': /* Current byte offset */ + pos = curr_byte(where); + if (pos != NULL_POSITION) + ap_pos(pos); + else + ap_quest(); + break; + case 'c': + ap_int(hshift); + break; + case 'd': /* Current page number */ + linenum = currline(where); + if (linenum > 0 && sc_height > header_lines + 1) + ap_linenum(PAGE_NUM(linenum)); + else + ap_quest(); + break; + case 'D': /* Final page number */ + /* Find the page number of the last byte in the file (len-1). */ + len = ch_length(); + if (len == NULL_POSITION) + ap_quest(); + else if (len == 0) + /* An empty file has no pages. */ + ap_linenum(0); + else + { + linenum = find_linenum(len - 1); + if (linenum <= 0) + ap_quest(); + else + ap_linenum(PAGE_NUM(linenum)); + } + break; +#if EDITOR + case 'E': /* Editor name */ + ap_str(editor); + break; +#endif + case 'f': /* File name */ + ap_str(get_filename(curr_ifile)); + break; + case 'F': /* Last component of file name */ + ap_str(last_component(get_filename(curr_ifile))); + break; + case 'g': /* Shell-escaped file name */ + s = shell_quote(get_filename(curr_ifile)); + ap_str(s); + free(s); + break; + case 'i': /* Index into list of files */ +#if TAGS + if (ntags()) + ap_int(curr_tag()); + else +#endif + ap_int(get_index(curr_ifile)); + break; + case 'l': /* Current line number */ + linenum = currline(where); + if (linenum != 0) + ap_linenum(vlinenum(linenum)); + else + ap_quest(); + break; + case 'L': /* Final line number */ + len = ch_length(); + if (len == NULL_POSITION || len == ch_zero() || + (linenum = find_linenum(len)) <= 0) + ap_quest(); + else + ap_linenum(vlinenum(linenum-1)); + break; + case 'm': /* Number of files */ +#if TAGS + n = ntags(); + if (n) + ap_int(n); + else +#endif + ap_int(nifile()); + break; + case 'p': /* Percent into file (bytes) */ + pos = curr_byte(where); + len = ch_length(); + if (pos != NULL_POSITION && len > 0) + ap_int(percentage(pos,len)); + else + ap_quest(); + break; + case 'P': /* Percent into file (lines) */ + linenum = currline(where); + if (linenum == 0 || + (len = ch_length()) == NULL_POSITION || len == ch_zero() || + (last_linenum = find_linenum(len)) <= 0) + ap_quest(); + else + ap_int(percentage(linenum, last_linenum)); + break; + case 's': /* Size of file */ + case 'B': + len = ch_length(); + if (len != NULL_POSITION) + ap_pos(len); + else + ap_quest(); + break; + case 't': /* Truncate trailing spaces in the message */ + while (mp > message && mp[-1] == ' ') + mp--; + *mp = '\0'; + break; + case 'T': /* Type of list */ +#if TAGS + if (ntags()) + ap_str("tag"); + else +#endif + ap_str("file"); + break; + case 'x': /* Name of next file */ + h = next_ifile(curr_ifile); + if (h != NULL_IFILE) + ap_str(get_filename(h)); + else + ap_quest(); + break; + } +} + +/* + * Skip a false conditional. + * When a false condition is found (either a false IF or the ELSE part + * of a true IF), this routine scans the prototype string to decide + * where to resume parsing the string. + * We must keep track of nested IFs and skip them properly. + */ +static constant char * skipcond(constant char *p) +{ + int iflevel; + + /* + * We came in here after processing a ? or :, + * so we start nested one level deep. + */ + iflevel = 1; + + for (;;) switch (*++p) + { + case '?': + /* + * Start of a nested IF. + */ + iflevel++; + break; + case ':': + /* + * Else. + * If this matches the IF we came in here with, + * then we're done. + */ + if (iflevel == 1) + return (p); + break; + case '.': + /* + * Endif. + * If this matches the IF we came in here with, + * then we're done. + */ + if (--iflevel == 0) + return (p); + break; + case '\\': + /* + * Backslash escapes the next character. + */ + if (p[1] != '\0') + ++p; + break; + case '\0': + /* + * Whoops. Hit end of string. + * This is a malformed conditional, but just treat it + * as if all active conditionals ends here. + */ + return (p-1); + } + /*NOTREACHED*/ +} + +/* + * Decode a char that represents a position on the screen. + */ +static constant char * wherechar(char constant *p, int *wp) +{ + switch (*p) + { + case 'b': case 'd': case 'l': case 'p': case 'P': + switch (*++p) + { + case 't': *wp = TOP; break; + case 'm': *wp = MIDDLE; break; + case 'b': *wp = BOTTOM; break; + case 'B': *wp = BOTTOM_PLUS_ONE; break; + case 'j': *wp = sindex_from_sline(jump_sline); break; + default: *wp = TOP; p--; break; + } + } + return (p); +} + +/* + * Construct a message based on a prototype string. + */ +public char * pr_expand(constant char *proto) +{ + constant char *p; + int c; + int where; + + mp = message; + + if (*proto == '\0') + return (""); + + for (p = proto; *p != '\0'; p++) + { + switch (*p) + { + default: /* Just put the character in the message */ + ap_char(*p); + break; + case '\\': /* Backslash escapes the next character */ + if (p[1] != '\0') + ap_char(*++p); + break; + case '?': /* Conditional (IF) */ + if ((c = *++p) == '\0') + --p; + else + { + where = 0; + p = wherechar(p, &where); + if (!cond(c, where)) + p = skipcond(p); + } + break; + case ':': /* ELSE */ + p = skipcond(p); + break; + case '.': /* ENDIF */ + break; + case '%': /* Percent escape */ + if ((c = *++p) == '\0') + --p; + else + { + where = 0; + p = wherechar(p, &where); + protochar(c, where, +#if EDITOR + (proto == editproto)); +#else + 0); +#endif + + } + break; + } + } + + if (mp == message) + return (""); + return (message); +} + +/* + * Return a message suitable for printing by the "=" command. + */ +public char * eq_message(void) +{ + return (pr_expand(eqproto)); +} + +/* + * Return a prompt. + * This depends on the prompt type (SHORT, MEDIUM, LONG), etc. + * If we can't come up with an appropriate prompt, return NULL + * and the caller will prompt with a colon. + */ +public char * pr_string(void) +{ + char *prompt; + int type; + + type = (!less_is_more) ? pr_type : pr_type ? 0 : 1; + prompt = pr_expand((ch_getflags() & CH_HELPFILE) ? + hproto : prproto[type]); + new_file = 0; + return (prompt); +} + +/* + * Return a message suitable for printing while waiting in the F command. + */ +public char * wait_message(void) +{ + return (pr_expand(wproto)); +} diff --git a/third_party/less/regexp.h b/third_party/less/regexp.h new file mode 100644 index 000000000..283ff2aad --- /dev/null +++ b/third_party/less/regexp.h @@ -0,0 +1,34 @@ +/* + * Definitions etc. for regexp(3) routines. + * + * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof], + * not the System V one. + */ + +#ifndef _REGEXP +#define _REGEXP 1 + +#define NSUBEXP 10 +typedef struct regexp { + char *startp[NSUBEXP]; + char *endp[NSUBEXP]; + char regstart; /* Internal use only. */ + char reganch; /* Internal use only. */ + char *regmust; /* Internal use only. */ + int regmlen; /* Internal use only. */ + char program[1]; /* Unwarranted chumminess with compiler. */ +} regexp; + +#if defined(__STDC__) || defined(__cplusplus) +# define _ANSI_ARGS_(x) x +#else +# define _ANSI_ARGS_(x) () +#endif + +extern regexp *regcomp _ANSI_ARGS_((char *exp)); +extern int regexec _ANSI_ARGS_((regexp *prog, char *string)); +extern int regexec2 _ANSI_ARGS_((regexp *prog, char *string, int notbol)); +extern void regsub _ANSI_ARGS_((regexp *prog, char *source, char *dest)); +extern void regerror _ANSI_ARGS_((char *msg)); + +#endif /* REGEXP */ diff --git a/third_party/less/screen.c b/third_party/less/screen.c new file mode 100644 index 000000000..0da0e9f64 --- /dev/null +++ b/third_party/less/screen.c @@ -0,0 +1,3018 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * Routines which deal with the characteristics of the terminal. + * Uses termcap to be as terminal-independent as possible. + */ + +#include "less.h" +#include "cmd.h" + +#if MSDOS_COMPILER +#include "pckeys.h" +#if MSDOS_COMPILER==MSOFTC +#include +#else +#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC +#include +#if MSDOS_COMPILER==DJGPPC +#include +extern int fd0; +#endif +#else +#if MSDOS_COMPILER==WIN32C +/* #include */ +#endif +#endif +#endif +#include + +#ifndef FOREGROUND_BLUE +#define FOREGROUND_BLUE 0x0001 +#endif +#ifndef FOREGROUND_GREEN +#define FOREGROUND_GREEN 0x0002 +#endif +#ifndef FOREGROUND_RED +#define FOREGROUND_RED 0x0004 +#endif +#ifndef FOREGROUND_INTENSITY +#define FOREGROUND_INTENSITY 0x0008 +#endif + +#else + +#if HAVE_SYS_IOCTL_H +#include +#endif + +#if HAVE_TERMIOS_H && HAVE_TERMIOS_FUNCS +#include +#else +#if HAVE_TERMIO_H +#include +#else +#if HAVE_SGSTAT_H +#include +#else +#include +#endif +#endif +#endif + +#if HAVE_NCURSESW_TERMCAP_H +#include +#else +#if HAVE_NCURSES_TERMCAP_H +#include "third_party/ncurses/termcap.h" +#else +#if HAVE_TERMCAP_H +#include +#endif +#endif +#endif +#ifdef _OSK +#include +#endif +#if OS2 +#include +#include "pckeys.h" +#endif +#if HAVE_SYS_STREAM_H +#include +#endif +#if HAVE_SYS_PTEM_H +#include +#endif + +#endif /* MSDOS_COMPILER */ + +/* + * Check for broken termios package that forces you to manually + * set the line discipline. + */ +#ifdef __ultrix__ +#define MUST_SET_LINE_DISCIPLINE 1 +#else +#define MUST_SET_LINE_DISCIPLINE 0 +#endif + +#if OS2 +#define DEFAULT_TERM "ansi" +static char *windowid; +#else +#define DEFAULT_TERM "unknown" +#endif + +#if MSDOS_COMPILER==MSOFTC +static int videopages; +static long msec_loops; +static int flash_created = 0; +#define SET_FG_COLOR(fg) _settextcolor(fg) +#define SET_BG_COLOR(bg) _setbkcolor(bg) +#define SETCOLORS(fg,bg) { SET_FG_COLOR(fg); SET_BG_COLOR(bg); } +#endif + +#if MSDOS_COMPILER==BORLANDC +static unsigned short *whitescreen; +static int flash_created = 0; +#endif +#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC +#define _settextposition(y,x) gotoxy(x,y) +#define _clearscreen(m) clrscr() +#define _outtext(s) cputs(s) +#define SET_FG_COLOR(fg) textcolor(fg) +#define SET_BG_COLOR(bg) textbackground(bg) +#define SETCOLORS(fg,bg) { SET_FG_COLOR(fg); SET_BG_COLOR(bg); } +extern int sc_height; +#endif + +#if MSDOS_COMPILER==WIN32C +#define UTF8_MAX_LENGTH 4 +struct keyRecord +{ + WCHAR unicode; + int ascii; + int scan; +} currentKey; + +static int keyCount = 0; +static WORD curr_attr; +static int pending_scancode = 0; +static char x11mousebuf[] = "[M???"; /* Mouse report, after ESC */ +static int x11mousePos, x11mouseCount; +static int win_unget_pending = FALSE; +static int win_unget_data; + +static HANDLE con_out_save = INVALID_HANDLE_VALUE; /* previous console */ +static HANDLE con_out_ours = INVALID_HANDLE_VALUE; /* our own */ +HANDLE con_out = INVALID_HANDLE_VALUE; /* current console */ + +extern int utf_mode; +extern int quitting; +static void win32_init_term(); +static void win32_deinit_term(); + +#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING +#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 4 +#endif + +#define FG_COLORS (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY) +#define BG_COLORS (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY) +#define MAKEATTR(fg,bg) ((WORD)((fg)|((bg)<<4))) +#define APPLY_COLORS() { if (SetConsoleTextAttribute(con_out, curr_attr) == 0) \ + error("SETCOLORS failed", NULL_PARG); } +#define SET_FG_COLOR(fg) { curr_attr &= ~0x0f; curr_attr |= (fg); APPLY_COLORS(); } +#define SET_BG_COLOR(bg) { curr_attr &= ~0xf0; curr_attr |= ((bg)<<4); APPLY_COLORS(); } +#define SETCOLORS(fg,bg) { curr_attr = MAKEATTR(fg,bg); APPLY_COLORS(); } +#endif + +#if MSDOS_COMPILER +public int nm_fg_color; /* Color of normal text */ +public int nm_bg_color; +public int bo_fg_color; /* Color of bold text */ +public int bo_bg_color; +public int ul_fg_color; /* Color of underlined text */ +public int ul_bg_color; +public int so_fg_color; /* Color of standout text */ +public int so_bg_color; +public int bl_fg_color; /* Color of blinking text */ +public int bl_bg_color; +static int sy_fg_color; /* Color of system text (before less) */ +static int sy_bg_color; +public int sgr_mode; /* Honor ANSI sequences rather than using above */ +#if MSDOS_COMPILER==WIN32C +static DWORD init_output_mode; /* The initial console output mode */ +public int vt_enabled = -1; /* Is virtual terminal processing available? */ +#endif +#else + +/* + * 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_return, /* Cursor to beginning of current line */ + *sc_move, /* General cursor positioning */ + *sc_clear, /* Clear screen */ + *sc_eol_clear, /* Clear to end of line */ + *sc_eos_clear, /* Clear to end of screen */ + *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_bl_in, /* Enter blink mode */ + *sc_bl_out, /* Exit blink mode */ + *sc_visual_bell, /* Visual bell (flash screen) sequence */ + *sc_backspace, /* Backspace cursor */ + *sc_s_keypad, /* Start keypad mode */ + *sc_e_keypad, /* End keypad mode */ + *sc_s_mousecap, /* Start mouse capture mode */ + *sc_e_mousecap, /* End mouse capture mode */ + *sc_init, /* Startup terminal initialization */ + *sc_deinit; /* Exit terminal de-initialization */ + +static int attrcolor = -1; +#endif + +static int init_done = 0; + +public int auto_wrap; /* Terminal does \r\n when write past margin */ +public int ignaw; /* Terminal ignores \n immediately after wrap */ +public int erase_char; /* The user's erase char */ +public int erase2_char; /* The user's other erase char */ +public int kill_char; /* The user's line-kill char */ +public int werase_char; /* The user's word-erase char */ +public int sc_width, sc_height; /* Height & width of screen */ +public int bo_s_width, bo_e_width; /* Printing width of boldface seq */ +public int ul_s_width, ul_e_width; /* Printing width of underline seq */ +public int so_s_width, so_e_width; /* Printing width of standout seq */ +public int bl_s_width, bl_e_width; /* Printing width of blink seq */ +public int above_mem, below_mem; /* Memory retained above/below screen */ +public int can_goto_line; /* Can move cursor to any line */ +public int clear_bg; /* Clear fills with background color */ +public int missing_cap = 0; /* Some capability is missing */ +public char *kent = NULL; /* Keypad ENTER sequence */ +public int term_init_done = FALSE; +public int full_screen = TRUE; + +static int attrmode = AT_NORMAL; +static int termcap_debug = -1; +static int no_alt_screen; /* sc_init does not switch to alt screen */ +extern int binattr; +extern int one_screen; +#if LESSTEST +extern char *ttyin_name; +#endif /*LESSTEST*/ + +#if !MSDOS_COMPILER +static char *cheaper(char *t1, char *t2, char *def); +static void tmodes(char *incap, char *outcap, char **instr, + char **outstr, char *def_instr, char *def_outstr, char **spp); +#endif + +/* + * These two variables are sometimes defined in, + * and needed by, the termcap library. + */ +#if MUST_DEFINE_OSPEED +extern short ospeed; /* Terminal output baud rate */ +extern char PC; /* Pad character */ +#endif +#ifdef _OSK +short ospeed; +char PC_, *UP, *BC; +#endif + +extern int quiet; /* If VERY_QUIET, use visual bell for bell */ +extern int no_vbell; +extern int no_back_scroll; +extern int swindow; +extern int no_init; +extern int no_keypad; +extern int sigs; +extern int wscroll; +extern int screen_trashed; +extern int top_scroll; +extern int quit_if_one_screen; +extern int oldbot; +extern int mousecap; +extern int is_tty; +extern int use_color; +#if HILITE_SEARCH +extern int hilite_search; +#endif +#if MSDOS_COMPILER==WIN32C +extern HANDLE tty; +extern DWORD console_mode; +#ifndef ENABLE_EXTENDED_FLAGS +#define ENABLE_EXTENDED_FLAGS 0x80 +#define ENABLE_QUICK_EDIT_MODE 0x40 +#endif +#else +extern int tty; +#endif + +#if (HAVE_TERMIOS_H && HAVE_TERMIOS_FUNCS) || defined(TCGETA) +/* + * Set termio flags for use by less. + */ +static void set_termio_flags( +#if HAVE_TERMIOS_H && HAVE_TERMIOS_FUNCS + struct termios *s +#else + struct termio *s +#endif + ) +{ + s->c_lflag &= ~(0 +#ifdef ICANON + | ICANON +#endif +#ifdef ECHO + | ECHO +#endif +#ifdef ECHOE + | ECHOE +#endif +#ifdef ECHOK + | ECHOK +#endif +#ifdef ECHONL + | ECHONL +#endif + ); + + s->c_oflag |= (0 +#ifdef OXTABS + | OXTABS +#else +#ifdef TAB3 + | TAB3 +#else +#ifdef XTABS + | XTABS +#endif +#endif +#endif +#ifdef OPOST + | OPOST +#endif +#ifdef ONLCR + | ONLCR +#endif + ); + + s->c_oflag &= ~(0 +#ifdef ONOEOT + | ONOEOT +#endif +#ifdef OCRNL + | OCRNL +#endif +#ifdef ONOCR + | ONOCR +#endif +#ifdef ONLRET + | ONLRET +#endif + ); +} +#endif + +/* + * 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. + */ +public void raw_mode(int on) +{ + static int curr_on = 0; + + if (on == curr_on) + return; + erase2_char = '\b'; /* in case OS doesn't know about erase2 */ +#if LESSTEST + if (ttyin_name != NULL) + { + /* {{ For consistent conditions when running tests. }} */ + erase_char = '\b'; + kill_char = CONTROL('U'); + werase_char = CONTROL('W'); + } else +#endif /*LESSTEST*/ +#if HAVE_TERMIOS_H && HAVE_TERMIOS_FUNCS + { + struct termios s; + static struct termios save_term; + static int saved_term = 0; + + if (on) + { + /* + * Get terminal modes. + */ + if (tcgetattr(tty, &s) < 0) + { + erase_char = '\b'; + kill_char = CONTROL('U'); + werase_char = CONTROL('W'); + } else + { + /* + * Save modes and set certain variables dependent on modes. + */ + if (!saved_term) + { + save_term = s; + saved_term = 1; + } +#if HAVE_OSPEED + switch (cfgetospeed(&s)) + { +#ifdef B0 + case B0: ospeed = 0; break; +#endif +#ifdef B50 + case B50: ospeed = 1; break; +#endif +#ifdef B75 + case B75: ospeed = 2; break; +#endif +#ifdef B110 + case B110: ospeed = 3; break; +#endif +#ifdef B134 + case B134: ospeed = 4; break; +#endif +#ifdef B150 + case B150: ospeed = 5; break; +#endif +#ifdef B200 + case B200: ospeed = 6; break; +#endif +#ifdef B300 + case B300: ospeed = 7; break; +#endif +#ifdef B600 + case B600: ospeed = 8; break; +#endif +#ifdef B1200 + case B1200: ospeed = 9; break; +#endif +#ifdef B1800 + case B1800: ospeed = 10; break; +#endif +#ifdef B2400 + case B2400: ospeed = 11; break; +#endif +#ifdef B4800 + case B4800: ospeed = 12; break; +#endif +#ifdef B9600 + case B9600: ospeed = 13; break; +#endif +#ifdef EXTA + case EXTA: ospeed = 14; break; +#endif +#ifdef EXTB + case EXTB: ospeed = 15; break; +#endif +#ifdef B57600 + case B57600: ospeed = 16; break; +#endif +#ifdef B115200 + case B115200: ospeed = 17; break; +#endif + default: ; + } +#endif + erase_char = s.c_cc[VERASE]; +#ifdef VERASE2 + erase2_char = s.c_cc[VERASE2]; +#endif + kill_char = s.c_cc[VKILL]; +#ifdef VWERASE + werase_char = s.c_cc[VWERASE]; +#else + werase_char = CONTROL('W'); +#endif + + /* + * Set the modes to the way we want them. + */ + set_termio_flags(&s); + s.c_cc[VMIN] = 1; + s.c_cc[VTIME] = 0; +#ifdef VLNEXT + s.c_cc[VLNEXT] = 0; +#endif +#ifdef VDSUSP + s.c_cc[VDSUSP] = 0; +#endif +#ifdef VSTOP + s.c_cc[VSTOP] = 0; +#endif +#ifdef VSTART + s.c_cc[VSTART] = 0; +#endif +#if MUST_SET_LINE_DISCIPLINE + /* + * System's termios is broken; need to explicitly + * request TERMIODISC line discipline. + */ + s.c_line = TERMIODISC; +#endif + } + } else + { + /* + * Restore saved modes. + */ + s = save_term; + } +#if HAVE_FSYNC + fsync(tty); +#endif + tcsetattr(tty, TCSADRAIN, &s); +#if MUST_SET_LINE_DISCIPLINE + if (!on) + { + /* + * Broken termios *ignores* any line discipline + * except TERMIODISC. A different old line discipline + * is therefore not restored, yet. Restore the old + * line discipline by hand. + */ + ioctl(tty, TIOCSETD, &save_term.c_line); + } +#endif + } +#else +#ifdef TCGETA + { + struct termio s; + static struct termio save_term; + static int saved_term = 0; + + if (on) + { + /* + * Get terminal modes. + */ + ioctl(tty, TCGETA, &s); + + /* + * Save modes and set certain variables dependent on modes. + */ + if (!saved_term) + { + save_term = s; + saved_term = 1; + } +#if HAVE_OSPEED + ospeed = s.c_cflag & CBAUD; +#endif + erase_char = s.c_cc[VERASE]; + kill_char = s.c_cc[VKILL]; +#ifdef VWERASE + werase_char = s.c_cc[VWERASE]; +#else + werase_char = CONTROL('W'); +#endif + + /* + * Set the modes to the way we want them. + */ + set_termio_flags(&s); + s.c_cc[VMIN] = 1; + s.c_cc[VTIME] = 0; +#ifdef VSTOP + s.c_cc[VSTOP] = 0; +#endif +#ifdef VSTART + s.c_cc[VSTART] = 0; +#endif + } else + { + /* + * Restore saved modes. + */ + s = save_term; + } + ioctl(tty, TCSETAW, &s); + } +#else +#ifdef TIOCGETP + { + struct sgttyb s; + static struct sgttyb save_term; + static int saved_term = 0; + + if (on) + { + /* + * Get terminal modes. + */ + ioctl(tty, TIOCGETP, &s); + + /* + * Save modes and set certain variables dependent on modes. + */ + if (!saved_term) + { + save_term = s; + saved_term = 1; + } +#if HAVE_OSPEED + ospeed = s.sg_ospeed; +#endif + erase_char = s.sg_erase; + kill_char = s.sg_kill; + werase_char = CONTROL('W'); + + /* + * 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; + } + ioctl(tty, TIOCSETN, &s); + } +#else +#ifdef _OSK + { + struct sgbuf s; + static struct sgbuf save_term; + static int saved_term = 0; + + if (on) + { + /* + * Get terminal modes. + */ + _gs_opt(tty, &s); + + /* + * Save modes and set certain variables dependent on modes. + */ + if (!saved_term) + { + save_term = s; + saved_term = 1; + } + erase_char = s.sg_bspch; + kill_char = s.sg_dlnch; + werase_char = CONTROL('W'); + + /* + * Set the modes to the way we want them. + */ + s.sg_echo = 0; + s.sg_eofch = 0; + s.sg_pause = 0; + s.sg_psch = 0; + } else + { + /* + * Restore saved modes. + */ + s = save_term; + } + _ss_opt(tty, &s); + } +#else + /* MS-DOS, Windows, or OS2 */ +#if OS2 + /* OS2 */ + LSIGNAL(SIGINT, SIG_IGN); +#endif + erase_char = '\b'; +#if MSDOS_COMPILER==DJGPPC + kill_char = CONTROL('U'); + /* + * So that when we shell out or run another program, its + * stdin is in cooked mode. We do not switch stdin to binary + * mode if fd0 is zero, since that means we were called before + * tty was reopened in open_getchr, in which case we would be + * changing the original stdin device outside less. + */ + if (fd0 != 0) + setmode(0, on ? O_BINARY : O_TEXT); +#else + kill_char = ESC; +#endif + werase_char = CONTROL('W'); +#endif +#endif +#endif +#endif + curr_on = on; +} + +#if !MSDOS_COMPILER +/* + * Some glue to prevent calling termcap functions if tgetent() failed. + */ +static int hardcopy; + +static char * ltget_env(char *capname) +{ + char name[64]; + + if (termcap_debug) + { + struct env { struct env *next; char *name; char *value; }; + static struct env *envs = NULL; + struct env *p; + for (p = envs; p != NULL; p = p->next) + if (strcmp(p->name, capname) == 0) + return p->value; + p = (struct env *) ecalloc(1, sizeof(struct env)); + p->name = save(capname); + p->value = (char *) ecalloc(strlen(capname)+3, sizeof(char)); + sprintf(p->value, "<%s>", capname); + p->next = envs; + envs = p; + return p->value; + } + SNPRINTF1(name, sizeof(name), "LESS_TERMCAP_%s", capname); + return (lgetenv(name)); +} + +static int ltgetflag(char *capname) +{ + char *s; + + if ((s = ltget_env(capname)) != NULL) + return (*s != '\0' && *s != '0'); + if (hardcopy) + return (0); + return (tgetflag(capname)); +} + +static int ltgetnum(char *capname) +{ + char *s; + + if ((s = ltget_env(capname)) != NULL) + return (atoi(s)); + if (hardcopy) + return (-1); + return (tgetnum(capname)); +} + +static char * ltgetstr(char *capname, char **pp) +{ + char *s; + + if ((s = ltget_env(capname)) != NULL) + return (s); + if (hardcopy) + return (NULL); + return (tgetstr(capname, pp)); +} +#endif /* MSDOS_COMPILER */ + +/* + * Get size of the output screen. + */ +public void scrsize(void) +{ + char *s; + int sys_height; + int sys_width; +#if !MSDOS_COMPILER + int n; +#endif + +#define DEF_SC_WIDTH 80 +#if MSDOS_COMPILER +#define DEF_SC_HEIGHT 25 +#else +#define DEF_SC_HEIGHT 24 +#endif + + + sys_width = sys_height = 0; + +#if LESSTEST + if (ttyin_name != NULL) +#endif /*LESSTEST*/ + { +#if MSDOS_COMPILER==MSOFTC + { + struct videoconfig w; + _getvideoconfig(&w); + sys_height = w.numtextrows; + sys_width = w.numtextcols; + } +#else +#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC + { + struct text_info w; + gettextinfo(&w); + sys_height = w.screenheight; + sys_width = w.screenwidth; + } +#else +#if MSDOS_COMPILER==WIN32C + { + CONSOLE_SCREEN_BUFFER_INFO scr; + GetConsoleScreenBufferInfo(con_out, &scr); + sys_height = scr.srWindow.Bottom - scr.srWindow.Top + 1; + sys_width = scr.srWindow.Right - scr.srWindow.Left + 1; + } +#else +#if OS2 + { + int s[2]; + _scrsize(s); + sys_width = s[0]; + sys_height = s[1]; + /* + * When using terminal emulators for XFree86/OS2, the + * _scrsize function does not work well. + * Call the scrsize.exe program to get the window size. + */ + windowid = getenv("WINDOWID"); + if (windowid != NULL) + { + FILE *fd = popen("scrsize", "rt"); + if (fd != NULL) + { + int w, h; + fscanf(fd, "%i %i", &w, &h); + if (w > 0 && h > 0) + { + sys_width = w; + sys_height = h; + } + pclose(fd); + } + } + } +#else +#ifdef TIOCGWINSZ + { + struct winsize w; + if (ioctl(2, TIOCGWINSZ, &w) == 0) + { + if (w.ws_row > 0) + sys_height = w.ws_row; + if (w.ws_col > 0) + sys_width = w.ws_col; + } + } +#else +#ifdef WIOCGETD + { + struct uwdata w; + if (ioctl(2, WIOCGETD, &w) == 0) + { + if (w.uw_height > 0) + sys_height = w.uw_height / w.uw_vs; + if (w.uw_width > 0) + sys_width = w.uw_width / w.uw_hs; + } + } +#endif +#endif +#endif +#endif +#endif +#endif + } + + if (sys_height > 0) + sc_height = sys_height; + else if ((s = lgetenv("LINES")) != NULL) + sc_height = atoi(s); +#if !MSDOS_COMPILER + else if ((n = ltgetnum("li")) > 0) + sc_height = n; +#endif + if ((s = lgetenv("LESS_LINES")) != NULL) + { + int height = atoi(s); + sc_height = (height < 0) ? sc_height + height : height; + full_screen = FALSE; + } + if (sc_height <= 0) + sc_height = DEF_SC_HEIGHT; + + if (sys_width > 0) + sc_width = sys_width; + else if ((s = lgetenv("COLUMNS")) != NULL) + sc_width = atoi(s); +#if !MSDOS_COMPILER + else if ((n = ltgetnum("co")) > 0) + sc_width = n; +#endif + if ((s = lgetenv("LESS_COLUMNS")) != NULL) + { + int width = atoi(s); + sc_width = (width < 0) ? sc_width + width : width; + } + if (sc_width <= 0) + sc_width = DEF_SC_WIDTH; +} + +#if MSDOS_COMPILER==MSOFTC +/* + * Figure out how many empty loops it takes to delay a millisecond. + */ +static void get_clock(void) +{ + clock_t start; + + /* + * Get synchronized at the start of a tick. + */ + start = clock(); + while (clock() == start) + ; + /* + * Now count loops till the next tick. + */ + start = clock(); + msec_loops = 0; + while (clock() == start) + msec_loops++; + /* + * Convert from (loops per clock) to (loops per millisecond). + */ + msec_loops *= CLOCKS_PER_SEC; + msec_loops /= 1000; +} + +/* + * Delay for a specified number of milliseconds. + */ +static void delay(int msec) +{ + long i; + + while (msec-- > 0) + { + for (i = 0; i < msec_loops; i++) + (void) clock(); + } +} +#endif + +/* + * Return the characters actually input by a "special" key. + */ +public char * special_key_str(int key) +{ + static char tbuf[40]; + char *s; +#if MSDOS_COMPILER || OS2 + static char k_right[] = { '\340', PCK_RIGHT, 0 }; + static char k_left[] = { '\340', PCK_LEFT, 0 }; + static char k_ctl_right[] = { '\340', PCK_CTL_RIGHT, 0 }; + static char k_ctl_left[] = { '\340', PCK_CTL_LEFT, 0 }; + static char k_insert[] = { '\340', PCK_INSERT, 0 }; + static char k_delete[] = { '\340', PCK_DELETE, 0 }; + static char k_ctl_delete[] = { '\340', PCK_CTL_DELETE, 0 }; + static char k_ctl_backspace[] = { '\177', 0 }; + static char k_backspace[] = { '\b', 0 }; + static char k_home[] = { '\340', PCK_HOME, 0 }; + static char k_end[] = { '\340', PCK_END, 0 }; + static char k_up[] = { '\340', PCK_UP, 0 }; + static char k_down[] = { '\340', PCK_DOWN, 0 }; + static char k_backtab[] = { '\340', PCK_SHIFT_TAB, 0 }; + static char k_pagedown[] = { '\340', PCK_PAGEDOWN, 0 }; + static char k_pageup[] = { '\340', PCK_PAGEUP, 0 }; + static char k_f1[] = { '\340', PCK_F1, 0 }; +#endif +#if !MSDOS_COMPILER + char *sp = tbuf; +#endif + + switch (key) + { +#if OS2 + /* + * If windowid is not NULL, assume less is executed in + * the XFree86 environment. + */ + case SK_RIGHT_ARROW: + s = windowid ? ltgetstr("kr", &sp) : k_right; + break; + case SK_LEFT_ARROW: + s = windowid ? ltgetstr("kl", &sp) : k_left; + break; + case SK_UP_ARROW: + s = windowid ? ltgetstr("ku", &sp) : k_up; + break; + case SK_DOWN_ARROW: + s = windowid ? ltgetstr("kd", &sp) : k_down; + break; + case SK_PAGE_UP: + s = windowid ? ltgetstr("kP", &sp) : k_pageup; + break; + case SK_PAGE_DOWN: + s = windowid ? ltgetstr("kN", &sp) : k_pagedown; + break; + case SK_HOME: + s = windowid ? ltgetstr("kh", &sp) : k_home; + break; + case SK_END: + s = windowid ? ltgetstr("@7", &sp) : k_end; + break; + case SK_DELETE: + s = windowid ? ltgetstr("kD", &sp) : k_delete; + if (s == NULL) + { + tbuf[0] = '\177'; + tbuf[1] = '\0'; + s = tbuf; + } + break; +#endif +#if MSDOS_COMPILER + case SK_RIGHT_ARROW: + s = k_right; + break; + case SK_LEFT_ARROW: + s = k_left; + break; + case SK_UP_ARROW: + s = k_up; + break; + case SK_DOWN_ARROW: + s = k_down; + break; + case SK_PAGE_UP: + s = k_pageup; + break; + case SK_PAGE_DOWN: + s = k_pagedown; + break; + case SK_HOME: + s = k_home; + break; + case SK_END: + s = k_end; + break; + case SK_DELETE: + s = k_delete; + break; +#endif +#if MSDOS_COMPILER || OS2 + case SK_INSERT: + s = k_insert; + break; + case SK_CTL_LEFT_ARROW: + s = k_ctl_left; + break; + case SK_CTL_RIGHT_ARROW: + s = k_ctl_right; + break; + case SK_CTL_BACKSPACE: + s = k_ctl_backspace; + break; + case SK_CTL_DELETE: + s = k_ctl_delete; + break; + case SK_BACKSPACE: + s = k_backspace; + break; + case SK_F1: + s = k_f1; + break; + case SK_BACKTAB: + s = k_backtab; + break; +#else + case SK_RIGHT_ARROW: + s = ltgetstr("kr", &sp); + break; + case SK_LEFT_ARROW: + s = ltgetstr("kl", &sp); + break; + case SK_UP_ARROW: + s = ltgetstr("ku", &sp); + break; + case SK_DOWN_ARROW: + s = ltgetstr("kd", &sp); + break; + case SK_PAGE_UP: + s = ltgetstr("kP", &sp); + break; + case SK_PAGE_DOWN: + s = ltgetstr("kN", &sp); + break; + case SK_HOME: + s = ltgetstr("kh", &sp); + break; + case SK_END: + s = ltgetstr("@7", &sp); + break; + case SK_DELETE: + s = ltgetstr("kD", &sp); + if (s == NULL) + { + tbuf[0] = '\177'; + tbuf[1] = '\0'; + s = tbuf; + } + break; + case SK_BACKSPACE: + s = ltgetstr("kb", &sp); + if (s == NULL) + { + tbuf[0] = '\b'; + tbuf[1] = '\0'; + s = tbuf; + } + break; +#endif + case SK_CONTROL_K: + tbuf[0] = CONTROL('K'); + tbuf[1] = '\0'; + s = tbuf; + break; + default: + return (NULL); + } + return (s); +} + +/* + * Get terminal capabilities via termcap. + */ +public void get_term(void) +{ + termcap_debug = !isnullenv(lgetenv("LESS_TERMCAP_DEBUG")); +#if MSDOS_COMPILER + auto_wrap = 1; + ignaw = 0; + can_goto_line = 1; + clear_bg = 1; + /* + * Set up default colors. + * The xx_s_width and xx_e_width vars are already initialized to 0. + */ +#if MSDOS_COMPILER==MSOFTC + sy_bg_color = _getbkcolor(); + sy_fg_color = _gettextcolor(); + get_clock(); +#else +#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC + { + struct text_info w; + gettextinfo(&w); + sy_bg_color = (w.attribute >> 4) & 0x0F; + sy_fg_color = (w.attribute >> 0) & 0x0F; + } +#else +#if MSDOS_COMPILER==WIN32C + { + CONSOLE_SCREEN_BUFFER_INFO scr; + + con_out_save = con_out = GetStdHandle(STD_OUTPUT_HANDLE); + /* + * Always open stdin in binary. Note this *must* be done + * before any file operations have been done on fd0. + */ + SET_BINARY(0); + GetConsoleMode(con_out, &init_output_mode); + GetConsoleScreenBufferInfo(con_out, &scr); + curr_attr = scr.wAttributes; + sy_bg_color = (curr_attr & BG_COLORS) >> 4; /* normalize */ + sy_fg_color = curr_attr & FG_COLORS; + } +#endif +#endif +#endif + nm_fg_color = sy_fg_color; + nm_bg_color = sy_bg_color; + bo_fg_color = 11; + bo_bg_color = 0; + ul_fg_color = 9; + ul_bg_color = 0; + so_fg_color = 15; + so_bg_color = 9; + bl_fg_color = 15; + bl_bg_color = 0; + sgr_mode = 0; + + /* + * Get size of the screen. + */ + scrsize(); + pos_init(); + + +#else /* !MSDOS_COMPILER */ +{ + char *sp; + char *t1, *t2; + char *term; + /* + * Some termcap libraries assume termbuf is static + * (accessible after tgetent returns). + */ + static char termbuf[TERMBUF_SIZE]; + static char sbuf[TERMSBUF_SIZE]; + +#if OS2 + /* + * Make sure the termcap database is available. + */ + sp = lgetenv("TERMCAP"); + if (isnullenv(sp)) + { + char *termcap; + if ((sp = homefile("termcap.dat")) != NULL) + { + termcap = (char *) ecalloc(strlen(sp)+9, sizeof(char)); + sprintf(termcap, "TERMCAP=%s", sp); + free(sp); + putenv(termcap); + } + } +#endif + /* + * Find out what kind of terminal this is. + */ + if ((term = lgetenv("TERM")) == NULL) + term = DEFAULT_TERM; + hardcopy = 0; + /* {{ Should probably just pass NULL instead of termbuf. }} */ + if (tgetent(termbuf, term) != TGETENT_OK) + hardcopy = 1; + if (ltgetflag("hc")) + hardcopy = 1; + + /* + * Get size of the screen. + */ + scrsize(); + pos_init(); + + auto_wrap = ltgetflag("am"); + ignaw = ltgetflag("xn"); + above_mem = ltgetflag("da"); + below_mem = ltgetflag("db"); + clear_bg = ltgetflag("ut"); + no_alt_screen = ltgetflag("NR"); + + /* + * 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_s_width = ltgetnum("sg")) < 0) + so_s_width = 0; + so_e_width = so_s_width; + + bo_s_width = bo_e_width = so_s_width; + ul_s_width = ul_e_width = so_s_width; + bl_s_width = bl_e_width = so_s_width; + +#if HILITE_SEARCH + if (so_s_width > 0 || so_e_width > 0) + /* + * Disable highlighting by default on magic cookie terminals. + * Turning on highlighting might change the displayed width + * of a line, causing the display to get messed up. + * The user can turn it back on with -g, + * but she won't like the results. + */ + hilite_search = 0; +#endif + + /* + * Get various string-valued capabilities. + */ + sp = sbuf; + +#if HAVE_OSPEED + sc_pad = ltgetstr("pc", &sp); + if (sc_pad != NULL) + PC = *sc_pad; +#endif + + sc_s_keypad = ltgetstr("ks", &sp); + if (sc_s_keypad == NULL) + sc_s_keypad = ""; + sc_e_keypad = ltgetstr("ke", &sp); + if (sc_e_keypad == NULL) + sc_e_keypad = ""; + kent = ltgetstr("@8", &sp); + + sc_s_mousecap = ltgetstr("MOUSE_START", &sp); + if (sc_s_mousecap == NULL) + sc_s_mousecap = ESCS "[?1000h" ESCS "[?1006h"; + sc_e_mousecap = ltgetstr("MOUSE_END", &sp); + if (sc_e_mousecap == NULL) + sc_e_mousecap = ESCS "[?1006l" ESCS "[?1000l"; + + sc_init = ltgetstr("ti", &sp); + if (sc_init == NULL) + sc_init = ""; + + sc_deinit= ltgetstr("te", &sp); + if (sc_deinit == NULL) + sc_deinit = ""; + + sc_eol_clear = ltgetstr("ce", &sp); + if (sc_eol_clear == NULL || *sc_eol_clear == '\0') + { + missing_cap = 1; + sc_eol_clear = ""; + } + + sc_eos_clear = ltgetstr("cd", &sp); + if (below_mem && (sc_eos_clear == NULL || *sc_eos_clear == '\0')) + { + missing_cap = 1; + sc_eos_clear = ""; + } + + sc_clear = ltgetstr("cl", &sp); + if (sc_clear == NULL || *sc_clear == '\0') + { + missing_cap = 1; + sc_clear = "\n\n"; + } + + sc_move = ltgetstr("cm", &sp); + if (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 = ""; + can_goto_line = 0; + } else + can_goto_line = 1; + + tmodes("so", "se", &sc_s_in, &sc_s_out, "", "", &sp); + tmodes("us", "ue", &sc_u_in, &sc_u_out, sc_s_in, sc_s_out, &sp); + tmodes("md", "me", &sc_b_in, &sc_b_out, sc_s_in, sc_s_out, &sp); + tmodes("mb", "me", &sc_bl_in, &sc_bl_out, sc_s_in, sc_s_out, &sp); + + sc_visual_bell = ltgetstr("vb", &sp); + if (sc_visual_bell == NULL) + sc_visual_bell = ""; + + if (ltgetflag("bs")) + sc_backspace = "\b"; + else + { + sc_backspace = ltgetstr("bc", &sp); + if (sc_backspace == NULL || *sc_backspace == '\0') + sc_backspace = "\b"; + } + + /* + * Choose between using "ho" and "cm" ("home" and "cursor move") + * to move the cursor to the upper left corner of the screen. + */ + t1 = ltgetstr("ho", &sp); + if (t1 == NULL) + t1 = ""; + if (*sc_move == '\0') + t2 = ""; + else + { + strcpy(sp, tgoto(sc_move, 0, 0)); + t2 = sp; + sp += strlen(sp) + 1; + } + sc_home = cheaper(t1, t2, "|\b^"); + + /* + * Choose between using "ll" and "cm" ("lower left" and "cursor move") + * to move the cursor to the lower left corner of the screen. + */ + t1 = ltgetstr("ll", &sp); + if (t1 == NULL || !full_screen) + t1 = ""; + if (*sc_move == '\0') + t2 = ""; + else + { + strcpy(sp, tgoto(sc_move, 0, sc_height-1)); + t2 = sp; + sp += strlen(sp) + 1; + } + sc_lower_left = cheaper(t1, t2, "\r"); + + /* + * Get carriage return string. + */ + sc_return = ltgetstr("cr", &sp); + if (sc_return == NULL) + sc_return = "\r"; + + /* + * Choose between using "al" or "sr" ("add line" or "scroll reverse") + * to add a line at the top of the screen. + */ + t1 = ltgetstr("al", &sp); + if (t1 == NULL) + t1 = ""; + t2 = ltgetstr("sr", &sp); + if (t2 == NULL) + t2 = ""; +#if OS2 + if (*t1 == '\0' && *t2 == '\0') + sc_addline = ""; + else +#endif + if (above_mem) + sc_addline = t1; + else + sc_addline = cheaper(t1, t2, ""); + if (*sc_addline == '\0') + { + /* + * Force repaint on any backward movement. + */ + no_back_scroll = 1; + } +} +#endif /* MSDOS_COMPILER */ +} + +#if !MSDOS_COMPILER +/* + * Return the cost of displaying a termcap string. + * We use the trick of calling tputs, but as a char printing function + * we give it inc_costcount, which just increments "costcount". + * This tells us how many chars would be printed by using this string. + * {{ Couldn't we just use strlen? }} + */ +static int costcount; + +/*ARGSUSED*/ +static int inc_costcount(int c) +{ + costcount++; + return (c); +} + +static int cost(char *t) +{ + costcount = 0; + tputs(t, sc_height, inc_costcount); + return (costcount); +} + +/* + * Return the "best" of the two given termcap strings. + * The best, if both exist, is the one with the lower + * cost (see cost() function). + */ +static char * cheaper(char *t1, char *t2, char *def) +{ + if (*t1 == '\0' && *t2 == '\0') + { + missing_cap = 1; + return (def); + } + if (*t1 == '\0') + return (t2); + if (*t2 == '\0') + return (t1); + if (cost(t1) < cost(t2)) + return (t1); + return (t2); +} + +static void tmodes(char *incap, char *outcap, char **instr, char **outstr, char *def_instr, char *def_outstr, char **spp) +{ + *instr = ltgetstr(incap, spp); + if (*instr == NULL) + { + /* Use defaults. */ + *instr = def_instr; + *outstr = def_outstr; + return; + } + + *outstr = ltgetstr(outcap, spp); + if (*outstr == NULL) + /* No specific out capability; use "me". */ + *outstr = ltgetstr("me", spp); + if (*outstr == NULL) + /* Don't even have "me"; use a null string. */ + *outstr = ""; +} + +#endif /* MSDOS_COMPILER */ + + +/* + * Below are the functions which perform all the + * terminal-specific screen manipulation. + */ + + +#if MSDOS_COMPILER + +#if MSDOS_COMPILER==WIN32C +static void _settextposition(int row, int col) +{ + COORD cpos; + CONSOLE_SCREEN_BUFFER_INFO csbi; + + GetConsoleScreenBufferInfo(con_out, &csbi); + cpos.X = csbi.srWindow.Left + (col - 1); + cpos.Y = csbi.srWindow.Top + (row - 1); + SetConsoleCursorPosition(con_out, cpos); +} +#endif + +/* + * Initialize the screen to the correct color at startup. + */ +static void initcolor(void) +{ +#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC + intensevideo(); +#endif + SETCOLORS(nm_fg_color, nm_bg_color); +#if 0 + /* + * This clears the screen at startup. This is different from + * the behavior of other versions of less. Disable it for now. + */ + char *blanks; + int row; + int col; + + /* + * Create a complete, blank screen using "normal" colors. + */ + SETCOLORS(nm_fg_color, nm_bg_color); + blanks = (char *) ecalloc(width+1, sizeof(char)); + for (col = 0; col < sc_width; col++) + blanks[col] = ' '; + blanks[sc_width] = '\0'; + for (row = 0; row < sc_height; row++) + _outtext(blanks); + free(blanks); +#endif +} +#endif + +#if MSDOS_COMPILER==WIN32C + +/* + * Enable virtual terminal processing, if available. + */ +static void win32_init_vt_term(void) +{ + DWORD output_mode; + + if (vt_enabled == 0 || (vt_enabled == 1 && con_out == con_out_ours)) + return; + + GetConsoleMode(con_out, &output_mode); + vt_enabled = SetConsoleMode(con_out, + output_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING); + if (vt_enabled) + { + auto_wrap = 0; + ignaw = 1; + } +} + +static void win32_deinit_vt_term(void) +{ + if (vt_enabled == 1 && con_out == con_out_save) + SetConsoleMode(con_out, init_output_mode); +} + +/* + * Termcap-like init with a private win32 console. + */ +static void win32_init_term(void) +{ + CONSOLE_SCREEN_BUFFER_INFO scr; + COORD size; + + if (con_out_save == INVALID_HANDLE_VALUE) + return; + + GetConsoleScreenBufferInfo(con_out_save, &scr); + + if (con_out_ours == INVALID_HANDLE_VALUE) + { + /* + * Create our own screen buffer, so that we + * may restore the original when done. + */ + con_out_ours = CreateConsoleScreenBuffer( + GENERIC_WRITE | GENERIC_READ, + FILE_SHARE_WRITE | FILE_SHARE_READ, + (LPSECURITY_ATTRIBUTES) NULL, + CONSOLE_TEXTMODE_BUFFER, + (LPVOID) NULL); + } + + size.X = scr.srWindow.Right - scr.srWindow.Left + 1; + size.Y = scr.srWindow.Bottom - scr.srWindow.Top + 1; + SetConsoleScreenBufferSize(con_out_ours, size); + SetConsoleActiveScreenBuffer(con_out_ours); + con_out = con_out_ours; +} + +/* + * Restore the startup console. + */ +static void win32_deinit_term(void) +{ + if (con_out_save == INVALID_HANDLE_VALUE) + return; + if (quitting) + (void) CloseHandle(con_out_ours); + SetConsoleActiveScreenBuffer(con_out_save); + con_out = con_out_save; +} + +#endif + +#if !MSDOS_COMPILER +static void do_tputs(char *str, int affcnt, int (*f_putc)(int)) +{ +#if LESSTEST + if (ttyin_name != NULL && f_putc == putchr) + putstr(str); + else +#endif /*LESSTEST*/ + tputs(str, affcnt, f_putc); +} + +/* + * Like tputs but we handle $<...> delay strings here because + * some implementations of tputs don't perform delays correctly. + */ +static void ltputs(char *str, int affcnt, int (*f_putc)(int)) +{ + while (str != NULL && *str != '\0') + { +#if HAVE_STRSTR + char *obrac = strstr(str, "$<"); + if (obrac != NULL) + { + char str2[64]; + int slen = obrac - str; + if (slen < sizeof(str2)) + { + int delay; + /* Output first part of string (before "$<"). */ + memcpy(str2, str, slen); + str2[slen] = '\0'; + do_tputs(str2, affcnt, f_putc); + str += slen + 2; + /* Perform the delay. */ + delay = lstrtoi(str, &str, 10); + if (*str == '*') + if (ckd_mul(&delay, delay, affcnt)) + delay = INT_MAX; + flush(); + sleep_ms(delay); + /* Skip past closing ">" at end of delay string. */ + str = strstr(str, ">"); + if (str != NULL) + str++; + continue; + } + } +#endif + /* Pass the rest of the string to tputs and we're done. */ + do_tputs(str, affcnt, f_putc); + break; + } +} +#endif /* MSDOS_COMPILER */ + +/* + * Configure the terminal so mouse clicks and wheel moves + * produce input to less. + */ +public void init_mouse(void) +{ +#if !MSDOS_COMPILER + ltputs(sc_s_mousecap, sc_height, putchr); +#else +#if MSDOS_COMPILER==WIN32C + SetConsoleMode(tty, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT + | ENABLE_EXTENDED_FLAGS /* disable quick edit */); + +#endif +#endif +} + +/* + * Configure the terminal so mouse clicks and wheel moves + * are handled by the system (so text can be selected, etc). + */ +public void deinit_mouse(void) +{ +#if !MSDOS_COMPILER + ltputs(sc_e_mousecap, sc_height, putchr); +#else +#if MSDOS_COMPILER==WIN32C + SetConsoleMode(tty, ENABLE_PROCESSED_INPUT | ENABLE_EXTENDED_FLAGS + | (console_mode & ENABLE_QUICK_EDIT_MODE)); +#endif +#endif +} + +/* + * Initialize terminal + */ +public void init(void) +{ + clear_bot_if_needed(); +#if !MSDOS_COMPILER + if (!(quit_if_one_screen && one_screen)) + { + if (!no_init) + { + ltputs(sc_init, sc_height, putchr); + /* + * Some terminals leave the cursor unmoved when switching + * to the alt screen. To avoid having the text appear at + * a seemingly random line on the alt screen, move to + * lower left if we are using an alt screen. + */ + if (*sc_init != '\0' && *sc_deinit != '\0' && !no_alt_screen) + lower_left(); + term_init_done = 1; + } + if (!no_keypad) + ltputs(sc_s_keypad, sc_height, putchr); + if (mousecap) + init_mouse(); + } + init_done = 1; + if (top_scroll) + { + int i; + + /* + * This is nice to terminals with no alternate screen, + * but with saved scrolled-off-the-top lines. This way, + * no previous line is lost, but we start with a whole + * screen to ourself. + */ + for (i = 1; i < sc_height; i++) + putchr('\n'); + } else + line_left(); +#else +#if MSDOS_COMPILER==WIN32C + if (!(quit_if_one_screen && one_screen)) + { + if (!no_init) + { + win32_init_term(); + term_init_done = 1; + } + if (mousecap) + init_mouse(); + + } + win32_init_vt_term(); +#endif + init_done = 1; + initcolor(); + flush(); +#endif +} + +/* + * Deinitialize terminal + */ +public void deinit(void) +{ + if (!init_done) + return; +#if !MSDOS_COMPILER + if (!(quit_if_one_screen && one_screen)) + { + if (mousecap) + deinit_mouse(); + if (!no_keypad) + ltputs(sc_e_keypad, sc_height, putchr); + if (!no_init) + ltputs(sc_deinit, sc_height, putchr); + } +#else + /* Restore system colors. */ + SETCOLORS(sy_fg_color, sy_bg_color); +#if MSDOS_COMPILER==WIN32C + win32_deinit_vt_term(); + if (!(quit_if_one_screen && one_screen)) + { + if (mousecap) + deinit_mouse(); + if (!no_init) + win32_deinit_term(); + } +#else + /* Need clreol to make SETCOLORS take effect. */ + clreol(); +#endif +#endif + init_done = 0; +} + +/* + * Are we interactive (ie. writing to an initialized tty)? + */ +public int interactive(void) +{ + return (is_tty && init_done); +} + +static void assert_interactive(void) +{ + if (interactive()) return; + /* abort(); */ +} + +/* + * Home cursor (move to upper left corner of screen). + */ +public void home(void) +{ + assert_interactive(); +#if !MSDOS_COMPILER + ltputs(sc_home, 1, putchr); +#else + flush(); + _settextposition(1,1); +#endif +} + +#if LESSTEST +public void dump_screen(void) +{ + char dump_cmd[32]; + SNPRINTF1(dump_cmd, sizeof(dump_cmd), ESCS"0;0;%dR", sc_width * sc_height); + ltputs(dump_cmd, sc_height, putchr); + flush(); +} +#endif /*LESSTEST*/ + +/* + * Add a blank line (called with cursor at home). + * Should scroll the display down. + */ +public void add_line(void) +{ + assert_interactive(); +#if !MSDOS_COMPILER + ltputs(sc_addline, sc_height, putchr); +#else + flush(); +#if MSDOS_COMPILER==MSOFTC + _scrolltextwindow(_GSCROLLDOWN); + _settextposition(1,1); +#else +#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC + movetext(1,1, sc_width,sc_height-1, 1,2); + gotoxy(1,1); + clreol(); +#else +#if MSDOS_COMPILER==WIN32C + { + CHAR_INFO fillchar; + SMALL_RECT rcSrc, rcClip; + COORD new_org; + CONSOLE_SCREEN_BUFFER_INFO csbi; + + GetConsoleScreenBufferInfo(con_out,&csbi); + + /* The clip rectangle is the entire visible screen. */ + rcClip.Left = csbi.srWindow.Left; + rcClip.Top = csbi.srWindow.Top; + rcClip.Right = csbi.srWindow.Right; + rcClip.Bottom = csbi.srWindow.Bottom; + + /* The source rectangle is the visible screen minus the last line. */ + rcSrc = rcClip; + rcSrc.Bottom--; + + /* Move the top left corner of the source window down one row. */ + new_org.X = rcSrc.Left; + new_org.Y = rcSrc.Top + 1; + + /* Fill the right character and attributes. */ + fillchar.Char.AsciiChar = ' '; + curr_attr = MAKEATTR(nm_fg_color, nm_bg_color); + fillchar.Attributes = curr_attr; + ScrollConsoleScreenBuffer(con_out, &rcSrc, &rcClip, new_org, &fillchar); + _settextposition(1,1); + } +#endif +#endif +#endif +#endif +} + +#if 0 +/* + * Remove the n topmost lines and scroll everything below it in the + * window upward. This is needed to stop leaking the topmost line + * into the scrollback buffer when we go down-one-line (in WIN32). + */ +public void remove_top(int n) +{ +#if MSDOS_COMPILER==WIN32C + SMALL_RECT rcSrc, rcClip; + CHAR_INFO fillchar; + COORD new_org; + CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */ + + if (n >= sc_height - 1) + { + clear(); + home(); + return; + } + + flush(); + + GetConsoleScreenBufferInfo(con_out, &csbi); + + /* Get the extent of all-visible-rows-but-the-last. */ + rcSrc.Left = csbi.srWindow.Left; + rcSrc.Top = csbi.srWindow.Top + n; + rcSrc.Right = csbi.srWindow.Right; + rcSrc.Bottom = csbi.srWindow.Bottom; + + /* Get the clip rectangle. */ + rcClip.Left = rcSrc.Left; + rcClip.Top = csbi.srWindow.Top; + rcClip.Right = rcSrc.Right; + rcClip.Bottom = rcSrc.Bottom ; + + /* Move the source window up n rows. */ + new_org.X = rcSrc.Left; + new_org.Y = rcSrc.Top - n; + + /* Fill the right character and attributes. */ + fillchar.Char.AsciiChar = ' '; + curr_attr = MAKEATTR(nm_fg_color, nm_bg_color); + fillchar.Attributes = curr_attr; + + ScrollConsoleScreenBuffer(con_out, &rcSrc, &rcClip, new_org, &fillchar); + + /* Position cursor on first blank line. */ + goto_line(sc_height - n - 1); +#endif +} +#endif + +#if MSDOS_COMPILER==WIN32C +/* + * Clear the screen. + */ +static void win32_clear(void) +{ + /* + * This will clear only the currently visible rows of the NT + * console buffer, which means none of the precious scrollback + * rows are touched making for faster scrolling. Note that, if + * the window has fewer columns than the console buffer (i.e. + * there is a horizontal scrollbar as well), the entire width + * of the visible rows will be cleared. + */ + COORD topleft; + DWORD nchars; + DWORD winsz; + CONSOLE_SCREEN_BUFFER_INFO csbi; + + /* get the number of cells in the current buffer */ + GetConsoleScreenBufferInfo(con_out, &csbi); + winsz = csbi.dwSize.X * (csbi.srWindow.Bottom - csbi.srWindow.Top + 1); + topleft.X = 0; + topleft.Y = csbi.srWindow.Top; + + curr_attr = MAKEATTR(nm_fg_color, nm_bg_color); + FillConsoleOutputCharacter(con_out, ' ', winsz, topleft, &nchars); + FillConsoleOutputAttribute(con_out, curr_attr, winsz, topleft, &nchars); +} + +/* + * Remove the n topmost lines and scroll everything below it in the + * window upward. + */ +public void win32_scroll_up(int n) +{ + SMALL_RECT rcSrc, rcClip; + CHAR_INFO fillchar; + COORD topleft; + COORD new_org; + DWORD nchars; + DWORD size; + CONSOLE_SCREEN_BUFFER_INFO csbi; + + if (n <= 0) + return; + + if (n >= sc_height - 1) + { + win32_clear(); + _settextposition(1,1); + return; + } + + /* Get the extent of what will remain visible after scrolling. */ + GetConsoleScreenBufferInfo(con_out, &csbi); + rcSrc.Left = csbi.srWindow.Left; + rcSrc.Top = csbi.srWindow.Top + n; + rcSrc.Right = csbi.srWindow.Right; + rcSrc.Bottom = csbi.srWindow.Bottom; + + /* Get the clip rectangle. */ + rcClip.Left = rcSrc.Left; + rcClip.Top = csbi.srWindow.Top; + rcClip.Right = rcSrc.Right; + rcClip.Bottom = rcSrc.Bottom ; + + /* Move the source text to the top of the screen. */ + new_org.X = rcSrc.Left; + new_org.Y = rcClip.Top; + + /* Fill the right character and attributes. */ + fillchar.Char.AsciiChar = ' '; + fillchar.Attributes = MAKEATTR(nm_fg_color, nm_bg_color); + + /* Scroll the window. */ + SetConsoleTextAttribute(con_out, fillchar.Attributes); + ScrollConsoleScreenBuffer(con_out, &rcSrc, &rcClip, new_org, &fillchar); + + /* Clear remaining lines at bottom. */ + topleft.X = csbi.dwCursorPosition.X; + topleft.Y = rcSrc.Bottom - n; + size = (n * csbi.dwSize.X) + (rcSrc.Right - topleft.X); + FillConsoleOutputCharacter(con_out, ' ', size, topleft, + &nchars); + FillConsoleOutputAttribute(con_out, fillchar.Attributes, size, topleft, + &nchars); + SetConsoleTextAttribute(con_out, curr_attr); + + /* Move cursor n lines up from where it was. */ + csbi.dwCursorPosition.Y -= n; + SetConsoleCursorPosition(con_out, csbi.dwCursorPosition); +} +#endif + +/* + * Move cursor to lower left corner of screen. + */ +public void lower_left(void) +{ + assert_interactive(); +#if !MSDOS_COMPILER + ltputs(sc_lower_left, 1, putchr); +#else + flush(); + _settextposition(sc_height, 1); +#endif +} + +/* + * Move cursor to left position of current line. + */ +public void line_left(void) +{ + assert_interactive(); +#if !MSDOS_COMPILER + ltputs(sc_return, 1, putchr); +#else + { + int row; + flush(); +#if MSDOS_COMPILER==WIN32C + { + CONSOLE_SCREEN_BUFFER_INFO scr; + GetConsoleScreenBufferInfo(con_out, &scr); + row = scr.dwCursorPosition.Y - scr.srWindow.Top + 1; + } +#else +#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC + row = wherey(); +#else + { + struct rccoord tpos = _gettextposition(); + row = tpos.row; + } +#endif +#endif + _settextposition(row, 1); + } +#endif +} + +/* + * Check if the console size has changed and reset internals + * (in lieu of SIGWINCH for WIN32). + */ +public void check_winch(void) +{ +#if MSDOS_COMPILER==WIN32C + CONSOLE_SCREEN_BUFFER_INFO scr; + COORD size; + + if (con_out == INVALID_HANDLE_VALUE) + return; + + flush(); + GetConsoleScreenBufferInfo(con_out, &scr); + size.Y = scr.srWindow.Bottom - scr.srWindow.Top + 1; + size.X = scr.srWindow.Right - scr.srWindow.Left + 1; + if (size.Y != sc_height || size.X != sc_width) + { + sc_height = size.Y; + sc_width = size.X; + if (!no_init && con_out_ours == con_out) + SetConsoleScreenBufferSize(con_out, size); + pos_init(); + wscroll = (sc_height + 1) / 2; + screen_trashed = 1; + } +#endif +} + +/* + * Goto a specific line on the screen. + */ +public void goto_line(int sindex) +{ + assert_interactive(); +#if !MSDOS_COMPILER + ltputs(tgoto(sc_move, 0, sindex), 1, putchr); +#else + flush(); + _settextposition(sindex+1, 1); +#endif +} + +#if MSDOS_COMPILER==MSOFTC || MSDOS_COMPILER==BORLANDC +/* + * Create an alternate screen which is all white. + * This screen is used to create a "flash" effect, by displaying it + * briefly and then switching back to the normal screen. + * {{ Yuck! There must be a better way to get a visual bell. }} + */ +static void create_flash(void) +{ +#if MSDOS_COMPILER==MSOFTC + struct videoconfig w; + char *blanks; + int row, col; + + _getvideoconfig(&w); + videopages = w.numvideopages; + if (videopages < 2) + { + at_enter(AT_STANDOUT); + at_exit(); + } else + { + _setactivepage(1); + at_enter(AT_STANDOUT); + blanks = (char *) ecalloc(w.numtextcols, sizeof(char)); + for (col = 0; col < w.numtextcols; col++) + blanks[col] = ' '; + for (row = w.numtextrows; row > 0; row--) + _outmem(blanks, w.numtextcols); + _setactivepage(0); + _setvisualpage(0); + free(blanks); + at_exit(); + } +#else +#if MSDOS_COMPILER==BORLANDC + int n; + + whitescreen = (unsigned short *) + malloc(sc_width * sc_height * sizeof(short)); + if (whitescreen == NULL) + return; + for (n = 0; n < sc_width * sc_height; n++) + whitescreen[n] = 0x7020; +#endif +#endif + flash_created = 1; +} +#endif /* MSDOS_COMPILER */ + +/* + * Output the "visual bell", if there is one. + */ +public void vbell(void) +{ + if (no_vbell) + return; +#if !MSDOS_COMPILER + if (*sc_visual_bell == '\0') + return; + ltputs(sc_visual_bell, sc_height, putchr); +#else +#if MSDOS_COMPILER==DJGPPC + ScreenVisualBell(); +#else +#if MSDOS_COMPILER==MSOFTC + /* + * Create a flash screen on the second video page. + * Switch to that page, then switch back. + */ + if (!flash_created) + create_flash(); + if (videopages < 2) + return; + _setvisualpage(1); + delay(100); + _setvisualpage(0); +#else +#if MSDOS_COMPILER==BORLANDC + unsigned short *currscreen; + + /* + * Get a copy of the current screen. + * Display the flash screen. + * Then restore the old screen. + */ + if (!flash_created) + create_flash(); + if (whitescreen == NULL) + return; + currscreen = (unsigned short *) + malloc(sc_width * sc_height * sizeof(short)); + if (currscreen == NULL) return; + gettext(1, 1, sc_width, sc_height, currscreen); + puttext(1, 1, sc_width, sc_height, whitescreen); + delay(100); + puttext(1, 1, sc_width, sc_height, currscreen); + free(currscreen); +#else +#if MSDOS_COMPILER==WIN32C + /* paint screen with an inverse color */ + clear(); + + /* leave it displayed for 100 msec. */ + Sleep(100); + + /* restore with a redraw */ + repaint(); +#endif +#endif +#endif +#endif +#endif +} + +/* + * Make a noise. + */ +static void beep(void) +{ +#if !MSDOS_COMPILER + putchr(CONTROL('G')); +#else +#if MSDOS_COMPILER==WIN32C + MessageBeep(0); +#else + write(1, "\7", 1); +#endif +#endif +} + +/* + * Ring the terminal bell. + */ +public void bell(void) +{ + if (quiet == VERY_QUIET) + vbell(); + else + beep(); +} + +/* + * Clear the screen. + */ +public void clear(void) +{ + assert_interactive(); +#if !MSDOS_COMPILER + ltputs(sc_clear, sc_height, putchr); +#else + flush(); +#if MSDOS_COMPILER==WIN32C + win32_clear(); +#else + _clearscreen(_GCLEARSCREEN); +#endif +#endif +} + +/* + * Clear from the cursor to the end of the cursor's line. + * {{ This must not move the cursor. }} + */ +public void clear_eol(void) +{ + /* assert_interactive();*/ +#if !MSDOS_COMPILER + ltputs(sc_eol_clear, 1, putchr); +#else +#if MSDOS_COMPILER==MSOFTC + short top, left; + short bot, right; + struct rccoord tpos; + + flush(); + /* + * Save current state. + */ + tpos = _gettextposition(); + _gettextwindow(&top, &left, &bot, &right); + /* + * Set a temporary window to the current line, + * from the cursor's position to the right edge of the screen. + * Then clear that window. + */ + _settextwindow(tpos.row, tpos.col, tpos.row, sc_width); + _clearscreen(_GWINDOW); + /* + * Restore state. + */ + _settextwindow(top, left, bot, right); + _settextposition(tpos.row, tpos.col); +#else +#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC + flush(); + clreol(); +#else +#if MSDOS_COMPILER==WIN32C + DWORD nchars; + COORD cpos; + CONSOLE_SCREEN_BUFFER_INFO scr; + + flush(); + memset(&scr, 0, sizeof(scr)); + GetConsoleScreenBufferInfo(con_out, &scr); + cpos.X = scr.dwCursorPosition.X; + cpos.Y = scr.dwCursorPosition.Y; + curr_attr = MAKEATTR(nm_fg_color, nm_bg_color); + FillConsoleOutputAttribute(con_out, curr_attr, + scr.dwSize.X - cpos.X, cpos, &nchars); + FillConsoleOutputCharacter(con_out, ' ', + scr.dwSize.X - cpos.X, cpos, &nchars); +#endif +#endif +#endif +#endif +} + +/* + * Clear the current line. + * Clear the screen if there's off-screen memory below the display. + */ +static void clear_eol_bot(void) +{ + assert_interactive(); +#if MSDOS_COMPILER + clear_eol(); +#else + if (below_mem) + ltputs(sc_eos_clear, 1, putchr); + else + ltputs(sc_eol_clear, 1, putchr); +#endif +} + +/* + * Clear the bottom line of the display. + * Leave the cursor at the beginning of the bottom line. + */ +public void clear_bot(void) +{ + /* + * If we're in a non-normal attribute mode, temporarily exit + * the mode while we do the clear. Some terminals fill the + * cleared area with the current attribute. + */ + if (oldbot) + lower_left(); + else + line_left(); + + if (attrmode == AT_NORMAL) + clear_eol_bot(); + else + { + int saved_attrmode = attrmode; + + at_exit(); + clear_eol_bot(); + at_enter(saved_attrmode); + } +} + +/* + * Color string may be "x[y]" where x and y are 4-bit color chars, + * or "N[.M]" where N and M are decimal integers> + * Any of x,y,N,M may also be "-" to mean "unchanged". + */ + +/* + * Parse a 4-bit color char. + */ +static int parse_color4(char ch) +{ + switch (ch) + { + case 'k': return 0; + case 'r': return CV_RED; + case 'g': return CV_GREEN; + case 'y': return CV_RED|CV_GREEN; + case 'b': return CV_BLUE; + case 'm': return CV_RED|CV_BLUE; + case 'c': return CV_GREEN|CV_BLUE; + case 'w': return CV_RED|CV_GREEN|CV_BLUE; + case 'K': return 0|CV_BRIGHT; + case 'R': return CV_RED|CV_BRIGHT; + case 'G': return CV_GREEN|CV_BRIGHT; + case 'Y': return CV_RED|CV_GREEN|CV_BRIGHT; + case 'B': return CV_BLUE|CV_BRIGHT; + case 'M': return CV_RED|CV_BLUE|CV_BRIGHT; + case 'C': return CV_GREEN|CV_BLUE|CV_BRIGHT; + case 'W': return CV_RED|CV_GREEN|CV_BLUE|CV_BRIGHT; + case '-': return CV_NOCHANGE; + default: return CV_ERROR; + } +} + +/* + * Parse a color as a decimal integer. + */ +static int parse_color6(char **ps) +{ + if (**ps == '-') + { + (*ps)++; + return CV_NOCHANGE; + } else + { + char *ops = *ps; + int color = lstrtoi(ops, ps, 10); + if (color < 0 || *ps == ops) + return CV_ERROR; + return color; + } +} + +/* + * Parse a color pair and return the foreground/background values. + * Return type of color specifier: + * CV_4BIT: fg/bg values are OR of CV_{RGB} bits. + * CV_6BIT: fg/bg values are integers entered by user. + */ +public COLOR_TYPE parse_color(char *str, int *p_fg, int *p_bg) +{ + int fg; + int bg; + COLOR_TYPE type = CT_NULL; + + if (str == NULL || *str == '\0') + return CT_NULL; + if (*str == '+') + str++; /* ignore leading + */ + + fg = parse_color4(str[0]); + bg = parse_color4((strlen(str) < 2) ? '-' : str[1]); + if (fg != CV_ERROR && bg != CV_ERROR) + type = CT_4BIT; + else + { + fg = parse_color6(&str); + bg = (fg != CV_ERROR && *str++ == '.') ? parse_color6(&str) : CV_NOCHANGE; + if (fg != CV_ERROR && bg != CV_ERROR) + type = CT_6BIT; + } + if (p_fg != NULL) *p_fg = fg; + if (p_bg != NULL) *p_bg = bg; + return type; +} + +#if !MSDOS_COMPILER + +static int sgr_color(int color) +{ + switch (color) + { + case 0: return 30; + case CV_RED: return 31; + case CV_GREEN: return 32; + case CV_RED|CV_GREEN: return 33; + case CV_BLUE: return 34; + case CV_RED|CV_BLUE: return 35; + case CV_GREEN|CV_BLUE: return 36; + case CV_RED|CV_GREEN|CV_BLUE: return 37; + + case CV_BRIGHT: return 90; + case CV_RED|CV_BRIGHT: return 91; + case CV_GREEN|CV_BRIGHT: return 92; + case CV_RED|CV_GREEN|CV_BRIGHT: return 93; + case CV_BLUE|CV_BRIGHT: return 94; + case CV_RED|CV_BLUE|CV_BRIGHT: return 95; + case CV_GREEN|CV_BLUE|CV_BRIGHT: return 96; + case CV_RED|CV_GREEN|CV_BLUE|CV_BRIGHT: return 97; + + default: return color; + } +} + +static void tput_fmt(char *fmt, int color, int (*f_putc)(int)) +{ + char buf[INT_STRLEN_BOUND(int)+16]; + if (color == attrcolor) + return; + SNPRINTF1(buf, sizeof(buf), fmt, color); + ltputs(buf, 1, f_putc); + attrcolor = color; +} + +static void tput_color(char *str, int (*f_putc)(int)) +{ + int fg; + int bg; + + if (str != NULL && strcmp(str, "*") == 0) + { + /* Special case: reset to normal */ + tput_fmt(ESCS"[m", -1, f_putc); + return; + } + switch (parse_color(str, &fg, &bg)) + { + case CT_4BIT: + if (fg >= 0) + tput_fmt(ESCS"[%dm", sgr_color(fg), f_putc); + if (bg >= 0) + tput_fmt(ESCS"[%dm", sgr_color(bg)+10, f_putc); + break; + case CT_6BIT: + if (fg >= 0) + tput_fmt(ESCS"[38;5;%dm", fg, f_putc); + if (bg >= 0) + tput_fmt(ESCS"[48;5;%dm", bg, f_putc); + break; + default: + break; + } +} + +static void tput_inmode(char *mode_str, int attr, int attr_bit, int (*f_putc)(int)) +{ + char *color_str; + if ((attr & attr_bit) == 0) + return; + color_str = get_color_map(attr_bit); + if (color_str == NULL || *color_str == '\0' || *color_str == '+') + { + ltputs(mode_str, 1, f_putc); + if (color_str == NULL || *color_str++ != '+') + return; + } + /* Color overrides mode string */ + tput_color(color_str, f_putc); +} + +static void tput_outmode(char *mode_str, int attr_bit, int (*f_putc)(int)) +{ + if ((attrmode & attr_bit) == 0) + return; + ltputs(mode_str, 1, f_putc); +} + +#else /* MSDOS_COMPILER */ + +#if MSDOS_COMPILER==WIN32C +static int WIN32put_fmt(char *fmt, int color) +{ + char buf[INT_STRLEN_BOUND(int)+16]; + int len = SNPRINTF1(buf, sizeof(buf), fmt, color); + WIN32textout(buf, len); + return TRUE; +} +#endif + +static int win_set_color(int attr) +{ + int fg; + int bg; + int out = FALSE; + char *str = get_color_map(attr); + if (str == NULL || str[0] == '\0') + return FALSE; + switch (parse_color(str, &fg, &bg)) + { + case CT_4BIT: + if (fg >= 0 && bg >= 0) + { + SETCOLORS(fg, bg); + out = TRUE; + } else if (fg >= 0) + { + SET_FG_COLOR(fg); + out = TRUE; + } else if (bg >= 0) + { + SET_BG_COLOR(bg); + out = TRUE; + } + break; +#if MSDOS_COMPILER==WIN32C + case CT_6BIT: + if (vt_enabled) + { + if (fg > 0) + out = WIN32put_fmt(ESCS"[38;5;%dm", fg); + if (bg > 0) + out = WIN32put_fmt(ESCS"[48;5;%dm", bg); + } + break; +#endif + default: + break; + } + return out; +} + +#endif /* MSDOS_COMPILER */ + +public void at_enter(int attr) +{ + attr = apply_at_specials(attr); +#if !MSDOS_COMPILER + /* The one with the most priority is last. */ + tput_inmode(sc_u_in, attr, AT_UNDERLINE, putchr); + tput_inmode(sc_b_in, attr, AT_BOLD, putchr); + tput_inmode(sc_bl_in, attr, AT_BLINK, putchr); + /* Don't use standout and color at the same time. */ + if (use_color && (attr & AT_COLOR)) + tput_color(get_color_map(attr), putchr); + else + tput_inmode(sc_s_in, attr, AT_STANDOUT, putchr); +#else + flush(); + /* The one with the most priority is first. */ + if ((attr & AT_COLOR) && use_color) + { + win_set_color(attr); + } else if (attr & AT_STANDOUT) + { + SETCOLORS(so_fg_color, so_bg_color); + } else if (attr & AT_BLINK) + { + SETCOLORS(bl_fg_color, bl_bg_color); + } else if (attr & AT_BOLD) + { + SETCOLORS(bo_fg_color, bo_bg_color); + } else if (attr & AT_UNDERLINE) + { + SETCOLORS(ul_fg_color, ul_bg_color); + } +#endif + attrmode = attr; +} + +public void at_exit(void) +{ +#if !MSDOS_COMPILER + /* Undo things in the reverse order we did them. */ + tput_color("*", putchr); + tput_outmode(sc_s_out, AT_STANDOUT, putchr); + tput_outmode(sc_bl_out, AT_BLINK, putchr); + tput_outmode(sc_b_out, AT_BOLD, putchr); + tput_outmode(sc_u_out, AT_UNDERLINE, putchr); +#else + flush(); + SETCOLORS(nm_fg_color, nm_bg_color); +#endif + attrmode = AT_NORMAL; +} + +public void at_switch(int attr) +{ + int new_attrmode = apply_at_specials(attr); + int ignore_modes = AT_ANSI; + + if ((new_attrmode & ~ignore_modes) != (attrmode & ~ignore_modes)) + { + at_exit(); + at_enter(attr); + } +} + +public int is_at_equiv(int attr1, int attr2) +{ + attr1 = apply_at_specials(attr1); + attr2 = apply_at_specials(attr2); + + return (attr1 == attr2); +} + +public int apply_at_specials(int attr) +{ + if (attr & AT_BINARY) + attr |= binattr; + if (attr & AT_HILITE) + attr |= AT_STANDOUT; + attr &= ~(AT_BINARY|AT_HILITE); + + return attr; +} + +/* + * Output a plain backspace, without erasing the previous char. + */ +public void putbs(void) +{ + if (termcap_debug) + putstr(""); + else + { +#if !MSDOS_COMPILER + ltputs(sc_backspace, 1, putchr); +#else + int row, col; + + flush(); + { +#if MSDOS_COMPILER==MSOFTC + struct rccoord tpos; + tpos = _gettextposition(); + row = tpos.row; + col = tpos.col; +#else +#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC + row = wherey(); + col = wherex(); +#else +#if MSDOS_COMPILER==WIN32C + CONSOLE_SCREEN_BUFFER_INFO scr; + GetConsoleScreenBufferInfo(con_out, &scr); + row = scr.dwCursorPosition.Y - scr.srWindow.Top + 1; + col = scr.dwCursorPosition.X - scr.srWindow.Left + 1; +#endif +#endif +#endif + } + if (col <= 1) + return; + _settextposition(row, col-1); +#endif /* MSDOS_COMPILER */ + } +} + +#if MSDOS_COMPILER==WIN32C +/* + * Determine whether an input character is waiting to be read. + */ +public int win32_kbhit(void) +{ + INPUT_RECORD ip; + DWORD read; + + if (keyCount > 0 || win_unget_pending) + return (TRUE); + + currentKey.ascii = 0; + currentKey.scan = 0; + + if (x11mouseCount > 0) + { + currentKey.ascii = x11mousebuf[x11mousePos++]; + --x11mouseCount; + keyCount = 1; + return (TRUE); + } + + /* + * Wait for a real key-down event, but + * ignore SHIFT and CONTROL key events. + */ + do + { + PeekConsoleInputW(tty, &ip, 1, &read); + if (read == 0) + return (FALSE); + ReadConsoleInputW(tty, &ip, 1, &read); + /* generate an X11 mouse sequence from the mouse event */ + if (mousecap && ip.EventType == MOUSE_EVENT && + ip.Event.MouseEvent.dwEventFlags != MOUSE_MOVED) + { + x11mousebuf[3] = X11MOUSE_OFFSET + ip.Event.MouseEvent.dwMousePosition.X + 1; + x11mousebuf[4] = X11MOUSE_OFFSET + ip.Event.MouseEvent.dwMousePosition.Y + 1; + switch (ip.Event.MouseEvent.dwEventFlags) + { + case 0: /* press or release */ + if (ip.Event.MouseEvent.dwButtonState == 0) + x11mousebuf[2] = X11MOUSE_OFFSET + X11MOUSE_BUTTON_REL; + else if (ip.Event.MouseEvent.dwButtonState & (FROM_LEFT_3RD_BUTTON_PRESSED | FROM_LEFT_4TH_BUTTON_PRESSED)) + continue; + else + x11mousebuf[2] = X11MOUSE_OFFSET + X11MOUSE_BUTTON1 + ((int)ip.Event.MouseEvent.dwButtonState << 1); + break; + case MOUSE_WHEELED: + x11mousebuf[2] = X11MOUSE_OFFSET + (((int)ip.Event.MouseEvent.dwButtonState < 0) ? X11MOUSE_WHEEL_DOWN : X11MOUSE_WHEEL_UP); + break; + default: + continue; + } + x11mousePos = 0; + x11mouseCount = 5; + currentKey.ascii = ESC; + keyCount = 1; + return (TRUE); + } + } while (ip.EventType != KEY_EVENT || + ip.Event.KeyEvent.bKeyDown != TRUE || + (ip.Event.KeyEvent.wVirtualScanCode == 0 && ip.Event.KeyEvent.uChar.UnicodeChar == 0) || + ((ip.Event.KeyEvent.dwControlKeyState & (RIGHT_ALT_PRESSED|LEFT_CTRL_PRESSED)) == (RIGHT_ALT_PRESSED|LEFT_CTRL_PRESSED) && ip.Event.KeyEvent.uChar.UnicodeChar == 0) || + ip.Event.KeyEvent.wVirtualKeyCode == VK_KANJI || + ip.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT || + ip.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL || + ip.Event.KeyEvent.wVirtualKeyCode == VK_MENU); + + currentKey.unicode = ip.Event.KeyEvent.uChar.UnicodeChar; + currentKey.ascii = ip.Event.KeyEvent.uChar.AsciiChar; + currentKey.scan = ip.Event.KeyEvent.wVirtualScanCode; + keyCount = ip.Event.KeyEvent.wRepeatCount; + + if (ip.Event.KeyEvent.dwControlKeyState & + (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) + { + switch (currentKey.scan) + { + case PCK_ALT_E: /* letter 'E' */ + currentKey.ascii = 0; + break; + } + } else if (ip.Event.KeyEvent.dwControlKeyState & + (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + { + switch (currentKey.scan) + { + case PCK_RIGHT: /* right arrow */ + currentKey.scan = PCK_CTL_RIGHT; + break; + case PCK_LEFT: /* left arrow */ + currentKey.scan = PCK_CTL_LEFT; + break; + case PCK_DELETE: /* delete */ + currentKey.scan = PCK_CTL_DELETE; + break; + } + } else if (ip.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) + { + switch (currentKey.scan) + { + case PCK_SHIFT_TAB: /* tab */ + currentKey.ascii = 0; + break; + } + } + + return (TRUE); +} + +/* + * Read a character from the keyboard. + * + * Known issues: + * - WIN32getch API should be int like libc (with unsigned char values or -1). + * - The unicode code below can return 0 - incorrectly indicating scan code. + * - UTF16-LE surrogate pairs don't work (and return 0). + * - If win32_kbhit returns true then WIN32getch should never block, but it + * will block till the next keypress if it's numlock/capslock scan code. + */ +public char WIN32getch(void) +{ + char ascii; + static unsigned char utf8[UTF8_MAX_LENGTH]; + static int utf8_size = 0; + static int utf8_next_byte = 0; + + if (win_unget_pending) + { + win_unget_pending = FALSE; + return (char) win_unget_data; + } + + // Return the rest of multibyte character from the prior call + if (utf8_next_byte < utf8_size) + { + ascii = utf8[utf8_next_byte++]; + return ascii; + } + utf8_size = 0; + + if (pending_scancode) + { + pending_scancode = 0; + return ((char)(currentKey.scan & 0x00FF)); + } + + do { + while (!win32_kbhit()) + { + Sleep(20); + if (ABORT_SIGS()) + return ('\003'); + } + keyCount--; + // If multibyte character, return its first byte + if (currentKey.unicode > 0x7f) + { + utf8_size = WideCharToMultiByte(CP_UTF8, 0, ¤tKey.unicode, 1, (LPSTR) &utf8, sizeof(utf8), NULL, NULL); + if (utf8_size == 0) + return '\0'; + ascii = utf8[0]; + utf8_next_byte = 1; + } else + ascii = currentKey.ascii; + /* + * On PC's, the extended keys return a 2 byte sequence beginning + * with '00', so if the ascii code is 00, the next byte will be + * the lsb of the scan code. + */ + pending_scancode = (ascii == 0x00); + } while (pending_scancode && + (currentKey.scan == PCK_CAPS_LOCK || currentKey.scan == PCK_NUM_LOCK)); + + return ascii; +} + +/* + * Make the next call to WIN32getch return ch without changing the queue state. + */ +public void WIN32ungetch(int ch) +{ + win_unget_pending = TRUE; + win_unget_data = ch; +} +#endif + +#if MSDOS_COMPILER +/* + */ +public void WIN32setcolors(int fg, int bg) +{ + SETCOLORS(fg, bg); +} + +/* + */ +public void WIN32textout(char *text, int len) +{ +#if MSDOS_COMPILER==WIN32C + DWORD written; + if (utf_mode == 2) + { + /* + * We've got UTF-8 text in a non-UTF-8 console. Convert it to + * wide and use WriteConsoleW. + */ + WCHAR wtext[1024]; + len = MultiByteToWideChar(CP_UTF8, 0, text, len, wtext, + sizeof(wtext)/sizeof(*wtext)); + WriteConsoleW(con_out, wtext, len, &written, NULL); + } else + WriteConsole(con_out, text, len, &written, NULL); +#else + char c = text[len]; + text[len] = '\0'; + cputs(text); + text[len] = c; +#endif +} +#endif + diff --git a/third_party/less/search.c b/third_party/less/search.c new file mode 100644 index 000000000..98f01e5fc --- /dev/null +++ b/third_party/less/search.c @@ -0,0 +1,1868 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * Routines to search a file for a pattern. + */ + +#include "less.h" +#include "position.h" +#include "charset.h" + +#define MINPOS(a,b) (((a) < (b)) ? (a) : (b)) +#define MAXPOS(a,b) (((a) > (b)) ? (a) : (b)) + +extern int sigs; +extern int how_search; +extern int caseless; +extern int linenums; +extern int sc_height; +extern int jump_sline; +extern int bs_mode; +extern int proc_backspace; +extern int proc_return; +extern int ctldisp; +extern int status_col; +extern void *ml_search; +extern POSITION start_attnpos; +extern POSITION end_attnpos; +extern int utf_mode; +extern int screen_trashed; +extern int sc_width; +extern int sc_height; +extern int hshift; +extern int nosearch_headers; +extern int header_lines; +extern int header_cols; +#if HILITE_SEARCH +extern int hilite_search; +extern int size_linebuf; +extern int squished; +extern int can_goto_line; +static int hide_hilite; +static POSITION prep_startpos; +static POSITION prep_endpos; +extern POSITION xxpos; + +/* + * Structures for maintaining a set of ranges for hilites and filtered-out + * lines. Each range is stored as a node within a red-black tree, and we + * try to extend existing ranges (without creating overlaps) rather than + * create new nodes if possible. We remember the last node found by a + * search for constant-time lookup if the next search is near enough to + * the previous. To aid that, we overlay a secondary doubly-linked list + * on top of the red-black tree so we can find the preceding/succeeding + * nodes also in constant time. + * + * Each node is allocated from a series of pools, each pool double the size + * of the previous (for amortised constant time allocation). Since our only + * tree operations are clear and node insertion, not node removal, we don't + * need to maintain a usage bitmap or freelist and can just return nodes + * from the pool in-order until capacity is reached. + */ +struct hilite +{ + POSITION hl_startpos; + POSITION hl_endpos; + int hl_attr; +}; +struct hilite_node +{ + struct hilite_node *parent; + struct hilite_node *left; + struct hilite_node *right; + struct hilite_node *prev; + struct hilite_node *next; + int red; + struct hilite r; +}; +struct hilite_storage +{ + int capacity; + int used; + struct hilite_storage *next; + struct hilite_node *nodes; +}; +struct hilite_tree +{ + struct hilite_storage *first; + struct hilite_storage *current; + struct hilite_node *root; + struct hilite_node *lookaside; +}; +#define HILITE_INITIALIZER() { NULL, NULL, NULL, NULL } +#define HILITE_LOOKASIDE_STEPS 2 + +static struct hilite_tree hilite_anchor = HILITE_INITIALIZER(); +static struct hilite_tree filter_anchor = HILITE_INITIALIZER(); +static struct pattern_info *filter_infos = NULL; + +#endif + +/* + * These are the static variables that represent the "remembered" + * search pattern and filter pattern. + */ +struct pattern_info { + PATTERN_TYPE compiled; + char* text; + int search_type; + int is_ucase_pattern; + struct pattern_info *next; +}; + +#if NO_REGEX +#define info_compiled(info) ((void*)0) +#else +#define info_compiled(info) ((info)->compiled) +#endif + +static struct pattern_info search_info; +public int is_caseless; + +/* + * Are there any uppercase letters in this string? + */ +static int is_ucase(char *str) +{ + char *str_end = str + strlen(str); + LWCHAR ch; + + while (str < str_end) + { + ch = step_char(&str, +1, str_end); + if (IS_UPPER(ch)) + return (1); + } + return (0); +} + +/* + * Discard a saved pattern. + */ +static void clear_pattern(struct pattern_info *info) +{ + if (info->text != NULL) + free(info->text); + info->text = NULL; +#if !NO_REGEX + uncompile_pattern(&info->compiled); +#endif +} + +/* + * Compile and save a search pattern. + */ +static int set_pattern(struct pattern_info *info, char *pattern, int search_type, int show_error) +{ + /* + * Ignore case if -I is set OR + * -i is set AND the pattern is all lowercase. + */ + info->is_ucase_pattern = (pattern == NULL) ? FALSE : is_ucase(pattern); + is_caseless = (info->is_ucase_pattern && caseless != OPT_ONPLUS) ? 0 : caseless; +#if !NO_REGEX + if (pattern == NULL) + SET_NULL_PATTERN(info->compiled); + else if (compile_pattern(pattern, search_type, show_error, &info->compiled) < 0) + return -1; +#endif + /* Pattern compiled successfully; save the text too. */ + if (info->text != NULL) + free(info->text); + info->text = NULL; + if (pattern != NULL) + { + info->text = (char *) ecalloc(1, strlen(pattern)+1); + strcpy(info->text, pattern); + } + info->search_type = search_type; + return 0; +} + +/* + * Initialize saved pattern to nothing. + */ +static void init_pattern(struct pattern_info *info) +{ + SET_NULL_PATTERN(info->compiled); + info->text = NULL; + info->search_type = 0; + info->next = NULL; +} + +/* + * Initialize search variables. + */ +public void init_search(void) +{ + init_pattern(&search_info); +} + +/* + * Determine which text conversions to perform before pattern matching. + */ +static int get_cvt_ops(int search_type) +{ + int ops = 0; + + if (is_caseless && (!re_handles_caseless || (search_type & SRCH_NO_REGEX))) + ops |= CVT_TO_LC; + if (proc_backspace == OPT_ON || (bs_mode == BS_SPECIAL && proc_backspace == OPT_OFF)) + ops |= CVT_BS; + if (proc_return == OPT_ON || (bs_mode != BS_CONTROL && proc_backspace == OPT_OFF)) + ops |= CVT_CRLF; + if (ctldisp == OPT_ONPLUS) + ops |= CVT_ANSI; + return (ops); +} + +/* + * Is there a previous (remembered) search pattern? + */ +static int prev_pattern(struct pattern_info *info) +{ +#if !NO_REGEX + if ((info->search_type & SRCH_NO_REGEX) == 0) + return (!is_null_pattern(info->compiled)); +#endif + return (info->text != NULL); +} + +#if HILITE_SEARCH +/* + * Repaint the hilites currently displayed on the screen. + * Repaint each line which contains highlighted text. + * If on==0, force all hilites off. + */ +public void repaint_hilite(int on) +{ + int sindex; + POSITION pos; + int save_hide_hilite; + + if (squished) + repaint(); + + save_hide_hilite = hide_hilite; + if (!on) + { + if (hide_hilite) + return; + hide_hilite = 1; + } + + if (!can_goto_line) + { + repaint(); + hide_hilite = save_hide_hilite; + return; + } + + for (sindex = TOP; sindex < TOP + sc_height-1; sindex++) + { + pos = position(sindex); + if (pos == NULL_POSITION) + continue; + (void) forw_line(pos); + goto_line(sindex); + clear_eol(); + put_line(); + } + overlay_header(); + lower_left(); + hide_hilite = save_hide_hilite; +} +#endif + +/* + * Clear the attn hilite. + */ +public void clear_attn(void) +{ +#if HILITE_SEARCH + int sindex; + POSITION old_start_attnpos; + POSITION old_end_attnpos; + POSITION pos; + POSITION epos; + int moved = 0; + + if (start_attnpos == NULL_POSITION) + return; + old_start_attnpos = start_attnpos; + old_end_attnpos = end_attnpos; + start_attnpos = end_attnpos = NULL_POSITION; + + if (!can_goto_line) + { + repaint(); + return; + } + if (squished) + repaint(); + + for (sindex = TOP; sindex < TOP + sc_height-1; sindex++) + { + pos = position(sindex); + if (pos == NULL_POSITION) + continue; + epos = position(sindex+1); + if (pos <= old_end_attnpos && + (epos == NULL_POSITION || epos > old_start_attnpos)) + { + (void) forw_line(pos); + goto_line(sindex); + clear_eol(); + put_line(); + moved = 1; + } + } + if (overlay_header()) + moved = 1; + if (moved) + lower_left(); +#endif +} + +/* + * Toggle or clear search string highlighting. + */ +public void undo_search(int clear) +{ + clear_pattern(&search_info); +#if HILITE_SEARCH + if (clear) + { + clr_hilite(); + } else + { + if (hilite_anchor.first == NULL) + { + error("No previous regular expression", NULL_PARG); + return; + } + hide_hilite = !hide_hilite; + } + repaint_hilite(1); +#endif +} + +#if HILITE_SEARCH +/* + * Clear the hilite list. + */ +public void clr_hlist(struct hilite_tree *anchor) +{ + struct hilite_storage *hls; + struct hilite_storage *nexthls; + + for (hls = anchor->first; hls != NULL; hls = nexthls) + { + nexthls = hls->next; + free((void*)hls->nodes); + free((void*)hls); + } + anchor->first = NULL; + anchor->current = NULL; + anchor->root = NULL; + + anchor->lookaside = NULL; + + prep_startpos = prep_endpos = NULL_POSITION; +} + +public void clr_hilite(void) +{ + clr_hlist(&hilite_anchor); +} + +public void clr_filter(void) +{ + clr_hlist(&filter_anchor); +} + +/* + * Find the node covering pos, or the node after it if no node covers it, + * or return NULL if pos is after the last range. Remember the found node, + * to speed up subsequent searches for the same or similar positions (if + * we return NULL, remember the last node.) + */ +static struct hilite_node* hlist_find(struct hilite_tree *anchor, POSITION pos) +{ + struct hilite_node *n, *m; + + if (anchor->lookaside) + { + int steps = 0; + int hit = 0; + + n = anchor->lookaside; + + for (;;) + { + if (pos < n->r.hl_endpos) + { + if (n->prev == NULL || pos >= n->prev->r.hl_endpos) + { + hit = 1; + break; + } + } else if (n->next == NULL) + { + n = NULL; + hit = 1; + break; + } + + /* + * If we don't find the right node within a small + * distance, don't keep doing a linear search! + */ + if (steps >= HILITE_LOOKASIDE_STEPS) + break; + steps++; + + if (pos < n->r.hl_endpos) + anchor->lookaside = n = n->prev; + else + anchor->lookaside = n = n->next; + } + + if (hit) + return n; + } + + n = anchor->root; + m = NULL; + + while (n != NULL) + { + if (pos < n->r.hl_startpos) + { + if (n->left != NULL) + { + m = n; + n = n->left; + continue; + } + break; + } + if (pos >= n->r.hl_endpos) + { + if (n->right != NULL) + { + n = n->right; + continue; + } + if (m != NULL) + { + n = m; + } else + { + m = n; + n = NULL; + } + } + break; + } + + if (n != NULL) + anchor->lookaside = n; + else if (m != NULL) + anchor->lookaside = m; + + return n; +} + +/* + * Should any characters in a specified range be highlighted? + */ +static int hilited_range_attr(POSITION pos, POSITION epos) +{ + struct hilite_node *n = hlist_find(&hilite_anchor, pos); + if (n == NULL) + return 0; + if (epos != NULL_POSITION && epos <= n->r.hl_startpos) + return 0; + return n->r.hl_attr; +} + +/* + * Is a line "filtered" -- that is, should it be hidden? + */ +public int is_filtered(POSITION pos) +{ + struct hilite_node *n; + + if (ch_getflags() & CH_HELPFILE) + return (0); + + n = hlist_find(&filter_anchor, pos); + return (n != NULL && pos >= n->r.hl_startpos); +} + +/* + * If pos is hidden, return the next position which isn't, otherwise + * just return pos. + */ +public POSITION next_unfiltered(POSITION pos) +{ + struct hilite_node *n; + + if (ch_getflags() & CH_HELPFILE) + return (pos); + + n = hlist_find(&filter_anchor, pos); + while (n != NULL && pos >= n->r.hl_startpos) + { + pos = n->r.hl_endpos; + n = n->next; + } + return (pos); +} + +/* + * If pos is hidden, return the previous position which isn't or 0 if + * we're filtered right to the beginning, otherwise just return pos. + */ +public POSITION prev_unfiltered(POSITION pos) +{ + struct hilite_node *n; + + if (ch_getflags() & CH_HELPFILE) + return (pos); + + n = hlist_find(&filter_anchor, pos); + while (n != NULL && pos >= n->r.hl_startpos) + { + pos = n->r.hl_startpos; + if (pos == 0) + break; + pos--; + n = n->prev; + } + return (pos); +} + + +/* + * Should any characters in a specified range be highlighted? + * If nohide is nonzero, don't consider hide_hilite. + */ +public int is_hilited_attr(POSITION pos, POSITION epos, int nohide, int *p_matches) +{ + int attr; + + if (p_matches != NULL) + *p_matches = 0; + + if (!status_col && + start_attnpos != NULL_POSITION && + pos <= end_attnpos && + (epos == NULL_POSITION || epos >= start_attnpos)) + /* + * The attn line overlaps this range. + */ + return (AT_HILITE|AT_COLOR_ATTN); + + attr = hilited_range_attr(pos, epos); + if (attr == 0) + return (0); + + if (p_matches == NULL) + /* + * Kinda kludgy way to recognize that caller is checking for + * hilite in status column. In this case we want to return + * hilite status even if hiliting is disabled or hidden. + */ + return (attr); + + /* + * Report matches, even if we're hiding highlights. + */ + *p_matches = 1; + + if (hilite_search == 0) + /* + * Not doing highlighting. + */ + return (0); + + if (!nohide && hide_hilite) + /* + * Highlighting is hidden. + */ + return (0); + + return (attr); +} + +/* + * Tree node storage: get the current block of nodes if it has spare + * capacity, or create a new one if not. + */ +static struct hilite_storage * hlist_getstorage(struct hilite_tree *anchor) +{ + int capacity = 1; + struct hilite_storage *s; + + if (anchor->current) + { + if (anchor->current->used < anchor->current->capacity) + return anchor->current; + capacity = anchor->current->capacity * 2; + } + + s = (struct hilite_storage *) ecalloc(1, sizeof(struct hilite_storage)); + s->nodes = (struct hilite_node *) ecalloc(capacity, sizeof(struct hilite_node)); + s->capacity = capacity; + s->used = 0; + s->next = NULL; + if (anchor->current) + anchor->current->next = s; + else + anchor->first = s; + anchor->current = s; + return s; +} + +/* + * Tree node storage: retrieve a new empty node to be inserted into the + * tree. + */ +static struct hilite_node * hlist_getnode(struct hilite_tree *anchor) +{ + struct hilite_storage *s = hlist_getstorage(anchor); + return &s->nodes[s->used++]; +} + +/* + * Rotate the tree left around a pivot node. + */ +static void hlist_rotate_left(struct hilite_tree *anchor, struct hilite_node *n) +{ + struct hilite_node *np = n->parent; + struct hilite_node *nr = n->right; + struct hilite_node *nrl = n->right->left; + + if (np != NULL) + { + if (n == np->left) + np->left = nr; + else + np->right = nr; + } else + { + anchor->root = nr; + } + nr->left = n; + n->right = nrl; + + nr->parent = np; + n->parent = nr; + if (nrl != NULL) + nrl->parent = n; +} + +/* + * Rotate the tree right around a pivot node. + */ +static void hlist_rotate_right(struct hilite_tree *anchor, struct hilite_node *n) +{ + struct hilite_node *np = n->parent; + struct hilite_node *nl = n->left; + struct hilite_node *nlr = n->left->right; + + if (np != NULL) + { + if (n == np->right) + np->right = nl; + else + np->left = nl; + } else + { + anchor->root = nl; + } + nl->right = n; + n->left = nlr; + + nl->parent = np; + n->parent = nl; + if (nlr != NULL) + nlr->parent = n; +} + + +/* + * Add a new hilite to a hilite list. + */ +static void add_hilite(struct hilite_tree *anchor, struct hilite *hl) +{ + struct hilite_node *p, *n, *u; + + /* Ignore empty ranges. */ + if (hl->hl_startpos >= hl->hl_endpos) + return; + + p = anchor->root; + + /* Inserting the very first node is trivial. */ + if (p == NULL) + { + n = hlist_getnode(anchor); + n->r = *hl; + anchor->root = n; + anchor->lookaside = n; + return; + } + + /* + * Find our insertion point. If we come across any overlapping + * or adjoining existing ranges, shrink our range and discard + * if it become empty. + */ + for (;;) + { + if (hl->hl_startpos < p->r.hl_startpos) + { + if (hl->hl_endpos > p->r.hl_startpos && hl->hl_attr == p->r.hl_attr) + hl->hl_endpos = p->r.hl_startpos; + if (p->left != NULL) + { + p = p->left; + continue; + } + break; + } + if (hl->hl_startpos < p->r.hl_endpos && hl->hl_attr == p->r.hl_attr) { + hl->hl_startpos = p->r.hl_endpos; + if (hl->hl_startpos >= hl->hl_endpos) + return; + } + if (p->right != NULL) + { + p = p->right; + continue; + } + break; + } + + /* + * Now we're at the right leaf, again check for contiguous ranges + * and extend the existing node if possible to avoid the + * insertion. Otherwise insert a new node at the leaf. + */ + if (hl->hl_startpos < p->r.hl_startpos) { + if (hl->hl_attr == p->r.hl_attr) + { + if (hl->hl_endpos == p->r.hl_startpos) + { + p->r.hl_startpos = hl->hl_startpos; + return; + } + if (p->prev != NULL && p->prev->r.hl_endpos == hl->hl_startpos) + { + p->prev->r.hl_endpos = hl->hl_endpos; + return; + } + } + p->left = n = hlist_getnode(anchor); + n->next = p; + if (p->prev != NULL) + { + n->prev = p->prev; + p->prev->next = n; + } + p->prev = n; + } else { + if (hl->hl_attr == p->r.hl_attr) + { + if (p->r.hl_endpos == hl->hl_startpos) + { + p->r.hl_endpos = hl->hl_endpos; + return; + } + if (p->next != NULL && hl->hl_endpos == p->next->r.hl_startpos) { + p->next->r.hl_startpos = hl->hl_startpos; + return; + } + } + p->right = n = hlist_getnode(anchor); + n->prev = p; + if (p->next != NULL) + { + n->next = p->next; + p->next->prev = n; + } + p->next = n; + } + n->parent = p; + n->red = 1; + n->r = *hl; + + /* + * The tree is in the correct order and covers the right ranges + * now, but may have become unbalanced. Rebalance it using the + * standard red-black tree constraints and operations. + */ + for (;;) + { + /* case 1 - current is root, root is always black */ + if (n->parent == NULL) + { + n->red = 0; + break; + } + + /* case 2 - parent is black, we can always be red */ + if (!n->parent->red) + break; + + /* + * constraint: because the root must be black, if our + * parent is red it cannot be the root therefore we must + * have a grandparent + */ + + /* + * case 3 - parent and uncle are red, repaint them black, + * the grandparent red, and start again at the grandparent. + */ + u = n->parent->parent->left; + if (n->parent == u) + u = n->parent->parent->right; + if (u != NULL && u->red) + { + n->parent->red = 0; + u->red = 0; + n = n->parent->parent; + n->red = 1; + continue; + } + + /* + * case 4 - parent is red but uncle is black, parent and + * grandparent on opposite sides. We need to start + * changing the structure now. This and case 5 will shorten + * our branch and lengthen the sibling, between them + * restoring balance. + */ + if (n == n->parent->right && + n->parent == n->parent->parent->left) + { + hlist_rotate_left(anchor, n->parent); + n = n->left; + } else if (n == n->parent->left && + n->parent == n->parent->parent->right) + { + hlist_rotate_right(anchor, n->parent); + n = n->right; + } + + /* + * case 5 - parent is red but uncle is black, parent and + * grandparent on same side + */ + n->parent->red = 0; + n->parent->parent->red = 1; + if (n == n->parent->left) + hlist_rotate_right(anchor, n->parent->parent); + else + hlist_rotate_left(anchor, n->parent->parent); + break; + } +} + +/* + * Highlight every character in a range of displayed characters. + */ +static void create_hilites(POSITION linepos, char *line, char *sp, char *ep, int attr, int *chpos) +{ + int start_index = sp - line; + int end_index = ep - line; + struct hilite hl; + int i; + + /* Start the first hilite. */ + hl.hl_startpos = linepos + chpos[start_index]; + hl.hl_attr = attr; + + /* + * Step through the displayed chars. + * If the source position (before cvt) of the char is one more + * than the source pos of the previous char (the usual case), + * just increase the size of the current hilite by one. + * Otherwise (there are backspaces or something involved), + * finish the current hilite and start a new one. + */ + for (i = start_index+1; i <= end_index; i++) + { + if (chpos[i] != chpos[i-1] + 1 || i == end_index) + { + hl.hl_endpos = linepos + chpos[i-1] + 1; + add_hilite(&hilite_anchor, &hl); + /* Start new hilite unless this is the last char. */ + if (i < end_index) + { + hl.hl_startpos = linepos + chpos[i]; + } + } + } +} + +/* + * Make a hilite for each string in a physical line which matches + * the current pattern. + * sp,ep delimit the first match already found. + */ +static void hilite_line(POSITION linepos, char *line, int line_len, int *chpos, char **sp, char **ep, int nsp, int cvt_ops) +{ + char *searchp; + char *line_end = line + line_len; + + /* + * sp[0] and ep[0] delimit the first match in the line. + * Mark the corresponding file positions, then + * look for further matches and mark them. + * {{ This technique, of calling match_pattern on subsequent + * substrings of the line, may mark more than is correct + * if the pattern starts with "^". This bug is fixed + * for those regex functions that accept a notbol parameter + * (currently POSIX, PCRE and V8-with-regexec2). }} + * sp[i] and ep[i] for i>0 delimit subpattern matches. + * Color each of them with its unique color. + */ + searchp = line; + do { + char *lep = sp[0]; + int i; + if (sp[0] == NULL || ep[0] == NULL) + break; + for (i = 1; i < nsp; i++) + { + if (sp[i] == NULL || ep[i] == NULL) + break; + if (ep[i] > sp[i]) + { + create_hilites(linepos, line, lep, sp[i], + AT_HILITE | AT_COLOR_SEARCH, chpos); + create_hilites(linepos, line, sp[i], ep[i], + AT_HILITE | AT_COLOR_SUBSEARCH(i), chpos); + lep = ep[i]; + } + } + create_hilites(linepos, line, lep, ep[0], + AT_HILITE | AT_COLOR_SEARCH, chpos); + + /* + * If we matched more than zero characters, + * move to the first char after the string we matched. + * If we matched zero, just move to the next char. + */ + if (ep[0] > searchp) + searchp = ep[0]; + else if (searchp != line_end) + searchp++; + else /* end of line */ + break; + } while (match_pattern(info_compiled(&search_info), search_info.text, + searchp, line_end - searchp, sp, ep, nsp, 1, search_info.search_type)); +} +#endif + +#if HILITE_SEARCH +/* + * Find matching text which is currently on screen and highlight it. + */ +static void hilite_screen(void) +{ + struct scrpos scrpos; + + get_scrpos(&scrpos, TOP); + if (scrpos.pos == NULL_POSITION) + return; + prep_hilite(scrpos.pos, position(BOTTOM_PLUS_ONE), -1); + repaint_hilite(1); +} + +/* + * Change highlighting parameters. + */ +public void chg_hilite(void) +{ + /* + * Erase any highlights currently on screen. + */ + clr_hilite(); + hide_hilite = 0; + + if (hilite_search == OPT_ONPLUS) + /* + * Display highlights. + */ + hilite_screen(); +} +#endif + +/* + * Figure out where to start a search. + */ +static POSITION search_pos(int search_type) +{ + POSITION pos; + int sindex; + + if (empty_screen()) + { + /* + * Start at the beginning (or end) of the file. + * The empty_screen() case is mainly for + * command line initiated searches; + * for example, "+/xyz" on the command line. + * Also for multi-file (SRCH_PAST_EOF) searches. + */ + if (search_type & SRCH_FORW) + { + pos = ch_zero(); + } else + { + pos = ch_length(); + if (pos == NULL_POSITION) + { + (void) ch_end_seek(); + pos = ch_length(); + } + } + sindex = 0; + } else + { + int add_one = 0; + + if (how_search == OPT_ON) + { + /* + * Search does not include current screen. + */ + if (search_type & SRCH_FORW) + sindex = sc_height-1; /* BOTTOM_PLUS_ONE */ + else + sindex = 0; /* TOP */ + } else if (how_search == OPT_ONPLUS && !(search_type & SRCH_AFTER_TARGET)) + { + /* + * Search includes all of displayed screen. + */ + if (search_type & SRCH_FORW) + sindex = 0; /* TOP */ + else + sindex = sc_height-1; /* BOTTOM_PLUS_ONE */ + } else + { + /* + * Search includes the part of current screen beyond the jump target. + * It starts at the jump target (if searching backwards), + * or at the jump target plus one (if forwards). + */ + sindex = sindex_from_sline(jump_sline); + if (search_type & SRCH_FORW) + add_one = 1; + } + pos = position(sindex); + if (add_one) + pos = forw_raw_line(pos, (char **)NULL, (int *)NULL); + } + + /* + * If the line is empty, look around for a plausible starting place. + */ + if (search_type & SRCH_FORW) + { + while (pos == NULL_POSITION) + { + if (++sindex >= sc_height) + break; + pos = position(sindex); + } + } else + { + while (pos == NULL_POSITION) + { + if (--sindex < 0) + break; + pos = position(sindex); + } + } + return (pos); +} + +/* + * Check to see if the line matches the filter pattern. + * If so, add an entry to the filter list. + */ +#if HILITE_SEARCH +static int matches_filters(POSITION pos, char *cline, int line_len, int *chpos, POSITION linepos, char **sp, char **ep, int nsp) +{ + struct pattern_info *filter; + + for (filter = filter_infos; filter != NULL; filter = filter->next) + { + int line_filter = match_pattern(info_compiled(filter), filter->text, + cline, line_len, sp, ep, nsp, 0, filter->search_type); + if (line_filter) + { + struct hilite hl; + hl.hl_startpos = linepos; + hl.hl_endpos = pos; + add_hilite(&filter_anchor, &hl); + free(cline); + free(chpos); + return (1); + } + } + return (0); +} +#endif + +/* + * Get the position of the first char in the screen line which + * puts tpos on screen. + */ +static POSITION get_lastlinepos(POSITION pos, POSITION tpos, int sheight) +{ + int nlines; + + for (nlines = 0;; nlines++) + { + POSITION npos = forw_line(pos); + if (npos > tpos) + { + if (nlines < sheight) + return NULL_POSITION; + return pos; + } + pos = npos; + } +} + +/* + * Get the segment index of tpos in the line starting at pos. + * A segment is a string of printable chars that fills the screen width. + */ +static int get_seg(POSITION pos, POSITION tpos) +{ + int seg; + + for (seg = 0;; seg++) + { + POSITION npos = forw_line_seg(pos, FALSE, FALSE, TRUE); + if (npos > tpos) + return seg; + pos = npos; + } +} + +/* + * Search a subset of the file, specified by start/end position. + */ +static int search_range(POSITION pos, POSITION endpos, int search_type, int matches, int maxlines, POSITION *plinepos, POSITION *pendpos, POSITION *plastlinepos) +{ + char *line; + char *cline; + int line_len; + LINENUM linenum; + #define NSP (NUM_SEARCH_COLORS+2) + char *sp[NSP]; + char *ep[NSP]; + int line_match; + int cvt_ops; + int cvt_len; + int *chpos; + POSITION linepos, oldpos; + int skip_bytes = 0; + int swidth = sc_width - line_pfx_width(); + int sheight = sc_height - sindex_from_sline(jump_sline); + + linenum = find_linenum(pos); + if (nosearch_headers && linenum <= header_lines) + { + linenum = header_lines + 1; + pos = find_pos(linenum); + } + if (pos == NULL_POSITION) + return (-1); + oldpos = pos; + /* When the search wraps around, end at starting position. */ + if ((search_type & SRCH_WRAP) && endpos == NULL_POSITION) + endpos = 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), or until we hit the end position. + */ + if (ABORT_SIGS()) + { + /* + * A signal aborts the search. + */ + return (-1); + } + + if ((endpos != NULL_POSITION && !(search_type & SRCH_WRAP) && + (((search_type & SRCH_FORW) && pos >= endpos) || + ((search_type & SRCH_BACK) && pos <= endpos))) || maxlines == 0) + { + /* + * Reached end position without a match. + */ + if (pendpos != NULL) + *pendpos = pos; + return (matches); + } + if (maxlines > 0) + maxlines--; + + if (search_type & SRCH_FORW) + { + /* + * Read the next line, and save the + * starting position of that line in linepos. + */ + linepos = pos; + pos = forw_raw_line(pos, &line, &line_len); + if (linenum != 0) + linenum++; + } else + { + /* + * Read the previous line and save the + * starting position of that line in linepos. + */ + pos = back_raw_line(pos, &line, &line_len); + linepos = pos; + if (linenum != 0) + linenum--; + } + + if (pos == NULL_POSITION) + { + /* + * Reached EOF/BOF without a match. + */ + if (search_type & SRCH_WRAP) + { + /* + * The search wraps around the current file, so + * try to continue at BOF/EOF. + */ + if (search_type & SRCH_FORW) + { + pos = ch_zero(); + } else + { + pos = ch_length(); + if (pos == NULL_POSITION) + { + (void) ch_end_seek(); + pos = ch_length(); + } + } + if (pos != NULL_POSITION) { + /* + * Wrap-around was successful. Clear + * the flag so we don't wrap again, and + * continue the search at new pos. + */ + search_type &= ~SRCH_WRAP; + linenum = find_linenum(pos); + continue; + } + } + if (pendpos != NULL) + *pendpos = oldpos; + return (matches); + } + + /* + * 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). + * Don't do it for every line because it slows down + * the search. Remember the line number only if + * we're "far" from the last place we remembered it. + */ + if (linenums && abs((int)(pos - oldpos)) > 2048) + add_lnum(linenum, pos); + oldpos = pos; + +#if HILITE_SEARCH + if (is_filtered(linepos)) + continue; +#endif + if (nosearch_headers) + skip_bytes = skip_columns(header_cols, &line, &line_len); + + /* + * If it's a caseless search, convert the line to lowercase. + * If we're doing backspace processing, delete backspaces. + */ + cvt_ops = get_cvt_ops(search_type); + cvt_len = cvt_length(line_len, cvt_ops); + cline = (char *) ecalloc(1, cvt_len); + chpos = cvt_alloc_chpos(cvt_len); + cvt_text(cline, line, chpos, &line_len, cvt_ops); + +#if HILITE_SEARCH + /* + * If any filters are in effect, ignore non-matching lines. + */ + if (filter_infos != NULL && + ((search_type & SRCH_FIND_ALL) || + prep_startpos == NULL_POSITION || + linepos < prep_startpos || linepos >= prep_endpos)) { + if (matches_filters(pos, cline, line_len, chpos, linepos, sp, ep, NSP)) + continue; + } +#endif + + /* + * Test the next line to see if we have a match. + * We are successful if we either want a match and got one, + * or if we want a non-match and got one. + */ + if (prev_pattern(&search_info)) + { + line_match = match_pattern(info_compiled(&search_info), search_info.text, + cline, line_len, sp, ep, NSP, 0, search_type); + if (line_match) + { + /* + * Got a match. + */ + if (search_type & SRCH_FIND_ALL) + { +#if HILITE_SEARCH + /* + * We are supposed to find all matches in the range. + * Just add the matches in this line to the + * hilite list and keep searching. + */ + hilite_line(linepos + skip_bytes, cline, line_len, chpos, sp, ep, NSP, cvt_ops); +#endif + } else if (--matches <= 0) + { + /* + * Found the one match we're looking for. + * Return it. + */ +#if HILITE_SEARCH + if (hilite_search == OPT_ON) + { + /* + * Clear the hilite list and add only + * the matches in this one line. + */ + clr_hilite(); + hilite_line(linepos + skip_bytes, cline, line_len, chpos, sp, ep, NSP, cvt_ops); + } +#endif + if (chop_line()) + { + /* + * If necessary, shift horizontally to make sure + * search match is fully visible. + */ + if (sp[0] != NULL && ep[0] != NULL) + { + int start_off = sp[0] - cline; + int end_off = ep[0] - cline; + int save_hshift = hshift; + int sshift; + int eshift; + hshift = 0; /* make get_seg count screen lines */ + sshift = swidth * get_seg(linepos, linepos + chpos[start_off]); + eshift = swidth * get_seg(linepos, linepos + chpos[end_off]); + if (sshift >= save_hshift && eshift <= save_hshift) + { + hshift = save_hshift; + } else + { + hshift = sshift; + screen_trashed = 1; + } + } + } else if (plastlinepos != NULL) + { + /* + * If the line is so long that the highlighted match + * won't be seen when the line is displayed normally + * (starting at the first char) because it fills the whole + * screen and more, scroll forward until the last char + * of the match appears in the last line on the screen. + * lastlinepos is the position of the first char of that last line. + */ + if (ep[0] != NULL) + { + int end_off = ep[0] - cline; + if (end_off >= swidth * sheight / 4) /* heuristic */ + *plastlinepos = get_lastlinepos(linepos, linepos + chpos[end_off], sheight); + } + } + free(cline); + free(chpos); + if (plinepos != NULL) + *plinepos = linepos; + return (0); + } + } + } + free(cline); + free(chpos); + } +} + +/* + * search for a pattern in history. If found, compile that pattern. + */ +static int hist_pattern(int search_type) +{ +#if CMD_HISTORY + char *pattern; + + set_mlist(ml_search, 0); + pattern = cmd_lastpattern(); + if (pattern == NULL) + return (0); + + if (set_pattern(&search_info, pattern, search_type, 1) < 0) + return (-1); + +#if HILITE_SEARCH + if (hilite_search == OPT_ONPLUS && !hide_hilite) + hilite_screen(); +#endif + + return (1); +#else /* CMD_HISTORY */ + return (0); +#endif /* CMD_HISTORY */ +} + +/* + * Change the caseless-ness of searches. + * Updates the internal search state to reflect a change in the -i flag. + */ +public void chg_caseless(void) +{ + if (!search_info.is_ucase_pattern) + { + /* + * Pattern did not have uppercase. + * Set the search caselessness to the global caselessness. + */ + is_caseless = caseless; + /* + * If regex handles caseless, we need to discard + * the pattern which was compiled with the old caseless. + */ + if (!re_handles_caseless) + /* We handle caseless, so the pattern doesn't change. */ + return; + } + /* + * Regenerate the pattern using the new state. + */ + clear_pattern(&search_info); + (void) hist_pattern(search_info.search_type); +} + +/* + * Search for the n-th occurrence of a specified pattern, + * either forward or backward. + * Return the number of matches not yet found in this file + * (that is, n minus the number of matches found). + * Return -1 if the search should be aborted. + * Caller may continue the search in another file + * if less than n matches are found in this file. + */ +public int search(int search_type, char *pattern, int n) +{ + POSITION pos; + POSITION opos; + POSITION lastlinepos = NULL_POSITION; + + if (pattern == NULL || *pattern == '\0') + { + /* + * A null pattern means use the previously compiled pattern. + */ + search_type |= SRCH_AFTER_TARGET; + if (!prev_pattern(&search_info)) + { + int r = hist_pattern(search_type); + if (r == 0) + error("No previous regular expression", NULL_PARG); + if (r <= 0) + return (-1); + } + if ((search_type & SRCH_NO_REGEX) != + (search_info.search_type & SRCH_NO_REGEX)) + { + error("Please re-enter search pattern", NULL_PARG); + return -1; + } +#if HILITE_SEARCH + if (hilite_search == OPT_ON || status_col) + { + /* + * Erase the highlights currently on screen. + * If the search fails, we'll redisplay them later. + */ + repaint_hilite(0); + } + if (hilite_search == OPT_ONPLUS && hide_hilite) + { + /* + * Highlight any matches currently on screen, + * before we actually start the search. + */ + hide_hilite = 0; + hilite_screen(); + } + hide_hilite = 0; +#endif + } else + { + /* + * Compile the pattern. + */ + int show_error = !(search_type & SRCH_INCR); + if (set_pattern(&search_info, pattern, search_type, show_error) < 0) + return (-1); +#if HILITE_SEARCH + if (hilite_search || status_col) + { + /* + * Erase the highlights currently on screen. + * Also permanently delete them from the hilite list. + */ + repaint_hilite(0); + hide_hilite = 0; + clr_hilite(); + } + if (hilite_search == OPT_ONPLUS || status_col) + { + /* + * Highlight any matches currently on screen, + * before we actually start the search. + */ + hilite_screen(); + } +#endif + } + + /* + * Figure out where to start the search. + */ + pos = search_pos(search_type); + opos = position(sindex_from_sline(jump_sline)); + if (pos == NULL_POSITION) + { + /* + * Can't find anyplace to start searching from. + */ + if (search_type & SRCH_PAST_EOF) + return (n); +#if HILITE_SEARCH + if (hilite_search == OPT_ON || status_col) + repaint_hilite(1); +#endif + error("Nothing to search", NULL_PARG); + return (-1); + } + + n = search_range(pos, NULL_POSITION, search_type, n, -1, + &pos, (POSITION*)NULL, &lastlinepos); + if (n != 0) + { + /* + * Search was unsuccessful. + */ +#if HILITE_SEARCH + if ((hilite_search == OPT_ON || status_col) && n > 0) + /* + * Redisplay old hilites. + */ + repaint_hilite(1); +#endif + return (n); + } + + if (!(search_type & SRCH_NO_MOVE)) + { + /* + * Go to the matching line. + */ + if (lastlinepos != NULL_POSITION) + jump_loc(lastlinepos, BOTTOM); + else if (pos != opos) + jump_loc(pos, jump_sline); + } + +#if HILITE_SEARCH + if (hilite_search == OPT_ON || status_col) + /* + * Display new hilites in the matching line. + */ + repaint_hilite(1); +#endif + return (0); +} + +#if HILITE_SEARCH +/* + * Prepare hilites in a given range of the file. + * + * The pair (prep_startpos,prep_endpos) delimits a contiguous region + * of the file that has been "prepared"; that is, scanned for matches for + * the current search pattern, and hilites have been created for such matches. + * If prep_startpos == NULL_POSITION, the prep region is empty. + * If prep_endpos == NULL_POSITION, the prep region extends to EOF. + * prep_hilite asks that the range (spos,epos) be covered by the prep region. + */ +public void prep_hilite(POSITION spos, POSITION epos, int maxlines) +{ + POSITION nprep_startpos = prep_startpos; + POSITION nprep_endpos = prep_endpos; + POSITION new_epos; + POSITION max_epos; + int result; + int i; + +/* + * Search beyond where we're asked to search, so the prep region covers + * more than we need. Do one big search instead of a bunch of small ones. + */ +#define SEARCH_MORE (3*size_linebuf) + + if (!prev_pattern(&search_info) && !is_filtering()) + return; + + /* + * Make sure our prep region always starts at the beginning of + * a line. (search_range takes care of the end boundary below.) + */ + spos = back_raw_line(spos+1, (char **)NULL, (int *)NULL); + + /* + * If we're limited to a max number of lines, figure out the + * file position we should stop at. + */ + if (maxlines < 0) + max_epos = NULL_POSITION; + else + { + max_epos = spos; + for (i = 0; i < maxlines; i++) + max_epos = forw_raw_line(max_epos, (char **)NULL, (int *)NULL); + } + + /* + * Find two ranges: + * The range that we need to search (spos,epos); and the range that + * the "prep" region will then cover (nprep_startpos,nprep_endpos). + */ + + if (prep_startpos == NULL_POSITION || + (epos != NULL_POSITION && epos < prep_startpos) || + spos > prep_endpos) + { + /* + * New range is not contiguous with old prep region. + * Discard the old prep region and start a new one. + */ + clr_hilite(); + clr_filter(); + if (epos != NULL_POSITION) + epos += SEARCH_MORE; + nprep_startpos = spos; + } else + { + /* + * New range partially or completely overlaps old prep region. + */ + if (epos == NULL_POSITION) + { + /* + * New range goes to end of file. + */ + ; + } else if (epos > prep_endpos) + { + /* + * New range ends after old prep region. + * Extend prep region to end at end of new range. + */ + epos += SEARCH_MORE; + } else /* (epos <= prep_endpos) */ + { + /* + * New range ends within old prep region. + * Truncate search to end at start of old prep region. + */ + epos = prep_startpos; + } + + if (spos < prep_startpos) + { + /* + * New range starts before old prep region. + * Extend old prep region backwards to start at + * start of new range. + */ + if (spos < SEARCH_MORE) + spos = 0; + else + spos -= SEARCH_MORE; + nprep_startpos = spos; + } else /* (spos >= prep_startpos) */ + { + /* + * New range starts within or after old prep region. + * Trim search to start at end of old prep region. + */ + spos = prep_endpos; + } + } + + if (epos != NULL_POSITION && max_epos != NULL_POSITION && + epos > max_epos) + /* + * Don't go past the max position we're allowed. + */ + epos = max_epos; + + if (epos == NULL_POSITION || epos > spos) + { + int search_type = SRCH_FORW | SRCH_FIND_ALL; + search_type |= (search_info.search_type & (SRCH_NO_REGEX|SRCH_SUBSEARCH_ALL)); + for (;;) + { + result = search_range(spos, epos, search_type, 0, maxlines, (POSITION*)NULL, &new_epos, (POSITION*)NULL); + if (result < 0) + return; + if (prep_endpos == NULL_POSITION || new_epos > prep_endpos) + nprep_endpos = new_epos; + + /* + * Check both ends of the resulting prep region to + * make sure they're not filtered. If they are, + * keep going at least one more line until we find + * something that isn't filtered, or hit the end. + */ + if (prep_endpos == NULL_POSITION || nprep_endpos > prep_endpos) + { + if (new_epos >= nprep_endpos && is_filtered(new_epos-1)) + { + spos = nprep_endpos; + epos = forw_raw_line(nprep_endpos, (char **)NULL, (int *)NULL); + if (epos == NULL_POSITION) + break; + maxlines = 1; + continue; + } + } + + if (prep_startpos == NULL_POSITION || nprep_startpos < prep_startpos) + { + if (nprep_startpos > 0 && is_filtered(nprep_startpos)) + { + epos = nprep_startpos; + spos = back_raw_line(nprep_startpos, (char **)NULL, (int *)NULL); + if (spos == NULL_POSITION) + break; + nprep_startpos = spos; + maxlines = 1; + continue; + } + } + break; + } + } + prep_startpos = nprep_startpos; + prep_endpos = nprep_endpos; +} + +/* + * Set the pattern to be used for line filtering. + */ +public void set_filter_pattern(char *pattern, int search_type) +{ + struct pattern_info *filter; + + clr_filter(); + if (pattern == NULL || *pattern == '\0') + { + /* Clear and free all filters. */ + for (filter = filter_infos; filter != NULL; ) + { + struct pattern_info *next_filter = filter->next; + clear_pattern(filter); + free(filter); + filter = next_filter; + } + filter_infos = NULL; + } else + { + /* Create a new filter and add it to the filter_infos list. */ + filter = ecalloc(1, sizeof(struct pattern_info)); + init_pattern(filter); + if (set_pattern(filter, pattern, search_type, 1) < 0) + { + free(filter); + return; + } + filter->next = filter_infos; + filter_infos = filter; + } + screen_trashed = 1; +} + +/* + * Is there a line filter in effect? + */ +public int is_filtering(void) +{ + if (ch_getflags() & CH_HELPFILE) + return (0); + return (filter_infos != NULL); +} +#endif + +#if HAVE_V8_REGCOMP +/* + * This function is called by the V8 regcomp to report + * errors in regular expressions. + */ +public int reg_show_error = 1; + +void regerror(char *s) +{ + PARG parg; + + if (!reg_show_error) + return; + parg.p_string = s; + error("%s", &parg); +} +#endif + diff --git a/third_party/less/signal.c b/third_party/less/signal.c new file mode 100644 index 000000000..7380cc8f9 --- /dev/null +++ b/third_party/less/signal.c @@ -0,0 +1,261 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * 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 + +/* + * "sigs" contains bits indicating signals which need to be processed. + */ +public int sigs; + +extern int sc_width, sc_height; +extern int screen_trashed; +extern int lnloop; +extern int linenums; +extern int wscroll; +extern int reading; +extern int quit_on_intr; +extern int secure; +extern long jump_sline_fraction; + +/* + * Interrupt signal handler. + */ +#if MSDOS_COMPILER!=WIN32C + /* ARGSUSED*/ +static RETSIGTYPE u_interrupt(int type) +{ + bell(); +#if OS2 + LSIGNAL(SIGINT, SIG_ACK); +#endif + LSIGNAL(SIGINT, u_interrupt); + sigs |= S_INTERRUPT; +#if MSDOS_COMPILER==DJGPPC + /* + * If a keyboard has been hit, it must be Ctrl-C + * (as opposed to Ctrl-Break), so consume it. + * (Otherwise, Less will beep when it sees Ctrl-C from keyboard.) + */ + if (kbhit()) + getkey(); +#endif +#if HILITE_SEARCH + set_filter_pattern(NULL, 0); +#endif + if (reading) + intread(); /* May longjmp */ +} +#endif + +#ifdef SIGTSTP +/* + * "Stop" (^Z) signal handler. + */ + /* ARGSUSED*/ +static RETSIGTYPE stop(int type) +{ + LSIGNAL(SIGTSTP, stop); + sigs |= S_STOP; + if (reading) + intread(); +} +#endif + +#undef SIG_LESSWINDOW +#ifdef SIGWINCH +#define SIG_LESSWINDOW SIGWINCH +#else +#ifdef SIGWIND +#define SIG_LESSWINDOW SIGWIND +#endif +#endif + +#ifdef SIG_LESSWINDOW +/* + * "Window" change handler + */ + /* ARGSUSED*/ +public RETSIGTYPE winch(int type) +{ + LSIGNAL(SIG_LESSWINDOW, winch); + sigs |= S_WINCH; + if (reading) + intread(); +} +#endif + +#if MSDOS_COMPILER==WIN32C +/* + * Handle CTRL-C and CTRL-BREAK keys. + */ +#define WIN32_LEAN_AND_MEAN +/* #include */ + +static BOOL WINAPI wbreak_handler(DWORD dwCtrlType) +{ + switch (dwCtrlType) + { + case CTRL_C_EVENT: + case CTRL_BREAK_EVENT: + sigs |= S_INTERRUPT; +#if HILITE_SEARCH + set_filter_pattern(NULL, 0); +#endif + return (TRUE); + default: + break; + } + return (FALSE); +} +#endif + +static RETSIGTYPE terminate(int type) +{ + quit(15); +} + +/* + * Set up the signal handlers. + */ +public void init_signals(int on) +{ + if (on) + { + /* + * Set signal handlers. + */ +#if MSDOS_COMPILER==WIN32C + SetConsoleCtrlHandler(wbreak_handler, TRUE); +#else + (void) LSIGNAL(SIGINT, u_interrupt); +#endif +#ifdef SIGTSTP + (void) LSIGNAL(SIGTSTP, secure ? SIG_IGN : stop); +#endif +#ifdef SIGWINCH + (void) LSIGNAL(SIGWINCH, winch); +#endif +#ifdef SIGWIND + (void) LSIGNAL(SIGWIND, winch); +#endif +#ifdef SIGQUIT + (void) LSIGNAL(SIGQUIT, SIG_IGN); +#endif +#ifdef SIGTERM + (void) LSIGNAL(SIGTERM, terminate); +#endif + } else + { + /* + * Restore signals to defaults. + */ +#if MSDOS_COMPILER==WIN32C + SetConsoleCtrlHandler(wbreak_handler, FALSE); +#else + (void) LSIGNAL(SIGINT, SIG_DFL); +#endif +#ifdef SIGTSTP + (void) LSIGNAL(SIGTSTP, SIG_DFL); +#endif +#ifdef SIGWINCH + (void) LSIGNAL(SIGWINCH, SIG_IGN); +#endif +#ifdef SIGWIND + (void) LSIGNAL(SIGWIND, SIG_IGN); +#endif +#ifdef SIGQUIT + (void) LSIGNAL(SIGQUIT, SIG_DFL); +#endif +#ifdef SIGTERM + (void) LSIGNAL(SIGTERM, SIG_DFL); +#endif + } +} + +/* + * Process any signals we have received. + * A received signal cause a bit to be set in "sigs". + */ +public void psignals(void) +{ + int tsignals; + + if ((tsignals = sigs) == 0) + return; + sigs = 0; + +#ifdef SIGTSTP + if (tsignals & S_STOP) + { + /* + * Clean up the terminal. + */ +#ifdef SIGTTOU + LSIGNAL(SIGTTOU, SIG_IGN); +#endif + clear_bot(); + deinit(); + flush(); + raw_mode(0); +#ifdef SIGTTOU + LSIGNAL(SIGTTOU, SIG_DFL); +#endif + LSIGNAL(SIGTSTP, SIG_DFL); + 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. + */ + LSIGNAL(SIGTSTP, stop); + raw_mode(1); + init(); + screen_trashed = 1; + tsignals |= S_WINCH; + } +#endif +#ifdef S_WINCH + if (tsignals & S_WINCH) + { + int old_width, old_height; + /* + * Re-execute scrsize() 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) + { + wscroll = (sc_height + 1) / 2; + calc_jump_sline(); + calc_shift_count(); + } + screen_trashed = 1; + } +#endif + if (tsignals & S_INTERRUPT) + { + if (quit_on_intr) + quit(QUIT_INTERRUPT); + } +} diff --git a/third_party/less/tags.c b/third_party/less/tags.c new file mode 100644 index 000000000..41f6f220e --- /dev/null +++ b/third_party/less/tags.c @@ -0,0 +1,758 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +#include "less.h" + +#define WHITESP(c) ((c)==' ' || (c)=='\t') + +#if TAGS + +public char ztags[] = "tags"; +public char *tags = ztags; + +static int total; +static int curseq; + +extern int linenums; +extern int sigs; +extern int ctldisp; + +enum tag_result { + TAG_FOUND, + TAG_NOFILE, + TAG_NOTAG, + TAG_NOTYPE, + TAG_INTR +}; + +/* + * Tag type + */ +enum { + T_CTAGS, /* 'tags': standard and extended format (ctags) */ + T_CTAGS_X, /* stdin: cross reference format (ctags) */ + T_GTAGS, /* 'GTAGS': function definition (global) */ + T_GRTAGS, /* 'GRTAGS': function reference (global) */ + T_GSYMS, /* 'GSYMS': other symbols (global) */ + T_GPATH /* 'GPATH': path name (global) */ +}; + +static enum tag_result findctag(char *tag); +static enum tag_result findgtag(char *tag, int type); +static char *nextgtag(void); +static char *prevgtag(void); +static POSITION ctagsearch(void); +static POSITION gtagsearch(void); +static int getentry(char *buf, char **tag, char **file, char **line); + +/* + * The list of tags generated by the last findgtag() call. + * + * Use either pattern or line number. + * findgtag() always uses line number, so pattern is always NULL. + * findctag() uses either pattern (in which case line number is 0), + * or line number (in which case pattern is NULL). + */ +struct taglist { + struct tag *tl_first; + struct tag *tl_last; +}; +struct tag { + struct tag *next, *prev; /* List links */ + char *tag_file; /* Source file containing the tag */ + LINENUM tag_linenum; /* Appropriate line number in source file */ + char *tag_pattern; /* Pattern used to find the tag */ + char tag_endline; /* True if the pattern includes '$' */ +}; +#define TAG_END ((struct tag *) &taglist) +static struct taglist taglist = { TAG_END, TAG_END }; +static struct tag *curtag; + +#define TAG_INS(tp) \ + (tp)->next = TAG_END; \ + (tp)->prev = taglist.tl_last; \ + taglist.tl_last->next = (tp); \ + taglist.tl_last = (tp); + +#define TAG_RM(tp) \ + (tp)->next->prev = (tp)->prev; \ + (tp)->prev->next = (tp)->next; + +/* + * Delete tag structures. + */ +public void cleantags(void) +{ + struct tag *tp; + + /* + * Delete any existing tag list. + * {{ Ideally, we wouldn't do this until after we know that we + * can load some other tag information. }} + */ + while ((tp = taglist.tl_first) != TAG_END) + { + TAG_RM(tp); + free(tp->tag_file); + free(tp->tag_pattern); + free(tp); + } + curtag = NULL; + total = curseq = 0; +} + +/* + * Create a new tag entry. + */ +static struct tag * maketagent(char *name, char *file, LINENUM linenum, char *pattern, int endline) +{ + struct tag *tp; + + tp = (struct tag *) ecalloc(sizeof(struct tag), 1); + tp->tag_file = (char *) ecalloc(strlen(file) + 1, sizeof(char)); + strcpy(tp->tag_file, file); + tp->tag_linenum = linenum; + tp->tag_endline = endline; + if (pattern == NULL) + tp->tag_pattern = NULL; + else + { + tp->tag_pattern = (char *) ecalloc(strlen(pattern) + 1, sizeof(char)); + strcpy(tp->tag_pattern, pattern); + } + return (tp); +} + +/* + * Get tag mode. + */ +public int gettagtype(void) +{ + int f; + + if (strcmp(tags, "GTAGS") == 0) + return T_GTAGS; + if (strcmp(tags, "GRTAGS") == 0) + return T_GRTAGS; + if (strcmp(tags, "GSYMS") == 0) + return T_GSYMS; + if (strcmp(tags, "GPATH") == 0) + return T_GPATH; + if (strcmp(tags, "-") == 0) + return T_CTAGS_X; + f = open(tags, OPEN_READ); + if (f >= 0) + { + close(f); + return T_CTAGS; + } + return T_GTAGS; +} + +/* + * Find tags in tag file. + * Find a tag in the "tags" file. + * Sets "tag_file" to the name of the file containing the tag, + * and "tagpattern" to the search pattern which should be used + * to find the tag. + */ +public void findtag(char *tag) +{ + int type = gettagtype(); + enum tag_result result; + + if (type == T_CTAGS) + result = findctag(tag); + else + result = findgtag(tag, type); + switch (result) + { + case TAG_FOUND: + case TAG_INTR: + break; + case TAG_NOFILE: + error("No tags file", NULL_PARG); + break; + case TAG_NOTAG: + error("No such tag in tags file", NULL_PARG); + break; + case TAG_NOTYPE: + error("unknown tag type", NULL_PARG); + break; + } +} + +/* + * Search for a tag. + */ +public POSITION tagsearch(void) +{ + if (curtag == NULL) + return (NULL_POSITION); /* No gtags loaded! */ + if (curtag->tag_linenum != 0) + return gtagsearch(); + else + return ctagsearch(); +} + +/* + * Go to the next tag. + */ +public char * nexttag(int n) +{ + char *tagfile = (char *) NULL; + + while (n-- > 0) + tagfile = nextgtag(); + return tagfile; +} + +/* + * Go to the previous tag. + */ +public char * prevtag(int n) +{ + char *tagfile = (char *) NULL; + + while (n-- > 0) + tagfile = prevgtag(); + return tagfile; +} + +/* + * Return the total number of tags. + */ +public int ntags(void) +{ + return total; +} + +/* + * Return the sequence number of current tag. + */ +public int curr_tag(void) +{ + return curseq; +} + +/***************************************************************************** + * ctags + */ + +/* + * Find tags in the "tags" file. + * Sets curtag to the first tag entry. + */ +static enum tag_result findctag(char *tag) +{ + char *p; + char *q; + FILE *f; + int taglen; + LINENUM taglinenum; + char *tagfile; + char *tagpattern; + int tagendline; + int search_char; + int err; + char tline[TAGLINE_SIZE]; + struct tag *tp; + + p = shell_unquote(tags); + f = fopen(p, "r"); + free(p); + if (f == NULL) + return TAG_NOFILE; + + cleantags(); + total = 0; + taglen = (int) strlen(tag); + + /* + * Search the tags file for the desired tag. + */ + while (fgets(tline, sizeof(tline), f) != NULL) + { + if (tline[0] == '!') + /* Skip header of extended format. */ + continue; + if (strncmp(tag, tline, taglen) != 0 || !WHITESP(tline[taglen])) + continue; + + /* + * Found it. + * The line contains the tag, the filename and the + * location in the file, separated by white space. + * The location is either a decimal line number, + * or a search pattern surrounded by a pair of delimiters. + * Parse the line and extract these parts. + */ + tagpattern = NULL; + + /* + * Skip over the whitespace after the tag name. + */ + p = skipsp(tline+taglen); + if (*p == '\0') + /* File name is missing! */ + continue; + + /* + * Save the file name. + * Skip over the whitespace after the file name. + */ + tagfile = p; + while (!WHITESP(*p) && *p != '\0') + p++; + *p++ = '\0'; + p = skipsp(p); + if (*p == '\0') + /* Pattern is missing! */ + continue; + + /* + * First see if it is a line number. + */ + tagendline = 0; + taglinenum = getnum(&p, 0, &err); + if (err) + { + /* + * No, it must be a pattern. + * Delete the initial "^" (if present) and + * the final "$" from the pattern. + * Delete any backslash in the pattern. + */ + taglinenum = 0; + search_char = *p++; + if (*p == '^') + p++; + tagpattern = q = p; + while (*p != search_char && *p != '\0') + { + if (*p == '\\') + p++; + if (q != p) + { + *q++ = *p++; + } else + { + q++; + p++; + } + } + tagendline = (q[-1] == '$'); + if (tagendline) + q--; + *q = '\0'; + } + tp = maketagent(tag, tagfile, taglinenum, tagpattern, tagendline); + TAG_INS(tp); + total++; + } + fclose(f); + if (total == 0) + return TAG_NOTAG; + curtag = taglist.tl_first; + curseq = 1; + return TAG_FOUND; +} + +/* + * Edit current tagged file. + */ +public int edit_tagfile(void) +{ + if (curtag == NULL) + return (1); + return (edit(curtag->tag_file)); +} + +static int curtag_match(char constant *line, POSITION linepos) +{ + /* + * Test the line to see if we have a match. + * Use strncmp because the pattern may be + * truncated (in the tags file) if it is too long. + * If tagendline is set, make sure we match all + * the way to end of line (no extra chars after the match). + */ + int len = (int) strlen(curtag->tag_pattern); + if (strncmp(curtag->tag_pattern, line, len) == 0 && + (!curtag->tag_endline || line[len] == '\0' || line[len] == '\r')) + { + curtag->tag_linenum = find_linenum(linepos); + return 1; + } + return 0; +} + +/* + * Search for a tag. + * 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). + */ +static POSITION ctagsearch(void) +{ + POSITION pos, linepos; + LINENUM linenum; + int line_len; + char *line; + int found; + + pos = ch_zero(); + linenum = find_linenum(pos); + + for (found = 0; !found;) + { + /* + * Get lines until we find a matching one or + * until we hit end-of-file. + */ + if (ABORT_SIGS()) + return (NULL_POSITION); + + /* + * Read the next line, and save the + * starting position of that line in linepos. + */ + linepos = pos; + pos = forw_raw_line(pos, &line, &line_len); + if (linenum != 0) + linenum++; + + if (pos == NULL_POSITION) + { + /* + * We hit EOF without a match. + */ + error("Tag not found", NULL_PARG); + return (NULL_POSITION); + } + + /* + * 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); + + if (ctldisp != OPT_ONPLUS) + { + if (curtag_match(line, linepos)) + found = 1; + } else + { + int cvt_ops = CVT_ANSI; + int cvt_len = cvt_length(line_len, cvt_ops); + int *chpos = cvt_alloc_chpos(cvt_len); + char *cline = (char *) ecalloc(1, cvt_len); + cvt_text(cline, line, chpos, &line_len, cvt_ops); + if (curtag_match(cline, linepos)) + found = 1; + free(chpos); + free(cline); + } + } + + return (linepos); +} + +/******************************************************************************* + * gtags + */ + +/* + * Find tags in the GLOBAL's tag file. + * The findgtag() will try and load information about the requested tag. + * It does this by calling "global -x tag" and storing the parsed output + * for future use by gtagsearch(). + * Sets curtag to the first tag entry. + */ +static enum tag_result findgtag(char *tag, int type) +{ + char buf[1024]; + FILE *fp; + struct tag *tp; + + if (type != T_CTAGS_X && tag == NULL) + return TAG_NOFILE; + + cleantags(); + total = 0; + + /* + * If type == T_CTAGS_X then read ctags's -x format from stdin + * else execute global(1) and read from it. + */ + if (type == T_CTAGS_X) + { + fp = stdin; + /* Set tag default because we cannot read stdin again. */ + tags = ztags; + } else + { +#if !HAVE_POPEN + return TAG_NOFILE; +#else + char *command; + char *flag; + char *qtag; + char *cmd = lgetenv("LESSGLOBALTAGS"); + + if (isnullenv(cmd)) + return TAG_NOFILE; + /* Get suitable flag value for global(1). */ + switch (type) + { + case T_GTAGS: + flag = "" ; + break; + case T_GRTAGS: + flag = "r"; + break; + case T_GSYMS: + flag = "s"; + break; + case T_GPATH: + flag = "P"; + break; + default: + return TAG_NOTYPE; + } + + /* Get our data from global(1). */ + qtag = shell_quote(tag); + if (qtag == NULL) + qtag = tag; + command = (char *) ecalloc(strlen(cmd) + strlen(flag) + + strlen(qtag) + 5, sizeof(char)); + sprintf(command, "%s -x%s %s", cmd, flag, qtag); + if (qtag != tag) + free(qtag); + fp = popen(command, "r"); + free(command); +#endif + } + if (fp != NULL) + { + while (fgets(buf, sizeof(buf), fp)) + { + char *name, *file, *line; + int len; + + if (sigs) + { +#if HAVE_POPEN + if (fp != stdin) + pclose(fp); +#endif + return TAG_INTR; + } + len = (int) strlen(buf); + if (len > 0 && buf[len-1] == '\n') + buf[len-1] = '\0'; + else + { + int c; + do { + c = fgetc(fp); + } while (c != '\n' && c != EOF); + } + + if (getentry(buf, &name, &file, &line)) + { + /* + * Couldn't parse this line for some reason. + * We'll just pretend it never happened. + */ + break; + } + + /* Make new entry and add to list. */ + tp = maketagent(name, file, (LINENUM) atoi(line), NULL, 0); + TAG_INS(tp); + total++; + } + if (fp != stdin) + { + if (pclose(fp)) + { + curtag = NULL; + total = curseq = 0; + return TAG_NOFILE; + } + } + } + + /* Check to see if we found anything. */ + tp = taglist.tl_first; + if (tp == TAG_END) + return TAG_NOTAG; + curtag = tp; + curseq = 1; + return TAG_FOUND; +} + +static int circular = 0; /* 1: circular tag structure */ + +/* + * 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(void) +{ + struct tag *tp; + + if (curtag == NULL) + /* No tag loaded */ + return NULL; + + tp = curtag->next; + if (tp == TAG_END) + { + if (!circular) + return NULL; + /* Wrapped around to the head of the queue */ + curtag = taglist.tl_first; + curseq = 1; + } else + { + curtag = tp; + curseq++; + } + return (curtag->tag_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(void) +{ + struct tag *tp; + + if (curtag == NULL) + /* No tag loaded */ + return NULL; + + tp = curtag->prev; + if (tp == TAG_END) + { + if (!circular) + return NULL; + /* Wrapped around to the tail of the queue */ + curtag = taglist.tl_last; + curseq = total; + } else + { + curtag = tp; + curseq--; + } + return (curtag->tag_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 successful. + */ +static POSITION gtagsearch(void) +{ + if (curtag == NULL) + return (NULL_POSITION); /* No gtags loaded! */ + return (find_pos(curtag->tag_linenum)); +} + +/* + * The getentry() parses both standard and extended ctags -x format. + * + * [standard format] + * + * +------------------------------------------------ + * |main 30 main.c main(argc, argv) + * |func 21 subr.c func(arg) + * + * The following commands write this format. + * o Traditinal Ctags with -x option + * o Global with -x option + * See + * + * [extended format] + * + * +---------------------------------------------------------- + * |main function 30 main.c main(argc, argv) + * |func function 21 subr.c func(arg) + * + * The following commands write this format. + * o Exuberant Ctags with -x option + * See + * + * Returns 0 on success, -1 on error. + * The tag, file, and line will each be NUL-terminated pointers + * into buf. + */ +static int getentry(char *buf, char **tag, char **file, char **line) +{ + char *p = buf; + + for (*tag = p; *p && !IS_SPACE(*p); p++) /* tag name */ + ; + if (*p == 0) + return (-1); + *p++ = 0; + for ( ; *p && IS_SPACE(*p); p++) /* (skip blanks) */ + ; + if (*p == 0) + return (-1); + /* + * If the second part begin with other than digit, + * it is assumed tag type. Skip it. + */ + if (!IS_DIGIT(*p)) + { + for ( ; *p && !IS_SPACE(*p); p++) /* (skip tag type) */ + ; + for (; *p && IS_SPACE(*p); p++) /* (skip blanks) */ + ; + } + if (!IS_DIGIT(*p)) + return (-1); + *line = p; /* line number */ + for (*line = p; *p && !IS_SPACE(*p); p++) + ; + if (*p == 0) + return (-1); + *p++ = 0; + for ( ; *p && IS_SPACE(*p); p++) /* (skip blanks) */ + ; + if (*p == 0) + return (-1); + *file = p; /* file name */ + for (*file = p; *p && !IS_SPACE(*p); p++) + ; + if (*p == 0) + return (-1); + *p = 0; + + /* value check */ + if (strlen(*tag) && strlen(*line) && strlen(*file) && atoi(*line) > 0) + return (0); + return (-1); +} + +#endif diff --git a/third_party/less/ttyin.c b/third_party/less/ttyin.c new file mode 100644 index 000000000..12024e64b --- /dev/null +++ b/third_party/less/ttyin.c @@ -0,0 +1,251 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* + * Routines dealing with getting input from the keyboard (i.e. from the user). + */ + +#include "less.h" +#if OS2 +#include "cmd.h" +#include "pckeys.h" +#endif +#if MSDOS_COMPILER==WIN32C +#define WIN32_LEAN_AND_MEAN +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x400 +#endif +/* #include */ +public DWORD console_mode; +public HANDLE tty; +#else +public int tty; +#endif +#if LESSTEST +public char *ttyin_name = NULL; +#endif /*LESSTEST*/ +extern int sigs; +extern int utf_mode; +extern int wheel_lines; + +#if !MSDOS_COMPILER +static int open_tty_device(constant char* dev) +{ +#if OS2 + /* The __open() system call translates "/dev/tty" to "con". */ + return __open(dev, OPEN_READ); +#else + return open(dev, OPEN_READ); +#endif +} + +/* + * Open the tty device. + * Try ttyname(), then try /dev/tty, then use file descriptor 2. + * In Unix, file descriptor 2 is usually attached to the screen, + * but also usually lets you read from the keyboard. + */ +public int open_tty(void) +{ + int fd = -1; +#if LESSTEST + if (ttyin_name != NULL) + fd = open_tty_device(ttyin_name); +#endif /*LESSTEST*/ +#if HAVE_TTYNAME + if (fd < 0) + { + constant char *dev = ttyname(2); + if (dev != NULL) + fd = open_tty_device(dev); + } +#endif + if (fd < 0) + fd = open_tty_device("/dev/tty"); + if (fd < 0) + fd = 2; + return fd; +} +#endif /* MSDOS_COMPILER */ + +/* + * Open keyboard for input. + */ +public void open_getchr(void) +{ +#if MSDOS_COMPILER==WIN32C + /* Need this to let child processes inherit our console handle */ + SECURITY_ATTRIBUTES sa; + memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); + sa.nLength = sizeof(SECURITY_ATTRIBUTES); + sa.bInheritHandle = TRUE; + tty = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ, &sa, + OPEN_EXISTING, 0L, NULL); + GetConsoleMode(tty, &console_mode); + /* Make sure we get Ctrl+C events. */ + SetConsoleMode(tty, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT); +#else +#if MSDOS_COMPILER + extern int fd0; + /* + * Open a new handle to CON: in binary mode + * for unbuffered keyboard read. + */ + fd0 = dup(0); + close(0); + tty = open("CON", OPEN_READ); +#if MSDOS_COMPILER==DJGPPC + /* + * Setting stdin to binary causes Ctrl-C to not + * raise SIGINT. We must undo that side-effect. + */ + (void) __djgpp_set_ctrl_c(1); +#endif +#else + tty = open_tty(); +#endif +#endif +} + +/* + * Close the keyboard. + */ +public void close_getchr(void) +{ +#if MSDOS_COMPILER==WIN32C + SetConsoleMode(tty, console_mode); + CloseHandle(tty); +#endif +} + +#if MSDOS_COMPILER==WIN32C +/* + * Close the pipe, restoring the keyboard (CMD resets it, losing the mouse). + */ +public int pclose(FILE *f) +{ + int result; + + result = _pclose(f); + SetConsoleMode(tty, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT); + return result; +} +#endif + +/* + * Get the number of lines to scroll when mouse wheel is moved. + */ +public int default_wheel_lines(void) +{ + int lines = 1; +#if MSDOS_COMPILER==WIN32C + if (SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &lines, 0)) + { + if (lines == WHEEL_PAGESCROLL) + lines = 3; + } +#endif + return lines; +} + +/* + * Get a character from the keyboard. + */ +public int getchr(void) +{ + char c; + int result; + + do + { + flush(); +#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC + /* + * In raw read, we don't see ^C so look here for it. + */ +#if MSDOS_COMPILER==WIN32C + if (ABORT_SIGS()) + return (READ_INTR); + c = WIN32getch(); +#else + c = getch(); +#endif + result = 1; + if (c == '\003') + return (READ_INTR); +#else + { + unsigned char uc; + result = iread(tty, &uc, sizeof(char)); + c = (char) uc; + } + if (result == READ_INTR) + return (READ_INTR); + if (result < 0) + { + /* + * Don't call error() here, + * because error calls getchr! + */ + quit(QUIT_ERROR); + } +#endif +#if LESSTEST + if (c == LESS_DUMP_CHAR) + { + dump_screen(); + result = 0; + continue; + } +#endif +#if 0 /* allow entering arbitrary hex chars for testing */ + /* ctrl-A followed by two hex chars makes a byte */ + { + static int hex_in = 0; + static int hex_value = 0; + if (c == CONTROL('A')) + { + hex_in = 2; + result = 0; + continue; + } + if (hex_in > 0) + { + int v; + if (c >= '0' && c <= '9') + v = c - '0'; + else if (c >= 'a' && c <= 'f') + v = c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + v = c - 'A' + 10; + else + v = 0; + hex_value = (hex_value << 4) | v; + if (--hex_in > 0) + { + result = 0; + continue; + } + c = hex_value; + } + } +#endif + /* + * Various parts of the program cannot handle + * an input character of '\0'. + * If a '\0' was actually typed, convert it to '\340' here. + */ + if (c == '\0') + c = '\340'; + } while (result != 1); + + return (c & 0xFF); +} diff --git a/third_party/less/ubin.inc b/third_party/less/ubin.inc new file mode 100644 index 000000000..14e651997 --- /dev/null +++ b/third_party/less/ubin.inc @@ -0,0 +1,11 @@ +/* Generated by "./mkutable -f2 Cc Cs Co Zl Zp -- unicode/UnicodeData.txt" on Mon Nov 14 18:19:24 PST 2022 */ + { 0x0000, 0x0007 }, /* Cc */ + { 0x000b, 0x000b }, /* Cc */ + { 0x000e, 0x001f }, /* Cc */ + { 0x007f, 0x009f }, /* Cc */ + { 0x2028, 0x2028 }, /* Zl */ + { 0x2029, 0x2029 }, /* Zp */ + { 0xd800, 0xdfff }, /* Cs */ + { 0xe000, 0xf8ff }, /* Co */ + { 0xf0000, 0xffffd }, /* Co */ + { 0x100000, 0x10fffd }, /* Co */ diff --git a/third_party/less/version.c b/third_party/less/version.c new file mode 100644 index 000000000..8c20787bf --- /dev/null +++ b/third_party/less/version.c @@ -0,0 +1,998 @@ +/* + * Copyright (C) 1984-2023 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information, see the README file. + */ + + +/* +----------------------- CHANGE HISTORY -------------------------- + + 1/29/84 Allowed use on standard input + 2/1/84 Added E, N, P commands + 4/17/84 Added '=' command, 'stop' signal handling + 4/20/84 Added line folding +v2 4/27/84 Fixed '=' command to use BOTTOM_PLUS_ONE, + instead of TOP, added 'p' & 'v' commands +v3 5/3/84 Added -m and -t options, '-' command +v4 5/3/84 Added LESS environment variable +v5 5/3/84 New comments, fixed '-' command slightly +v6 5/15/84 Added -Q, visual bell +v7 5/24/84 Fixed jump_back(n) bug: n should count real + lines, not folded lines. Also allow number on G command. +v8 5/30/84 Re-do -q and -Q commands +v9 9/25/84 Added "+" argument +v10 10/10/84 Fixed bug in -b argument processing +v11 10/18/84 Made error() ring bell if \n not entered. +----------------------------------------------------------------- +v12 2/13/85 Reorganized signal handling and made portable to 4.2bsd. +v13 2/16/85 Reword error message for '-' command. +v14 2/22/85 Added -bf and -bp variants of -b. +v15 2/25/85 Miscellaneous changes. +v16 3/13/85 Added -u flag for backspace processing. +v17 4/13/85 Added j and k commands, changed -t default. +v18 4/20/85 Rewrote signal handling code. +v19 5/2/85 Got rid of "verbose" eq_message(). + Made search() scroll in some cases. +v20 5/21/85 Fixed screen.c ioctls for System V. +v21 5/23/85 Fixed some first_cmd bugs. +v22 5/24/85 Added support for no RECOMP nor REGCMP. +v23 5/25/85 Miscellanous changes and prettying up. + Posted to USENET. +----------------------------------------------------------------- +v24 6/3/85 Added ti,te terminal init & de-init. + (Thanks to Mike Kersenbrock) +v25 6/8/85 Added -U flag, standout mode underlining. +v26 6/9/85 Added -M flag. + Use underline termcap (us) if it exists. +v27 6/15/85 Renamed some variables to make unique in + 6 chars. Minor fix to -m. +v28 6/28/85 Fixed right margin bug. +v29 6/28/85 Incorporated M.Rose's changes to signal.c +v30 6/29/85 Fixed stupid bug in argument processing. +v31 7/15/85 Added -p flag, changed repaint algorithm. + Added kludge for magic cookie terminals. +v32 7/16/85 Added cat_file if output not a tty. +v33 7/23/85 Added -e flag and EDITOR. +v34 7/26/85 Added -s flag. +v35 7/27/85 Rewrote option handling; added option.c. +v36 7/29/85 Fixed -e flag to work if not last file. +v37 8/10/85 Added -x flag. +v38 8/19/85 Changed prompting; created prompt.c. +v39 8/24/85 (Not -p) does not initially clear screen. +v40 8/26/85 Added "skipping" indicator in forw(). + Posted to USENET. +----------------------------------------------------------------- +v41 9/17/85 ONLY_RETURN, control char commands, + faster search, other minor fixes. +v42 9/25/85 Added ++ command line syntax; + ch_fsize for pipes. +v43 10/15/85 Added -h flag, changed prim.c algorithms. +v44 10/16/85 Made END print in all cases of eof; + ignore SIGTTOU after receiv ing SIGTSTP. +v45 10/16/85 Never print backspaces unless -u. +v46 10/24/85 Backwards scroll in jump_loc. +v47 10/30/85 Fixed bug in edit(): *first_cmd==0 +v48 11/16/85 Use TIOCSETN instead of TIOCSETP. + Added marks (m and ' commands). + Posted to USENET. +----------------------------------------------------------------- +v49 1/9/86 Fixed bug: signal didn't clear mcc. +v50 1/15/86 Added ' (quote) to gomark. +v51 1/16/86 Added + cmd, fixed problem if first_cmd + fails, made g cmd sort of "work" on pipes + ev en if bof is no longer buffered. +v52 1/17/86 Made short files work better. +v53 1/20/86 Added -P option. +v54 1/20/86 Changed help to use HELPFILE. +v55 1/23/86 Messages work better if not tty output. +v56 1/24/86 Added -l option. +v57 1/31/86 Fixed -l to get confirmation before + ov erwriting an existing file. +v58 8/28/86 Added filename globbing. +v59 9/15/86 Fixed some bugs with very long filenames. +v60 9/26/86 Incorporated changes from Leith (Casey) + Leedom for boldface and -z option. +v61 9/26/86 Got rid of annoying repaints after ! cmd. + Posted to USENET. +----------------------------------------------------------------- +v62 12/23/86 Added is_directory(); change -z default to + -1 instead of 24; cat-and-exit if -e and + file is less than a screenful. +v63 1/8/87 Fixed bug in cat-and-exit if > 1 file. +v64 1/12/87 Changed puts/putstr, putc/putchr, + getc/getchr to av oid name conflict with + stdio functions. +v65 1/26/87 Allowed '-' command to change NUMBER + v alued options (thanks to Gary Puckering) +v66 2/13/87 Fixed bug: prepaint should use force=1. +v67 2/24/87 Added !! and % expansion to ! command. +v68 2/25/87 Added SIGWINCH and TIOCGWINSZ support; + changed is_directory to bad_file. + (thanks to J. Robert Ward) +v69 2/25/87 Added SIGWIND and WIOCGETD (for Unix PC). +v70 3/13/87 Changed help cmd from 'h' to 'H'; better + error msgs in bad_file, errno_message. +v71 5/11/87 Changed -p to -c, made triple -c/-C + for clear-eol like more's -c. +v72 6/26/87 Added -E, -L, use $SHELL in lsystem(). + (thanks to Stev e Spearman) +v73 6/26/87 Allow Examine "#" for previous file. + Posted to USENET 8/25/87. +----------------------------------------------------------------- +v74 9/18/87 Fix conflict in EOF symbol with stdio.h, + Make os.c more portable to BSD. +v75 9/23/87 Fix problems in get_term (thanks to + Paul Eggert); new backwards scrolling in + jump_loc (thanks to Marion Hakanson). +v76 9/23/87 Added -i flag; allow single "!" to + inv oke a shell (thanks to Franco Barber). +v77 9/24/87 Added -n flag and line number support. +v78 9/25/87 Fixed problem with prompts longer than + the screen width. +v79 9/29/87 Added the _ command. +v80 10/6/87 Allow signal to break out of linenum scan. +v81 10/6/87 Allow -b to be changed from within less. +v82 10/7/87 Add cmd_decode to use a table for key + binding (thanks to Dav id Nason). +v83 10/9/87 Allow .less file for user-defined keys. +v84 10/11/87 Fix -e/-E problems (thanks to Felix Lee). +v85 10/15/87 Search now keeps track of line numbers. +v86 10/20/87 Added -B option and autobuf; fixed + "pipe error" bug. +v87 3/1/88 Fix bug re BSD signals while reading file. +v88 3/12/88 Use new format for -P option (thanks to + der Mouse), allow "+-c" without message, + fix bug re BSD hangup. +v89 3/18/88 Turn off line numbers if linenum scan + is interrupted. +v90 3/30/88 Allow -P from within less. +v91 3/30/88 Added tags file support (new -t option) + (thanks to Brian Campbell). +v92 4/4/88 Added -+option syntax. +v93 4/11/88 Add support for slow input (thanks to + Joe Orost & apologies for taking almost + 3 years to get this in!) +v94 4/11/88 Redo reading/signal stuff. +v95 4/20/88 Repaint screen better after signal. +v96 4/21/88 Add /! and ?! commands. +v97 5/17/88 Allow -l/-L from within less. + Eliminate some static arrays (use calloc). + Posted to USENET. +----------------------------------------------------------------- +v98 10/14/88 Fix incorrect calloc call; uninitialized + var in exec_mca; core dump on unknown TERM. + Make v cmd work if past last line of file. + Fix some signal bugs. +v99 10/29/88 Allow space between -X and string, + when X is a string-valued option. +v100 1/5/89 Fix globbing bug when $SHELL not set; + allow spaces after -t command. +v101 1/6/89 Fix problem with long (truncated) lines + in tags file (thanks to Neil Dixon). +v102 1/6/89 Fix bug with E# when no prev file; + allow spaces after -l command. +v103 3/14/89 Add -N, -f and -? options. Add z and w + commands. Add %L for prompt strings. +v104 3/16/89 Added EDITPROTO. +v105 3/20/89 Fix bug in find_linenum which cached + incorrectly on long lines. +v106 3/31/89 Added -k option and multiple lesskey + files. +v107 4/27/89 Add 8-bit char support and -g option. + Split option code into 3 files. +v108 5/5/89 Allocate position table dynamically + (thanks to Paul Eggert); change % command + from "percent" to vi-style brace finder. +v109 5/10/89 Added ESC-% command, split prim.c. +v110 5/24/89 Fixed bug in + option; fixed repaint bug + under Sun windows (thanks to Paul Eggert). +v111 5/25/89 Generalized # and % expansion; use + calloc for some error messages. +v112 5/30/89 Get rid of ESC-%, add {}()[] commands. +v113 5/31/89 Optimize lseeks (thanks to Paul Eggert). +v114 7/25/89 Added ESC-/ and ESC-/! commands. +v115 7/26/89 Added ESC-n command. +v116 7/31/89 Added find_pos to optimize g command. +v117 8/1/89 Change -f option to -r. +v118 8/2/89 Save positions for all previous files, + not just the immediately previous one. +v119 8/7/89 Save marks across file boundaries. + Add file handle stuff. +v120 8/11/89 Add :ta command. +v121 8/16/89 Add -f option. +v122 8/30/89 Fix performance with many buffers. +v123 8/31/89 Verbose prompts for string options. + Posted beta to USENET. +----------------------------------------------------------------- +v124 9/18/89 Reorganize search commands, + N = rev, ESC-n = span, add ESC-N. +v125 9/18/89 Fix tab bug (thanks to Alex Liu). + Fix EOF bug when both -w and -c. +v126 10/25/89 Add -j option. +v127 10/27/89 Fix problems with blank lines before BOF. +v128 10/27/89 Add %bj, etc. to prompt strings. +v129 11/3/89 Add -+,-- commands; add set-option and + unset-option to lesskey. +v130 11/6/89 Generalize A_EXTRA to string, remove + set-option, unset-option from lesskey. +v131 11/7/89 Changed name of EDITPROTO to LESSEDIT. +v132 11/8/89 Allow editing of command prefix. +v133 11/16/89 Add -y option (thanks to Jeff Sullivan). +v134 12/1/89 Glob filenames in the -l command. +v135 12/5/89 Combined {}()[] commands into one, and + added ESC-^F and ESC-^B commands. +v136 1/20/90 Added -S, -R flags. Added | command. + Added warning for binary files. (thanks + to Richard Brittain and J. Sullivan). +v137 1/21/90 Rewrote horrible pappend code. + Added * notation for hi-bit chars. +v138 1/24/90 Fix magic cookie terminal handling. + Get rid of "cleanup" loop in ch_get. +v139 1/27/90 Added MSDOS support. (many thanks + to Richard Brittain). +v140 2/7/90 Editing a new file adds it to the + command line list. +v141 2/8/90 Add edit_list for editing >1 file. +v142 2/10/90 Add :x command. +v143 2/11/90 Add * and @ modifies to search cmds. + Change ESC-/ cmd from /@* to / *. +v144 3/1/90 Messed around with ch_zero; + no real change. +v145 3/2/90 Added -R and -v/-V for MSDOS; + renamed FILENAME to avoid conflict. +v146 3/5/90 Pull cmdbuf functions out of command.c +v147 3/7/90 Implement ?@; fix multi-file edit bugs. +v148 3/29/90 Fixed bug in :e then :e#. +v149 4/3/90 Change error,ierror,query to use PARG. +v150 4/6/90 Add LESS_CHARSET, LESS_CHARDEF. +v151 4/13/90 Remove -g option; clean up ispipe. +v152 4/14/90 lsystem() closes input file, for + editors which require exclusive open. +v153 4/18/90 Fix bug if SHELL unset; + fix bug in overstrike control char. +v154 4/25/90 Output to fd 2 via buffer. +v155 4/30/90 Ignore -i if uppercase in pattern + (thanks to Michael Rendell.) +v156 5/3/90 Remove scroll limits in forw() & back(); + causes problems with -c. +v157 5/4/90 Forward search starts at next real line + (not screen line) after jump target. +v158 6/14/90 Added F command. +v159 7/29/90 Fix bug in exiting: output not flushed. +v160 7/29/90 Clear screen before initial output w/ -c. +v161 7/29/90 Add -T flag. +v162 8/14/90 Fix bug with +F on command line. +v163 8/21/90 Added LESSBINFMT variable. +v164 9/5/90 Added -p, LINES, COLUMNS and + unset mark ' == BOF, for 1003.2 D5. +v165 9/6/90 At EOF with -c set, don't display empty + screen when try to page forward. +v166 9/6/90 Fix G when final line in file wraps. +v167 9/11/90 Translate CR/LF -> LF for 1003.2. +v168 9/13/90 Return to curr file if "tag not found". +v169 12/12/90 G goes to EOF even if file has grown. +v170 1/17/91 Add optimization for BSD _setjmp; + fix #include ioctl.h TERMIO problem. + (thanks to Paul Eggert) + Posted to USENET. +----------------------------------------------------------------- +v171 3/6/91 Fix -? bug in get_filename. +v172 3/15/91 Fix G bug in empty file. + Fix bug with ?\n and -i and uppercase + pattern at EOF! + (thanks to Paul Eggert) +v173 3/17/91 Change N cmd to not permanently change + direction. (thanks to Brian Matthews) +v174 3/18/91 Fix bug with namelogfile not getting + cleared when change files. +v175 3/18/91 Fix bug with ++cmd on command line. + (thanks to Jim Meyering) +v176 4/2/91 Change | to not force current screen, + include marked line, start/end from + top of screen. Improve search speed. + (thanks to Don Mears) +v177 4/2/91 Add LESSHELP variable. + Fix bug with F command with -e. + Try /dev/tty for input before using fd 2. + Patches posted to USENET 4/2/91. +----------------------------------------------------------------- +v178 4/8/91 Fixed bug in globbing logfile name. + (thanks to Jim Meyering) +v179 4/9/91 Allow negative -z for screen-relative. +v180 4/9/91 Clear to eos rather than eol if "db"; + don't use "sr" if "da". + (thanks to Tor Lillqvist) +v181 4/18/91 Fixed bug with "negative" chars 80 - FF. + (thanks to Benny Sander Hofmann) +v182 5/16/91 Fixed bug with attribute at EOL. + (thanks to Brian Matthews) +v183 6/1/91 Rewrite linstall to do smart config. +v184 7/11/91 Process \b in searches based on -u + rather than -i. +v185 7/11/91 -Pxxx sets short prompt; assume SIGWINCH + after a SIGSTOP. (thanks to Ken Laprade) +----------------------------------------------------------------- +v186 4/20/92 Port to MS-DOS (Microsoft C). +v187 4/23/92 Added -D option & TAB_COMPLETE_FILENAME. +v188 4/28/92 Added command line editing features. +v189 12/8/92 Fix mem overrun in anscreen.c:init; + fix edit_list to recover from bin file. +v190 2/13/93 Make TAB enter one filename at a time; + create ^L with old TAB functionality. +v191 3/10/93 Defer creating "flash" page for MS-DOS. +v192 9/6/93 Add BACK-TAB. +v193 9/17/93 Simplify binary_file handling. +v194 1/4/94 Add rudiments of alt_filename handling. +v195 1/11/94 Port back to Unix; support keypad. +----------------------------------------------------------------- +v196 6/7/94 Fix bug with bad filename; fix IFILE + type problem. (thanks to David MacKenzie) +v197 6/7/94 Fix bug with .less tables inserted wrong. +v198 6/23/94 Use autoconf installation technology. + (thanks to David MacKenzie) +v199 6/29/94 Fix MS-DOS build (thanks to Tim Wiegman). +v200 7/25/94 Clean up copyright, minor fixes. + Posted to prep.ai.mit.edu +----------------------------------------------------------------- +v201 7/27/94 Check for no memcpy; add casts to calloc; + look for regcmp in libgen.a. + (thanks to Kaveh Ghazi). +v202 7/28/94 Fix bug in edit_next/edit_prev with + non-existent files. +v203 8/2/94 Fix a variety of configuration bugs on + various systems. (thanks to Sakai + Kiyotaka, Harald Koenig, Bjorn Brox, + Teemu Rantanen, and Thorsten Lockert) +v204 8/3/94 Use strerror if available. + (thanks to J.T. Conklin) +v205 8/5/94 Fix bug in finding "me" termcap entry. + (thanks to Andreas Stolcke) +8/10/94 v205+: Change BUFSIZ to LBUFSIZE to avoid name + conflict with stdio.h. + Posted to prep.ai.mit.edu +----------------------------------------------------------------- +v206 8/10/94 Use initial_scrpos for -t to avoid + displaying first page before init(). + (thanks to Dominique Petitpierre) +v207 8/12/94 Fix bug if stdout is not tty. +v208 8/16/94 Fix bug in close_altfile if goto err1 + in edit_ifile. (Thanks to M.J. Hewitt) +v209 8/16/94 Change scroll to wscroll to avoid + conflict with library function. +v210 8/16/94 Fix bug with bold on 8 bit chars. + (thanks to Vitor Duarte) +v211 8/16/94 Don't quit on EOI in jump_loc / forw. +v212 8/18/94 Use time_t if available. +v213 8/20/94 Allow ospeed to be defined in termcap.h. +v214 8/20/94 Added HILITE_SEARCH, -F, ESC-u cmd. + (thanks to Paul Lew and Bob Byrnes) +v215 8/23/94 Fix -i toggle behavior. +v216 8/23/94 Process BS in all searches, not only -u. +v217 8/24/94 Added -X flag. +v218 8/24/94 Reimplement undo_search. +v219 8/24/94 Find tags marked with line number + instead of pattern. +v220 8/24/94 Stay at same position after SIG_WINCH. +v221 8/24/94 Fix bug in file percentage in big file. +v222 8/25/94 Do better if can't reopen current file. +v223 8/27/94 Support setlocale. + (thanks to Robert Joop) +v224 8/29/94 Revert v216: process BS in search + only if -u. +v225 9/6/94 Rewrite undo_search again: toggle. +v226 9/15/94 Configuration fixes. + (thanks to David MacKenzie) +v227 9/19/94 Fixed strerror config problem. + Posted to prep.ai.mit.edu +----------------------------------------------------------------- +v228 9/21/94 Fix bug in signals: repeated calls to + get_editkeys overflowed st_edittable. +v229 9/21/94 Fix "Nothing to search" error if -a + and SRCH_PAST_EOF. +v230 9/21/94 Don't print extra error msg in search + after regerror(). +v231 9/22/94 Fix hilite bug if search matches 0 chars. + (thanks to John Polstra) +v232 9/23/94 Deal with weird systems that have + termios.h but not tcgetattr(). + Posted to prep.ai.mit.edu +----------------------------------------------------------------- +v233 9/26/94 Use get_term() instead of pos_init() in + psignals to re-get lower_left termcap. + (Thanks to John Malecki) +v234 9/26/94 Make MIDDLE closer to middle of screen. +v235 9/27/94 Use local strchr if system doesn't have. +v236 9/28/94 Don't use libucb; use libterm if + libtermcap & libcurses doesn't work. + (Fix for Solaris; thanks to Frank Kaefer) +v237 9/30/94 Use system isupper() etc if provided. + Posted to prep.ai.mit.edu +----------------------------------------------------------------- +v238 10/6/94 Make binary non-blinking if LESSBINFMT + is set to a string without a *. +v239 10/7/94 Don't let delimit_word run back past + beginning of cmdbuf. +v240 10/10/94 Don't write into termcap buffer. + (Thanks to Benoit Speckel) +v241 10/13/94 New lesskey file format. + Don't expand filenames in search command. +v242 10/14/94 Allow lesskey specification of "literal". +v243 10/14/94 Add #stop command to lesskey. +v244 10/16/94 Add -f flag to lesskey. +v245 10/25/94 Allow TAB_COMPLETE_FILENAME to be undefd. +v246 10/27/94 Move help file to /usr/local/share. +v247 10/27/94 Add -V option. +v248 11/5/94 Add -V option to lesskey. +v249 11/5/94 Remove -f flag from lesskey; default + input file is ~/.lesskey.in, not stdin. +v250 11/7/94 Lesskey input file "-" means stdin. +v251 11/9/94 Convert cfgetospeed result to ospeed. + (Thanks to Andrew Chernov) +v252 11/16/94 Change default lesskey input file from + .lesskey.in to .lesskey. + Posted to prep.ai.mit.edu +----------------------------------------------------------------- +v253 11/21/94 Fix bug when tags file has a backslash. +v254 12/6/94 Fix -k option. +v255 12/8/94 Add #define EXAMINE to disable :e etc. +v256 12/10/94 Change highlighting: only highlite search + results (but now it is reliable). +v257 12/10/94 Add goto_line and repaint_highlight + to optimize highlight repaints. +v258 12/12/94 Fixup in hilite_line if BS_SPECIAL. +v259 12/12/94 Convert to autoconf 2.0. +v260 12/13/94 Add SECURE define. +v261 12/14/94 Use system WERASE char as EC_W_BACKSPACE. +v262 12/16/94 Add -g/-G flag and screen_hilite. +v263 12/20/94 Reimplement/optimize -G flag behavior. +v264 12/23/94 Allow EXTRA string after line-edit cmd + in lesskey file. +v265 12/24/94 Add LESSOPEN=|cmd syntax. +v266 12/26/94 Add -I flag. +v267 12/28/94 Formalize the four-byte header emitted + by a LESSOPEN pipe. +v268 12/28/94 Get rid of four-byte header. +v269 1/2/95 Close alt file before open new one. + Avoids multiple popen(). +v270 1/3/95 Use VISUAL; use S_ISDIR/S_ISREG; fix + config problem with Solaris POSIX regcomp. +v271 1/4/95 Don't quit on read error. +v272 1/5/95 Get rid of -L. +v273 1/6/95 Fix ch_ungetchar bug; don't call + LESSOPEN on a pipe. +v274 1/6/95 Ported to OS/2 (thanks to Kai Uwe Rommel) +v275 1/18/95 Fix bug if toggle -G at EOF. +v276 1/30/95 Fix OS/2 version. +v277 1/31/95 Add "next" charset; don't display ^X + for X > 128. +v278 2/14/95 Change default for -G. + Posted to prep.ai.mit.edu +----------------------------------------------------------------- +v279 2/22/95 Add GNU options --help, --version. + Minor config fixes. +v280 2/24/95 Clean up calls to glob(); don't set # + if we can't open the new file. +v281 2/24/95 Repeat search should turn on hilites. +v282 3/2/95 Minor fixes. +v283 3/2/95 Fix homefile; make OS2 look in $HOME. +v284 3/2/95 Error if "v" on LESSOPENed file; + "%" figures out file size on pipe. +v285 3/7/95 Don't set # in lsystem; + lesskey try $HOME first. +v286 3/7/95 Reformat change history (too much free time?). +v287 3/8/95 Fix hilite bug if overstrike multiple chars. +v288 3/8/95 Allow lesskey to override get_editkey keys. +v289 3/9/95 Fix adj_hilite bug when line gets processed by + hilite_line more than once. +v290 3/9/95 Make configure automatically. Fix Sequent problem + with incompatible sigsetmask(). + Posted to prep.ai.mit.edu +----------------------------------------------------------------- +v291 3/21/95 Add #env to lesskey. Fix MS-DOS build. + Posted to simtel. +----------------------------------------------------------------- +v292 4/24/95 Add MS-DOS support for Borland C. + Fix arrow keys in MS-DOS versions. +v293 4/28/95 Add auto-versioning stuff to make dist. +v294 5/12/95 Fix Borland build. +v295 1/20/96 Fix search on squished file; add /@@. +v296 1/23/96 Allow cmdbuf larger than screen width. +v297 1/24/96 Don't call termcap if tgetent fails; + add #defines for buffers. +v298 1/24/96 Change @@ to ^K. + Add alternate search modifiers ^N, ^F, ^E. +v299 1/25/96 Fix percent overflow in jump_percent (thanks to Brent Wiese); + don't send "ti" after shell command till RETURN pressed. +v300 1/25/96 Change -U to print tabs as ^I. +v301 1/30/96 Make hilites work in cmd F output. +v302 1/31/96 Fix cmd F to notice window-change signals. +v303 1/31/96 Add ESC-SPACE command. +v304 2/1/96 Add ^R search modifier; add LESSSECURE. +v305 2/2/96 Workaround Linux /proc kernel bug; add LESSKEY. +v306 3/16/96 Minor fixes. +v307 3/25/96 Allow cmd line arg "--"; fix DOS & OS/2 defines.h. +v308 4/4/96 Port to OS-9 (thanks to Boisy Pitre); fix -d. +v309 4/9/96 Fix OS-9 version; fix tags bug with "$". +v310 4/10/96 Get rid of HELPFILE. +v311 4/22/96 Add Windows32 support; merge doscreen.c into screen.c. +v312 4/24/96 Don't quit after "cannot reopen" error. +v313 4/25/96 Added horizontal scrolling. +v314 4/26/96 Modified -e to quit on reaching end of a squished file. +v315 4/26/96 Fix "!;TAB" bug. +v316 5/2/96 Make "|a" when (a < curr screen) go to end of curr screen. +v317 5/14/96 Various fixes for the MS-DOS and OS/2 builds. + Added ## and %% handling for filenames +v318 5/29/96 Port to OS-9 Microware compiler; minor fixes + (thanks to Martin Gregorie). +v319 7/8/96 Fix Windows port (thanks to Jeff Paquette). +v320 7/11/96 Final fixes for Windows port. +v321 7/18/96 Minor fixes. + Posted to Web page. +----------------------------------------------------------------- +v322 8/13/96 Fix bug in shell escape from help file; add support for + Microsoft Visual C under Windows; numerous small fixes. +v323 8/19/96 Fixes for Windows version (thanks to Simon Munton); + fix for Linux library weirdness (thanks to Jim Diamond); + port to DJGPP (thanks to Eli Zaretskii). +v324 8/21/96 Add support for spaces in filenames (thanks to Simon Munton). +v325 8/21/96 Add lessecho, for spaces in filenames under Unix. +v326 8/27/96 Fix DJGPP version. +v327 9/1/96 Reorganize lglob, make spaces in filenames work better in Unix. +v328 10/7/96 Append / to directory name in filename completion. + Fix MS-DOS and OS-9 versions. +v329 10/11/96 Fix more MS-DOS bugs; add LESSSEPARATOR; add -" option. + Add LESSMETACHARS, LESSMETAESCAPE. +v330 10/21/96 Minor fixes. + Posted to Web page. +----------------------------------------------------------------- +v331 4/22/97 Various Windows fixes (thanks to Gurusamy Sarathy). +v332 4/22/97 Enter filenames from cmd line into edit history. + Posted to Web page. +----------------------------------------------------------------- +v333 3/4/99 Changed -w to highlite new line after forward movement. +v334 3/9/99 Avoid overflowing prompt buffer; add %d and %D. +v335 3/20/99 Add EBCDIC support (thanks to Thomas Dorner). + Use HOMEDRIVE/HOMEPATH on Windows (thanks to Preston Bannister). + Posted to Web page. +----------------------------------------------------------------- +v336 4/8/99 Fix installation bugs. +v337 4/9/99 Fix another installation bug. + Posted to Web page. +----------------------------------------------------------------- +v338 4/13/99 Add support for long option names. +v339 4/18/99 Add \k, long option names to lesskey. Add -^P. Add :d. +v340 4/21/99 Add regexec2. Fix Windows build. + Posted to Web page. +----------------------------------------------------------------- +v341 5/6/99 Add -F option; %c & ?c prompt escapes. + (Thanks to Michele Maltoni) +v342 7/22/99 Add system-wide lesskey file; allow GPL or Less License. +v343 9/23/99 Support UTF-8 (Thanks to Robert Brady). + Add %P and ?P in prompts. +v344 10/27/99 -w highlights target line of g and p commands. +v345 10/29/99 Make -R pass thru ESC but not other control chars. + Posted to Web page. +----------------------------------------------------------------- +v346 11/4/99 Fix bugs in long option processing; R cmd should clear hilites. + Posted to Web page. +----------------------------------------------------------------- +v347 12/13/99 Fixes for DJGPP version (thanks to Eli Zaretskii). +v348 12/28/99 Fix deleting file with marks (thanks to Dimitar Jekov). + Fix color problem in DJGPP version (thanks to Eli Zaretskii). +v349 1/24/00 Fix minor DJGPP bugs; check environment vars for UTF-8; + add --with-editor (thanks to Eli, Markus Kuhn, Thomas Schoepf). +v350 3/1/00 Fix clear-while-standout bug. +v351 3/5/00 Change -M and = prompts to show top & bottom line number. + Posted to Web page. +----------------------------------------------------------------- +v352 3/8/00 Fix scan_option NULL dereference. +----------------------------------------------------------------- +v353 3/20/00 Fix SECURE compile bug, allow space after numeric option. +v354 3/23/00 Add support for PCRE; add --with-regex configure option. +----------------------------------------------------------------- +v355 6/28/00 Add -# option (thanks to Andy Levinson). +v356 7/5/00 Add -J option. +v357 7/6/00 Support sigprocmask. +----------------------------------------------------------------- +v358 7/8/00 Fix problems with #stop in lesskey file. + Posted to Web page. +----------------------------------------------------------------- +v359 9/10/00 Fixes for Win32 display problems (thanks to Maurizio Vairani). +v360 1/17/01 Move sysless to etc. +v361 12/4/01 Add IBM-1047 charset & EBCDIC fixes (thanks to Thomas Dorner). + Fix 32 bit dependencies (thanks to Paul Eggert). + Fix UTF-8 overstriking (thanks to Robert Brady). +v362 12/4/01 Make status column show search targets. +v363 12/6/01 Add --no-keypad option. + Add variable width tabstops (thanks to Peter Samuelson). +v364 12/10/01 Better handling of very long lines in input; + Fix horizontal shifting of colored text. +v365 12/11/01 Fix overstriking of tabs; + Add support for global(1) and multiple tag matches + (thanks to Shigio Yamaguchi and Tim Vanderhoek). +v366 12/11/01 Fixes for OS/2 (thanks to Kyosuke Tokoro). +v367 12/13/01 Allow -D and -x options to terminate without dollar sign; + Right/left arrow when entering N are shift cmds, not line edit. +v368 12/18/01 Update lesskey commands. +v370 12/23/01 Fix tags error messages. + Posted to Web page. +----------------------------------------------------------------- +v371 12/26/01 Fix new_file bug; use popen in Windows version; + fix some compiler warnings. +v372 12/29/01 Make -b be in units of 1K. +v373 1/14/02 Improve handling of filenames containing shell metachars. +v374 2/7/02 Fix memory leak; fix bug in -x argument parsing. +v375 4/7/02 Fix searching for SGR sequences; fix SECURE build; + add SGR support to DJGPP version (thanks to Eli Zaretskii). +v376 6/10/02 Fix bug in overstriking mulitbyte UTF-8 characters + (thanks to Jungshik Shin). + Posted to Web page. +----------------------------------------------------------------- +v377 9/10/02 Fix bug in Windows version when file contains CR; + fix bug in search highlights with -R; + make initial buffer limit really be 64K not unlimited. +v378 9/30/02 Misc bug fixes and compiler warning cleanup. + Posted to Web page. +----------------------------------------------------------------- +v379 11/23/02 Add -L option; fix bug with ctrl-K in lesskey files; + improve UTF-8 overstriking and underscore overstriking; + fix minor man page problems; change to autoconf 2.54. +v380 11/24/02 Make LINENUM same as POSITION. +v381 11/28/02 Make -N use 7 columns for line number if possible. +----------------------------------------------------------------- +v382 2/3/04 Remove copyrighted code. +----------------------------------------------------------------- +v383 2/16/04 Add history file; add -K option; improve UTF-8 handling; + fix some signed char bugs (thanks to Christian Biere); + fix some upper/lower case bugs (thanks to Bjoern Jacke); + add erase2 char (thanks to David Lawrence); + add windows charset (thanks to Dimitar Zhekov). +v384 2/20/04 Improvements in UTF-8 handling. +v385 2/23/04 Fix UTF-8 output bug. +----------------------------------------------------------------- +v386 9/13/05 Improvements to UTF-8 shift & color (thanks to Charles Levert); + protect against invalid LESSOPEN and LESSCLOSE values. +v387 9/14/05 Update Charles Levert's UTF-8 patch. +v388 9/14/05 Change history behavior; change most sprintf calls to snprintf. +v389 9/14/05 Fix copy & paste with long lines; improve performance of + expand_linebuf; fix crash in init_mlist; +v390 9/15/05 Show search matches in status column even if -G is set. +----------------------------------------------------------------- +v391 9/17/05 Fix bugs. +v392 10/14/05 Fix line wrapping bug. +v393 10/19/05 Allow multiple attributes per char; fix bold+underline bug + (thanks again to Charles Levert). +v394 11/8/05 Fix prompt bug; fix compile problem in Windows build. +----------------------------------------------------------------- +v395 1/12/07 Update Unicode tables (thanks to Charles Levert); + don't chmod if LESSHISTFILE = /dev/null; + make -f work for directories; support DESTDIR in Makefile; + fix sigset_t detection in configure; + make "t" cmd traverse tags in correct order +v396 1/13/07 Add compatibility with POSIX more. +v397 3/21/07 Allow decimal point in number for % command; + Allow decimal point in number for -j option; + Allow n command to fetch last search pattern from history + (thanks to arno). +v398 3/22/07 Don't rewrite history file if not necessary; + fix bug when filenames contain "$". +v399 3/22/07 Don't move to bottom of screen at startup; + don't output extraneous newlines. +v400 3/23/07 Allow search to find pattern after null byte (PCRE and no-regex) + (thanks to Michael Constant). +----------------------------------------------------------------- +v401 3/24/07 Minor documentation fixes. +v402 3/30/07 Fix autoconf bug when memcpy etc are inline; + fix bug in terminating number following -j option. +v403 5/25/07 Fix Windows build. +v404 6/5/07 Fix display bug with F command and long lines. +v405 6/17/07 Fix display bug when using -w option. +v406 6/17/07 Fix secure build. +v407 8/16/07 Fix bugs; support CSI chars. +v408 10/1/07 Fix bug in -i with non-ASCII chars. +v409 10/12/07 Fix crash when viewing text with invalid UTF-8 sequences. +v411 11/6/07 Fix case-insensitive searching with non-ASCII text. +v412 11/6/07 Use symbolic SEEK constants. +v413 11/6/07 Fix search highlight bug with non-ASCII text. +v414 11/6/07 Fix display bug with no-wrap terminals. +v415 11/14/07 Add --follow-name option. +v416 11/22/07 Fix crash when searching text with invalid UTF-8 sequences. +v417 12/31/07 Don't support single-char CSI in UTF-8 mode; + fix bug with -R and invalid CSI sequences; + fix bug searching text with SGR sequences with -r; + emulate SGR sequences in WIN32 build. +v418 12/31/07 Clean up. +----------------------------------------------------------------- +v419 1/16/08 Make CSI char 0x9B work in UTF-8 mode (thanks to Colin Watson). +v420 2/24/08 Add & command; fix -F option; fix '' after G. +v421 2/24/08 Ignore filtered lines when searching. +v422 3/2/08 Output CR at startup. +v423 5/27/08 Clean up. +v424 6/16/08 Fix compile bug with pcre; don't filter help file. +v425 7/14/08 Fix non-ANSI code in list handling in ch.c. +v426 10/27/08 Fix ignaw terminal handling (thanks to Per Hedeland); + fix binary file detection in UTF-8 mode. +v427 3/16/09 A few Win32 fixes (thanks to Jason Hood). +v428 3/30/09 Add "|-" syntax to LESSOPEN. +v429 4/10/09 Fix search highlighting bug with underlined text. +----------------------------------------------------------------- +v430 4/22/09 Don't pass "-" to non-pipe LESSOPEN unless it starts with "-". +v431 4/29/09 Fix highlight bug when match is at end of line. +v432 6/27/09 Better fix for highlight bugs; + fix new problems with ignaw terminals. +v433 6/28/09 Cleanup search code. +v434 6/29/09 More cleanup. +v435 7/04/09 Fix bugs with non-regex filtering. +v436 7/05/09 Fix memory leak. +----------------------------------------------------------------- +v437 7/14/09 Fix bug in handling some long option names; + make percentage calculation more accurate. +v438 12/29/10 Fix bugs with -i/-I and & filtering; + exit with status 2 on ctrl-C with -K. +v439 12/31/10 Add -A option. +v440 1/5/11 Fix bug displaying prompt after = command. +v441 1/21/11 Fix semi-infinite loop if no newlines in file; + make new -A behavior the default. +----------------------------------------------------------------- +v442 3/2/11 Fix search bug. + Add ctrl-G line edit command. +v443 4/9/11 Fix Windows build. +v444 6/8/11 Fix ungetc bug; remove vestiges of obsolete -l option. +----------------------------------------------------------------- +v445 10/19/11 Fix hilite bug in backwards scroll with -J. + Fix hilite bug with backspaces. + Fix bugs handling SGR sequences in Win32 (thanks to Eric Lee). + Add support for GNU regex (thanks to Reuben Thomas). +v446 5/15/12 Up/down arrows in cmd editing search for matching cmd. +v447 5/21/12 Add ESC-F command, two-pipe LESSOPEN syntax. +v448 6/15/12 Print name of regex library in version message. +v449 6/23/12 Allow config option --with-regex=none. +v450 7/4/12 Fix EOF bug with ESC-F. +v451 7/20/12 Fix typo. +----------------------------------------------------------------- +v452 10/19/12 Fix --with-regex=none, fix "stty 0", fix Win32. + Don't quit if errors in cmd line options. +v453 10/27/12 Increase buffer sizes. +v454 11/5/12 Fix typo. +v455 11/5/12 Fix typo. +v456 11/8/12 Fix option string incompatibility. +v457 12/8/12 Use new option string syntax only after --use-backslash. +v458 4/4/13 Fix display bug in using up/down in cmd buffer. +----------------------------------------------------------------- +v459 5/6/13 Fix ++ bug. +v460 6/19/13 Automate construction of Unicode tables. +v461 6/21/13 Collapse multiple CRs before LF. +v462 11/26/13 Don't overwrite history file, just append to it. +v463 7/13/14 Misc. fixes. +v464 7/19/14 Fix bugs & improve performance in & filtering + (thanks to John Sullivan). +v465 8/9/14 More fixes from John Sullivan. +v466 8/23/14 Add colon to LESSANSIMIDCHARS. +v467 9/18/14 Misc. fixes. +v468 9/18/14 Fix typo +v469 10/2/14 Allow extra string in command to append to a multichar + cmd without executing it; fix bug using GNU regex. +v470 10/5/14 Fix some compiler warnings. +v471 12/14/14 Fix unget issues with prompt. Allow disabling history + when compiled value of LESSHISTFILE = "-". +v473 12/19/14 Fix prompt bug with stdin and -^P in lesskey extra string. +v474 1/30/15 Fix bug in backwards search with match on bottom line. + Make follow mode reopen file if file shrinks. +v475 3/2/15 Fix possible buffer overrun with invalid UTF-8; + fix bug when compiled with no regex; fix non-match search. +v476 5/3/15 Update man pages. +v477 5/19/15 Fix off-by-one in jump_forw_buffered; + don't add FAKE_* files to cmd history. +v478 5/21/15 Fix nonportable pointer usage in hilite tree. +v479 7/6/15 Allow %% escapes in LESSOPEN variable. +v480 7/24/15 Fix bug in no-regex searches; support MSVC v1900. +v481 8/20/15 Fix broken -g option. +----------------------------------------------------------------- +v482 2/25/16 Update Unicode database to "2015-06-16, 20:24:00 GMT [KW]". +v483 2/27/16 Regenerate hilite when change search caselessness. + (Thanks to Jason Hood) + Fix bug when terminal has no "cm". (Thanks to Noel Cragg) +v484 9/20/16 Update to Unicode 9.0.0 database. +v485 10/21/16 Fix "nothing to search" bug when top/bottom line is empty; + Display line numbers in bold. (thanks to Jason Hood); + Fix incorrect display when entering double-width chars in + search string. +v486 10/22/16 New commands ESC-{ and ESC-} to shift to start/end of + displayed lines; new option -Da in Windows version to + enable SGR mode (thanks to Jason Hood). +v487 10/23/16 configure --help formatting. +----------------------------------------------------------------- +v488 2/23/17 Fix memory leaks in search (thanks to John Brooks). +v489 3/30/17 Make -F not do init/deinit if file fits on one screen + (thanks to Jindrich Novy). +v490 4/5/17 Switch to ANSI prototypes in funcs.h; remove "register". +v491 4/7/17 Fix signed char bug. +v492 4/21/17 Handle SIGTERM. +v493 6/22/17 Fix bug initializing charset in MSDOS build. +v494 6/26/17 Update Unicode tables; make Cf chars composing not binary. +v495 7/3/17 Improve binary file detection (thanks to Bela Lubkin); + do -R filter when matching tags (thanks to Matthew Malcomson). +v496 7/5/17 Add LESSRSCROLL marker. +v497 7/5/17 Sync. +v498 7/7/17 Fix early truncation of text if last char is double-width. +v499 7/10/17 Misc fixes. +v500 7/11/17 Fix bug where certain env variables couldn't be set in lesskey. +v501 7/12/17 Make sure rscroll char is standout by default. +v502 7/13/17 Control rscroll char via command line option not env variable. +v503 7/13/17 Switch to git. +v504 7/13/17 Call opt_rscroll at startup; change mkhelp.c to mkhelp.pl. +v505 7/17/17 Add M and ESC-M commands; + fix buffer handling with stdin and LESSOPEN. +v506 7/17/17 On Windows, convert UTF-8 to multibyte if console is not UTF-8; + handle extended chars on input (thanks to Jason Hood). +v507 7/18/17 Fix some bugs handling filenames containing shell metachars. +v508 7/19/17 Fix bugs when using LESSOPEN to read stdin. +v509 7/19/17 Fix another stdin bug. +v510 7/20/17 Fix bug in determining when to reopen a file. +v511 7/25/17 Fix bugs in recent MSDOS changes (thanks to Jason Hood). +v512 7/26/17 Fix MSDOS build. +v513 7/26/17 Fix switch to normal attr at end of line with -R and rscroll. +v514 7/27/17 Fix bug in fcomplete when pattern does not match a file. +v515 7/28/17 Allow 'u' in -D option on Windows. +v516 7/29/17 Fix bug using LESSOPEN with filename containing metachars. +v517 7/30/17 Status column shows matches even if hiliting is disabled via -G. +v518 8/1/17 Use underline in sgr mode in MSDOS (thanks to Jason Hood). +v519 8/10/17 Fix rscroll bug when last char of line starts coloration. +v520 9/3/17 Fix compiler warning. +v521 10/20/17 Fix binary file warning in UTF-8 files with SGI sequences. +v522 10/20/17 Handle keypad ENTER key properly. +v523 10/23/17 Cleanup. +v524 10/24/17 Fix getcc bug. +v525 10/24/17 Change M command to mark last displayed line. +v526 10/25/17 Fix search hilite bug introduced in v517. +v527 10/30/17 Fix search hilite bug on last page with -a. +v528 11/3/17 Make second ESC-u clear status column. +v529 11/12/17 Display Unicode formatting chars in hex if -U is set. +v530 12/2/17 Minor doc change and add missing VOID_PARAM. +----------------------------------------------------------------- +v531 5/13/18 Fix bug with v on empty file; fix bug with v on file with + metachars in name; add --nohistdups option. +v532 7/27/18 Redraw screen on SIGWINCH even if screen size doesn't change. +v533 8/1/18 Shell escape filenames in history; use PCRE_UTF8 flag; + use wide-chars for Windows console title (thanks to Jason Hood). +v534 8/9/18 Support PCRE2. +v535 8/16/18 Don't count lines of initial screen if using -X with -F + (thanks to Linus Torvalds). +v536 8/31/18 Use descriptive error messages for PCRE2. +v537 8/31/18 Support mingw build system (thanks to Mike Soyka). +v538 9/3/18 Clean up some WIN32 code. +v539 9/13/18 Fix spurious input on Windows with CAPSLOCK. +v540 10/29/18 Add --mouse option. +v541 10/30/18 Add --MOUSE option. +v542 11/6/18 Add mouse support for WIN32; add --wheel-lines option. + (thanks to Jason Hood). +v543 11/12/18 Code cleanup. +v544 11/16/18 Don't init/deinit keyboard/mouse if quit due to -F. +v545 11/22/18 Fix Windows build, memory leaks. +v546 11/29/18 Add --save-marks option. +v547 11/30/18 Fix some bugs with saved marks. +v548 12/14/18 Ignore mouse input when line editing. +v549 2/10/19 Support X11 mouse extension 1006; + Win32 fixes (thanks to Jason Hood). +v550 2/16/19 Fix Win32 build; don't enable mouse unless --mouse is set. +v551 6/10/19 Doc changes. +----------------------------------------------------------------- +v552 7/8/19 Update Unicode tables. +v553 10/17/19 Support tinfow; handle zero-width Hangul chars. +v554 1/19/20 Remove erroneous free(). +v555 3/15/20 Display error msg immediately when toggle -o without stdin. +v556 3/15/20 Update copyright. +v557 3/21/20 Fix memory corruption with libtermcap. +v558 4/17/20 Don't init terminal if -F and file fits on one screen (WIN32). +v559 4/19/20 Handle deinit correctly on WIN32. +v560 5/3/20 Fix regression when command results in no movement; + fix some less.nro issues (thanks to Bjarni I. Gislason). +v561 5/11/20 Fix erroneous EOF calculation when F command is interrupted. +v562 5/19/20 Update Unicode tables; minor doc formatting. +v563 6/13/20 Fix crash due to realpath() incompatibility. +v564 8/25/20 Handle realpath consistently; update docs. +v565 11/3/20 Add ESC-U command, optimize calls to realpath(). +v566 11/25/20 Fix crash when reopening a file while using LESSOPEN; + support OSC 8 hyperlinks. +v567 11/25/20 Fix typo. +v568 11/29/20 Fix some hyperlink bugs; add ^W search modifier + (thanks to Arminius); allow Makefile.aut to use Python + instead of Perl (thanks to Charlie Lin). +v569 12/1/20 Allow multiple & filters (thanks to Mattias Johansson), + allow ^X to exit F command. +v570 12/12/20 Better handling of multiple + or -p options; + fix bugs in horizontal scrolling. +v571 12/30/20 Add --line-num-width and --status-col-width options. +v572 1/4/21 Save lastmark in history file; don't toggle mouse reporting; + implement termcap delays. +v573 1/9/21 Limit eof bell to 1 per second. +v574 1/13/21 Add incremental search. +v575 1/17/21 Fix build without HILITE_SEARCH; + fix bug with ^K in lesskey extra string. +v576 2/4/21 Make sure search result is visible; add --use-color and --color. +v577 2/9/21 Use ttyname to get name of tty device. +v578 2/9/21 Doc +v579 2/14/21 Fix double-width char bugs and non-match search crash. +v580 3/2/21 Some color fixes; fix compiler warnings; some lesstest support. +v581 4/6/21 Ignore SIGTSTP in secure mode; don't print "skipping" when filtering. +v582 4/21/21 Less now reads lesskey source file rather than binary; + fix bug in finding tags with backslashes. +v583 4/21/21 Use XDG_CONFIG_HOME and XDG_DATA_HOME to find files. +v584 4/30/21 Add --file-size option. +v585 5/2/21 Allow color desc W per man page. +v586 5/7/21 Doc changes. +v587 5/27/21 Fix --with-secure; fix --file-size message on Windows; + fix colored search hilite in colored text; don't exit + if -F and screen is resized; fix memcpy usage. +v588 5/27/21 Fix release. +v589 5/29/21 Copyright & build changes. +v590 6/3/21 Fix non-autoconf Makefiles. +v591 8/8/21 Use \kB for backspace key in lesskey; add more \k codes; + handle multibyte chars in prompt. +v592 8/24/21 Add --status-line option; limit use of /proc kludge; add --header. +v593 8/30/21 Add header columns, --no-number-headers. +v594 10/1/21 Let regex library handle caseless; add --redraw-on-quit option; + add #version to lesskey. +v595 10/12/21 Add H color type; add += to lesskey var section; + add --search-options. +v596 11/8/21 Look for lesskey in $HOME/.config. +v597 11/16/21 Fix bugs in --header. +v598 12/6/21 Look for lesshst in $XDG_STATE_HOME and $HOME/.local/state. +v599 12/28/21 Defer moving to lower left in some cases; + suppress TAB expansion in some cases. +v600 1/7/22 Use /dev/tty if cannot open ttyname(). +v601 1/31/22 Add --exit-follow-on-close option. +v602 3/1/22 Doc changes. +v603 3/14/22 Fix --header. +v604 5/14/22 Fix termlib detection; fix non-ASCII input on Windows. +v605 6/14/22 Update version number. +v606 7/17/22 Fix bug with multibyte chars and --incsearch; + escape filenames in LESSCLOSE; fix bin_file overrun. +v607 7/19/22 Update Unicode tables. +v608 7/22/22 Fix highlighting on colored text boundaries. +v609 11/10/22 Add LESSUTFCHARDEF; fix overstrike color bug; + fix procfs bug; fix signal race. +v610 11/14/22 Update Unicode tables; fix again-search after filter; + improve ^X to interrupt F command. +v611 11/16/22 Fix EOF bug related to ^X change. +v612 11/18/22 Fix more bugs related to ^X change. +v613 11/28/22 Even more ^X issues. +v614 11/28/22 Add ^X to wait message. +v615 11/30/22 Add --no-vbell option. +v616 12/9/22 Don't open tty as input file without -f. +v617 12/10/22 Support poll on newer versions of MacOS. +v618 12/29/22 Add --no-search-headers option; use C89 function definitions. +v619 12/30/22 Fix bug using 'n' before '/'. +v620 1/12/23 Add --modelines option; add --intr option; + add subpattern coloring. +v621 1/15/23 Add --wordwrap option; add LESS_LINES & LESS_COLUMNS. +v622 1/27/23 Add --show-preproc-errors option. +v623 2/2/23 Add # command; add ^S search modifier. +v624 2/11/23 Add --proc-backspace, --proc-tab and --proc-return options. +v625 2/16/23 Minor fixes. +v626 2/19/23 Fix rare crash in add_attr_normal. +v627 2/19/23 Doc. +v628 2/20/23 Don't require newline after +&... +v629 2/26/23 Delay "waiting for data" message for 500 ms. +v630 3/18/23 Add LESS_DATA_DELAY. +v631 3/26/23 Fix input of dead keys on Windows. +v632 4/6/23 Make lesstest work on MacOS; minor fixes. +v633 5/3/23 Fix build on systems with ncurses/termcap.h or ncursesw/termcap.h. +v634 5/29/23 Allow program piping into less to access tty; + fix search modifier ^E after ^W. +v635 6/2/23 Fix crash with ! search modifier. +v636 6/18/23 Fix -D in MS-DOS build; fix mouse wheel in MS-DOS build. +v637 6/28/23 Fix early EOF when SIGWINCH is received. +v638 6/29/23 Fix compile error with ECHONL. +v639 6/29/23 Fix SIGWINCH while reading tty. +v640 7/10/23 Add lesstest to release. +v641 7/10/23 Fix release. +v642 7/10/23 Fix release. +v643 7/20/23 Fix crash on Windows with -o. +*/ + +char version[] = "643"; diff --git a/third_party/less/wide.inc b/third_party/less/wide.inc new file mode 100644 index 000000000..51a762999 --- /dev/null +++ b/third_party/less/wide.inc @@ -0,0 +1,123 @@ +/* Generated by "./mkutable -f1 W F -- unicode/EastAsianWidth.txt" on Mon Nov 14 18:19:24 PST 2022 */ + { 0x1100, 0x115f }, /* W */ + { 0x231a, 0x231b }, /* W */ + { 0x2329, 0x232a }, /* W */ + { 0x23e9, 0x23ec }, /* W */ + { 0x23f0, 0x23f0 }, /* W */ + { 0x23f3, 0x23f3 }, /* W */ + { 0x25fd, 0x25fe }, /* W */ + { 0x2614, 0x2615 }, /* W */ + { 0x2648, 0x2653 }, /* W */ + { 0x267f, 0x267f }, /* W */ + { 0x2693, 0x2693 }, /* W */ + { 0x26a1, 0x26a1 }, /* W */ + { 0x26aa, 0x26ab }, /* W */ + { 0x26bd, 0x26be }, /* W */ + { 0x26c4, 0x26c5 }, /* W */ + { 0x26ce, 0x26ce }, /* W */ + { 0x26d4, 0x26d4 }, /* W */ + { 0x26ea, 0x26ea }, /* W */ + { 0x26f2, 0x26f3 }, /* W */ + { 0x26f5, 0x26f5 }, /* W */ + { 0x26fa, 0x26fa }, /* W */ + { 0x26fd, 0x26fd }, /* W */ + { 0x2705, 0x2705 }, /* W */ + { 0x270a, 0x270b }, /* W */ + { 0x2728, 0x2728 }, /* W */ + { 0x274c, 0x274c }, /* W */ + { 0x274e, 0x274e }, /* W */ + { 0x2753, 0x2755 }, /* W */ + { 0x2757, 0x2757 }, /* W */ + { 0x2795, 0x2797 }, /* W */ + { 0x27b0, 0x27b0 }, /* W */ + { 0x27bf, 0x27bf }, /* W */ + { 0x2b1b, 0x2b1c }, /* W */ + { 0x2b50, 0x2b50 }, /* W */ + { 0x2b55, 0x2b55 }, /* W */ + { 0x2e80, 0x2e99 }, /* W */ + { 0x2e9b, 0x2ef3 }, /* W */ + { 0x2f00, 0x2fd5 }, /* W */ + { 0x2ff0, 0x2ffb }, /* W */ + { 0x3000, 0x3000 }, /* F */ + { 0x3001, 0x303e }, /* W */ + { 0x3041, 0x3096 }, /* W */ + { 0x3099, 0x30ff }, /* W */ + { 0x3105, 0x312f }, /* W */ + { 0x3131, 0x318e }, /* W */ + { 0x3190, 0x31e3 }, /* W */ + { 0x31f0, 0x321e }, /* W */ + { 0x3220, 0x3247 }, /* W */ + { 0x3250, 0x4dbf }, /* W */ + { 0x4e00, 0xa48c }, /* W */ + { 0xa490, 0xa4c6 }, /* W */ + { 0xa960, 0xa97c }, /* W */ + { 0xac00, 0xd7a3 }, /* W */ + { 0xf900, 0xfaff }, /* W */ + { 0xfe10, 0xfe19 }, /* W */ + { 0xfe30, 0xfe52 }, /* W */ + { 0xfe54, 0xfe66 }, /* W */ + { 0xfe68, 0xfe6b }, /* W */ + { 0xff01, 0xff60 }, /* F */ + { 0xffe0, 0xffe6 }, /* F */ + { 0x16fe0, 0x16fe4 }, /* W */ + { 0x16ff0, 0x16ff1 }, /* W */ + { 0x17000, 0x187f7 }, /* W */ + { 0x18800, 0x18cd5 }, /* W */ + { 0x18d00, 0x18d08 }, /* W */ + { 0x1aff0, 0x1aff3 }, /* W */ + { 0x1aff5, 0x1affb }, /* W */ + { 0x1affd, 0x1affe }, /* W */ + { 0x1b000, 0x1b122 }, /* W */ + { 0x1b132, 0x1b132 }, /* W */ + { 0x1b150, 0x1b152 }, /* W */ + { 0x1b155, 0x1b155 }, /* W */ + { 0x1b164, 0x1b167 }, /* W */ + { 0x1b170, 0x1b2fb }, /* W */ + { 0x1f004, 0x1f004 }, /* W */ + { 0x1f0cf, 0x1f0cf }, /* W */ + { 0x1f18e, 0x1f18e }, /* W */ + { 0x1f191, 0x1f19a }, /* W */ + { 0x1f200, 0x1f202 }, /* W */ + { 0x1f210, 0x1f23b }, /* W */ + { 0x1f240, 0x1f248 }, /* W */ + { 0x1f250, 0x1f251 }, /* W */ + { 0x1f260, 0x1f265 }, /* W */ + { 0x1f300, 0x1f320 }, /* W */ + { 0x1f32d, 0x1f335 }, /* W */ + { 0x1f337, 0x1f37c }, /* W */ + { 0x1f37e, 0x1f393 }, /* W */ + { 0x1f3a0, 0x1f3ca }, /* W */ + { 0x1f3cf, 0x1f3d3 }, /* W */ + { 0x1f3e0, 0x1f3f0 }, /* W */ + { 0x1f3f4, 0x1f3f4 }, /* W */ + { 0x1f3f8, 0x1f43e }, /* W */ + { 0x1f440, 0x1f440 }, /* W */ + { 0x1f442, 0x1f4fc }, /* W */ + { 0x1f4ff, 0x1f53d }, /* W */ + { 0x1f54b, 0x1f54e }, /* W */ + { 0x1f550, 0x1f567 }, /* W */ + { 0x1f57a, 0x1f57a }, /* W */ + { 0x1f595, 0x1f596 }, /* W */ + { 0x1f5a4, 0x1f5a4 }, /* W */ + { 0x1f5fb, 0x1f64f }, /* W */ + { 0x1f680, 0x1f6c5 }, /* W */ + { 0x1f6cc, 0x1f6cc }, /* W */ + { 0x1f6d0, 0x1f6d2 }, /* W */ + { 0x1f6d5, 0x1f6d7 }, /* W */ + { 0x1f6dc, 0x1f6df }, /* W */ + { 0x1f6eb, 0x1f6ec }, /* W */ + { 0x1f6f4, 0x1f6fc }, /* W */ + { 0x1f7e0, 0x1f7eb }, /* W */ + { 0x1f7f0, 0x1f7f0 }, /* W */ + { 0x1f90c, 0x1f93a }, /* W */ + { 0x1f93c, 0x1f945 }, /* W */ + { 0x1f947, 0x1f9ff }, /* W */ + { 0x1fa70, 0x1fa7c }, /* W */ + { 0x1fa80, 0x1fa88 }, /* W */ + { 0x1fa90, 0x1fabd }, /* W */ + { 0x1fabf, 0x1fac5 }, /* W */ + { 0x1face, 0x1fadb }, /* W */ + { 0x1fae0, 0x1fae8 }, /* W */ + { 0x1faf0, 0x1faf8 }, /* W */ + { 0x20000, 0x2fffd }, /* W */ + { 0x30000, 0x3fffd }, /* W */ diff --git a/third_party/less/xbuf.c b/third_party/less/xbuf.c new file mode 100644 index 000000000..92076764d --- /dev/null +++ b/third_party/less/xbuf.c @@ -0,0 +1,163 @@ +#include "less.h" +#include "xbuf.h" + +/* + * Initialize an expandable text buffer. + */ +public void xbuf_init(struct xbuffer *xbuf) +{ + xbuf->data = NULL; + xbuf->size = xbuf->end = 0; +} + +public void xbuf_deinit(struct xbuffer *xbuf) +{ + if (xbuf->data != NULL) + free(xbuf->data); + xbuf_init(xbuf); +} + +public void xbuf_reset(struct xbuffer *xbuf) +{ + xbuf->end = 0; +} + +/* + * Add a byte to an expandable text buffer. + */ +public void xbuf_add_byte(struct xbuffer *xbuf, unsigned char b) +{ + if (xbuf->end >= xbuf->size) + { + unsigned char *data; + if (ckd_add(&xbuf->size, xbuf->size, xbuf->size ? xbuf->size : 16)) + out_of_memory(); + data = (unsigned char *) ecalloc(xbuf->size, sizeof(unsigned char)); + if (xbuf->data != NULL) + { + memcpy(data, xbuf->data, xbuf->end); + free(xbuf->data); + } + xbuf->data = data; + } + xbuf->data[xbuf->end++] = (unsigned char) b; +} + +public void xbuf_add_data(struct xbuffer *xbuf, unsigned char *data, int len) +{ + int i; + for (i = 0; i < len; i++) + xbuf_add_byte(xbuf, data[i]); +} + +public int xbuf_pop(struct xbuffer *buf) +{ + if (buf->end == 0) + return -1; + return (int) buf->data[--(buf->end)]; +} + +public void xbuf_set(struct xbuffer *dst, struct xbuffer *src) +{ + xbuf_reset(dst); + xbuf_add_data(dst, src->data, src->end); +} + +public char * xbuf_char_data(struct xbuffer *xbuf) +{ + return (char *)(xbuf->data); +} + + +/* + * Helper functions for the ckd_add and ckd_mul macro substitutes. + * These helper functions do not set *R on overflow, and assume that + * arguments are nonnegative, that INTMAX_MAX <= UINTMAX_MAX, and that + * sizeof is a reliable way to distinguish integer representations. + * Despite these limitations they are good enough for 'less' on all + * known practical platforms. For more-complicated substitutes + * without most of these limitations, see Gnulib's stdckdint module. + */ +#if !HAVE_STDCKDINT_H +/* + * If the integer *R can represent VAL, store the value and return FALSE. + * Otherwise, possibly set *R to an indeterminate value and return TRUE. + * R has size RSIZE, and is signed if and only if RSIGNED is nonzero. + */ +static int help_fixup(void *r, uintmax val, int rsize, int rsigned) +{ + if (rsigned) + { + if (rsize == sizeof (int)) + { + int *pr = r; + if (INT_MAX < val) + return TRUE; + *pr = (int) val; +#ifdef LLONG_MAX + } else if (rsize == sizeof (long long)) + { + long long *pr = r; + if (LLONG_MAX < val) + return TRUE; + *pr = val; +#endif +#ifdef INTMAX_MAX + } else if (rsize == sizeof (intmax_t)) { + intmax_t *pr = r; + if (INTMAX_MAX < val) + return TRUE; + *pr = val; +#endif + } else /* rsize == sizeof (long) */ + { + long *pr = r; + if (LONG_MAX < val) + return TRUE; + *pr = (long) val; + } + } else { + if (rsize == sizeof (unsigned)) { + unsigned *pr = r; + if (UINT_MAX < val) + return TRUE; + *pr = (unsigned) val; + } else if (rsize == sizeof (unsigned long)) { + unsigned long *pr = r; + if (ULONG_MAX < val) + return TRUE; + *pr = (unsigned long) val; +#ifdef ULLONG_MAX + } else if (rsize == sizeof (unsigned long long)) { + long long *pr = r; + if (ULLONG_MAX < val) + return TRUE; + *pr = val; +#endif + } else /* rsize == sizeof (uintmax) */ + { + uintmax *pr = r; + *pr = val; + } + } + return FALSE; +} +/* + * If *R can represent the mathematical sum of A and B, store the sum + * and return FALSE. Otherwise, possibly set *R to an indeterminate + * value and return TRUE. R has size RSIZE, and is signed if and only + * if RSIGNED is nonzero. + */ +public int help_ckd_add(void *r, uintmax a, uintmax b, int rsize, int rsigned) +{ + uintmax sum = a + b; + return sum < a || help_fixup(r, sum, rsize, rsigned); +} +/* Likewise, but for the product of A and B. */ +public int help_ckd_mul(void *r, uintmax a, uintmax b, int rsize, int rsigned) +{ + uintmax product = a * b; + return ((b != 0 && a != product / b) + || help_fixup(r, product, rsize, rsigned)); +} +#endif diff --git a/third_party/less/xbuf.h b/third_party/less/xbuf.h new file mode 100644 index 000000000..acd5485ca --- /dev/null +++ b/third_party/less/xbuf.h @@ -0,0 +1,19 @@ +#ifndef XBUF_H_ +#define XBUF_H_ + +struct xbuffer +{ + unsigned char *data; + int end; + int size; +}; + +void xbuf_init(struct xbuffer *xbuf); +void xbuf_deinit(struct xbuffer *xbuf); +void xbuf_reset(struct xbuffer *xbuf); +void xbuf_add_byte(struct xbuffer *xbuf, unsigned char b); +void xbuf_add_data(struct xbuffer *xbuf, unsigned char *data, int len); +int xbuf_pop(struct xbuffer *xbuf); +char *xbuf_char_data(struct xbuffer *xbuf); + +#endif diff --git a/third_party/ncurses/read_entry.c b/third_party/ncurses/read_entry.c index b0934fae9..f06f6ce0a 100644 --- a/third_party/ncurses/read_entry.c +++ b/third_party/ncurses/read_entry.c @@ -1,3 +1,2856 @@ +__static_yoink("usr/share/terminfo/5/5630DMD-24"); +__static_yoink("usr/share/terminfo/5/5620"); +__static_yoink("usr/share/terminfo/5/5051"); +__static_yoink("usr/share/terminfo/5/5410-w"); +__static_yoink("usr/share/terminfo/5/5630-24"); +__static_yoink("usr/share/terminfo/k/konsole-solaris"); +__static_yoink("usr/share/terminfo/k/klone+acs"); +__static_yoink("usr/share/terminfo/k/konsole"); +__static_yoink("usr/share/terminfo/k/kitty"); +__static_yoink("usr/share/terminfo/k/kterm-co"); +__static_yoink("usr/share/terminfo/k/klone+sgr8"); +__static_yoink("usr/share/terminfo/k/kterm"); +__static_yoink("usr/share/terminfo/k/konsole-xf4x"); +__static_yoink("usr/share/terminfo/k/kds7372"); +__static_yoink("usr/share/terminfo/k/kermit"); +__static_yoink("usr/share/terminfo/k/kon"); +__static_yoink("usr/share/terminfo/k/konsole-vt420pc"); +__static_yoink("usr/share/terminfo/k/klone+sgr-dumb"); +__static_yoink("usr/share/terminfo/k/kitty-direct"); +__static_yoink("usr/share/terminfo/k/kermit-am"); +__static_yoink("usr/share/terminfo/k/kon2"); +__static_yoink("usr/share/terminfo/k/konsole-linux"); +__static_yoink("usr/share/terminfo/k/kds6402"); +__static_yoink("usr/share/terminfo/k/ktm"); +__static_yoink("usr/share/terminfo/k/kt7ix"); +__static_yoink("usr/share/terminfo/k/kds7372-w"); +__static_yoink("usr/share/terminfo/k/kaypro2"); +__static_yoink("usr/share/terminfo/k/konsole-xf3x"); +__static_yoink("usr/share/terminfo/k/konsole-16color"); +__static_yoink("usr/share/terminfo/k/konsole-256color"); +__static_yoink("usr/share/terminfo/k/k45"); +__static_yoink("usr/share/terminfo/k/konsole-vt100"); +__static_yoink("usr/share/terminfo/k/konsole+pcfkeys"); +__static_yoink("usr/share/terminfo/k/kaypro"); +__static_yoink("usr/share/terminfo/k/konsole-base"); +__static_yoink("usr/share/terminfo/k/konsole-direct"); +__static_yoink("usr/share/terminfo/k/klone+color"); +__static_yoink("usr/share/terminfo/k/kitty+common"); +__static_yoink("usr/share/terminfo/k/klone+sgr"); +__static_yoink("usr/share/terminfo/k/klone+koi8acs"); +__static_yoink("usr/share/terminfo/k/kt7"); +__static_yoink("usr/share/terminfo/k/kitty+setal"); +__static_yoink("usr/share/terminfo/k/kterm-color"); +__static_yoink("usr/share/terminfo/k/kvt"); +__static_yoink("usr/share/terminfo/2/2621"); +__static_yoink("usr/share/terminfo/2/2621a"); +__static_yoink("usr/share/terminfo/2/2621A"); +__static_yoink("usr/share/terminfo/2/2621-wl"); +__static_yoink("usr/share/terminfo/q/qnxt"); +__static_yoink("usr/share/terminfo/q/qvt119+"); +__static_yoink("usr/share/terminfo/q/qume5"); +__static_yoink("usr/share/terminfo/q/qnx4"); +__static_yoink("usr/share/terminfo/q/qdss"); +__static_yoink("usr/share/terminfo/q/qansi-w"); +__static_yoink("usr/share/terminfo/q/qnx"); +__static_yoink("usr/share/terminfo/q/qvt119p"); +__static_yoink("usr/share/terminfo/q/qvt203"); +__static_yoink("usr/share/terminfo/q/qvt101p"); +__static_yoink("usr/share/terminfo/q/qvt119p-25-w"); +__static_yoink("usr/share/terminfo/q/qnxtmono"); +__static_yoink("usr/share/terminfo/q/qvt203-25"); +__static_yoink("usr/share/terminfo/q/qvt103"); +__static_yoink("usr/share/terminfo/q/qnxt2"); +__static_yoink("usr/share/terminfo/q/qvt119p-w"); +__static_yoink("usr/share/terminfo/q/qnxt4"); +__static_yoink("usr/share/terminfo/q/qvt103-w"); +__static_yoink("usr/share/terminfo/q/qansi"); +__static_yoink("usr/share/terminfo/q/qvt203-w"); +__static_yoink("usr/share/terminfo/q/qvt203-w-am"); +__static_yoink("usr/share/terminfo/q/qnxm"); +__static_yoink("usr/share/terminfo/q/qvt119+-25-w"); +__static_yoink("usr/share/terminfo/q/qvt102"); +__static_yoink("usr/share/terminfo/q/qansi-m"); +__static_yoink("usr/share/terminfo/q/qvt119"); +__static_yoink("usr/share/terminfo/q/qnxw"); +__static_yoink("usr/share/terminfo/q/qvt119-w"); +__static_yoink("usr/share/terminfo/q/qvt101+"); +__static_yoink("usr/share/terminfo/q/qdcons"); +__static_yoink("usr/share/terminfo/q/qvt119+-25"); +__static_yoink("usr/share/terminfo/q/qvt203+"); +__static_yoink("usr/share/terminfo/q/qvt203-25-w"); +__static_yoink("usr/share/terminfo/q/qvt108"); +__static_yoink("usr/share/terminfo/q/qvt119p-25"); +__static_yoink("usr/share/terminfo/q/qume"); +__static_yoink("usr/share/terminfo/q/qvt119+-w"); +__static_yoink("usr/share/terminfo/q/qvt119-25-w"); +__static_yoink("usr/share/terminfo/q/qansi-t"); +__static_yoink("usr/share/terminfo/q/qansi-g"); +__static_yoink("usr/share/terminfo/q/qvt101"); +__static_yoink("usr/share/terminfo/m/mlterm"); +__static_yoink("usr/share/terminfo/m/mai"); +__static_yoink("usr/share/terminfo/m/msk227am"); +__static_yoink("usr/share/terminfo/m/minix-1.5"); +__static_yoink("usr/share/terminfo/m/ms-vt100"); +__static_yoink("usr/share/terminfo/m/minitel1"); +__static_yoink("usr/share/terminfo/m/mintty"); +__static_yoink("usr/share/terminfo/m/mgr-sun"); +__static_yoink("usr/share/terminfo/m/mime-hb"); +__static_yoink("usr/share/terminfo/m/msk227"); +__static_yoink("usr/share/terminfo/m/minitel1b-nb"); +__static_yoink("usr/share/terminfo/m/mach"); +__static_yoink("usr/share/terminfo/m/microterm"); +__static_yoink("usr/share/terminfo/m/mod"); +__static_yoink("usr/share/terminfo/m/mvterm"); +__static_yoink("usr/share/terminfo/m/minitel1b-80"); +__static_yoink("usr/share/terminfo/m/ms-vt100-color"); +__static_yoink("usr/share/terminfo/m/ms-vt100+"); +__static_yoink("usr/share/terminfo/m/mterm-ansi"); +__static_yoink("usr/share/terminfo/m/mime"); +__static_yoink("usr/share/terminfo/m/microterm5"); +__static_yoink("usr/share/terminfo/m/masscomp1"); +__static_yoink("usr/share/terminfo/m/m2-nam"); +__static_yoink("usr/share/terminfo/m/macintosh"); +__static_yoink("usr/share/terminfo/m/mime3ax"); +__static_yoink("usr/share/terminfo/m/msk22714"); +__static_yoink("usr/share/terminfo/m/minix-old-am"); +__static_yoink("usr/share/terminfo/m/mskermit227am"); +__static_yoink("usr/share/terminfo/m/mime-3ax"); +__static_yoink("usr/share/terminfo/m/mgterm"); +__static_yoink("usr/share/terminfo/m/mintty+common"); +__static_yoink("usr/share/terminfo/m/minitel1b"); +__static_yoink("usr/share/terminfo/m/mlterm+pcfkeys"); +__static_yoink("usr/share/terminfo/m/mimei"); +__static_yoink("usr/share/terminfo/m/minitel1-nb"); +__static_yoink("usr/share/terminfo/m/minix"); +__static_yoink("usr/share/terminfo/m/mime2a-v"); +__static_yoink("usr/share/terminfo/m/mime2a"); +__static_yoink("usr/share/terminfo/m/mac"); +__static_yoink("usr/share/terminfo/m/mod24"); +__static_yoink("usr/share/terminfo/m/mintty-direct"); +__static_yoink("usr/share/terminfo/m/mach-color"); +__static_yoink("usr/share/terminfo/m/minix-3.0"); +__static_yoink("usr/share/terminfo/m/minitel-2-nam"); +__static_yoink("usr/share/terminfo/m/mlterm-256color"); +__static_yoink("usr/share/terminfo/m/mouse-sun"); +__static_yoink("usr/share/terminfo/m/mskermit22714"); +__static_yoink("usr/share/terminfo/m/mlterm3"); +__static_yoink("usr/share/terminfo/m/minix-1.7"); +__static_yoink("usr/share/terminfo/m/mm314"); +__static_yoink("usr/share/terminfo/m/mach-gnu-color"); +__static_yoink("usr/share/terminfo/m/mime1"); +__static_yoink("usr/share/terminfo/m/mm340"); +__static_yoink("usr/share/terminfo/m/mosh-256color"); +__static_yoink("usr/share/terminfo/m/ms-terminal"); +__static_yoink("usr/share/terminfo/m/mt4520-rv"); +__static_yoink("usr/share/terminfo/m/mime2a-s"); +__static_yoink("usr/share/terminfo/m/mosh"); +__static_yoink("usr/share/terminfo/m/mt-70"); +__static_yoink("usr/share/terminfo/m/mrxvt-256color"); +__static_yoink("usr/share/terminfo/m/mimeii"); +__static_yoink("usr/share/terminfo/m/mime-fb"); +__static_yoink("usr/share/terminfo/m/modgraph48"); +__static_yoink("usr/share/terminfo/m/mono-emx"); +__static_yoink("usr/share/terminfo/m/minitel2-80"); +__static_yoink("usr/share/terminfo/m/mlterm2"); +__static_yoink("usr/share/terminfo/m/megatek"); +__static_yoink("usr/share/terminfo/m/masscomp2"); +__static_yoink("usr/share/terminfo/m/mgt"); +__static_yoink("usr/share/terminfo/m/minix-old"); +__static_yoink("usr/share/terminfo/m/microb"); +__static_yoink("usr/share/terminfo/m/mdl110"); +__static_yoink("usr/share/terminfo/m/mime2"); +__static_yoink("usr/share/terminfo/m/macterminal-w"); +__static_yoink("usr/share/terminfo/m/masscomp"); +__static_yoink("usr/share/terminfo/m/modgraph2"); +__static_yoink("usr/share/terminfo/m/memhp"); +__static_yoink("usr/share/terminfo/m/mskermit227"); +__static_yoink("usr/share/terminfo/m/mgr"); +__static_yoink("usr/share/terminfo/m/minitel"); +__static_yoink("usr/share/terminfo/m/mach-gnu"); +__static_yoink("usr/share/terminfo/m/mime3a"); +__static_yoink("usr/share/terminfo/m/mime340"); +__static_yoink("usr/share/terminfo/m/mterm"); +__static_yoink("usr/share/terminfo/m/modgraph"); +__static_yoink("usr/share/terminfo/m/mlterm-direct"); +__static_yoink("usr/share/terminfo/m/mt70"); +__static_yoink("usr/share/terminfo/m/minitel12-80"); +__static_yoink("usr/share/terminfo/m/ms-vt-utf8"); +__static_yoink("usr/share/terminfo/m/mach-bold"); +__static_yoink("usr/share/terminfo/m/mac-w"); +__static_yoink("usr/share/terminfo/m/morphos"); +__static_yoink("usr/share/terminfo/m/microbee"); +__static_yoink("usr/share/terminfo/m/mrxvt"); +__static_yoink("usr/share/terminfo/m/mime314"); +__static_yoink("usr/share/terminfo/m/minitel-2"); +__static_yoink("usr/share/terminfo/m/mgr-linux"); +__static_yoink("usr/share/terminfo/9/955-w"); +__static_yoink("usr/share/terminfo/9/955-hb"); +__static_yoink("usr/share/terminfo/9/9term"); +__static_yoink("usr/share/terminfo/l/linux+decid"); +__static_yoink("usr/share/terminfo/l/linux-nic"); +__static_yoink("usr/share/terminfo/l/linux-m"); +__static_yoink("usr/share/terminfo/l/luna68k"); +__static_yoink("usr/share/terminfo/l/linux2.6"); +__static_yoink("usr/share/terminfo/l/la120"); +__static_yoink("usr/share/terminfo/l/linux-koi8r"); +__static_yoink("usr/share/terminfo/l/linux-c"); +__static_yoink("usr/share/terminfo/l/lpr"); +__static_yoink("usr/share/terminfo/l/linux-c-nc"); +__static_yoink("usr/share/terminfo/l/lisaterm"); +__static_yoink("usr/share/terminfo/l/linux-basic"); +__static_yoink("usr/share/terminfo/l/lisa"); +__static_yoink("usr/share/terminfo/l/lft"); +__static_yoink("usr/share/terminfo/l/liswb"); +__static_yoink("usr/share/terminfo/l/linux+sfkeys"); +__static_yoink("usr/share/terminfo/l/linux3.0"); +__static_yoink("usr/share/terminfo/l/ln03"); +__static_yoink("usr/share/terminfo/l/linux"); +__static_yoink("usr/share/terminfo/l/linux2.6.26"); +__static_yoink("usr/share/terminfo/l/lft-pc850"); +__static_yoink("usr/share/terminfo/l/linux-m1"); +__static_yoink("usr/share/terminfo/l/linux-lat"); +__static_yoink("usr/share/terminfo/l/luna"); +__static_yoink("usr/share/terminfo/l/linux-m1b"); +__static_yoink("usr/share/terminfo/l/lisaterm-w"); +__static_yoink("usr/share/terminfo/l/linux-m2"); +__static_yoink("usr/share/terminfo/l/ln03-w"); +__static_yoink("usr/share/terminfo/l/linux-vt"); +__static_yoink("usr/share/terminfo/l/linux-s"); +__static_yoink("usr/share/terminfo/l/linux2.2"); +__static_yoink("usr/share/terminfo/l/linux-16color"); +__static_yoink("usr/share/terminfo/l/layer"); +__static_yoink("usr/share/terminfo/l/linux-koi8"); +__static_yoink("usr/share/terminfo/v/vt220-8"); +__static_yoink("usr/share/terminfo/v/vt340"); +__static_yoink("usr/share/terminfo/v/vsc"); +__static_yoink("usr/share/terminfo/v/vte-2007"); +__static_yoink("usr/share/terminfo/v/vt510pcdos"); +__static_yoink("usr/share/terminfo/v/vi200-f"); +__static_yoink("usr/share/terminfo/v/vt52"); +__static_yoink("usr/share/terminfo/v/vt132"); +__static_yoink("usr/share/terminfo/v/vp90"); +__static_yoink("usr/share/terminfo/v/vt100+enq"); +__static_yoink("usr/share/terminfo/v/vt100+pfkeys"); +__static_yoink("usr/share/terminfo/v/vc103"); +__static_yoink("usr/share/terminfo/v/vi200"); +__static_yoink("usr/share/terminfo/v/vtnt"); +__static_yoink("usr/share/terminfo/v/vt400-24"); +__static_yoink("usr/share/terminfo/v/vt-61"); +__static_yoink("usr/share/terminfo/v/vt125"); +__static_yoink("usr/share/terminfo/v/vt420pc"); +__static_yoink("usr/share/terminfo/v/vt300-w-nam"); +__static_yoink("usr/share/terminfo/v/vt102-w"); +__static_yoink("usr/share/terminfo/v/vt100-am"); +__static_yoink("usr/share/terminfo/v/v200-nam"); +__static_yoink("usr/share/terminfo/v/vt100-w-nam"); +__static_yoink("usr/share/terminfo/v/vt320-w"); +__static_yoink("usr/share/terminfo/v/vc414"); +__static_yoink("usr/share/terminfo/v/vc303"); +__static_yoink("usr/share/terminfo/v/vt320"); +__static_yoink("usr/share/terminfo/v/vt100-w-am"); +__static_yoink("usr/share/terminfo/v/vanilla"); +__static_yoink("usr/share/terminfo/v/vt420pcdos"); +__static_yoink("usr/share/terminfo/v/vt100-bm-o"); +__static_yoink("usr/share/terminfo/v/vc203"); +__static_yoink("usr/share/terminfo/v/vt220"); +__static_yoink("usr/share/terminfo/v/vc303a"); +__static_yoink("usr/share/terminfo/v/vip-H"); +__static_yoink("usr/share/terminfo/v/vt100+fnkeys"); +__static_yoink("usr/share/terminfo/v/viewpoint60"); +__static_yoink("usr/share/terminfo/v/vt200-old"); +__static_yoink("usr/share/terminfo/v/vt320nam"); +__static_yoink("usr/share/terminfo/v/vte"); +__static_yoink("usr/share/terminfo/v/vt200-8"); +__static_yoink("usr/share/terminfo/v/viewdata"); +__static_yoink("usr/share/terminfo/v/vi50adm"); +__static_yoink("usr/share/terminfo/v/vi300"); +__static_yoink("usr/share/terminfo/v/vt220+cvis8"); +__static_yoink("usr/share/terminfo/v/vt102-nsgr"); +__static_yoink("usr/share/terminfo/v/vt200-8bit"); +__static_yoink("usr/share/terminfo/v/vt300-w"); +__static_yoink("usr/share/terminfo/v/vte-direct"); +__static_yoink("usr/share/terminfo/v/vc403a"); +__static_yoink("usr/share/terminfo/v/vscode-direct"); +__static_yoink("usr/share/terminfo/v/v5410"); +__static_yoink("usr/share/terminfo/v/vt220-js"); +__static_yoink("usr/share/terminfo/v/vt100-bm"); +__static_yoink("usr/share/terminfo/v/vt220-base"); +__static_yoink("usr/share/terminfo/v/vt510"); +__static_yoink("usr/share/terminfo/v/vt525"); +__static_yoink("usr/share/terminfo/v/vt131"); +__static_yoink("usr/share/terminfo/v/vt102"); +__static_yoink("usr/share/terminfo/v/vt50h"); +__static_yoink("usr/share/terminfo/v/vt420f"); +__static_yoink("usr/share/terminfo/v/visa50"); +__static_yoink("usr/share/terminfo/v/vt320-w-nam"); +__static_yoink("usr/share/terminfo/v/vt52-basic"); +__static_yoink("usr/share/terminfo/v/vte-2018"); +__static_yoink("usr/share/terminfo/v/vt100"); +__static_yoink("usr/share/terminfo/v/vt400"); +__static_yoink("usr/share/terminfo/v/vip-Hw"); +__static_yoink("usr/share/terminfo/v/visual603"); +__static_yoink("usr/share/terminfo/v/vt220-8bit"); +__static_yoink("usr/share/terminfo/v/vt61"); +__static_yoink("usr/share/terminfo/v/vi300-old"); +__static_yoink("usr/share/terminfo/v/vi200-rv"); +__static_yoink("usr/share/terminfo/v/vc404"); +__static_yoink("usr/share/terminfo/v/vt220d"); +__static_yoink("usr/share/terminfo/v/vip7800-w"); +__static_yoink("usr/share/terminfo/v/vip"); +__static_yoink("usr/share/terminfo/v/vapple"); +__static_yoink("usr/share/terminfo/v/vt220+vtedit"); +__static_yoink("usr/share/terminfo/v/vt330"); +__static_yoink("usr/share/terminfo/v/vt61.5"); +__static_yoink("usr/share/terminfo/v/vt50"); +__static_yoink("usr/share/terminfo/v/vt100+keypad"); +__static_yoink("usr/share/terminfo/v/vt220+keypad"); +__static_yoink("usr/share/terminfo/v/vc404-s"); +__static_yoink("usr/share/terminfo/v/vte-2008"); +__static_yoink("usr/share/terminfo/v/vt320-k311"); +__static_yoink("usr/share/terminfo/v/vt100-s"); +__static_yoink("usr/share/terminfo/v/vs100-x10"); +__static_yoink("usr/share/terminfo/v/viewdata-o"); +__static_yoink("usr/share/terminfo/v/versaterm"); +__static_yoink("usr/share/terminfo/v/vi50"); +__static_yoink("usr/share/terminfo/v/vwmterm"); +__static_yoink("usr/share/terminfo/v/venix"); +__static_yoink("usr/share/terminfo/v/vitty"); +__static_yoink("usr/share/terminfo/v/viewpoint90"); +__static_yoink("usr/share/terminfo/v/vt220-old"); +__static_yoink("usr/share/terminfo/v/vt100-nam"); +__static_yoink("usr/share/terminfo/v/vt200-w"); +__static_yoink("usr/share/terminfo/v/vt100-w-nav"); +__static_yoink("usr/share/terminfo/v/vt52+keypad"); +__static_yoink("usr/share/terminfo/v/vt100-putty"); +__static_yoink("usr/share/terminfo/v/vk100"); +__static_yoink("usr/share/terminfo/v/vt220+pcedit"); +__static_yoink("usr/share/terminfo/v/viewpoint"); +__static_yoink("usr/share/terminfo/v/vt200-js"); +__static_yoink("usr/share/terminfo/v/vt220-nam"); +__static_yoink("usr/share/terminfo/v/vt520"); +__static_yoink("usr/share/terminfo/v/vt100-w"); +__static_yoink("usr/share/terminfo/v/vt100-vb"); +__static_yoink("usr/share/terminfo/v/vs100"); +__static_yoink("usr/share/terminfo/v/vte-2017"); +__static_yoink("usr/share/terminfo/v/vt220+cvis"); +__static_yoink("usr/share/terminfo/v/vt100-nam-w"); +__static_yoink("usr/share/terminfo/v/vte-2012"); +__static_yoink("usr/share/terminfo/v/vt100-nav"); +__static_yoink("usr/share/terminfo/v/vt100-nav-w"); +__static_yoink("usr/share/terminfo/v/vscode"); +__static_yoink("usr/share/terminfo/v/vt320-k3"); +__static_yoink("usr/share/terminfo/v/v320n"); +__static_yoink("usr/share/terminfo/v/vt100nam"); +__static_yoink("usr/share/terminfo/v/vt100+4bsd"); +__static_yoink("usr/share/terminfo/v/vt100-bot-s"); +__static_yoink("usr/share/terminfo/v/vt320-nam"); +__static_yoink("usr/share/terminfo/v/vp60"); +__static_yoink("usr/share/terminfo/v/vt420"); +__static_yoink("usr/share/terminfo/v/vi603"); +__static_yoink("usr/share/terminfo/v/vt220-w"); +__static_yoink("usr/share/terminfo/v/vt102+enq"); +__static_yoink("usr/share/terminfo/v/vc415"); +__static_yoink("usr/share/terminfo/v/vte-2014"); +__static_yoink("usr/share/terminfo/v/vte+pcfkeys"); +__static_yoink("usr/share/terminfo/v/viewpoint3a+"); +__static_yoink("usr/share/terminfo/v/vc414h"); +__static_yoink("usr/share/terminfo/v/vp3a+"); +__static_yoink("usr/share/terminfo/v/vip7800-H"); +__static_yoink("usr/share/terminfo/v/vip7800-Hw"); +__static_yoink("usr/share/terminfo/v/vt-utf8"); +__static_yoink("usr/share/terminfo/v/vt300"); +__static_yoink("usr/share/terminfo/v/vte-256color"); +__static_yoink("usr/share/terminfo/v/vt100-top-s"); +__static_yoink("usr/share/terminfo/v/vt300-nam"); +__static_yoink("usr/share/terminfo/v/v3220"); +__static_yoink("usr/share/terminfo/v/vt100-s-bot"); +__static_yoink("usr/share/terminfo/v/vremote"); +__static_yoink("usr/share/terminfo/v/vi55"); +__static_yoink("usr/share/terminfo/v/vt100-s-top"); +__static_yoink("usr/share/terminfo/v/vt510pc"); +__static_yoink("usr/share/terminfo/v/vi500"); +__static_yoink("usr/share/terminfo/v/vv100"); +__static_yoink("usr/share/terminfo/v/vt520ansi"); +__static_yoink("usr/share/terminfo/v/viewdata-rv"); +__static_yoink("usr/share/terminfo/v/vip-w"); +__static_yoink("usr/share/terminfo/v/vt200"); +__static_yoink("usr/share/terminfo/v/vt100+"); +__static_yoink("usr/share/terminfo/v/vi550"); +__static_yoink("usr/share/terminfo/v/vt420+lrmm"); +__static_yoink("usr/share/terminfo/g/gnome-2012"); +__static_yoink("usr/share/terminfo/g/guru-76-w"); +__static_yoink("usr/share/terminfo/g/go225"); +__static_yoink("usr/share/terminfo/g/gator-t"); +__static_yoink("usr/share/terminfo/g/guru-44"); +__static_yoink("usr/share/terminfo/g/go140"); +__static_yoink("usr/share/terminfo/g/gnome-2008"); +__static_yoink("usr/share/terminfo/g/go140w"); +__static_yoink("usr/share/terminfo/g/guru+unk"); +__static_yoink("usr/share/terminfo/g/gnome-rh90"); +__static_yoink("usr/share/terminfo/g/gnome-256color"); +__static_yoink("usr/share/terminfo/g/glasstty"); +__static_yoink("usr/share/terminfo/g/guru-nctxt"); +__static_yoink("usr/share/terminfo/g/gs5430-24"); +__static_yoink("usr/share/terminfo/g/go-225"); +__static_yoink("usr/share/terminfo/g/gt100a"); +__static_yoink("usr/share/terminfo/g/gnome-rh72"); +__static_yoink("usr/share/terminfo/g/guru-24"); +__static_yoink("usr/share/terminfo/g/gs6300"); +__static_yoink("usr/share/terminfo/g/gnome"); +__static_yoink("usr/share/terminfo/g/guru-s"); +__static_yoink("usr/share/terminfo/g/guru+rv"); +__static_yoink("usr/share/terminfo/g/gnome-rh62"); +__static_yoink("usr/share/terminfo/g/guru-76-w-s"); +__static_yoink("usr/share/terminfo/g/guru-rv"); +__static_yoink("usr/share/terminfo/g/gator-52"); +__static_yoink("usr/share/terminfo/g/gsi"); +__static_yoink("usr/share/terminfo/g/guru+s"); +__static_yoink("usr/share/terminfo/g/guru-76"); +__static_yoink("usr/share/terminfo/g/gnome-fc5"); +__static_yoink("usr/share/terminfo/g/guru"); +__static_yoink("usr/share/terminfo/g/gator-52t"); +__static_yoink("usr/share/terminfo/g/guru-lp"); +__static_yoink("usr/share/terminfo/g/gs5430-22"); +__static_yoink("usr/share/terminfo/g/gator"); +__static_yoink("usr/share/terminfo/g/gnome-2007"); +__static_yoink("usr/share/terminfo/g/gigi"); +__static_yoink("usr/share/terminfo/g/guru-33-s"); +__static_yoink("usr/share/terminfo/g/gt100"); +__static_yoink("usr/share/terminfo/g/gnome-rh80"); +__static_yoink("usr/share/terminfo/g/gt42"); +__static_yoink("usr/share/terminfo/g/guru-44-s"); +__static_yoink("usr/share/terminfo/g/gt40"); +__static_yoink("usr/share/terminfo/g/guru-76-wm"); +__static_yoink("usr/share/terminfo/g/guru-76-lp"); +__static_yoink("usr/share/terminfo/g/graphos-30"); +__static_yoink("usr/share/terminfo/g/guru-33-rv"); +__static_yoink("usr/share/terminfo/g/graphos"); +__static_yoink("usr/share/terminfo/g/gnome+pcfkeys"); +__static_yoink("usr/share/terminfo/g/gs5430"); +__static_yoink("usr/share/terminfo/g/guru-33"); +__static_yoink("usr/share/terminfo/g/guru-76-s"); +__static_yoink("usr/share/terminfo/b/bitgraph"); +__static_yoink("usr/share/terminfo/b/bq300-8-pc"); +__static_yoink("usr/share/terminfo/b/bq300-w-8rv"); +__static_yoink("usr/share/terminfo/b/bg1.25rv"); +__static_yoink("usr/share/terminfo/b/bq300-8"); +__static_yoink("usr/share/terminfo/b/bq300-w-rv"); +__static_yoink("usr/share/terminfo/b/bsdos-ppc"); +__static_yoink("usr/share/terminfo/b/bsdos-pc-m"); +__static_yoink("usr/share/terminfo/b/bg2.0"); +__static_yoink("usr/share/terminfo/b/beehive"); +__static_yoink("usr/share/terminfo/b/bh3m"); +__static_yoink("usr/share/terminfo/b/beehiveIIIm"); +__static_yoink("usr/share/terminfo/b/bsdos-pc-nobold"); +__static_yoink("usr/share/terminfo/b/bg2.0nv"); +__static_yoink("usr/share/terminfo/b/beehive4"); +__static_yoink("usr/share/terminfo/b/basic4"); +__static_yoink("usr/share/terminfo/b/bq300-pc-rv"); +__static_yoink("usr/share/terminfo/b/basis"); +__static_yoink("usr/share/terminfo/b/bq300-w"); +__static_yoink("usr/share/terminfo/b/bsdos-pc-mono"); +__static_yoink("usr/share/terminfo/b/bracketed+paste"); +__static_yoink("usr/share/terminfo/b/bq300-pc"); +__static_yoink("usr/share/terminfo/b/bct510a"); +__static_yoink("usr/share/terminfo/b/bg3.10rv"); +__static_yoink("usr/share/terminfo/b/bantam"); +__static_yoink("usr/share/terminfo/b/bct510d"); +__static_yoink("usr/share/terminfo/b/bq300-8-pc-rv"); +__static_yoink("usr/share/terminfo/b/bg1.25nv"); +__static_yoink("usr/share/terminfo/b/bobcat"); +__static_yoink("usr/share/terminfo/b/bsdos-pc"); +__static_yoink("usr/share/terminfo/b/bq300-pc-w-rv"); +__static_yoink("usr/share/terminfo/b/beterm"); +__static_yoink("usr/share/terminfo/b/bsdos-sparc"); +__static_yoink("usr/share/terminfo/b/bq300-8w"); +__static_yoink("usr/share/terminfo/b/b-128"); +__static_yoink("usr/share/terminfo/b/bq300-8-pc-w"); +__static_yoink("usr/share/terminfo/b/blit"); +__static_yoink("usr/share/terminfo/b/bq300-8-pc-w-rv"); +__static_yoink("usr/share/terminfo/b/bq300"); +__static_yoink("usr/share/terminfo/b/bg3.10nv"); +__static_yoink("usr/share/terminfo/b/beehive3"); +__static_yoink("usr/share/terminfo/b/bh4"); +__static_yoink("usr/share/terminfo/b/bq300-pc-w"); +__static_yoink("usr/share/terminfo/b/bterm"); +__static_yoink("usr/share/terminfo/b/bee"); +__static_yoink("usr/share/terminfo/b/beacon"); +__static_yoink("usr/share/terminfo/b/bq300-8rv"); +__static_yoink("usr/share/terminfo/b/bq300-rv"); +__static_yoink("usr/share/terminfo/b/bg1.25"); +__static_yoink("usr/share/terminfo/b/bg2.0rv"); +__static_yoink("usr/share/terminfo/b/bg3.10"); +__static_yoink("usr/share/terminfo/P/P9-W"); +__static_yoink("usr/share/terminfo/P/P7"); +__static_yoink("usr/share/terminfo/P/P14-M-W"); +__static_yoink("usr/share/terminfo/P/P8-W"); +__static_yoink("usr/share/terminfo/P/P8"); +__static_yoink("usr/share/terminfo/P/P12-M"); +__static_yoink("usr/share/terminfo/P/P4"); +__static_yoink("usr/share/terminfo/P/P14-M"); +__static_yoink("usr/share/terminfo/P/P12"); +__static_yoink("usr/share/terminfo/P/P9"); +__static_yoink("usr/share/terminfo/P/P12-W"); +__static_yoink("usr/share/terminfo/P/P14-W"); +__static_yoink("usr/share/terminfo/P/P9-8"); +__static_yoink("usr/share/terminfo/P/P9-8-W"); +__static_yoink("usr/share/terminfo/P/P12-M-W"); +__static_yoink("usr/share/terminfo/P/P14"); +__static_yoink("usr/share/terminfo/P/P5"); +__static_yoink("usr/share/terminfo/r/rxvt-cygwin"); +__static_yoink("usr/share/terminfo/r/rca"); +__static_yoink("usr/share/terminfo/r/regent40+"); +__static_yoink("usr/share/terminfo/r/regent100"); +__static_yoink("usr/share/terminfo/r/rxvt-basic"); +__static_yoink("usr/share/terminfo/r/regent40"); +__static_yoink("usr/share/terminfo/r/rxvt-color"); +__static_yoink("usr/share/terminfo/r/rbcomm-nam"); +__static_yoink("usr/share/terminfo/r/rbcomm"); +__static_yoink("usr/share/terminfo/r/rt6221"); +__static_yoink("usr/share/terminfo/r/regent"); +__static_yoink("usr/share/terminfo/r/rxvt-xpm"); +__static_yoink("usr/share/terminfo/r/rcons-color"); +__static_yoink("usr/share/terminfo/r/regent200"); +__static_yoink("usr/share/terminfo/r/regent20"); +__static_yoink("usr/share/terminfo/r/regent25"); +__static_yoink("usr/share/terminfo/r/rbcomm-w"); +__static_yoink("usr/share/terminfo/r/rxvt-16color"); +__static_yoink("usr/share/terminfo/r/rxvt-88color"); +__static_yoink("usr/share/terminfo/r/rebus3180"); +__static_yoink("usr/share/terminfo/r/rt6221-w"); +__static_yoink("usr/share/terminfo/r/rxvt-cygwin-native"); +__static_yoink("usr/share/terminfo/r/rcons"); +__static_yoink("usr/share/terminfo/r/rxvt-256color"); +__static_yoink("usr/share/terminfo/r/rtpc"); +__static_yoink("usr/share/terminfo/r/rxvt+pcfkeys"); +__static_yoink("usr/share/terminfo/r/regent60"); +__static_yoink("usr/share/terminfo/r/rxvt"); +__static_yoink("usr/share/terminfo/h/hp+labels"); +__static_yoink("usr/share/terminfo/h/hp70092A"); +__static_yoink("usr/share/terminfo/h/h19k"); +__static_yoink("usr/share/terminfo/h/hp2621-wl"); +__static_yoink("usr/share/terminfo/h/hp2644a"); +__static_yoink("usr/share/terminfo/h/hp236"); +__static_yoink("usr/share/terminfo/h/hp2626a"); +__static_yoink("usr/share/terminfo/h/hp2627a-rev"); +__static_yoink("usr/share/terminfo/h/hp2627c"); +__static_yoink("usr/share/terminfo/h/hmod1"); +__static_yoink("usr/share/terminfo/h/ha8686"); +__static_yoink("usr/share/terminfo/h/hpex"); +__static_yoink("usr/share/terminfo/h/h19kermit"); +__static_yoink("usr/share/terminfo/h/hp2621k45"); +__static_yoink("usr/share/terminfo/h/hp2622a"); +__static_yoink("usr/share/terminfo/h/hp2622"); +__static_yoink("usr/share/terminfo/h/hp2621b-kx"); +__static_yoink("usr/share/terminfo/h/hz1500"); +__static_yoink("usr/share/terminfo/h/hp2640a"); +__static_yoink("usr/share/terminfo/h/hp2626p"); +__static_yoink("usr/share/terminfo/h/hp9845"); +__static_yoink("usr/share/terminfo/h/hp700"); +__static_yoink("usr/share/terminfo/h/hp2640b"); +__static_yoink("usr/share/terminfo/h/hp2624"); +__static_yoink("usr/share/terminfo/h/hp2624b-4p-p"); +__static_yoink("usr/share/terminfo/h/ha8675"); +__static_yoink("usr/share/terminfo/h/h80"); +__static_yoink("usr/share/terminfo/h/hft"); +__static_yoink("usr/share/terminfo/h/hz1520"); +__static_yoink("usr/share/terminfo/h/hp2626-12-s"); +__static_yoink("usr/share/terminfo/h/h29a-nkc-bc"); +__static_yoink("usr/share/terminfo/h/h19-b"); +__static_yoink("usr/share/terminfo/h/heathkit-a"); +__static_yoink("usr/share/terminfo/h/hft-old"); +__static_yoink("usr/share/terminfo/h/h19-g"); +__static_yoink("usr/share/terminfo/h/hp2626-ns"); +__static_yoink("usr/share/terminfo/h/hp2382a"); +__static_yoink("usr/share/terminfo/h/hz1000"); +__static_yoink("usr/share/terminfo/h/hp2621"); +__static_yoink("usr/share/terminfo/h/hp700-wy"); +__static_yoink("usr/share/terminfo/h/hp150"); +__static_yoink("usr/share/terminfo/h/hds200"); +__static_yoink("usr/share/terminfo/h/h-100"); +__static_yoink("usr/share/terminfo/h/hp98550"); +__static_yoink("usr/share/terminfo/h/hp2623a"); +__static_yoink("usr/share/terminfo/h/hpex2"); +__static_yoink("usr/share/terminfo/h/hp300h"); +__static_yoink("usr/share/terminfo/h/hz1420"); +__static_yoink("usr/share/terminfo/h/hp110"); +__static_yoink("usr/share/terminfo/h/hp2624a"); +__static_yoink("usr/share/terminfo/h/hp2621-ba"); +__static_yoink("usr/share/terminfo/h/hp2626-x40"); +__static_yoink("usr/share/terminfo/h/hterm"); +__static_yoink("usr/share/terminfo/h/hp2621p"); +__static_yoink("usr/share/terminfo/h/hp2624b-10p-p"); +__static_yoink("usr/share/terminfo/h/hpterm-color"); +__static_yoink("usr/share/terminfo/h/hp2621a-a"); +__static_yoink("usr/share/terminfo/h/h19us"); +__static_yoink("usr/share/terminfo/h/hp70092a"); +__static_yoink("usr/share/terminfo/h/hp98550-color"); +__static_yoink("usr/share/terminfo/h/h29a-kc-bc"); +__static_yoink("usr/share/terminfo/h/hp2621b-p"); +__static_yoink("usr/share/terminfo/h/hp2397a"); +__static_yoink("usr/share/terminfo/h/hp2648a"); +__static_yoink("usr/share/terminfo/h/h19g"); +__static_yoink("usr/share/terminfo/h/hp2626-12"); +__static_yoink("usr/share/terminfo/h/hp2392"); +__static_yoink("usr/share/terminfo/h/hterm-256color"); +__static_yoink("usr/share/terminfo/h/hp262x"); +__static_yoink("usr/share/terminfo/h/hpansi"); +__static_yoink("usr/share/terminfo/h/hp2641a"); +__static_yoink("usr/share/terminfo/h/hp70092"); +__static_yoink("usr/share/terminfo/h/h19-smul"); +__static_yoink("usr/share/terminfo/h/h19a"); +__static_yoink("usr/share/terminfo/h/he80"); +__static_yoink("usr/share/terminfo/h/h19-us"); +__static_yoink("usr/share/terminfo/h/hirez100-w"); +__static_yoink("usr/share/terminfo/h/hp2621-nl"); +__static_yoink("usr/share/terminfo/h/h19-bs"); +__static_yoink("usr/share/terminfo/h/hz2000"); +__static_yoink("usr/share/terminfo/h/hz1552"); +__static_yoink("usr/share/terminfo/h/heathkit"); +__static_yoink("usr/share/terminfo/h/hirez100"); +__static_yoink("usr/share/terminfo/h/hp2623"); +__static_yoink("usr/share/terminfo/h/hp2621-fl"); +__static_yoink("usr/share/terminfo/h/hp9837"); +__static_yoink("usr/share/terminfo/h/hz1510"); +__static_yoink("usr/share/terminfo/h/hp98721"); +__static_yoink("usr/share/terminfo/h/hp98550a-color"); +__static_yoink("usr/share/terminfo/h/hpterm"); +__static_yoink("usr/share/terminfo/h/hp2627a"); +__static_yoink("usr/share/terminfo/h/hz1552-rv"); +__static_yoink("usr/share/terminfo/h/h19"); +__static_yoink("usr/share/terminfo/h/hp45"); +__static_yoink("usr/share/terminfo/h/hazel"); +__static_yoink("usr/share/terminfo/h/hp2382"); +__static_yoink("usr/share/terminfo/h/hp+color"); +__static_yoink("usr/share/terminfo/h/hurd"); +__static_yoink("usr/share/terminfo/h/hp2"); +__static_yoink("usr/share/terminfo/h/heath"); +__static_yoink("usr/share/terminfo/h/h19-u"); +__static_yoink("usr/share/terminfo/h/h-100bw"); +__static_yoink("usr/share/terminfo/h/hp2621-a"); +__static_yoink("usr/share/terminfo/h/hpterm-color2"); +__static_yoink("usr/share/terminfo/h/htx11"); +__static_yoink("usr/share/terminfo/h/hp98720"); +__static_yoink("usr/share/terminfo/h/hp2621b-kx-p"); +__static_yoink("usr/share/terminfo/h/hp2621b"); +__static_yoink("usr/share/terminfo/h/hp2624b-p"); +__static_yoink("usr/share/terminfo/h/hp2397"); +__static_yoink("usr/share/terminfo/h/hpsub"); +__static_yoink("usr/share/terminfo/h/hft-c-old"); +__static_yoink("usr/share/terminfo/h/h100"); +__static_yoink("usr/share/terminfo/h/hp2626-12x40"); +__static_yoink("usr/share/terminfo/h/h100bw"); +__static_yoink("usr/share/terminfo/h/hp2621a"); +__static_yoink("usr/share/terminfo/h/hp98550a"); +__static_yoink("usr/share/terminfo/h/hp2624-10p"); +__static_yoink("usr/share/terminfo/h/hp2624b-4p"); +__static_yoink("usr/share/terminfo/h/hp+arrows"); +__static_yoink("usr/share/terminfo/h/hp2647a"); +__static_yoink("usr/share/terminfo/h/hp2621-k45"); +__static_yoink("usr/share/terminfo/h/hp2621A"); +__static_yoink("usr/share/terminfo/h/hp"); +__static_yoink("usr/share/terminfo/h/hp2624b"); +__static_yoink("usr/share/terminfo/h/hz1520-noesc"); +__static_yoink("usr/share/terminfo/h/hp+pfk-cr"); +__static_yoink("usr/share/terminfo/h/hp+pfk+cr"); +__static_yoink("usr/share/terminfo/h/hft-c"); +__static_yoink("usr/share/terminfo/h/hp2648"); +__static_yoink("usr/share/terminfo/h/hp2645a"); +__static_yoink("usr/share/terminfo/h/h29a-nkc-uc"); +__static_yoink("usr/share/terminfo/h/heath-19"); +__static_yoink("usr/share/terminfo/h/hp2645"); +__static_yoink("usr/share/terminfo/h/hpgeneric"); +__static_yoink("usr/share/terminfo/h/h19-a"); +__static_yoink("usr/share/terminfo/h/hp2624b-10p"); +__static_yoink("usr/share/terminfo/h/hp2626-s"); +__static_yoink("usr/share/terminfo/h/hp+printer"); +__static_yoink("usr/share/terminfo/h/hp2624a-10p"); +__static_yoink("usr/share/terminfo/h/hp2621-nt"); +__static_yoink("usr/share/terminfo/h/h29a-kc-uc"); +__static_yoink("usr/share/terminfo/h/hp2626"); +__static_yoink("usr/share/terminfo/h/heath-ansi"); +__static_yoink("usr/share/terminfo/h/hp2621-48"); +__static_yoink("usr/share/terminfo/h/hp+pfk+arrows"); +__static_yoink("usr/share/terminfo/h/hp2621p-a"); +__static_yoink("usr/share/terminfo/e/emu"); +__static_yoink("usr/share/terminfo/e/esprit"); +__static_yoink("usr/share/terminfo/e/elks-vt52"); +__static_yoink("usr/share/terminfo/e/ergo4000"); +__static_yoink("usr/share/terminfo/e/ep40"); +__static_yoink("usr/share/terminfo/e/ecma+italics"); +__static_yoink("usr/share/terminfo/e/excel64-rv"); +__static_yoink("usr/share/terminfo/e/excel64"); +__static_yoink("usr/share/terminfo/e/eterm-color"); +__static_yoink("usr/share/terminfo/e/elks-glasstty"); +__static_yoink("usr/share/terminfo/e/emots"); +__static_yoink("usr/share/terminfo/e/excel62"); +__static_yoink("usr/share/terminfo/e/emu-220"); +__static_yoink("usr/share/terminfo/e/excel62-w"); +__static_yoink("usr/share/terminfo/e/esprit-am"); +__static_yoink("usr/share/terminfo/e/eterm"); +__static_yoink("usr/share/terminfo/e/ecma+color"); +__static_yoink("usr/share/terminfo/e/ex155"); +__static_yoink("usr/share/terminfo/e/exec80"); +__static_yoink("usr/share/terminfo/e/elks"); +__static_yoink("usr/share/terminfo/e/ep4000"); +__static_yoink("usr/share/terminfo/e/ep48"); +__static_yoink("usr/share/terminfo/e/emx-base"); +__static_yoink("usr/share/terminfo/e/elks-ansi"); +__static_yoink("usr/share/terminfo/e/ecma+sgr"); +__static_yoink("usr/share/terminfo/e/excel64-w"); +__static_yoink("usr/share/terminfo/e/ecma+strikeout"); +__static_yoink("usr/share/terminfo/e/ep4080"); +__static_yoink("usr/share/terminfo/e/excel62-rv"); +__static_yoink("usr/share/terminfo/e/ecma+index"); +__static_yoink("usr/share/terminfo/e/env230"); +__static_yoink("usr/share/terminfo/e/envision230"); +__static_yoink("usr/share/terminfo/i/intext2"); +__static_yoink("usr/share/terminfo/i/infoton"); +__static_yoink("usr/share/terminfo/i/ibmmpel-c"); +__static_yoink("usr/share/terminfo/i/ibm3161"); +__static_yoink("usr/share/terminfo/i/ibm6154"); +__static_yoink("usr/share/terminfo/i/iris-ansi"); +__static_yoink("usr/share/terminfo/i/ibmpc"); +__static_yoink("usr/share/terminfo/i/intertube"); +__static_yoink("usr/share/terminfo/i/ims950"); +__static_yoink("usr/share/terminfo/i/ibm8604"); +__static_yoink("usr/share/terminfo/i/ibm8513"); +__static_yoink("usr/share/terminfo/i/ibm8514"); +__static_yoink("usr/share/terminfo/i/ibmapa16"); +__static_yoink("usr/share/terminfo/i/iq140"); +__static_yoink("usr/share/terminfo/i/i100"); +__static_yoink("usr/share/terminfo/i/iris-ansi-ap"); +__static_yoink("usr/share/terminfo/i/ibm-system1"); +__static_yoink("usr/share/terminfo/i/ims950-rv"); +__static_yoink("usr/share/terminfo/i/ibmpc3r"); +__static_yoink("usr/share/terminfo/i/ibm8512"); +__static_yoink("usr/share/terminfo/i/ibm5081-c"); +__static_yoink("usr/share/terminfo/i/ibm6154-c"); +__static_yoink("usr/share/terminfo/i/iterm2-direct"); +__static_yoink("usr/share/terminfo/i/ibm5051"); +__static_yoink("usr/share/terminfo/i/ibm6153"); +__static_yoink("usr/share/terminfo/i/ibm327x"); +__static_yoink("usr/share/terminfo/i/intertec"); +__static_yoink("usr/share/terminfo/i/ibmega"); +__static_yoink("usr/share/terminfo/i/ibm3151"); +__static_yoink("usr/share/terminfo/i/ibmmono"); +__static_yoink("usr/share/terminfo/i/ibmpc3r-mono"); +__static_yoink("usr/share/terminfo/i/ibm5081"); +__static_yoink("usr/share/terminfo/i/ibmpcx"); +__static_yoink("usr/share/terminfo/i/ibmvga"); +__static_yoink("usr/share/terminfo/i/ibmapa8c"); +__static_yoink("usr/share/terminfo/i/ips"); +__static_yoink("usr/share/terminfo/i/iterm"); +__static_yoink("usr/share/terminfo/i/ibmx"); +__static_yoink("usr/share/terminfo/i/icl6402"); +__static_yoink("usr/share/terminfo/i/ibcs2"); +__static_yoink("usr/share/terminfo/i/ibmapa8c-c"); +__static_yoink("usr/share/terminfo/i/ibm5154-c"); +__static_yoink("usr/share/terminfo/i/ibm+16color"); +__static_yoink("usr/share/terminfo/i/i3164"); +__static_yoink("usr/share/terminfo/i/ibmvga-c"); +__static_yoink("usr/share/terminfo/i/ibm5154"); +__static_yoink("usr/share/terminfo/i/iris-ansi-net"); +__static_yoink("usr/share/terminfo/i/ibm3164"); +__static_yoink("usr/share/terminfo/i/ibm6153-40"); +__static_yoink("usr/share/terminfo/i/iTerm2.app"); +__static_yoink("usr/share/terminfo/i/ibm6153-90"); +__static_yoink("usr/share/terminfo/i/ibm3163"); +__static_yoink("usr/share/terminfo/i/ibmpc3"); +__static_yoink("usr/share/terminfo/i/iq120"); +__static_yoink("usr/share/terminfo/i/intextii"); +__static_yoink("usr/share/terminfo/i/i400"); +__static_yoink("usr/share/terminfo/i/ibm8503"); +__static_yoink("usr/share/terminfo/i/interix"); +__static_yoink("usr/share/terminfo/i/ibmaed"); +__static_yoink("usr/share/terminfo/i/ifmr"); +__static_yoink("usr/share/terminfo/i/ibm-apl"); +__static_yoink("usr/share/terminfo/i/iris-color"); +__static_yoink("usr/share/terminfo/i/ibmega-c"); +__static_yoink("usr/share/terminfo/i/ibm-pc"); +__static_yoink("usr/share/terminfo/i/ibm8507"); +__static_yoink("usr/share/terminfo/i/ibmapa8"); +__static_yoink("usr/share/terminfo/i/ibm5151"); +__static_yoink("usr/share/terminfo/i/ims-ansi"); +__static_yoink("usr/share/terminfo/i/icl6404"); +__static_yoink("usr/share/terminfo/i/ipsi"); +__static_yoink("usr/share/terminfo/i/intext"); +__static_yoink("usr/share/terminfo/i/intertube2"); +__static_yoink("usr/share/terminfo/i/interix-nti"); +__static_yoink("usr/share/terminfo/i/infoton2"); +__static_yoink("usr/share/terminfo/i/ibm+color"); +__static_yoink("usr/share/terminfo/i/iTerm.app"); +__static_yoink("usr/share/terminfo/i/iris40"); +__static_yoink("usr/share/terminfo/i/ibm3161-C"); +__static_yoink("usr/share/terminfo/i/iterm2"); +__static_yoink("usr/share/terminfo/i/ibm3101"); +__static_yoink("usr/share/terminfo/i/icl6404-w"); +__static_yoink("usr/share/terminfo/i/ibm3162"); +__static_yoink("usr/share/terminfo/i/i3101"); +__static_yoink("usr/share/terminfo/i/ibm6155"); +__static_yoink("usr/share/terminfo/i/ibm8514-c"); +__static_yoink("usr/share/terminfo/i/ims950-b"); +__static_yoink("usr/share/terminfo/w/wy520-vb"); +__static_yoink("usr/share/terminfo/w/wy160-w-vb"); +__static_yoink("usr/share/terminfo/w/wyse520-24"); +__static_yoink("usr/share/terminfo/w/wyse60-43-w"); +__static_yoink("usr/share/terminfo/w/wyse60-w"); +__static_yoink("usr/share/terminfo/w/wy60-43"); +__static_yoink("usr/share/terminfo/w/wy325-80"); +__static_yoink("usr/share/terminfo/w/wy325-43w-vb"); +__static_yoink("usr/share/terminfo/w/wy50-vb"); +__static_yoink("usr/share/terminfo/w/wyse325-25w"); +__static_yoink("usr/share/terminfo/w/wy85-8bit"); +__static_yoink("usr/share/terminfo/w/wy370-w"); +__static_yoink("usr/share/terminfo/w/wy-75ap"); +__static_yoink("usr/share/terminfo/w/wyse50-vb"); +__static_yoink("usr/share/terminfo/w/wyse520-pc-vb"); +__static_yoink("usr/share/terminfo/w/wy325-25w"); +__static_yoink("usr/share/terminfo/w/wyse150-25"); +__static_yoink("usr/share/terminfo/w/wyse150-w-vb"); +__static_yoink("usr/share/terminfo/w/wy99gt-vb"); +__static_yoink("usr/share/terminfo/w/wyse60-PC"); +__static_yoink("usr/share/terminfo/w/wy120-wvb"); +__static_yoink("usr/share/terminfo/w/wy160-wvb"); +__static_yoink("usr/share/terminfo/w/wyse325-42w"); +__static_yoink("usr/share/terminfo/w/wyse75-w"); +__static_yoink("usr/share/terminfo/w/wy99fgta"); +__static_yoink("usr/share/terminfo/w/wsvt25m"); +__static_yoink("usr/share/terminfo/w/wyse520-48pc"); +__static_yoink("usr/share/terminfo/w/wy50-wvb"); +__static_yoink("usr/share/terminfo/w/wy520-36"); +__static_yoink("usr/share/terminfo/w/wy160"); +__static_yoink("usr/share/terminfo/w/wy60-316X"); +__static_yoink("usr/share/terminfo/w/wy150"); +__static_yoink("usr/share/terminfo/w/wyse160-w"); +__static_yoink("usr/share/terminfo/w/wyse350-wvb"); +__static_yoink("usr/share/terminfo/w/wy520-36wpc"); +__static_yoink("usr/share/terminfo/w/wy370-vb"); +__static_yoink("usr/share/terminfo/w/wyse520-epc-w"); +__static_yoink("usr/share/terminfo/w/wy325-42"); +__static_yoink("usr/share/terminfo/w/wy75-vb"); +__static_yoink("usr/share/terminfo/w/wyse370"); +__static_yoink("usr/share/terminfo/w/wy99gt-tek"); +__static_yoink("usr/share/terminfo/w/wy350-vb"); +__static_yoink("usr/share/terminfo/w/wy85-vb"); +__static_yoink("usr/share/terminfo/w/wsiris"); +__static_yoink("usr/share/terminfo/w/wy520-48pc"); +__static_yoink("usr/share/terminfo/w/wyse+sl"); +__static_yoink("usr/share/terminfo/w/wy100q"); +__static_yoink("usr/share/terminfo/w/wy150-w"); +__static_yoink("usr/share/terminfo/w/wy325-vb"); +__static_yoink("usr/share/terminfo/w/wy50-w"); +__static_yoink("usr/share/terminfo/w/wy520-epc-24"); +__static_yoink("usr/share/terminfo/w/wyse325-42"); +__static_yoink("usr/share/terminfo/w/wy520-36pc"); +__static_yoink("usr/share/terminfo/w/wyse60-vb"); +__static_yoink("usr/share/terminfo/w/wy150-25"); +__static_yoink("usr/share/terminfo/w/wy325-42w"); +__static_yoink("usr/share/terminfo/w/wyse75ap"); +__static_yoink("usr/share/terminfo/w/wy325"); +__static_yoink("usr/share/terminfo/w/wyse185-24"); +__static_yoink("usr/share/terminfo/w/wy160-42"); +__static_yoink("usr/share/terminfo/w/wy350-w"); +__static_yoink("usr/share/terminfo/w/wy75-wvb"); +__static_yoink("usr/share/terminfo/w/wyse185-w"); +__static_yoink("usr/share/terminfo/w/wyse60-43"); +__static_yoink("usr/share/terminfo/w/wyse160-25"); +__static_yoink("usr/share/terminfo/w/wyse75-vb"); +__static_yoink("usr/share/terminfo/w/wy160-tek"); +__static_yoink("usr/share/terminfo/w/wy60-42-w"); +__static_yoink("usr/share/terminfo/w/wyse160-43-w"); +__static_yoink("usr/share/terminfo/w/wyse60-wvb"); +__static_yoink("usr/share/terminfo/w/wy160-w"); +__static_yoink("usr/share/terminfo/w/wy520-epc-vb"); +__static_yoink("usr/share/terminfo/w/wy350"); +__static_yoink("usr/share/terminfo/w/wyse60-25-w"); +__static_yoink("usr/share/terminfo/w/wy325w-24"); +__static_yoink("usr/share/terminfo/w/wy350-wvb"); +__static_yoink("usr/share/terminfo/w/wy325-25"); +__static_yoink("usr/share/terminfo/w/wyse520-48"); +__static_yoink("usr/share/terminfo/w/wyse99gt"); +__static_yoink("usr/share/terminfo/w/wy520-epc-w"); +__static_yoink("usr/share/terminfo/w/wy520-36w"); +__static_yoink("usr/share/terminfo/w/wy30-vb"); +__static_yoink("usr/share/terminfo/w/wy185-vb"); +__static_yoink("usr/share/terminfo/w/wyse50-mc"); +__static_yoink("usr/share/terminfo/w/wyse520-wvb"); +__static_yoink("usr/share/terminfo/w/wyse60-25"); +__static_yoink("usr/share/terminfo/w/wyse325-25"); +__static_yoink("usr/share/terminfo/w/wy75"); +__static_yoink("usr/share/terminfo/w/wy520"); +__static_yoink("usr/share/terminfo/w/wyse120-25-w"); +__static_yoink("usr/share/terminfo/w/wyse99gt-vb"); +__static_yoink("usr/share/terminfo/w/wyse520-epc"); +__static_yoink("usr/share/terminfo/w/wy60-43-w"); +__static_yoink("usr/share/terminfo/w/wy185-w"); +__static_yoink("usr/share/terminfo/w/wy160-43"); +__static_yoink("usr/share/terminfo/w/wyse160-wvb"); +__static_yoink("usr/share/terminfo/w/wy99fa"); +__static_yoink("usr/share/terminfo/w/wy100"); +__static_yoink("usr/share/terminfo/w/wyse60-42"); +__static_yoink("usr/share/terminfo/w/wrenw"); +__static_yoink("usr/share/terminfo/w/wren"); +__static_yoink("usr/share/terminfo/w/wyse150-vb"); +__static_yoink("usr/share/terminfo/w/wyse325"); +__static_yoink("usr/share/terminfo/w/wy160-42-w"); +__static_yoink("usr/share/terminfo/w/wyse60"); +__static_yoink("usr/share/terminfo/w/wy325-43"); +__static_yoink("usr/share/terminfo/w/wy120-vb"); +__static_yoink("usr/share/terminfo/w/wyse120-w"); +__static_yoink("usr/share/terminfo/w/wy150-w-vb"); +__static_yoink("usr/share/terminfo/w/wyse185-vb"); +__static_yoink("usr/share/terminfo/w/wyse85"); +__static_yoink("usr/share/terminfo/w/wy520-24"); +__static_yoink("usr/share/terminfo/w/wyse350-w"); +__static_yoink("usr/share/terminfo/w/wy60-42"); +__static_yoink("usr/share/terminfo/w/wy370-tek"); +__static_yoink("usr/share/terminfo/w/wyse520-36pc"); +__static_yoink("usr/share/terminfo/w/wy60-w"); +__static_yoink("usr/share/terminfo/w/wyse50-w"); +__static_yoink("usr/share/terminfo/w/wy99gt-w"); +__static_yoink("usr/share/terminfo/w/wyse350"); +__static_yoink("usr/share/terminfo/w/wy99a-ansi"); +__static_yoink("usr/share/terminfo/w/wyse520-vb"); +__static_yoink("usr/share/terminfo/w/wyse160-42-w"); +__static_yoink("usr/share/terminfo/w/wyse-vp"); +__static_yoink("usr/share/terminfo/w/wyse520-p-wvb"); +__static_yoink("usr/share/terminfo/w/wyse120-vb"); +__static_yoink("usr/share/terminfo/w/wy99gt-w-vb"); +__static_yoink("usr/share/terminfo/w/wy60-25-w"); +__static_yoink("usr/share/terminfo/w/wy520-48w"); +__static_yoink("usr/share/terminfo/w/wy120-w-vb"); +__static_yoink("usr/share/terminfo/w/wyse520-36"); +__static_yoink("usr/share/terminfo/w/wy185"); +__static_yoink("usr/share/terminfo/w/wy75-mc"); +__static_yoink("usr/share/terminfo/w/wy520-w"); +__static_yoink("usr/share/terminfo/w/wyse85-wvb"); +__static_yoink("usr/share/terminfo/w/wy160-25"); +__static_yoink("usr/share/terminfo/w/wy50"); +__static_yoink("usr/share/terminfo/w/wyse60-316X"); +__static_yoink("usr/share/terminfo/w/wy75-w"); +__static_yoink("usr/share/terminfo/w/wy99gt-25"); +__static_yoink("usr/share/terminfo/w/wyse520-48wpc"); +__static_yoink("usr/share/terminfo/w/wyse185-wvb"); +__static_yoink("usr/share/terminfo/w/wyse120"); +__static_yoink("usr/share/terminfo/w/wyse185"); +__static_yoink("usr/share/terminfo/w/wy520-48wpc"); +__static_yoink("usr/share/terminfo/w/wy370-101k"); +__static_yoink("usr/share/terminfo/w/wyse50-wvb"); +__static_yoink("usr/share/terminfo/w/wy325-42wvb"); +__static_yoink("usr/share/terminfo/w/wy370-wvb"); +__static_yoink("usr/share/terminfo/w/wyse350-vb"); +__static_yoink("usr/share/terminfo/w/wyse325-43"); +__static_yoink("usr/share/terminfo/w/wyse75"); +__static_yoink("usr/share/terminfo/w/wyse150-25-w"); +__static_yoink("usr/share/terminfo/w/wyse85-vb"); +__static_yoink("usr/share/terminfo/w/wy325-43w"); +__static_yoink("usr/share/terminfo/w/wy85-w"); +__static_yoink("usr/share/terminfo/w/wyse325-vb"); +__static_yoink("usr/share/terminfo/w/wy370-rv"); +__static_yoink("usr/share/terminfo/w/wy520-wvb"); +__static_yoink("usr/share/terminfo/w/wy-99fgt"); +__static_yoink("usr/share/terminfo/w/wy99gt"); +__static_yoink("usr/share/terminfo/w/wy325-w"); +__static_yoink("usr/share/terminfo/w/wy160-vb"); +__static_yoink("usr/share/terminfo/w/wy85-wvb"); +__static_yoink("usr/share/terminfo/w/wy60-vb"); +__static_yoink("usr/share/terminfo/w/wy325-42w-vb"); +__static_yoink("usr/share/terminfo/w/wyse160"); +__static_yoink("usr/share/terminfo/w/wyse85-8bit"); +__static_yoink("usr/share/terminfo/w/wy370-nk"); +__static_yoink("usr/share/terminfo/w/wyse520-pc-24"); +__static_yoink("usr/share/terminfo/w/wyse99gt-25"); +__static_yoink("usr/share/terminfo/w/wyse99gt-w"); +__static_yoink("usr/share/terminfo/w/wy325-43wvb"); +__static_yoink("usr/share/terminfo/w/wy60-AT"); +__static_yoink("usr/share/terminfo/w/wyse-325"); +__static_yoink("usr/share/terminfo/w/wy99f"); +__static_yoink("usr/share/terminfo/w/wy185-24"); +__static_yoink("usr/share/terminfo/w/wyse30"); +__static_yoink("usr/share/terminfo/w/wyse520-36wpc"); +__static_yoink("usr/share/terminfo/w/wy520-48"); +__static_yoink("usr/share/terminfo/w/wy370-105k"); +__static_yoink("usr/share/terminfo/w/wy75ap"); +__static_yoink("usr/share/terminfo/w/wy120-25"); +__static_yoink("usr/share/terminfo/w/wyse75-mc"); +__static_yoink("usr/share/terminfo/w/wyse150-w"); +__static_yoink("usr/share/terminfo/w/wyse-75ap"); +__static_yoink("usr/share/terminfo/w/wyse325-wvb"); +__static_yoink("usr/share/terminfo/w/wyse99gt-wvb"); +__static_yoink("usr/share/terminfo/w/wyse520-48w"); +__static_yoink("usr/share/terminfo/w/wy60-25"); +__static_yoink("usr/share/terminfo/w/wy520-epc"); +__static_yoink("usr/share/terminfo/w/wyse150"); +__static_yoink("usr/share/terminfo/w/wy160-43-w"); +__static_yoink("usr/share/terminfo/w/wyse520"); +__static_yoink("usr/share/terminfo/w/wy99gt-25-w"); +__static_yoink("usr/share/terminfo/w/wyse99gt-25-w"); +__static_yoink("usr/share/terminfo/w/wy120-w"); +__static_yoink("usr/share/terminfo/w/wy370"); +__static_yoink("usr/share/terminfo/w/wyse30-mc"); +__static_yoink("usr/share/terminfo/w/wy185-wvb"); +__static_yoink("usr/share/terminfo/w/wy60-w-vb"); +__static_yoink("usr/share/terminfo/w/wy370-EPC"); +__static_yoink("usr/share/terminfo/w/wy99-ansi"); +__static_yoink("usr/share/terminfo/w/wy120"); +__static_yoink("usr/share/terminfo/w/wyse75-wvb"); +__static_yoink("usr/share/terminfo/w/wy50-mc"); +__static_yoink("usr/share/terminfo/w/wy325-wvb"); +__static_yoink("usr/share/terminfo/w/wy-99fgta"); +__static_yoink("usr/share/terminfo/w/wy150-25-w"); +__static_yoink("usr/share/terminfo/w/wy99gt-wvb"); +__static_yoink("usr/share/terminfo/w/wy160-25-w"); +__static_yoink("usr/share/terminfo/w/wy85"); +__static_yoink("usr/share/terminfo/w/wyse160-25-w"); +__static_yoink("usr/share/terminfo/w/wy150-vb"); +__static_yoink("usr/share/terminfo/w/wsvt25"); +__static_yoink("usr/share/terminfo/w/wyse120-wvb"); +__static_yoink("usr/share/terminfo/w/wyse60-AT"); +__static_yoink("usr/share/terminfo/w/wy30-mc"); +__static_yoink("usr/share/terminfo/w/wyse325-43w"); +__static_yoink("usr/share/terminfo/w/wy99fgt"); +__static_yoink("usr/share/terminfo/w/wy325-w-vb"); +__static_yoink("usr/share/terminfo/w/wy120-25-w"); +__static_yoink("usr/share/terminfo/w/wyse160-42"); +__static_yoink("usr/share/terminfo/w/wy520-epc-wvb"); +__static_yoink("usr/share/terminfo/w/wyse30-vb"); +__static_yoink("usr/share/terminfo/w/wy30"); +__static_yoink("usr/share/terminfo/w/wyse120-25"); +__static_yoink("usr/share/terminfo/w/wy60-PC"); +__static_yoink("usr/share/terminfo/w/wyse520-w"); +__static_yoink("usr/share/terminfo/w/wyse325-w"); +__static_yoink("usr/share/terminfo/w/wy60-wvb"); +__static_yoink("usr/share/terminfo/w/wyse160-vb"); +__static_yoink("usr/share/terminfo/w/wy60"); +__static_yoink("usr/share/terminfo/w/wyse520-36w"); +__static_yoink("usr/share/terminfo/w/wyse60-42-w"); +__static_yoink("usr/share/terminfo/w/wyse160-43"); +__static_yoink("usr/share/terminfo/w/wyse50"); +__static_yoink("usr/share/terminfo/w/wyse85-w"); +__static_yoink("usr/share/terminfo/6/605x"); +__static_yoink("usr/share/terminfo/6/605x-dg"); +__static_yoink("usr/share/terminfo/6/630-lm"); +__static_yoink("usr/share/terminfo/6/630MTG-24"); +__static_yoink("usr/share/terminfo/6/6053"); +__static_yoink("usr/share/terminfo/6/6053-dg"); +__static_yoink("usr/share/terminfo/7/730MTG-41"); +__static_yoink("usr/share/terminfo/7/730MTGr-24"); +__static_yoink("usr/share/terminfo/7/730MTG-24"); +__static_yoink("usr/share/terminfo/7/730MTG-41r"); +__static_yoink("usr/share/terminfo/7/730MTGr"); +__static_yoink("usr/share/terminfo/o/o31"); +__static_yoink("usr/share/terminfo/o/oabm85h"); +__static_yoink("usr/share/terminfo/o/osexec"); +__static_yoink("usr/share/terminfo/o/otek4112"); +__static_yoink("usr/share/terminfo/o/origpc3"); +__static_yoink("usr/share/terminfo/o/ojerq"); +__static_yoink("usr/share/terminfo/o/osborne-w"); +__static_yoink("usr/share/terminfo/o/opennt-25-nti"); +__static_yoink("usr/share/terminfo/o/opennt-60-w"); +__static_yoink("usr/share/terminfo/o/opennt-25-w"); +__static_yoink("usr/share/terminfo/o/oc100"); +__static_yoink("usr/share/terminfo/o/oldsun"); +__static_yoink("usr/share/terminfo/o/origibmpc3"); +__static_yoink("usr/share/terminfo/o/osborne"); +__static_yoink("usr/share/terminfo/o/otek4114"); +__static_yoink("usr/share/terminfo/o/osborne1-w"); +__static_yoink("usr/share/terminfo/o/oldibmpc3"); +__static_yoink("usr/share/terminfo/o/old-st"); +__static_yoink("usr/share/terminfo/o/opennt-35"); +__static_yoink("usr/share/terminfo/o/opennt-100"); +__static_yoink("usr/share/terminfo/o/opennt-50"); +__static_yoink("usr/share/terminfo/o/opennt-60-nti"); +__static_yoink("usr/share/terminfo/o/opennt-50-w"); +__static_yoink("usr/share/terminfo/o/opennt"); +__static_yoink("usr/share/terminfo/o/opennt-50-nti"); +__static_yoink("usr/share/terminfo/o/o4112-nd"); +__static_yoink("usr/share/terminfo/o/ofcons"); +__static_yoink("usr/share/terminfo/o/opennt-25"); +__static_yoink("usr/share/terminfo/o/omron"); +__static_yoink("usr/share/terminfo/o/owl"); +__static_yoink("usr/share/terminfo/o/opennt-25-w-vt"); +__static_yoink("usr/share/terminfo/o/oblit"); +__static_yoink("usr/share/terminfo/o/opennt-w"); +__static_yoink("usr/share/terminfo/o/oldpc3"); +__static_yoink("usr/share/terminfo/o/opennt-nti"); +__static_yoink("usr/share/terminfo/o/oconcept"); +__static_yoink("usr/share/terminfo/o/opus3n1+"); +__static_yoink("usr/share/terminfo/o/opennt-w-vt"); +__static_yoink("usr/share/terminfo/o/o85h"); +__static_yoink("usr/share/terminfo/o/opennt-35-nti"); +__static_yoink("usr/share/terminfo/o/otek4113"); +__static_yoink("usr/share/terminfo/o/os9LII"); +__static_yoink("usr/share/terminfo/o/opennt-100-nti"); +__static_yoink("usr/share/terminfo/o/otek4115"); +__static_yoink("usr/share/terminfo/o/opennt-60"); +__static_yoink("usr/share/terminfo/o/osborne1"); +__static_yoink("usr/share/terminfo/o/opennt-35-w"); +__static_yoink("usr/share/terminfo/n/nsterm-acs-c-s"); +__static_yoink("usr/share/terminfo/n/nec"); +__static_yoink("usr/share/terminfo/n/ncr160vt100pp"); +__static_yoink("usr/share/terminfo/n/nsterm-s-acs"); +__static_yoink("usr/share/terminfo/n/news-42-sjis"); +__static_yoink("usr/share/terminfo/n/nec5520"); +__static_yoink("usr/share/terminfo/n/nsterm-m-s-7"); +__static_yoink("usr/share/terminfo/n/nsterm-acs-s"); +__static_yoink("usr/share/terminfo/n/nsterm-build326"); +__static_yoink("usr/share/terminfo/n/ncr260vt300an"); +__static_yoink("usr/share/terminfo/n/ndr9500-25-mc"); +__static_yoink("usr/share/terminfo/n/news-33-sjis"); +__static_yoink("usr/share/terminfo/n/ncsa"); +__static_yoink("usr/share/terminfo/n/nsterm-7-m"); +__static_yoink("usr/share/terminfo/n/ncr260vt100wan"); +__static_yoink("usr/share/terminfo/n/ndr9500-25-mc-nl"); +__static_yoink("usr/share/terminfo/n/nsterm-m-s"); +__static_yoink("usr/share/terminfo/n/ncr260wy350wpp"); +__static_yoink("usr/share/terminfo/n/ncr260wy60pp"); +__static_yoink("usr/share/terminfo/n/ncr160vt200pp"); +__static_yoink("usr/share/terminfo/n/nwe501-a"); +__static_yoink("usr/share/terminfo/n/nwp514-a"); +__static_yoink("usr/share/terminfo/n/nsterm-256color"); +__static_yoink("usr/share/terminfo/n/ncr260vt200wpp"); +__static_yoink("usr/share/terminfo/n/ncr260intwan"); +__static_yoink("usr/share/terminfo/n/nsterm"); +__static_yoink("usr/share/terminfo/n/ntconsole-25-w-vt"); +__static_yoink("usr/share/terminfo/n/nsterm-c-7"); +__static_yoink("usr/share/terminfo/n/ndr9500-25"); +__static_yoink("usr/share/terminfo/n/ncr7901"); +__static_yoink("usr/share/terminfo/n/ncr260vt200an"); +__static_yoink("usr/share/terminfo/n/nwp514-o"); +__static_yoink("usr/share/terminfo/n/nansi.sys"); +__static_yoink("usr/share/terminfo/n/ncr260intwpp"); +__static_yoink("usr/share/terminfo/n/nsterm-build440"); +__static_yoink("usr/share/terminfo/n/northstar"); +__static_yoink("usr/share/terminfo/n/ncr160wy50+pp"); +__static_yoink("usr/share/terminfo/n/nsterm-build361"); +__static_yoink("usr/share/terminfo/n/nwp512"); +__static_yoink("usr/share/terminfo/n/ncr260vppp"); +__static_yoink("usr/share/terminfo/n/ntconsole-35-w"); +__static_yoink("usr/share/terminfo/n/news33"); +__static_yoink("usr/share/terminfo/n/ntconsole-35-nti"); +__static_yoink("usr/share/terminfo/n/ncr160vt300an"); +__static_yoink("usr/share/terminfo/n/ncr160vt200an"); +__static_yoink("usr/share/terminfo/n/nsterm-7"); +__static_yoink("usr/share/terminfo/n/nextshell"); +__static_yoink("usr/share/terminfo/n/ntconsole-25"); +__static_yoink("usr/share/terminfo/n/news40-a"); +__static_yoink("usr/share/terminfo/n/ncr260wy325pp"); +__static_yoink("usr/share/terminfo/n/ncr260vt100an"); +__static_yoink("usr/share/terminfo/n/ntconsole-60-w"); +__static_yoink("usr/share/terminfo/n/news-old-unk"); +__static_yoink("usr/share/terminfo/n/ntconsole-50-w"); +__static_yoink("usr/share/terminfo/n/nsterm+c"); +__static_yoink("usr/share/terminfo/n/ncr160vt200wpp"); +__static_yoink("usr/share/terminfo/n/news-42-euc"); +__static_yoink("usr/share/terminfo/n/ncr260vt300pp"); +__static_yoink("usr/share/terminfo/n/nsterm-acs"); +__static_yoink("usr/share/terminfo/n/nsterm+7"); +__static_yoink("usr/share/terminfo/n/ntconsole-60"); +__static_yoink("usr/share/terminfo/n/ncr260vpwpp"); +__static_yoink("usr/share/terminfo/n/ntconsole-50-nti"); +__static_yoink("usr/share/terminfo/n/nsterm-c-acs"); +__static_yoink("usr/share/terminfo/n/ntconsole-w"); +__static_yoink("usr/share/terminfo/n/next"); +__static_yoink("usr/share/terminfo/n/ntconsole"); +__static_yoink("usr/share/terminfo/n/ncrvt100an"); +__static_yoink("usr/share/terminfo/n/ncsa-vt220-8"); +__static_yoink("usr/share/terminfo/n/nsterm-acs-c"); +__static_yoink("usr/share/terminfo/n/nwp511"); +__static_yoink("usr/share/terminfo/n/ncr160vt300pp"); +__static_yoink("usr/share/terminfo/n/ncsa-m-ns"); +__static_yoink("usr/share/terminfo/n/n7900"); +__static_yoink("usr/share/terminfo/n/news40"); +__static_yoink("usr/share/terminfo/n/ncr260intpp"); +__static_yoink("usr/share/terminfo/n/nwp518"); +__static_yoink("usr/share/terminfo/n/nsterm-acs-m"); +__static_yoink("usr/share/terminfo/n/ncr260wy50+wpp"); +__static_yoink("usr/share/terminfo/n/ndr9500-mc-nl"); +__static_yoink("usr/share/terminfo/n/nansi.sysk"); +__static_yoink("usr/share/terminfo/n/newscbm"); +__static_yoink("usr/share/terminfo/n/ncr7900iv"); +__static_yoink("usr/share/terminfo/n/nsterm-c-s-acs"); +__static_yoink("usr/share/terminfo/n/ndr9500"); +__static_yoink("usr/share/terminfo/n/nsterm-bce"); +__static_yoink("usr/share/terminfo/n/no+brackets"); +__static_yoink("usr/share/terminfo/n/nsterm+c41"); +__static_yoink("usr/share/terminfo/n/ntconsole-25-w"); +__static_yoink("usr/share/terminfo/n/nsterm-m-s-acs"); +__static_yoink("usr/share/terminfo/n/nsterm-c-s-7"); +__static_yoink("usr/share/terminfo/n/news42"); +__static_yoink("usr/share/terminfo/n/nsterm-old"); +__static_yoink("usr/share/terminfo/n/ncr260vt100wpp"); +__static_yoink("usr/share/terminfo/n/ntconsole-25-nti"); +__static_yoink("usr/share/terminfo/n/nwp518-o"); +__static_yoink("usr/share/terminfo/n/news-unk"); +__static_yoink("usr/share/terminfo/n/nwp513"); +__static_yoink("usr/share/terminfo/n/nd9500"); +__static_yoink("usr/share/terminfo/n/nwp517"); +__static_yoink("usr/share/terminfo/n/nwe501"); +__static_yoink("usr/share/terminfo/n/nsterm-direct"); +__static_yoink("usr/share/terminfo/n/nwp512-a"); +__static_yoink("usr/share/terminfo/n/ntconsole-35"); +__static_yoink("usr/share/terminfo/n/ncr160vpwpp"); +__static_yoink("usr/share/terminfo/n/ncr260wy350pp"); +__static_yoink("usr/share/terminfo/n/nsterm-7-c"); +__static_yoink("usr/share/terminfo/n/ncr260intan"); +__static_yoink("usr/share/terminfo/n/newhpkeyboard"); +__static_yoink("usr/share/terminfo/n/nsterm-7-c-s"); +__static_yoink("usr/share/terminfo/n/ncr160vt300wpp"); +__static_yoink("usr/share/terminfo/n/nsterm-build309"); +__static_yoink("usr/share/terminfo/n/ncr160vt100an"); +__static_yoink("usr/share/terminfo/n/ncsa-m"); +__static_yoink("usr/share/terminfo/n/ncrvt100wan"); +__static_yoink("usr/share/terminfo/n/nsterm-c"); +__static_yoink("usr/share/terminfo/n/ncr160vt200wan"); +__static_yoink("usr/share/terminfo/n/nsterm-m-7"); +__static_yoink("usr/share/terminfo/n/ntconsole-w-vt"); +__static_yoink("usr/share/terminfo/n/ncr7900"); +__static_yoink("usr/share/terminfo/n/news-29-sjis"); +__static_yoink("usr/share/terminfo/n/news-o"); +__static_yoink("usr/share/terminfo/n/ncr260vt100pp"); +__static_yoink("usr/share/terminfo/n/ncr160wy60pp"); +__static_yoink("usr/share/terminfo/n/ndr9500-25-nl"); +__static_yoink("usr/share/terminfo/n/news40-o"); +__static_yoink("usr/share/terminfo/n/ncr260vt200wan"); +__static_yoink("usr/share/terminfo/n/ncr160vt100wan"); +__static_yoink("usr/share/terminfo/n/ndr9500-mc"); +__static_yoink("usr/share/terminfo/n/news31-a"); +__static_yoink("usr/share/terminfo/n/netbsd6"); +__static_yoink("usr/share/terminfo/n/ntconsole-100-nti"); +__static_yoink("usr/share/terminfo/n/news-33"); +__static_yoink("usr/share/terminfo/n/nwe501-o"); +__static_yoink("usr/share/terminfo/n/ncr7900i"); +__static_yoink("usr/share/terminfo/n/news-29"); +__static_yoink("usr/share/terminfo/n/nsterm-c-s"); +__static_yoink("usr/share/terminfo/n/nsterm-7-m-s"); +__static_yoink("usr/share/terminfo/n/ndr9500-nl"); +__static_yoink("usr/share/terminfo/n/ncrvt100wpp"); +__static_yoink("usr/share/terminfo/n/nsterm-7-s"); +__static_yoink("usr/share/terminfo/n/news28-a"); +__static_yoink("usr/share/terminfo/n/nsterm-m-acs"); +__static_yoink("usr/share/terminfo/n/newhp"); +__static_yoink("usr/share/terminfo/n/ncr160vppp"); +__static_yoink("usr/share/terminfo/n/nwp512-o"); +__static_yoink("usr/share/terminfo/n/ncr260wy60wpp"); +__static_yoink("usr/share/terminfo/n/nsterm-build400"); +__static_yoink("usr/share/terminfo/n/news31"); +__static_yoink("usr/share/terminfo/n/newscbm-a"); +__static_yoink("usr/share/terminfo/n/news29"); +__static_yoink("usr/share/terminfo/n/ncr160vt100wpp"); +__static_yoink("usr/share/terminfo/n/nwp-517-w"); +__static_yoink("usr/share/terminfo/n/ncrvt100pp"); +__static_yoink("usr/share/terminfo/n/nsterm-acs-m-s"); +__static_yoink("usr/share/terminfo/n/nsterm-16color"); +__static_yoink("usr/share/terminfo/n/nsterm+s"); +__static_yoink("usr/share/terminfo/n/nsterm+mac"); +__static_yoink("usr/share/terminfo/n/nwp-511"); +__static_yoink("usr/share/terminfo/n/news-33-euc"); +__static_yoink("usr/share/terminfo/n/nansisysk"); +__static_yoink("usr/share/terminfo/n/ntconsole-50"); +__static_yoink("usr/share/terminfo/n/news-29-euc"); +__static_yoink("usr/share/terminfo/n/nsterm-s"); +__static_yoink("usr/share/terminfo/n/news-a"); +__static_yoink("usr/share/terminfo/n/ncr260vt+sl"); +__static_yoink("usr/share/terminfo/n/nwp513-a"); +__static_yoink("usr/share/terminfo/n/ncr160wy50+wpp"); +__static_yoink("usr/share/terminfo/n/ncr260vt300wpp"); +__static_yoink("usr/share/terminfo/n/news31-o"); +__static_yoink("usr/share/terminfo/n/news-42"); +__static_yoink("usr/share/terminfo/n/ncr260wy50+pp"); +__static_yoink("usr/share/terminfo/n/nsterm-m"); +__static_yoink("usr/share/terminfo/n/nwp251-o"); +__static_yoink("usr/share/terminfo/n/nsterm+acs"); +__static_yoink("usr/share/terminfo/n/ncsa-vt220"); +__static_yoink("usr/share/terminfo/n/ncr260vt200pp"); +__static_yoink("usr/share/terminfo/n/nxterm"); +__static_yoink("usr/share/terminfo/n/news28"); +__static_yoink("usr/share/terminfo/n/nsterm-s-7"); +__static_yoink("usr/share/terminfo/n/newscbm33"); +__static_yoink("usr/share/terminfo/n/ncr160vt300wan"); +__static_yoink("usr/share/terminfo/n/ncr260wy325wpp"); +__static_yoink("usr/share/terminfo/n/nwp514"); +__static_yoink("usr/share/terminfo/n/ncr260vt300wan"); +__static_yoink("usr/share/terminfo/n/newscbm-o"); +__static_yoink("usr/share/terminfo/n/ncsa-ns"); +__static_yoink("usr/share/terminfo/n/nsterm-build343"); +__static_yoink("usr/share/terminfo/n/nwp513-o"); +__static_yoink("usr/share/terminfo/n/news"); +__static_yoink("usr/share/terminfo/n/ntconsole-100"); +__static_yoink("usr/share/terminfo/n/nwp517-w"); +__static_yoink("usr/share/terminfo/n/ncr260vp+sl"); +__static_yoink("usr/share/terminfo/n/nansisys"); +__static_yoink("usr/share/terminfo/n/nwp-517"); +__static_yoink("usr/share/terminfo/n/nwp518-a"); +__static_yoink("usr/share/terminfo/n/ncr160wy60wpp"); +__static_yoink("usr/share/terminfo/n/nwp251-a"); +__static_yoink("usr/share/terminfo/n/ntconsole-60-nti"); +__static_yoink("usr/share/terminfo/E/Eterm"); +__static_yoink("usr/share/terminfo/E/Eterm-88color"); +__static_yoink("usr/share/terminfo/E/Eterm-256color"); +__static_yoink("usr/share/terminfo/E/Eterm-color"); +__static_yoink("usr/share/terminfo/A/Apple_Terminal"); +__static_yoink("usr/share/terminfo/M/MtxOrb204"); +__static_yoink("usr/share/terminfo/M/MtxOrb162"); +__static_yoink("usr/share/terminfo/M/MtxOrb"); +__static_yoink("usr/share/terminfo/d/dg450"); +__static_yoink("usr/share/terminfo/d/diablo"); +__static_yoink("usr/share/terminfo/d/dgmode+color"); +__static_yoink("usr/share/terminfo/d/d215-dg"); +__static_yoink("usr/share/terminfo/d/d555-w"); +__static_yoink("usr/share/terminfo/d/dg+fixed"); +__static_yoink("usr/share/terminfo/d/d2-dg"); +__static_yoink("usr/share/terminfo/d/d430-unix"); +__static_yoink("usr/share/terminfo/d/d216-dg"); +__static_yoink("usr/share/terminfo/d/d430-unix-sr-ccc"); +__static_yoink("usr/share/terminfo/d/d460-7b-w"); +__static_yoink("usr/share/terminfo/d/dg100"); +__static_yoink("usr/share/terminfo/d/d430-unix-w"); +__static_yoink("usr/share/terminfo/d/dialogue"); +__static_yoink("usr/share/terminfo/d/d430c-unix-25-ccc"); +__static_yoink("usr/share/terminfo/d/darwin-256x96"); +__static_yoink("usr/share/terminfo/d/d216e+dg"); +__static_yoink("usr/share/terminfo/d/ds40-2"); +__static_yoink("usr/share/terminfo/d/d216+"); +__static_yoink("usr/share/terminfo/d/d430-unix-25"); +__static_yoink("usr/share/terminfo/d/dmd-24"); +__static_yoink("usr/share/terminfo/d/decansi"); +__static_yoink("usr/share/terminfo/d/dt100"); +__static_yoink("usr/share/terminfo/d/dg6134"); +__static_yoink("usr/share/terminfo/d/d555-7b-w"); +__static_yoink("usr/share/terminfo/d/d461"); +__static_yoink("usr/share/terminfo/d/d412+25"); +__static_yoink("usr/share/terminfo/d/d411-7b-w"); +__static_yoink("usr/share/terminfo/d/darwin-f2"); +__static_yoink("usr/share/terminfo/d/diablo-lm"); +__static_yoink("usr/share/terminfo/d/darwin-128x48-m"); +__static_yoink("usr/share/terminfo/d/d577-7b-w"); +__static_yoink("usr/share/terminfo/d/d400"); +__static_yoink("usr/share/terminfo/d/dg6053"); +__static_yoink("usr/share/terminfo/d/dtc382"); +__static_yoink("usr/share/terminfo/d/dg+color8"); +__static_yoink("usr/share/terminfo/d/d414-unix-sr"); +__static_yoink("usr/share/terminfo/d/d216-unix"); +__static_yoink("usr/share/terminfo/d/darwin-m-b"); +__static_yoink("usr/share/terminfo/d/datagraphix"); +__static_yoink("usr/share/terminfo/d/dt110"); +__static_yoink("usr/share/terminfo/d/d412+s"); +__static_yoink("usr/share/terminfo/d/d460"); +__static_yoink("usr/share/terminfo/d/d216+25"); +__static_yoink("usr/share/terminfo/d/darwin-100x37"); +__static_yoink("usr/share/terminfo/d/ds40"); +__static_yoink("usr/share/terminfo/d/dku7202"); +__static_yoink("usr/share/terminfo/d/darwin-112x37-m"); +__static_yoink("usr/share/terminfo/d/d430c-unix-s"); +__static_yoink("usr/share/terminfo/d/d2"); +__static_yoink("usr/share/terminfo/d/d461-dg"); +__static_yoink("usr/share/terminfo/d/dtc300s"); +__static_yoink("usr/share/terminfo/d/darwin-90x30"); +__static_yoink("usr/share/terminfo/d/d430c-unix-w"); +__static_yoink("usr/share/terminfo/d/d80"); +__static_yoink("usr/share/terminfo/d/d430-unix-w-ccc"); +__static_yoink("usr/share/terminfo/d/d430c-unix-s-ccc"); +__static_yoink("usr/share/terminfo/d/d430-dg-ccc"); +__static_yoink("usr/share/terminfo/d/darwin-m"); +__static_yoink("usr/share/terminfo/d/d412-unix-25"); +__static_yoink("usr/share/terminfo/d/dg460-ansi"); +__static_yoink("usr/share/terminfo/d/dmdt80w"); +__static_yoink("usr/share/terminfo/d/dmd"); +__static_yoink("usr/share/terminfo/d/d462-unix-w"); +__static_yoink("usr/share/terminfo/d/decwriter"); +__static_yoink("usr/share/terminfo/d/d430c-unix-w-ccc"); +__static_yoink("usr/share/terminfo/d/d460-w"); +__static_yoink("usr/share/terminfo/d/d413-dg"); +__static_yoink("usr/share/terminfo/d/d464-unix-25"); +__static_yoink("usr/share/terminfo/d/darwin-m-f"); +__static_yoink("usr/share/terminfo/d/darwin-90x30-m"); +__static_yoink("usr/share/terminfo/d/d577"); +__static_yoink("usr/share/terminfo/d/dec-vt340"); +__static_yoink("usr/share/terminfo/d/dw3"); +__static_yoink("usr/share/terminfo/d/darwin-200x64"); +__static_yoink("usr/share/terminfo/d/d463-unix-w"); +__static_yoink("usr/share/terminfo/d/diablo1720"); +__static_yoink("usr/share/terminfo/d/d411-7b"); +__static_yoink("usr/share/terminfo/d/darwin-200x75-m"); +__static_yoink("usr/share/terminfo/d/d132"); +__static_yoink("usr/share/terminfo/d/dp3360"); +__static_yoink("usr/share/terminfo/d/d464-unix-w"); +__static_yoink("usr/share/terminfo/d/d461-7b-w"); +__static_yoink("usr/share/terminfo/d/d215"); +__static_yoink("usr/share/terminfo/d/d430c-unix"); +__static_yoink("usr/share/terminfo/d/d577-w"); +__static_yoink("usr/share/terminfo/d/d214"); +__static_yoink("usr/share/terminfo/d/d413-unix-25"); +__static_yoink("usr/share/terminfo/d/d430c-unix-ccc"); +__static_yoink("usr/share/terminfo/d/dvtm"); +__static_yoink("usr/share/terminfo/d/digilog"); +__static_yoink("usr/share/terminfo/d/darwin-f"); +__static_yoink("usr/share/terminfo/d/d217-unix"); +__static_yoink("usr/share/terminfo/d/dp8242"); +__static_yoink("usr/share/terminfo/d/djgpp203"); +__static_yoink("usr/share/terminfo/d/dmd1"); +__static_yoink("usr/share/terminfo/d/decid+cpr"); +__static_yoink("usr/share/terminfo/d/d210-dg"); +__static_yoink("usr/share/terminfo/d/d400-dg"); +__static_yoink("usr/share/terminfo/d/darwin-200x75"); +__static_yoink("usr/share/terminfo/d/dg605x"); +__static_yoink("usr/share/terminfo/d/datapoint"); +__static_yoink("usr/share/terminfo/d/darwin-80x25-m"); +__static_yoink("usr/share/terminfo/d/dg6053-old"); +__static_yoink("usr/share/terminfo/d/darwin-80x30-m"); +__static_yoink("usr/share/terminfo/d/d462-unix-25"); +__static_yoink("usr/share/terminfo/d/d216e-dg"); +__static_yoink("usr/share/terminfo/d/d430-unix-s-ccc"); +__static_yoink("usr/share/terminfo/d/darwin-160x64-m"); +__static_yoink("usr/share/terminfo/d/d214-dg"); +__static_yoink("usr/share/terminfo/d/d220"); +__static_yoink("usr/share/terminfo/d/dw4"); +__static_yoink("usr/share/terminfo/d/d211"); +__static_yoink("usr/share/terminfo/d/diablo1730"); +__static_yoink("usr/share/terminfo/d/diablo1640"); +__static_yoink("usr/share/terminfo/d/dt80-sas"); +__static_yoink("usr/share/terminfo/d/d470"); +__static_yoink("usr/share/terminfo/d/dm80w"); +__static_yoink("usr/share/terminfo/d/dw2"); +__static_yoink("usr/share/terminfo/d/d461-7b"); +__static_yoink("usr/share/terminfo/d/dku7102-sna"); +__static_yoink("usr/share/terminfo/d/d211-dg"); +__static_yoink("usr/share/terminfo/d/dg+ccc"); +__static_yoink("usr/share/terminfo/d/d414-unix"); +__static_yoink("usr/share/terminfo/d/dt100w"); +__static_yoink("usr/share/terminfo/d/darwin-144x48-m"); +__static_yoink("usr/share/terminfo/d/dt80"); +__static_yoink("usr/share/terminfo/d/darwin-200x64-m"); +__static_yoink("usr/share/terminfo/d/darwin-256x96-m"); +__static_yoink("usr/share/terminfo/d/d414-unix-w"); +__static_yoink("usr/share/terminfo/d/d578-dg"); +__static_yoink("usr/share/terminfo/d/dgunix+ccc"); +__static_yoink("usr/share/terminfo/d/dwk-vt"); +__static_yoink("usr/share/terminfo/d/darwin-80x30"); +__static_yoink("usr/share/terminfo/d/diablo1740"); +__static_yoink("usr/share/terminfo/d/d217-dg"); +__static_yoink("usr/share/terminfo/d/d462+sr"); +__static_yoink("usr/share/terminfo/d/d211-7b"); +__static_yoink("usr/share/terminfo/d/diablo1640-lm"); +__static_yoink("usr/share/terminfo/d/diablo630"); +__static_yoink("usr/share/terminfo/d/dgkeys+11"); +__static_yoink("usr/share/terminfo/d/dvtm-256color"); +__static_yoink("usr/share/terminfo/d/d412-unix"); +__static_yoink("usr/share/terminfo/d/dku7003-dumb"); +__static_yoink("usr/share/terminfo/d/domterm"); +__static_yoink("usr/share/terminfo/d/d412+w"); +__static_yoink("usr/share/terminfo/d/d412-dg"); +__static_yoink("usr/share/terminfo/d/d555"); +__static_yoink("usr/share/terminfo/d/diablo1620-m8"); +__static_yoink("usr/share/terminfo/d/d230"); +__static_yoink("usr/share/terminfo/d/d412+dg"); +__static_yoink("usr/share/terminfo/d/d412-unix-sr"); +__static_yoink("usr/share/terminfo/d/d462-unix-s"); +__static_yoink("usr/share/terminfo/d/dm3025"); +__static_yoink("usr/share/terminfo/d/dg211"); +__static_yoink("usr/share/terminfo/d/darwin-80x25"); +__static_yoink("usr/share/terminfo/d/d470-dg"); +__static_yoink("usr/share/terminfo/d/dt-100w"); +__static_yoink("usr/share/terminfo/d/dg-generic"); +__static_yoink("usr/share/terminfo/d/dmd-34"); +__static_yoink("usr/share/terminfo/d/d470-7b"); +__static_yoink("usr/share/terminfo/d/d413-unix-s"); +__static_yoink("usr/share/terminfo/d/darwin-b"); +__static_yoink("usr/share/terminfo/d/ddr"); +__static_yoink("usr/share/terminfo/d/d200-dg"); +__static_yoink("usr/share/terminfo/d/d414-unix-25"); +__static_yoink("usr/share/terminfo/d/d411-w"); +__static_yoink("usr/share/terminfo/d/d464-unix"); +__static_yoink("usr/share/terminfo/d/d216e-unix"); +__static_yoink("usr/share/terminfo/d/d430c-unix-sr-ccc"); +__static_yoink("usr/share/terminfo/d/dmdt80"); +__static_yoink("usr/share/terminfo/d/d411-dg"); +__static_yoink("usr/share/terminfo/d/dg200"); +__static_yoink("usr/share/terminfo/d/d412+"); +__static_yoink("usr/share/terminfo/d/d412-unix-w"); +__static_yoink("usr/share/terminfo/d/dku7103-sna"); +__static_yoink("usr/share/terminfo/d/dgmode+color8"); +__static_yoink("usr/share/terminfo/d/dw1"); +__static_yoink("usr/share/terminfo/d/dd5000"); +__static_yoink("usr/share/terminfo/d/d460-dg"); +__static_yoink("usr/share/terminfo/d/djgpp204"); +__static_yoink("usr/share/terminfo/d/d470c"); +__static_yoink("usr/share/terminfo/d/d464-unix-sr"); +__static_yoink("usr/share/terminfo/d/diablo1620"); +__static_yoink("usr/share/terminfo/d/dec-vt330"); +__static_yoink("usr/share/terminfo/d/darwin-128x48"); +__static_yoink("usr/share/terminfo/d/diablo1640-m8"); +__static_yoink("usr/share/terminfo/d/d410-7b-w"); +__static_yoink("usr/share/terminfo/d/d230c-dg"); +__static_yoink("usr/share/terminfo/d/d462-dg"); +__static_yoink("usr/share/terminfo/d/dku7003"); +__static_yoink("usr/share/terminfo/d/d216+dg"); +__static_yoink("usr/share/terminfo/d/d461-w"); +__static_yoink("usr/share/terminfo/d/darwin-160x64"); +__static_yoink("usr/share/terminfo/d/dt-100"); +__static_yoink("usr/share/terminfo/d/d430c-dg"); +__static_yoink("usr/share/terminfo/d/diablo450"); +__static_yoink("usr/share/terminfo/d/d470c-7b"); +__static_yoink("usr/share/terminfo/d/dku7102-old"); +__static_yoink("usr/share/terminfo/d/dm2500"); +__static_yoink("usr/share/terminfo/d/dgkeys+15"); +__static_yoink("usr/share/terminfo/d/d410-7b"); +__static_yoink("usr/share/terminfo/d/dm1520"); +__static_yoink("usr/share/terminfo/d/datamedia2500"); +__static_yoink("usr/share/terminfo/d/d463-dg"); +__static_yoink("usr/share/terminfo/d/diablo1740-lm"); +__static_yoink("usr/share/terminfo/d/d216-unix-25"); +__static_yoink("usr/share/terminfo/d/d462-unix"); +__static_yoink("usr/share/terminfo/d/d462+"); +__static_yoink("usr/share/terminfo/d/darwin-100x37-m"); +__static_yoink("usr/share/terminfo/d/dw"); +__static_yoink("usr/share/terminfo/d/d578-7b"); +__static_yoink("usr/share/terminfo/d/dumb-emacs-ansi"); +__static_yoink("usr/share/terminfo/d/dataspeed40"); +__static_yoink("usr/share/terminfo/d/d430c-unix-25"); +__static_yoink("usr/share/terminfo/d/d215-7b"); +__static_yoink("usr/share/terminfo/d/dgunix+fixed"); +__static_yoink("usr/share/terminfo/d/dm3045"); +__static_yoink("usr/share/terminfo/d/dec-vt220"); +__static_yoink("usr/share/terminfo/d/d800"); +__static_yoink("usr/share/terminfo/d/dtterm"); +__static_yoink("usr/share/terminfo/d/dwk"); +__static_yoink("usr/share/terminfo/d/d430-unix-sr"); +__static_yoink("usr/share/terminfo/d/dg-ansi"); +__static_yoink("usr/share/terminfo/d/dg210"); +__static_yoink("usr/share/terminfo/d/darwin-144x48"); +__static_yoink("usr/share/terminfo/d/d555-dg"); +__static_yoink("usr/share/terminfo/d/d462+s"); +__static_yoink("usr/share/terminfo/d/d217-unix-25"); +__static_yoink("usr/share/terminfo/d/d430c-unix-sr"); +__static_yoink("usr/share/terminfo/d/d462+w"); +__static_yoink("usr/share/terminfo/d/dec-vt400"); +__static_yoink("usr/share/terminfo/d/d463-unix-s"); +__static_yoink("usr/share/terminfo/d/d470c-dg"); +__static_yoink("usr/share/terminfo/d/d463-unix"); +__static_yoink("usr/share/terminfo/d/d411"); +__static_yoink("usr/share/terminfo/d/d200"); +__static_yoink("usr/share/terminfo/d/decpro"); +__static_yoink("usr/share/terminfo/d/d413-unix-sr"); +__static_yoink("usr/share/terminfo/d/djgpp"); +__static_yoink("usr/share/terminfo/d/d462+dg"); +__static_yoink("usr/share/terminfo/d/d413-unix-w"); +__static_yoink("usr/share/terminfo/d/d410-dg"); +__static_yoink("usr/share/terminfo/d/d577-7b"); +__static_yoink("usr/share/terminfo/d/d450"); +__static_yoink("usr/share/terminfo/d/dumb"); +__static_yoink("usr/share/terminfo/d/d430-unix-s"); +__static_yoink("usr/share/terminfo/d/darwin"); +__static_yoink("usr/share/terminfo/d/d430-unix-25-ccc"); +__static_yoink("usr/share/terminfo/d/d464-unix-s"); +__static_yoink("usr/share/terminfo/d/d578"); +__static_yoink("usr/share/terminfo/d/d230c"); +__static_yoink("usr/share/terminfo/d/dg+color"); +__static_yoink("usr/share/terminfo/d/d230-dg"); +__static_yoink("usr/share/terminfo/d/d462e-dg"); +__static_yoink("usr/share/terminfo/d/d410-w"); +__static_yoink("usr/share/terminfo/d/dgkeys+7b"); +__static_yoink("usr/share/terminfo/d/dec+sl"); +__static_yoink("usr/share/terminfo/d/dmchat"); +__static_yoink("usr/share/terminfo/d/d463-unix-sr"); +__static_yoink("usr/share/terminfo/d/d462-unix-sr"); +__static_yoink("usr/share/terminfo/d/d430-unix-ccc"); +__static_yoink("usr/share/terminfo/d/delta"); +__static_yoink("usr/share/terminfo/d/dec+pp"); +__static_yoink("usr/share/terminfo/d/d430-dg"); +__static_yoink("usr/share/terminfo/d/d414-unix-s"); +__static_yoink("usr/share/terminfo/d/d460-7b"); +__static_yoink("usr/share/terminfo/d/dec-vt100"); +__static_yoink("usr/share/terminfo/d/d413-unix"); +__static_yoink("usr/share/terminfo/d/dm80"); +__static_yoink("usr/share/terminfo/d/dgkeys+8b"); +__static_yoink("usr/share/terminfo/d/d220-dg"); +__static_yoink("usr/share/terminfo/d/d577-dg"); +__static_yoink("usr/share/terminfo/d/darwin-112x37"); +__static_yoink("usr/share/terminfo/d/d430c-dg-ccc"); +__static_yoink("usr/share/terminfo/d/ddr3180"); +__static_yoink("usr/share/terminfo/d/darwin-128x40"); +__static_yoink("usr/share/terminfo/d/darwin-m-f2"); +__static_yoink("usr/share/terminfo/d/dm1521"); +__static_yoink("usr/share/terminfo/d/d450-dg"); +__static_yoink("usr/share/terminfo/d/d220-7b"); +__static_yoink("usr/share/terminfo/d/dialogue80"); +__static_yoink("usr/share/terminfo/d/d410"); +__static_yoink("usr/share/terminfo/d/dmterm"); +__static_yoink("usr/share/terminfo/d/d462+25"); +__static_yoink("usr/share/terminfo/d/d555-7b"); +__static_yoink("usr/share/terminfo/d/dt80w"); +__static_yoink("usr/share/terminfo/d/d463-unix-25"); +__static_yoink("usr/share/terminfo/d/d412+sr"); +__static_yoink("usr/share/terminfo/d/darwin-128x40-m"); +__static_yoink("usr/share/terminfo/d/d210"); +__static_yoink("usr/share/terminfo/d/d216e+"); +__static_yoink("usr/share/terminfo/d/d412-unix-s"); +__static_yoink("usr/share/terminfo/d/dku7102"); +__static_yoink("usr/share/terminfo/L/LFT-PC850"); +__static_yoink("usr/share/terminfo/8/8510"); +__static_yoink("usr/share/terminfo/p/pcvt25"); +__static_yoink("usr/share/terminfo/p/psterm-fast"); +__static_yoink("usr/share/terminfo/p/pt100"); +__static_yoink("usr/share/terminfo/p/p9-w"); +__static_yoink("usr/share/terminfo/p/pro350"); +__static_yoink("usr/share/terminfo/p/pccon+base"); +__static_yoink("usr/share/terminfo/p/putty-m1b"); +__static_yoink("usr/share/terminfo/p/prism8-w"); +__static_yoink("usr/share/terminfo/p/pt200w"); +__static_yoink("usr/share/terminfo/p/putty+fnkeys+vt100"); +__static_yoink("usr/share/terminfo/p/pt505-22"); +__static_yoink("usr/share/terminfo/p/putty-sco"); +__static_yoink("usr/share/terminfo/p/pcconsole"); +__static_yoink("usr/share/terminfo/p/prism14"); +__static_yoink("usr/share/terminfo/p/pcansi-m"); +__static_yoink("usr/share/terminfo/p/prism12-m-w"); +__static_yoink("usr/share/terminfo/p/pcvt50w"); +__static_yoink("usr/share/terminfo/p/pcansi25m"); +__static_yoink("usr/share/terminfo/p/putty-256color"); +__static_yoink("usr/share/terminfo/p/pcvtXX"); +__static_yoink("usr/share/terminfo/p/prism2"); +__static_yoink("usr/share/terminfo/p/pccon"); +__static_yoink("usr/share/terminfo/p/pe550"); +__static_yoink("usr/share/terminfo/p/putty+fnkeys+esc"); +__static_yoink("usr/share/terminfo/p/putty+fnkeys+sco"); +__static_yoink("usr/share/terminfo/p/prism7"); +__static_yoink("usr/share/terminfo/p/putty+fnkeys+vt400"); +__static_yoink("usr/share/terminfo/p/putty-m2"); +__static_yoink("usr/share/terminfo/p/pcix"); +__static_yoink("usr/share/terminfo/p/pe6100"); +__static_yoink("usr/share/terminfo/p/putty+screen"); +__static_yoink("usr/share/terminfo/p/p19"); +__static_yoink("usr/share/terminfo/p/putty-noapp"); +__static_yoink("usr/share/terminfo/p/pt505"); +__static_yoink("usr/share/terminfo/p/prism9-8"); +__static_yoink("usr/share/terminfo/p/prism12-w"); +__static_yoink("usr/share/terminfo/p/pcvt35w"); +__static_yoink("usr/share/terminfo/p/pc3"); +__static_yoink("usr/share/terminfo/p/pccon+colors"); +__static_yoink("usr/share/terminfo/p/prism12-m"); +__static_yoink("usr/share/terminfo/p/pe6300"); +__static_yoink("usr/share/terminfo/p/p9"); +__static_yoink("usr/share/terminfo/p/p14-m-w"); +__static_yoink("usr/share/terminfo/p/pmconsole"); +__static_yoink("usr/share/terminfo/p/pty"); +__static_yoink("usr/share/terminfo/p/pccon+keys"); +__static_yoink("usr/share/terminfo/p/pe1100"); +__static_yoink("usr/share/terminfo/p/pe7000m"); +__static_yoink("usr/share/terminfo/p/p12-w"); +__static_yoink("usr/share/terminfo/p/putty-m1"); +__static_yoink("usr/share/terminfo/p/pcansi33"); +__static_yoink("usr/share/terminfo/p/prism9-8-w"); +__static_yoink("usr/share/terminfo/p/ps300"); +__static_yoink("usr/share/terminfo/p/psterm-90x28"); +__static_yoink("usr/share/terminfo/p/p5"); +__static_yoink("usr/share/terminfo/p/pc-venix"); +__static_yoink("usr/share/terminfo/p/pc6300plus"); +__static_yoink("usr/share/terminfo/p/pcplot"); +__static_yoink("usr/share/terminfo/p/pt505-24"); +__static_yoink("usr/share/terminfo/p/psterm-80x24"); +__static_yoink("usr/share/terminfo/p/prism4"); +__static_yoink("usr/share/terminfo/p/psterm"); +__static_yoink("usr/share/terminfo/p/prism12"); +__static_yoink("usr/share/terminfo/p/putty+keypad"); +__static_yoink("usr/share/terminfo/p/pc3r-m"); +__static_yoink("usr/share/terminfo/p/pccons"); +__static_yoink("usr/share/terminfo/p/pt210"); +__static_yoink("usr/share/terminfo/p/pcvt50"); +__static_yoink("usr/share/terminfo/p/prism14-m"); +__static_yoink("usr/share/terminfo/p/pt100w"); +__static_yoink("usr/share/terminfo/p/pcansi43"); +__static_yoink("usr/share/terminfo/p/putty-screen"); +__static_yoink("usr/share/terminfo/p/pckermit"); +__static_yoink("usr/share/terminfo/p/pcvt25-color"); +__static_yoink("usr/share/terminfo/p/p14-m"); +__static_yoink("usr/share/terminfo/p/pe6312"); +__static_yoink("usr/share/terminfo/p/psterm-basic"); +__static_yoink("usr/share/terminfo/p/pt200"); +__static_yoink("usr/share/terminfo/p/pt250w"); +__static_yoink("usr/share/terminfo/p/p9-8"); +__static_yoink("usr/share/terminfo/p/psx_ansi"); +__static_yoink("usr/share/terminfo/p/p14"); +__static_yoink("usr/share/terminfo/p/p14-w"); +__static_yoink("usr/share/terminfo/p/p12"); +__static_yoink("usr/share/terminfo/p/pcansi-33-m"); +__static_yoink("usr/share/terminfo/p/pcvt40"); +__static_yoink("usr/share/terminfo/p/pcvt28w"); +__static_yoink("usr/share/terminfo/p/pe1200"); +__static_yoink("usr/share/terminfo/p/pccon+sgr+acs"); +__static_yoink("usr/share/terminfo/p/pccon+sgr+acs0"); +__static_yoink("usr/share/terminfo/p/p8-w"); +__static_yoink("usr/share/terminfo/p/pcansi-25-m"); +__static_yoink("usr/share/terminfo/p/pcvt43w"); +__static_yoink("usr/share/terminfo/p/pcansi-33"); +__static_yoink("usr/share/terminfo/p/putty+fnkeys+xterm"); +__static_yoink("usr/share/terminfo/p/pccon-m"); +__static_yoink("usr/share/terminfo/p/putty-vt100"); +__static_yoink("usr/share/terminfo/p/pmcons"); +__static_yoink("usr/share/terminfo/p/pc7300"); +__static_yoink("usr/share/terminfo/p/pc-minix"); +__static_yoink("usr/share/terminfo/p/pcansi"); +__static_yoink("usr/share/terminfo/p/p8"); +__static_yoink("usr/share/terminfo/p/pcansi33m"); +__static_yoink("usr/share/terminfo/p/pcvt43"); +__static_yoink("usr/share/terminfo/p/pcansi-43"); +__static_yoink("usr/share/terminfo/p/prism5"); +__static_yoink("usr/share/terminfo/p/pcmw"); +__static_yoink("usr/share/terminfo/p/pcansi-25"); +__static_yoink("usr/share/terminfo/p/prism8"); +__static_yoink("usr/share/terminfo/p/pccon0"); +__static_yoink("usr/share/terminfo/p/pcvt25w"); +__static_yoink("usr/share/terminfo/p/prism14-w"); +__static_yoink("usr/share/terminfo/p/pt250"); +__static_yoink("usr/share/terminfo/p/pcansi-mono"); +__static_yoink("usr/share/terminfo/p/pe1251"); +__static_yoink("usr/share/terminfo/p/pcvt35"); +__static_yoink("usr/share/terminfo/p/pc3r"); +__static_yoink("usr/share/terminfo/p/prism9-w"); +__static_yoink("usr/share/terminfo/p/p7"); +__static_yoink("usr/share/terminfo/p/pcansi-43-m"); +__static_yoink("usr/share/terminfo/p/putty+fnkeys+linux"); +__static_yoink("usr/share/terminfo/p/prism14-m-w"); +__static_yoink("usr/share/terminfo/p/p8gl"); +__static_yoink("usr/share/terminfo/p/p4"); +__static_yoink("usr/share/terminfo/p/psterm-96x48"); +__static_yoink("usr/share/terminfo/p/printer"); +__static_yoink("usr/share/terminfo/p/p12-m"); +__static_yoink("usr/share/terminfo/p/pe7000c"); +__static_yoink("usr/share/terminfo/p/pc-coherent"); +__static_yoink("usr/share/terminfo/p/pc3-bold"); +__static_yoink("usr/share/terminfo/p/p12-m-w"); +__static_yoink("usr/share/terminfo/p/p9-8-w"); +__static_yoink("usr/share/terminfo/p/pcvt40w"); +__static_yoink("usr/share/terminfo/p/pckermit120"); +__static_yoink("usr/share/terminfo/p/pilot"); +__static_yoink("usr/share/terminfo/p/pcansi25"); +__static_yoink("usr/share/terminfo/p/pcz19"); +__static_yoink("usr/share/terminfo/p/pcvt28"); +__static_yoink("usr/share/terminfo/p/prism9"); +__static_yoink("usr/share/terminfo/p/putty"); +__static_yoink("usr/share/terminfo/p/pccon0-m"); +__static_yoink("usr/share/terminfo/p/prism8gl"); +__static_yoink("usr/share/terminfo/p/pckermit12"); +__static_yoink("usr/share/terminfo/p/putty+fnkeys"); +__static_yoink("usr/share/terminfo/s/screen-s"); +__static_yoink("usr/share/terminfo/s/sun-e-s"); +__static_yoink("usr/share/terminfo/s/st-256color"); +__static_yoink("usr/share/terminfo/s/screen.vte"); +__static_yoink("usr/share/terminfo/s/screen-256color-bce"); +__static_yoink("usr/share/terminfo/s/st52-color"); +__static_yoink("usr/share/terminfo/s/sibo"); +__static_yoink("usr/share/terminfo/s/screen-bce.konsole"); +__static_yoink("usr/share/terminfo/s/sun-cmd"); +__static_yoink("usr/share/terminfo/s/stv52pc"); +__static_yoink("usr/share/terminfo/s/screen.linux-s"); +__static_yoink("usr/share/terminfo/s/swtp"); +__static_yoink("usr/share/terminfo/s/sun-s"); +__static_yoink("usr/share/terminfo/s/scoansi-old"); +__static_yoink("usr/share/terminfo/s/synertek380"); +__static_yoink("usr/share/terminfo/s/screen.mrxvt"); +__static_yoink("usr/share/terminfo/s/st-direct"); +__static_yoink("usr/share/terminfo/s/st"); +__static_yoink("usr/share/terminfo/s/st-0.7"); +__static_yoink("usr/share/terminfo/s/sune"); +__static_yoink("usr/share/terminfo/s/superbee-xsb"); +__static_yoink("usr/share/terminfo/s/superbeeic"); +__static_yoink("usr/share/terminfo/s/sc410"); +__static_yoink("usr/share/terminfo/s/screen-bce.xterm-new"); +__static_yoink("usr/share/terminfo/s/sun-12"); +__static_yoink("usr/share/terminfo/s/sb2"); +__static_yoink("usr/share/terminfo/s/superbee"); +__static_yoink("usr/share/terminfo/s/st-0.6"); +__static_yoink("usr/share/terminfo/s/sun-1"); +__static_yoink("usr/share/terminfo/s/sun-color"); +__static_yoink("usr/share/terminfo/s/stterm"); +__static_yoink("usr/share/terminfo/s/sbobcat"); +__static_yoink("usr/share/terminfo/s/screen.xterm-r6"); +__static_yoink("usr/share/terminfo/s/screen-bce.linux"); +__static_yoink("usr/share/terminfo/s/scoansi"); +__static_yoink("usr/share/terminfo/s/screen.minitel1"); +__static_yoink("usr/share/terminfo/s/scanset"); +__static_yoink("usr/share/terminfo/s/stterm-256color"); +__static_yoink("usr/share/terminfo/s/screen"); +__static_yoink("usr/share/terminfo/s/st52"); +__static_yoink("usr/share/terminfo/s/screen-16color-bce"); +__static_yoink("usr/share/terminfo/s/sun-type4"); +__static_yoink("usr/share/terminfo/s/scrhp"); +__static_yoink("usr/share/terminfo/s/screen.putty-m2"); +__static_yoink("usr/share/terminfo/s/screen3"); +__static_yoink("usr/share/terminfo/s/st-0.8"); +__static_yoink("usr/share/terminfo/s/sbi"); +__static_yoink("usr/share/terminfo/s/screen-bce"); +__static_yoink("usr/share/terminfo/s/screen.mlterm"); +__static_yoink("usr/share/terminfo/s/stv52"); +__static_yoink("usr/share/terminfo/s/simpleterm"); +__static_yoink("usr/share/terminfo/s/screen.putty-256color"); +__static_yoink("usr/share/terminfo/s/synertek"); +__static_yoink("usr/share/terminfo/s/securecrt"); +__static_yoink("usr/share/terminfo/s/sun-48"); +__static_yoink("usr/share/terminfo/s/screen.minitel2-80"); +__static_yoink("usr/share/terminfo/s/sun-24"); +__static_yoink("usr/share/terminfo/s/screen.konsole"); +__static_yoink("usr/share/terminfo/s/st52-m"); +__static_yoink("usr/share/terminfo/s/sun2"); +__static_yoink("usr/share/terminfo/s/screen4"); +__static_yoink("usr/share/terminfo/s/sun"); +__static_yoink("usr/share/terminfo/s/screen-base"); +__static_yoink("usr/share/terminfo/s/screen-bce.gnome"); +__static_yoink("usr/share/terminfo/s/screen.minitel1b-nb"); +__static_yoink("usr/share/terminfo/s/screen-bce.Eterm"); +__static_yoink("usr/share/terminfo/s/screen.xterm-256color"); +__static_yoink("usr/share/terminfo/s/screen-16color-s"); +__static_yoink("usr/share/terminfo/s/simterm"); +__static_yoink("usr/share/terminfo/s/screen+italics"); +__static_yoink("usr/share/terminfo/s/screen-256color-bce-s"); +__static_yoink("usr/share/terminfo/s/scrt"); +__static_yoink("usr/share/terminfo/s/screen.linux-m1b"); +__static_yoink("usr/share/terminfo/s/sun-il"); +__static_yoink("usr/share/terminfo/s/screen-256color-s"); +__static_yoink("usr/share/terminfo/s/st52-old"); +__static_yoink("usr/share/terminfo/s/screen.teraterm"); +__static_yoink("usr/share/terminfo/s/screen+fkeys"); +__static_yoink("usr/share/terminfo/s/screen-bce.rxvt"); +__static_yoink("usr/share/terminfo/s/sun-cgsix"); +__static_yoink("usr/share/terminfo/s/screen.vte-256color"); +__static_yoink("usr/share/terminfo/s/sun-34"); +__static_yoink("usr/share/terminfo/s/screen-bce.mrxvt"); +__static_yoink("usr/share/terminfo/s/screen-w"); +__static_yoink("usr/share/terminfo/s/sun-c"); +__static_yoink("usr/share/terminfo/s/screen.minitel1b-80"); +__static_yoink("usr/share/terminfo/s/screen.minitel1b"); +__static_yoink("usr/share/terminfo/s/screen.putty"); +__static_yoink("usr/share/terminfo/s/sv80"); +__static_yoink("usr/share/terminfo/s/screen.putty-m1b"); +__static_yoink("usr/share/terminfo/s/sun-nic"); +__static_yoink("usr/share/terminfo/s/sun-s-e"); +__static_yoink("usr/share/terminfo/s/soroc120"); +__static_yoink("usr/share/terminfo/s/screen.gnome"); +__static_yoink("usr/share/terminfo/s/spinwriter"); +__static_yoink("usr/share/terminfo/s/screen-256color"); +__static_yoink("usr/share/terminfo/s/sun+sl"); +__static_yoink("usr/share/terminfo/s/sun1"); +__static_yoink("usr/share/terminfo/s/screen5"); +__static_yoink("usr/share/terminfo/s/screen.minitel12-80"); +__static_yoink("usr/share/terminfo/s/screen.minitel1-nb"); +__static_yoink("usr/share/terminfo/s/stterm-16color"); +__static_yoink("usr/share/terminfo/s/screwpoint"); +__static_yoink("usr/share/terminfo/s/scoansi-new"); +__static_yoink("usr/share/terminfo/s/screen-16color"); +__static_yoink("usr/share/terminfo/s/screen.linux"); +__static_yoink("usr/share/terminfo/s/screen2"); +__static_yoink("usr/share/terminfo/s/st-16color"); +__static_yoink("usr/share/terminfo/s/sun-ss5"); +__static_yoink("usr/share/terminfo/s/screen.linux-m2"); +__static_yoink("usr/share/terminfo/s/superbrain"); +__static_yoink("usr/share/terminfo/s/screen.putty-m1"); +__static_yoink("usr/share/terminfo/s/sun-e"); +__static_yoink("usr/share/terminfo/s/screen.linux-m1"); +__static_yoink("usr/share/terminfo/s/soroc"); +__static_yoink("usr/share/terminfo/s/sb3"); +__static_yoink("usr/share/terminfo/s/screen.konsole-256color"); +__static_yoink("usr/share/terminfo/s/sb1"); +__static_yoink("usr/share/terminfo/s/screen.xterm-xfree86"); +__static_yoink("usr/share/terminfo/s/sc415"); +__static_yoink("usr/share/terminfo/s/system1"); +__static_yoink("usr/share/terminfo/s/screen.Eterm"); +__static_yoink("usr/share/terminfo/s/s4"); +__static_yoink("usr/share/terminfo/s/screen.xterm-new"); +__static_yoink("usr/share/terminfo/s/screen-16color-bce-s"); +__static_yoink("usr/share/terminfo/s/screen.mlterm-256color"); +__static_yoink("usr/share/terminfo/s/sun-17"); +__static_yoink("usr/share/terminfo/s/soroc140"); +__static_yoink("usr/share/terminfo/s/screen.rxvt"); +__static_yoink("usr/share/terminfo/f/f100"); +__static_yoink("usr/share/terminfo/f/fbterm"); +__static_yoink("usr/share/terminfo/f/fenix"); +__static_yoink("usr/share/terminfo/f/f200vi-w"); +__static_yoink("usr/share/terminfo/f/freedom200"); +__static_yoink("usr/share/terminfo/f/f110-w"); +__static_yoink("usr/share/terminfo/f/f200"); +__static_yoink("usr/share/terminfo/f/freedom110"); +__static_yoink("usr/share/terminfo/f/foot"); +__static_yoink("usr/share/terminfo/f/fox"); +__static_yoink("usr/share/terminfo/f/f100-rv"); +__static_yoink("usr/share/terminfo/f/freedom100"); +__static_yoink("usr/share/terminfo/f/f110"); +__static_yoink("usr/share/terminfo/f/f1720"); +__static_yoink("usr/share/terminfo/f/falco-p"); +__static_yoink("usr/share/terminfo/f/fenixw"); +__static_yoink("usr/share/terminfo/f/fortune"); +__static_yoink("usr/share/terminfo/f/foot+base"); +__static_yoink("usr/share/terminfo/f/f1720a"); +__static_yoink("usr/share/terminfo/f/freedom"); +__static_yoink("usr/share/terminfo/f/f110-14"); +__static_yoink("usr/share/terminfo/f/falco"); +__static_yoink("usr/share/terminfo/f/f200-w"); +__static_yoink("usr/share/terminfo/f/fos"); +__static_yoink("usr/share/terminfo/f/freedom-rv"); +__static_yoink("usr/share/terminfo/f/foot-direct"); +__static_yoink("usr/share/terminfo/f/f110-14w"); +__static_yoink("usr/share/terminfo/f/f200vi"); +__static_yoink("usr/share/terminfo/f/fixterm"); +__static_yoink("usr/share/terminfo/3/386at"); +__static_yoink("usr/share/terminfo/3/3b1"); +__static_yoink("usr/share/terminfo/1/1730-lm"); +__static_yoink("usr/share/terminfo/1/1178"); +__static_yoink("usr/share/terminfo/X/X-hpterm"); +__static_yoink("usr/share/terminfo/X/X-hpterm-color2"); +__static_yoink("usr/share/terminfo/Q/Q310-vip-Hw"); +__static_yoink("usr/share/terminfo/Q/Q310-vip-w"); +__static_yoink("usr/share/terminfo/Q/Q310-vip-H"); +__static_yoink("usr/share/terminfo/Q/Q310-vip-H-am"); +__static_yoink("usr/share/terminfo/Q/Q306-8-pc"); +__static_yoink("usr/share/terminfo/Q/Q310-vip-w-am"); +__static_yoink("usr/share/terminfo/t/tty4424m"); +__static_yoink("usr/share/terminfo/t/t1061"); +__static_yoink("usr/share/terminfo/t/tvi92B"); +__static_yoink("usr/share/terminfo/t/tvi920b-p-2p"); +__static_yoink("usr/share/terminfo/t/tek4025-cr"); +__static_yoink("usr/share/terminfo/t/terminet"); +__static_yoink("usr/share/terminfo/t/tvi910+"); +__static_yoink("usr/share/terminfo/t/teken-sc"); +__static_yoink("usr/share/terminfo/t/tab"); +__static_yoink("usr/share/terminfo/t/tvi920b-vb-p"); +__static_yoink("usr/share/terminfo/t/tn300"); +__static_yoink("usr/share/terminfo/t/tvi914"); +__static_yoink("usr/share/terminfo/t/tvi920c-p-2p"); +__static_yoink("usr/share/terminfo/t/ti916"); +__static_yoink("usr/share/terminfo/t/tvi912c-unk"); +__static_yoink("usr/share/terminfo/t/ti916-132"); +__static_yoink("usr/share/terminfo/t/ti703-w"); +__static_yoink("usr/share/terminfo/t/tvi920c-unk"); +__static_yoink("usr/share/terminfo/t/tek4027-ex"); +__static_yoink("usr/share/terminfo/t/t16"); +__static_yoink("usr/share/terminfo/t/ts-1p"); +__static_yoink("usr/share/terminfo/t/tty4420"); +__static_yoink("usr/share/terminfo/t/tvi920b-2p-p"); +__static_yoink("usr/share/terminfo/t/ti924-8"); +__static_yoink("usr/share/terminfo/t/tek"); +__static_yoink("usr/share/terminfo/t/teken-2022"); +__static_yoink("usr/share/terminfo/t/tek4404"); +__static_yoink("usr/share/terminfo/t/ti931"); +__static_yoink("usr/share/terminfo/t/tek4025a"); +__static_yoink("usr/share/terminfo/t/tvi920b-2p-mc"); +__static_yoink("usr/share/terminfo/t/tn1200"); +__static_yoink("usr/share/terminfo/t/tek4107"); +__static_yoink("usr/share/terminfo/t/tvi912b+printer"); +__static_yoink("usr/share/terminfo/t/tek4105"); +__static_yoink("usr/share/terminfo/t/ti916-8"); +__static_yoink("usr/share/terminfo/t/tvi912c-p-vb"); +__static_yoink("usr/share/terminfo/t/tvi920c-unk-vb"); +__static_yoink("usr/share/terminfo/t/tvi912c-2p-mc"); +__static_yoink("usr/share/terminfo/t/tvi912c-2p"); +__static_yoink("usr/share/terminfo/t/teken-16color"); +__static_yoink("usr/share/terminfo/t/tvi912b-vb-mc"); +__static_yoink("usr/share/terminfo/t/ti735"); +__static_yoink("usr/share/terminfo/t/tvi920b-unk-2p"); +__static_yoink("usr/share/terminfo/t/teraterm4.97"); +__static_yoink("usr/share/terminfo/t/tty5420+nl"); +__static_yoink("usr/share/terminfo/t/tws2102-sna"); +__static_yoink("usr/share/terminfo/t/ti916-220-8"); +__static_yoink("usr/share/terminfo/t/tek4113"); +__static_yoink("usr/share/terminfo/t/tek4025-17"); +__static_yoink("usr/share/terminfo/t/tvi920c-vb-mc"); +__static_yoink("usr/share/terminfo/t/tvi920b-mc-vb"); +__static_yoink("usr/share/terminfo/t/terminology-1.8.1"); +__static_yoink("usr/share/terminfo/t/tvi912b-unk"); +__static_yoink("usr/share/terminfo/t/tvi912b+dim"); +__static_yoink("usr/share/terminfo/t/tek4014"); +__static_yoink("usr/share/terminfo/t/ts100-sp"); +__static_yoink("usr/share/terminfo/t/tvi970-vb"); +__static_yoink("usr/share/terminfo/t/tvi955"); +__static_yoink("usr/share/terminfo/t/ts1"); +__static_yoink("usr/share/terminfo/t/tvi950-rv-4p"); +__static_yoink("usr/share/terminfo/t/tandem653"); +__static_yoink("usr/share/terminfo/t/tab132-rv"); +__static_yoink("usr/share/terminfo/t/teraterm"); +__static_yoink("usr/share/terminfo/t/tek4114"); +__static_yoink("usr/share/terminfo/t/tvi955-w"); +__static_yoink("usr/share/terminfo/t/ti928"); +__static_yoink("usr/share/terminfo/t/tek4025-ex"); +__static_yoink("usr/share/terminfo/t/ti928-8"); +__static_yoink("usr/share/terminfo/t/tws2103"); +__static_yoink("usr/share/terminfo/t/tkterm"); +__static_yoink("usr/share/terminfo/t/tek4115"); +__static_yoink("usr/share/terminfo/t/tvi920c-mc-vb"); +__static_yoink("usr/share/terminfo/t/tvi920b-mc-2p"); +__static_yoink("usr/share/terminfo/t/tek4112"); +__static_yoink("usr/share/terminfo/t/tvi920b-vb-mc"); +__static_yoink("usr/share/terminfo/t/tandem6510"); +__static_yoink("usr/share/terminfo/t/tvi912c-2p-p"); +__static_yoink("usr/share/terminfo/t/tvipt"); +__static_yoink("usr/share/terminfo/t/tek4027"); +__static_yoink("usr/share/terminfo/t/tek4023"); +__static_yoink("usr/share/terminfo/t/teraterm-256color"); +__static_yoink("usr/share/terminfo/t/tty5410-w"); +__static_yoink("usr/share/terminfo/t/ttydmd"); +__static_yoink("usr/share/terminfo/t/tty5410v1-w"); +__static_yoink("usr/share/terminfo/t/tvi912b+mc"); +__static_yoink("usr/share/terminfo/t/tty5420-rv-nl"); +__static_yoink("usr/share/terminfo/t/tek4024"); +__static_yoink("usr/share/terminfo/t/ti745"); +__static_yoink("usr/share/terminfo/t/ts100"); +__static_yoink("usr/share/terminfo/t/tvi920c-unk-2p"); +__static_yoink("usr/share/terminfo/t/tab132-15"); +__static_yoink("usr/share/terminfo/t/tw100"); +__static_yoink("usr/share/terminfo/t/tek4107brl"); +__static_yoink("usr/share/terminfo/t/tvi920c-vb-unk"); +__static_yoink("usr/share/terminfo/t/tvi920c-vb"); +__static_yoink("usr/share/terminfo/t/tvi912b-2p-p"); +__static_yoink("usr/share/terminfo/t/tvi920b-2p"); +__static_yoink("usr/share/terminfo/t/tvi920c-p"); +__static_yoink("usr/share/terminfo/t/tvi920b-vb-unk"); +__static_yoink("usr/share/terminfo/t/tvi921"); +__static_yoink("usr/share/terminfo/t/tvi92D"); +__static_yoink("usr/share/terminfo/t/tvi912b-unk-vb"); +__static_yoink("usr/share/terminfo/t/tvi920b-unk-vb"); +__static_yoink("usr/share/terminfo/t/tek4013"); +__static_yoink("usr/share/terminfo/t/tws2103-sna"); +__static_yoink("usr/share/terminfo/t/tvi950-2p"); +__static_yoink("usr/share/terminfo/t/terminator"); +__static_yoink("usr/share/terminfo/t/tek4112-5"); +__static_yoink("usr/share/terminfo/t/tty5420-w-rv"); +__static_yoink("usr/share/terminfo/t/ti707"); +__static_yoink("usr/share/terminfo/t/ti916-8-132"); +__static_yoink("usr/share/terminfo/t/t3700"); +__static_yoink("usr/share/terminfo/t/tvi920c-p-vb"); +__static_yoink("usr/share/terminfo/t/ti924-8w"); +__static_yoink("usr/share/terminfo/t/tvi920c"); +__static_yoink("usr/share/terminfo/t/tty5410v1"); +__static_yoink("usr/share/terminfo/t/teken"); +__static_yoink("usr/share/terminfo/t/ti707-w"); +__static_yoink("usr/share/terminfo/t/tek4205"); +__static_yoink("usr/share/terminfo/t/tab132-w-rv"); +__static_yoink("usr/share/terminfo/t/tek4207-s"); +__static_yoink("usr/share/terminfo/t/tek4207"); +__static_yoink("usr/share/terminfo/t/tek4025-17-ws"); +__static_yoink("usr/share/terminfo/t/tek4109brl"); +__static_yoink("usr/share/terminfo/t/tvi950"); +__static_yoink("usr/share/terminfo/t/tvi925"); +__static_yoink("usr/share/terminfo/t/tek4106brl"); +__static_yoink("usr/share/terminfo/t/tvi9065"); +__static_yoink("usr/share/terminfo/t/t10"); +__static_yoink("usr/share/terminfo/t/tvi955-hb"); +__static_yoink("usr/share/terminfo/t/tty43"); +__static_yoink("usr/share/terminfo/t/tty5420-w"); +__static_yoink("usr/share/terminfo/t/tvi912b"); +__static_yoink("usr/share/terminfo/t/ti926-8"); +__static_yoink("usr/share/terminfo/t/tty5425-w"); +__static_yoink("usr/share/terminfo/t/tek4015"); +__static_yoink("usr/share/terminfo/t/tty5425-nl"); +__static_yoink("usr/share/terminfo/t/tvi920"); +__static_yoink("usr/share/terminfo/t/tvi920c-mc"); +__static_yoink("usr/share/terminfo/t/tvi912b-2p"); +__static_yoink("usr/share/terminfo/t/tty5620-1"); +__static_yoink("usr/share/terminfo/t/tab132-w"); +__static_yoink("usr/share/terminfo/t/ts-1"); +__static_yoink("usr/share/terminfo/t/ti916-220-7"); +__static_yoink("usr/share/terminfo/t/terminet300"); +__static_yoink("usr/share/terminfo/t/ts100-ctxt"); +__static_yoink("usr/share/terminfo/t/tvi912c-mc-2p"); +__static_yoink("usr/share/terminfo/t/tty35"); +__static_yoink("usr/share/terminfo/t/terminology"); +__static_yoink("usr/share/terminfo/t/tek4105-30"); +__static_yoink("usr/share/terminfo/t/tvi912b+2p"); +__static_yoink("usr/share/terminfo/t/tvi912c"); +__static_yoink("usr/share/terminfo/t/tvi912c-unk-vb"); +__static_yoink("usr/share/terminfo/t/tty4424"); +__static_yoink("usr/share/terminfo/t/ti_ansi"); +__static_yoink("usr/share/terminfo/t/tek4113-nd"); +__static_yoink("usr/share/terminfo/t/tt"); +__static_yoink("usr/share/terminfo/t/tgtelnet"); +__static_yoink("usr/share/terminfo/t/t1061f"); +__static_yoink("usr/share/terminfo/t/tty5620-24"); +__static_yoink("usr/share/terminfo/t/tvi912b-vb-p"); +__static_yoink("usr/share/terminfo/t/tvi912b-p"); +__static_yoink("usr/share/terminfo/t/tmux-direct"); +__static_yoink("usr/share/terminfo/t/tvi970"); +__static_yoink("usr/share/terminfo/t/tvi920b-mc"); +__static_yoink("usr/share/terminfo/t/teleray"); +__static_yoink("usr/share/terminfo/t/tvi920c-vb-p"); +__static_yoink("usr/share/terminfo/t/tvi950-rv"); +__static_yoink("usr/share/terminfo/t/tty40"); +__static_yoink("usr/share/terminfo/t/ti703"); +__static_yoink("usr/share/terminfo/t/tvi920b+fn"); +__static_yoink("usr/share/terminfo/t/tvi950-rv-2p"); +__static_yoink("usr/share/terminfo/t/tvi912b-mc-2p"); +__static_yoink("usr/share/terminfo/t/ti924"); +__static_yoink("usr/share/terminfo/t/trs2"); +__static_yoink("usr/share/terminfo/t/tvi912b-unk-2p"); +__static_yoink("usr/share/terminfo/t/tvi912b-p-vb"); +__static_yoink("usr/share/terminfo/t/trsII"); +__static_yoink("usr/share/terminfo/t/tvi920c-2p-p"); +__static_yoink("usr/share/terminfo/t/tvi912c-vb-p"); +__static_yoink("usr/share/terminfo/t/terminology-0.6.1"); +__static_yoink("usr/share/terminfo/t/tty33"); +__static_yoink("usr/share/terminfo/t/trs16"); +__static_yoink("usr/share/terminfo/t/tek4014-sm"); +__static_yoink("usr/share/terminfo/t/tmux"); +__static_yoink("usr/share/terminfo/t/tvi912c-vb"); +__static_yoink("usr/share/terminfo/t/tek4025ex"); +__static_yoink("usr/share/terminfo/t/tek4113-34"); +__static_yoink("usr/share/terminfo/t/tw52"); +__static_yoink("usr/share/terminfo/t/ti800"); +__static_yoink("usr/share/terminfo/t/tvi950-4p"); +__static_yoink("usr/share/terminfo/t/t653x"); +__static_yoink("usr/share/terminfo/t/tvi912c-mc"); +__static_yoink("usr/share/terminfo/t/tvi912b-2p-unk"); +__static_yoink("usr/share/terminfo/t/tvi920c-2p-mc"); +__static_yoink("usr/share/terminfo/t/teraterm4.59"); +__static_yoink("usr/share/terminfo/t/tty5410"); +__static_yoink("usr/share/terminfo/t/tvi920b-2p-unk"); +__static_yoink("usr/share/terminfo/t/ti733"); +__static_yoink("usr/share/terminfo/t/tty5620"); +__static_yoink("usr/share/terminfo/t/tvi912c-p-2p"); +__static_yoink("usr/share/terminfo/t/trs80II"); +__static_yoink("usr/share/terminfo/t/tty5420-w-nl"); +__static_yoink("usr/share/terminfo/t/teletec"); +__static_yoink("usr/share/terminfo/t/tab132"); +__static_yoink("usr/share/terminfo/t/tek4015-sm"); +__static_yoink("usr/share/terminfo/t/teken-vt"); +__static_yoink("usr/share/terminfo/t/tvi920c-mc-2p"); +__static_yoink("usr/share/terminfo/t/tek4012"); +__static_yoink("usr/share/terminfo/t/tvi910"); +__static_yoink("usr/share/terminfo/t/tvi912"); +__static_yoink("usr/share/terminfo/t/tty37"); +__static_yoink("usr/share/terminfo/t/teraterm2.3"); +__static_yoink("usr/share/terminfo/t/tvi912b-vb"); +__static_yoink("usr/share/terminfo/t/tty5420-nl"); +__static_yoink("usr/share/terminfo/t/tw52-color"); +__static_yoink("usr/share/terminfo/t/ti924w"); +__static_yoink("usr/share/terminfo/t/t3800"); +__static_yoink("usr/share/terminfo/t/tty5425"); +__static_yoink("usr/share/terminfo/t/ti700"); +__static_yoink("usr/share/terminfo/t/tvi912b-vb-unk"); +__static_yoink("usr/share/terminfo/t/tvi912b+vb"); +__static_yoink("usr/share/terminfo/t/tty5420-rv"); +__static_yoink("usr/share/terminfo/t/tvi912c-p"); +__static_yoink("usr/share/terminfo/t/tek4112-nd"); +__static_yoink("usr/share/terminfo/t/tvi912c-mc-vb"); +__static_yoink("usr/share/terminfo/t/tvi912c-vb-mc"); +__static_yoink("usr/share/terminfo/t/tty4426"); +__static_yoink("usr/share/terminfo/t/tty5620-34"); +__static_yoink("usr/share/terminfo/t/tty5420-w-rv-n"); +__static_yoink("usr/share/terminfo/t/ti926"); +__static_yoink("usr/share/terminfo/t/tvi912cc"); +__static_yoink("usr/share/terminfo/t/tvi920c-2p"); +__static_yoink("usr/share/terminfo/t/tvi912c-unk-2p"); +__static_yoink("usr/share/terminfo/t/tvi920b-p"); +__static_yoink("usr/share/terminfo/t/tvi912b-mc-vb"); +__static_yoink("usr/share/terminfo/t/tvi925-hi"); +__static_yoink("usr/share/terminfo/t/tvi912c-2p-unk"); +__static_yoink("usr/share/terminfo/t/ts1p"); +__static_yoink("usr/share/terminfo/t/tvi912c-vb-unk"); +__static_yoink("usr/share/terminfo/t/tvi803"); +__static_yoink("usr/share/terminfo/t/tek4025"); +__static_yoink("usr/share/terminfo/t/tty5420"); +__static_yoink("usr/share/terminfo/t/tvi920b-unk"); +__static_yoink("usr/share/terminfo/t/teken-vt+fkeys"); +__static_yoink("usr/share/terminfo/t/tvi920b"); +__static_yoink("usr/share/terminfo/t/tek4105a"); +__static_yoink("usr/share/terminfo/t/tvi912b-2p-mc"); +__static_yoink("usr/share/terminfo/t/tty4424-1"); +__static_yoink("usr/share/terminfo/t/tvi970-2p"); +__static_yoink("usr/share/terminfo/t/tvi912b-p-2p"); +__static_yoink("usr/share/terminfo/t/tvi924"); +__static_yoink("usr/share/terminfo/t/tws-generic"); +__static_yoink("usr/share/terminfo/t/tek4125"); +__static_yoink("usr/share/terminfo/t/tmux-256color"); +__static_yoink("usr/share/terminfo/t/tw52-m"); +__static_yoink("usr/share/terminfo/t/tvi920c-2p-unk"); +__static_yoink("usr/share/terminfo/t/tt52"); +__static_yoink("usr/share/terminfo/t/tvi912b-mc"); +__static_yoink("usr/share/terminfo/t/termite"); +__static_yoink("usr/share/terminfo/t/tek4109"); +__static_yoink("usr/share/terminfo/t/terminology-1.0.0"); +__static_yoink("usr/share/terminfo/t/teken-sc+fkeys"); +__static_yoink("usr/share/terminfo/t/tvi920b-p-vb"); +__static_yoink("usr/share/terminfo/t/terminet1200"); +__static_yoink("usr/share/terminfo/t/tty5620-s"); +__static_yoink("usr/share/terminfo/t/teken-2018"); +__static_yoink("usr/share/terminfo/t/tvi920b-vb"); +__static_yoink("usr/share/terminfo/a/att2300"); +__static_yoink("usr/share/terminfo/a/adds980"); +__static_yoink("usr/share/terminfo/a/att730-41"); +__static_yoink("usr/share/terminfo/a/att4415-nl"); +__static_yoink("usr/share/terminfo/a/altos-2"); +__static_yoink("usr/share/terminfo/a/att610-103k-w"); +__static_yoink("usr/share/terminfo/a/avt-w"); +__static_yoink("usr/share/terminfo/a/ansiw"); +__static_yoink("usr/share/terminfo/a/aaa-24"); +__static_yoink("usr/share/terminfo/a/aj510"); +__static_yoink("usr/share/terminfo/a/ansil-mono"); +__static_yoink("usr/share/terminfo/a/att4410v1"); +__static_yoink("usr/share/terminfo/a/aixterm-m-old"); +__static_yoink("usr/share/terminfo/a/att5420-w"); +__static_yoink("usr/share/terminfo/a/adm2"); +__static_yoink("usr/share/terminfo/a/aaa-28"); +__static_yoink("usr/share/terminfo/a/ansi+cpr"); +__static_yoink("usr/share/terminfo/a/att610+cvis0"); +__static_yoink("usr/share/terminfo/a/abm85h-old"); +__static_yoink("usr/share/terminfo/a/at-color"); +__static_yoink("usr/share/terminfo/a/att513"); +__static_yoink("usr/share/terminfo/a/aaa-60-s"); +__static_yoink("usr/share/terminfo/a/att4410"); +__static_yoink("usr/share/terminfo/a/annarbor4080"); +__static_yoink("usr/share/terminfo/a/att615-103k-w"); +__static_yoink("usr/share/terminfo/a/avatar1"); +__static_yoink("usr/share/terminfo/a/att4415"); +__static_yoink("usr/share/terminfo/a/att610-w"); +__static_yoink("usr/share/terminfo/a/ansi-color-2-emx"); +__static_yoink("usr/share/terminfo/a/aaa-26"); +__static_yoink("usr/share/terminfo/a/att5410v1-w"); +__static_yoink("usr/share/terminfo/a/ansi+idl"); +__static_yoink("usr/share/terminfo/a/aaa-40-rv"); +__static_yoink("usr/share/terminfo/a/apple2e-p"); +__static_yoink("usr/share/terminfo/a/act5"); +__static_yoink("usr/share/terminfo/a/abm85h"); +__static_yoink("usr/share/terminfo/a/att4425-nl"); +__static_yoink("usr/share/terminfo/a/abm85e"); +__static_yoink("usr/share/terminfo/a/adm3a"); +__static_yoink("usr/share/terminfo/a/avt-s"); +__static_yoink("usr/share/terminfo/a/ansi+sgrul"); +__static_yoink("usr/share/terminfo/a/att730r"); +__static_yoink("usr/share/terminfo/a/apple-videx2"); +__static_yoink("usr/share/terminfo/a/aas1901"); +__static_yoink("usr/share/terminfo/a/aaa-30-s-rv-ct"); +__static_yoink("usr/share/terminfo/a/ansi.sysk"); +__static_yoink("usr/share/terminfo/a/ansi+pp"); +__static_yoink("usr/share/terminfo/a/ampex232"); +__static_yoink("usr/share/terminfo/a/ampex-232"); +__static_yoink("usr/share/terminfo/a/att5420-w-nl"); +__static_yoink("usr/share/terminfo/a/att615-w"); +__static_yoink("usr/share/terminfo/a/aaa-18"); +__static_yoink("usr/share/terminfo/a/ansi+enq"); +__static_yoink("usr/share/terminfo/a/ansi77"); +__static_yoink("usr/share/terminfo/a/aa4080"); +__static_yoink("usr/share/terminfo/a/avt-rv-ns"); +__static_yoink("usr/share/terminfo/a/att4425"); +__static_yoink("usr/share/terminfo/a/att5620-1"); +__static_yoink("usr/share/terminfo/a/ansi80x60"); +__static_yoink("usr/share/terminfo/a/apple-vm80"); +__static_yoink("usr/share/terminfo/a/alto-h19"); +__static_yoink("usr/share/terminfo/a/aaa-30-s-ctxt"); +__static_yoink("usr/share/terminfo/a/att5420-rv"); +__static_yoink("usr/share/terminfo/a/att605-w"); +__static_yoink("usr/share/terminfo/a/atari-old"); +__static_yoink("usr/share/terminfo/a/apple-80"); +__static_yoink("usr/share/terminfo/a/aaa"); +__static_yoink("usr/share/terminfo/a/atari-m"); +__static_yoink("usr/share/terminfo/a/arm100"); +__static_yoink("usr/share/terminfo/a/aaa-30-s-rv"); +__static_yoink("usr/share/terminfo/a/avt-ns"); +__static_yoink("usr/share/terminfo/a/ansi+local"); +__static_yoink("usr/share/terminfo/a/aaa-db"); +__static_yoink("usr/share/terminfo/a/aixterm+sl"); +__static_yoink("usr/share/terminfo/a/ansi+rep"); +__static_yoink("usr/share/terminfo/a/ansi+rca2"); +__static_yoink("usr/share/terminfo/a/ansi+erase"); +__static_yoink("usr/share/terminfo/a/avt-w-rv-s"); +__static_yoink("usr/share/terminfo/a/att5620-s"); +__static_yoink("usr/share/terminfo/a/adm3"); +__static_yoink("usr/share/terminfo/a/arm100-am"); +__static_yoink("usr/share/terminfo/a/aixterm-16color"); +__static_yoink("usr/share/terminfo/a/aaa-36"); +__static_yoink("usr/share/terminfo/a/atari"); +__static_yoink("usr/share/terminfo/a/adm31-old"); +__static_yoink("usr/share/terminfo/a/apple-uterm-vb"); +__static_yoink("usr/share/terminfo/a/ansisysk"); +__static_yoink("usr/share/terminfo/a/apollo"); +__static_yoink("usr/share/terminfo/a/at-m"); +__static_yoink("usr/share/terminfo/a/att610-103k"); +__static_yoink("usr/share/terminfo/a/ansi80x50"); +__static_yoink("usr/share/terminfo/a/at386"); +__static_yoink("usr/share/terminfo/a/adm1178"); +__static_yoink("usr/share/terminfo/a/ansi"); +__static_yoink("usr/share/terminfo/a/alt2"); +__static_yoink("usr/share/terminfo/a/aaa-30"); +__static_yoink("usr/share/terminfo/a/ansi80x60-mono"); +__static_yoink("usr/share/terminfo/a/att5420_2"); +__static_yoink("usr/share/terminfo/a/ansi+sgr"); +__static_yoink("usr/share/terminfo/a/aaa-30-rv"); +__static_yoink("usr/share/terminfo/a/amp219"); +__static_yoink("usr/share/terminfo/a/ansi-mini"); +__static_yoink("usr/share/terminfo/a/aaa-24-rv"); +__static_yoink("usr/share/terminfo/a/aaa-60-dec-rv"); +__static_yoink("usr/share/terminfo/a/aterm"); +__static_yoink("usr/share/terminfo/a/att5320"); +__static_yoink("usr/share/terminfo/a/amiga-8bit"); +__static_yoink("usr/share/terminfo/a/avatar0+"); +__static_yoink("usr/share/terminfo/a/aaa-s"); +__static_yoink("usr/share/terminfo/a/ansi+rca"); +__static_yoink("usr/share/terminfo/a/addrinfo"); +__static_yoink("usr/share/terminfo/a/ansi+idl1"); +__static_yoink("usr/share/terminfo/a/ansi80x43-mono"); +__static_yoink("usr/share/terminfo/a/alt4"); +__static_yoink("usr/share/terminfo/a/att605"); +__static_yoink("usr/share/terminfo/a/att5420-w-rv"); +__static_yoink("usr/share/terminfo/a/ansi+local1"); +__static_yoink("usr/share/terminfo/a/ansi80x25"); +__static_yoink("usr/share/terminfo/a/ansi80x25-raw"); +__static_yoink("usr/share/terminfo/a/adm1a"); +__static_yoink("usr/share/terminfo/a/alt5"); +__static_yoink("usr/share/terminfo/a/att5620-34"); +__static_yoink("usr/share/terminfo/a/ansi-mr"); +__static_yoink("usr/share/terminfo/a/avt-w-rv-ns"); +__static_yoink("usr/share/terminfo/a/aaa-40"); +__static_yoink("usr/share/terminfo/a/alacritty"); +__static_yoink("usr/share/terminfo/a/aaa-30-rv-ctxt"); +__static_yoink("usr/share/terminfo/a/att4424"); +__static_yoink("usr/share/terminfo/a/apple80p"); +__static_yoink("usr/share/terminfo/a/att4410-w"); +__static_yoink("usr/share/terminfo/a/ampex232w"); +__static_yoink("usr/share/terminfo/a/ansiterm"); +__static_yoink("usr/share/terminfo/a/aaa-60-rv"); +__static_yoink("usr/share/terminfo/a/ampex80"); +__static_yoink("usr/share/terminfo/a/att730r-24"); +__static_yoink("usr/share/terminfo/a/altos7pc"); +__static_yoink("usr/share/terminfo/a/adm+sgr"); +__static_yoink("usr/share/terminfo/a/att5420-rv-nl"); +__static_yoink("usr/share/terminfo/a/att610+cvis"); +__static_yoink("usr/share/terminfo/a/adm36"); +__static_yoink("usr/share/terminfo/a/adm5"); +__static_yoink("usr/share/terminfo/a/aaa-36-rv"); +__static_yoink("usr/share/terminfo/a/appleIIgs"); +__static_yoink("usr/share/terminfo/a/att5430"); +__static_yoink("usr/share/terminfo/a/apple-videx3"); +__static_yoink("usr/share/terminfo/a/amiga"); +__static_yoink("usr/share/terminfo/a/att5420+nl"); +__static_yoink("usr/share/terminfo/a/aws"); +__static_yoink("usr/share/terminfo/a/ansi+sgrbold"); +__static_yoink("usr/share/terminfo/a/adm31"); +__static_yoink("usr/share/terminfo/a/ansis"); +__static_yoink("usr/share/terminfo/a/ansi+idc"); +__static_yoink("usr/share/terminfo/a/alt7pc"); +__static_yoink("usr/share/terminfo/a/abm85"); +__static_yoink("usr/share/terminfo/a/att4415-rv"); +__static_yoink("usr/share/terminfo/a/aaa-rv-ctxt"); +__static_yoink("usr/share/terminfo/a/ampex210"); +__static_yoink("usr/share/terminfo/a/ansi80x50-mono"); +__static_yoink("usr/share/terminfo/a/avatar"); +__static_yoink("usr/share/terminfo/a/avt-rv-s"); +__static_yoink("usr/share/terminfo/a/ansi+cup"); +__static_yoink("usr/share/terminfo/a/alacritty-direct"); +__static_yoink("usr/share/terminfo/a/att5420-nl"); +__static_yoink("usr/share/terminfo/a/att6386"); +__static_yoink("usr/share/terminfo/a/aaa-s-rv-ctxt"); +__static_yoink("usr/share/terminfo/a/altos3"); +__static_yoink("usr/share/terminfo/a/altos5"); +__static_yoink("usr/share/terminfo/a/aepro"); +__static_yoink("usr/share/terminfo/a/amiga-vnc"); +__static_yoink("usr/share/terminfo/a/altos2"); +__static_yoink("usr/share/terminfo/a/att630-24"); +__static_yoink("usr/share/terminfo/a/appleIIc"); +__static_yoink("usr/share/terminfo/a/adm12"); +__static_yoink("usr/share/terminfo/a/atari-color"); +__static_yoink("usr/share/terminfo/a/a80"); +__static_yoink("usr/share/terminfo/a/att510a"); +__static_yoink("usr/share/terminfo/a/att630"); +__static_yoink("usr/share/terminfo/a/aaa+rv"); +__static_yoink("usr/share/terminfo/a/at"); +__static_yoink("usr/share/terminfo/a/alto-heath"); +__static_yoink("usr/share/terminfo/a/ansi80x30"); +__static_yoink("usr/share/terminfo/a/att4425-w"); +__static_yoink("usr/share/terminfo/a/apple-videx"); +__static_yoink("usr/share/terminfo/a/alt3"); +__static_yoink("usr/share/terminfo/a/att505-22"); +__static_yoink("usr/share/terminfo/a/apl"); +__static_yoink("usr/share/terminfo/a/ampex175-b"); +__static_yoink("usr/share/terminfo/a/att5420-w-rv-n"); +__static_yoink("usr/share/terminfo/a/ansi-emx"); +__static_yoink("usr/share/terminfo/a/addsviewpoint"); +__static_yoink("usr/share/terminfo/a/ansi43m"); +__static_yoink("usr/share/terminfo/a/att5310"); +__static_yoink("usr/share/terminfo/a/adm20"); +__static_yoink("usr/share/terminfo/a/aaa+dec"); +__static_yoink("usr/share/terminfo/a/adm3a+"); +__static_yoink("usr/share/terminfo/a/ansis-mono"); +__static_yoink("usr/share/terminfo/a/awsc"); +__static_yoink("usr/share/terminfo/a/ansi.sys-old"); +__static_yoink("usr/share/terminfo/a/altoheath"); +__static_yoink("usr/share/terminfo/a/apple2e"); +__static_yoink("usr/share/terminfo/a/ambas"); +__static_yoink("usr/share/terminfo/a/att700"); +__static_yoink("usr/share/terminfo/a/amiga-h"); +__static_yoink("usr/share/terminfo/a/adm1"); +__static_yoink("usr/share/terminfo/a/a980"); +__static_yoink("usr/share/terminfo/a/ansi+sgrdim"); +__static_yoink("usr/share/terminfo/a/altos-4"); +__static_yoink("usr/share/terminfo/a/att4415+nl"); +__static_yoink("usr/share/terminfo/a/att4418-w"); +__static_yoink("usr/share/terminfo/a/aj830"); +__static_yoink("usr/share/terminfo/a/att5410-w"); +__static_yoink("usr/share/terminfo/a/att4415-w-rv"); +__static_yoink("usr/share/terminfo/a/arm100-wam"); +__static_yoink("usr/share/terminfo/a/ansi.sys"); +__static_yoink("usr/share/terminfo/a/aaa-s-rv"); +__static_yoink("usr/share/terminfo/a/adm42"); +__static_yoink("usr/share/terminfo/a/att4418"); +__static_yoink("usr/share/terminfo/a/alacritty+common"); +__static_yoink("usr/share/terminfo/a/att7300"); +__static_yoink("usr/share/terminfo/a/att4410v1-w"); +__static_yoink("usr/share/terminfo/a/aaa-30-s"); +__static_yoink("usr/share/terminfo/a/appleII"); +__static_yoink("usr/share/terminfo/a/aaa-48-rv"); +__static_yoink("usr/share/terminfo/a/absolute"); +__static_yoink("usr/share/terminfo/a/aaa-ctxt"); +__static_yoink("usr/share/terminfo/a/atari_st-color"); +__static_yoink("usr/share/terminfo/a/aaa-rv-unk"); +__static_yoink("usr/share/terminfo/a/avt-w-ns"); +__static_yoink("usr/share/terminfo/a/ansi-generic"); +__static_yoink("usr/share/terminfo/a/ampex-219w"); +__static_yoink("usr/share/terminfo/a/att4415-w-rv-n"); +__static_yoink("usr/share/terminfo/a/apple-uterm"); +__static_yoink("usr/share/terminfo/a/aaa-30-ctxt"); +__static_yoink("usr/share/terminfo/a/aixterm-m"); +__static_yoink("usr/share/terminfo/a/avt+s"); +__static_yoink("usr/share/terminfo/a/ansi+inittabs"); +__static_yoink("usr/share/terminfo/a/ansi80x43"); +__static_yoink("usr/share/terminfo/a/ansi+idc1"); +__static_yoink("usr/share/terminfo/a/avt-w-rv"); +__static_yoink("usr/share/terminfo/a/adm42-ns"); +__static_yoink("usr/share/terminfo/a/arm100-w"); +__static_yoink("usr/share/terminfo/a/aixterm"); +__static_yoink("usr/share/terminfo/a/atarist-m"); +__static_yoink("usr/share/terminfo/a/ansi80x25-mono"); +__static_yoink("usr/share/terminfo/a/ansi80x30-mono"); +__static_yoink("usr/share/terminfo/a/altos-3"); +__static_yoink("usr/share/terminfo/a/aaa-unk"); +__static_yoink("usr/share/terminfo/a/ansi+sgrso"); +__static_yoink("usr/share/terminfo/a/avatar0"); +__static_yoink("usr/share/terminfo/a/att4424-1"); +__static_yoink("usr/share/terminfo/a/a210"); +__static_yoink("usr/share/terminfo/a/altos7"); +__static_yoink("usr/share/terminfo/a/att5425-w"); +__static_yoink("usr/share/terminfo/a/apollo_19L"); +__static_yoink("usr/share/terminfo/a/ansi-mono"); +__static_yoink("usr/share/terminfo/a/ampex175"); +__static_yoink("usr/share/terminfo/a/att505-24"); +__static_yoink("usr/share/terminfo/a/aaa-22"); +__static_yoink("usr/share/terminfo/a/appleIIe"); +__static_yoink("usr/share/terminfo/a/att615-103k"); +__static_yoink("usr/share/terminfo/a/ampex219"); +__static_yoink("usr/share/terminfo/a/adm11"); +__static_yoink("usr/share/terminfo/a/att730-24"); +__static_yoink("usr/share/terminfo/a/avt-w-s"); +__static_yoink("usr/share/terminfo/a/aaa-48"); +__static_yoink("usr/share/terminfo/a/apple-soroc"); +__static_yoink("usr/share/terminfo/a/aaa-60"); +__static_yoink("usr/share/terminfo/a/att605-pc"); +__static_yoink("usr/share/terminfo/a/altos4"); +__static_yoink("usr/share/terminfo/a/aaa+unk"); +__static_yoink("usr/share/terminfo/a/att5425"); +__static_yoink("usr/share/terminfo/a/ansi-mtabs"); +__static_yoink("usr/share/terminfo/a/att5410"); +__static_yoink("usr/share/terminfo/a/apollo_15P"); +__static_yoink("usr/share/terminfo/a/avt"); +__static_yoink("usr/share/terminfo/a/att500"); +__static_yoink("usr/share/terminfo/a/att5420_2-w"); +__static_yoink("usr/share/terminfo/a/att730"); +__static_yoink("usr/share/terminfo/a/amp219w"); +__static_yoink("usr/share/terminfo/a/att4424m"); +__static_yoink("usr/share/terminfo/a/att620-103k"); +__static_yoink("usr/share/terminfo/a/avt-rv"); +__static_yoink("usr/share/terminfo/a/apple-ae"); +__static_yoink("usr/share/terminfo/a/aaa-rv"); +__static_yoink("usr/share/terminfo/a/att5620"); +__static_yoink("usr/share/terminfo/a/apollo_color"); +__static_yoink("usr/share/terminfo/a/att505"); +__static_yoink("usr/share/terminfo/a/att5620-24"); +__static_yoink("usr/share/terminfo/a/aaa-20"); +__static_yoink("usr/share/terminfo/a/att510d"); +__static_yoink("usr/share/terminfo/a/att4415-w-nl"); +__static_yoink("usr/share/terminfo/a/att4415-rv-nl"); +__static_yoink("usr/share/terminfo/a/aaa-60-s-rv"); +__static_yoink("usr/share/terminfo/a/ansi+csr"); +__static_yoink("usr/share/terminfo/a/att5420"); +__static_yoink("usr/share/terminfo/a/ambassador"); +__static_yoink("usr/share/terminfo/a/adm22"); +__static_yoink("usr/share/terminfo/a/ansi+arrows"); +__static_yoink("usr/share/terminfo/a/att4426"); +__static_yoink("usr/share/terminfo/a/ansil"); +__static_yoink("usr/share/terminfo/a/att615"); +__static_yoink("usr/share/terminfo/a/att5418"); +__static_yoink("usr/share/terminfo/a/att620-103k-w"); +__static_yoink("usr/share/terminfo/a/att5410v1"); +__static_yoink("usr/share/terminfo/a/att5418-w"); +__static_yoink("usr/share/terminfo/a/adds200"); +__static_yoink("usr/share/terminfo/a/atari_st"); +__static_yoink("usr/share/terminfo/a/aj832"); +__static_yoink("usr/share/terminfo/a/ansi+tabs"); +__static_yoink("usr/share/terminfo/a/ampex-219"); +__static_yoink("usr/share/terminfo/a/att2350"); +__static_yoink("usr/share/terminfo/a/act4"); +__static_yoink("usr/share/terminfo/a/ampex219w"); +__static_yoink("usr/share/terminfo/a/aaa-18-rv"); +__static_yoink("usr/share/terminfo/a/att5425-nl"); +__static_yoink("usr/share/terminfo/a/ansi-nt"); +__static_yoink("usr/share/terminfo/a/aj"); +__static_yoink("usr/share/terminfo/a/apollo+vt132"); +__static_yoink("usr/share/terminfo/a/abm80"); +__static_yoink("usr/share/terminfo/a/altos-5"); +__static_yoink("usr/share/terminfo/a/ap-vm80"); +__static_yoink("usr/share/terminfo/a/att620"); +__static_yoink("usr/share/terminfo/a/att4415-w"); +__static_yoink("usr/share/terminfo/a/ansi-m"); +__static_yoink("usr/share/terminfo/a/adm21"); +__static_yoink("usr/share/terminfo/a/addsvp60"); +__static_yoink("usr/share/terminfo/a/att4420"); +__static_yoink("usr/share/terminfo/a/att730r-41"); +__static_yoink("usr/share/terminfo/a/altoh19"); +__static_yoink("usr/share/terminfo/a/alt7"); +__static_yoink("usr/share/terminfo/a/aaa-s-ctxt"); +__static_yoink("usr/share/terminfo/a/att610"); +__static_yoink("usr/share/terminfo/a/att620-w"); +__static_yoink("usr/share/terminfo/a/ansi-color-3-emx"); +__static_yoink("usr/share/terminfo/N/NCRVT100WPP"); +__static_yoink("usr/share/terminfo/N/NCR260VT300WPP"); +__static_yoink("usr/share/terminfo/j/jfbterm"); +__static_yoink("usr/share/terminfo/j/jaixterm-m"); +__static_yoink("usr/share/terminfo/j/jaixterm"); +__static_yoink("usr/share/terminfo/j/jerq"); +__static_yoink("usr/share/terminfo/4/4027ex"); +__static_yoink("usr/share/terminfo/4/4410-w"); +__static_yoink("usr/share/terminfo/4/4025ex"); +__static_yoink("usr/share/terminfo/x/xnuppc-80x25"); +__static_yoink("usr/share/terminfo/x/x1700"); +__static_yoink("usr/share/terminfo/x/xterm+kbs"); +__static_yoink("usr/share/terminfo/x/xtermm"); +__static_yoink("usr/share/terminfo/x/xterm+pcc2"); +__static_yoink("usr/share/terminfo/x/xnuppc+160x64"); +__static_yoink("usr/share/terminfo/x/xwsh"); +__static_yoink("usr/share/terminfo/x/xterm+x11mouse"); +__static_yoink("usr/share/terminfo/x/xterm+sm+1002"); +__static_yoink("usr/share/terminfo/x/xterm+keypad"); +__static_yoink("usr/share/terminfo/x/xnuppc-m-f"); +__static_yoink("usr/share/terminfo/x/xnuppc"); +__static_yoink("usr/share/terminfo/x/xnuppc+f"); +__static_yoink("usr/share/terminfo/x/xterm-nic"); +__static_yoink("usr/share/terminfo/x/xterm+edit"); +__static_yoink("usr/share/terminfo/x/xterm+direct16"); +__static_yoink("usr/share/terminfo/x/xterm+focus"); +__static_yoink("usr/share/terminfo/x/xnuppc-b"); +__static_yoink("usr/share/terminfo/x/xterms-sun"); +__static_yoink("usr/share/terminfo/x/xnuppc+200x64"); +__static_yoink("usr/share/terminfo/x/xnuppc+256x96"); +__static_yoink("usr/share/terminfo/x/xnuppc+200x75"); +__static_yoink("usr/share/terminfo/x/xnuppc+112x37"); +__static_yoink("usr/share/terminfo/x/xterm+alt+title"); +__static_yoink("usr/share/terminfo/x/xterm-1003"); +__static_yoink("usr/share/terminfo/x/xterm+acs"); +__static_yoink("usr/share/terminfo/x/xterm-xf86-v44"); +__static_yoink("usr/share/terminfo/x/x68k"); +__static_yoink("usr/share/terminfo/x/xterm+tmux2"); +__static_yoink("usr/share/terminfo/x/xterm+sl-twm"); +__static_yoink("usr/share/terminfo/x/xnuppc-128x48"); +__static_yoink("usr/share/terminfo/x/xfce"); +__static_yoink("usr/share/terminfo/x/xterm+sm+1003"); +__static_yoink("usr/share/terminfo/x/xnuppc-100x37-m"); +__static_yoink("usr/share/terminfo/x/xterm-r6"); +__static_yoink("usr/share/terminfo/x/x1700-lm"); +__static_yoink("usr/share/terminfo/x/xterm+88color2"); +__static_yoink("usr/share/terminfo/x/xterm-direct16"); +__static_yoink("usr/share/terminfo/x/x1720"); +__static_yoink("usr/share/terminfo/x/xerox-lm"); +__static_yoink("usr/share/terminfo/x/xterm-kitty"); +__static_yoink("usr/share/terminfo/x/xterm-hp"); +__static_yoink("usr/share/terminfo/x/xterm-p370"); +__static_yoink("usr/share/terminfo/x/xterm+pcc3"); +__static_yoink("usr/share/terminfo/x/xnuppc-256x96-m"); +__static_yoink("usr/share/terminfo/x/xterm+x11hilite"); +__static_yoink("usr/share/terminfo/x/xterm+noapp"); +__static_yoink("usr/share/terminfo/x/xterm-direct2"); +__static_yoink("usr/share/terminfo/x/xterm+pc+edit"); +__static_yoink("usr/share/terminfo/x/xterm-sun"); +__static_yoink("usr/share/terminfo/x/xiterm"); +__static_yoink("usr/share/terminfo/x/xerox820"); +__static_yoink("usr/share/terminfo/x/xnuppc+c"); +__static_yoink("usr/share/terminfo/x/x1750"); +__static_yoink("usr/share/terminfo/x/xterm-old"); +__static_yoink("usr/share/terminfo/x/xterm-1006"); +__static_yoink("usr/share/terminfo/x/xterm+tmux"); +__static_yoink("usr/share/terminfo/x/xterm-x10mouse"); +__static_yoink("usr/share/terminfo/x/xterm"); +__static_yoink("usr/share/terminfo/x/xterm-8bit"); +__static_yoink("usr/share/terminfo/x/xterm+nopcfkeys"); +__static_yoink("usr/share/terminfo/x/xterm+pcf2"); +__static_yoink("usr/share/terminfo/x/xterm1"); +__static_yoink("usr/share/terminfo/x/xterm-vt220"); +__static_yoink("usr/share/terminfo/x/xnuppc-80x30-m"); +__static_yoink("usr/share/terminfo/x/xterm+pcfkeys"); +__static_yoink("usr/share/terminfo/x/xnuppc-m-f2"); +__static_yoink("usr/share/terminfo/x/xtermc"); +__static_yoink("usr/share/terminfo/x/xterm-24"); +__static_yoink("usr/share/terminfo/x/xterm+sm+1005"); +__static_yoink("usr/share/terminfo/x/xterm-88color"); +__static_yoink("usr/share/terminfo/x/xterm+app"); +__static_yoink("usr/share/terminfo/x/xterm+x10mouse"); +__static_yoink("usr/share/terminfo/x/xerox1720"); +__static_yoink("usr/share/terminfo/x/xnuppc-256x96"); +__static_yoink("usr/share/terminfo/x/xterm-xf86-v33"); +__static_yoink("usr/share/terminfo/x/xterms"); +__static_yoink("usr/share/terminfo/x/xterm-sco"); +__static_yoink("usr/share/terminfo/x/xterm+sl-alt"); +__static_yoink("usr/share/terminfo/x/xnuppc+b"); +__static_yoink("usr/share/terminfo/x/xterm-new"); +__static_yoink("usr/share/terminfo/x/xterm+direct"); +__static_yoink("usr/share/terminfo/x/xnuppc+128x40"); +__static_yoink("usr/share/terminfo/x/xterm-1005"); +__static_yoink("usr/share/terminfo/x/xterm+pcc0"); +__static_yoink("usr/share/terminfo/x/xterm+osc104"); +__static_yoink("usr/share/terminfo/x/xnuppc-90x30"); +__static_yoink("usr/share/terminfo/x/xterm+256color2"); +__static_yoink("usr/share/terminfo/x/xterm-noapp"); +__static_yoink("usr/share/terminfo/x/xnuppc-80x25-m"); +__static_yoink("usr/share/terminfo/x/xterm+alt47"); +__static_yoink("usr/share/terminfo/x/xterm-256color"); +__static_yoink("usr/share/terminfo/x/xnuppc-128x40"); +__static_yoink("usr/share/terminfo/x/xterm+88color"); +__static_yoink("usr/share/terminfo/x/xerox"); +__static_yoink("usr/share/terminfo/x/xterm-16color"); +__static_yoink("usr/share/terminfo/x/xterm-r5"); +__static_yoink("usr/share/terminfo/x/xterm-mono"); +__static_yoink("usr/share/terminfo/x/xnuppc+128x48"); +__static_yoink("usr/share/terminfo/x/x68k-ite"); +__static_yoink("usr/share/terminfo/x/xnuppc+100x37"); +__static_yoink("usr/share/terminfo/x/xterm-bold"); +__static_yoink("usr/share/terminfo/x/xterm-xf86-v32"); +__static_yoink("usr/share/terminfo/x/xterm+direct256"); +__static_yoink("usr/share/terminfo/x/xnuppc-128x48-m"); +__static_yoink("usr/share/terminfo/x/xnuppc-80x30"); +__static_yoink("usr/share/terminfo/x/xterm+titlestack"); +__static_yoink("usr/share/terminfo/x/xnuppc-128x40-m"); +__static_yoink("usr/share/terminfo/x/xterm+nofkeys"); +__static_yoink("usr/share/terminfo/x/xnuppc-144x48-m"); +__static_yoink("usr/share/terminfo/x/xnuppc-144x48"); +__static_yoink("usr/share/terminfo/x/xterm-pcolor"); +__static_yoink("usr/share/terminfo/x/xnuppc-f2"); +__static_yoink("usr/share/terminfo/x/xterm-x11hilite"); +__static_yoink("usr/share/terminfo/x/xterm+indirect"); +__static_yoink("usr/share/terminfo/x/xnuppc-100x37"); +__static_yoink("usr/share/terminfo/x/xterm+direct2"); +__static_yoink("usr/share/terminfo/x/xterm-utf8"); +__static_yoink("usr/share/terminfo/x/xnuppc+90x30"); +__static_yoink("usr/share/terminfo/x/xterm-color"); +__static_yoink("usr/share/terminfo/x/x10term+sl"); +__static_yoink("usr/share/terminfo/x/xnuppc+80x25"); +__static_yoink("usr/share/terminfo/x/xnuppc-200x64"); +__static_yoink("usr/share/terminfo/x/xterm+meta"); +__static_yoink("usr/share/terminfo/x/xterm-direct"); +__static_yoink("usr/share/terminfo/x/xnuppc-200x64-m"); +__static_yoink("usr/share/terminfo/x/xterm+noalt"); +__static_yoink("usr/share/terminfo/x/xnuppc-90x30-m"); +__static_yoink("usr/share/terminfo/x/xnuppc-200x75-m"); +__static_yoink("usr/share/terminfo/x/xterm+alt1049"); +__static_yoink("usr/share/terminfo/x/xterm-xf86-v43"); +__static_yoink("usr/share/terminfo/x/xterm-p371"); +__static_yoink("usr/share/terminfo/x/xterm-xfree86"); +__static_yoink("usr/share/terminfo/x/xterm-xi"); +__static_yoink("usr/share/terminfo/x/xnuppc+144x48"); +__static_yoink("usr/share/terminfo/x/xnuppc+basic"); +__static_yoink("usr/share/terminfo/x/xnuppc-112x37-m"); +__static_yoink("usr/share/terminfo/x/xnuppc-m-b"); +__static_yoink("usr/share/terminfo/x/xterm+r6f2"); +__static_yoink("usr/share/terminfo/x/xterm+256setaf"); +__static_yoink("usr/share/terminfo/x/xtalk"); +__static_yoink("usr/share/terminfo/x/xterm+sl"); +__static_yoink("usr/share/terminfo/x/x10term"); +__static_yoink("usr/share/terminfo/x/xterm+256color"); +__static_yoink("usr/share/terminfo/x/xterm+vt+edit"); +__static_yoink("usr/share/terminfo/x/x820"); +__static_yoink("usr/share/terminfo/x/xterm-direct256"); +__static_yoink("usr/share/terminfo/x/xnuppc-200x75"); +__static_yoink("usr/share/terminfo/x/xterm+sm+1006"); +__static_yoink("usr/share/terminfo/x/xl83"); +__static_yoink("usr/share/terminfo/x/xterm-xf86-v333"); +__static_yoink("usr/share/terminfo/x/xnuppc-160x64-m"); +__static_yoink("usr/share/terminfo/x/xterm-vt52"); +__static_yoink("usr/share/terminfo/x/xnuppc-112x37"); +__static_yoink("usr/share/terminfo/x/xgterm"); +__static_yoink("usr/share/terminfo/x/xnuppc+80x30"); +__static_yoink("usr/share/terminfo/x/xnuppc-m"); +__static_yoink("usr/share/terminfo/x/xterm+pcc1"); +__static_yoink("usr/share/terminfo/x/xterm-xf86-v40"); +__static_yoink("usr/share/terminfo/x/xenix"); +__static_yoink("usr/share/terminfo/x/xterm+pce2"); +__static_yoink("usr/share/terminfo/x/xnuppc-160x64"); +__static_yoink("usr/share/terminfo/x/xterm-basic"); +__static_yoink("usr/share/terminfo/x/xnuppc-f"); +__static_yoink("usr/share/terminfo/x/xterm-x11mouse"); +__static_yoink("usr/share/terminfo/x/xterm-1002"); +__static_yoink("usr/share/terminfo/x/xdku"); +__static_yoink("usr/share/terminfo/x/xterm+pcf0"); +__static_yoink("usr/share/terminfo/x/xterm.js"); +__static_yoink("usr/share/terminfo/x/xnuppc+f2"); +__static_yoink("usr/share/terminfo/c/cgc3"); +__static_yoink("usr/share/terminfo/c/cit500"); +__static_yoink("usr/share/terminfo/c/cons50-koi8r"); +__static_yoink("usr/share/terminfo/c/concept100-rv"); +__static_yoink("usr/share/terminfo/c/cons50-iso-m"); +__static_yoink("usr/share/terminfo/c/coco3"); +__static_yoink("usr/share/terminfo/c/concept100"); +__static_yoink("usr/share/terminfo/c/cygwin"); +__static_yoink("usr/share/terminfo/c/cons60l1"); +__static_yoink("usr/share/terminfo/c/cit101e-132"); +__static_yoink("usr/share/terminfo/c/cit101e-n132"); +__static_yoink("usr/share/terminfo/c/cad68-3"); +__static_yoink("usr/share/terminfo/c/cons25l1-m"); +__static_yoink("usr/share/terminfo/c/cons50-iso8859"); +__static_yoink("usr/share/terminfo/c/commodore"); +__static_yoink("usr/share/terminfo/c/chromatics"); +__static_yoink("usr/share/terminfo/c/citoh-8lpi"); +__static_yoink("usr/share/terminfo/c/cx100"); +__static_yoink("usr/share/terminfo/c/citoh-comp"); +__static_yoink("usr/share/terminfo/c/cit80"); +__static_yoink("usr/share/terminfo/c/cons25-iso-m"); +__static_yoink("usr/share/terminfo/c/contel321"); +__static_yoink("usr/share/terminfo/c/ct82"); +__static_yoink("usr/share/terminfo/c/cgc2"); +__static_yoink("usr/share/terminfo/c/contel301"); +__static_yoink("usr/share/terminfo/c/cons43-m"); +__static_yoink("usr/share/terminfo/c/cs10"); +__static_yoink("usr/share/terminfo/c/cci1"); +__static_yoink("usr/share/terminfo/c/cops"); +__static_yoink("usr/share/terminfo/c/cons50-koi8r-m"); +__static_yoink("usr/share/terminfo/c/c108-rv"); +__static_yoink("usr/share/terminfo/c/cons60r"); +__static_yoink("usr/share/terminfo/c/coherent"); +__static_yoink("usr/share/terminfo/c/ctrm"); +__static_yoink("usr/share/terminfo/c/cyb110"); +__static_yoink("usr/share/terminfo/c/cygwinB19"); +__static_yoink("usr/share/terminfo/c/cons43"); +__static_yoink("usr/share/terminfo/c/cons60-iso"); +__static_yoink("usr/share/terminfo/c/cons50r-m"); +__static_yoink("usr/share/terminfo/c/cons25-iso8859"); +__static_yoink("usr/share/terminfo/c/cops-10"); +__static_yoink("usr/share/terminfo/c/citoh-elite"); +__static_yoink("usr/share/terminfo/c/cci"); +__static_yoink("usr/share/terminfo/c/cit101e"); +__static_yoink("usr/share/terminfo/c/cops10"); +__static_yoink("usr/share/terminfo/c/cdc756"); +__static_yoink("usr/share/terminfo/c/c100-rv"); +__static_yoink("usr/share/terminfo/c/cons50"); +__static_yoink("usr/share/terminfo/c/cons25-koi8-r"); +__static_yoink("usr/share/terminfo/c/c301"); +__static_yoink("usr/share/terminfo/c/colorscan"); +__static_yoink("usr/share/terminfo/c/cs10-w"); +__static_yoink("usr/share/terminfo/c/crt"); +__static_yoink("usr/share/terminfo/c/concept108"); +__static_yoink("usr/share/terminfo/c/cg7900"); +__static_yoink("usr/share/terminfo/c/crt-vt220"); +__static_yoink("usr/share/terminfo/c/cons30"); +__static_yoink("usr/share/terminfo/c/c100-4p"); +__static_yoink("usr/share/terminfo/c/cx"); +__static_yoink("usr/share/terminfo/c/c300"); +__static_yoink("usr/share/terminfo/c/cdc721"); +__static_yoink("usr/share/terminfo/c/cdc752"); +__static_yoink("usr/share/terminfo/c/cbunix"); +__static_yoink("usr/share/terminfo/c/cons25"); +__static_yoink("usr/share/terminfo/c/c108"); +__static_yoink("usr/share/terminfo/c/contel300"); +__static_yoink("usr/share/terminfo/c/cons50l1"); +__static_yoink("usr/share/terminfo/c/cons25-debian"); +__static_yoink("usr/share/terminfo/c/concept108-8p"); +__static_yoink("usr/share/terminfo/c/cons25r"); +__static_yoink("usr/share/terminfo/c/cdc721-esc"); +__static_yoink("usr/share/terminfo/c/c100-1p"); +__static_yoink("usr/share/terminfo/c/c108-rv-4p"); +__static_yoink("usr/share/terminfo/c/concept108-w-8"); +__static_yoink("usr/share/terminfo/c/concept"); +__static_yoink("usr/share/terminfo/c/c100"); +__static_yoink("usr/share/terminfo/c/cons60r-m"); +__static_yoink("usr/share/terminfo/c/cons25w"); +__static_yoink("usr/share/terminfo/c/concept108rv4p"); +__static_yoink("usr/share/terminfo/c/c108-rv-8p"); +__static_yoink("usr/share/terminfo/c/concept-avt"); +__static_yoink("usr/share/terminfo/c/ca22851"); +__static_yoink("usr/share/terminfo/c/cit-80"); +__static_yoink("usr/share/terminfo/c/c321"); +__static_yoink("usr/share/terminfo/c/cad68-2"); +__static_yoink("usr/share/terminfo/c/cons60-iso-m"); +__static_yoink("usr/share/terminfo/c/cons60"); +__static_yoink("usr/share/terminfo/c/cons60l1-m"); +__static_yoink("usr/share/terminfo/c/cons50l1-m"); +__static_yoink("usr/share/terminfo/c/cons25r-m"); +__static_yoink("usr/share/terminfo/c/cit101e-rv"); +__static_yoink("usr/share/terminfo/c/cons60-koi8r-m"); +__static_yoink("usr/share/terminfo/c/c104"); +__static_yoink("usr/share/terminfo/c/citoh-prop"); +__static_yoink("usr/share/terminfo/c/cit101"); +__static_yoink("usr/share/terminfo/c/cdc721ll"); +__static_yoink("usr/share/terminfo/c/citoh"); +__static_yoink("usr/share/terminfo/c/cons50r"); +__static_yoink("usr/share/terminfo/c/citoh-6lpi"); +__static_yoink("usr/share/terminfo/c/cons25l1"); +__static_yoink("usr/share/terminfo/c/c108-w"); +__static_yoink("usr/share/terminfo/c/c108-8p"); +__static_yoink("usr/share/terminfo/c/cons60-koi8r"); +__static_yoink("usr/share/terminfo/c/c108-4p"); +__static_yoink("usr/share/terminfo/c/ct8500"); +__static_yoink("usr/share/terminfo/c/citoh-ps"); +__static_yoink("usr/share/terminfo/c/cons25-koi8r-m"); +__static_yoink("usr/share/terminfo/c/cons30-m"); +__static_yoink("usr/share/terminfo/c/c108-w-8p"); +__static_yoink("usr/share/terminfo/c/cyb83"); +__static_yoink("usr/share/terminfo/c/cdc456"); +__static_yoink("usr/share/terminfo/c/cons60-m"); +__static_yoink("usr/share/terminfo/c/cbblit"); +__static_yoink("usr/share/terminfo/c/cons50-m"); +__static_yoink("usr/share/terminfo/c/color_xterm"); +__static_yoink("usr/share/terminfo/c/cons25-m"); +__static_yoink("usr/share/terminfo/c/ci8510"); +__static_yoink("usr/share/terminfo/c/citoh-pica"); +__static_yoink("usr/share/terminfo/c/contel320"); +__static_yoink("usr/share/terminfo/c/citc"); +__static_yoink("usr/share/terminfo/c/concept108-4p"); +__static_yoink("usr/share/terminfo/c/cygwinDBG"); +__static_yoink("usr/share/terminfo/c/c100-rv-4p"); +__static_yoink("usr/share/terminfo/c/cit101e-n"); +__static_yoink("usr/share/terminfo/c/concept108-w8p"); +__static_yoink("usr/share/terminfo/u/unknown"); +__static_yoink("usr/share/terminfo/u/ultimaII"); +__static_yoink("usr/share/terminfo/u/uniterm"); +__static_yoink("usr/share/terminfo/u/ultima2"); +__static_yoink("usr/share/terminfo/u/uwin"); +__static_yoink("usr/share/terminfo/u/uts30"); +__static_yoink("usr/share/terminfo/u/uniterm49"); +__static_yoink("usr/share/terminfo/u/unixpc"); +__static_yoink("usr/share/terminfo/z/z-100"); +__static_yoink("usr/share/terminfo/z/z110"); +__static_yoink("usr/share/terminfo/z/zen30"); +__static_yoink("usr/share/terminfo/z/z340-nam"); +__static_yoink("usr/share/terminfo/z/z39-a"); +__static_yoink("usr/share/terminfo/z/z29b"); +__static_yoink("usr/share/terminfo/z/ztx-1-a"); +__static_yoink("usr/share/terminfo/z/zenith39-ansi"); +__static_yoink("usr/share/terminfo/z/z110bw"); +__static_yoink("usr/share/terminfo/z/z100"); +__static_yoink("usr/share/terminfo/z/z19"); +__static_yoink("usr/share/terminfo/z/ztx"); +__static_yoink("usr/share/terminfo/z/z29"); +__static_yoink("usr/share/terminfo/z/z340"); +__static_yoink("usr/share/terminfo/z/z29a-nkc-bc"); +__static_yoink("usr/share/terminfo/z/zen8001"); +__static_yoink("usr/share/terminfo/z/zen50"); +__static_yoink("usr/share/terminfo/z/zenith"); +__static_yoink("usr/share/terminfo/z/z39a"); +__static_yoink("usr/share/terminfo/z/z-100bw"); +__static_yoink("usr/share/terminfo/z/z29a"); +__static_yoink("usr/share/terminfo/z/z100bw"); +__static_yoink("usr/share/terminfo/z/z30"); +__static_yoink("usr/share/terminfo/z/z29a-kc-bc"); +__static_yoink("usr/share/terminfo/z/z29a-nkc-uc"); +__static_yoink("usr/share/terminfo/z/zenith29"); +__static_yoink("usr/share/terminfo/z/z50"); +__static_yoink("usr/share/terminfo/z/zt-1"); +__static_yoink("usr/share/terminfo/z/z29a-kc-uc"); +__static_yoink("usr/share/terminfo/z/zenith39-a"); +__static_yoink("usr/share/terminfo/z/ztx11"); +__static_yoink("usr/share/terminfo/z/z8001"); + /**************************************************************************** * Copyright 2018-2021,2022 Thomas E. Dickey * * Copyright 1998-2016,2017 Free Software Foundation, Inc. * diff --git a/third_party/ncurses/read_termcap.c b/third_party/ncurses/read_termcap.c index d204cca6e..d7da27004 100644 --- a/third_party/ncurses/read_termcap.c +++ b/third_party/ncurses/read_termcap.c @@ -1,2856 +1,3 @@ -__static_yoink("usr/share/terminfo/5/5630DMD-24"); -__static_yoink("usr/share/terminfo/5/5620"); -__static_yoink("usr/share/terminfo/5/5051"); -__static_yoink("usr/share/terminfo/5/5410-w"); -__static_yoink("usr/share/terminfo/5/5630-24"); -__static_yoink("usr/share/terminfo/k/konsole-solaris"); -__static_yoink("usr/share/terminfo/k/klone+acs"); -__static_yoink("usr/share/terminfo/k/konsole"); -__static_yoink("usr/share/terminfo/k/kitty"); -__static_yoink("usr/share/terminfo/k/kterm-co"); -__static_yoink("usr/share/terminfo/k/klone+sgr8"); -__static_yoink("usr/share/terminfo/k/kterm"); -__static_yoink("usr/share/terminfo/k/konsole-xf4x"); -__static_yoink("usr/share/terminfo/k/kds7372"); -__static_yoink("usr/share/terminfo/k/kermit"); -__static_yoink("usr/share/terminfo/k/kon"); -__static_yoink("usr/share/terminfo/k/konsole-vt420pc"); -__static_yoink("usr/share/terminfo/k/klone+sgr-dumb"); -__static_yoink("usr/share/terminfo/k/kitty-direct"); -__static_yoink("usr/share/terminfo/k/kermit-am"); -__static_yoink("usr/share/terminfo/k/kon2"); -__static_yoink("usr/share/terminfo/k/konsole-linux"); -__static_yoink("usr/share/terminfo/k/kds6402"); -__static_yoink("usr/share/terminfo/k/ktm"); -__static_yoink("usr/share/terminfo/k/kt7ix"); -__static_yoink("usr/share/terminfo/k/kds7372-w"); -__static_yoink("usr/share/terminfo/k/kaypro2"); -__static_yoink("usr/share/terminfo/k/konsole-xf3x"); -__static_yoink("usr/share/terminfo/k/konsole-16color"); -__static_yoink("usr/share/terminfo/k/konsole-256color"); -__static_yoink("usr/share/terminfo/k/k45"); -__static_yoink("usr/share/terminfo/k/konsole-vt100"); -__static_yoink("usr/share/terminfo/k/konsole+pcfkeys"); -__static_yoink("usr/share/terminfo/k/kaypro"); -__static_yoink("usr/share/terminfo/k/konsole-base"); -__static_yoink("usr/share/terminfo/k/konsole-direct"); -__static_yoink("usr/share/terminfo/k/klone+color"); -__static_yoink("usr/share/terminfo/k/kitty+common"); -__static_yoink("usr/share/terminfo/k/klone+sgr"); -__static_yoink("usr/share/terminfo/k/klone+koi8acs"); -__static_yoink("usr/share/terminfo/k/kt7"); -__static_yoink("usr/share/terminfo/k/kitty+setal"); -__static_yoink("usr/share/terminfo/k/kterm-color"); -__static_yoink("usr/share/terminfo/k/kvt"); -__static_yoink("usr/share/terminfo/2/2621"); -__static_yoink("usr/share/terminfo/2/2621a"); -__static_yoink("usr/share/terminfo/2/2621A"); -__static_yoink("usr/share/terminfo/2/2621-wl"); -__static_yoink("usr/share/terminfo/q/qnxt"); -__static_yoink("usr/share/terminfo/q/qvt119+"); -__static_yoink("usr/share/terminfo/q/qume5"); -__static_yoink("usr/share/terminfo/q/qnx4"); -__static_yoink("usr/share/terminfo/q/qdss"); -__static_yoink("usr/share/terminfo/q/qansi-w"); -__static_yoink("usr/share/terminfo/q/qnx"); -__static_yoink("usr/share/terminfo/q/qvt119p"); -__static_yoink("usr/share/terminfo/q/qvt203"); -__static_yoink("usr/share/terminfo/q/qvt101p"); -__static_yoink("usr/share/terminfo/q/qvt119p-25-w"); -__static_yoink("usr/share/terminfo/q/qnxtmono"); -__static_yoink("usr/share/terminfo/q/qvt203-25"); -__static_yoink("usr/share/terminfo/q/qvt103"); -__static_yoink("usr/share/terminfo/q/qnxt2"); -__static_yoink("usr/share/terminfo/q/qvt119p-w"); -__static_yoink("usr/share/terminfo/q/qnxt4"); -__static_yoink("usr/share/terminfo/q/qvt103-w"); -__static_yoink("usr/share/terminfo/q/qansi"); -__static_yoink("usr/share/terminfo/q/qvt203-w"); -__static_yoink("usr/share/terminfo/q/qvt203-w-am"); -__static_yoink("usr/share/terminfo/q/qnxm"); -__static_yoink("usr/share/terminfo/q/qvt119+-25-w"); -__static_yoink("usr/share/terminfo/q/qvt102"); -__static_yoink("usr/share/terminfo/q/qansi-m"); -__static_yoink("usr/share/terminfo/q/qvt119"); -__static_yoink("usr/share/terminfo/q/qnxw"); -__static_yoink("usr/share/terminfo/q/qvt119-w"); -__static_yoink("usr/share/terminfo/q/qvt101+"); -__static_yoink("usr/share/terminfo/q/qdcons"); -__static_yoink("usr/share/terminfo/q/qvt119+-25"); -__static_yoink("usr/share/terminfo/q/qvt203+"); -__static_yoink("usr/share/terminfo/q/qvt203-25-w"); -__static_yoink("usr/share/terminfo/q/qvt108"); -__static_yoink("usr/share/terminfo/q/qvt119p-25"); -__static_yoink("usr/share/terminfo/q/qume"); -__static_yoink("usr/share/terminfo/q/qvt119+-w"); -__static_yoink("usr/share/terminfo/q/qvt119-25-w"); -__static_yoink("usr/share/terminfo/q/qansi-t"); -__static_yoink("usr/share/terminfo/q/qansi-g"); -__static_yoink("usr/share/terminfo/q/qvt101"); -__static_yoink("usr/share/terminfo/m/mlterm"); -__static_yoink("usr/share/terminfo/m/mai"); -__static_yoink("usr/share/terminfo/m/msk227am"); -__static_yoink("usr/share/terminfo/m/minix-1.5"); -__static_yoink("usr/share/terminfo/m/ms-vt100"); -__static_yoink("usr/share/terminfo/m/minitel1"); -__static_yoink("usr/share/terminfo/m/mintty"); -__static_yoink("usr/share/terminfo/m/mgr-sun"); -__static_yoink("usr/share/terminfo/m/mime-hb"); -__static_yoink("usr/share/terminfo/m/msk227"); -__static_yoink("usr/share/terminfo/m/minitel1b-nb"); -__static_yoink("usr/share/terminfo/m/mach"); -__static_yoink("usr/share/terminfo/m/microterm"); -__static_yoink("usr/share/terminfo/m/mod"); -__static_yoink("usr/share/terminfo/m/mvterm"); -__static_yoink("usr/share/terminfo/m/minitel1b-80"); -__static_yoink("usr/share/terminfo/m/ms-vt100-color"); -__static_yoink("usr/share/terminfo/m/ms-vt100+"); -__static_yoink("usr/share/terminfo/m/mterm-ansi"); -__static_yoink("usr/share/terminfo/m/mime"); -__static_yoink("usr/share/terminfo/m/microterm5"); -__static_yoink("usr/share/terminfo/m/masscomp1"); -__static_yoink("usr/share/terminfo/m/m2-nam"); -__static_yoink("usr/share/terminfo/m/macintosh"); -__static_yoink("usr/share/terminfo/m/mime3ax"); -__static_yoink("usr/share/terminfo/m/msk22714"); -__static_yoink("usr/share/terminfo/m/minix-old-am"); -__static_yoink("usr/share/terminfo/m/mskermit227am"); -__static_yoink("usr/share/terminfo/m/mime-3ax"); -__static_yoink("usr/share/terminfo/m/mgterm"); -__static_yoink("usr/share/terminfo/m/mintty+common"); -__static_yoink("usr/share/terminfo/m/minitel1b"); -__static_yoink("usr/share/terminfo/m/mlterm+pcfkeys"); -__static_yoink("usr/share/terminfo/m/mimei"); -__static_yoink("usr/share/terminfo/m/minitel1-nb"); -__static_yoink("usr/share/terminfo/m/minix"); -__static_yoink("usr/share/terminfo/m/mime2a-v"); -__static_yoink("usr/share/terminfo/m/mime2a"); -__static_yoink("usr/share/terminfo/m/mac"); -__static_yoink("usr/share/terminfo/m/mod24"); -__static_yoink("usr/share/terminfo/m/mintty-direct"); -__static_yoink("usr/share/terminfo/m/mach-color"); -__static_yoink("usr/share/terminfo/m/minix-3.0"); -__static_yoink("usr/share/terminfo/m/minitel-2-nam"); -__static_yoink("usr/share/terminfo/m/mlterm-256color"); -__static_yoink("usr/share/terminfo/m/mouse-sun"); -__static_yoink("usr/share/terminfo/m/mskermit22714"); -__static_yoink("usr/share/terminfo/m/mlterm3"); -__static_yoink("usr/share/terminfo/m/minix-1.7"); -__static_yoink("usr/share/terminfo/m/mm314"); -__static_yoink("usr/share/terminfo/m/mach-gnu-color"); -__static_yoink("usr/share/terminfo/m/mime1"); -__static_yoink("usr/share/terminfo/m/mm340"); -__static_yoink("usr/share/terminfo/m/mosh-256color"); -__static_yoink("usr/share/terminfo/m/ms-terminal"); -__static_yoink("usr/share/terminfo/m/mt4520-rv"); -__static_yoink("usr/share/terminfo/m/mime2a-s"); -__static_yoink("usr/share/terminfo/m/mosh"); -__static_yoink("usr/share/terminfo/m/mt-70"); -__static_yoink("usr/share/terminfo/m/mrxvt-256color"); -__static_yoink("usr/share/terminfo/m/mimeii"); -__static_yoink("usr/share/terminfo/m/mime-fb"); -__static_yoink("usr/share/terminfo/m/modgraph48"); -__static_yoink("usr/share/terminfo/m/mono-emx"); -__static_yoink("usr/share/terminfo/m/minitel2-80"); -__static_yoink("usr/share/terminfo/m/mlterm2"); -__static_yoink("usr/share/terminfo/m/megatek"); -__static_yoink("usr/share/terminfo/m/masscomp2"); -__static_yoink("usr/share/terminfo/m/mgt"); -__static_yoink("usr/share/terminfo/m/minix-old"); -__static_yoink("usr/share/terminfo/m/microb"); -__static_yoink("usr/share/terminfo/m/mdl110"); -__static_yoink("usr/share/terminfo/m/mime2"); -__static_yoink("usr/share/terminfo/m/macterminal-w"); -__static_yoink("usr/share/terminfo/m/masscomp"); -__static_yoink("usr/share/terminfo/m/modgraph2"); -__static_yoink("usr/share/terminfo/m/memhp"); -__static_yoink("usr/share/terminfo/m/mskermit227"); -__static_yoink("usr/share/terminfo/m/mgr"); -__static_yoink("usr/share/terminfo/m/minitel"); -__static_yoink("usr/share/terminfo/m/mach-gnu"); -__static_yoink("usr/share/terminfo/m/mime3a"); -__static_yoink("usr/share/terminfo/m/mime340"); -__static_yoink("usr/share/terminfo/m/mterm"); -__static_yoink("usr/share/terminfo/m/modgraph"); -__static_yoink("usr/share/terminfo/m/mlterm-direct"); -__static_yoink("usr/share/terminfo/m/mt70"); -__static_yoink("usr/share/terminfo/m/minitel12-80"); -__static_yoink("usr/share/terminfo/m/ms-vt-utf8"); -__static_yoink("usr/share/terminfo/m/mach-bold"); -__static_yoink("usr/share/terminfo/m/mac-w"); -__static_yoink("usr/share/terminfo/m/morphos"); -__static_yoink("usr/share/terminfo/m/microbee"); -__static_yoink("usr/share/terminfo/m/mrxvt"); -__static_yoink("usr/share/terminfo/m/mime314"); -__static_yoink("usr/share/terminfo/m/minitel-2"); -__static_yoink("usr/share/terminfo/m/mgr-linux"); -__static_yoink("usr/share/terminfo/9/955-w"); -__static_yoink("usr/share/terminfo/9/955-hb"); -__static_yoink("usr/share/terminfo/9/9term"); -__static_yoink("usr/share/terminfo/l/linux+decid"); -__static_yoink("usr/share/terminfo/l/linux-nic"); -__static_yoink("usr/share/terminfo/l/linux-m"); -__static_yoink("usr/share/terminfo/l/luna68k"); -__static_yoink("usr/share/terminfo/l/linux2.6"); -__static_yoink("usr/share/terminfo/l/la120"); -__static_yoink("usr/share/terminfo/l/linux-koi8r"); -__static_yoink("usr/share/terminfo/l/linux-c"); -__static_yoink("usr/share/terminfo/l/lpr"); -__static_yoink("usr/share/terminfo/l/linux-c-nc"); -__static_yoink("usr/share/terminfo/l/lisaterm"); -__static_yoink("usr/share/terminfo/l/linux-basic"); -__static_yoink("usr/share/terminfo/l/lisa"); -__static_yoink("usr/share/terminfo/l/lft"); -__static_yoink("usr/share/terminfo/l/liswb"); -__static_yoink("usr/share/terminfo/l/linux+sfkeys"); -__static_yoink("usr/share/terminfo/l/linux3.0"); -__static_yoink("usr/share/terminfo/l/ln03"); -__static_yoink("usr/share/terminfo/l/linux"); -__static_yoink("usr/share/terminfo/l/linux2.6.26"); -__static_yoink("usr/share/terminfo/l/lft-pc850"); -__static_yoink("usr/share/terminfo/l/linux-m1"); -__static_yoink("usr/share/terminfo/l/linux-lat"); -__static_yoink("usr/share/terminfo/l/luna"); -__static_yoink("usr/share/terminfo/l/linux-m1b"); -__static_yoink("usr/share/terminfo/l/lisaterm-w"); -__static_yoink("usr/share/terminfo/l/linux-m2"); -__static_yoink("usr/share/terminfo/l/ln03-w"); -__static_yoink("usr/share/terminfo/l/linux-vt"); -__static_yoink("usr/share/terminfo/l/linux-s"); -__static_yoink("usr/share/terminfo/l/linux2.2"); -__static_yoink("usr/share/terminfo/l/linux-16color"); -__static_yoink("usr/share/terminfo/l/layer"); -__static_yoink("usr/share/terminfo/l/linux-koi8"); -__static_yoink("usr/share/terminfo/v/vt220-8"); -__static_yoink("usr/share/terminfo/v/vt340"); -__static_yoink("usr/share/terminfo/v/vsc"); -__static_yoink("usr/share/terminfo/v/vte-2007"); -__static_yoink("usr/share/terminfo/v/vt510pcdos"); -__static_yoink("usr/share/terminfo/v/vi200-f"); -__static_yoink("usr/share/terminfo/v/vt52"); -__static_yoink("usr/share/terminfo/v/vt132"); -__static_yoink("usr/share/terminfo/v/vp90"); -__static_yoink("usr/share/terminfo/v/vt100+enq"); -__static_yoink("usr/share/terminfo/v/vt100+pfkeys"); -__static_yoink("usr/share/terminfo/v/vc103"); -__static_yoink("usr/share/terminfo/v/vi200"); -__static_yoink("usr/share/terminfo/v/vtnt"); -__static_yoink("usr/share/terminfo/v/vt400-24"); -__static_yoink("usr/share/terminfo/v/vt-61"); -__static_yoink("usr/share/terminfo/v/vt125"); -__static_yoink("usr/share/terminfo/v/vt420pc"); -__static_yoink("usr/share/terminfo/v/vt300-w-nam"); -__static_yoink("usr/share/terminfo/v/vt102-w"); -__static_yoink("usr/share/terminfo/v/vt100-am"); -__static_yoink("usr/share/terminfo/v/v200-nam"); -__static_yoink("usr/share/terminfo/v/vt100-w-nam"); -__static_yoink("usr/share/terminfo/v/vt320-w"); -__static_yoink("usr/share/terminfo/v/vc414"); -__static_yoink("usr/share/terminfo/v/vc303"); -__static_yoink("usr/share/terminfo/v/vt320"); -__static_yoink("usr/share/terminfo/v/vt100-w-am"); -__static_yoink("usr/share/terminfo/v/vanilla"); -__static_yoink("usr/share/terminfo/v/vt420pcdos"); -__static_yoink("usr/share/terminfo/v/vt100-bm-o"); -__static_yoink("usr/share/terminfo/v/vc203"); -__static_yoink("usr/share/terminfo/v/vt220"); -__static_yoink("usr/share/terminfo/v/vc303a"); -__static_yoink("usr/share/terminfo/v/vip-H"); -__static_yoink("usr/share/terminfo/v/vt100+fnkeys"); -__static_yoink("usr/share/terminfo/v/viewpoint60"); -__static_yoink("usr/share/terminfo/v/vt200-old"); -__static_yoink("usr/share/terminfo/v/vt320nam"); -__static_yoink("usr/share/terminfo/v/vte"); -__static_yoink("usr/share/terminfo/v/vt200-8"); -__static_yoink("usr/share/terminfo/v/viewdata"); -__static_yoink("usr/share/terminfo/v/vi50adm"); -__static_yoink("usr/share/terminfo/v/vi300"); -__static_yoink("usr/share/terminfo/v/vt220+cvis8"); -__static_yoink("usr/share/terminfo/v/vt102-nsgr"); -__static_yoink("usr/share/terminfo/v/vt200-8bit"); -__static_yoink("usr/share/terminfo/v/vt300-w"); -__static_yoink("usr/share/terminfo/v/vte-direct"); -__static_yoink("usr/share/terminfo/v/vc403a"); -__static_yoink("usr/share/terminfo/v/vscode-direct"); -__static_yoink("usr/share/terminfo/v/v5410"); -__static_yoink("usr/share/terminfo/v/vt220-js"); -__static_yoink("usr/share/terminfo/v/vt100-bm"); -__static_yoink("usr/share/terminfo/v/vt220-base"); -__static_yoink("usr/share/terminfo/v/vt510"); -__static_yoink("usr/share/terminfo/v/vt525"); -__static_yoink("usr/share/terminfo/v/vt131"); -__static_yoink("usr/share/terminfo/v/vt102"); -__static_yoink("usr/share/terminfo/v/vt50h"); -__static_yoink("usr/share/terminfo/v/vt420f"); -__static_yoink("usr/share/terminfo/v/visa50"); -__static_yoink("usr/share/terminfo/v/vt320-w-nam"); -__static_yoink("usr/share/terminfo/v/vt52-basic"); -__static_yoink("usr/share/terminfo/v/vte-2018"); -__static_yoink("usr/share/terminfo/v/vt100"); -__static_yoink("usr/share/terminfo/v/vt400"); -__static_yoink("usr/share/terminfo/v/vip-Hw"); -__static_yoink("usr/share/terminfo/v/visual603"); -__static_yoink("usr/share/terminfo/v/vt220-8bit"); -__static_yoink("usr/share/terminfo/v/vt61"); -__static_yoink("usr/share/terminfo/v/vi300-old"); -__static_yoink("usr/share/terminfo/v/vi200-rv"); -__static_yoink("usr/share/terminfo/v/vc404"); -__static_yoink("usr/share/terminfo/v/vt220d"); -__static_yoink("usr/share/terminfo/v/vip7800-w"); -__static_yoink("usr/share/terminfo/v/vip"); -__static_yoink("usr/share/terminfo/v/vapple"); -__static_yoink("usr/share/terminfo/v/vt220+vtedit"); -__static_yoink("usr/share/terminfo/v/vt330"); -__static_yoink("usr/share/terminfo/v/vt61.5"); -__static_yoink("usr/share/terminfo/v/vt50"); -__static_yoink("usr/share/terminfo/v/vt100+keypad"); -__static_yoink("usr/share/terminfo/v/vt220+keypad"); -__static_yoink("usr/share/terminfo/v/vc404-s"); -__static_yoink("usr/share/terminfo/v/vte-2008"); -__static_yoink("usr/share/terminfo/v/vt320-k311"); -__static_yoink("usr/share/terminfo/v/vt100-s"); -__static_yoink("usr/share/terminfo/v/vs100-x10"); -__static_yoink("usr/share/terminfo/v/viewdata-o"); -__static_yoink("usr/share/terminfo/v/versaterm"); -__static_yoink("usr/share/terminfo/v/vi50"); -__static_yoink("usr/share/terminfo/v/vwmterm"); -__static_yoink("usr/share/terminfo/v/venix"); -__static_yoink("usr/share/terminfo/v/vitty"); -__static_yoink("usr/share/terminfo/v/viewpoint90"); -__static_yoink("usr/share/terminfo/v/vt220-old"); -__static_yoink("usr/share/terminfo/v/vt100-nam"); -__static_yoink("usr/share/terminfo/v/vt200-w"); -__static_yoink("usr/share/terminfo/v/vt100-w-nav"); -__static_yoink("usr/share/terminfo/v/vt52+keypad"); -__static_yoink("usr/share/terminfo/v/vt100-putty"); -__static_yoink("usr/share/terminfo/v/vk100"); -__static_yoink("usr/share/terminfo/v/vt220+pcedit"); -__static_yoink("usr/share/terminfo/v/viewpoint"); -__static_yoink("usr/share/terminfo/v/vt200-js"); -__static_yoink("usr/share/terminfo/v/vt220-nam"); -__static_yoink("usr/share/terminfo/v/vt520"); -__static_yoink("usr/share/terminfo/v/vt100-w"); -__static_yoink("usr/share/terminfo/v/vt100-vb"); -__static_yoink("usr/share/terminfo/v/vs100"); -__static_yoink("usr/share/terminfo/v/vte-2017"); -__static_yoink("usr/share/terminfo/v/vt220+cvis"); -__static_yoink("usr/share/terminfo/v/vt100-nam-w"); -__static_yoink("usr/share/terminfo/v/vte-2012"); -__static_yoink("usr/share/terminfo/v/vt100-nav"); -__static_yoink("usr/share/terminfo/v/vt100-nav-w"); -__static_yoink("usr/share/terminfo/v/vscode"); -__static_yoink("usr/share/terminfo/v/vt320-k3"); -__static_yoink("usr/share/terminfo/v/v320n"); -__static_yoink("usr/share/terminfo/v/vt100nam"); -__static_yoink("usr/share/terminfo/v/vt100+4bsd"); -__static_yoink("usr/share/terminfo/v/vt100-bot-s"); -__static_yoink("usr/share/terminfo/v/vt320-nam"); -__static_yoink("usr/share/terminfo/v/vp60"); -__static_yoink("usr/share/terminfo/v/vt420"); -__static_yoink("usr/share/terminfo/v/vi603"); -__static_yoink("usr/share/terminfo/v/vt220-w"); -__static_yoink("usr/share/terminfo/v/vt102+enq"); -__static_yoink("usr/share/terminfo/v/vc415"); -__static_yoink("usr/share/terminfo/v/vte-2014"); -__static_yoink("usr/share/terminfo/v/vte+pcfkeys"); -__static_yoink("usr/share/terminfo/v/viewpoint3a+"); -__static_yoink("usr/share/terminfo/v/vc414h"); -__static_yoink("usr/share/terminfo/v/vp3a+"); -__static_yoink("usr/share/terminfo/v/vip7800-H"); -__static_yoink("usr/share/terminfo/v/vip7800-Hw"); -__static_yoink("usr/share/terminfo/v/vt-utf8"); -__static_yoink("usr/share/terminfo/v/vt300"); -__static_yoink("usr/share/terminfo/v/vte-256color"); -__static_yoink("usr/share/terminfo/v/vt100-top-s"); -__static_yoink("usr/share/terminfo/v/vt300-nam"); -__static_yoink("usr/share/terminfo/v/v3220"); -__static_yoink("usr/share/terminfo/v/vt100-s-bot"); -__static_yoink("usr/share/terminfo/v/vremote"); -__static_yoink("usr/share/terminfo/v/vi55"); -__static_yoink("usr/share/terminfo/v/vt100-s-top"); -__static_yoink("usr/share/terminfo/v/vt510pc"); -__static_yoink("usr/share/terminfo/v/vi500"); -__static_yoink("usr/share/terminfo/v/vv100"); -__static_yoink("usr/share/terminfo/v/vt520ansi"); -__static_yoink("usr/share/terminfo/v/viewdata-rv"); -__static_yoink("usr/share/terminfo/v/vip-w"); -__static_yoink("usr/share/terminfo/v/vt200"); -__static_yoink("usr/share/terminfo/v/vt100+"); -__static_yoink("usr/share/terminfo/v/vi550"); -__static_yoink("usr/share/terminfo/v/vt420+lrmm"); -__static_yoink("usr/share/terminfo/g/gnome-2012"); -__static_yoink("usr/share/terminfo/g/guru-76-w"); -__static_yoink("usr/share/terminfo/g/go225"); -__static_yoink("usr/share/terminfo/g/gator-t"); -__static_yoink("usr/share/terminfo/g/guru-44"); -__static_yoink("usr/share/terminfo/g/go140"); -__static_yoink("usr/share/terminfo/g/gnome-2008"); -__static_yoink("usr/share/terminfo/g/go140w"); -__static_yoink("usr/share/terminfo/g/guru+unk"); -__static_yoink("usr/share/terminfo/g/gnome-rh90"); -__static_yoink("usr/share/terminfo/g/gnome-256color"); -__static_yoink("usr/share/terminfo/g/glasstty"); -__static_yoink("usr/share/terminfo/g/guru-nctxt"); -__static_yoink("usr/share/terminfo/g/gs5430-24"); -__static_yoink("usr/share/terminfo/g/go-225"); -__static_yoink("usr/share/terminfo/g/gt100a"); -__static_yoink("usr/share/terminfo/g/gnome-rh72"); -__static_yoink("usr/share/terminfo/g/guru-24"); -__static_yoink("usr/share/terminfo/g/gs6300"); -__static_yoink("usr/share/terminfo/g/gnome"); -__static_yoink("usr/share/terminfo/g/guru-s"); -__static_yoink("usr/share/terminfo/g/guru+rv"); -__static_yoink("usr/share/terminfo/g/gnome-rh62"); -__static_yoink("usr/share/terminfo/g/guru-76-w-s"); -__static_yoink("usr/share/terminfo/g/guru-rv"); -__static_yoink("usr/share/terminfo/g/gator-52"); -__static_yoink("usr/share/terminfo/g/gsi"); -__static_yoink("usr/share/terminfo/g/guru+s"); -__static_yoink("usr/share/terminfo/g/guru-76"); -__static_yoink("usr/share/terminfo/g/gnome-fc5"); -__static_yoink("usr/share/terminfo/g/guru"); -__static_yoink("usr/share/terminfo/g/gator-52t"); -__static_yoink("usr/share/terminfo/g/guru-lp"); -__static_yoink("usr/share/terminfo/g/gs5430-22"); -__static_yoink("usr/share/terminfo/g/gator"); -__static_yoink("usr/share/terminfo/g/gnome-2007"); -__static_yoink("usr/share/terminfo/g/gigi"); -__static_yoink("usr/share/terminfo/g/guru-33-s"); -__static_yoink("usr/share/terminfo/g/gt100"); -__static_yoink("usr/share/terminfo/g/gnome-rh80"); -__static_yoink("usr/share/terminfo/g/gt42"); -__static_yoink("usr/share/terminfo/g/guru-44-s"); -__static_yoink("usr/share/terminfo/g/gt40"); -__static_yoink("usr/share/terminfo/g/guru-76-wm"); -__static_yoink("usr/share/terminfo/g/guru-76-lp"); -__static_yoink("usr/share/terminfo/g/graphos-30"); -__static_yoink("usr/share/terminfo/g/guru-33-rv"); -__static_yoink("usr/share/terminfo/g/graphos"); -__static_yoink("usr/share/terminfo/g/gnome+pcfkeys"); -__static_yoink("usr/share/terminfo/g/gs5430"); -__static_yoink("usr/share/terminfo/g/guru-33"); -__static_yoink("usr/share/terminfo/g/guru-76-s"); -__static_yoink("usr/share/terminfo/b/bitgraph"); -__static_yoink("usr/share/terminfo/b/bq300-8-pc"); -__static_yoink("usr/share/terminfo/b/bq300-w-8rv"); -__static_yoink("usr/share/terminfo/b/bg1.25rv"); -__static_yoink("usr/share/terminfo/b/bq300-8"); -__static_yoink("usr/share/terminfo/b/bq300-w-rv"); -__static_yoink("usr/share/terminfo/b/bsdos-ppc"); -__static_yoink("usr/share/terminfo/b/bsdos-pc-m"); -__static_yoink("usr/share/terminfo/b/bg2.0"); -__static_yoink("usr/share/terminfo/b/beehive"); -__static_yoink("usr/share/terminfo/b/bh3m"); -__static_yoink("usr/share/terminfo/b/beehiveIIIm"); -__static_yoink("usr/share/terminfo/b/bsdos-pc-nobold"); -__static_yoink("usr/share/terminfo/b/bg2.0nv"); -__static_yoink("usr/share/terminfo/b/beehive4"); -__static_yoink("usr/share/terminfo/b/basic4"); -__static_yoink("usr/share/terminfo/b/bq300-pc-rv"); -__static_yoink("usr/share/terminfo/b/basis"); -__static_yoink("usr/share/terminfo/b/bq300-w"); -__static_yoink("usr/share/terminfo/b/bsdos-pc-mono"); -__static_yoink("usr/share/terminfo/b/bracketed+paste"); -__static_yoink("usr/share/terminfo/b/bq300-pc"); -__static_yoink("usr/share/terminfo/b/bct510a"); -__static_yoink("usr/share/terminfo/b/bg3.10rv"); -__static_yoink("usr/share/terminfo/b/bantam"); -__static_yoink("usr/share/terminfo/b/bct510d"); -__static_yoink("usr/share/terminfo/b/bq300-8-pc-rv"); -__static_yoink("usr/share/terminfo/b/bg1.25nv"); -__static_yoink("usr/share/terminfo/b/bobcat"); -__static_yoink("usr/share/terminfo/b/bsdos-pc"); -__static_yoink("usr/share/terminfo/b/bq300-pc-w-rv"); -__static_yoink("usr/share/terminfo/b/beterm"); -__static_yoink("usr/share/terminfo/b/bsdos-sparc"); -__static_yoink("usr/share/terminfo/b/bq300-8w"); -__static_yoink("usr/share/terminfo/b/b-128"); -__static_yoink("usr/share/terminfo/b/bq300-8-pc-w"); -__static_yoink("usr/share/terminfo/b/blit"); -__static_yoink("usr/share/terminfo/b/bq300-8-pc-w-rv"); -__static_yoink("usr/share/terminfo/b/bq300"); -__static_yoink("usr/share/terminfo/b/bg3.10nv"); -__static_yoink("usr/share/terminfo/b/beehive3"); -__static_yoink("usr/share/terminfo/b/bh4"); -__static_yoink("usr/share/terminfo/b/bq300-pc-w"); -__static_yoink("usr/share/terminfo/b/bterm"); -__static_yoink("usr/share/terminfo/b/bee"); -__static_yoink("usr/share/terminfo/b/beacon"); -__static_yoink("usr/share/terminfo/b/bq300-8rv"); -__static_yoink("usr/share/terminfo/b/bq300-rv"); -__static_yoink("usr/share/terminfo/b/bg1.25"); -__static_yoink("usr/share/terminfo/b/bg2.0rv"); -__static_yoink("usr/share/terminfo/b/bg3.10"); -__static_yoink("usr/share/terminfo/P/P9-W"); -__static_yoink("usr/share/terminfo/P/P7"); -__static_yoink("usr/share/terminfo/P/P14-M-W"); -__static_yoink("usr/share/terminfo/P/P8-W"); -__static_yoink("usr/share/terminfo/P/P8"); -__static_yoink("usr/share/terminfo/P/P12-M"); -__static_yoink("usr/share/terminfo/P/P4"); -__static_yoink("usr/share/terminfo/P/P14-M"); -__static_yoink("usr/share/terminfo/P/P12"); -__static_yoink("usr/share/terminfo/P/P9"); -__static_yoink("usr/share/terminfo/P/P12-W"); -__static_yoink("usr/share/terminfo/P/P14-W"); -__static_yoink("usr/share/terminfo/P/P9-8"); -__static_yoink("usr/share/terminfo/P/P9-8-W"); -__static_yoink("usr/share/terminfo/P/P12-M-W"); -__static_yoink("usr/share/terminfo/P/P14"); -__static_yoink("usr/share/terminfo/P/P5"); -__static_yoink("usr/share/terminfo/r/rxvt-cygwin"); -__static_yoink("usr/share/terminfo/r/rca"); -__static_yoink("usr/share/terminfo/r/regent40+"); -__static_yoink("usr/share/terminfo/r/regent100"); -__static_yoink("usr/share/terminfo/r/rxvt-basic"); -__static_yoink("usr/share/terminfo/r/regent40"); -__static_yoink("usr/share/terminfo/r/rxvt-color"); -__static_yoink("usr/share/terminfo/r/rbcomm-nam"); -__static_yoink("usr/share/terminfo/r/rbcomm"); -__static_yoink("usr/share/terminfo/r/rt6221"); -__static_yoink("usr/share/terminfo/r/regent"); -__static_yoink("usr/share/terminfo/r/rxvt-xpm"); -__static_yoink("usr/share/terminfo/r/rcons-color"); -__static_yoink("usr/share/terminfo/r/regent200"); -__static_yoink("usr/share/terminfo/r/regent20"); -__static_yoink("usr/share/terminfo/r/regent25"); -__static_yoink("usr/share/terminfo/r/rbcomm-w"); -__static_yoink("usr/share/terminfo/r/rxvt-16color"); -__static_yoink("usr/share/terminfo/r/rxvt-88color"); -__static_yoink("usr/share/terminfo/r/rebus3180"); -__static_yoink("usr/share/terminfo/r/rt6221-w"); -__static_yoink("usr/share/terminfo/r/rxvt-cygwin-native"); -__static_yoink("usr/share/terminfo/r/rcons"); -__static_yoink("usr/share/terminfo/r/rxvt-256color"); -__static_yoink("usr/share/terminfo/r/rtpc"); -__static_yoink("usr/share/terminfo/r/rxvt+pcfkeys"); -__static_yoink("usr/share/terminfo/r/regent60"); -__static_yoink("usr/share/terminfo/r/rxvt"); -__static_yoink("usr/share/terminfo/h/hp+labels"); -__static_yoink("usr/share/terminfo/h/hp70092A"); -__static_yoink("usr/share/terminfo/h/h19k"); -__static_yoink("usr/share/terminfo/h/hp2621-wl"); -__static_yoink("usr/share/terminfo/h/hp2644a"); -__static_yoink("usr/share/terminfo/h/hp236"); -__static_yoink("usr/share/terminfo/h/hp2626a"); -__static_yoink("usr/share/terminfo/h/hp2627a-rev"); -__static_yoink("usr/share/terminfo/h/hp2627c"); -__static_yoink("usr/share/terminfo/h/hmod1"); -__static_yoink("usr/share/terminfo/h/ha8686"); -__static_yoink("usr/share/terminfo/h/hpex"); -__static_yoink("usr/share/terminfo/h/h19kermit"); -__static_yoink("usr/share/terminfo/h/hp2621k45"); -__static_yoink("usr/share/terminfo/h/hp2622a"); -__static_yoink("usr/share/terminfo/h/hp2622"); -__static_yoink("usr/share/terminfo/h/hp2621b-kx"); -__static_yoink("usr/share/terminfo/h/hz1500"); -__static_yoink("usr/share/terminfo/h/hp2640a"); -__static_yoink("usr/share/terminfo/h/hp2626p"); -__static_yoink("usr/share/terminfo/h/hp9845"); -__static_yoink("usr/share/terminfo/h/hp700"); -__static_yoink("usr/share/terminfo/h/hp2640b"); -__static_yoink("usr/share/terminfo/h/hp2624"); -__static_yoink("usr/share/terminfo/h/hp2624b-4p-p"); -__static_yoink("usr/share/terminfo/h/ha8675"); -__static_yoink("usr/share/terminfo/h/h80"); -__static_yoink("usr/share/terminfo/h/hft"); -__static_yoink("usr/share/terminfo/h/hz1520"); -__static_yoink("usr/share/terminfo/h/hp2626-12-s"); -__static_yoink("usr/share/terminfo/h/h29a-nkc-bc"); -__static_yoink("usr/share/terminfo/h/h19-b"); -__static_yoink("usr/share/terminfo/h/heathkit-a"); -__static_yoink("usr/share/terminfo/h/hft-old"); -__static_yoink("usr/share/terminfo/h/h19-g"); -__static_yoink("usr/share/terminfo/h/hp2626-ns"); -__static_yoink("usr/share/terminfo/h/hp2382a"); -__static_yoink("usr/share/terminfo/h/hz1000"); -__static_yoink("usr/share/terminfo/h/hp2621"); -__static_yoink("usr/share/terminfo/h/hp700-wy"); -__static_yoink("usr/share/terminfo/h/hp150"); -__static_yoink("usr/share/terminfo/h/hds200"); -__static_yoink("usr/share/terminfo/h/h-100"); -__static_yoink("usr/share/terminfo/h/hp98550"); -__static_yoink("usr/share/terminfo/h/hp2623a"); -__static_yoink("usr/share/terminfo/h/hpex2"); -__static_yoink("usr/share/terminfo/h/hp300h"); -__static_yoink("usr/share/terminfo/h/hz1420"); -__static_yoink("usr/share/terminfo/h/hp110"); -__static_yoink("usr/share/terminfo/h/hp2624a"); -__static_yoink("usr/share/terminfo/h/hp2621-ba"); -__static_yoink("usr/share/terminfo/h/hp2626-x40"); -__static_yoink("usr/share/terminfo/h/hterm"); -__static_yoink("usr/share/terminfo/h/hp2621p"); -__static_yoink("usr/share/terminfo/h/hp2624b-10p-p"); -__static_yoink("usr/share/terminfo/h/hpterm-color"); -__static_yoink("usr/share/terminfo/h/hp2621a-a"); -__static_yoink("usr/share/terminfo/h/h19us"); -__static_yoink("usr/share/terminfo/h/hp70092a"); -__static_yoink("usr/share/terminfo/h/hp98550-color"); -__static_yoink("usr/share/terminfo/h/h29a-kc-bc"); -__static_yoink("usr/share/terminfo/h/hp2621b-p"); -__static_yoink("usr/share/terminfo/h/hp2397a"); -__static_yoink("usr/share/terminfo/h/hp2648a"); -__static_yoink("usr/share/terminfo/h/h19g"); -__static_yoink("usr/share/terminfo/h/hp2626-12"); -__static_yoink("usr/share/terminfo/h/hp2392"); -__static_yoink("usr/share/terminfo/h/hterm-256color"); -__static_yoink("usr/share/terminfo/h/hp262x"); -__static_yoink("usr/share/terminfo/h/hpansi"); -__static_yoink("usr/share/terminfo/h/hp2641a"); -__static_yoink("usr/share/terminfo/h/hp70092"); -__static_yoink("usr/share/terminfo/h/h19-smul"); -__static_yoink("usr/share/terminfo/h/h19a"); -__static_yoink("usr/share/terminfo/h/he80"); -__static_yoink("usr/share/terminfo/h/h19-us"); -__static_yoink("usr/share/terminfo/h/hirez100-w"); -__static_yoink("usr/share/terminfo/h/hp2621-nl"); -__static_yoink("usr/share/terminfo/h/h19-bs"); -__static_yoink("usr/share/terminfo/h/hz2000"); -__static_yoink("usr/share/terminfo/h/hz1552"); -__static_yoink("usr/share/terminfo/h/heathkit"); -__static_yoink("usr/share/terminfo/h/hirez100"); -__static_yoink("usr/share/terminfo/h/hp2623"); -__static_yoink("usr/share/terminfo/h/hp2621-fl"); -__static_yoink("usr/share/terminfo/h/hp9837"); -__static_yoink("usr/share/terminfo/h/hz1510"); -__static_yoink("usr/share/terminfo/h/hp98721"); -__static_yoink("usr/share/terminfo/h/hp98550a-color"); -__static_yoink("usr/share/terminfo/h/hpterm"); -__static_yoink("usr/share/terminfo/h/hp2627a"); -__static_yoink("usr/share/terminfo/h/hz1552-rv"); -__static_yoink("usr/share/terminfo/h/h19"); -__static_yoink("usr/share/terminfo/h/hp45"); -__static_yoink("usr/share/terminfo/h/hazel"); -__static_yoink("usr/share/terminfo/h/hp2382"); -__static_yoink("usr/share/terminfo/h/hp+color"); -__static_yoink("usr/share/terminfo/h/hurd"); -__static_yoink("usr/share/terminfo/h/hp2"); -__static_yoink("usr/share/terminfo/h/heath"); -__static_yoink("usr/share/terminfo/h/h19-u"); -__static_yoink("usr/share/terminfo/h/h-100bw"); -__static_yoink("usr/share/terminfo/h/hp2621-a"); -__static_yoink("usr/share/terminfo/h/hpterm-color2"); -__static_yoink("usr/share/terminfo/h/htx11"); -__static_yoink("usr/share/terminfo/h/hp98720"); -__static_yoink("usr/share/terminfo/h/hp2621b-kx-p"); -__static_yoink("usr/share/terminfo/h/hp2621b"); -__static_yoink("usr/share/terminfo/h/hp2624b-p"); -__static_yoink("usr/share/terminfo/h/hp2397"); -__static_yoink("usr/share/terminfo/h/hpsub"); -__static_yoink("usr/share/terminfo/h/hft-c-old"); -__static_yoink("usr/share/terminfo/h/h100"); -__static_yoink("usr/share/terminfo/h/hp2626-12x40"); -__static_yoink("usr/share/terminfo/h/h100bw"); -__static_yoink("usr/share/terminfo/h/hp2621a"); -__static_yoink("usr/share/terminfo/h/hp98550a"); -__static_yoink("usr/share/terminfo/h/hp2624-10p"); -__static_yoink("usr/share/terminfo/h/hp2624b-4p"); -__static_yoink("usr/share/terminfo/h/hp+arrows"); -__static_yoink("usr/share/terminfo/h/hp2647a"); -__static_yoink("usr/share/terminfo/h/hp2621-k45"); -__static_yoink("usr/share/terminfo/h/hp2621A"); -__static_yoink("usr/share/terminfo/h/hp"); -__static_yoink("usr/share/terminfo/h/hp2624b"); -__static_yoink("usr/share/terminfo/h/hz1520-noesc"); -__static_yoink("usr/share/terminfo/h/hp+pfk-cr"); -__static_yoink("usr/share/terminfo/h/hp+pfk+cr"); -__static_yoink("usr/share/terminfo/h/hft-c"); -__static_yoink("usr/share/terminfo/h/hp2648"); -__static_yoink("usr/share/terminfo/h/hp2645a"); -__static_yoink("usr/share/terminfo/h/h29a-nkc-uc"); -__static_yoink("usr/share/terminfo/h/heath-19"); -__static_yoink("usr/share/terminfo/h/hp2645"); -__static_yoink("usr/share/terminfo/h/hpgeneric"); -__static_yoink("usr/share/terminfo/h/h19-a"); -__static_yoink("usr/share/terminfo/h/hp2624b-10p"); -__static_yoink("usr/share/terminfo/h/hp2626-s"); -__static_yoink("usr/share/terminfo/h/hp+printer"); -__static_yoink("usr/share/terminfo/h/hp2624a-10p"); -__static_yoink("usr/share/terminfo/h/hp2621-nt"); -__static_yoink("usr/share/terminfo/h/h29a-kc-uc"); -__static_yoink("usr/share/terminfo/h/hp2626"); -__static_yoink("usr/share/terminfo/h/heath-ansi"); -__static_yoink("usr/share/terminfo/h/hp2621-48"); -__static_yoink("usr/share/terminfo/h/hp+pfk+arrows"); -__static_yoink("usr/share/terminfo/h/hp2621p-a"); -__static_yoink("usr/share/terminfo/e/emu"); -__static_yoink("usr/share/terminfo/e/esprit"); -__static_yoink("usr/share/terminfo/e/elks-vt52"); -__static_yoink("usr/share/terminfo/e/ergo4000"); -__static_yoink("usr/share/terminfo/e/ep40"); -__static_yoink("usr/share/terminfo/e/ecma+italics"); -__static_yoink("usr/share/terminfo/e/excel64-rv"); -__static_yoink("usr/share/terminfo/e/excel64"); -__static_yoink("usr/share/terminfo/e/eterm-color"); -__static_yoink("usr/share/terminfo/e/elks-glasstty"); -__static_yoink("usr/share/terminfo/e/emots"); -__static_yoink("usr/share/terminfo/e/excel62"); -__static_yoink("usr/share/terminfo/e/emu-220"); -__static_yoink("usr/share/terminfo/e/excel62-w"); -__static_yoink("usr/share/terminfo/e/esprit-am"); -__static_yoink("usr/share/terminfo/e/eterm"); -__static_yoink("usr/share/terminfo/e/ecma+color"); -__static_yoink("usr/share/terminfo/e/ex155"); -__static_yoink("usr/share/terminfo/e/exec80"); -__static_yoink("usr/share/terminfo/e/elks"); -__static_yoink("usr/share/terminfo/e/ep4000"); -__static_yoink("usr/share/terminfo/e/ep48"); -__static_yoink("usr/share/terminfo/e/emx-base"); -__static_yoink("usr/share/terminfo/e/elks-ansi"); -__static_yoink("usr/share/terminfo/e/ecma+sgr"); -__static_yoink("usr/share/terminfo/e/excel64-w"); -__static_yoink("usr/share/terminfo/e/ecma+strikeout"); -__static_yoink("usr/share/terminfo/e/ep4080"); -__static_yoink("usr/share/terminfo/e/excel62-rv"); -__static_yoink("usr/share/terminfo/e/ecma+index"); -__static_yoink("usr/share/terminfo/e/env230"); -__static_yoink("usr/share/terminfo/e/envision230"); -__static_yoink("usr/share/terminfo/i/intext2"); -__static_yoink("usr/share/terminfo/i/infoton"); -__static_yoink("usr/share/terminfo/i/ibmmpel-c"); -__static_yoink("usr/share/terminfo/i/ibm3161"); -__static_yoink("usr/share/terminfo/i/ibm6154"); -__static_yoink("usr/share/terminfo/i/iris-ansi"); -__static_yoink("usr/share/terminfo/i/ibmpc"); -__static_yoink("usr/share/terminfo/i/intertube"); -__static_yoink("usr/share/terminfo/i/ims950"); -__static_yoink("usr/share/terminfo/i/ibm8604"); -__static_yoink("usr/share/terminfo/i/ibm8513"); -__static_yoink("usr/share/terminfo/i/ibm8514"); -__static_yoink("usr/share/terminfo/i/ibmapa16"); -__static_yoink("usr/share/terminfo/i/iq140"); -__static_yoink("usr/share/terminfo/i/i100"); -__static_yoink("usr/share/terminfo/i/iris-ansi-ap"); -__static_yoink("usr/share/terminfo/i/ibm-system1"); -__static_yoink("usr/share/terminfo/i/ims950-rv"); -__static_yoink("usr/share/terminfo/i/ibmpc3r"); -__static_yoink("usr/share/terminfo/i/ibm8512"); -__static_yoink("usr/share/terminfo/i/ibm5081-c"); -__static_yoink("usr/share/terminfo/i/ibm6154-c"); -__static_yoink("usr/share/terminfo/i/iterm2-direct"); -__static_yoink("usr/share/terminfo/i/ibm5051"); -__static_yoink("usr/share/terminfo/i/ibm6153"); -__static_yoink("usr/share/terminfo/i/ibm327x"); -__static_yoink("usr/share/terminfo/i/intertec"); -__static_yoink("usr/share/terminfo/i/ibmega"); -__static_yoink("usr/share/terminfo/i/ibm3151"); -__static_yoink("usr/share/terminfo/i/ibmmono"); -__static_yoink("usr/share/terminfo/i/ibmpc3r-mono"); -__static_yoink("usr/share/terminfo/i/ibm5081"); -__static_yoink("usr/share/terminfo/i/ibmpcx"); -__static_yoink("usr/share/terminfo/i/ibmvga"); -__static_yoink("usr/share/terminfo/i/ibmapa8c"); -__static_yoink("usr/share/terminfo/i/ips"); -__static_yoink("usr/share/terminfo/i/iterm"); -__static_yoink("usr/share/terminfo/i/ibmx"); -__static_yoink("usr/share/terminfo/i/icl6402"); -__static_yoink("usr/share/terminfo/i/ibcs2"); -__static_yoink("usr/share/terminfo/i/ibmapa8c-c"); -__static_yoink("usr/share/terminfo/i/ibm5154-c"); -__static_yoink("usr/share/terminfo/i/ibm+16color"); -__static_yoink("usr/share/terminfo/i/i3164"); -__static_yoink("usr/share/terminfo/i/ibmvga-c"); -__static_yoink("usr/share/terminfo/i/ibm5154"); -__static_yoink("usr/share/terminfo/i/iris-ansi-net"); -__static_yoink("usr/share/terminfo/i/ibm3164"); -__static_yoink("usr/share/terminfo/i/ibm6153-40"); -__static_yoink("usr/share/terminfo/i/iTerm2.app"); -__static_yoink("usr/share/terminfo/i/ibm6153-90"); -__static_yoink("usr/share/terminfo/i/ibm3163"); -__static_yoink("usr/share/terminfo/i/ibmpc3"); -__static_yoink("usr/share/terminfo/i/iq120"); -__static_yoink("usr/share/terminfo/i/intextii"); -__static_yoink("usr/share/terminfo/i/i400"); -__static_yoink("usr/share/terminfo/i/ibm8503"); -__static_yoink("usr/share/terminfo/i/interix"); -__static_yoink("usr/share/terminfo/i/ibmaed"); -__static_yoink("usr/share/terminfo/i/ifmr"); -__static_yoink("usr/share/terminfo/i/ibm-apl"); -__static_yoink("usr/share/terminfo/i/iris-color"); -__static_yoink("usr/share/terminfo/i/ibmega-c"); -__static_yoink("usr/share/terminfo/i/ibm-pc"); -__static_yoink("usr/share/terminfo/i/ibm8507"); -__static_yoink("usr/share/terminfo/i/ibmapa8"); -__static_yoink("usr/share/terminfo/i/ibm5151"); -__static_yoink("usr/share/terminfo/i/ims-ansi"); -__static_yoink("usr/share/terminfo/i/icl6404"); -__static_yoink("usr/share/terminfo/i/ipsi"); -__static_yoink("usr/share/terminfo/i/intext"); -__static_yoink("usr/share/terminfo/i/intertube2"); -__static_yoink("usr/share/terminfo/i/interix-nti"); -__static_yoink("usr/share/terminfo/i/infoton2"); -__static_yoink("usr/share/terminfo/i/ibm+color"); -__static_yoink("usr/share/terminfo/i/iTerm.app"); -__static_yoink("usr/share/terminfo/i/iris40"); -__static_yoink("usr/share/terminfo/i/ibm3161-C"); -__static_yoink("usr/share/terminfo/i/iterm2"); -__static_yoink("usr/share/terminfo/i/ibm3101"); -__static_yoink("usr/share/terminfo/i/icl6404-w"); -__static_yoink("usr/share/terminfo/i/ibm3162"); -__static_yoink("usr/share/terminfo/i/i3101"); -__static_yoink("usr/share/terminfo/i/ibm6155"); -__static_yoink("usr/share/terminfo/i/ibm8514-c"); -__static_yoink("usr/share/terminfo/i/ims950-b"); -__static_yoink("usr/share/terminfo/w/wy520-vb"); -__static_yoink("usr/share/terminfo/w/wy160-w-vb"); -__static_yoink("usr/share/terminfo/w/wyse520-24"); -__static_yoink("usr/share/terminfo/w/wyse60-43-w"); -__static_yoink("usr/share/terminfo/w/wyse60-w"); -__static_yoink("usr/share/terminfo/w/wy60-43"); -__static_yoink("usr/share/terminfo/w/wy325-80"); -__static_yoink("usr/share/terminfo/w/wy325-43w-vb"); -__static_yoink("usr/share/terminfo/w/wy50-vb"); -__static_yoink("usr/share/terminfo/w/wyse325-25w"); -__static_yoink("usr/share/terminfo/w/wy85-8bit"); -__static_yoink("usr/share/terminfo/w/wy370-w"); -__static_yoink("usr/share/terminfo/w/wy-75ap"); -__static_yoink("usr/share/terminfo/w/wyse50-vb"); -__static_yoink("usr/share/terminfo/w/wyse520-pc-vb"); -__static_yoink("usr/share/terminfo/w/wy325-25w"); -__static_yoink("usr/share/terminfo/w/wyse150-25"); -__static_yoink("usr/share/terminfo/w/wyse150-w-vb"); -__static_yoink("usr/share/terminfo/w/wy99gt-vb"); -__static_yoink("usr/share/terminfo/w/wyse60-PC"); -__static_yoink("usr/share/terminfo/w/wy120-wvb"); -__static_yoink("usr/share/terminfo/w/wy160-wvb"); -__static_yoink("usr/share/terminfo/w/wyse325-42w"); -__static_yoink("usr/share/terminfo/w/wyse75-w"); -__static_yoink("usr/share/terminfo/w/wy99fgta"); -__static_yoink("usr/share/terminfo/w/wsvt25m"); -__static_yoink("usr/share/terminfo/w/wyse520-48pc"); -__static_yoink("usr/share/terminfo/w/wy50-wvb"); -__static_yoink("usr/share/terminfo/w/wy520-36"); -__static_yoink("usr/share/terminfo/w/wy160"); -__static_yoink("usr/share/terminfo/w/wy60-316X"); -__static_yoink("usr/share/terminfo/w/wy150"); -__static_yoink("usr/share/terminfo/w/wyse160-w"); -__static_yoink("usr/share/terminfo/w/wyse350-wvb"); -__static_yoink("usr/share/terminfo/w/wy520-36wpc"); -__static_yoink("usr/share/terminfo/w/wy370-vb"); -__static_yoink("usr/share/terminfo/w/wyse520-epc-w"); -__static_yoink("usr/share/terminfo/w/wy325-42"); -__static_yoink("usr/share/terminfo/w/wy75-vb"); -__static_yoink("usr/share/terminfo/w/wyse370"); -__static_yoink("usr/share/terminfo/w/wy99gt-tek"); -__static_yoink("usr/share/terminfo/w/wy350-vb"); -__static_yoink("usr/share/terminfo/w/wy85-vb"); -__static_yoink("usr/share/terminfo/w/wsiris"); -__static_yoink("usr/share/terminfo/w/wy520-48pc"); -__static_yoink("usr/share/terminfo/w/wyse+sl"); -__static_yoink("usr/share/terminfo/w/wy100q"); -__static_yoink("usr/share/terminfo/w/wy150-w"); -__static_yoink("usr/share/terminfo/w/wy325-vb"); -__static_yoink("usr/share/terminfo/w/wy50-w"); -__static_yoink("usr/share/terminfo/w/wy520-epc-24"); -__static_yoink("usr/share/terminfo/w/wyse325-42"); -__static_yoink("usr/share/terminfo/w/wy520-36pc"); -__static_yoink("usr/share/terminfo/w/wyse60-vb"); -__static_yoink("usr/share/terminfo/w/wy150-25"); -__static_yoink("usr/share/terminfo/w/wy325-42w"); -__static_yoink("usr/share/terminfo/w/wyse75ap"); -__static_yoink("usr/share/terminfo/w/wy325"); -__static_yoink("usr/share/terminfo/w/wyse185-24"); -__static_yoink("usr/share/terminfo/w/wy160-42"); -__static_yoink("usr/share/terminfo/w/wy350-w"); -__static_yoink("usr/share/terminfo/w/wy75-wvb"); -__static_yoink("usr/share/terminfo/w/wyse185-w"); -__static_yoink("usr/share/terminfo/w/wyse60-43"); -__static_yoink("usr/share/terminfo/w/wyse160-25"); -__static_yoink("usr/share/terminfo/w/wyse75-vb"); -__static_yoink("usr/share/terminfo/w/wy160-tek"); -__static_yoink("usr/share/terminfo/w/wy60-42-w"); -__static_yoink("usr/share/terminfo/w/wyse160-43-w"); -__static_yoink("usr/share/terminfo/w/wyse60-wvb"); -__static_yoink("usr/share/terminfo/w/wy160-w"); -__static_yoink("usr/share/terminfo/w/wy520-epc-vb"); -__static_yoink("usr/share/terminfo/w/wy350"); -__static_yoink("usr/share/terminfo/w/wyse60-25-w"); -__static_yoink("usr/share/terminfo/w/wy325w-24"); -__static_yoink("usr/share/terminfo/w/wy350-wvb"); -__static_yoink("usr/share/terminfo/w/wy325-25"); -__static_yoink("usr/share/terminfo/w/wyse520-48"); -__static_yoink("usr/share/terminfo/w/wyse99gt"); -__static_yoink("usr/share/terminfo/w/wy520-epc-w"); -__static_yoink("usr/share/terminfo/w/wy520-36w"); -__static_yoink("usr/share/terminfo/w/wy30-vb"); -__static_yoink("usr/share/terminfo/w/wy185-vb"); -__static_yoink("usr/share/terminfo/w/wyse50-mc"); -__static_yoink("usr/share/terminfo/w/wyse520-wvb"); -__static_yoink("usr/share/terminfo/w/wyse60-25"); -__static_yoink("usr/share/terminfo/w/wyse325-25"); -__static_yoink("usr/share/terminfo/w/wy75"); -__static_yoink("usr/share/terminfo/w/wy520"); -__static_yoink("usr/share/terminfo/w/wyse120-25-w"); -__static_yoink("usr/share/terminfo/w/wyse99gt-vb"); -__static_yoink("usr/share/terminfo/w/wyse520-epc"); -__static_yoink("usr/share/terminfo/w/wy60-43-w"); -__static_yoink("usr/share/terminfo/w/wy185-w"); -__static_yoink("usr/share/terminfo/w/wy160-43"); -__static_yoink("usr/share/terminfo/w/wyse160-wvb"); -__static_yoink("usr/share/terminfo/w/wy99fa"); -__static_yoink("usr/share/terminfo/w/wy100"); -__static_yoink("usr/share/terminfo/w/wyse60-42"); -__static_yoink("usr/share/terminfo/w/wrenw"); -__static_yoink("usr/share/terminfo/w/wren"); -__static_yoink("usr/share/terminfo/w/wyse150-vb"); -__static_yoink("usr/share/terminfo/w/wyse325"); -__static_yoink("usr/share/terminfo/w/wy160-42-w"); -__static_yoink("usr/share/terminfo/w/wyse60"); -__static_yoink("usr/share/terminfo/w/wy325-43"); -__static_yoink("usr/share/terminfo/w/wy120-vb"); -__static_yoink("usr/share/terminfo/w/wyse120-w"); -__static_yoink("usr/share/terminfo/w/wy150-w-vb"); -__static_yoink("usr/share/terminfo/w/wyse185-vb"); -__static_yoink("usr/share/terminfo/w/wyse85"); -__static_yoink("usr/share/terminfo/w/wy520-24"); -__static_yoink("usr/share/terminfo/w/wyse350-w"); -__static_yoink("usr/share/terminfo/w/wy60-42"); -__static_yoink("usr/share/terminfo/w/wy370-tek"); -__static_yoink("usr/share/terminfo/w/wyse520-36pc"); -__static_yoink("usr/share/terminfo/w/wy60-w"); -__static_yoink("usr/share/terminfo/w/wyse50-w"); -__static_yoink("usr/share/terminfo/w/wy99gt-w"); -__static_yoink("usr/share/terminfo/w/wyse350"); -__static_yoink("usr/share/terminfo/w/wy99a-ansi"); -__static_yoink("usr/share/terminfo/w/wyse520-vb"); -__static_yoink("usr/share/terminfo/w/wyse160-42-w"); -__static_yoink("usr/share/terminfo/w/wyse-vp"); -__static_yoink("usr/share/terminfo/w/wyse520-p-wvb"); -__static_yoink("usr/share/terminfo/w/wyse120-vb"); -__static_yoink("usr/share/terminfo/w/wy99gt-w-vb"); -__static_yoink("usr/share/terminfo/w/wy60-25-w"); -__static_yoink("usr/share/terminfo/w/wy520-48w"); -__static_yoink("usr/share/terminfo/w/wy120-w-vb"); -__static_yoink("usr/share/terminfo/w/wyse520-36"); -__static_yoink("usr/share/terminfo/w/wy185"); -__static_yoink("usr/share/terminfo/w/wy75-mc"); -__static_yoink("usr/share/terminfo/w/wy520-w"); -__static_yoink("usr/share/terminfo/w/wyse85-wvb"); -__static_yoink("usr/share/terminfo/w/wy160-25"); -__static_yoink("usr/share/terminfo/w/wy50"); -__static_yoink("usr/share/terminfo/w/wyse60-316X"); -__static_yoink("usr/share/terminfo/w/wy75-w"); -__static_yoink("usr/share/terminfo/w/wy99gt-25"); -__static_yoink("usr/share/terminfo/w/wyse520-48wpc"); -__static_yoink("usr/share/terminfo/w/wyse185-wvb"); -__static_yoink("usr/share/terminfo/w/wyse120"); -__static_yoink("usr/share/terminfo/w/wyse185"); -__static_yoink("usr/share/terminfo/w/wy520-48wpc"); -__static_yoink("usr/share/terminfo/w/wy370-101k"); -__static_yoink("usr/share/terminfo/w/wyse50-wvb"); -__static_yoink("usr/share/terminfo/w/wy325-42wvb"); -__static_yoink("usr/share/terminfo/w/wy370-wvb"); -__static_yoink("usr/share/terminfo/w/wyse350-vb"); -__static_yoink("usr/share/terminfo/w/wyse325-43"); -__static_yoink("usr/share/terminfo/w/wyse75"); -__static_yoink("usr/share/terminfo/w/wyse150-25-w"); -__static_yoink("usr/share/terminfo/w/wyse85-vb"); -__static_yoink("usr/share/terminfo/w/wy325-43w"); -__static_yoink("usr/share/terminfo/w/wy85-w"); -__static_yoink("usr/share/terminfo/w/wyse325-vb"); -__static_yoink("usr/share/terminfo/w/wy370-rv"); -__static_yoink("usr/share/terminfo/w/wy520-wvb"); -__static_yoink("usr/share/terminfo/w/wy-99fgt"); -__static_yoink("usr/share/terminfo/w/wy99gt"); -__static_yoink("usr/share/terminfo/w/wy325-w"); -__static_yoink("usr/share/terminfo/w/wy160-vb"); -__static_yoink("usr/share/terminfo/w/wy85-wvb"); -__static_yoink("usr/share/terminfo/w/wy60-vb"); -__static_yoink("usr/share/terminfo/w/wy325-42w-vb"); -__static_yoink("usr/share/terminfo/w/wyse160"); -__static_yoink("usr/share/terminfo/w/wyse85-8bit"); -__static_yoink("usr/share/terminfo/w/wy370-nk"); -__static_yoink("usr/share/terminfo/w/wyse520-pc-24"); -__static_yoink("usr/share/terminfo/w/wyse99gt-25"); -__static_yoink("usr/share/terminfo/w/wyse99gt-w"); -__static_yoink("usr/share/terminfo/w/wy325-43wvb"); -__static_yoink("usr/share/terminfo/w/wy60-AT"); -__static_yoink("usr/share/terminfo/w/wyse-325"); -__static_yoink("usr/share/terminfo/w/wy99f"); -__static_yoink("usr/share/terminfo/w/wy185-24"); -__static_yoink("usr/share/terminfo/w/wyse30"); -__static_yoink("usr/share/terminfo/w/wyse520-36wpc"); -__static_yoink("usr/share/terminfo/w/wy520-48"); -__static_yoink("usr/share/terminfo/w/wy370-105k"); -__static_yoink("usr/share/terminfo/w/wy75ap"); -__static_yoink("usr/share/terminfo/w/wy120-25"); -__static_yoink("usr/share/terminfo/w/wyse75-mc"); -__static_yoink("usr/share/terminfo/w/wyse150-w"); -__static_yoink("usr/share/terminfo/w/wyse-75ap"); -__static_yoink("usr/share/terminfo/w/wyse325-wvb"); -__static_yoink("usr/share/terminfo/w/wyse99gt-wvb"); -__static_yoink("usr/share/terminfo/w/wyse520-48w"); -__static_yoink("usr/share/terminfo/w/wy60-25"); -__static_yoink("usr/share/terminfo/w/wy520-epc"); -__static_yoink("usr/share/terminfo/w/wyse150"); -__static_yoink("usr/share/terminfo/w/wy160-43-w"); -__static_yoink("usr/share/terminfo/w/wyse520"); -__static_yoink("usr/share/terminfo/w/wy99gt-25-w"); -__static_yoink("usr/share/terminfo/w/wyse99gt-25-w"); -__static_yoink("usr/share/terminfo/w/wy120-w"); -__static_yoink("usr/share/terminfo/w/wy370"); -__static_yoink("usr/share/terminfo/w/wyse30-mc"); -__static_yoink("usr/share/terminfo/w/wy185-wvb"); -__static_yoink("usr/share/terminfo/w/wy60-w-vb"); -__static_yoink("usr/share/terminfo/w/wy370-EPC"); -__static_yoink("usr/share/terminfo/w/wy99-ansi"); -__static_yoink("usr/share/terminfo/w/wy120"); -__static_yoink("usr/share/terminfo/w/wyse75-wvb"); -__static_yoink("usr/share/terminfo/w/wy50-mc"); -__static_yoink("usr/share/terminfo/w/wy325-wvb"); -__static_yoink("usr/share/terminfo/w/wy-99fgta"); -__static_yoink("usr/share/terminfo/w/wy150-25-w"); -__static_yoink("usr/share/terminfo/w/wy99gt-wvb"); -__static_yoink("usr/share/terminfo/w/wy160-25-w"); -__static_yoink("usr/share/terminfo/w/wy85"); -__static_yoink("usr/share/terminfo/w/wyse160-25-w"); -__static_yoink("usr/share/terminfo/w/wy150-vb"); -__static_yoink("usr/share/terminfo/w/wsvt25"); -__static_yoink("usr/share/terminfo/w/wyse120-wvb"); -__static_yoink("usr/share/terminfo/w/wyse60-AT"); -__static_yoink("usr/share/terminfo/w/wy30-mc"); -__static_yoink("usr/share/terminfo/w/wyse325-43w"); -__static_yoink("usr/share/terminfo/w/wy99fgt"); -__static_yoink("usr/share/terminfo/w/wy325-w-vb"); -__static_yoink("usr/share/terminfo/w/wy120-25-w"); -__static_yoink("usr/share/terminfo/w/wyse160-42"); -__static_yoink("usr/share/terminfo/w/wy520-epc-wvb"); -__static_yoink("usr/share/terminfo/w/wyse30-vb"); -__static_yoink("usr/share/terminfo/w/wy30"); -__static_yoink("usr/share/terminfo/w/wyse120-25"); -__static_yoink("usr/share/terminfo/w/wy60-PC"); -__static_yoink("usr/share/terminfo/w/wyse520-w"); -__static_yoink("usr/share/terminfo/w/wyse325-w"); -__static_yoink("usr/share/terminfo/w/wy60-wvb"); -__static_yoink("usr/share/terminfo/w/wyse160-vb"); -__static_yoink("usr/share/terminfo/w/wy60"); -__static_yoink("usr/share/terminfo/w/wyse520-36w"); -__static_yoink("usr/share/terminfo/w/wyse60-42-w"); -__static_yoink("usr/share/terminfo/w/wyse160-43"); -__static_yoink("usr/share/terminfo/w/wyse50"); -__static_yoink("usr/share/terminfo/w/wyse85-w"); -__static_yoink("usr/share/terminfo/6/605x"); -__static_yoink("usr/share/terminfo/6/605x-dg"); -__static_yoink("usr/share/terminfo/6/630-lm"); -__static_yoink("usr/share/terminfo/6/630MTG-24"); -__static_yoink("usr/share/terminfo/6/6053"); -__static_yoink("usr/share/terminfo/6/6053-dg"); -__static_yoink("usr/share/terminfo/7/730MTG-41"); -__static_yoink("usr/share/terminfo/7/730MTGr-24"); -__static_yoink("usr/share/terminfo/7/730MTG-24"); -__static_yoink("usr/share/terminfo/7/730MTG-41r"); -__static_yoink("usr/share/terminfo/7/730MTGr"); -__static_yoink("usr/share/terminfo/o/o31"); -__static_yoink("usr/share/terminfo/o/oabm85h"); -__static_yoink("usr/share/terminfo/o/osexec"); -__static_yoink("usr/share/terminfo/o/otek4112"); -__static_yoink("usr/share/terminfo/o/origpc3"); -__static_yoink("usr/share/terminfo/o/ojerq"); -__static_yoink("usr/share/terminfo/o/osborne-w"); -__static_yoink("usr/share/terminfo/o/opennt-25-nti"); -__static_yoink("usr/share/terminfo/o/opennt-60-w"); -__static_yoink("usr/share/terminfo/o/opennt-25-w"); -__static_yoink("usr/share/terminfo/o/oc100"); -__static_yoink("usr/share/terminfo/o/oldsun"); -__static_yoink("usr/share/terminfo/o/origibmpc3"); -__static_yoink("usr/share/terminfo/o/osborne"); -__static_yoink("usr/share/terminfo/o/otek4114"); -__static_yoink("usr/share/terminfo/o/osborne1-w"); -__static_yoink("usr/share/terminfo/o/oldibmpc3"); -__static_yoink("usr/share/terminfo/o/old-st"); -__static_yoink("usr/share/terminfo/o/opennt-35"); -__static_yoink("usr/share/terminfo/o/opennt-100"); -__static_yoink("usr/share/terminfo/o/opennt-50"); -__static_yoink("usr/share/terminfo/o/opennt-60-nti"); -__static_yoink("usr/share/terminfo/o/opennt-50-w"); -__static_yoink("usr/share/terminfo/o/opennt"); -__static_yoink("usr/share/terminfo/o/opennt-50-nti"); -__static_yoink("usr/share/terminfo/o/o4112-nd"); -__static_yoink("usr/share/terminfo/o/ofcons"); -__static_yoink("usr/share/terminfo/o/opennt-25"); -__static_yoink("usr/share/terminfo/o/omron"); -__static_yoink("usr/share/terminfo/o/owl"); -__static_yoink("usr/share/terminfo/o/opennt-25-w-vt"); -__static_yoink("usr/share/terminfo/o/oblit"); -__static_yoink("usr/share/terminfo/o/opennt-w"); -__static_yoink("usr/share/terminfo/o/oldpc3"); -__static_yoink("usr/share/terminfo/o/opennt-nti"); -__static_yoink("usr/share/terminfo/o/oconcept"); -__static_yoink("usr/share/terminfo/o/opus3n1+"); -__static_yoink("usr/share/terminfo/o/opennt-w-vt"); -__static_yoink("usr/share/terminfo/o/o85h"); -__static_yoink("usr/share/terminfo/o/opennt-35-nti"); -__static_yoink("usr/share/terminfo/o/otek4113"); -__static_yoink("usr/share/terminfo/o/os9LII"); -__static_yoink("usr/share/terminfo/o/opennt-100-nti"); -__static_yoink("usr/share/terminfo/o/otek4115"); -__static_yoink("usr/share/terminfo/o/opennt-60"); -__static_yoink("usr/share/terminfo/o/osborne1"); -__static_yoink("usr/share/terminfo/o/opennt-35-w"); -__static_yoink("usr/share/terminfo/n/nsterm-acs-c-s"); -__static_yoink("usr/share/terminfo/n/nec"); -__static_yoink("usr/share/terminfo/n/ncr160vt100pp"); -__static_yoink("usr/share/terminfo/n/nsterm-s-acs"); -__static_yoink("usr/share/terminfo/n/news-42-sjis"); -__static_yoink("usr/share/terminfo/n/nec5520"); -__static_yoink("usr/share/terminfo/n/nsterm-m-s-7"); -__static_yoink("usr/share/terminfo/n/nsterm-acs-s"); -__static_yoink("usr/share/terminfo/n/nsterm-build326"); -__static_yoink("usr/share/terminfo/n/ncr260vt300an"); -__static_yoink("usr/share/terminfo/n/ndr9500-25-mc"); -__static_yoink("usr/share/terminfo/n/news-33-sjis"); -__static_yoink("usr/share/terminfo/n/ncsa"); -__static_yoink("usr/share/terminfo/n/nsterm-7-m"); -__static_yoink("usr/share/terminfo/n/ncr260vt100wan"); -__static_yoink("usr/share/terminfo/n/ndr9500-25-mc-nl"); -__static_yoink("usr/share/terminfo/n/nsterm-m-s"); -__static_yoink("usr/share/terminfo/n/ncr260wy350wpp"); -__static_yoink("usr/share/terminfo/n/ncr260wy60pp"); -__static_yoink("usr/share/terminfo/n/ncr160vt200pp"); -__static_yoink("usr/share/terminfo/n/nwe501-a"); -__static_yoink("usr/share/terminfo/n/nwp514-a"); -__static_yoink("usr/share/terminfo/n/nsterm-256color"); -__static_yoink("usr/share/terminfo/n/ncr260vt200wpp"); -__static_yoink("usr/share/terminfo/n/ncr260intwan"); -__static_yoink("usr/share/terminfo/n/nsterm"); -__static_yoink("usr/share/terminfo/n/ntconsole-25-w-vt"); -__static_yoink("usr/share/terminfo/n/nsterm-c-7"); -__static_yoink("usr/share/terminfo/n/ndr9500-25"); -__static_yoink("usr/share/terminfo/n/ncr7901"); -__static_yoink("usr/share/terminfo/n/ncr260vt200an"); -__static_yoink("usr/share/terminfo/n/nwp514-o"); -__static_yoink("usr/share/terminfo/n/nansi.sys"); -__static_yoink("usr/share/terminfo/n/ncr260intwpp"); -__static_yoink("usr/share/terminfo/n/nsterm-build440"); -__static_yoink("usr/share/terminfo/n/northstar"); -__static_yoink("usr/share/terminfo/n/ncr160wy50+pp"); -__static_yoink("usr/share/terminfo/n/nsterm-build361"); -__static_yoink("usr/share/terminfo/n/nwp512"); -__static_yoink("usr/share/terminfo/n/ncr260vppp"); -__static_yoink("usr/share/terminfo/n/ntconsole-35-w"); -__static_yoink("usr/share/terminfo/n/news33"); -__static_yoink("usr/share/terminfo/n/ntconsole-35-nti"); -__static_yoink("usr/share/terminfo/n/ncr160vt300an"); -__static_yoink("usr/share/terminfo/n/ncr160vt200an"); -__static_yoink("usr/share/terminfo/n/nsterm-7"); -__static_yoink("usr/share/terminfo/n/nextshell"); -__static_yoink("usr/share/terminfo/n/ntconsole-25"); -__static_yoink("usr/share/terminfo/n/news40-a"); -__static_yoink("usr/share/terminfo/n/ncr260wy325pp"); -__static_yoink("usr/share/terminfo/n/ncr260vt100an"); -__static_yoink("usr/share/terminfo/n/ntconsole-60-w"); -__static_yoink("usr/share/terminfo/n/news-old-unk"); -__static_yoink("usr/share/terminfo/n/ntconsole-50-w"); -__static_yoink("usr/share/terminfo/n/nsterm+c"); -__static_yoink("usr/share/terminfo/n/ncr160vt200wpp"); -__static_yoink("usr/share/terminfo/n/news-42-euc"); -__static_yoink("usr/share/terminfo/n/ncr260vt300pp"); -__static_yoink("usr/share/terminfo/n/nsterm-acs"); -__static_yoink("usr/share/terminfo/n/nsterm+7"); -__static_yoink("usr/share/terminfo/n/ntconsole-60"); -__static_yoink("usr/share/terminfo/n/ncr260vpwpp"); -__static_yoink("usr/share/terminfo/n/ntconsole-50-nti"); -__static_yoink("usr/share/terminfo/n/nsterm-c-acs"); -__static_yoink("usr/share/terminfo/n/ntconsole-w"); -__static_yoink("usr/share/terminfo/n/next"); -__static_yoink("usr/share/terminfo/n/ntconsole"); -__static_yoink("usr/share/terminfo/n/ncrvt100an"); -__static_yoink("usr/share/terminfo/n/ncsa-vt220-8"); -__static_yoink("usr/share/terminfo/n/nsterm-acs-c"); -__static_yoink("usr/share/terminfo/n/nwp511"); -__static_yoink("usr/share/terminfo/n/ncr160vt300pp"); -__static_yoink("usr/share/terminfo/n/ncsa-m-ns"); -__static_yoink("usr/share/terminfo/n/n7900"); -__static_yoink("usr/share/terminfo/n/news40"); -__static_yoink("usr/share/terminfo/n/ncr260intpp"); -__static_yoink("usr/share/terminfo/n/nwp518"); -__static_yoink("usr/share/terminfo/n/nsterm-acs-m"); -__static_yoink("usr/share/terminfo/n/ncr260wy50+wpp"); -__static_yoink("usr/share/terminfo/n/ndr9500-mc-nl"); -__static_yoink("usr/share/terminfo/n/nansi.sysk"); -__static_yoink("usr/share/terminfo/n/newscbm"); -__static_yoink("usr/share/terminfo/n/ncr7900iv"); -__static_yoink("usr/share/terminfo/n/nsterm-c-s-acs"); -__static_yoink("usr/share/terminfo/n/ndr9500"); -__static_yoink("usr/share/terminfo/n/nsterm-bce"); -__static_yoink("usr/share/terminfo/n/no+brackets"); -__static_yoink("usr/share/terminfo/n/nsterm+c41"); -__static_yoink("usr/share/terminfo/n/ntconsole-25-w"); -__static_yoink("usr/share/terminfo/n/nsterm-m-s-acs"); -__static_yoink("usr/share/terminfo/n/nsterm-c-s-7"); -__static_yoink("usr/share/terminfo/n/news42"); -__static_yoink("usr/share/terminfo/n/nsterm-old"); -__static_yoink("usr/share/terminfo/n/ncr260vt100wpp"); -__static_yoink("usr/share/terminfo/n/ntconsole-25-nti"); -__static_yoink("usr/share/terminfo/n/nwp518-o"); -__static_yoink("usr/share/terminfo/n/news-unk"); -__static_yoink("usr/share/terminfo/n/nwp513"); -__static_yoink("usr/share/terminfo/n/nd9500"); -__static_yoink("usr/share/terminfo/n/nwp517"); -__static_yoink("usr/share/terminfo/n/nwe501"); -__static_yoink("usr/share/terminfo/n/nsterm-direct"); -__static_yoink("usr/share/terminfo/n/nwp512-a"); -__static_yoink("usr/share/terminfo/n/ntconsole-35"); -__static_yoink("usr/share/terminfo/n/ncr160vpwpp"); -__static_yoink("usr/share/terminfo/n/ncr260wy350pp"); -__static_yoink("usr/share/terminfo/n/nsterm-7-c"); -__static_yoink("usr/share/terminfo/n/ncr260intan"); -__static_yoink("usr/share/terminfo/n/newhpkeyboard"); -__static_yoink("usr/share/terminfo/n/nsterm-7-c-s"); -__static_yoink("usr/share/terminfo/n/ncr160vt300wpp"); -__static_yoink("usr/share/terminfo/n/nsterm-build309"); -__static_yoink("usr/share/terminfo/n/ncr160vt100an"); -__static_yoink("usr/share/terminfo/n/ncsa-m"); -__static_yoink("usr/share/terminfo/n/ncrvt100wan"); -__static_yoink("usr/share/terminfo/n/nsterm-c"); -__static_yoink("usr/share/terminfo/n/ncr160vt200wan"); -__static_yoink("usr/share/terminfo/n/nsterm-m-7"); -__static_yoink("usr/share/terminfo/n/ntconsole-w-vt"); -__static_yoink("usr/share/terminfo/n/ncr7900"); -__static_yoink("usr/share/terminfo/n/news-29-sjis"); -__static_yoink("usr/share/terminfo/n/news-o"); -__static_yoink("usr/share/terminfo/n/ncr260vt100pp"); -__static_yoink("usr/share/terminfo/n/ncr160wy60pp"); -__static_yoink("usr/share/terminfo/n/ndr9500-25-nl"); -__static_yoink("usr/share/terminfo/n/news40-o"); -__static_yoink("usr/share/terminfo/n/ncr260vt200wan"); -__static_yoink("usr/share/terminfo/n/ncr160vt100wan"); -__static_yoink("usr/share/terminfo/n/ndr9500-mc"); -__static_yoink("usr/share/terminfo/n/news31-a"); -__static_yoink("usr/share/terminfo/n/netbsd6"); -__static_yoink("usr/share/terminfo/n/ntconsole-100-nti"); -__static_yoink("usr/share/terminfo/n/news-33"); -__static_yoink("usr/share/terminfo/n/nwe501-o"); -__static_yoink("usr/share/terminfo/n/ncr7900i"); -__static_yoink("usr/share/terminfo/n/news-29"); -__static_yoink("usr/share/terminfo/n/nsterm-c-s"); -__static_yoink("usr/share/terminfo/n/nsterm-7-m-s"); -__static_yoink("usr/share/terminfo/n/ndr9500-nl"); -__static_yoink("usr/share/terminfo/n/ncrvt100wpp"); -__static_yoink("usr/share/terminfo/n/nsterm-7-s"); -__static_yoink("usr/share/terminfo/n/news28-a"); -__static_yoink("usr/share/terminfo/n/nsterm-m-acs"); -__static_yoink("usr/share/terminfo/n/newhp"); -__static_yoink("usr/share/terminfo/n/ncr160vppp"); -__static_yoink("usr/share/terminfo/n/nwp512-o"); -__static_yoink("usr/share/terminfo/n/ncr260wy60wpp"); -__static_yoink("usr/share/terminfo/n/nsterm-build400"); -__static_yoink("usr/share/terminfo/n/news31"); -__static_yoink("usr/share/terminfo/n/newscbm-a"); -__static_yoink("usr/share/terminfo/n/news29"); -__static_yoink("usr/share/terminfo/n/ncr160vt100wpp"); -__static_yoink("usr/share/terminfo/n/nwp-517-w"); -__static_yoink("usr/share/terminfo/n/ncrvt100pp"); -__static_yoink("usr/share/terminfo/n/nsterm-acs-m-s"); -__static_yoink("usr/share/terminfo/n/nsterm-16color"); -__static_yoink("usr/share/terminfo/n/nsterm+s"); -__static_yoink("usr/share/terminfo/n/nsterm+mac"); -__static_yoink("usr/share/terminfo/n/nwp-511"); -__static_yoink("usr/share/terminfo/n/news-33-euc"); -__static_yoink("usr/share/terminfo/n/nansisysk"); -__static_yoink("usr/share/terminfo/n/ntconsole-50"); -__static_yoink("usr/share/terminfo/n/news-29-euc"); -__static_yoink("usr/share/terminfo/n/nsterm-s"); -__static_yoink("usr/share/terminfo/n/news-a"); -__static_yoink("usr/share/terminfo/n/ncr260vt+sl"); -__static_yoink("usr/share/terminfo/n/nwp513-a"); -__static_yoink("usr/share/terminfo/n/ncr160wy50+wpp"); -__static_yoink("usr/share/terminfo/n/ncr260vt300wpp"); -__static_yoink("usr/share/terminfo/n/news31-o"); -__static_yoink("usr/share/terminfo/n/news-42"); -__static_yoink("usr/share/terminfo/n/ncr260wy50+pp"); -__static_yoink("usr/share/terminfo/n/nsterm-m"); -__static_yoink("usr/share/terminfo/n/nwp251-o"); -__static_yoink("usr/share/terminfo/n/nsterm+acs"); -__static_yoink("usr/share/terminfo/n/ncsa-vt220"); -__static_yoink("usr/share/terminfo/n/ncr260vt200pp"); -__static_yoink("usr/share/terminfo/n/nxterm"); -__static_yoink("usr/share/terminfo/n/news28"); -__static_yoink("usr/share/terminfo/n/nsterm-s-7"); -__static_yoink("usr/share/terminfo/n/newscbm33"); -__static_yoink("usr/share/terminfo/n/ncr160vt300wan"); -__static_yoink("usr/share/terminfo/n/ncr260wy325wpp"); -__static_yoink("usr/share/terminfo/n/nwp514"); -__static_yoink("usr/share/terminfo/n/ncr260vt300wan"); -__static_yoink("usr/share/terminfo/n/newscbm-o"); -__static_yoink("usr/share/terminfo/n/ncsa-ns"); -__static_yoink("usr/share/terminfo/n/nsterm-build343"); -__static_yoink("usr/share/terminfo/n/nwp513-o"); -__static_yoink("usr/share/terminfo/n/news"); -__static_yoink("usr/share/terminfo/n/ntconsole-100"); -__static_yoink("usr/share/terminfo/n/nwp517-w"); -__static_yoink("usr/share/terminfo/n/ncr260vp+sl"); -__static_yoink("usr/share/terminfo/n/nansisys"); -__static_yoink("usr/share/terminfo/n/nwp-517"); -__static_yoink("usr/share/terminfo/n/nwp518-a"); -__static_yoink("usr/share/terminfo/n/ncr160wy60wpp"); -__static_yoink("usr/share/terminfo/n/nwp251-a"); -__static_yoink("usr/share/terminfo/n/ntconsole-60-nti"); -__static_yoink("usr/share/terminfo/E/Eterm"); -__static_yoink("usr/share/terminfo/E/Eterm-88color"); -__static_yoink("usr/share/terminfo/E/Eterm-256color"); -__static_yoink("usr/share/terminfo/E/Eterm-color"); -__static_yoink("usr/share/terminfo/A/Apple_Terminal"); -__static_yoink("usr/share/terminfo/M/MtxOrb204"); -__static_yoink("usr/share/terminfo/M/MtxOrb162"); -__static_yoink("usr/share/terminfo/M/MtxOrb"); -__static_yoink("usr/share/terminfo/d/dg450"); -__static_yoink("usr/share/terminfo/d/diablo"); -__static_yoink("usr/share/terminfo/d/dgmode+color"); -__static_yoink("usr/share/terminfo/d/d215-dg"); -__static_yoink("usr/share/terminfo/d/d555-w"); -__static_yoink("usr/share/terminfo/d/dg+fixed"); -__static_yoink("usr/share/terminfo/d/d2-dg"); -__static_yoink("usr/share/terminfo/d/d430-unix"); -__static_yoink("usr/share/terminfo/d/d216-dg"); -__static_yoink("usr/share/terminfo/d/d430-unix-sr-ccc"); -__static_yoink("usr/share/terminfo/d/d460-7b-w"); -__static_yoink("usr/share/terminfo/d/dg100"); -__static_yoink("usr/share/terminfo/d/d430-unix-w"); -__static_yoink("usr/share/terminfo/d/dialogue"); -__static_yoink("usr/share/terminfo/d/d430c-unix-25-ccc"); -__static_yoink("usr/share/terminfo/d/darwin-256x96"); -__static_yoink("usr/share/terminfo/d/d216e+dg"); -__static_yoink("usr/share/terminfo/d/ds40-2"); -__static_yoink("usr/share/terminfo/d/d216+"); -__static_yoink("usr/share/terminfo/d/d430-unix-25"); -__static_yoink("usr/share/terminfo/d/dmd-24"); -__static_yoink("usr/share/terminfo/d/decansi"); -__static_yoink("usr/share/terminfo/d/dt100"); -__static_yoink("usr/share/terminfo/d/dg6134"); -__static_yoink("usr/share/terminfo/d/d555-7b-w"); -__static_yoink("usr/share/terminfo/d/d461"); -__static_yoink("usr/share/terminfo/d/d412+25"); -__static_yoink("usr/share/terminfo/d/d411-7b-w"); -__static_yoink("usr/share/terminfo/d/darwin-f2"); -__static_yoink("usr/share/terminfo/d/diablo-lm"); -__static_yoink("usr/share/terminfo/d/darwin-128x48-m"); -__static_yoink("usr/share/terminfo/d/d577-7b-w"); -__static_yoink("usr/share/terminfo/d/d400"); -__static_yoink("usr/share/terminfo/d/dg6053"); -__static_yoink("usr/share/terminfo/d/dtc382"); -__static_yoink("usr/share/terminfo/d/dg+color8"); -__static_yoink("usr/share/terminfo/d/d414-unix-sr"); -__static_yoink("usr/share/terminfo/d/d216-unix"); -__static_yoink("usr/share/terminfo/d/darwin-m-b"); -__static_yoink("usr/share/terminfo/d/datagraphix"); -__static_yoink("usr/share/terminfo/d/dt110"); -__static_yoink("usr/share/terminfo/d/d412+s"); -__static_yoink("usr/share/terminfo/d/d460"); -__static_yoink("usr/share/terminfo/d/d216+25"); -__static_yoink("usr/share/terminfo/d/darwin-100x37"); -__static_yoink("usr/share/terminfo/d/ds40"); -__static_yoink("usr/share/terminfo/d/dku7202"); -__static_yoink("usr/share/terminfo/d/darwin-112x37-m"); -__static_yoink("usr/share/terminfo/d/d430c-unix-s"); -__static_yoink("usr/share/terminfo/d/d2"); -__static_yoink("usr/share/terminfo/d/d461-dg"); -__static_yoink("usr/share/terminfo/d/dtc300s"); -__static_yoink("usr/share/terminfo/d/darwin-90x30"); -__static_yoink("usr/share/terminfo/d/d430c-unix-w"); -__static_yoink("usr/share/terminfo/d/d80"); -__static_yoink("usr/share/terminfo/d/d430-unix-w-ccc"); -__static_yoink("usr/share/terminfo/d/d430c-unix-s-ccc"); -__static_yoink("usr/share/terminfo/d/d430-dg-ccc"); -__static_yoink("usr/share/terminfo/d/darwin-m"); -__static_yoink("usr/share/terminfo/d/d412-unix-25"); -__static_yoink("usr/share/terminfo/d/dg460-ansi"); -__static_yoink("usr/share/terminfo/d/dmdt80w"); -__static_yoink("usr/share/terminfo/d/dmd"); -__static_yoink("usr/share/terminfo/d/d462-unix-w"); -__static_yoink("usr/share/terminfo/d/decwriter"); -__static_yoink("usr/share/terminfo/d/d430c-unix-w-ccc"); -__static_yoink("usr/share/terminfo/d/d460-w"); -__static_yoink("usr/share/terminfo/d/d413-dg"); -__static_yoink("usr/share/terminfo/d/d464-unix-25"); -__static_yoink("usr/share/terminfo/d/darwin-m-f"); -__static_yoink("usr/share/terminfo/d/darwin-90x30-m"); -__static_yoink("usr/share/terminfo/d/d577"); -__static_yoink("usr/share/terminfo/d/dec-vt340"); -__static_yoink("usr/share/terminfo/d/dw3"); -__static_yoink("usr/share/terminfo/d/darwin-200x64"); -__static_yoink("usr/share/terminfo/d/d463-unix-w"); -__static_yoink("usr/share/terminfo/d/diablo1720"); -__static_yoink("usr/share/terminfo/d/d411-7b"); -__static_yoink("usr/share/terminfo/d/darwin-200x75-m"); -__static_yoink("usr/share/terminfo/d/d132"); -__static_yoink("usr/share/terminfo/d/dp3360"); -__static_yoink("usr/share/terminfo/d/d464-unix-w"); -__static_yoink("usr/share/terminfo/d/d461-7b-w"); -__static_yoink("usr/share/terminfo/d/d215"); -__static_yoink("usr/share/terminfo/d/d430c-unix"); -__static_yoink("usr/share/terminfo/d/d577-w"); -__static_yoink("usr/share/terminfo/d/d214"); -__static_yoink("usr/share/terminfo/d/d413-unix-25"); -__static_yoink("usr/share/terminfo/d/d430c-unix-ccc"); -__static_yoink("usr/share/terminfo/d/dvtm"); -__static_yoink("usr/share/terminfo/d/digilog"); -__static_yoink("usr/share/terminfo/d/darwin-f"); -__static_yoink("usr/share/terminfo/d/d217-unix"); -__static_yoink("usr/share/terminfo/d/dp8242"); -__static_yoink("usr/share/terminfo/d/djgpp203"); -__static_yoink("usr/share/terminfo/d/dmd1"); -__static_yoink("usr/share/terminfo/d/decid+cpr"); -__static_yoink("usr/share/terminfo/d/d210-dg"); -__static_yoink("usr/share/terminfo/d/d400-dg"); -__static_yoink("usr/share/terminfo/d/darwin-200x75"); -__static_yoink("usr/share/terminfo/d/dg605x"); -__static_yoink("usr/share/terminfo/d/datapoint"); -__static_yoink("usr/share/terminfo/d/darwin-80x25-m"); -__static_yoink("usr/share/terminfo/d/dg6053-old"); -__static_yoink("usr/share/terminfo/d/darwin-80x30-m"); -__static_yoink("usr/share/terminfo/d/d462-unix-25"); -__static_yoink("usr/share/terminfo/d/d216e-dg"); -__static_yoink("usr/share/terminfo/d/d430-unix-s-ccc"); -__static_yoink("usr/share/terminfo/d/darwin-160x64-m"); -__static_yoink("usr/share/terminfo/d/d214-dg"); -__static_yoink("usr/share/terminfo/d/d220"); -__static_yoink("usr/share/terminfo/d/dw4"); -__static_yoink("usr/share/terminfo/d/d211"); -__static_yoink("usr/share/terminfo/d/diablo1730"); -__static_yoink("usr/share/terminfo/d/diablo1640"); -__static_yoink("usr/share/terminfo/d/dt80-sas"); -__static_yoink("usr/share/terminfo/d/d470"); -__static_yoink("usr/share/terminfo/d/dm80w"); -__static_yoink("usr/share/terminfo/d/dw2"); -__static_yoink("usr/share/terminfo/d/d461-7b"); -__static_yoink("usr/share/terminfo/d/dku7102-sna"); -__static_yoink("usr/share/terminfo/d/d211-dg"); -__static_yoink("usr/share/terminfo/d/dg+ccc"); -__static_yoink("usr/share/terminfo/d/d414-unix"); -__static_yoink("usr/share/terminfo/d/dt100w"); -__static_yoink("usr/share/terminfo/d/darwin-144x48-m"); -__static_yoink("usr/share/terminfo/d/dt80"); -__static_yoink("usr/share/terminfo/d/darwin-200x64-m"); -__static_yoink("usr/share/terminfo/d/darwin-256x96-m"); -__static_yoink("usr/share/terminfo/d/d414-unix-w"); -__static_yoink("usr/share/terminfo/d/d578-dg"); -__static_yoink("usr/share/terminfo/d/dgunix+ccc"); -__static_yoink("usr/share/terminfo/d/dwk-vt"); -__static_yoink("usr/share/terminfo/d/darwin-80x30"); -__static_yoink("usr/share/terminfo/d/diablo1740"); -__static_yoink("usr/share/terminfo/d/d217-dg"); -__static_yoink("usr/share/terminfo/d/d462+sr"); -__static_yoink("usr/share/terminfo/d/d211-7b"); -__static_yoink("usr/share/terminfo/d/diablo1640-lm"); -__static_yoink("usr/share/terminfo/d/diablo630"); -__static_yoink("usr/share/terminfo/d/dgkeys+11"); -__static_yoink("usr/share/terminfo/d/dvtm-256color"); -__static_yoink("usr/share/terminfo/d/d412-unix"); -__static_yoink("usr/share/terminfo/d/dku7003-dumb"); -__static_yoink("usr/share/terminfo/d/domterm"); -__static_yoink("usr/share/terminfo/d/d412+w"); -__static_yoink("usr/share/terminfo/d/d412-dg"); -__static_yoink("usr/share/terminfo/d/d555"); -__static_yoink("usr/share/terminfo/d/diablo1620-m8"); -__static_yoink("usr/share/terminfo/d/d230"); -__static_yoink("usr/share/terminfo/d/d412+dg"); -__static_yoink("usr/share/terminfo/d/d412-unix-sr"); -__static_yoink("usr/share/terminfo/d/d462-unix-s"); -__static_yoink("usr/share/terminfo/d/dm3025"); -__static_yoink("usr/share/terminfo/d/dg211"); -__static_yoink("usr/share/terminfo/d/darwin-80x25"); -__static_yoink("usr/share/terminfo/d/d470-dg"); -__static_yoink("usr/share/terminfo/d/dt-100w"); -__static_yoink("usr/share/terminfo/d/dg-generic"); -__static_yoink("usr/share/terminfo/d/dmd-34"); -__static_yoink("usr/share/terminfo/d/d470-7b"); -__static_yoink("usr/share/terminfo/d/d413-unix-s"); -__static_yoink("usr/share/terminfo/d/darwin-b"); -__static_yoink("usr/share/terminfo/d/ddr"); -__static_yoink("usr/share/terminfo/d/d200-dg"); -__static_yoink("usr/share/terminfo/d/d414-unix-25"); -__static_yoink("usr/share/terminfo/d/d411-w"); -__static_yoink("usr/share/terminfo/d/d464-unix"); -__static_yoink("usr/share/terminfo/d/d216e-unix"); -__static_yoink("usr/share/terminfo/d/d430c-unix-sr-ccc"); -__static_yoink("usr/share/terminfo/d/dmdt80"); -__static_yoink("usr/share/terminfo/d/d411-dg"); -__static_yoink("usr/share/terminfo/d/dg200"); -__static_yoink("usr/share/terminfo/d/d412+"); -__static_yoink("usr/share/terminfo/d/d412-unix-w"); -__static_yoink("usr/share/terminfo/d/dku7103-sna"); -__static_yoink("usr/share/terminfo/d/dgmode+color8"); -__static_yoink("usr/share/terminfo/d/dw1"); -__static_yoink("usr/share/terminfo/d/dd5000"); -__static_yoink("usr/share/terminfo/d/d460-dg"); -__static_yoink("usr/share/terminfo/d/djgpp204"); -__static_yoink("usr/share/terminfo/d/d470c"); -__static_yoink("usr/share/terminfo/d/d464-unix-sr"); -__static_yoink("usr/share/terminfo/d/diablo1620"); -__static_yoink("usr/share/terminfo/d/dec-vt330"); -__static_yoink("usr/share/terminfo/d/darwin-128x48"); -__static_yoink("usr/share/terminfo/d/diablo1640-m8"); -__static_yoink("usr/share/terminfo/d/d410-7b-w"); -__static_yoink("usr/share/terminfo/d/d230c-dg"); -__static_yoink("usr/share/terminfo/d/d462-dg"); -__static_yoink("usr/share/terminfo/d/dku7003"); -__static_yoink("usr/share/terminfo/d/d216+dg"); -__static_yoink("usr/share/terminfo/d/d461-w"); -__static_yoink("usr/share/terminfo/d/darwin-160x64"); -__static_yoink("usr/share/terminfo/d/dt-100"); -__static_yoink("usr/share/terminfo/d/d430c-dg"); -__static_yoink("usr/share/terminfo/d/diablo450"); -__static_yoink("usr/share/terminfo/d/d470c-7b"); -__static_yoink("usr/share/terminfo/d/dku7102-old"); -__static_yoink("usr/share/terminfo/d/dm2500"); -__static_yoink("usr/share/terminfo/d/dgkeys+15"); -__static_yoink("usr/share/terminfo/d/d410-7b"); -__static_yoink("usr/share/terminfo/d/dm1520"); -__static_yoink("usr/share/terminfo/d/datamedia2500"); -__static_yoink("usr/share/terminfo/d/d463-dg"); -__static_yoink("usr/share/terminfo/d/diablo1740-lm"); -__static_yoink("usr/share/terminfo/d/d216-unix-25"); -__static_yoink("usr/share/terminfo/d/d462-unix"); -__static_yoink("usr/share/terminfo/d/d462+"); -__static_yoink("usr/share/terminfo/d/darwin-100x37-m"); -__static_yoink("usr/share/terminfo/d/dw"); -__static_yoink("usr/share/terminfo/d/d578-7b"); -__static_yoink("usr/share/terminfo/d/dumb-emacs-ansi"); -__static_yoink("usr/share/terminfo/d/dataspeed40"); -__static_yoink("usr/share/terminfo/d/d430c-unix-25"); -__static_yoink("usr/share/terminfo/d/d215-7b"); -__static_yoink("usr/share/terminfo/d/dgunix+fixed"); -__static_yoink("usr/share/terminfo/d/dm3045"); -__static_yoink("usr/share/terminfo/d/dec-vt220"); -__static_yoink("usr/share/terminfo/d/d800"); -__static_yoink("usr/share/terminfo/d/dtterm"); -__static_yoink("usr/share/terminfo/d/dwk"); -__static_yoink("usr/share/terminfo/d/d430-unix-sr"); -__static_yoink("usr/share/terminfo/d/dg-ansi"); -__static_yoink("usr/share/terminfo/d/dg210"); -__static_yoink("usr/share/terminfo/d/darwin-144x48"); -__static_yoink("usr/share/terminfo/d/d555-dg"); -__static_yoink("usr/share/terminfo/d/d462+s"); -__static_yoink("usr/share/terminfo/d/d217-unix-25"); -__static_yoink("usr/share/terminfo/d/d430c-unix-sr"); -__static_yoink("usr/share/terminfo/d/d462+w"); -__static_yoink("usr/share/terminfo/d/dec-vt400"); -__static_yoink("usr/share/terminfo/d/d463-unix-s"); -__static_yoink("usr/share/terminfo/d/d470c-dg"); -__static_yoink("usr/share/terminfo/d/d463-unix"); -__static_yoink("usr/share/terminfo/d/d411"); -__static_yoink("usr/share/terminfo/d/d200"); -__static_yoink("usr/share/terminfo/d/decpro"); -__static_yoink("usr/share/terminfo/d/d413-unix-sr"); -__static_yoink("usr/share/terminfo/d/djgpp"); -__static_yoink("usr/share/terminfo/d/d462+dg"); -__static_yoink("usr/share/terminfo/d/d413-unix-w"); -__static_yoink("usr/share/terminfo/d/d410-dg"); -__static_yoink("usr/share/terminfo/d/d577-7b"); -__static_yoink("usr/share/terminfo/d/d450"); -__static_yoink("usr/share/terminfo/d/dumb"); -__static_yoink("usr/share/terminfo/d/d430-unix-s"); -__static_yoink("usr/share/terminfo/d/darwin"); -__static_yoink("usr/share/terminfo/d/d430-unix-25-ccc"); -__static_yoink("usr/share/terminfo/d/d464-unix-s"); -__static_yoink("usr/share/terminfo/d/d578"); -__static_yoink("usr/share/terminfo/d/d230c"); -__static_yoink("usr/share/terminfo/d/dg+color"); -__static_yoink("usr/share/terminfo/d/d230-dg"); -__static_yoink("usr/share/terminfo/d/d462e-dg"); -__static_yoink("usr/share/terminfo/d/d410-w"); -__static_yoink("usr/share/terminfo/d/dgkeys+7b"); -__static_yoink("usr/share/terminfo/d/dec+sl"); -__static_yoink("usr/share/terminfo/d/dmchat"); -__static_yoink("usr/share/terminfo/d/d463-unix-sr"); -__static_yoink("usr/share/terminfo/d/d462-unix-sr"); -__static_yoink("usr/share/terminfo/d/d430-unix-ccc"); -__static_yoink("usr/share/terminfo/d/delta"); -__static_yoink("usr/share/terminfo/d/dec+pp"); -__static_yoink("usr/share/terminfo/d/d430-dg"); -__static_yoink("usr/share/terminfo/d/d414-unix-s"); -__static_yoink("usr/share/terminfo/d/d460-7b"); -__static_yoink("usr/share/terminfo/d/dec-vt100"); -__static_yoink("usr/share/terminfo/d/d413-unix"); -__static_yoink("usr/share/terminfo/d/dm80"); -__static_yoink("usr/share/terminfo/d/dgkeys+8b"); -__static_yoink("usr/share/terminfo/d/d220-dg"); -__static_yoink("usr/share/terminfo/d/d577-dg"); -__static_yoink("usr/share/terminfo/d/darwin-112x37"); -__static_yoink("usr/share/terminfo/d/d430c-dg-ccc"); -__static_yoink("usr/share/terminfo/d/ddr3180"); -__static_yoink("usr/share/terminfo/d/darwin-128x40"); -__static_yoink("usr/share/terminfo/d/darwin-m-f2"); -__static_yoink("usr/share/terminfo/d/dm1521"); -__static_yoink("usr/share/terminfo/d/d450-dg"); -__static_yoink("usr/share/terminfo/d/d220-7b"); -__static_yoink("usr/share/terminfo/d/dialogue80"); -__static_yoink("usr/share/terminfo/d/d410"); -__static_yoink("usr/share/terminfo/d/dmterm"); -__static_yoink("usr/share/terminfo/d/d462+25"); -__static_yoink("usr/share/terminfo/d/d555-7b"); -__static_yoink("usr/share/terminfo/d/dt80w"); -__static_yoink("usr/share/terminfo/d/d463-unix-25"); -__static_yoink("usr/share/terminfo/d/d412+sr"); -__static_yoink("usr/share/terminfo/d/darwin-128x40-m"); -__static_yoink("usr/share/terminfo/d/d210"); -__static_yoink("usr/share/terminfo/d/d216e+"); -__static_yoink("usr/share/terminfo/d/d412-unix-s"); -__static_yoink("usr/share/terminfo/d/dku7102"); -__static_yoink("usr/share/terminfo/L/LFT-PC850"); -__static_yoink("usr/share/terminfo/8/8510"); -__static_yoink("usr/share/terminfo/p/pcvt25"); -__static_yoink("usr/share/terminfo/p/psterm-fast"); -__static_yoink("usr/share/terminfo/p/pt100"); -__static_yoink("usr/share/terminfo/p/p9-w"); -__static_yoink("usr/share/terminfo/p/pro350"); -__static_yoink("usr/share/terminfo/p/pccon+base"); -__static_yoink("usr/share/terminfo/p/putty-m1b"); -__static_yoink("usr/share/terminfo/p/prism8-w"); -__static_yoink("usr/share/terminfo/p/pt200w"); -__static_yoink("usr/share/terminfo/p/putty+fnkeys+vt100"); -__static_yoink("usr/share/terminfo/p/pt505-22"); -__static_yoink("usr/share/terminfo/p/putty-sco"); -__static_yoink("usr/share/terminfo/p/pcconsole"); -__static_yoink("usr/share/terminfo/p/prism14"); -__static_yoink("usr/share/terminfo/p/pcansi-m"); -__static_yoink("usr/share/terminfo/p/prism12-m-w"); -__static_yoink("usr/share/terminfo/p/pcvt50w"); -__static_yoink("usr/share/terminfo/p/pcansi25m"); -__static_yoink("usr/share/terminfo/p/putty-256color"); -__static_yoink("usr/share/terminfo/p/pcvtXX"); -__static_yoink("usr/share/terminfo/p/prism2"); -__static_yoink("usr/share/terminfo/p/pccon"); -__static_yoink("usr/share/terminfo/p/pe550"); -__static_yoink("usr/share/terminfo/p/putty+fnkeys+esc"); -__static_yoink("usr/share/terminfo/p/putty+fnkeys+sco"); -__static_yoink("usr/share/terminfo/p/prism7"); -__static_yoink("usr/share/terminfo/p/putty+fnkeys+vt400"); -__static_yoink("usr/share/terminfo/p/putty-m2"); -__static_yoink("usr/share/terminfo/p/pcix"); -__static_yoink("usr/share/terminfo/p/pe6100"); -__static_yoink("usr/share/terminfo/p/putty+screen"); -__static_yoink("usr/share/terminfo/p/p19"); -__static_yoink("usr/share/terminfo/p/putty-noapp"); -__static_yoink("usr/share/terminfo/p/pt505"); -__static_yoink("usr/share/terminfo/p/prism9-8"); -__static_yoink("usr/share/terminfo/p/prism12-w"); -__static_yoink("usr/share/terminfo/p/pcvt35w"); -__static_yoink("usr/share/terminfo/p/pc3"); -__static_yoink("usr/share/terminfo/p/pccon+colors"); -__static_yoink("usr/share/terminfo/p/prism12-m"); -__static_yoink("usr/share/terminfo/p/pe6300"); -__static_yoink("usr/share/terminfo/p/p9"); -__static_yoink("usr/share/terminfo/p/p14-m-w"); -__static_yoink("usr/share/terminfo/p/pmconsole"); -__static_yoink("usr/share/terminfo/p/pty"); -__static_yoink("usr/share/terminfo/p/pccon+keys"); -__static_yoink("usr/share/terminfo/p/pe1100"); -__static_yoink("usr/share/terminfo/p/pe7000m"); -__static_yoink("usr/share/terminfo/p/p12-w"); -__static_yoink("usr/share/terminfo/p/putty-m1"); -__static_yoink("usr/share/terminfo/p/pcansi33"); -__static_yoink("usr/share/terminfo/p/prism9-8-w"); -__static_yoink("usr/share/terminfo/p/ps300"); -__static_yoink("usr/share/terminfo/p/psterm-90x28"); -__static_yoink("usr/share/terminfo/p/p5"); -__static_yoink("usr/share/terminfo/p/pc-venix"); -__static_yoink("usr/share/terminfo/p/pc6300plus"); -__static_yoink("usr/share/terminfo/p/pcplot"); -__static_yoink("usr/share/terminfo/p/pt505-24"); -__static_yoink("usr/share/terminfo/p/psterm-80x24"); -__static_yoink("usr/share/terminfo/p/prism4"); -__static_yoink("usr/share/terminfo/p/psterm"); -__static_yoink("usr/share/terminfo/p/prism12"); -__static_yoink("usr/share/terminfo/p/putty+keypad"); -__static_yoink("usr/share/terminfo/p/pc3r-m"); -__static_yoink("usr/share/terminfo/p/pccons"); -__static_yoink("usr/share/terminfo/p/pt210"); -__static_yoink("usr/share/terminfo/p/pcvt50"); -__static_yoink("usr/share/terminfo/p/prism14-m"); -__static_yoink("usr/share/terminfo/p/pt100w"); -__static_yoink("usr/share/terminfo/p/pcansi43"); -__static_yoink("usr/share/terminfo/p/putty-screen"); -__static_yoink("usr/share/terminfo/p/pckermit"); -__static_yoink("usr/share/terminfo/p/pcvt25-color"); -__static_yoink("usr/share/terminfo/p/p14-m"); -__static_yoink("usr/share/terminfo/p/pe6312"); -__static_yoink("usr/share/terminfo/p/psterm-basic"); -__static_yoink("usr/share/terminfo/p/pt200"); -__static_yoink("usr/share/terminfo/p/pt250w"); -__static_yoink("usr/share/terminfo/p/p9-8"); -__static_yoink("usr/share/terminfo/p/psx_ansi"); -__static_yoink("usr/share/terminfo/p/p14"); -__static_yoink("usr/share/terminfo/p/p14-w"); -__static_yoink("usr/share/terminfo/p/p12"); -__static_yoink("usr/share/terminfo/p/pcansi-33-m"); -__static_yoink("usr/share/terminfo/p/pcvt40"); -__static_yoink("usr/share/terminfo/p/pcvt28w"); -__static_yoink("usr/share/terminfo/p/pe1200"); -__static_yoink("usr/share/terminfo/p/pccon+sgr+acs"); -__static_yoink("usr/share/terminfo/p/pccon+sgr+acs0"); -__static_yoink("usr/share/terminfo/p/p8-w"); -__static_yoink("usr/share/terminfo/p/pcansi-25-m"); -__static_yoink("usr/share/terminfo/p/pcvt43w"); -__static_yoink("usr/share/terminfo/p/pcansi-33"); -__static_yoink("usr/share/terminfo/p/putty+fnkeys+xterm"); -__static_yoink("usr/share/terminfo/p/pccon-m"); -__static_yoink("usr/share/terminfo/p/putty-vt100"); -__static_yoink("usr/share/terminfo/p/pmcons"); -__static_yoink("usr/share/terminfo/p/pc7300"); -__static_yoink("usr/share/terminfo/p/pc-minix"); -__static_yoink("usr/share/terminfo/p/pcansi"); -__static_yoink("usr/share/terminfo/p/p8"); -__static_yoink("usr/share/terminfo/p/pcansi33m"); -__static_yoink("usr/share/terminfo/p/pcvt43"); -__static_yoink("usr/share/terminfo/p/pcansi-43"); -__static_yoink("usr/share/terminfo/p/prism5"); -__static_yoink("usr/share/terminfo/p/pcmw"); -__static_yoink("usr/share/terminfo/p/pcansi-25"); -__static_yoink("usr/share/terminfo/p/prism8"); -__static_yoink("usr/share/terminfo/p/pccon0"); -__static_yoink("usr/share/terminfo/p/pcvt25w"); -__static_yoink("usr/share/terminfo/p/prism14-w"); -__static_yoink("usr/share/terminfo/p/pt250"); -__static_yoink("usr/share/terminfo/p/pcansi-mono"); -__static_yoink("usr/share/terminfo/p/pe1251"); -__static_yoink("usr/share/terminfo/p/pcvt35"); -__static_yoink("usr/share/terminfo/p/pc3r"); -__static_yoink("usr/share/terminfo/p/prism9-w"); -__static_yoink("usr/share/terminfo/p/p7"); -__static_yoink("usr/share/terminfo/p/pcansi-43-m"); -__static_yoink("usr/share/terminfo/p/putty+fnkeys+linux"); -__static_yoink("usr/share/terminfo/p/prism14-m-w"); -__static_yoink("usr/share/terminfo/p/p8gl"); -__static_yoink("usr/share/terminfo/p/p4"); -__static_yoink("usr/share/terminfo/p/psterm-96x48"); -__static_yoink("usr/share/terminfo/p/printer"); -__static_yoink("usr/share/terminfo/p/p12-m"); -__static_yoink("usr/share/terminfo/p/pe7000c"); -__static_yoink("usr/share/terminfo/p/pc-coherent"); -__static_yoink("usr/share/terminfo/p/pc3-bold"); -__static_yoink("usr/share/terminfo/p/p12-m-w"); -__static_yoink("usr/share/terminfo/p/p9-8-w"); -__static_yoink("usr/share/terminfo/p/pcvt40w"); -__static_yoink("usr/share/terminfo/p/pckermit120"); -__static_yoink("usr/share/terminfo/p/pilot"); -__static_yoink("usr/share/terminfo/p/pcansi25"); -__static_yoink("usr/share/terminfo/p/pcz19"); -__static_yoink("usr/share/terminfo/p/pcvt28"); -__static_yoink("usr/share/terminfo/p/prism9"); -__static_yoink("usr/share/terminfo/p/putty"); -__static_yoink("usr/share/terminfo/p/pccon0-m"); -__static_yoink("usr/share/terminfo/p/prism8gl"); -__static_yoink("usr/share/terminfo/p/pckermit12"); -__static_yoink("usr/share/terminfo/p/putty+fnkeys"); -__static_yoink("usr/share/terminfo/s/screen-s"); -__static_yoink("usr/share/terminfo/s/sun-e-s"); -__static_yoink("usr/share/terminfo/s/st-256color"); -__static_yoink("usr/share/terminfo/s/screen.vte"); -__static_yoink("usr/share/terminfo/s/screen-256color-bce"); -__static_yoink("usr/share/terminfo/s/st52-color"); -__static_yoink("usr/share/terminfo/s/sibo"); -__static_yoink("usr/share/terminfo/s/screen-bce.konsole"); -__static_yoink("usr/share/terminfo/s/sun-cmd"); -__static_yoink("usr/share/terminfo/s/stv52pc"); -__static_yoink("usr/share/terminfo/s/screen.linux-s"); -__static_yoink("usr/share/terminfo/s/swtp"); -__static_yoink("usr/share/terminfo/s/sun-s"); -__static_yoink("usr/share/terminfo/s/scoansi-old"); -__static_yoink("usr/share/terminfo/s/synertek380"); -__static_yoink("usr/share/terminfo/s/screen.mrxvt"); -__static_yoink("usr/share/terminfo/s/st-direct"); -__static_yoink("usr/share/terminfo/s/st"); -__static_yoink("usr/share/terminfo/s/st-0.7"); -__static_yoink("usr/share/terminfo/s/sune"); -__static_yoink("usr/share/terminfo/s/superbee-xsb"); -__static_yoink("usr/share/terminfo/s/superbeeic"); -__static_yoink("usr/share/terminfo/s/sc410"); -__static_yoink("usr/share/terminfo/s/screen-bce.xterm-new"); -__static_yoink("usr/share/terminfo/s/sun-12"); -__static_yoink("usr/share/terminfo/s/sb2"); -__static_yoink("usr/share/terminfo/s/superbee"); -__static_yoink("usr/share/terminfo/s/st-0.6"); -__static_yoink("usr/share/terminfo/s/sun-1"); -__static_yoink("usr/share/terminfo/s/sun-color"); -__static_yoink("usr/share/terminfo/s/stterm"); -__static_yoink("usr/share/terminfo/s/sbobcat"); -__static_yoink("usr/share/terminfo/s/screen.xterm-r6"); -__static_yoink("usr/share/terminfo/s/screen-bce.linux"); -__static_yoink("usr/share/terminfo/s/scoansi"); -__static_yoink("usr/share/terminfo/s/screen.minitel1"); -__static_yoink("usr/share/terminfo/s/scanset"); -__static_yoink("usr/share/terminfo/s/stterm-256color"); -__static_yoink("usr/share/terminfo/s/screen"); -__static_yoink("usr/share/terminfo/s/st52"); -__static_yoink("usr/share/terminfo/s/screen-16color-bce"); -__static_yoink("usr/share/terminfo/s/sun-type4"); -__static_yoink("usr/share/terminfo/s/scrhp"); -__static_yoink("usr/share/terminfo/s/screen.putty-m2"); -__static_yoink("usr/share/terminfo/s/screen3"); -__static_yoink("usr/share/terminfo/s/st-0.8"); -__static_yoink("usr/share/terminfo/s/sbi"); -__static_yoink("usr/share/terminfo/s/screen-bce"); -__static_yoink("usr/share/terminfo/s/screen.mlterm"); -__static_yoink("usr/share/terminfo/s/stv52"); -__static_yoink("usr/share/terminfo/s/simpleterm"); -__static_yoink("usr/share/terminfo/s/screen.putty-256color"); -__static_yoink("usr/share/terminfo/s/synertek"); -__static_yoink("usr/share/terminfo/s/securecrt"); -__static_yoink("usr/share/terminfo/s/sun-48"); -__static_yoink("usr/share/terminfo/s/screen.minitel2-80"); -__static_yoink("usr/share/terminfo/s/sun-24"); -__static_yoink("usr/share/terminfo/s/screen.konsole"); -__static_yoink("usr/share/terminfo/s/st52-m"); -__static_yoink("usr/share/terminfo/s/sun2"); -__static_yoink("usr/share/terminfo/s/screen4"); -__static_yoink("usr/share/terminfo/s/sun"); -__static_yoink("usr/share/terminfo/s/screen-base"); -__static_yoink("usr/share/terminfo/s/screen-bce.gnome"); -__static_yoink("usr/share/terminfo/s/screen.minitel1b-nb"); -__static_yoink("usr/share/terminfo/s/screen-bce.Eterm"); -__static_yoink("usr/share/terminfo/s/screen.xterm-256color"); -__static_yoink("usr/share/terminfo/s/screen-16color-s"); -__static_yoink("usr/share/terminfo/s/simterm"); -__static_yoink("usr/share/terminfo/s/screen+italics"); -__static_yoink("usr/share/terminfo/s/screen-256color-bce-s"); -__static_yoink("usr/share/terminfo/s/scrt"); -__static_yoink("usr/share/terminfo/s/screen.linux-m1b"); -__static_yoink("usr/share/terminfo/s/sun-il"); -__static_yoink("usr/share/terminfo/s/screen-256color-s"); -__static_yoink("usr/share/terminfo/s/st52-old"); -__static_yoink("usr/share/terminfo/s/screen.teraterm"); -__static_yoink("usr/share/terminfo/s/screen+fkeys"); -__static_yoink("usr/share/terminfo/s/screen-bce.rxvt"); -__static_yoink("usr/share/terminfo/s/sun-cgsix"); -__static_yoink("usr/share/terminfo/s/screen.vte-256color"); -__static_yoink("usr/share/terminfo/s/sun-34"); -__static_yoink("usr/share/terminfo/s/screen-bce.mrxvt"); -__static_yoink("usr/share/terminfo/s/screen-w"); -__static_yoink("usr/share/terminfo/s/sun-c"); -__static_yoink("usr/share/terminfo/s/screen.minitel1b-80"); -__static_yoink("usr/share/terminfo/s/screen.minitel1b"); -__static_yoink("usr/share/terminfo/s/screen.putty"); -__static_yoink("usr/share/terminfo/s/sv80"); -__static_yoink("usr/share/terminfo/s/screen.putty-m1b"); -__static_yoink("usr/share/terminfo/s/sun-nic"); -__static_yoink("usr/share/terminfo/s/sun-s-e"); -__static_yoink("usr/share/terminfo/s/soroc120"); -__static_yoink("usr/share/terminfo/s/screen.gnome"); -__static_yoink("usr/share/terminfo/s/spinwriter"); -__static_yoink("usr/share/terminfo/s/screen-256color"); -__static_yoink("usr/share/terminfo/s/sun+sl"); -__static_yoink("usr/share/terminfo/s/sun1"); -__static_yoink("usr/share/terminfo/s/screen5"); -__static_yoink("usr/share/terminfo/s/screen.minitel12-80"); -__static_yoink("usr/share/terminfo/s/screen.minitel1-nb"); -__static_yoink("usr/share/terminfo/s/stterm-16color"); -__static_yoink("usr/share/terminfo/s/screwpoint"); -__static_yoink("usr/share/terminfo/s/scoansi-new"); -__static_yoink("usr/share/terminfo/s/screen-16color"); -__static_yoink("usr/share/terminfo/s/screen.linux"); -__static_yoink("usr/share/terminfo/s/screen2"); -__static_yoink("usr/share/terminfo/s/st-16color"); -__static_yoink("usr/share/terminfo/s/sun-ss5"); -__static_yoink("usr/share/terminfo/s/screen.linux-m2"); -__static_yoink("usr/share/terminfo/s/superbrain"); -__static_yoink("usr/share/terminfo/s/screen.putty-m1"); -__static_yoink("usr/share/terminfo/s/sun-e"); -__static_yoink("usr/share/terminfo/s/screen.linux-m1"); -__static_yoink("usr/share/terminfo/s/soroc"); -__static_yoink("usr/share/terminfo/s/sb3"); -__static_yoink("usr/share/terminfo/s/screen.konsole-256color"); -__static_yoink("usr/share/terminfo/s/sb1"); -__static_yoink("usr/share/terminfo/s/screen.xterm-xfree86"); -__static_yoink("usr/share/terminfo/s/sc415"); -__static_yoink("usr/share/terminfo/s/system1"); -__static_yoink("usr/share/terminfo/s/screen.Eterm"); -__static_yoink("usr/share/terminfo/s/s4"); -__static_yoink("usr/share/terminfo/s/screen.xterm-new"); -__static_yoink("usr/share/terminfo/s/screen-16color-bce-s"); -__static_yoink("usr/share/terminfo/s/screen.mlterm-256color"); -__static_yoink("usr/share/terminfo/s/sun-17"); -__static_yoink("usr/share/terminfo/s/soroc140"); -__static_yoink("usr/share/terminfo/s/screen.rxvt"); -__static_yoink("usr/share/terminfo/f/f100"); -__static_yoink("usr/share/terminfo/f/fbterm"); -__static_yoink("usr/share/terminfo/f/fenix"); -__static_yoink("usr/share/terminfo/f/f200vi-w"); -__static_yoink("usr/share/terminfo/f/freedom200"); -__static_yoink("usr/share/terminfo/f/f110-w"); -__static_yoink("usr/share/terminfo/f/f200"); -__static_yoink("usr/share/terminfo/f/freedom110"); -__static_yoink("usr/share/terminfo/f/foot"); -__static_yoink("usr/share/terminfo/f/fox"); -__static_yoink("usr/share/terminfo/f/f100-rv"); -__static_yoink("usr/share/terminfo/f/freedom100"); -__static_yoink("usr/share/terminfo/f/f110"); -__static_yoink("usr/share/terminfo/f/f1720"); -__static_yoink("usr/share/terminfo/f/falco-p"); -__static_yoink("usr/share/terminfo/f/fenixw"); -__static_yoink("usr/share/terminfo/f/fortune"); -__static_yoink("usr/share/terminfo/f/foot+base"); -__static_yoink("usr/share/terminfo/f/f1720a"); -__static_yoink("usr/share/terminfo/f/freedom"); -__static_yoink("usr/share/terminfo/f/f110-14"); -__static_yoink("usr/share/terminfo/f/falco"); -__static_yoink("usr/share/terminfo/f/f200-w"); -__static_yoink("usr/share/terminfo/f/fos"); -__static_yoink("usr/share/terminfo/f/freedom-rv"); -__static_yoink("usr/share/terminfo/f/foot-direct"); -__static_yoink("usr/share/terminfo/f/f110-14w"); -__static_yoink("usr/share/terminfo/f/f200vi"); -__static_yoink("usr/share/terminfo/f/fixterm"); -__static_yoink("usr/share/terminfo/3/386at"); -__static_yoink("usr/share/terminfo/3/3b1"); -__static_yoink("usr/share/terminfo/1/1730-lm"); -__static_yoink("usr/share/terminfo/1/1178"); -__static_yoink("usr/share/terminfo/X/X-hpterm"); -__static_yoink("usr/share/terminfo/X/X-hpterm-color2"); -__static_yoink("usr/share/terminfo/Q/Q310-vip-Hw"); -__static_yoink("usr/share/terminfo/Q/Q310-vip-w"); -__static_yoink("usr/share/terminfo/Q/Q310-vip-H"); -__static_yoink("usr/share/terminfo/Q/Q310-vip-H-am"); -__static_yoink("usr/share/terminfo/Q/Q306-8-pc"); -__static_yoink("usr/share/terminfo/Q/Q310-vip-w-am"); -__static_yoink("usr/share/terminfo/t/tty4424m"); -__static_yoink("usr/share/terminfo/t/t1061"); -__static_yoink("usr/share/terminfo/t/tvi92B"); -__static_yoink("usr/share/terminfo/t/tvi920b-p-2p"); -__static_yoink("usr/share/terminfo/t/tek4025-cr"); -__static_yoink("usr/share/terminfo/t/terminet"); -__static_yoink("usr/share/terminfo/t/tvi910+"); -__static_yoink("usr/share/terminfo/t/teken-sc"); -__static_yoink("usr/share/terminfo/t/tab"); -__static_yoink("usr/share/terminfo/t/tvi920b-vb-p"); -__static_yoink("usr/share/terminfo/t/tn300"); -__static_yoink("usr/share/terminfo/t/tvi914"); -__static_yoink("usr/share/terminfo/t/tvi920c-p-2p"); -__static_yoink("usr/share/terminfo/t/ti916"); -__static_yoink("usr/share/terminfo/t/tvi912c-unk"); -__static_yoink("usr/share/terminfo/t/ti916-132"); -__static_yoink("usr/share/terminfo/t/ti703-w"); -__static_yoink("usr/share/terminfo/t/tvi920c-unk"); -__static_yoink("usr/share/terminfo/t/tek4027-ex"); -__static_yoink("usr/share/terminfo/t/t16"); -__static_yoink("usr/share/terminfo/t/ts-1p"); -__static_yoink("usr/share/terminfo/t/tty4420"); -__static_yoink("usr/share/terminfo/t/tvi920b-2p-p"); -__static_yoink("usr/share/terminfo/t/ti924-8"); -__static_yoink("usr/share/terminfo/t/tek"); -__static_yoink("usr/share/terminfo/t/teken-2022"); -__static_yoink("usr/share/terminfo/t/tek4404"); -__static_yoink("usr/share/terminfo/t/ti931"); -__static_yoink("usr/share/terminfo/t/tek4025a"); -__static_yoink("usr/share/terminfo/t/tvi920b-2p-mc"); -__static_yoink("usr/share/terminfo/t/tn1200"); -__static_yoink("usr/share/terminfo/t/tek4107"); -__static_yoink("usr/share/terminfo/t/tvi912b+printer"); -__static_yoink("usr/share/terminfo/t/tek4105"); -__static_yoink("usr/share/terminfo/t/ti916-8"); -__static_yoink("usr/share/terminfo/t/tvi912c-p-vb"); -__static_yoink("usr/share/terminfo/t/tvi920c-unk-vb"); -__static_yoink("usr/share/terminfo/t/tvi912c-2p-mc"); -__static_yoink("usr/share/terminfo/t/tvi912c-2p"); -__static_yoink("usr/share/terminfo/t/teken-16color"); -__static_yoink("usr/share/terminfo/t/tvi912b-vb-mc"); -__static_yoink("usr/share/terminfo/t/ti735"); -__static_yoink("usr/share/terminfo/t/tvi920b-unk-2p"); -__static_yoink("usr/share/terminfo/t/teraterm4.97"); -__static_yoink("usr/share/terminfo/t/tty5420+nl"); -__static_yoink("usr/share/terminfo/t/tws2102-sna"); -__static_yoink("usr/share/terminfo/t/ti916-220-8"); -__static_yoink("usr/share/terminfo/t/tek4113"); -__static_yoink("usr/share/terminfo/t/tek4025-17"); -__static_yoink("usr/share/terminfo/t/tvi920c-vb-mc"); -__static_yoink("usr/share/terminfo/t/tvi920b-mc-vb"); -__static_yoink("usr/share/terminfo/t/terminology-1.8.1"); -__static_yoink("usr/share/terminfo/t/tvi912b-unk"); -__static_yoink("usr/share/terminfo/t/tvi912b+dim"); -__static_yoink("usr/share/terminfo/t/tek4014"); -__static_yoink("usr/share/terminfo/t/ts100-sp"); -__static_yoink("usr/share/terminfo/t/tvi970-vb"); -__static_yoink("usr/share/terminfo/t/tvi955"); -__static_yoink("usr/share/terminfo/t/ts1"); -__static_yoink("usr/share/terminfo/t/tvi950-rv-4p"); -__static_yoink("usr/share/terminfo/t/tandem653"); -__static_yoink("usr/share/terminfo/t/tab132-rv"); -__static_yoink("usr/share/terminfo/t/teraterm"); -__static_yoink("usr/share/terminfo/t/tek4114"); -__static_yoink("usr/share/terminfo/t/tvi955-w"); -__static_yoink("usr/share/terminfo/t/ti928"); -__static_yoink("usr/share/terminfo/t/tek4025-ex"); -__static_yoink("usr/share/terminfo/t/ti928-8"); -__static_yoink("usr/share/terminfo/t/tws2103"); -__static_yoink("usr/share/terminfo/t/tkterm"); -__static_yoink("usr/share/terminfo/t/tek4115"); -__static_yoink("usr/share/terminfo/t/tvi920c-mc-vb"); -__static_yoink("usr/share/terminfo/t/tvi920b-mc-2p"); -__static_yoink("usr/share/terminfo/t/tek4112"); -__static_yoink("usr/share/terminfo/t/tvi920b-vb-mc"); -__static_yoink("usr/share/terminfo/t/tandem6510"); -__static_yoink("usr/share/terminfo/t/tvi912c-2p-p"); -__static_yoink("usr/share/terminfo/t/tvipt"); -__static_yoink("usr/share/terminfo/t/tek4027"); -__static_yoink("usr/share/terminfo/t/tek4023"); -__static_yoink("usr/share/terminfo/t/teraterm-256color"); -__static_yoink("usr/share/terminfo/t/tty5410-w"); -__static_yoink("usr/share/terminfo/t/ttydmd"); -__static_yoink("usr/share/terminfo/t/tty5410v1-w"); -__static_yoink("usr/share/terminfo/t/tvi912b+mc"); -__static_yoink("usr/share/terminfo/t/tty5420-rv-nl"); -__static_yoink("usr/share/terminfo/t/tek4024"); -__static_yoink("usr/share/terminfo/t/ti745"); -__static_yoink("usr/share/terminfo/t/ts100"); -__static_yoink("usr/share/terminfo/t/tvi920c-unk-2p"); -__static_yoink("usr/share/terminfo/t/tab132-15"); -__static_yoink("usr/share/terminfo/t/tw100"); -__static_yoink("usr/share/terminfo/t/tek4107brl"); -__static_yoink("usr/share/terminfo/t/tvi920c-vb-unk"); -__static_yoink("usr/share/terminfo/t/tvi920c-vb"); -__static_yoink("usr/share/terminfo/t/tvi912b-2p-p"); -__static_yoink("usr/share/terminfo/t/tvi920b-2p"); -__static_yoink("usr/share/terminfo/t/tvi920c-p"); -__static_yoink("usr/share/terminfo/t/tvi920b-vb-unk"); -__static_yoink("usr/share/terminfo/t/tvi921"); -__static_yoink("usr/share/terminfo/t/tvi92D"); -__static_yoink("usr/share/terminfo/t/tvi912b-unk-vb"); -__static_yoink("usr/share/terminfo/t/tvi920b-unk-vb"); -__static_yoink("usr/share/terminfo/t/tek4013"); -__static_yoink("usr/share/terminfo/t/tws2103-sna"); -__static_yoink("usr/share/terminfo/t/tvi950-2p"); -__static_yoink("usr/share/terminfo/t/terminator"); -__static_yoink("usr/share/terminfo/t/tek4112-5"); -__static_yoink("usr/share/terminfo/t/tty5420-w-rv"); -__static_yoink("usr/share/terminfo/t/ti707"); -__static_yoink("usr/share/terminfo/t/ti916-8-132"); -__static_yoink("usr/share/terminfo/t/t3700"); -__static_yoink("usr/share/terminfo/t/tvi920c-p-vb"); -__static_yoink("usr/share/terminfo/t/ti924-8w"); -__static_yoink("usr/share/terminfo/t/tvi920c"); -__static_yoink("usr/share/terminfo/t/tty5410v1"); -__static_yoink("usr/share/terminfo/t/teken"); -__static_yoink("usr/share/terminfo/t/ti707-w"); -__static_yoink("usr/share/terminfo/t/tek4205"); -__static_yoink("usr/share/terminfo/t/tab132-w-rv"); -__static_yoink("usr/share/terminfo/t/tek4207-s"); -__static_yoink("usr/share/terminfo/t/tek4207"); -__static_yoink("usr/share/terminfo/t/tek4025-17-ws"); -__static_yoink("usr/share/terminfo/t/tek4109brl"); -__static_yoink("usr/share/terminfo/t/tvi950"); -__static_yoink("usr/share/terminfo/t/tvi925"); -__static_yoink("usr/share/terminfo/t/tek4106brl"); -__static_yoink("usr/share/terminfo/t/tvi9065"); -__static_yoink("usr/share/terminfo/t/t10"); -__static_yoink("usr/share/terminfo/t/tvi955-hb"); -__static_yoink("usr/share/terminfo/t/tty43"); -__static_yoink("usr/share/terminfo/t/tty5420-w"); -__static_yoink("usr/share/terminfo/t/tvi912b"); -__static_yoink("usr/share/terminfo/t/ti926-8"); -__static_yoink("usr/share/terminfo/t/tty5425-w"); -__static_yoink("usr/share/terminfo/t/tek4015"); -__static_yoink("usr/share/terminfo/t/tty5425-nl"); -__static_yoink("usr/share/terminfo/t/tvi920"); -__static_yoink("usr/share/terminfo/t/tvi920c-mc"); -__static_yoink("usr/share/terminfo/t/tvi912b-2p"); -__static_yoink("usr/share/terminfo/t/tty5620-1"); -__static_yoink("usr/share/terminfo/t/tab132-w"); -__static_yoink("usr/share/terminfo/t/ts-1"); -__static_yoink("usr/share/terminfo/t/ti916-220-7"); -__static_yoink("usr/share/terminfo/t/terminet300"); -__static_yoink("usr/share/terminfo/t/ts100-ctxt"); -__static_yoink("usr/share/terminfo/t/tvi912c-mc-2p"); -__static_yoink("usr/share/terminfo/t/tty35"); -__static_yoink("usr/share/terminfo/t/terminology"); -__static_yoink("usr/share/terminfo/t/tek4105-30"); -__static_yoink("usr/share/terminfo/t/tvi912b+2p"); -__static_yoink("usr/share/terminfo/t/tvi912c"); -__static_yoink("usr/share/terminfo/t/tvi912c-unk-vb"); -__static_yoink("usr/share/terminfo/t/tty4424"); -__static_yoink("usr/share/terminfo/t/ti_ansi"); -__static_yoink("usr/share/terminfo/t/tek4113-nd"); -__static_yoink("usr/share/terminfo/t/tt"); -__static_yoink("usr/share/terminfo/t/tgtelnet"); -__static_yoink("usr/share/terminfo/t/t1061f"); -__static_yoink("usr/share/terminfo/t/tty5620-24"); -__static_yoink("usr/share/terminfo/t/tvi912b-vb-p"); -__static_yoink("usr/share/terminfo/t/tvi912b-p"); -__static_yoink("usr/share/terminfo/t/tmux-direct"); -__static_yoink("usr/share/terminfo/t/tvi970"); -__static_yoink("usr/share/terminfo/t/tvi920b-mc"); -__static_yoink("usr/share/terminfo/t/teleray"); -__static_yoink("usr/share/terminfo/t/tvi920c-vb-p"); -__static_yoink("usr/share/terminfo/t/tvi950-rv"); -__static_yoink("usr/share/terminfo/t/tty40"); -__static_yoink("usr/share/terminfo/t/ti703"); -__static_yoink("usr/share/terminfo/t/tvi920b+fn"); -__static_yoink("usr/share/terminfo/t/tvi950-rv-2p"); -__static_yoink("usr/share/terminfo/t/tvi912b-mc-2p"); -__static_yoink("usr/share/terminfo/t/ti924"); -__static_yoink("usr/share/terminfo/t/trs2"); -__static_yoink("usr/share/terminfo/t/tvi912b-unk-2p"); -__static_yoink("usr/share/terminfo/t/tvi912b-p-vb"); -__static_yoink("usr/share/terminfo/t/trsII"); -__static_yoink("usr/share/terminfo/t/tvi920c-2p-p"); -__static_yoink("usr/share/terminfo/t/tvi912c-vb-p"); -__static_yoink("usr/share/terminfo/t/terminology-0.6.1"); -__static_yoink("usr/share/terminfo/t/tty33"); -__static_yoink("usr/share/terminfo/t/trs16"); -__static_yoink("usr/share/terminfo/t/tek4014-sm"); -__static_yoink("usr/share/terminfo/t/tmux"); -__static_yoink("usr/share/terminfo/t/tvi912c-vb"); -__static_yoink("usr/share/terminfo/t/tek4025ex"); -__static_yoink("usr/share/terminfo/t/tek4113-34"); -__static_yoink("usr/share/terminfo/t/tw52"); -__static_yoink("usr/share/terminfo/t/ti800"); -__static_yoink("usr/share/terminfo/t/tvi950-4p"); -__static_yoink("usr/share/terminfo/t/t653x"); -__static_yoink("usr/share/terminfo/t/tvi912c-mc"); -__static_yoink("usr/share/terminfo/t/tvi912b-2p-unk"); -__static_yoink("usr/share/terminfo/t/tvi920c-2p-mc"); -__static_yoink("usr/share/terminfo/t/teraterm4.59"); -__static_yoink("usr/share/terminfo/t/tty5410"); -__static_yoink("usr/share/terminfo/t/tvi920b-2p-unk"); -__static_yoink("usr/share/terminfo/t/ti733"); -__static_yoink("usr/share/terminfo/t/tty5620"); -__static_yoink("usr/share/terminfo/t/tvi912c-p-2p"); -__static_yoink("usr/share/terminfo/t/trs80II"); -__static_yoink("usr/share/terminfo/t/tty5420-w-nl"); -__static_yoink("usr/share/terminfo/t/teletec"); -__static_yoink("usr/share/terminfo/t/tab132"); -__static_yoink("usr/share/terminfo/t/tek4015-sm"); -__static_yoink("usr/share/terminfo/t/teken-vt"); -__static_yoink("usr/share/terminfo/t/tvi920c-mc-2p"); -__static_yoink("usr/share/terminfo/t/tek4012"); -__static_yoink("usr/share/terminfo/t/tvi910"); -__static_yoink("usr/share/terminfo/t/tvi912"); -__static_yoink("usr/share/terminfo/t/tty37"); -__static_yoink("usr/share/terminfo/t/teraterm2.3"); -__static_yoink("usr/share/terminfo/t/tvi912b-vb"); -__static_yoink("usr/share/terminfo/t/tty5420-nl"); -__static_yoink("usr/share/terminfo/t/tw52-color"); -__static_yoink("usr/share/terminfo/t/ti924w"); -__static_yoink("usr/share/terminfo/t/t3800"); -__static_yoink("usr/share/terminfo/t/tty5425"); -__static_yoink("usr/share/terminfo/t/ti700"); -__static_yoink("usr/share/terminfo/t/tvi912b-vb-unk"); -__static_yoink("usr/share/terminfo/t/tvi912b+vb"); -__static_yoink("usr/share/terminfo/t/tty5420-rv"); -__static_yoink("usr/share/terminfo/t/tvi912c-p"); -__static_yoink("usr/share/terminfo/t/tek4112-nd"); -__static_yoink("usr/share/terminfo/t/tvi912c-mc-vb"); -__static_yoink("usr/share/terminfo/t/tvi912c-vb-mc"); -__static_yoink("usr/share/terminfo/t/tty4426"); -__static_yoink("usr/share/terminfo/t/tty5620-34"); -__static_yoink("usr/share/terminfo/t/tty5420-w-rv-n"); -__static_yoink("usr/share/terminfo/t/ti926"); -__static_yoink("usr/share/terminfo/t/tvi912cc"); -__static_yoink("usr/share/terminfo/t/tvi920c-2p"); -__static_yoink("usr/share/terminfo/t/tvi912c-unk-2p"); -__static_yoink("usr/share/terminfo/t/tvi920b-p"); -__static_yoink("usr/share/terminfo/t/tvi912b-mc-vb"); -__static_yoink("usr/share/terminfo/t/tvi925-hi"); -__static_yoink("usr/share/terminfo/t/tvi912c-2p-unk"); -__static_yoink("usr/share/terminfo/t/ts1p"); -__static_yoink("usr/share/terminfo/t/tvi912c-vb-unk"); -__static_yoink("usr/share/terminfo/t/tvi803"); -__static_yoink("usr/share/terminfo/t/tek4025"); -__static_yoink("usr/share/terminfo/t/tty5420"); -__static_yoink("usr/share/terminfo/t/tvi920b-unk"); -__static_yoink("usr/share/terminfo/t/teken-vt+fkeys"); -__static_yoink("usr/share/terminfo/t/tvi920b"); -__static_yoink("usr/share/terminfo/t/tek4105a"); -__static_yoink("usr/share/terminfo/t/tvi912b-2p-mc"); -__static_yoink("usr/share/terminfo/t/tty4424-1"); -__static_yoink("usr/share/terminfo/t/tvi970-2p"); -__static_yoink("usr/share/terminfo/t/tvi912b-p-2p"); -__static_yoink("usr/share/terminfo/t/tvi924"); -__static_yoink("usr/share/terminfo/t/tws-generic"); -__static_yoink("usr/share/terminfo/t/tek4125"); -__static_yoink("usr/share/terminfo/t/tmux-256color"); -__static_yoink("usr/share/terminfo/t/tw52-m"); -__static_yoink("usr/share/terminfo/t/tvi920c-2p-unk"); -__static_yoink("usr/share/terminfo/t/tt52"); -__static_yoink("usr/share/terminfo/t/tvi912b-mc"); -__static_yoink("usr/share/terminfo/t/termite"); -__static_yoink("usr/share/terminfo/t/tek4109"); -__static_yoink("usr/share/terminfo/t/terminology-1.0.0"); -__static_yoink("usr/share/terminfo/t/teken-sc+fkeys"); -__static_yoink("usr/share/terminfo/t/tvi920b-p-vb"); -__static_yoink("usr/share/terminfo/t/terminet1200"); -__static_yoink("usr/share/terminfo/t/tty5620-s"); -__static_yoink("usr/share/terminfo/t/teken-2018"); -__static_yoink("usr/share/terminfo/t/tvi920b-vb"); -__static_yoink("usr/share/terminfo/a/att2300"); -__static_yoink("usr/share/terminfo/a/adds980"); -__static_yoink("usr/share/terminfo/a/att730-41"); -__static_yoink("usr/share/terminfo/a/att4415-nl"); -__static_yoink("usr/share/terminfo/a/altos-2"); -__static_yoink("usr/share/terminfo/a/att610-103k-w"); -__static_yoink("usr/share/terminfo/a/avt-w"); -__static_yoink("usr/share/terminfo/a/ansiw"); -__static_yoink("usr/share/terminfo/a/aaa-24"); -__static_yoink("usr/share/terminfo/a/aj510"); -__static_yoink("usr/share/terminfo/a/ansil-mono"); -__static_yoink("usr/share/terminfo/a/att4410v1"); -__static_yoink("usr/share/terminfo/a/aixterm-m-old"); -__static_yoink("usr/share/terminfo/a/att5420-w"); -__static_yoink("usr/share/terminfo/a/adm2"); -__static_yoink("usr/share/terminfo/a/aaa-28"); -__static_yoink("usr/share/terminfo/a/ansi+cpr"); -__static_yoink("usr/share/terminfo/a/att610+cvis0"); -__static_yoink("usr/share/terminfo/a/abm85h-old"); -__static_yoink("usr/share/terminfo/a/at-color"); -__static_yoink("usr/share/terminfo/a/att513"); -__static_yoink("usr/share/terminfo/a/aaa-60-s"); -__static_yoink("usr/share/terminfo/a/att4410"); -__static_yoink("usr/share/terminfo/a/annarbor4080"); -__static_yoink("usr/share/terminfo/a/att615-103k-w"); -__static_yoink("usr/share/terminfo/a/avatar1"); -__static_yoink("usr/share/terminfo/a/att4415"); -__static_yoink("usr/share/terminfo/a/att610-w"); -__static_yoink("usr/share/terminfo/a/ansi-color-2-emx"); -__static_yoink("usr/share/terminfo/a/aaa-26"); -__static_yoink("usr/share/terminfo/a/att5410v1-w"); -__static_yoink("usr/share/terminfo/a/ansi+idl"); -__static_yoink("usr/share/terminfo/a/aaa-40-rv"); -__static_yoink("usr/share/terminfo/a/apple2e-p"); -__static_yoink("usr/share/terminfo/a/act5"); -__static_yoink("usr/share/terminfo/a/abm85h"); -__static_yoink("usr/share/terminfo/a/att4425-nl"); -__static_yoink("usr/share/terminfo/a/abm85e"); -__static_yoink("usr/share/terminfo/a/adm3a"); -__static_yoink("usr/share/terminfo/a/avt-s"); -__static_yoink("usr/share/terminfo/a/ansi+sgrul"); -__static_yoink("usr/share/terminfo/a/att730r"); -__static_yoink("usr/share/terminfo/a/apple-videx2"); -__static_yoink("usr/share/terminfo/a/aas1901"); -__static_yoink("usr/share/terminfo/a/aaa-30-s-rv-ct"); -__static_yoink("usr/share/terminfo/a/ansi.sysk"); -__static_yoink("usr/share/terminfo/a/ansi+pp"); -__static_yoink("usr/share/terminfo/a/ampex232"); -__static_yoink("usr/share/terminfo/a/ampex-232"); -__static_yoink("usr/share/terminfo/a/att5420-w-nl"); -__static_yoink("usr/share/terminfo/a/att615-w"); -__static_yoink("usr/share/terminfo/a/aaa-18"); -__static_yoink("usr/share/terminfo/a/ansi+enq"); -__static_yoink("usr/share/terminfo/a/ansi77"); -__static_yoink("usr/share/terminfo/a/aa4080"); -__static_yoink("usr/share/terminfo/a/avt-rv-ns"); -__static_yoink("usr/share/terminfo/a/att4425"); -__static_yoink("usr/share/terminfo/a/att5620-1"); -__static_yoink("usr/share/terminfo/a/ansi80x60"); -__static_yoink("usr/share/terminfo/a/apple-vm80"); -__static_yoink("usr/share/terminfo/a/alto-h19"); -__static_yoink("usr/share/terminfo/a/aaa-30-s-ctxt"); -__static_yoink("usr/share/terminfo/a/att5420-rv"); -__static_yoink("usr/share/terminfo/a/att605-w"); -__static_yoink("usr/share/terminfo/a/atari-old"); -__static_yoink("usr/share/terminfo/a/apple-80"); -__static_yoink("usr/share/terminfo/a/aaa"); -__static_yoink("usr/share/terminfo/a/atari-m"); -__static_yoink("usr/share/terminfo/a/arm100"); -__static_yoink("usr/share/terminfo/a/aaa-30-s-rv"); -__static_yoink("usr/share/terminfo/a/avt-ns"); -__static_yoink("usr/share/terminfo/a/ansi+local"); -__static_yoink("usr/share/terminfo/a/aaa-db"); -__static_yoink("usr/share/terminfo/a/aixterm+sl"); -__static_yoink("usr/share/terminfo/a/ansi+rep"); -__static_yoink("usr/share/terminfo/a/ansi+rca2"); -__static_yoink("usr/share/terminfo/a/ansi+erase"); -__static_yoink("usr/share/terminfo/a/avt-w-rv-s"); -__static_yoink("usr/share/terminfo/a/att5620-s"); -__static_yoink("usr/share/terminfo/a/adm3"); -__static_yoink("usr/share/terminfo/a/arm100-am"); -__static_yoink("usr/share/terminfo/a/aixterm-16color"); -__static_yoink("usr/share/terminfo/a/aaa-36"); -__static_yoink("usr/share/terminfo/a/atari"); -__static_yoink("usr/share/terminfo/a/adm31-old"); -__static_yoink("usr/share/terminfo/a/apple-uterm-vb"); -__static_yoink("usr/share/terminfo/a/ansisysk"); -__static_yoink("usr/share/terminfo/a/apollo"); -__static_yoink("usr/share/terminfo/a/at-m"); -__static_yoink("usr/share/terminfo/a/att610-103k"); -__static_yoink("usr/share/terminfo/a/ansi80x50"); -__static_yoink("usr/share/terminfo/a/at386"); -__static_yoink("usr/share/terminfo/a/adm1178"); -__static_yoink("usr/share/terminfo/a/ansi"); -__static_yoink("usr/share/terminfo/a/alt2"); -__static_yoink("usr/share/terminfo/a/aaa-30"); -__static_yoink("usr/share/terminfo/a/ansi80x60-mono"); -__static_yoink("usr/share/terminfo/a/att5420_2"); -__static_yoink("usr/share/terminfo/a/ansi+sgr"); -__static_yoink("usr/share/terminfo/a/aaa-30-rv"); -__static_yoink("usr/share/terminfo/a/amp219"); -__static_yoink("usr/share/terminfo/a/ansi-mini"); -__static_yoink("usr/share/terminfo/a/aaa-24-rv"); -__static_yoink("usr/share/terminfo/a/aaa-60-dec-rv"); -__static_yoink("usr/share/terminfo/a/aterm"); -__static_yoink("usr/share/terminfo/a/att5320"); -__static_yoink("usr/share/terminfo/a/amiga-8bit"); -__static_yoink("usr/share/terminfo/a/avatar0+"); -__static_yoink("usr/share/terminfo/a/aaa-s"); -__static_yoink("usr/share/terminfo/a/ansi+rca"); -__static_yoink("usr/share/terminfo/a/addrinfo"); -__static_yoink("usr/share/terminfo/a/ansi+idl1"); -__static_yoink("usr/share/terminfo/a/ansi80x43-mono"); -__static_yoink("usr/share/terminfo/a/alt4"); -__static_yoink("usr/share/terminfo/a/att605"); -__static_yoink("usr/share/terminfo/a/att5420-w-rv"); -__static_yoink("usr/share/terminfo/a/ansi+local1"); -__static_yoink("usr/share/terminfo/a/ansi80x25"); -__static_yoink("usr/share/terminfo/a/ansi80x25-raw"); -__static_yoink("usr/share/terminfo/a/adm1a"); -__static_yoink("usr/share/terminfo/a/alt5"); -__static_yoink("usr/share/terminfo/a/att5620-34"); -__static_yoink("usr/share/terminfo/a/ansi-mr"); -__static_yoink("usr/share/terminfo/a/avt-w-rv-ns"); -__static_yoink("usr/share/terminfo/a/aaa-40"); -__static_yoink("usr/share/terminfo/a/alacritty"); -__static_yoink("usr/share/terminfo/a/aaa-30-rv-ctxt"); -__static_yoink("usr/share/terminfo/a/att4424"); -__static_yoink("usr/share/terminfo/a/apple80p"); -__static_yoink("usr/share/terminfo/a/att4410-w"); -__static_yoink("usr/share/terminfo/a/ampex232w"); -__static_yoink("usr/share/terminfo/a/ansiterm"); -__static_yoink("usr/share/terminfo/a/aaa-60-rv"); -__static_yoink("usr/share/terminfo/a/ampex80"); -__static_yoink("usr/share/terminfo/a/att730r-24"); -__static_yoink("usr/share/terminfo/a/altos7pc"); -__static_yoink("usr/share/terminfo/a/adm+sgr"); -__static_yoink("usr/share/terminfo/a/att5420-rv-nl"); -__static_yoink("usr/share/terminfo/a/att610+cvis"); -__static_yoink("usr/share/terminfo/a/adm36"); -__static_yoink("usr/share/terminfo/a/adm5"); -__static_yoink("usr/share/terminfo/a/aaa-36-rv"); -__static_yoink("usr/share/terminfo/a/appleIIgs"); -__static_yoink("usr/share/terminfo/a/att5430"); -__static_yoink("usr/share/terminfo/a/apple-videx3"); -__static_yoink("usr/share/terminfo/a/amiga"); -__static_yoink("usr/share/terminfo/a/att5420+nl"); -__static_yoink("usr/share/terminfo/a/aws"); -__static_yoink("usr/share/terminfo/a/ansi+sgrbold"); -__static_yoink("usr/share/terminfo/a/adm31"); -__static_yoink("usr/share/terminfo/a/ansis"); -__static_yoink("usr/share/terminfo/a/ansi+idc"); -__static_yoink("usr/share/terminfo/a/alt7pc"); -__static_yoink("usr/share/terminfo/a/abm85"); -__static_yoink("usr/share/terminfo/a/att4415-rv"); -__static_yoink("usr/share/terminfo/a/aaa-rv-ctxt"); -__static_yoink("usr/share/terminfo/a/ampex210"); -__static_yoink("usr/share/terminfo/a/ansi80x50-mono"); -__static_yoink("usr/share/terminfo/a/avatar"); -__static_yoink("usr/share/terminfo/a/avt-rv-s"); -__static_yoink("usr/share/terminfo/a/ansi+cup"); -__static_yoink("usr/share/terminfo/a/alacritty-direct"); -__static_yoink("usr/share/terminfo/a/att5420-nl"); -__static_yoink("usr/share/terminfo/a/att6386"); -__static_yoink("usr/share/terminfo/a/aaa-s-rv-ctxt"); -__static_yoink("usr/share/terminfo/a/altos3"); -__static_yoink("usr/share/terminfo/a/altos5"); -__static_yoink("usr/share/terminfo/a/aepro"); -__static_yoink("usr/share/terminfo/a/amiga-vnc"); -__static_yoink("usr/share/terminfo/a/altos2"); -__static_yoink("usr/share/terminfo/a/att630-24"); -__static_yoink("usr/share/terminfo/a/appleIIc"); -__static_yoink("usr/share/terminfo/a/adm12"); -__static_yoink("usr/share/terminfo/a/atari-color"); -__static_yoink("usr/share/terminfo/a/a80"); -__static_yoink("usr/share/terminfo/a/att510a"); -__static_yoink("usr/share/terminfo/a/att630"); -__static_yoink("usr/share/terminfo/a/aaa+rv"); -__static_yoink("usr/share/terminfo/a/at"); -__static_yoink("usr/share/terminfo/a/alto-heath"); -__static_yoink("usr/share/terminfo/a/ansi80x30"); -__static_yoink("usr/share/terminfo/a/att4425-w"); -__static_yoink("usr/share/terminfo/a/apple-videx"); -__static_yoink("usr/share/terminfo/a/alt3"); -__static_yoink("usr/share/terminfo/a/att505-22"); -__static_yoink("usr/share/terminfo/a/apl"); -__static_yoink("usr/share/terminfo/a/ampex175-b"); -__static_yoink("usr/share/terminfo/a/att5420-w-rv-n"); -__static_yoink("usr/share/terminfo/a/ansi-emx"); -__static_yoink("usr/share/terminfo/a/addsviewpoint"); -__static_yoink("usr/share/terminfo/a/ansi43m"); -__static_yoink("usr/share/terminfo/a/att5310"); -__static_yoink("usr/share/terminfo/a/adm20"); -__static_yoink("usr/share/terminfo/a/aaa+dec"); -__static_yoink("usr/share/terminfo/a/adm3a+"); -__static_yoink("usr/share/terminfo/a/ansis-mono"); -__static_yoink("usr/share/terminfo/a/awsc"); -__static_yoink("usr/share/terminfo/a/ansi.sys-old"); -__static_yoink("usr/share/terminfo/a/altoheath"); -__static_yoink("usr/share/terminfo/a/apple2e"); -__static_yoink("usr/share/terminfo/a/ambas"); -__static_yoink("usr/share/terminfo/a/att700"); -__static_yoink("usr/share/terminfo/a/amiga-h"); -__static_yoink("usr/share/terminfo/a/adm1"); -__static_yoink("usr/share/terminfo/a/a980"); -__static_yoink("usr/share/terminfo/a/ansi+sgrdim"); -__static_yoink("usr/share/terminfo/a/altos-4"); -__static_yoink("usr/share/terminfo/a/att4415+nl"); -__static_yoink("usr/share/terminfo/a/att4418-w"); -__static_yoink("usr/share/terminfo/a/aj830"); -__static_yoink("usr/share/terminfo/a/att5410-w"); -__static_yoink("usr/share/terminfo/a/att4415-w-rv"); -__static_yoink("usr/share/terminfo/a/arm100-wam"); -__static_yoink("usr/share/terminfo/a/ansi.sys"); -__static_yoink("usr/share/terminfo/a/aaa-s-rv"); -__static_yoink("usr/share/terminfo/a/adm42"); -__static_yoink("usr/share/terminfo/a/att4418"); -__static_yoink("usr/share/terminfo/a/alacritty+common"); -__static_yoink("usr/share/terminfo/a/att7300"); -__static_yoink("usr/share/terminfo/a/att4410v1-w"); -__static_yoink("usr/share/terminfo/a/aaa-30-s"); -__static_yoink("usr/share/terminfo/a/appleII"); -__static_yoink("usr/share/terminfo/a/aaa-48-rv"); -__static_yoink("usr/share/terminfo/a/absolute"); -__static_yoink("usr/share/terminfo/a/aaa-ctxt"); -__static_yoink("usr/share/terminfo/a/atari_st-color"); -__static_yoink("usr/share/terminfo/a/aaa-rv-unk"); -__static_yoink("usr/share/terminfo/a/avt-w-ns"); -__static_yoink("usr/share/terminfo/a/ansi-generic"); -__static_yoink("usr/share/terminfo/a/ampex-219w"); -__static_yoink("usr/share/terminfo/a/att4415-w-rv-n"); -__static_yoink("usr/share/terminfo/a/apple-uterm"); -__static_yoink("usr/share/terminfo/a/aaa-30-ctxt"); -__static_yoink("usr/share/terminfo/a/aixterm-m"); -__static_yoink("usr/share/terminfo/a/avt+s"); -__static_yoink("usr/share/terminfo/a/ansi+inittabs"); -__static_yoink("usr/share/terminfo/a/ansi80x43"); -__static_yoink("usr/share/terminfo/a/ansi+idc1"); -__static_yoink("usr/share/terminfo/a/avt-w-rv"); -__static_yoink("usr/share/terminfo/a/adm42-ns"); -__static_yoink("usr/share/terminfo/a/arm100-w"); -__static_yoink("usr/share/terminfo/a/aixterm"); -__static_yoink("usr/share/terminfo/a/atarist-m"); -__static_yoink("usr/share/terminfo/a/ansi80x25-mono"); -__static_yoink("usr/share/terminfo/a/ansi80x30-mono"); -__static_yoink("usr/share/terminfo/a/altos-3"); -__static_yoink("usr/share/terminfo/a/aaa-unk"); -__static_yoink("usr/share/terminfo/a/ansi+sgrso"); -__static_yoink("usr/share/terminfo/a/avatar0"); -__static_yoink("usr/share/terminfo/a/att4424-1"); -__static_yoink("usr/share/terminfo/a/a210"); -__static_yoink("usr/share/terminfo/a/altos7"); -__static_yoink("usr/share/terminfo/a/att5425-w"); -__static_yoink("usr/share/terminfo/a/apollo_19L"); -__static_yoink("usr/share/terminfo/a/ansi-mono"); -__static_yoink("usr/share/terminfo/a/ampex175"); -__static_yoink("usr/share/terminfo/a/att505-24"); -__static_yoink("usr/share/terminfo/a/aaa-22"); -__static_yoink("usr/share/terminfo/a/appleIIe"); -__static_yoink("usr/share/terminfo/a/att615-103k"); -__static_yoink("usr/share/terminfo/a/ampex219"); -__static_yoink("usr/share/terminfo/a/adm11"); -__static_yoink("usr/share/terminfo/a/att730-24"); -__static_yoink("usr/share/terminfo/a/avt-w-s"); -__static_yoink("usr/share/terminfo/a/aaa-48"); -__static_yoink("usr/share/terminfo/a/apple-soroc"); -__static_yoink("usr/share/terminfo/a/aaa-60"); -__static_yoink("usr/share/terminfo/a/att605-pc"); -__static_yoink("usr/share/terminfo/a/altos4"); -__static_yoink("usr/share/terminfo/a/aaa+unk"); -__static_yoink("usr/share/terminfo/a/att5425"); -__static_yoink("usr/share/terminfo/a/ansi-mtabs"); -__static_yoink("usr/share/terminfo/a/att5410"); -__static_yoink("usr/share/terminfo/a/apollo_15P"); -__static_yoink("usr/share/terminfo/a/avt"); -__static_yoink("usr/share/terminfo/a/att500"); -__static_yoink("usr/share/terminfo/a/att5420_2-w"); -__static_yoink("usr/share/terminfo/a/att730"); -__static_yoink("usr/share/terminfo/a/amp219w"); -__static_yoink("usr/share/terminfo/a/att4424m"); -__static_yoink("usr/share/terminfo/a/att620-103k"); -__static_yoink("usr/share/terminfo/a/avt-rv"); -__static_yoink("usr/share/terminfo/a/apple-ae"); -__static_yoink("usr/share/terminfo/a/aaa-rv"); -__static_yoink("usr/share/terminfo/a/att5620"); -__static_yoink("usr/share/terminfo/a/apollo_color"); -__static_yoink("usr/share/terminfo/a/att505"); -__static_yoink("usr/share/terminfo/a/att5620-24"); -__static_yoink("usr/share/terminfo/a/aaa-20"); -__static_yoink("usr/share/terminfo/a/att510d"); -__static_yoink("usr/share/terminfo/a/att4415-w-nl"); -__static_yoink("usr/share/terminfo/a/att4415-rv-nl"); -__static_yoink("usr/share/terminfo/a/aaa-60-s-rv"); -__static_yoink("usr/share/terminfo/a/ansi+csr"); -__static_yoink("usr/share/terminfo/a/att5420"); -__static_yoink("usr/share/terminfo/a/ambassador"); -__static_yoink("usr/share/terminfo/a/adm22"); -__static_yoink("usr/share/terminfo/a/ansi+arrows"); -__static_yoink("usr/share/terminfo/a/att4426"); -__static_yoink("usr/share/terminfo/a/ansil"); -__static_yoink("usr/share/terminfo/a/att615"); -__static_yoink("usr/share/terminfo/a/att5418"); -__static_yoink("usr/share/terminfo/a/att620-103k-w"); -__static_yoink("usr/share/terminfo/a/att5410v1"); -__static_yoink("usr/share/terminfo/a/att5418-w"); -__static_yoink("usr/share/terminfo/a/adds200"); -__static_yoink("usr/share/terminfo/a/atari_st"); -__static_yoink("usr/share/terminfo/a/aj832"); -__static_yoink("usr/share/terminfo/a/ansi+tabs"); -__static_yoink("usr/share/terminfo/a/ampex-219"); -__static_yoink("usr/share/terminfo/a/att2350"); -__static_yoink("usr/share/terminfo/a/act4"); -__static_yoink("usr/share/terminfo/a/ampex219w"); -__static_yoink("usr/share/terminfo/a/aaa-18-rv"); -__static_yoink("usr/share/terminfo/a/att5425-nl"); -__static_yoink("usr/share/terminfo/a/ansi-nt"); -__static_yoink("usr/share/terminfo/a/aj"); -__static_yoink("usr/share/terminfo/a/apollo+vt132"); -__static_yoink("usr/share/terminfo/a/abm80"); -__static_yoink("usr/share/terminfo/a/altos-5"); -__static_yoink("usr/share/terminfo/a/ap-vm80"); -__static_yoink("usr/share/terminfo/a/att620"); -__static_yoink("usr/share/terminfo/a/att4415-w"); -__static_yoink("usr/share/terminfo/a/ansi-m"); -__static_yoink("usr/share/terminfo/a/adm21"); -__static_yoink("usr/share/terminfo/a/addsvp60"); -__static_yoink("usr/share/terminfo/a/att4420"); -__static_yoink("usr/share/terminfo/a/att730r-41"); -__static_yoink("usr/share/terminfo/a/altoh19"); -__static_yoink("usr/share/terminfo/a/alt7"); -__static_yoink("usr/share/terminfo/a/aaa-s-ctxt"); -__static_yoink("usr/share/terminfo/a/att610"); -__static_yoink("usr/share/terminfo/a/att620-w"); -__static_yoink("usr/share/terminfo/a/ansi-color-3-emx"); -__static_yoink("usr/share/terminfo/N/NCRVT100WPP"); -__static_yoink("usr/share/terminfo/N/NCR260VT300WPP"); -__static_yoink("usr/share/terminfo/j/jfbterm"); -__static_yoink("usr/share/terminfo/j/jaixterm-m"); -__static_yoink("usr/share/terminfo/j/jaixterm"); -__static_yoink("usr/share/terminfo/j/jerq"); -__static_yoink("usr/share/terminfo/4/4027ex"); -__static_yoink("usr/share/terminfo/4/4410-w"); -__static_yoink("usr/share/terminfo/4/4025ex"); -__static_yoink("usr/share/terminfo/x/xnuppc-80x25"); -__static_yoink("usr/share/terminfo/x/x1700"); -__static_yoink("usr/share/terminfo/x/xterm+kbs"); -__static_yoink("usr/share/terminfo/x/xtermm"); -__static_yoink("usr/share/terminfo/x/xterm+pcc2"); -__static_yoink("usr/share/terminfo/x/xnuppc+160x64"); -__static_yoink("usr/share/terminfo/x/xwsh"); -__static_yoink("usr/share/terminfo/x/xterm+x11mouse"); -__static_yoink("usr/share/terminfo/x/xterm+sm+1002"); -__static_yoink("usr/share/terminfo/x/xterm+keypad"); -__static_yoink("usr/share/terminfo/x/xnuppc-m-f"); -__static_yoink("usr/share/terminfo/x/xnuppc"); -__static_yoink("usr/share/terminfo/x/xnuppc+f"); -__static_yoink("usr/share/terminfo/x/xterm-nic"); -__static_yoink("usr/share/terminfo/x/xterm+edit"); -__static_yoink("usr/share/terminfo/x/xterm+direct16"); -__static_yoink("usr/share/terminfo/x/xterm+focus"); -__static_yoink("usr/share/terminfo/x/xnuppc-b"); -__static_yoink("usr/share/terminfo/x/xterms-sun"); -__static_yoink("usr/share/terminfo/x/xnuppc+200x64"); -__static_yoink("usr/share/terminfo/x/xnuppc+256x96"); -__static_yoink("usr/share/terminfo/x/xnuppc+200x75"); -__static_yoink("usr/share/terminfo/x/xnuppc+112x37"); -__static_yoink("usr/share/terminfo/x/xterm+alt+title"); -__static_yoink("usr/share/terminfo/x/xterm-1003"); -__static_yoink("usr/share/terminfo/x/xterm+acs"); -__static_yoink("usr/share/terminfo/x/xterm-xf86-v44"); -__static_yoink("usr/share/terminfo/x/x68k"); -__static_yoink("usr/share/terminfo/x/xterm+tmux2"); -__static_yoink("usr/share/terminfo/x/xterm+sl-twm"); -__static_yoink("usr/share/terminfo/x/xnuppc-128x48"); -__static_yoink("usr/share/terminfo/x/xfce"); -__static_yoink("usr/share/terminfo/x/xterm+sm+1003"); -__static_yoink("usr/share/terminfo/x/xnuppc-100x37-m"); -__static_yoink("usr/share/terminfo/x/xterm-r6"); -__static_yoink("usr/share/terminfo/x/x1700-lm"); -__static_yoink("usr/share/terminfo/x/xterm+88color2"); -__static_yoink("usr/share/terminfo/x/xterm-direct16"); -__static_yoink("usr/share/terminfo/x/x1720"); -__static_yoink("usr/share/terminfo/x/xerox-lm"); -__static_yoink("usr/share/terminfo/x/xterm-kitty"); -__static_yoink("usr/share/terminfo/x/xterm-hp"); -__static_yoink("usr/share/terminfo/x/xterm-p370"); -__static_yoink("usr/share/terminfo/x/xterm+pcc3"); -__static_yoink("usr/share/terminfo/x/xnuppc-256x96-m"); -__static_yoink("usr/share/terminfo/x/xterm+x11hilite"); -__static_yoink("usr/share/terminfo/x/xterm+noapp"); -__static_yoink("usr/share/terminfo/x/xterm-direct2"); -__static_yoink("usr/share/terminfo/x/xterm+pc+edit"); -__static_yoink("usr/share/terminfo/x/xterm-sun"); -__static_yoink("usr/share/terminfo/x/xiterm"); -__static_yoink("usr/share/terminfo/x/xerox820"); -__static_yoink("usr/share/terminfo/x/xnuppc+c"); -__static_yoink("usr/share/terminfo/x/x1750"); -__static_yoink("usr/share/terminfo/x/xterm-old"); -__static_yoink("usr/share/terminfo/x/xterm-1006"); -__static_yoink("usr/share/terminfo/x/xterm+tmux"); -__static_yoink("usr/share/terminfo/x/xterm-x10mouse"); -__static_yoink("usr/share/terminfo/x/xterm"); -__static_yoink("usr/share/terminfo/x/xterm-8bit"); -__static_yoink("usr/share/terminfo/x/xterm+nopcfkeys"); -__static_yoink("usr/share/terminfo/x/xterm+pcf2"); -__static_yoink("usr/share/terminfo/x/xterm1"); -__static_yoink("usr/share/terminfo/x/xterm-vt220"); -__static_yoink("usr/share/terminfo/x/xnuppc-80x30-m"); -__static_yoink("usr/share/terminfo/x/xterm+pcfkeys"); -__static_yoink("usr/share/terminfo/x/xnuppc-m-f2"); -__static_yoink("usr/share/terminfo/x/xtermc"); -__static_yoink("usr/share/terminfo/x/xterm-24"); -__static_yoink("usr/share/terminfo/x/xterm+sm+1005"); -__static_yoink("usr/share/terminfo/x/xterm-88color"); -__static_yoink("usr/share/terminfo/x/xterm+app"); -__static_yoink("usr/share/terminfo/x/xterm+x10mouse"); -__static_yoink("usr/share/terminfo/x/xerox1720"); -__static_yoink("usr/share/terminfo/x/xnuppc-256x96"); -__static_yoink("usr/share/terminfo/x/xterm-xf86-v33"); -__static_yoink("usr/share/terminfo/x/xterms"); -__static_yoink("usr/share/terminfo/x/xterm-sco"); -__static_yoink("usr/share/terminfo/x/xterm+sl-alt"); -__static_yoink("usr/share/terminfo/x/xnuppc+b"); -__static_yoink("usr/share/terminfo/x/xterm-new"); -__static_yoink("usr/share/terminfo/x/xterm+direct"); -__static_yoink("usr/share/terminfo/x/xnuppc+128x40"); -__static_yoink("usr/share/terminfo/x/xterm-1005"); -__static_yoink("usr/share/terminfo/x/xterm+pcc0"); -__static_yoink("usr/share/terminfo/x/xterm+osc104"); -__static_yoink("usr/share/terminfo/x/xnuppc-90x30"); -__static_yoink("usr/share/terminfo/x/xterm+256color2"); -__static_yoink("usr/share/terminfo/x/xterm-noapp"); -__static_yoink("usr/share/terminfo/x/xnuppc-80x25-m"); -__static_yoink("usr/share/terminfo/x/xterm+alt47"); -__static_yoink("usr/share/terminfo/x/xterm-256color"); -__static_yoink("usr/share/terminfo/x/xnuppc-128x40"); -__static_yoink("usr/share/terminfo/x/xterm+88color"); -__static_yoink("usr/share/terminfo/x/xerox"); -__static_yoink("usr/share/terminfo/x/xterm-16color"); -__static_yoink("usr/share/terminfo/x/xterm-r5"); -__static_yoink("usr/share/terminfo/x/xterm-mono"); -__static_yoink("usr/share/terminfo/x/xnuppc+128x48"); -__static_yoink("usr/share/terminfo/x/x68k-ite"); -__static_yoink("usr/share/terminfo/x/xnuppc+100x37"); -__static_yoink("usr/share/terminfo/x/xterm-bold"); -__static_yoink("usr/share/terminfo/x/xterm-xf86-v32"); -__static_yoink("usr/share/terminfo/x/xterm+direct256"); -__static_yoink("usr/share/terminfo/x/xnuppc-128x48-m"); -__static_yoink("usr/share/terminfo/x/xnuppc-80x30"); -__static_yoink("usr/share/terminfo/x/xterm+titlestack"); -__static_yoink("usr/share/terminfo/x/xnuppc-128x40-m"); -__static_yoink("usr/share/terminfo/x/xterm+nofkeys"); -__static_yoink("usr/share/terminfo/x/xnuppc-144x48-m"); -__static_yoink("usr/share/terminfo/x/xnuppc-144x48"); -__static_yoink("usr/share/terminfo/x/xterm-pcolor"); -__static_yoink("usr/share/terminfo/x/xnuppc-f2"); -__static_yoink("usr/share/terminfo/x/xterm-x11hilite"); -__static_yoink("usr/share/terminfo/x/xterm+indirect"); -__static_yoink("usr/share/terminfo/x/xnuppc-100x37"); -__static_yoink("usr/share/terminfo/x/xterm+direct2"); -__static_yoink("usr/share/terminfo/x/xterm-utf8"); -__static_yoink("usr/share/terminfo/x/xnuppc+90x30"); -__static_yoink("usr/share/terminfo/x/xterm-color"); -__static_yoink("usr/share/terminfo/x/x10term+sl"); -__static_yoink("usr/share/terminfo/x/xnuppc+80x25"); -__static_yoink("usr/share/terminfo/x/xnuppc-200x64"); -__static_yoink("usr/share/terminfo/x/xterm+meta"); -__static_yoink("usr/share/terminfo/x/xterm-direct"); -__static_yoink("usr/share/terminfo/x/xnuppc-200x64-m"); -__static_yoink("usr/share/terminfo/x/xterm+noalt"); -__static_yoink("usr/share/terminfo/x/xnuppc-90x30-m"); -__static_yoink("usr/share/terminfo/x/xnuppc-200x75-m"); -__static_yoink("usr/share/terminfo/x/xterm+alt1049"); -__static_yoink("usr/share/terminfo/x/xterm-xf86-v43"); -__static_yoink("usr/share/terminfo/x/xterm-p371"); -__static_yoink("usr/share/terminfo/x/xterm-xfree86"); -__static_yoink("usr/share/terminfo/x/xterm-xi"); -__static_yoink("usr/share/terminfo/x/xnuppc+144x48"); -__static_yoink("usr/share/terminfo/x/xnuppc+basic"); -__static_yoink("usr/share/terminfo/x/xnuppc-112x37-m"); -__static_yoink("usr/share/terminfo/x/xnuppc-m-b"); -__static_yoink("usr/share/terminfo/x/xterm+r6f2"); -__static_yoink("usr/share/terminfo/x/xterm+256setaf"); -__static_yoink("usr/share/terminfo/x/xtalk"); -__static_yoink("usr/share/terminfo/x/xterm+sl"); -__static_yoink("usr/share/terminfo/x/x10term"); -__static_yoink("usr/share/terminfo/x/xterm+256color"); -__static_yoink("usr/share/terminfo/x/xterm+vt+edit"); -__static_yoink("usr/share/terminfo/x/x820"); -__static_yoink("usr/share/terminfo/x/xterm-direct256"); -__static_yoink("usr/share/terminfo/x/xnuppc-200x75"); -__static_yoink("usr/share/terminfo/x/xterm+sm+1006"); -__static_yoink("usr/share/terminfo/x/xl83"); -__static_yoink("usr/share/terminfo/x/xterm-xf86-v333"); -__static_yoink("usr/share/terminfo/x/xnuppc-160x64-m"); -__static_yoink("usr/share/terminfo/x/xterm-vt52"); -__static_yoink("usr/share/terminfo/x/xnuppc-112x37"); -__static_yoink("usr/share/terminfo/x/xgterm"); -__static_yoink("usr/share/terminfo/x/xnuppc+80x30"); -__static_yoink("usr/share/terminfo/x/xnuppc-m"); -__static_yoink("usr/share/terminfo/x/xterm+pcc1"); -__static_yoink("usr/share/terminfo/x/xterm-xf86-v40"); -__static_yoink("usr/share/terminfo/x/xenix"); -__static_yoink("usr/share/terminfo/x/xterm+pce2"); -__static_yoink("usr/share/terminfo/x/xnuppc-160x64"); -__static_yoink("usr/share/terminfo/x/xterm-basic"); -__static_yoink("usr/share/terminfo/x/xnuppc-f"); -__static_yoink("usr/share/terminfo/x/xterm-x11mouse"); -__static_yoink("usr/share/terminfo/x/xterm-1002"); -__static_yoink("usr/share/terminfo/x/xdku"); -__static_yoink("usr/share/terminfo/x/xterm+pcf0"); -__static_yoink("usr/share/terminfo/x/xterm.js"); -__static_yoink("usr/share/terminfo/x/xnuppc+f2"); -__static_yoink("usr/share/terminfo/c/cgc3"); -__static_yoink("usr/share/terminfo/c/cit500"); -__static_yoink("usr/share/terminfo/c/cons50-koi8r"); -__static_yoink("usr/share/terminfo/c/concept100-rv"); -__static_yoink("usr/share/terminfo/c/cons50-iso-m"); -__static_yoink("usr/share/terminfo/c/coco3"); -__static_yoink("usr/share/terminfo/c/concept100"); -__static_yoink("usr/share/terminfo/c/cygwin"); -__static_yoink("usr/share/terminfo/c/cons60l1"); -__static_yoink("usr/share/terminfo/c/cit101e-132"); -__static_yoink("usr/share/terminfo/c/cit101e-n132"); -__static_yoink("usr/share/terminfo/c/cad68-3"); -__static_yoink("usr/share/terminfo/c/cons25l1-m"); -__static_yoink("usr/share/terminfo/c/cons50-iso8859"); -__static_yoink("usr/share/terminfo/c/commodore"); -__static_yoink("usr/share/terminfo/c/chromatics"); -__static_yoink("usr/share/terminfo/c/citoh-8lpi"); -__static_yoink("usr/share/terminfo/c/cx100"); -__static_yoink("usr/share/terminfo/c/citoh-comp"); -__static_yoink("usr/share/terminfo/c/cit80"); -__static_yoink("usr/share/terminfo/c/cons25-iso-m"); -__static_yoink("usr/share/terminfo/c/contel321"); -__static_yoink("usr/share/terminfo/c/ct82"); -__static_yoink("usr/share/terminfo/c/cgc2"); -__static_yoink("usr/share/terminfo/c/contel301"); -__static_yoink("usr/share/terminfo/c/cons43-m"); -__static_yoink("usr/share/terminfo/c/cs10"); -__static_yoink("usr/share/terminfo/c/cci1"); -__static_yoink("usr/share/terminfo/c/cops"); -__static_yoink("usr/share/terminfo/c/cons50-koi8r-m"); -__static_yoink("usr/share/terminfo/c/c108-rv"); -__static_yoink("usr/share/terminfo/c/cons60r"); -__static_yoink("usr/share/terminfo/c/coherent"); -__static_yoink("usr/share/terminfo/c/ctrm"); -__static_yoink("usr/share/terminfo/c/cyb110"); -__static_yoink("usr/share/terminfo/c/cygwinB19"); -__static_yoink("usr/share/terminfo/c/cons43"); -__static_yoink("usr/share/terminfo/c/cons60-iso"); -__static_yoink("usr/share/terminfo/c/cons50r-m"); -__static_yoink("usr/share/terminfo/c/cons25-iso8859"); -__static_yoink("usr/share/terminfo/c/cops-10"); -__static_yoink("usr/share/terminfo/c/citoh-elite"); -__static_yoink("usr/share/terminfo/c/cci"); -__static_yoink("usr/share/terminfo/c/cit101e"); -__static_yoink("usr/share/terminfo/c/cops10"); -__static_yoink("usr/share/terminfo/c/cdc756"); -__static_yoink("usr/share/terminfo/c/c100-rv"); -__static_yoink("usr/share/terminfo/c/cons50"); -__static_yoink("usr/share/terminfo/c/cons25-koi8-r"); -__static_yoink("usr/share/terminfo/c/c301"); -__static_yoink("usr/share/terminfo/c/colorscan"); -__static_yoink("usr/share/terminfo/c/cs10-w"); -__static_yoink("usr/share/terminfo/c/crt"); -__static_yoink("usr/share/terminfo/c/concept108"); -__static_yoink("usr/share/terminfo/c/cg7900"); -__static_yoink("usr/share/terminfo/c/crt-vt220"); -__static_yoink("usr/share/terminfo/c/cons30"); -__static_yoink("usr/share/terminfo/c/c100-4p"); -__static_yoink("usr/share/terminfo/c/cx"); -__static_yoink("usr/share/terminfo/c/c300"); -__static_yoink("usr/share/terminfo/c/cdc721"); -__static_yoink("usr/share/terminfo/c/cdc752"); -__static_yoink("usr/share/terminfo/c/cbunix"); -__static_yoink("usr/share/terminfo/c/cons25"); -__static_yoink("usr/share/terminfo/c/c108"); -__static_yoink("usr/share/terminfo/c/contel300"); -__static_yoink("usr/share/terminfo/c/cons50l1"); -__static_yoink("usr/share/terminfo/c/cons25-debian"); -__static_yoink("usr/share/terminfo/c/concept108-8p"); -__static_yoink("usr/share/terminfo/c/cons25r"); -__static_yoink("usr/share/terminfo/c/cdc721-esc"); -__static_yoink("usr/share/terminfo/c/c100-1p"); -__static_yoink("usr/share/terminfo/c/c108-rv-4p"); -__static_yoink("usr/share/terminfo/c/concept108-w-8"); -__static_yoink("usr/share/terminfo/c/concept"); -__static_yoink("usr/share/terminfo/c/c100"); -__static_yoink("usr/share/terminfo/c/cons60r-m"); -__static_yoink("usr/share/terminfo/c/cons25w"); -__static_yoink("usr/share/terminfo/c/concept108rv4p"); -__static_yoink("usr/share/terminfo/c/c108-rv-8p"); -__static_yoink("usr/share/terminfo/c/concept-avt"); -__static_yoink("usr/share/terminfo/c/ca22851"); -__static_yoink("usr/share/terminfo/c/cit-80"); -__static_yoink("usr/share/terminfo/c/c321"); -__static_yoink("usr/share/terminfo/c/cad68-2"); -__static_yoink("usr/share/terminfo/c/cons60-iso-m"); -__static_yoink("usr/share/terminfo/c/cons60"); -__static_yoink("usr/share/terminfo/c/cons60l1-m"); -__static_yoink("usr/share/terminfo/c/cons50l1-m"); -__static_yoink("usr/share/terminfo/c/cons25r-m"); -__static_yoink("usr/share/terminfo/c/cit101e-rv"); -__static_yoink("usr/share/terminfo/c/cons60-koi8r-m"); -__static_yoink("usr/share/terminfo/c/c104"); -__static_yoink("usr/share/terminfo/c/citoh-prop"); -__static_yoink("usr/share/terminfo/c/cit101"); -__static_yoink("usr/share/terminfo/c/cdc721ll"); -__static_yoink("usr/share/terminfo/c/citoh"); -__static_yoink("usr/share/terminfo/c/cons50r"); -__static_yoink("usr/share/terminfo/c/citoh-6lpi"); -__static_yoink("usr/share/terminfo/c/cons25l1"); -__static_yoink("usr/share/terminfo/c/c108-w"); -__static_yoink("usr/share/terminfo/c/c108-8p"); -__static_yoink("usr/share/terminfo/c/cons60-koi8r"); -__static_yoink("usr/share/terminfo/c/c108-4p"); -__static_yoink("usr/share/terminfo/c/ct8500"); -__static_yoink("usr/share/terminfo/c/citoh-ps"); -__static_yoink("usr/share/terminfo/c/cons25-koi8r-m"); -__static_yoink("usr/share/terminfo/c/cons30-m"); -__static_yoink("usr/share/terminfo/c/c108-w-8p"); -__static_yoink("usr/share/terminfo/c/cyb83"); -__static_yoink("usr/share/terminfo/c/cdc456"); -__static_yoink("usr/share/terminfo/c/cons60-m"); -__static_yoink("usr/share/terminfo/c/cbblit"); -__static_yoink("usr/share/terminfo/c/cons50-m"); -__static_yoink("usr/share/terminfo/c/color_xterm"); -__static_yoink("usr/share/terminfo/c/cons25-m"); -__static_yoink("usr/share/terminfo/c/ci8510"); -__static_yoink("usr/share/terminfo/c/citoh-pica"); -__static_yoink("usr/share/terminfo/c/contel320"); -__static_yoink("usr/share/terminfo/c/citc"); -__static_yoink("usr/share/terminfo/c/concept108-4p"); -__static_yoink("usr/share/terminfo/c/cygwinDBG"); -__static_yoink("usr/share/terminfo/c/c100-rv-4p"); -__static_yoink("usr/share/terminfo/c/cit101e-n"); -__static_yoink("usr/share/terminfo/c/concept108-w8p"); -__static_yoink("usr/share/terminfo/u/unknown"); -__static_yoink("usr/share/terminfo/u/ultimaII"); -__static_yoink("usr/share/terminfo/u/uniterm"); -__static_yoink("usr/share/terminfo/u/ultima2"); -__static_yoink("usr/share/terminfo/u/uwin"); -__static_yoink("usr/share/terminfo/u/uts30"); -__static_yoink("usr/share/terminfo/u/uniterm49"); -__static_yoink("usr/share/terminfo/u/unixpc"); -__static_yoink("usr/share/terminfo/z/z-100"); -__static_yoink("usr/share/terminfo/z/z110"); -__static_yoink("usr/share/terminfo/z/zen30"); -__static_yoink("usr/share/terminfo/z/z340-nam"); -__static_yoink("usr/share/terminfo/z/z39-a"); -__static_yoink("usr/share/terminfo/z/z29b"); -__static_yoink("usr/share/terminfo/z/ztx-1-a"); -__static_yoink("usr/share/terminfo/z/zenith39-ansi"); -__static_yoink("usr/share/terminfo/z/z110bw"); -__static_yoink("usr/share/terminfo/z/z100"); -__static_yoink("usr/share/terminfo/z/z19"); -__static_yoink("usr/share/terminfo/z/ztx"); -__static_yoink("usr/share/terminfo/z/z29"); -__static_yoink("usr/share/terminfo/z/z340"); -__static_yoink("usr/share/terminfo/z/z29a-nkc-bc"); -__static_yoink("usr/share/terminfo/z/zen8001"); -__static_yoink("usr/share/terminfo/z/zen50"); -__static_yoink("usr/share/terminfo/z/zenith"); -__static_yoink("usr/share/terminfo/z/z39a"); -__static_yoink("usr/share/terminfo/z/z-100bw"); -__static_yoink("usr/share/terminfo/z/z29a"); -__static_yoink("usr/share/terminfo/z/z100bw"); -__static_yoink("usr/share/terminfo/z/z30"); -__static_yoink("usr/share/terminfo/z/z29a-kc-bc"); -__static_yoink("usr/share/terminfo/z/z29a-nkc-uc"); -__static_yoink("usr/share/terminfo/z/zenith29"); -__static_yoink("usr/share/terminfo/z/z50"); -__static_yoink("usr/share/terminfo/z/zt-1"); -__static_yoink("usr/share/terminfo/z/z29a-kc-uc"); -__static_yoink("usr/share/terminfo/z/zenith39-a"); -__static_yoink("usr/share/terminfo/z/ztx11"); -__static_yoink("usr/share/terminfo/z/z8001"); - /**************************************************************************** * Copyright 2018-2020,2021 Thomas E. Dickey * * Copyright 1998-2016,2017 Free Software Foundation, Inc. *