1 /* ################################################################### */
2 /* Copyright 2015, Pierre Gentile (p.gen.progs@gmail.com) */
4 /* This Source Code Form is subject to the terms of the Mozilla Public */
5 /* License, v. 2.0. If a copy of the MPL was not distributed with this */
6 /* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
7 /* ################################################################### */
16 #define TPARM1(p) tparm(p, 0, 0, 0, 0, 0, 0, 0, 0, 0)
17 #define TPARM2(p, q) tparm(p, q, 0, 0, 0, 0, 0, 0, 0, 0)
18 #define TPARM3(p, q, r) tparm(p, q, r, 0, 0, 0, 0, 0, 0, 0)
20 #define _XOPEN_SOURCE 700
22 /* Used for timers management. */
23 /* """"""""""""""""""""""""""" */
24 #define SECOND 1000000
26 #define TCK (SECOND / FREQ)
28 /* Large bit array management written by */
29 /* Scott Dudley, Auke Reitsma and Bob Stout. */
30 /* Assumes CHAR_BIT is one of either 8, 16, or 32. */
32 /* """"""""""""""""""""""""""""""""""""""""""""""" */
33 #define MASK (CHAR_BIT - 1)
34 #define SHIFT ((CHAR_BIT == 8) ? 3 : (CHAR_BIT == 16) ? 4 : 8)
36 #define BIT_OFF(a, x) ((void)((a)[(x) >> SHIFT] &= ~(1 << ((x) & MASK))))
37 #define BIT_ON(a, x) ((void)((a)[(x) >> SHIFT] |= (1 << ((x) & MASK))))
38 #define BIT_FLIP(a, x) ((void)((a)[(x) >> SHIFT] ^= (1 << ((x) & MASK))))
39 #define BIT_ISSET(a, x) ((a)[(x) >> SHIFT] & (1 << ((x) & MASK)))
45 typedef struct charsetinfo_s charsetinfo_t
;
46 typedef struct term_s term_t
;
47 typedef struct toggle_s toggle_t
;
48 typedef struct win_s win_t
;
49 typedef struct word_s word_t
;
50 typedef struct attrib_s attrib_t
;
51 typedef struct limit_s limit_t
;
52 typedef struct ticker_s ticker_t
;
53 typedef struct misc_s misc_t
;
54 typedef struct mouse_s mouse_t
;
55 typedef struct sed_s sed_t
;
56 typedef struct timeout_s timeout_t
;
57 typedef struct output_s output_t
;
58 typedef struct daccess_s daccess_t
;
59 typedef struct search_data_s search_data_t
;
60 typedef struct attr_elem_s attr_elem_t
;
66 /* Various filter pseudo constants. */
67 /* """""""""""""""""""""""""""""""" */
68 typedef enum filter_types
75 /* Types of selectors. */
76 /* """"""""""""""""""" */
77 typedef enum selector_types
81 ALEFT
, /* Alignment to the left. */
82 ARIGHT
, /* Alignment to the right. */
83 ACENTER
, /* Alignment to the center. */
87 /* Used by the -N -F and -D options. */
88 /* """"""""""""""""""""""""""""""""" */
89 typedef enum daccess_modes
91 DA_TYPE_NONE
= 0, /* must be 0 (boolean value). */
96 /* Various timeout mode used by the -x/-X option. */
97 /* """""""""""""""""""""""""""""""""""""""""""""" */
98 typedef enum timeout_modes
100 CURRENT
, /* on timeout, outputs the selected word. */
101 QUIT
, /* on timeout, quit without selecting anything. */
102 WORD
/* on timeout , outputs the specified word. */
105 /* Constants used to set the color attributes. */
106 /* """"""""""""""""""""""""""""""""""""""""""" */
107 typedef enum attribute_settings
109 UNSET
= 0, /* must be 0 for future testings. */
111 FORCED
/* an attribute setting has been given in the command line. */
114 /* Method used to interpret the color numbers. */
115 /* """"""""""""""""""""""""""""""""""""""""""" */
116 typedef enum color_method
122 /* Constant to distinguish between the various search modes. */
123 /* """"""""""""""""""""""""""""""""""""""""""""""""""""""""" */
124 typedef enum search_modes
132 /* Constants used in search mode to orient the bit-mask building. */
133 /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */
134 typedef enum bitmap_affinities
141 typedef enum alignment
149 /* Used when managing the -C option. */
150 /* """"""""""""""""""""""""""""""""" */
153 EXCLUDE_MARK
= 0, /* must be 0 because used in various tests *
154 | these words cannot be re-included. */
155 INCLUDE_MARK
= 1, /* to forcibly include a word, these words can *
156 | be excluded later. */
157 SOFT_EXCLUDE_MARK
= 2, /* word with this mark are excluded by default *
158 | but can be included later. */
159 SOFT_INCLUDE_MARK
= 3 /* word with this mark are included by default *
160 | but can be excluded later. */
163 /* Mouse protocols. */
164 /* """""""""""""""" */
167 MOUSE1000
, /* VT200 */
168 MOUSE1006
, /* SGR_EXT_MODE */
169 MOUSE1015
/* URXVT_EXT_MODE */
176 /* Used to store the different allowed charsets data. */
177 /* """""""""""""""""""""""""""""""""""""""""""""""""" */
180 char *name
; /* canonical name of the allowed charset. */
181 int bits
; /* number of bits in this charset. */
184 /* Various toggles which can be set with command line options. */
185 /* """"""""""""""""""""""""""""""""""""""""""""""""""""""""""" */
188 int del_line
; /* 1 if the clean option is set (-d) else 0. */
189 int enter_val_in_search
; /* 1 if ENTER validates in search mode else 0. */
190 int no_scrollbar
; /* 1 to disable the scrollbar display else 0. */
191 int no_hor_scrollbar
; /* 1 to disable the horizontab scrollbar *
193 int blank_nonprintable
; /* 1 to try to display non-blanks in *
194 | symbolic form else 0. */
195 int keep_spaces
; /* 1 to keep the trailing spaces in columns *
196 | and tabulate mode. */
197 int taggable
; /* 1 if tagging is enabled. */
198 int pinable
; /* 1 if pinning is selected. */
199 int autotag
; /* 1 if tagging is selected and pinning is *
200 | not and we do no want an automatic tagging *
201 | when the users presses <ENTER>. */
202 int noautotag
; /* 1 if the word under the cursor must not be *
203 | autotagged when no other word are tagged. */
204 int visual_bell
; /* 1 to flash the window, 0 to make a sound. */
205 int incremental_search
; /* 1 makes the searching process incremental. *
206 | 0 keeps it forgetful. */
207 int no_mouse
; /* 1 to disable the possibly auto-detected *
208 | mouse, 0 to let smenu auto-detect it. */
209 int show_blank_words
; /* 1 if blank words are allowed then they will *
210 | be filled by an underscore, 0 to leave them *
212 int cols_first
; /* 1 if column alignment has priority over *
213 | row alignment else 0. */
214 int rows_first
; /* 1 if row alignment has priority over *
215 | column alignment else 0. */
218 /* Structure to store the default or imposed smenu limits. */
219 /* """"""""""""""""""""""""""""""""""""""""""""""""""""""" */
222 long word_length
; /* maximum number of bytes in a word. */
223 long words
; /* maximum number of words. */
224 long cols
; /* maximum number of columns. */
227 /* Structure to store the default or imposed timers. */
228 /* """"""""""""""""""""""""""""""""""""""""""""""""" */
238 /* Structure to store miscellaneous information. */
239 /* """"""""""""""""""""""""""""""""""""""""""""" */
242 search_mode_t default_search_method
;
243 char invalid_char_substitute
;
244 char blank_char_substitute
;
248 /* Structure to store mouse information. */
249 /* """"""""""""""""""""""""""""""""""""" */
252 int double_click_delay
;
256 /* Structure containing the attributes components. */
257 /* """"""""""""""""""""""""""""""""""""""""""""""" */
266 signed char standout
;
267 signed char underline
;
273 /* Structure containing some terminal characteristics. */
274 /* """"""""""""""""""""""""""""""""""""""""""""""""""" */
277 int ncolumns
; /* number of columns. */
278 int nlines
; /* number of lines. */
279 int curs_column
; /* current cursor column. */
280 int curs_line
; /* current cursor line. */
281 short colors
; /* number of available colors. */
282 color_method_t color_method
; /* color method (CLASSIC (0-7), ANSI). */
284 char has_cursor_up
; /* has cuu1 terminfo capability. */
285 char has_cursor_down
; /* has cud1 terminfo capability. */
286 char has_cursor_left
; /* has cub1 terminfo capability. */
287 char has_cursor_right
; /* has cuf1 terminfo capability. */
288 char has_parm_right_cursor
; /* has cuf terminfo capability. */
289 char has_cursor_address
; /* has cup terminfo capability. */
290 char has_save_cursor
; /* has sc terminfo capability. */
291 char has_restore_cursor
; /* has rc terminfo capability. */
292 char has_setf
; /* has set_foreground terminfo capability. */
293 char has_setb
; /* has set_background terminfo capability. */
294 char has_setaf
; /* idem for set_a_foreground (ANSI). */
295 char has_setab
; /* idem for set_a_background (ANSI). */
296 char has_hpa
; /* has column_address terminfo capability. */
297 char has_bold
; /* has bold mode. */
298 char has_dim
; /* has dim mode. */
299 char has_reverse
; /* has reverse mode. */
300 char has_underline
; /* has underline mode. */
301 char has_standout
; /* has standout mode. */
302 char has_italic
; /* has italic mode. */
303 char has_invis
; /* has invis mode. */
304 char has_blink
; /* has blink mode. */
305 char has_kmous
; /* has mouse reporting. */
306 char has_rep
; /* has repeact char. */
309 /* Structure describing a word. */
310 /* """""""""""""""""""""""""""" */
313 long start
, end
; /* start/end absolute horiz. word positions *
315 size_t mb
; /* number of UTF-8 glyphs to display. */
316 long tag_order
; /* each time a word is tagged, this value. *
318 unsigned short tag_id
; /* tag id. 0 means no tag. */
319 unsigned char special_level
; /* can vary from 0 to 9; 0 meaning normal. */
320 char *str
; /* display string associated with this word */
321 size_t len
; /* number of bytes of str (for trimming). */
322 char *orig
; /* NULL or original string if is had been. *
323 | shortened for being displayed or altered *
324 | by is expansion. */
325 char *bitmap
; /* used to store the position of the. *
326 | currently searched chars in a word. The *
327 | objective is to speed their display. */
328 unsigned char is_matching
; /* word is matching a search ERE. */
329 unsigned char is_last
; /* 1 if the word is the last of a line. */
330 unsigned char is_selectable
; /* word is selectable. */
331 unsigned char is_numbered
; /* word has a direct access index. */
332 attrib_t
*iattr
; /* Specific attribute set with the -Ra/-Ca *
336 /* Structure describing the window in which the user */
337 /* will be able to select a word. */
338 /* """""""""""""""""""""""""""""""""""""""""""""""""" */
341 long start
, end
; /* index of the first and last word. */
342 int first_column
; /* number of the first character displayed. */
343 int cur_line
; /* relative number of the cursor line (1+). */
344 int asked_max_lines
; /* requested number of lines in the window. */
345 int has_hbar
; /* 1 if an horizontal bar must be *
346 | displayed else 0. */
347 int hbar_displayed
; /* 1 if an hozizontal bas has ever been *
348 | displayed else 0. */
349 int max_lines
; /* effective number of lines in the window. */
350 int max_cols
; /* max number of words in a single line. */
351 int real_max_width
; /* max line length. In column, tab or line *
352 | mode it can be greater than the *
354 int message_lines
; /* number of lines taken by the messages *
355 | (updated by disp_message. */
356 int max_width
; /* max usable line width or the terminal. */
357 int offset
; /* Left margin, used in centered mode. */
358 char *sel_sep
; /* output separator when tags are enabled. */
359 char **gutter_a
; /* array of UTF-8 gutter glyphs. */
360 int gutter_nb
; /* number of UTF-8 gutter glyphs. */
361 int sb_column
; /* scroll bar column (-1) if no scroll bar. */
362 unsigned next_tag_id
; /* Next tag ID, increased on each tagging *
365 unsigned char tab_mode
; /* -t */
366 unsigned char col_mode
; /* -c */
367 unsigned char line_mode
; /* -l */
368 unsigned char col_sep
; /* -g */
369 unsigned char wide
; /* -w */
370 unsigned char center
; /* -M */
372 unsigned char has_truncated_lines
; /* 1 if win has tr. lines else 0. */
374 attrib_t cursor_attr
; /* current cursor attributes. */
375 attrib_t cursor_marked_attr
; /* current cursor when a mark is set. */
376 attrib_t cursor_on_marked_attr
; /* current cursor on marked word *
378 attrib_t cursor_on_tag_attr
; /* current cursor on tag attributes. */
379 attrib_t cursor_on_tag_marked_attr
; /* current cursor on tag attributes *
380 | if current word is marked. */
381 attrib_t marked_attr
; /* marked word. */
382 attrib_t bar_attr
; /* scrollbar attributes. */
383 attrib_t shift_attr
; /* shift indicator attributes. */
384 attrib_t message_attr
; /* message (title) attributes. */
385 attrib_t search_field_attr
; /* search mode field attributes. */
386 attrib_t search_text_attr
; /* search mode text attributes. */
387 attrib_t search_err_field_attr
; /* bad search mode field attributes. */
388 attrib_t search_err_text_attr
; /* bad search mode text attributes. */
389 attrib_t match_field_attr
; /* matching word field attributes. */
390 attrib_t match_text_attr
; /* matching word text attributes. */
391 attrib_t match_err_field_attr
; /* bad matching word field attributes. */
392 attrib_t match_err_text_attr
; /* bad matching word text attributes. */
393 attrib_t include_attr
; /* selectable words attributes. */
394 attrib_t exclude_attr
; /* non-selectable words attributes. */
395 attrib_t tag_attr
; /* non-selectable words attributes. */
396 attrib_t daccess_attr
; /* direct access tag attributes. */
397 attrib_t special_attr
[9]; /* special (-1,...) words attributes. */
400 /* Sed like node structure. */
401 /* """""""""""""""""""""""" */
404 char *pattern
; /* pattern to be matched. */
405 char *substitution
; /* substitution string. */
406 unsigned char visual
; /* visual flag: alterations are only visual. */
407 unsigned char global
; /* global flag: alterations can occur more *
409 unsigned char stop
; /* stop flag: only one alteration per word *
411 regex_t re
; /* compiled regular expression. */
414 /* Structure used to keep track of the different timeout values. */
415 /* """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */
418 to_mode_t mode
; /* timeout mode: current/quit/word. */
419 unsigned initial_value
; /* 0: no timeout else value in sec. */
420 unsigned remain
; /* remaining seconds. */
421 unsigned reached
; /* 1: timeout has expired, else 0. */
424 /* Structure used during the construction of the pinned words list. */
425 /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */
428 long order
; /* this field is incremented each time a word is *
430 char *output_str
; /* The pinned word itself. */
433 /* Structure describing the formatting of the automatic */
434 /* direct access entries. */
435 /* """""""""""""""""""""""""""""""""""""""""""""""""""" */
438 da_mode_t mode
; /* DA_TYPE_NONE (0), DA_TYPE_AUTO, DA_TYPE_POS. */
439 char *left
; /* character to put before the direct access *
441 char *right
; /* character to put after the direct access *
443 char alignment
; /* l: left; r: right. */
444 char padding
; /* a: all; i: only included words are padded. */
445 char head
; /* What to do with chars before the embedded *
447 int length
; /* selector size (5 max). */
448 int flength
; /* 0 or length + 3 (full prefix length. */
449 size_t offset
; /* offset to the start of the selector. */
450 char missing
; /* y: number missing embedded numbers. */
451 int plus
; /* 1 if we can look for the number to extract *
452 | after the offset, else 0. (a '+' follows the *
454 int size
; /* size in bytes of the selector to extract. */
455 size_t ignore
; /* number of UTF-8 glyphs to ignore after the *
457 char follow
; /* y: the numbering follows the last number set. */
458 char *num_sep
; /* character to separate number and selection. */
459 int def_number
; /* 1: the numbering is on by default 0: it is not. */
462 /* Structure used in search mod to store the current buffer and various */
463 /* related values. */
464 /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */
467 char *buf
; /* search buffer. */
468 long len
; /* current position in the search buffer. */
469 long utf8_len
; /* current position in the search buffer in *
471 long *utf8_off_a
; /* array of mb offsets in buf. */
472 long *utf8_len_a
; /* array of mb lengths in buf. */
474 int err
; /* match error indicator. */
475 long fuzzy_err_pos
; /* last good position in search buffer. */
477 int only_ending
; /* only searches giving a result with the. *
478 | pattern at the end of the word will be *
480 int only_starting
; /* same with the pattern at the beginning. */
483 /* Structure used to store an attribute and the list of elements */
484 /* (columns, rows or RE) for which this attribute must be the default */
486 /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */
489 attrib_t
*attr
; /* Attribute */
490 ll_t
*list
; /* list of RE or intervals of columns. */
498 help(win_t
*win
, term_t
*term
, long last_line
);
501 tag_comp(void const *a
, void const *b
);
504 tag_swap(void **a
, void **b
);
507 isempty(const char *s
);
510 my_beep(toggle_t
*toggles
);
513 get_cursor_position(int * const r
, int * const c
);
516 get_terminal_size(int * const r
, int * const c
, term_t
*term
);
526 restore_term(int const fd
, struct termios
*old
);
529 setup_term(int const fd
, struct termios
*old
, struct termios
*new);
532 strip_ansi_color(char *s
, toggle_t
*toggles
, misc_t
*misc
);
538 tst_cb_cli(void *elem
);
541 ini_load(const char *filename
,
548 int (*report
)(win_t
*win
,
570 make_ini_path(char *name
, char *base
);
573 color_transcode(short color
);
576 set_foreground_color(term_t
*term
, short color
);
579 set_background_color(term_t
*term
, short color
);
582 set_win_start_end(win_t
*win
, long current
, long last
);
585 build_metadata(term_t
*term
, long count
, win_t
*win
);
588 disp_lines(win_t
*win
,
592 search_mode_t search_mode
,
593 search_data_t
*search_data
,
597 langinfo_t
*langinfo
);
600 get_message_lines(char *message
,
601 ll_t
*message_lines_list
,
602 long *message_max_width
,
603 long *message_max_len
);
606 disp_message(ll_t
*message_lines_list
,
611 langinfo_t
*langinfo
);
614 check_integer_constraint(int nb_args
, char **args
, char *value
, char *par
);
617 update_bitmaps(search_mode_t search_mode
,
618 search_data_t
*search_data
,
619 bitmap_affinity_t affinity
);
622 find_next_matching_word(long *array
, long nb
, long value
, long *index
);
625 find_prev_matching_word(long *array
, long nb
, long value
, long *index
);
628 clean_matches(search_data_t
*search_data
, long size
);
631 disp_cursor_word(long pos
, win_t
*win
, term_t
*term
, int err
);
634 disp_matching_word(long pos
, win_t
*win
, term_t
*term
, int is_cursor
, int err
);
638 search_mode_t search_mode
,
639 search_data_t
*search_data
,
648 langinfo_t
*langinfo
,
653 read_bytes(FILE *input
,
655 ll_t
*ignored_glyphs_list
,
656 langinfo_t
*langinfo
,
660 get_scancode(unsigned char *s
, size_t max
);
663 read_word(FILE *input
,
664 ll_t
*word_delims_list
,
665 ll_t
*line_delims_list
,
666 ll_t
*ignored_glyphs_list
,
668 unsigned char *is_last
,
670 langinfo_t
*langinfo
,
676 left_margin_putp(char *s
, term_t
*term
, win_t
*win
);
679 right_margin_putp(char *s1
,
681 langinfo_t
*langinfo
,
691 set_new_first_column(win_t
*win
, term_t
*term
);
694 parse_sed_like_string(sed_t
*sed
);
697 parse_selectors(char *str
,
700 ll_t
**inc_interval_list
,
701 ll_t
**inc_regex_list
,
702 ll_t
**exc_interval_list
,
703 ll_t
**exc_regex_list
,
704 ll_t
**al_interval_list
,
705 ll_t
**al_regex_list
,
706 ll_t
**ar_interval_list
,
707 ll_t
**ar_regex_list
,
708 ll_t
**ac_interval_list
,
709 ll_t
**ac_regex_list
,
710 ll_t
**at_interval_list
,
711 ll_t
**at_regex_list
,
712 alignment_t
*al_default
,
718 parse_al_selectors(char *str
,
720 ll_t
**al_regex_list
,
721 ll_t
**ar_regex_list
,
722 ll_t
**ac_regex_list
,
723 alignment_t
*default_alignment
,
726 replace(char *orig
, sed_t
*sed
);
729 decode_attr_toggles(char *s
, attrib_t
*attr
);
732 parse_attr(char *str
, attrib_t
*attr
, short max_color
);
735 apply_attr(term_t
*term
, attrib_t attr
);
738 get_line_last_word(long line
, long last_line
);
741 move_left(win_t
*win
,
744 search_data_t
*search_data
,
745 langinfo_t
*langinfo
,
751 move_right(win_t
*win
,
754 search_data_t
*search_data
,
755 langinfo_t
*langinfo
,
761 find_best_word_upwards(long last_word
, long s
, long e
);
764 find_best_word_downwards(long last_word
, long s
, long e
);
770 search_data_t
*search_data
,
771 langinfo_t
*langinfo
,
774 long first_selectable
,
779 move_down(win_t
*win
,
782 search_data_t
*search_data
,
783 langinfo_t
*langinfo
,
786 long last_selectable
,
791 init_main_ds(attrib_t
*init_attr
,
802 reset_search_buffer(win_t
*win
,
803 search_data_t
*search_data
,
808 langinfo_t
*langinfo
,
811 long word_real_max_size
);
813 is_in_foreground_process_group(void);
817 get_clicked_index(win_t
*win
,
824 align_word(word_t
*word
, alignment_t alignment
, size_t prerfix
, char sp
);
827 isempty_non_utf8(const unsigned char *s
);
830 isempty_utf8(const unsigned char *s
);