1 /* ########################################################### */
2 /* This Software is licensed under the GPL licensed Version 2, */
3 /* please read http://www.gnu.org/copyleft/gpl.html.           */
4 /* ########################################################### */
5 
6 #ifndef SMENU_H
7 #define SMENU_H
8 
9 #define CHARSCHUNK 8
10 #define WORDSCHUNK 8
11 #define COLSCHUNK 16
12 
13 #define TPARM1(p) tparm(p, 0, 0, 0, 0, 0, 0, 0, 0, 0)
14 #define TPARM2(p, q) tparm(p, q, 0, 0, 0, 0, 0, 0, 0, 0)
15 #define TPARM3(p, q, r) tparm(p, q, r, 0, 0, 0, 0, 0, 0, 0)
16 
17 #define _XOPEN_SOURCE 700
18 
19 /* Used for timers management. */
20 /* """"""""""""""""""""""""""" */
21 #define SECOND 1000000
22 #define FREQ 10
23 #define TCK (SECOND / FREQ)
24 
25 /* Bit array management. */
26 /* """"""""""""""""""""" */
27 #define MASK (CHAR_BIT - 1)
28 #define SHIFT ((CHAR_BIT == 8) ? 3 : (CHAR_BIT == 16) ? 4 : 8)
29 
30 #define BIT_OFF(a, x) ((void)((a)[(x) >> SHIFT] &= ~(1 << ((x)&MASK))))
31 #define BIT_ON(a, x) ((void)((a)[(x) >> SHIFT] |= (1 << ((x)&MASK))))
32 #define BIT_FLIP(a, x) ((void)((a)[(x) >> SHIFT] ^= (1 << ((x)&MASK))))
33 #define BIT_ISSET(a, x) ((a)[(x) >> SHIFT] & (1 << ((x)&MASK)))
34 
35 /* ********* */
36 /* Typedefs. */
37 /* ********* */
38 
39 typedef struct charsetinfo_s charsetinfo_t;
40 typedef struct term_s        term_t;
41 typedef struct toggle_s      toggle_t;
42 typedef struct win_s         win_t;
43 typedef struct word_s        word_t;
44 typedef struct attrib_s      attrib_t;
45 typedef struct limit_s       limit_t;
46 typedef struct ticker_s      ticker_t;
47 typedef struct misc_s        misc_t;
48 typedef struct sed_s         sed_t;
49 typedef struct timeout_s     timeout_t;
50 typedef struct output_s      output_t;
51 typedef struct daccess_s     daccess_t;
52 typedef struct search_data_s search_data_t;
53 
54 /* ****** */
55 /* Enums. */
56 /* ****** */
57 
58 /* Various filter pseudo constants. */
59 /* """""""""""""""""""""""""""""""" */
60 typedef enum filter_types
61 {
62   UNKNOWN_FILTER,
63   INCLUDE_FILTER,
64   EXCLUDE_FILTER
65 } filters_t;
66 
67 /* Used by the -N -F and -D options. */
68 /* """"""""""""""""""""""""""""""""" */
69 typedef enum daccess_modes
70 {
71   DA_TYPE_NONE = 0, /* must be 0 (boolean value). */
72   DA_TYPE_AUTO = 1,
73   DA_TYPE_POS  = 2
74 } da_mode_t;
75 
76 /* Various timeout mode used by the -x/-X option. */
77 /* """""""""""""""""""""""""""""""""""""""""""""" */
78 typedef enum timeout_modes
79 {
80   CURRENT, /* on timeout, outputs the selected word.       */
81   QUIT,    /* on timeout, quit without selecting anything. */
82   WORD     /* on timeout , outputs the specified word.     */
83 } to_mode_t;
84 
85 /* Constants used to set the color attributes. */
86 /* """"""""""""""""""""""""""""""""""""""""""" */
87 typedef enum attribute_settings
88 {
89   UNSET = 0, /* must be 0 for future testings. */
90   SET,
91   FORCED /* an attribute setting has been given in the command line. */
92 } attr_set_t;
93 
94 /* Constant to distinguish between the various search modes. */
95 /* """"""""""""""""""""""""""""""""""""""""""""""""""""""""" */
96 typedef enum search_modes
97 {
98   NONE,
99   PREFIX,
100   FUZZY,
101   SUBSTRING
102 } search_mode_t;
103 
104 /* Constants used in search mode to orient the bit-mask building. */
105 /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */
106 typedef enum bitmap_affinities
107 {
108   NO_AFFINITY,
109   END_AFFINITY,
110   START_AFFINITY
111 } bitmap_affinity_t;
112 
113 /* Used when managing the -R option. */
114 /* """"""""""""""""""""""""""""""""" */
115 enum
116 {
117   ROW_REGEX_EXCLUDE = 0, /* must be 0 (boolean value). */
118   ROW_REGEX_INCLUDE = 1
119 };
120 
121 /* Used when managing the -C option. */
122 /* """"""""""""""""""""""""""""""""" */
123 enum
124 {
125   EXCLUDE_MARK      = 0, /* must be 0 because used in various tests      *
126                           | these words cannot be re-included.           */
127   INCLUDE_MARK      = 1, /* to forcibly include a word, these words can  *
128                           | be excluded later.                           */
129   SOFT_EXCLUDE_MARK = 2, /* word with this mark are excluded by default  *
130                           | but can be included later.                   */
131   SOFT_INCLUDE_MARK = 3  /* word with this mark are included by default  *
132                           | but can be excluded later.                   */
133 };
134 
135 /* ******* */
136 /* Structs */
137 /* ******* */
138 
139 /* Used to store the different allowed charsets data. */
140 /* """""""""""""""""""""""""""""""""""""""""""""""""" */
141 struct charsetinfo_s
142 {
143   char * name; /* canonical name of the allowed charset. */
144   int    bits; /* number of bits in this charset.        */
145 };
146 
147 /* Various toggles which can be set with command line options. */
148 /* """"""""""""""""""""""""""""""""""""""""""""""""""""""""""" */
149 struct toggle_s
150 {
151   int del_line;            /* 1 if the clean option is set (-d) else 0.   */
152   int enter_val_in_search; /* 1 if ENTER validates in search mode else 0. */
153   int no_scrollbar;        /* 1 to disable the scrollbar display else 0.  */
154   int blank_nonprintable;  /* 1 to try to display non-blanks in           *
155                             | symbolic form else 0.                       */
156   int keep_spaces;         /* 1 to keep the trailing spaces in columns    *
157                             | and tabulate mode.                          */
158   int taggable;            /* 1 if tagging is enabled.                    */
159   int pinable;             /* 1 if pinning is selected.                   */
160   int autotag;             /* 1 if tagging is selected and pinning is     *
161                             | not and we do no want an automatic tagging  *
162                             | when the users presses <ENTER>.             */
163   int noautotag;           /* 1 if the word under the cursor must not be  *
164                             | autotagged when no other word are tagged.   */
165   int visual_bell;         /* 1 to flash the window, 0 to make a sound.   */
166   int incremental_search;  /* 1 makes the searching process incremental.  *
167                             | 0 keeps it forgetful.                       */
168 };
169 
170 /* Structure to store the default or imposed smenu limits. */
171 /* """"""""""""""""""""""""""""""""""""""""""""""""""""""" */
172 struct limit_s
173 {
174   long word_length; /* maximum number of bytes in a word. */
175   long words;       /* maximum number of words.           */
176   long cols;        /* maximum number of columns.         */
177 };
178 
179 /* Structure to store the default or imposed timers. */
180 /* """"""""""""""""""""""""""""""""""""""""""""""""" */
181 struct ticker_s
182 {
183   int search;
184   int help;
185   int winch;
186   int direct_access;
187 };
188 
189 /* Structure to store miscellaneous informations. */
190 /* """""""""""""""""""""""""""""""""""""""""""""" */
191 struct misc_s
192 {
193   search_mode_t default_search_method;
194   char          invalid_char_substitute;
195   int           ignore_quotes;
196 };
197 
198 /* Terminal setting variables. */
199 /* """"""""""""""""""""""""""" */
200 struct termios new_in_attrs;
201 struct termios old_in_attrs;
202 
203 /* Interval timers used. */
204 /* """"""""""""""""""""" */
205 struct itimerval periodic_itv; /* refresh rate for the timeout counter. */
206 
207 int help_timer    = -1;
208 int winch_timer   = -1;
209 int daccess_timer = -1;
210 int search_timer  = -1;
211 
212 /* Structure containing the attributes components. */
213 /* """"""""""""""""""""""""""""""""""""""""""""""" */
214 struct attrib_s
215 {
216   attr_set_t  is_set;
217   short       fg;
218   short       bg;
219   signed char bold;
220   signed char dim;
221   signed char reverse;
222   signed char standout;
223   signed char underline;
224   signed char italic;
225   signed char blink;
226 };
227 
228 /* Structure containing some terminal characteristics. */
229 /* """"""""""""""""""""""""""""""""""""""""""""""""""" */
230 struct term_s
231 {
232   int   ncolumns;     /* number of columns.                      */
233   int   nlines;       /* number of lines.                        */
234   int   curs_column;  /* current cursor column.                  */
235   int   curs_line;    /* current cursor line.                    */
236   short colors;       /* number of available colors.             */
237   short color_method; /* color method (0=classic (0-7), 1=ANSI). */
238 
239   char has_cursor_up;         /* has cuu1 terminfo capability.           */
240   char has_cursor_down;       /* has cud1 terminfo capability.           */
241   char has_cursor_left;       /* has cub1 terminfo capability.           */
242   char has_cursor_right;      /* has cuf1 terminfo capability.           */
243   char has_parm_right_cursor; /* has cuf terminfo capability.            */
244   char has_cursor_address;    /* has cup terminfo capability.            */
245   char has_save_cursor;       /* has sc terminfo capability.             */
246   char has_restore_cursor;    /* has rc terminfo capability.             */
247   char has_setf;              /* has set_foreground terminfo capability. */
248   char has_setb;              /* has set_background terminfo capability. */
249   char has_setaf;             /* idem for set_a_foreground (ANSI).       */
250   char has_setab;             /* idem for set_a_background (ANSI).       */
251   char has_hpa;               /* has column_address terminfo capability. */
252   char has_bold;              /* has bold mode.                          */
253   char has_dim;               /* has dim mode.                           */
254   char has_reverse;           /* has reverse mode.                       */
255   char has_underline;         /* has underline mode.                     */
256   char has_standout;          /* has standout mode.                      */
257   char has_italic;            /* has italic mode.                        */
258   char has_blink;             /* has blink mode.                         */
259 };
260 
261 /* Structure describing a word. */
262 /* """""""""""""""""""""""""""" */
263 struct word_s
264 {
265   long          start, end;    /* start/end absolute horiz. word positions *
266                                 | on the screen.                           */
267   size_t        mb;            /* number of UTF-8 glyphs to display.       */
268   long          tag_order;     /* each time a word is tagged, this value.  *
269                                 | is increased.                            */
270   size_t        special_level; /* can vary from 0 to 9; 0 meaning normal.  */
271   char *        str;           /* display string associated with this word */
272   size_t        len;           /* number of bytes of str (for trimming).   */
273   char *        orig;          /* NULL or original string if is had been.  *
274                                 | shortened for being displayed or altered *
275                                 | by is expansion.                         */
276   char *        bitmap;        /* used to store the position of the.       *
277                                 | currently searched chars in a word. The  *
278                                 | objective is to speed their display.     */
279   unsigned char is_matching;   /* word is matching a search ERE.           */
280   unsigned char is_tagged;     /* 1 if the word is tagged, 0 if not.       */
281   unsigned char is_last;       /* 1 if the word is the last of a line.     */
282   unsigned char is_selectable; /* word is selectable.                      */
283   unsigned char is_numbered;   /* word has a direct access index.          */
284 };
285 
286 /* Structure describing the window in which the user  */
287 /* will be able to select a word.                     */
288 /* """""""""""""""""""""""""""""""""""""""""""""""""" */
289 struct win_s
290 {
291   long    start, end;      /* index of the first and last word.        */
292   long    first_column;    /* number of the first character displayed. */
293   long    cur_line;        /* relative number of the cursor line (1+). */
294   long    asked_max_lines; /* requested number of lines in the window. */
295   long    max_lines;       /* effective number of lines in the window. */
296   long    max_cols;        /* max number of words in a single line.    */
297   long    real_max_width;  /* max line length. In column, tab or line  *
298                             | mode it can be greater than the          *
299                             | terminal width.                          */
300   long    message_lines;   /* number of lines taken by the messages    *
301                             | (updated by disp_message.                */
302   long    max_width;       /* max usable line width or the terminal.   */
303   long    offset;          /* window offset user when centered.        */
304   char *  sel_sep;         /* output separator when tags are enabled.  */
305   char ** gutter_a;        /* array of UTF-8 gutter glyphs.            */
306   long    gutter_nb;       /* number of UTF-8 gutter glyphs.           */
307 
308   unsigned char tab_mode;  /* -t */
309   unsigned char col_mode;  /* -c */
310   unsigned char line_mode; /* -l */
311   unsigned char col_sep;   /* -g */
312   unsigned char wide;      /* -w */
313   unsigned char center;    /* -M */
314 
315   attrib_t cursor_attr;           /* current cursor attributes.          */
316   attrib_t cursor_on_tag_attr;    /* current cursor on tag attributes.   */
317   attrib_t bar_attr;              /* scrollbar attributes.               */
318   attrib_t shift_attr;            /* shift indicator attributes.         */
319   attrib_t message_attr;          /* message (title) attributes.         */
320   attrib_t search_field_attr;     /* search mode field attributes.       */
321   attrib_t search_text_attr;      /* search mode text attributes.        */
322   attrib_t search_err_field_attr; /* bad search mode field attributes.   */
323   attrib_t search_err_text_attr;  /* bad search mode text attributes.    */
324   attrib_t match_field_attr;      /* matching word field attributes.     */
325   attrib_t match_text_attr;       /* matching word text attributes.      */
326   attrib_t match_err_field_attr;  /* bad matching word field attributes. */
327   attrib_t match_err_text_attr;   /* bad matching word text attributes.  */
328   attrib_t include_attr;          /* selectable words attributes.        */
329   attrib_t exclude_attr;          /* non-selectable words attributes.    */
330   attrib_t tag_attr;              /* non-selectable words attributes.    */
331   attrib_t daccess_attr;          /* direct access tag attributes.       */
332   attrib_t special_attr[9];       /* special (-1,...) words attributes.  */
333 };
334 
335 /* Sed like node structure. */
336 /* """""""""""""""""""""""" */
337 struct sed_s
338 {
339   char *        pattern;      /* pattern to be matched.                    */
340   char *        substitution; /* substitution string.                      */
341   unsigned char visual;       /* visual flag: alterations are only visual. */
342   unsigned char global;       /* global flag: alterations can occur more   *
343                                | than once.                                */
344   unsigned char stop;         /* stop flag:   only one alteration per word *
345                                | is allowed.                               */
346   regex_t       re;           /* compiled regular expression.              */
347 };
348 
349 /* Structure used to keep track of the different timeout values. */
350 /* """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */
351 struct timeout_s
352 {
353   to_mode_t mode;          /* timeout mode: current/quit/word. */
354   unsigned  initial_value; /* 0: no timeout else value in sec. */
355   unsigned  remain;        /* remaining seconds.               */
356   unsigned  reached;       /* 1: timeout has expired, else 0.  */
357 };
358 
359 /* Structure used during the construction of the pinned words list. */
360 /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */
361 struct output_s
362 {
363   long   order;      /* this field is incremented each time a word is *
364                       | pinned.                                       */
365   char * output_str; /* The pinned word itself.                       */
366 };
367 
368 /* Structure describing the formatting of the automatic */
369 /* direct access entries.                               */
370 /* """""""""""""""""""""""""""""""""""""""""""""""""""" */
371 struct daccess_s
372 {
373   da_mode_t mode;       /* DA_TYPE_NONE (0), DA_TYPE_AUTO, DA_TYPE_POS.    */
374   char *    left;       /* character to put before the direct access       *
375                          | selector.                                       */
376   char *    right;      /* character to put after the direct access        *
377                          | selector.                                       */
378   char      alignment;  /* l: left; r: right.                              */
379   char      padding;    /* a: all; i: only included words are padded.      */
380   char      head;       /* What to do with chars before the embedded       *
381                          | number.                                         */
382   int       length;     /* selector size (5 max).                          */
383   int       flength;    /* 0 or length + 3 (full prefix length.            */
384   size_t    offset;     /* offset to the start of the selector.            */
385   char      missing;    /* y: number missing embedded numbers.             */
386   int       plus;       /* 1 if we can look for the number to extract      *
387                          | after the offset, else 0. (a '+' follows the    *
388                          | offset).                                        */
389   int       size;       /* size in bytes of the selector to extract.       */
390   size_t    ignore;     /* number of UTF-8 glyphs to ignore after the      *
391                          | number.                                         */
392   char      follow;     /* y: the numbering follows the last number set.   */
393   char *    num_sep;    /* character to separate number and selection.     */
394   int       def_number; /* 1: the numbering is on by default 0: it is not. */
395 };
396 
397 /* Structure used in search mod to store the current buffer and various   */
398 /* related values.                                                        */
399 /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */
400 struct search_data_s
401 {
402   char * buf;        /* search buffer.                            */
403   long   len;        /* current position in the search buffer.    */
404   long   utf8_len;   /* current position in the search buffer in  *
405                       | UTF-8 units.                              */
406   long * utf8_off_a; /* array of mb offsets in buf.               */
407   long * utf8_len_a; /* array of mb lengths in buf.               */
408 
409   int  fuzzy_err;     /* fuzzy match error indicator.             */
410   long fuzzy_err_pos; /* last good position in search buffer.     */
411 
412   int only_ending;   /* only searches giving a result with the.   *
413                       | pattern at the end of the word will be    *
414                       | selected.                                 */
415   int only_starting; /* same with the pattern at the beginning.   */
416 };
417 
418 /* *********** */
419 /* Prototypes. */
420 /* *********** */
421 
422 void
423 help(win_t * win, term_t * term, long last_line, toggle_t * toggles);
424 
425 int
426 tag_comp(void * a, void * b);
427 
428 void
429 tag_swap(void * a, void * b);
430 
431 int
432 isempty(const char * s);
433 
434 void
435 my_beep(toggle_t * toggles);
436 
437 int
438 get_cursor_position(int * const r, int * const c);
439 
440 void
441 get_terminal_size(int * const r, int * const c, term_t * term);
442 
443 int
444 #ifdef __sun
445 outch(char c);
446 #else
447 outch(int c);
448 #endif
449 
450 void
451 restore_term(int const fd);
452 
453 void
454 setup_term(int const fd);
455 
456 void
457 strip_ansi_color(char * s, toggle_t * toggles, misc_t * misc);
458 
459 int
460 tst_cb(void * elem);
461 
462 int
463 tst_cb_cli(void * elem);
464 
465 int
466 ini_load(const char * filename, win_t * win, term_t * term, limit_t * limits,
467          ticker_t * timers, misc_t * misc, langinfo_t * langinfo,
468          int (*report)(win_t * win, term_t * term, limit_t * limits,
469                        ticker_t * timers, misc_t * misc, langinfo_t * langinfo,
470                        const char * section, const char * name, char * value));
471 
472 int
473 ini_cb(win_t * win, term_t * term, limit_t * limits, ticker_t * timers,
474        misc_t * misc, langinfo_t * langinfo, const char * section,
475        const char * name, char * value);
476 
477 char *
478 make_ini_path(char * name, char * base);
479 
480 short
481 color_transcode(short color);
482 
483 void
484 set_foreground_color(term_t * term, short color);
485 
486 void
487 set_background_color(term_t * term, short color);
488 
489 void
490 set_win_start_end(win_t * win, long current, long last);
491 
492 long
493 build_metadata(term_t * term, long count, win_t * win);
494 
495 long
496 disp_lines(win_t * win, toggle_t * toggles, long current, long count,
497            search_mode_t search_mode, search_data_t * search_data,
498            term_t * term, long last_line, char * tmp_word,
499            langinfo_t * langinfo);
500 
501 void
502 get_message_lines(char * message, ll_t * message_lines_list,
503                   long * message_max_width, long * message_max_len);
504 
505 void
506 disp_message(ll_t * message_lines_list, long width, long max_len, term_t * term,
507              win_t * win, langinfo_t * langinfo);
508 
509 int
510 check_integer_constraint(int nb_args, char ** args, char * value, char * par);
511 
512 void
513 update_bitmaps(search_mode_t search_mode, search_data_t * search_data,
514                bitmap_affinity_t affinity);
515 
516 long
517 find_next_matching_word(long * array, long nb, long value, long * index);
518 
519 long
520 find_prev_matching_word(long * array, long nb, long value, long * index);
521 
522 void
523 clean_matches(search_data_t * search_data, long size);
524 
525 void
526 disp_cursor_word(long pos, win_t * win, term_t * term, int err);
527 
528 void
529 disp_matching_word(long pos, win_t * win, term_t * term, int is_cursor,
530                    int err);
531 
532 void
533 disp_word(long pos, search_mode_t search_mode, search_data_t * search_data,
534           term_t * term, win_t * win, char * tmp_word);
535 
536 size_t
537 expand(char * src, char * dest, langinfo_t * langinfo, toggle_t * toggles,
538        misc_t * misc);
539 
540 int
541 get_bytes(FILE * input, char * utf8_buffer, ll_t * ignored_glyphs_list,
542           langinfo_t * langinfo, misc_t * misc);
543 
544 int
545 get_scancode(unsigned char * s, size_t max);
546 
547 char *
548 get_word(FILE * input, ll_t * word_delims_list, ll_t * record_delims_list,
549          ll_t * ignored_glyphs_list, char * utf8_buffer,
550          unsigned char * is_last, toggle_t * toggles, langinfo_t * langinfo,
551          win_t * win, limit_t * limits, misc_t * misc);
552 
553 void
554 left_margin_putp(char * s, term_t * term, win_t * win);
555 
556 void
557 right_margin_putp(char * s1, char * s2, langinfo_t * langinfo, term_t * term,
558                   win_t * win, long line, long offset);
559 
560 void
561 sig_handler(int s);
562 
563 void
564 set_new_first_column(win_t * win, term_t * term);
565 
566 int
567 parse_sed_like_string(sed_t * sed);
568 
569 void
570 parse_selectors(char * str, filters_t * filter, char * unparsed,
571                 ll_t ** inc_interval_list, ll_t ** inc_regex_list,
572                 ll_t ** exc_interval_list, ll_t ** exc_regex_list,
573                 langinfo_t * langinfo, misc_t * misc);
574 
575 int
576 replace(char * orig, sed_t * sed);
577 
578 int
579 decode_attr_toggles(char * s, attrib_t * attr);
580 
581 int
582 parse_attr(char * str, attrib_t * attr, short max_color);
583 
584 void
585 apply_attr(term_t * term, attrib_t attr);
586 
587 int
588 delims_cmp(const void * a, const void * b);
589 
590 long
591 get_line_last_word(long line, long last_line);
592 
593 void
594 move_left(win_t * win, term_t * term, toggle_t * toggles,
595           search_data_t * search_data, langinfo_t * langinfo, long * nl,
596           long last_line, char * tmp_word);
597 
598 void
599 move_right(win_t * win, term_t * term, toggle_t * toggles,
600            search_data_t * search_data, langinfo_t * langinfo, long * nl,
601            long last_line, char * tmp_word);
602 
603 int
604 find_best_word_upward(long last_word, long s, long e);
605 
606 int
607 find_best_word_downward(long last_word, long s, long e);
608 
609 void
610 move_up(win_t * win, term_t * term, toggle_t * toggles,
611         search_data_t * search_data, langinfo_t * langinfo, long * nl,
612         long page, long first_selectable, long last_line, char * tmp_word);
613 
614 void
615 move_down(win_t * win, term_t * term, toggle_t * toggles,
616           search_data_t * search_data, langinfo_t * langinfo, long * nl,
617           long page, long last_selectable, long last_line, char * tmp_word);
618 
619 void
620 init_main_ds(attrib_t * init_attr, win_t * win, limit_t * limits,
621              ticker_t * timers, toggle_t * toggles, misc_t * misc,
622              timeout_t * timeout, daccess_t * daccess);
623 
624 void
625 reset_search_buffer(win_t * win, search_data_t * search_data, ticker_t * timers,
626                     toggle_t * toggles, term_t * term, daccess_t * daccess,
627                     langinfo_t * langinfo, long last_line, char * tmp_word,
628                     long word_real_max_size);
629 #endif
630