xref: /freebsd/contrib/less/less.h (revision 911f0260390e18cf85f3dbf2c719b593efdc1e3c)
1 /*
2  * Copyright (C) 1984-2023  Mark Nudelman
3  *
4  * You may distribute under the terms of either the GNU General Public
5  * License or the Less License, as specified in the README file.
6  *
7  * For more information, see the README file.
8  */
9 
10 #define NEWBOT 1
11 
12 /*
13  * Standard include file for "less".
14  */
15 
16 /*
17  * Defines for MSDOS_COMPILER.
18  */
19 #define MSOFTC          1   /* Microsoft C */
20 #define BORLANDC        2   /* Borland C */
21 #define WIN32C          3   /* Windows (Borland C or Microsoft C) */
22 #define DJGPPC          4   /* DJGPP C */
23 
24 /*
25  * Include the file of compile-time options.
26  * The <> make cc search for it in -I., not srcdir.
27  */
28 #include <defines.h>
29 
30 #ifdef _SEQUENT_
31 /*
32  * Kludge for Sequent Dynix systems that have sigsetmask, but
33  * it's not compatible with the way less calls it.
34  * {{ Do other systems need this? }}
35  */
36 #undef HAVE_SIGSETMASK
37 #endif
38 
39 /*
40  * Language details.
41  */
42 #if HAVE_CONST
43 #define constant        const
44 #else
45 #define constant
46 #endif
47 
48 #define public          /* PUBLIC FUNCTION */
49 
50 /* Library function declarations */
51 
52 #if HAVE_SYS_TYPES_H
53 #include <sys/types.h>
54 #endif
55 #if HAVE_STDIO_H
56 #include <stdio.h>
57 #endif
58 #if HAVE_FCNTL_H
59 #include <fcntl.h>
60 #endif
61 #if HAVE_UNISTD_H
62 #include <unistd.h>
63 #endif
64 #if HAVE_CTYPE_H
65 #include <ctype.h>
66 #endif
67 #if HAVE_WCTYPE_H
68 #include <wctype.h>
69 #endif
70 #if HAVE_LIMITS_H
71 #include <limits.h>
72 #endif
73 #if HAVE_STDINT_H
74 #include <stdint.h>
75 #endif
76 #if HAVE_STDLIB_H
77 #include <stdlib.h>
78 #endif
79 #if HAVE_STRING_H
80 #include <string.h>
81 #endif
82 
83 #if HAVE_STDCKDINT_H
84 #include <stdckdint.h>
85 #else
86 /*
87  * These substitutes for C23 stdckdint macros do not set *R on overflow,
88  * and they assume A and B are nonnegative.  That is good enough for us.
89  */
90 #define ckd_add(r, a, b) help_ckd_add(r, a, b, sizeof *(r), signed_expr(*(r)))
91 #define ckd_mul(r, a, b) help_ckd_mul(r, a, b, sizeof *(r), signed_expr(*(r)))
92 /* True if the integer expression E, after promotion, is signed.  */
93 #define signed_expr(e) ((TRUE ? 0 : e) - 1 < 0)
94 #endif
95 
96 #if defined UINTMAX_MAX
97 typedef uintmax_t uintmax;
98 #elif defined ULLONG_MAX
99 typedef unsigned long long uintmax;
100 #else
101 typedef unsigned long uintmax;
102 #endif
103 
104 /* OS-specific includes */
105 #ifdef _OSK
106 #include <modes.h>
107 #include <strings.h>
108 #endif
109 
110 #ifdef __TANDEM
111 #include <floss.h>
112 #endif
113 
114 #if MSDOS_COMPILER==WIN32C || OS2
115 #include <io.h>
116 #endif
117 
118 #if MSDOS_COMPILER==DJGPPC
119 #include <io.h>
120 #include <sys/exceptn.h>
121 #include <conio.h>
122 #include <pc.h>
123 #endif
124 
125 #if !HAVE_STDLIB_H
126 char *getenv();
127 off_t lseek();
128 void *calloc();
129 void free();
130 #endif
131 
132 /*
133  * Simple lowercase test which can be used during option processing
134  * (before options are parsed which might tell us what charset to use).
135  */
136 #define ASCII_IS_UPPER(c)       ((c) >= 'A' && (c) <= 'Z')
137 #define ASCII_IS_LOWER(c)       ((c) >= 'a' && (c) <= 'z')
138 #define ASCII_TO_UPPER(c)       ((c) - 'a' + 'A')
139 #define ASCII_TO_LOWER(c)       ((c) - 'A' + 'a')
140 
141 #undef IS_UPPER
142 #undef IS_LOWER
143 #undef TO_UPPER
144 #undef TO_LOWER
145 #undef IS_SPACE
146 #undef IS_DIGIT
147 
148 #if HAVE_WCTYPE
149 #define IS_UPPER(c)     iswupper(c)
150 #define IS_LOWER(c)     iswlower(c)
151 #define TO_UPPER(c)     towupper(c)
152 #define TO_LOWER(c)     towlower(c)
153 #else
154 #if HAVE_UPPER_LOWER
155 #define IS_UPPER(c)     isupper((unsigned char) (c))
156 #define IS_LOWER(c)     islower((unsigned char) (c))
157 #define TO_UPPER(c)     toupper((unsigned char) (c))
158 #define TO_LOWER(c)     tolower((unsigned char) (c))
159 #else
160 #define IS_UPPER(c)     ASCII_IS_UPPER(c)
161 #define IS_LOWER(c)     ASCII_IS_LOWER(c)
162 #define TO_UPPER(c)     ASCII_TO_UPPER(c)
163 #define TO_LOWER(c)     ASCII_TO_LOWER(c)
164 #endif
165 #endif
166 
167 #ifdef isspace
168 #define IS_SPACE(c)     isspace((unsigned char)(c))
169 #else
170 #define IS_SPACE(c)     ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\r' || (c) == '\f')
171 #endif
172 
173 #ifdef isdigit
174 #define IS_DIGIT(c)     isdigit((unsigned char)(c))
175 #else
176 #define IS_DIGIT(c)     ((c) >= '0' && (c) <= '9')
177 #endif
178 
179 #define IS_CSI_START(c) (((LWCHAR)(c)) == ESC || (((LWCHAR)(c)) == CSI))
180 
181 #ifndef NULL
182 #define NULL    0
183 #endif
184 
185 #ifndef TRUE
186 #define TRUE            1
187 #endif
188 #ifndef FALSE
189 #define FALSE           0
190 #endif
191 
192 #define OPT_OFF         0
193 #define OPT_ON          1
194 #define OPT_ONPLUS      2
195 
196 #if !HAVE_MEMCPY
197 #ifndef memcpy
198 #define memcpy(to,from,len)     bcopy((from),(to),(len))
199 #endif
200 #endif
201 
202 #if HAVE_SNPRINTF
203 #define SNPRINTF1(str, size, fmt, v1)             snprintf((str), (size), (fmt), (v1))
204 #define SNPRINTF2(str, size, fmt, v1, v2)         snprintf((str), (size), (fmt), (v1), (v2))
205 #define SNPRINTF3(str, size, fmt, v1, v2, v3)     snprintf((str), (size), (fmt), (v1), (v2), (v3))
206 #define SNPRINTF4(str, size, fmt, v1, v2, v3, v4) snprintf((str), (size), (fmt), (v1), (v2), (v3), (v4))
207 #else
208 /* Use unsafe sprintf if we don't have snprintf. */
209 #define SNPRINTF1(str, size, fmt, v1)             sprintf((str), (fmt), (v1))
210 #define SNPRINTF2(str, size, fmt, v1, v2)         sprintf((str), (fmt), (v1), (v2))
211 #define SNPRINTF3(str, size, fmt, v1, v2, v3)     sprintf((str), (fmt), (v1), (v2), (v3))
212 #define SNPRINTF4(str, size, fmt, v1, v2, v3, v4) sprintf((str), (fmt), (v1), (v2), (v3), (v4))
213 #endif
214 
215 #define BAD_LSEEK       ((off_t)-1)
216 
217 #ifndef SEEK_SET
218 #define SEEK_SET 0
219 #endif
220 #ifndef SEEK_END
221 #define SEEK_END 2
222 #endif
223 
224 #ifndef CHAR_BIT
225 #define CHAR_BIT 8
226 #endif
227 
228 /*
229  * Upper bound on the string length of an integer converted to string.
230  * 302 / 1000 is ceil (log10 (2.0)).  Subtract 1 for the sign bit;
231  * add 1 for integer division truncation; add 1 more for a minus sign.
232  */
233 #define INT_STRLEN_BOUND(t) ((sizeof(t) * CHAR_BIT - 1) * 302 / 1000 + 1 + 1)
234 
235 /*
236  * Special types and constants.
237  */
238 typedef unsigned long LWCHAR;
239 typedef off_t           POSITION;
240 typedef off_t           LINENUM;
241 #define MIN_LINENUM_WIDTH   7   /* Default min printing width of a line number */
242 #define MAX_LINENUM_WIDTH   16  /* Max width of a line number */
243 #define MAX_STATUSCOL_WIDTH 4   /* Max width of the status column */
244 #define MAX_UTF_CHAR_LEN    6   /* Max bytes in one UTF-8 char */
245 #define MAX_PRCHAR_LEN      31  /* Max chars in prchar() result */
246 
247 #define NULL_POSITION   ((POSITION)(-1))
248 
249 /*
250  * Flags for open()
251  */
252 #if MSDOS_COMPILER || OS2
253 #define OPEN_READ       (O_RDONLY|O_BINARY)
254 #else
255 #ifdef _OSK
256 #define OPEN_READ       (S_IREAD)
257 #else
258 #ifdef O_RDONLY
259 #define OPEN_READ       (O_RDONLY)
260 #else
261 #define OPEN_READ       (0)
262 #endif
263 #endif
264 #endif
265 
266 #if defined(O_WRONLY) && defined(O_APPEND)
267 #define OPEN_APPEND     (O_APPEND|O_WRONLY)
268 #else
269 #ifdef _OSK
270 #define OPEN_APPEND     (S_IWRITE)
271 #else
272 #define OPEN_APPEND     (1)
273 #endif
274 #endif
275 
276 /*
277  * Set a file descriptor to binary mode.
278  */
279 #if MSDOS_COMPILER==MSOFTC
280 #define SET_BINARY(f)   _setmode(f, _O_BINARY);
281 #else
282 #if MSDOS_COMPILER || OS2
283 #define SET_BINARY(f)   setmode(f, O_BINARY)
284 #else
285 #define SET_BINARY(f)
286 #endif
287 #endif
288 
289 /*
290  * Does the shell treat "?" as a metacharacter?
291  */
292 #if MSDOS_COMPILER || OS2 || _OSK
293 #define SHELL_META_QUEST 0
294 #else
295 #define SHELL_META_QUEST 1
296 #endif
297 
298 #define SPACES_IN_FILENAMES 1
299 
300 /*
301  * An IFILE represents an input file.
302  */
303 #define IFILE           void*
304 #define NULL_IFILE      ((IFILE)NULL)
305 
306 /*
307  * The structure used to represent a "screen position".
308  * This consists of a file position, and a screen line number.
309  * The meaning is that the line starting at the given file
310  * position is displayed on the ln-th line of the screen.
311  * (Screen lines before ln are empty.)
312  */
313 struct scrpos
314 {
315         POSITION pos;
316         int ln;
317 };
318 
319 typedef union parg
320 {
321         char *p_string;
322         int p_int;
323         LINENUM p_linenum;
324         char p_char;
325 } PARG;
326 
327 #define NULL_PARG       ((PARG *)NULL)
328 
329 struct textlist
330 {
331         char *string;
332         char *endstring;
333 };
334 
335 struct wchar_range
336 {
337         LWCHAR first, last;
338 };
339 
340 struct wchar_range_table
341 {
342         struct wchar_range *table;
343         int count;
344 };
345 
346 #if HAVE_POLL
347 typedef short POLL_EVENTS;
348 #endif
349 
350 #define EOI             (-1)
351 
352 #define READ_ERR        (-1)
353 #define READ_INTR       (-2)
354 #define READ_AGAIN      (-3)
355 
356 /*
357  * A fraction is represented by a long n; the fraction is n/NUM_FRAC_DENOM.
358  * To avoid overflow problems, 0 <= n < NUM_FRAC_DENUM <= LONG_MAX/100.
359  */
360 #define NUM_FRAC_DENOM                  1000000
361 #define NUM_LOG_FRAC_DENOM              6
362 
363 /* How quiet should we be? */
364 #define NOT_QUIET       0       /* Ring bell at eof and for errors */
365 #define LITTLE_QUIET    1       /* Ring bell only for errors */
366 #define VERY_QUIET      2       /* Never ring bell */
367 
368 /* How should we prompt? */
369 #define PR_SHORT        0       /* Prompt with colon */
370 #define PR_MEDIUM       1       /* Prompt with message */
371 #define PR_LONG         2       /* Prompt with longer message */
372 
373 /* How should we handle backspaces? */
374 #define BS_SPECIAL      0       /* Do special things for underlining and bold */
375 #define BS_NORMAL       1       /* \b treated as normal char; actually output */
376 #define BS_CONTROL      2       /* \b treated as control char; prints as ^H */
377 
378 /* How should we search? */
379 #define SRCH_FORW       (1 << 0)  /* Search forward from current position */
380 #define SRCH_BACK       (1 << 1)  /* Search backward from current position */
381 #define SRCH_NO_MOVE    (1 << 2)  /* Highlight, but don't move */
382 #define SRCH_INCR       (1 << 3)  /* Incremental search */
383 #define SRCH_FIND_ALL   (1 << 4)  /* Find and highlight all matches */
384 #define SRCH_NO_MATCH   (1 << 8)  /* Search for non-matching lines */
385 #define SRCH_PAST_EOF   (1 << 9)  /* Search past end-of-file, into next file */
386 #define SRCH_FIRST_FILE (1 << 10) /* Search starting at the first file */
387 #define SRCH_NO_REGEX   (1 << 12) /* Don't use regular expressions */
388 #define SRCH_FILTER     (1 << 13) /* Search is for '&' (filter) command */
389 #define SRCH_AFTER_TARGET (1 << 14) /* Start search after the target line */
390 #define SRCH_WRAP       (1 << 15) /* Wrap-around search (continue at BOF/EOF) */
391 #define SRCH_SUBSEARCH(i) (1 << (16+(i))) /* Search for subpattern */
392 /* {{ Depends on NUM_SEARCH_COLORS==5 }} */
393 #define SRCH_SUBSEARCH_ALL (SRCH_SUBSEARCH(1)|SRCH_SUBSEARCH(2)|SRCH_SUBSEARCH(3)|SRCH_SUBSEARCH(4)|SRCH_SUBSEARCH(5))
394 
395 #define SRCH_REVERSE(t) (((t) & SRCH_FORW) ? \
396                                 (((t) & ~SRCH_FORW) | SRCH_BACK) : \
397                                 (((t) & ~SRCH_BACK) | SRCH_FORW))
398 
399 /* */
400 #define NO_MCA          0
401 #define MCA_DONE        1
402 #define MCA_MORE        2
403 
404 #define CC_OK           0       /* Char was accepted & processed */
405 #define CC_QUIT         1       /* Char was a request to abort current cmd */
406 #define CC_ERROR        2       /* Char could not be accepted due to error */
407 #define CC_PASS         3       /* Char was rejected (internal) */
408 
409 #define CF_QUIT_ON_ERASE 0001   /* Abort cmd if its entirely erased */
410 
411 /* Special char bit-flags used to tell put_line() to do something special */
412 #define AT_NORMAL       (0)
413 #define AT_UNDERLINE    (1 << 0)
414 #define AT_BOLD         (1 << 1)
415 #define AT_BLINK        (1 << 2)
416 #define AT_STANDOUT     (1 << 3)
417 #define AT_ANSI         (1 << 4)  /* Content-supplied "ANSI" escape sequence */
418 #define AT_BINARY       (1 << 5)  /* LESS*BINFMT representation */
419 #define AT_HILITE       (1 << 6)  /* Internal highlights (e.g., for search) */
420 
421 #define AT_COLOR_SHIFT    8
422 #define AT_NUM_COLORS     16
423 #define AT_COLOR          ((AT_NUM_COLORS-1) << AT_COLOR_SHIFT)
424 #define AT_COLOR_ATTN     (1 << AT_COLOR_SHIFT)
425 #define AT_COLOR_BIN      (2 << AT_COLOR_SHIFT)
426 #define AT_COLOR_CTRL     (3 << AT_COLOR_SHIFT)
427 #define AT_COLOR_ERROR    (4 << AT_COLOR_SHIFT)
428 #define AT_COLOR_LINENUM  (5 << AT_COLOR_SHIFT)
429 #define AT_COLOR_MARK     (6 << AT_COLOR_SHIFT)
430 #define AT_COLOR_PROMPT   (7 << AT_COLOR_SHIFT)
431 #define AT_COLOR_RSCROLL  (8 << AT_COLOR_SHIFT)
432 #define AT_COLOR_HEADER   (9 << AT_COLOR_SHIFT)
433 #define AT_COLOR_SEARCH   (10 << AT_COLOR_SHIFT)
434 #define AT_COLOR_SUBSEARCH(i) ((10+(i)) << AT_COLOR_SHIFT)
435 #define NUM_SEARCH_COLORS (AT_NUM_COLORS-10-1)
436 
437 typedef enum { CT_NULL, CT_4BIT, CT_6BIT } COLOR_TYPE;
438 
439 typedef enum {
440 	CV_BLUE     = 1,
441 	CV_GREEN    = 2,
442 	CV_RED      = 4,
443 	CV_BRIGHT   = 8,
444 	CV_NOCHANGE = -2,
445 	CV_ERROR    = -1
446 } COLOR_VALUE;
447 
448 /* ANSI states */
449 #define ANSI_MID    1
450 #define ANSI_ERR    2
451 #define ANSI_END    3
452 
453 #if '0' == 240
454 #define IS_EBCDIC_HOST 1
455 #endif
456 
457 #if IS_EBCDIC_HOST
458 /*
459  * Long definition for EBCDIC.
460  * Since the argument is usually a constant, this macro normally compiles
461  * into a constant.
462  */
463 #define CONTROL(c) ( \
464         (c)=='[' ? '\047' : \
465         (c)=='a' ? '\001' : \
466         (c)=='b' ? '\002' : \
467         (c)=='c' ? '\003' : \
468         (c)=='d' ? '\067' : \
469         (c)=='e' ? '\055' : \
470         (c)=='f' ? '\056' : \
471         (c)=='g' ? '\057' : \
472         (c)=='h' ? '\026' : \
473         (c)=='i' ? '\005' : \
474         (c)=='j' ? '\025' : \
475         (c)=='k' ? '\013' : \
476         (c)=='l' ? '\014' : \
477         (c)=='m' ? '\015' : \
478         (c)=='n' ? '\016' : \
479         (c)=='o' ? '\017' : \
480         (c)=='p' ? '\020' : \
481         (c)=='q' ? '\021' : \
482         (c)=='r' ? '\022' : \
483         (c)=='s' ? '\023' : \
484         (c)=='t' ? '\074' : \
485         (c)=='u' ? '\075' : \
486         (c)=='v' ? '\062' : \
487         (c)=='w' ? '\046' : \
488         (c)=='x' ? '\030' : \
489         (c)=='y' ? '\031' : \
490         (c)=='z' ? '\077' : \
491         (c)=='A' ? '\001' : \
492         (c)=='B' ? '\002' : \
493         (c)=='C' ? '\003' : \
494         (c)=='D' ? '\067' : \
495         (c)=='E' ? '\055' : \
496         (c)=='F' ? '\056' : \
497         (c)=='G' ? '\057' : \
498         (c)=='H' ? '\026' : \
499         (c)=='I' ? '\005' : \
500         (c)=='J' ? '\025' : \
501         (c)=='K' ? '\013' : \
502         (c)=='L' ? '\014' : \
503         (c)=='M' ? '\015' : \
504         (c)=='N' ? '\016' : \
505         (c)=='O' ? '\017' : \
506         (c)=='P' ? '\020' : \
507         (c)=='Q' ? '\021' : \
508         (c)=='R' ? '\022' : \
509         (c)=='S' ? '\023' : \
510         (c)=='T' ? '\074' : \
511         (c)=='U' ? '\075' : \
512         (c)=='V' ? '\062' : \
513         (c)=='W' ? '\046' : \
514         (c)=='X' ? '\030' : \
515         (c)=='Y' ? '\031' : \
516         (c)=='Z' ? '\077' : \
517         (c)=='|' ? '\031' : \
518         (c)=='\\' ? '\034' : \
519         (c)=='^' ? '\036' : \
520         (c)&077)
521 #else
522 #define CONTROL(c)      ((c)&037)
523 #endif /* IS_EBCDIC_HOST */
524 
525 #define ESC             CONTROL('[')
526 #define ESCS            "\33"
527 #define CSI             ((unsigned char)'\233')
528 #define CHAR_END_COMMAND 0x40000000
529 
530 #if _OSK_MWC32
531 #define LSIGNAL(sig,func)       os9_signal(sig,func)
532 #else
533 #define LSIGNAL(sig,func)       signal(sig,func)
534 #endif
535 
536 #if HAVE_SIGPROCMASK
537 #if HAVE_SIGSET_T
538 #else
539 #undef HAVE_SIGPROCMASK
540 #endif
541 #endif
542 #if HAVE_SIGPROCMASK
543 #if HAVE_SIGEMPTYSET
544 #else
545 #undef  sigemptyset
546 #define sigemptyset(mp) *(mp) = 0
547 #endif
548 #endif
549 
550 #define S_INTERRUPT     01
551 #define S_STOP          02
552 #define S_WINCH         04
553 #define ABORT_SIGS()    (sigs & (S_INTERRUPT|S_STOP))
554 
555 #ifdef EXIT_SUCCESS
556 #define QUIT_OK         EXIT_SUCCESS
557 #else
558 #define QUIT_OK         0
559 #endif
560 #ifdef EXIT_FAILURE
561 #define QUIT_ERROR      EXIT_FAILURE
562 #define QUIT_INTERRUPT  (EXIT_FAILURE+1)
563 #else
564 #define QUIT_ERROR      1
565 #define QUIT_INTERRUPT  2
566 #endif
567 #define QUIT_SAVED_STATUS (-1)
568 
569 #define FOLLOW_DESC     0
570 #define FOLLOW_NAME     1
571 
572 /* filestate flags */
573 #define CH_CANSEEK      001
574 #define CH_KEEPOPEN     002
575 #define CH_POPENED      004
576 #define CH_HELPFILE     010
577 #define CH_NODATA       020     /* Special case for zero length files */
578 
579 #define ch_zero()       ((POSITION)0)
580 
581 #define FAKE_HELPFILE   "@/\\less/\\help/\\file/\\@"
582 #define FAKE_EMPTYFILE  "@/\\less/\\empty/\\file/\\@"
583 
584 /* Flags for cvt_text */
585 #define CVT_TO_LC       01      /* Convert upper-case to lower-case */
586 #define CVT_BS          02      /* Do backspace processing */
587 #define CVT_CRLF        04      /* Remove CR after LF */
588 #define CVT_ANSI        010     /* Remove ANSI escape sequences */
589 
590 #if HAVE_TIME_T
591 #define time_type       time_t
592 #else
593 #define time_type       long
594 #endif
595 
596 /* X11 mouse reporting definitions */
597 #define X11MOUSE_BUTTON1    0 /* Left button press */
598 #define X11MOUSE_BUTTON2    1 /* Middle button press */
599 #define X11MOUSE_BUTTON3    2 /* Right button press */
600 #define X11MOUSE_BUTTON_REL 3 /* Button release */
601 #define X11MOUSE_WHEEL_UP   0x40 /* Wheel scroll up */
602 #define X11MOUSE_WHEEL_DOWN 0x41 /* Wheel scroll down */
603 #define X11MOUSE_OFFSET     0x20 /* Added to button & pos bytes to create a char */
604 
605 #if LESSTEST
606 #define LESS_DUMP_CHAR CONTROL(']')
607 #endif
608 
609 struct mlist;
610 struct loption;
611 struct hilite_tree;
612 struct ansi_state;
613 #include "pattern.h"
614 #include "xbuf.h"
615 #include "funcs.h"
616 
617 /* Functions not included in funcs.h */
618 void postoa(POSITION, char*, int);
619 void linenumtoa(LINENUM, char*, int);
620 void inttoa(int, char*, int);
621 int lstrtoi(char*, char**, int);
622 POSITION lstrtopos(char*, char**, int);
623 unsigned long lstrtoul(char*, char**, int);
624 #if MSDOS_COMPILER==WIN32C
625 int pclose(FILE*);
626 #endif
627