version 1.9, 2014/04/25 13:38:21 |
version 1.10, 2015/11/05 22:08:44 |
|
|
* |
* |
* For more information, see the README file. |
* For more information, see the README file. |
*/ |
*/ |
|
|
#define NEWBOT 1 |
|
|
|
/* |
/* |
* Standard include file for "less". |
* Modified for use with illumos. |
|
* Copyright 2014 Garrett D'Amore <garrett@damore.org> |
*/ |
*/ |
|
|
/* |
/* |
* Defines for MSDOS_COMPILER. |
* Standard include file for "less". |
*/ |
*/ |
#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. |
* Include the file of compile-time options. |
|
|
*/ |
*/ |
#include <defines.h> |
#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_VOID |
|
#define VOID_POINTER void * |
|
#else |
|
#define VOID_POINTER char * |
|
#define void int |
|
#endif |
|
#if HAVE_CONST |
|
#define constant const |
|
#else |
|
#define constant |
|
#endif |
|
|
|
#define public /* PUBLIC FUNCTION */ |
|
|
|
/* Library function declarations */ |
/* Library function declarations */ |
|
|
#if HAVE_SYS_TYPES_H |
|
#include <sys/types.h> |
#include <sys/types.h> |
#endif |
|
#if HAVE_STDIO_H |
|
#include <stdio.h> |
#include <stdio.h> |
#endif |
|
#if HAVE_FCNTL_H |
|
#include <fcntl.h> |
#include <fcntl.h> |
#endif |
|
#if HAVE_UNISTD_H |
|
#include <unistd.h> |
#include <unistd.h> |
#endif |
|
#if HAVE_CTYPE_H |
|
#include <ctype.h> |
#include <ctype.h> |
#endif |
|
#if HAVE_WCTYPE_H |
|
#include <wctype.h> |
#include <wctype.h> |
#endif |
|
#if HAVE_LIMITS_H |
|
#include <limits.h> |
#include <limits.h> |
#endif |
|
#if HAVE_STDLIB_H |
|
#include <stdlib.h> |
#include <stdlib.h> |
#endif |
|
#if HAVE_STRING_H |
|
#include <string.h> |
#include <string.h> |
#endif |
#include <libgen.h> |
#include <signal.h> |
#include <signal.h> |
|
|
/* OS-specific includes */ |
|
#ifdef _OSK |
|
#include <modes.h> |
|
#include <strings.h> |
|
#endif |
|
|
|
#ifdef __TANDEM |
|
#include <floss.h> |
|
#endif |
|
|
|
#if MSDOS_COMPILER==WIN32C || OS2 |
|
#include <io.h> |
|
#endif |
|
|
|
#if MSDOS_COMPILER==DJGPPC |
|
#include <io.h> |
|
#include <sys/exceptn.h> |
|
#include <conio.h> |
|
#include <pc.h> |
|
#endif |
|
|
|
#if !HAVE_STDLIB_H |
|
char *getenv(); |
|
off_t lseek(); |
|
VOID_POINTER calloc(); |
|
void free(); |
|
#endif |
|
|
|
/* |
/* |
* Simple lowercase test which can be used during option processing |
* Simple lowercase test which can be used during option processing |
* (before options are parsed which might tell us what charset to use). |
* (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_UPPER |
#undef IS_LOWER |
#undef IS_LOWER |
|
|
#undef IS_SPACE |
#undef IS_SPACE |
#undef IS_DIGIT |
#undef IS_DIGIT |
|
|
#if HAVE_WCTYPE |
|
#define IS_UPPER(c) iswupper(c) |
#define IS_UPPER(c) iswupper(c) |
#define IS_LOWER(c) iswlower(c) |
#define IS_LOWER(c) iswlower(c) |
#define TO_UPPER(c) towupper(c) |
#define TO_UPPER(c) towupper(c) |
#define TO_LOWER(c) towlower(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)) |
#define IS_SPACE(c) isspace((unsigned char)(c)) |
#define IS_DIGIT(c) isdigit((unsigned char)(c)) |
#else |
|
#define IS_SPACE(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\r' || (c) == '\f') |
|
#endif |
|
|
|
#ifdef isdigit |
#define IS_CSI_START(c) (((LWCHAR)(c)) == ESC || (((LWCHAR)(c)) == CSI)) |
#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 |
#ifndef TRUE |
#define TRUE 1 |
#define TRUE 1 |
#endif |
#endif |
|
|
#define OPT_ON 1 |
#define OPT_ON 1 |
#define OPT_ONPLUS 2 |
#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) |
#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 |
#ifndef CHAR_BIT |
#define CHAR_BIT 8 |
#define CHAR_BIT 8 |
#endif |
#endif |
|
|
/* |
/* |
|
|
* 302 / 1000 is ceil (log10 (2.0)). Subtract 1 for the sign bit; |
* 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. |
* 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) |
#define INT_STRLEN_BOUND(t) ((sizeof (t) * CHAR_BIT - 1) * 302 / 1000 + 1 + 1) |
|
|
/* |
/* |
* Special types and constants. |
* Special types and constants. |
*/ |
*/ |
typedef unsigned long LWCHAR; |
typedef unsigned long LWCHAR; |
typedef off_t POSITION; |
|
typedef off_t LINENUM; |
typedef off_t LINENUM; |
#define MIN_LINENUM_WIDTH 7 /* Min printing width of a line number */ |
#define MIN_LINENUM_WIDTH 7 /* Min printing width of a line number */ |
#define MAX_UTF_CHAR_LEN 6 /* Max bytes in one UTF-8 char */ |
#define MAX_UTF_CHAR_LEN 6 /* Max bytes in one UTF-8 char */ |
|
|
#define NULL_POSITION ((POSITION)(-1)) |
|
|
|
/* |
/* |
* Flags for open() |
* 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) |
#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) |
#define OPEN_APPEND (O_APPEND|O_WRONLY) |
#else |
|
#ifdef _OSK |
|
#define OPEN_APPEND (S_IWRITE) |
|
#else |
|
#define OPEN_APPEND (1) |
|
#endif |
|
#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 |
#define SHELL_META_QUEST 1 |
#endif |
|
|
|
#define SPACES_IN_FILENAMES 1 |
#define SPACES_IN_FILENAMES 1 |
|
|
/* |
/* |
* An IFILE represents an input file. |
* An IFILE represents an input file. |
*/ |
*/ |
#define IFILE VOID_POINTER |
#define IFILE void * |
#define NULL_IFILE ((IFILE)NULL) |
#define NULL_IFILE (NULL) |
|
|
/* |
/* |
* The structure used to represent a "screen position". |
* The structure used to represent a "screen position". |
|
|
* position is displayed on the ln-th line of the screen. |
* position is displayed on the ln-th line of the screen. |
* (Screen lines before ln are empty.) |
* (Screen lines before ln are empty.) |
*/ |
*/ |
struct scrpos |
struct scrpos { |
{ |
off_t pos; |
POSITION pos; |
|
int ln; |
int ln; |
}; |
}; |
|
|
|
|
#define READ_INTR (-2) |
#define READ_INTR (-2) |
|
|
/* A fraction is represented by an int n; the fraction is n/NUM_FRAC_DENOM */ |
/* A fraction is represented by an int n; the fraction is n/NUM_FRAC_DENOM */ |
#define NUM_FRAC_DENOM 1000000 |
#define NUM_FRAC_DENOM 1000000 |
#define NUM_LOG_FRAC_DENOM 6 |
#define NUM_LOG_FRAC_DENOM 6 |
|
|
/* How quiet should we be? */ |
/* How quiet should we be? */ |
#define NOT_QUIET 0 /* Ring bell at eof and for errors */ |
#define NOT_QUIET 0 /* Ring bell at eof and for errors */ |
|
|
#define BS_CONTROL 2 /* \b treated as control char; prints as ^H */ |
#define BS_CONTROL 2 /* \b treated as control char; prints as ^H */ |
|
|
/* How should we search? */ |
/* How should we search? */ |
#define SRCH_FORW (1 << 0) /* Search forward from current position */ |
#define SRCH_FORW (1 << 0) /* Search forward from current position */ |
#define SRCH_BACK (1 << 1) /* Search backward 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_NO_MOVE (1 << 2) /* Highlight, but don't move */ |
#define SRCH_FIND_ALL (1 << 4) /* Find and highlight all matches */ |
#define SRCH_FIND_ALL (1 << 4) /* Find and highlight all matches */ |
#define SRCH_NO_MATCH (1 << 8) /* Search for non-matching lines */ |
#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_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_FIRST_FILE (1 << 10) /* Search starting at the first file */ |
#define SRCH_NO_REGEX (1 << 12) /* Don't use regular expressions */ |
#define SRCH_NO_REGEX (1 << 12) /* Don't use regular expressions */ |
#define SRCH_FILTER (1 << 13) /* Search is for '&' (filter) command */ |
#define SRCH_FILTER (1 << 13) /* Search is for '&' (filter) command */ |
#define SRCH_AFTER_TARGET (1 << 14) /* Start search after the target line */ |
#define SRCH_AFTER_TARGET (1 << 14) /* Start search after the target line */ |
|
|
#define SRCH_REVERSE(t) (((t) & SRCH_FORW) ? \ |
#define SRCH_REVERSE(t) (((t) & SRCH_FORW) ? \ |
(((t) & ~SRCH_FORW) | SRCH_BACK) : \ |
(((t) & ~SRCH_FORW) | SRCH_BACK) : \ |
|
|
#define CC_ERROR 2 /* Char could not be accepted due to error */ |
#define CC_ERROR 2 /* Char could not be accepted due to error */ |
#define CC_PASS 3 /* Char was rejected (internal) */ |
#define CC_PASS 3 /* Char was rejected (internal) */ |
|
|
#define CF_QUIT_ON_ERASE 0001 /* Abort cmd if its entirely erased */ |
#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 */ |
/* Special char bit-flags used to tell put_line() to do something special */ |
#define AT_NORMAL (0) |
#define AT_NORMAL (0) |
|
|
#define AT_BINARY (1 << 5) /* LESS*BINFMT representation */ |
#define AT_BINARY (1 << 5) /* LESS*BINFMT representation */ |
#define AT_HILITE (1 << 6) /* Internal highlights (e.g., for search) */ |
#define AT_HILITE (1 << 6) /* Internal highlights (e.g., for search) */ |
|
|
#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) |
#define CONTROL(c) ((c)&037) |
#endif /* IS_EBCDIC_HOST */ |
|
|
|
#define ESC CONTROL('[') |
#define ESC CONTROL('[') |
#define CSI ((unsigned char)'\233') |
#define CSI ((unsigned char)'\233') |
|
|
#if _OSK_MWC32 |
#define LSIGNAL(sig, func) lsignal(sig, func) |
#define LSIGNAL(sig,func) os9_signal(sig,func) |
|
#else |
|
#define LSIGNAL(sig,func) lsignal(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_INTERRUPT 01 |
#define S_STOP 02 |
#define S_STOP 02 |
#define S_WINCH 04 |
#define S_WINCH 04 |
#define ABORT_SIGS() (sigs & (S_INTERRUPT|S_STOP)) |
#define ABORT_SIGS() (sigs & (S_INTERRUPT|S_STOP)) |
|
|
#define QUIT_OK 0 |
#define QUIT_OK 0 |
|
|
#define QUIT_INTERRUPT 2 |
#define QUIT_INTERRUPT 2 |
#define QUIT_SAVED_STATUS (-1) |
#define QUIT_SAVED_STATUS (-1) |
|
|
#define FOLLOW_DESC 0 |
#define FOLLOW_DESC 0 |
#define FOLLOW_NAME 1 |
#define FOLLOW_NAME 1 |
|
|
/* filestate flags */ |
/* filestate flags */ |
#define CH_CANSEEK 001 |
#define CH_CANSEEK 001 |
|
|
#define CH_NODATA 020 /* Special case for zero length files */ |
#define CH_NODATA 020 /* Special case for zero length files */ |
|
|
|
|
#define ch_zero() ((POSITION)0) |
#define ch_zero() (0) |
|
|
#define FAKE_HELPFILE "@/\\less/\\help/\\file/\\@" |
#define FAKE_EMPTYFILE "@/\\less/\\empty/\\file/\\@" |
#define FAKE_EMPTYFILE "@/\\less/\\empty/\\file/\\@" |
|
|
|
/* Flags for cvt_text */ |
/* Flags for cvt_text */ |
#define CVT_TO_LC 01 /* Convert upper-case to lower-case */ |
#define CVT_TO_LC 01 /* Convert upper-case to lower-case */ |
|
|
#include "funcs.h" |
#include "funcs.h" |
|
|
/* Functions not included in funcs.h */ |
/* Functions not included in funcs.h */ |
void postoa(); |
void postoa(off_t, char *, size_t); |
void linenumtoa(); |
void linenumtoa(LINENUM, char *, size_t); |
void inttoa(); |
void inttoa(int, char *, size_t); |