summaryrefslogtreecommitdiffstats
path: root/smenu.c
diff options
context:
space:
mode:
Diffstat (limited to 'smenu.c')
-rw-r--r--smenu.c3761
1 files changed, 2523 insertions, 1238 deletions
diff --git a/smenu.c b/smenu.c
index d0a3f2a..1d5ff2f 100644
--- a/smenu.c
+++ b/smenu.c
@@ -25,6 +25,8 @@
#if defined(__sun) && defined(__SVR4)
#include <stdbool.h>
#endif
+#include <limits.h>
+#include <stdarg.h>
#include <signal.h>
#include <ctype.h>
#include <string.h>
@@ -59,174 +61,249 @@ typedef struct txt_attr_s txt_attr_t;
typedef struct limits_s limits_t;
typedef struct sed_s sed_t;
typedef struct interval_s interval_t;
+typedef struct timeout_s timeout_t;
/* ********** */
/* Prototypes */
/* ********** */
-static void help(win_t * win, term_t * term, int last_line, toggle_t * toggle);
-static void short_usage(void);
-static void usage(void);
+static void
+help(win_t * win, term_t * term, int last_line, toggle_t * toggle);
+
+static void
+short_usage(void);
+
+static void
+usage(void);
-static void * xmalloc(size_t size);
-static void * xcalloc(size_t num, size_t size);
-static void * xrealloc(void * ptr, size_t size);
+static void *
+xmalloc(size_t size);
-static interval_t * interval_new(void);
-static int interval_comp(void * a, void * b);
-static void interval_swap(void * a, void * b);
+static void *
+xcalloc(size_t num, size_t size);
+
+static void *
+xrealloc(void * ptr, size_t size);
+
+static interval_t *
+interval_new(void);
+
+static int
+interval_comp(void * a, void * b);
+
+static void
+interval_swap(void * a, void * b);
+
+static int
+ll_append(ll_t * const list, void * const data);
-static int ll_append(ll_t * const list, void * const data);
#if 0 /* here for coherency but not used. */
static int ll_prepend(ll_t * const list, void *const data);
-static void ll_insert_before(ll_t * const list, ll_node_t * node,
- void *const data);
-static void ll_insert_after(ll_t * const list, ll_node_t * node,
- void *const data);
+
+static void
+ll_insert_before(ll_t * const list, ll_node_t * node, void *const data);
+
+static void
+ll_insert_after(ll_t * const list, ll_node_t * node, void *const data);
#endif
-static ll_node_t * ll_partition(ll_node_t * l, ll_node_t * h,
- int (*comp)(void *, void *),
- void (*swap)(void *, void *));
-static void ll_quicksort(ll_node_t * l, ll_node_t * h,
- int (*comp)(void *, void *),
- void (*swap)(void * a, void *));
-static void ll_sort(ll_t * list, int (*comp)(void *, void *),
- void (*swap)(void * a, void *));
-static int ll_delete(ll_t * const list, ll_node_t * node);
-static ll_node_t * ll_find(ll_t * const, void * const,
- int (*)(const void *, const void *));
-static void ll_init(ll_t * list);
-static ll_node_t * ll_new_node(void);
-static ll_t * ll_new(void);
-
-static void ltrim(char * str, const char * trim);
-static void rtrim(char * str, const char * trim, size_t min_len);
-static int my_stricmp(const char * str1, const char * str2);
-
-static int isprint7(int i);
-static int isprint8(int i);
-
-static int count_leading_set_bits(unsigned char c);
-static int get_cursor_position(int * const r, int * const c);
-static void get_terminal_size(int * const r, int * const c);
-static char * mb_strprefix(char * d, char * s, int n, int * pos);
-static int mb_strlen(char * str);
-static wchar_t * mb_strtowcs(char * s);
-static int validate_mb(const char * str, int length);
-static int outch(int c);
-static void restore_term(int const fd);
-static void setup_term(int const fd);
-static void strip_ansi_color(char * s, toggle_t * toggle);
-static int strprefix(char * str1, char * str2);
-
-static int tst_cb(void * elem);
-static int tst_cb_cli(void * elem);
+
+static ll_node_t *
+ll_partition(ll_node_t * l, ll_node_t * h, int (*comp)(void *, void *),
+ void (*swap)(void *, void *));
+
+static void
+ll_quicksort(ll_node_t * l, ll_node_t * h, int (*comp)(void *, void *),
+ void (*swap)(void * a, void *));
+
+static void
+ll_sort(ll_t * list, int (*comp)(void *, void *),
+ void (*swap)(void * a, void *));
+
+static int
+ll_delete(ll_t * const list, ll_node_t * node);
+
+static ll_node_t *
+ll_find(ll_t * const, void * const, int (*)(const void *, const void *));
+
+static void
+ll_init(ll_t * list);
+
+static ll_node_t *
+ll_new_node(void);
+
+static ll_t *
+ll_new(void);
+
+static void
+ltrim(char * str, const char * trim);
+
+static void
+rtrim(char * str, const char * trim, size_t min_len);
+
+static int
+isempty(const char * str);
+
+static int
+my_stricmp(const char * str1, const char * str2);
+
+static int
+isprint7(int i);
+
+static int
+isprint8(int i);
+
+static int
+count_leading_set_bits(unsigned char c);
+
+static int
+get_cursor_position(int * const r, int * const c);
+
+static void
+get_terminal_size(int * const r, int * const c);
+
+static char *
+mb_strprefix(char * d, char * s, int n, int * pos);
+
+static int
+mb_strlen(char * str);
+
+static wchar_t *
+mb_strtowcs(char * s);
+
+static int
+validate_mb(const char * str, int length);
+
+static int
+outch(int c);
+
+static void
+restore_term(int const fd);
+
+static void
+setup_term(int const fd);
+
+static void
+strip_ansi_color(char * s, toggle_t * toggle);
+
+static int
+strprefix(char * str1, char * str2);
+
+static int
+tst_cb(void * elem);
+
+static int
+tst_cb_cli(void * elem);
+
#if 0 /* here for coherency but not used. */
static void tst_cleanup(tst_node_t * p);
#endif
-static tst_node_t * tst_insert(tst_node_t * p, wchar_t * w, void * data);
-static void * tst_prefix_search(tst_node_t * root, wchar_t * w,
- int (*callback)(void *));
-static void * tst_search(tst_node_t * root, wchar_t * w);
-static int tst_traverse(tst_node_t * p, int (*callback)(void *),
- int first_call);
-
-static int ini_load(const char * filename, win_t * win, term_t * term,
- limits_t * limits,
- int (*report)(win_t * win, term_t * term, limits_t * limits,
- const char * section, const char * name,
- char * value));
-static int ini_cb(win_t * win, term_t * term, limits_t * limits,
- const char * section, const char * name, char * value);
-static char * make_ini_path(char * name, char * base);
-
-static void set_foreground_color(term_t * term, int color);
-static void set_background_color(term_t * term, int color);
-
-static void set_win_start_end(win_t * win, int current, int last);
-static int build_metadata(word_t * word_a, term_t * term, int count,
- win_t * win);
-static int disp_lines(word_t * word_a, win_t * win, toggle_t * toggle,
- int current, int count, int search_mode,
- char * search_buf, term_t * term, int last_line,
- char * tmp_max_word, langinfo_t * langinfo);
-static void get_message_lines(char * message, ll_t * message_lines_list,
- int * message_max_width, int * message_max_len);
-static int disp_message(ll_t * message_lines_list, int width, int max_len,
- term_t * term, win_t * win);
-static void disp_word(word_t * word_a, int pos, int search_mode, char * buffer,
- term_t * term, win_t * win, char * tmp_max_word);
-static int egetopt(int nargc, char ** nargv, char * ostr);
-static int expand(char * src, char * dest, langinfo_t * langinfo);
-static int get_bytes(FILE * input, char * mb_buffer, ll_t * word_delims_list,
- toggle_t * toggle, langinfo_t * langinfo);
-static int get_scancode(unsigned char * s, int max);
-static char * get_word(FILE * input, ll_t * word_delims_list,
- ll_t * record_delims_list, char * mb_buffer,
- unsigned char * is_last, toggle_t * toggle,
- langinfo_t * langinfo, win_t * win, limits_t * limits);
-
-static void left_margin_putp(char * s, term_t * term, win_t * win);
-static void right_margin_putp(char * s1, char * s2, langinfo_t * langinfo,
- term_t * term, win_t * win, int line, int offset);
-
-static int search_next(tst_node_t * tst, word_t * word_a, char * search_buf,
- int after_only);
-static void sig_handler(int s);
-
-static void set_new_first_column(win_t * win, term_t * term, word_t * word_a);
-
-static int parse_sed_like_string(sed_t * sed);
-static int replace(char * orig, sed_t * sed, char * buf, size_t bufsiz);
-
-static int decode_txt_attr_toggles(char * s, txt_attr_t * attr);
-static int parse_txt_attr(char * str, txt_attr_t * attr, short max_color);
-static void apply_txt_attr(term_t * term, txt_attr_t attr);
-static int (*my_isprint)(int);
+static tst_node_t *
+tst_insert(tst_node_t * p, wchar_t * w, void * data);
-static int delims_cmp(const void * a, const void * b);
+static void *
+tst_prefix_search(tst_node_t * root, wchar_t * w, int (*callback)(void *));
-/* **************** */
-/* Global variables */
-/* **************** */
+static void *
+tst_search(tst_node_t * root, wchar_t * w);
-int dummy_rc; /* temporary variable to silence *
- * the compiler */
+static int
+tst_traverse(tst_node_t * p, int (*callback)(void *), int first_call);
-int count = 0; /* number of words read from stdin */
-int current; /* index the current selection *
- * (under the cursor) */
-int new_current; /* final current position, (used in *
- * search function) */
-int * line_nb_of_word_a; /* array containing the line number *
- * (from 0) of each word read */
-int * first_word_in_line_a; /* array containing the index of *
- * the first word of each lines */
-int search_mode = 0; /* 1 if in search mode else 0 */
-int help_mode = 0; /* 1 if help is display else 0 */
+static int
+ini_load(const char * filename, win_t * win, term_t * term, limits_t * limits,
+ int (*report)(win_t * win, term_t * term, limits_t * limits,
+ const char * section, const char * name, char * value));
-/* UTF-8 useful symbols */
-/* """"""""""""""""""""" */
-char * broken_line_sym = "\xc2\xa6"; /* broken_bar */
-char * shift_left_sym = "\xe2\x86\x90"; /* leftwards_arrow */
-char * shift_right_sym = "\xe2\x86\x92"; /* rightwards_arrow */
+static int
+ini_cb(win_t * win, term_t * term, limits_t * limits, const char * section,
+ const char * name, char * value);
-char * sbar_line = "\xe2\x94\x82"; /* box_drawings_light_vertical */
-char * sbar_top = "\xe2\x94\x90"; /* box_drawings_light_down_and_left */
-char * sbar_down = "\xe2\x94\x98"; /* box_drawings_light_up_and_left */
-char * sbar_curs = "\xe2\x95\x91"; /* box_drawings_double_vertical */
-char * sbar_arr_up = "\xe2\x96\xb2"; /* black_up_pointing_triangle */
-char * sbar_arr_down = "\xe2\x96\xbc"; /* black_down_pointing_triangle */
+static char *
+make_ini_path(char * name, char * base);
-tst_node_t * root;
+static void
+set_foreground_color(term_t * term, int color);
-/* Variables used in signal handlers */
-/* """"""""""""""""""""""""""""""""" */
-volatile sig_atomic_t got_winch = 0;
-volatile sig_atomic_t got_winch_alrm = 0;
-volatile sig_atomic_t got_search_alrm = 0;
-volatile sig_atomic_t got_help_alrm = 0;
+static void
+set_background_color(term_t * term, int color);
+
+static void
+set_win_start_end(win_t * win, int current, int last);
+
+static int
+build_metadata(word_t * word_a, term_t * term, int count, win_t * win);
+
+static int
+disp_lines(word_t * word_a, win_t * win, toggle_t * toggle, int current,
+ int count, int search_mode, char * search_buf, term_t * term,
+ int last_line, char * tmp_word, langinfo_t * langinfo);
+
+static void
+get_message_lines(char * message, ll_t * message_lines_list,
+ int * message_max_width, int * message_max_len);
+
+static int
+disp_message(ll_t * message_lines_list, int width, int max_len, term_t * term,
+ win_t * win);
+
+static void
+disp_word(word_t * word_a, int pos, int search_mode, char * buffer,
+ term_t * term, win_t * win, char * tmp_word);
+
+static int
+egetopt(int nargc, char ** nargv, char * ostr);
+
+static int
+expand(char * src, char * dest, langinfo_t * langinfo);
+
+static int
+get_bytes(FILE * input, char * mb_buffer, ll_t * word_delims_list,
+ toggle_t * toggle, langinfo_t * langinfo);
+static int
+get_scancode(unsigned char * s, int max);
+
+static char *
+get_word(FILE * input, ll_t * word_delims_list, ll_t * record_delims_list,
+ char * mb_buffer, unsigned char * is_last, toggle_t * toggle,
+ langinfo_t * langinfo, win_t * win, limits_t * limits);
+
+static void
+left_margin_putp(char * s, term_t * term, win_t * win);
+
+static void
+right_margin_putp(char * s1, char * s2, langinfo_t * langinfo, term_t * term,
+ win_t * win, int line, int offset);
+
+static int
+search_nex(tst_node_t * tst, word_t * word_a, char * search_buf,
+ int after_only);
+
+static void
+sig_handler(int s);
+
+static void
+set_new_first_column(win_t * win, term_t * term, word_t * word_a);
+
+static int
+parse_sed_like_string(sed_t * sed);
+
+static int
+replace(char * orig, sed_t * sed);
+
+static int
+decode_txt_attr_toggles(char * s, txt_attr_t * attr);
+
+static int
+parse_txt_attr(char * str, txt_attr_t * attr, short max_color);
+
+static void
+apply_txt_attr(term_t * term, txt_attr_t attr);
+
+static int (*my_isprint)(int);
+
+static int
+delims_cmp(const void * a, const void * b);
/* ***************** */
/* emums and structs */
@@ -241,10 +318,40 @@ enum filter_types
EXCLUDE_FILTER
};
+/* Used when managing the -R option */
+/* """""""""""""""""""""""""""""""" */
+enum row_regex_types
+{
+ ROW_REGEX_EXCLUDE = 0,
+ ROW_REGEX_INCLUDE = 1
+};
+
+/* Used when managing the -C option */
+/* """""""""""""""""""""""""""""""" */
enum filter_infos
{
- INCLUDE_MARK = '1',
- EXCLUDE_MARK = '0'
+ EXCLUDE_MARK = 0, /* must be 0 because used in various tests *
+ * these words cannot be re-included */
+ INCLUDE_MARK = 1, /* to forcibly include a word, these words can *
+ * be excluded later */
+ SOFT_EXCLUDE_MARK = 2, /* word with this mark are excluded by default *
+ * but can be included later */
+ SOFT_INCLUDE_MARK = 3 /* word with this mark are included by default *
+ * but can be excluded later */
+};
+
+enum timeout_types
+{
+ CURRENT, /* on timeout, outputs the selected word */
+ QUIT, /* on timeout, quit without selecting anything */
+ WORD /* on timeout , outputs the specified word */
+};
+
+enum attribute_settings
+{
+ UNSET = 0, /* must be 0 for future testings */
+ SET,
+ FORCED /* an attribute setting has been given in the command line */
};
/* Locale informations */
@@ -291,10 +398,11 @@ struct termios old_in_attrs;
/* Interval timers used */
/* """""""""""""""""""" */
-struct itimerval search_itv; /* used when searching */
-struct itimerval hlp_itv; /* used to remove the help line */
-struct itimerval winch_itv; /* used to delay the redisplay when *
- * the terminal is resized */
+struct itimerval periodic_itv; /* refresh rate for the timeout counter */
+
+int search_timer = -1;
+int help_timer = -1;
+int winch_timer = -1;
/* Structure containing the attributes components */
/* """""""""""""""""""""""""""""""""""""""""""""" */
@@ -322,21 +430,22 @@ struct term_s
short colors; /* number of available colors */
short color_method; /* color method (0=classic (0-7), 1=ANSI) */
- char has_cursor_up; /* has cuu1 terminfo capability */
- char has_cursor_down; /* has cud1 terminfo capability */
- char has_cursor_left; /* has cub1 terminfo capability */
- char has_cursor_right; /* has cuf1 terminfo capability */
- char has_save_cursor; /* has sc terminfo capability */
- char has_restore_cursor; /* has rc terminfo capability */
- char has_setf; /* has set_foreground terminfo capability */
- char has_setb; /* has set_background terminfo capability */
- char has_setaf; /* idem for set_a_foreground (ANSI) */
- char has_setab; /* idem for set_a_background (ANSI) */
- char has_hpa; /* has column_address terminfo capability */
- char has_bold; /* has bold mode */
- char has_reverse; /* has reverse mode */
- char has_underline; /* has underline mode */
- char has_standout; /* has standout mode */
+ char has_cursor_up; /* has cuu1 terminfo capability */
+ char has_cursor_down; /* has cud1 terminfo capability */
+ char has_cursor_left; /* has cub1 terminfo capability */
+ char has_cursor_right; /* has cuf1 terminfo capability */
+ char has_parm_right_cursor; /* has cuf terminfo capability */
+ char has_save_cursor; /* has sc terminfo capability */
+ char has_restore_cursor; /* has rc terminfo capability */
+ char has_setf; /* has set_foreground terminfo capability */
+ char has_setb; /* has set_background terminfo capability */
+ char has_setaf; /* idem for set_a_foreground (ANSI) */
+ char has_setab; /* idem for set_a_background (ANSI) */
+ char has_hpa; /* has column_address terminfo capability */
+ char has_bold; /* has bold mode */
+ char has_reverse; /* has reverse mode */
+ char has_underline; /* has underline mode */
+ char has_standout; /* has standout mode */
};
/* Structure describing a word */
@@ -354,7 +463,7 @@ struct word_s
* by is expansion. */
unsigned char is_tagged; /* 1 if the word is tagged, 0 if not */
unsigned char is_last; /* 1 if the word is the last of a line */
- unsigned char is_selectable; /* word is is_selectable */
+ unsigned char is_selectable; /* word is selectable */
};
/* Structure describing the window in which the user */
@@ -367,7 +476,7 @@ struct win_s
int cur_line; /* relative number of the cursor line (1+) */
int asked_max_lines; /* requested number of lines in the window */
int max_lines; /* effective number of lines in the window */
- int max_cols; /* max number of words in a sigle line */
+ int max_cols; /* max number of words in a single line */
int max_width; /* max line length. In column, tab or line *
* mode it can be greater than the *
* terminal width */
@@ -387,6 +496,7 @@ struct win_s
txt_attr_t shift_attr; /* shift indicator attributes */
txt_attr_t search_field_attr; /* search mode field attributes */
txt_attr_t search_text_attr; /* search mode text attributes */
+ txt_attr_t include_attr; /* selectable words attributes */
txt_attr_t exclude_attr; /* non-selectable words attributes */
txt_attr_t tag_attr; /* non-selectable words attributes */
txt_attr_t special_attr[5]; /* special (-1,...) words attributes */
@@ -415,6 +525,74 @@ struct interval_s
int high;
};
+/* Structure used by the replace function to delimit matches */
+/* """"""""""""""""""""""""""""""""""""""""""""""""""""""""" */
+struct range_s
+{
+ size_t start;
+ size_t end;
+};
+
+struct timeout_s
+{
+ unsigned type; /* timeout type: current/quit/word */
+ unsigned initial_value; /* 0: no timeout else value in sec */
+ unsigned remain; /* remaining seconds */
+ unsigned reached; /* 1: timeout has expired, else 0 */
+};
+
+/* **************** */
+/* Global variables */
+/* **************** */
+
+int dummy_rc; /* temporary variable to silence *
+ * the compiler */
+
+int count = 0; /* number of words read from stdin */
+int current; /* index the current selection *
+ * (under the cursor) */
+int new_current; /* final current position, (used in *
+ * search function) */
+int * line_nb_of_word_a; /* array containing the line number *
+ * (from 0) of each word read */
+int * first_word_in_line_a; /* array containing the index of *
+ * the first word of each lines */
+int search_mode = 0; /* 1 if in search mode else 0 */
+int help_mode = 0; /* 1 if help is display else 0 */
+
+char * word_buffer;
+
+/* UTF-8 useful symbols */
+/* """"""""""""""""""""" */
+char * broken_line_sym = "\xc2\xa6"; /* broken_bar */
+char * shift_left_sym = "\xe2\x86\x90"; /* leftwards_arrow */
+char * shift_right_sym = "\xe2\x86\x92"; /* rightwards_arrow */
+
+char * sbar_line = "\xe2\x94\x82"; /* box_drawings_light_vertical */
+char * sbar_top = "\xe2\x94\x90"; /* box_drawings_light_down_and_left */
+char * sbar_down = "\xe2\x94\x98"; /* box_drawings_light_up_and_left */
+char * sbar_curs = "\xe2\x95\x91"; /* box_drawings_double_vertical */
+char * sbar_arr_up = "\xe2\x96\xb2"; /* black_up_pointing_triangle */
+char * sbar_arr_down = "\xe2\x96\xbc"; /* black_down_pointing_triangle */
+
+tst_node_t * root;
+
+/* Variables used in signal handlers */
+/* """"""""""""""""""""""""""""""""" */
+volatile sig_atomic_t got_winch = 0;
+volatile sig_atomic_t got_winch_alrm = 0;
+volatile sig_atomic_t got_search_alrm = 0;
+volatile sig_atomic_t got_help_alrm = 0;
+volatile sig_atomic_t got_timeout_tick = 0;
+
+/* Variables used when a timeout is set (option -x) */
+/* """""""""""""""""""""""""""""""""""""""""""""""" */
+timeout_t timeout;
+char * timeout_word; /* printed word when the timeout type is WORD. */
+char * timeout_seconds; /* string containing the number of remaining *
+ * seconds. */
+int quiet_timeout = 0; /* 1 when we want no message to be displayed. */
+
/* ************************************************************************ */
/* custom fgetc/ungetc implementation able to unget more than one character */
/* ************************************************************************ */
@@ -431,7 +609,7 @@ static size_t next_buffer_pos = 0; /* next free position in the getc buffer */
/* ====================================== */
/* get a (possibly pushed-back) character */
/* ====================================== */
-int
+static int
my_fgetc(FILE * input)
{
return (next_buffer_pos > 0) ? getc_buffer[--next_buffer_pos] : fgetc(input);
@@ -440,7 +618,7 @@ my_fgetc(FILE * input)
/* ============================ */
/* push character back on input */
/* ============================ */
-void
+static void
my_ungetc(int c)
{
if (next_buffer_pos >= GETC_BUFF_SIZE)
@@ -493,41 +671,57 @@ struct ll_s
/* =================== */
/* Short usage display */
/* =================== */
-void
+static void
short_usage(void)
{
- fprintf(stderr, "Usage: smenu [-h|-?] [-n lines] [-c] [-l] [-s pattern] ");
- fprintf(stderr, "[-m message] [-w] \\\n");
- fprintf(stderr, " [-d] [-M] [-t [cols]] [-k] [-r] [-b] [-i regex] ");
- fprintf(stderr, "[-e regex] \\\n");
- fprintf(stderr, " [-C [a|A|s|S|r|R|d|D]col1[-col2],[col1[-col2]]...]");
- fprintf(stderr, " \\\n");
- fprintf(stderr, " [-R [a|A|s|S|r|R|d|D]row1[-row2],[row1[-row2]]...] ");
- fprintf(stderr, " \\\n");
+ fprintf(stderr, "Usage: smenu [-h|-?] [-f config_file] [-n lines] ");
+ fprintf(stderr, "[-t [cols]] [-k] \\\n");
+ fprintf(stderr, " [-s pattern] [-m message] [-w] [-d] [-M] [-c] [-l] ");
+ fprintf(stderr, "[-r] [-b] \\\n");
+ fprintf(stderr, " [-a prefix:attr [prefix:attr]...] ");
+ fprintf(stderr, "[-i regex] [-e regex] \\\n");
+ fprintf(stderr, " [-C [a|s|i|r|d|e]<col selectors>] ");
+ fprintf(stderr, "[-R [a|s|i|r|d|e]<row selectors>] \\\n");
fprintf(stderr, " [-S /regex/repl/[g][v][s][i]] ");
- fprintf(stderr, "[-I /regex/repl/[g][v][s][i]] \\\n");
+ fprintf(stderr, "[-I /regex/repl/[g][v][s][i]] \\\n");
fprintf(stderr, " [-E /regex/repl/[g][v][s][i]] ");
- fprintf(stderr, "[-A regex] [-Z regex] \\\n");
- fprintf(stderr, " [-1 regex [attr]] [-2 regex [attr]] ... ");
- fprintf(stderr, "[-5 regex [attr]] [-g] \\\n");
- fprintf(stderr, " [-W bytes] [-L bytes] [-T [separator]] [-V]\n");
+ fprintf(stderr, "[-A regex] [-Z regex] \\\n");
+ fprintf(stderr, " [-1 regex [attr]] [-2 regex [attr]]... ");
+ fprintf(stderr, "[-5 regex [attr]] \\\n");
+ fprintf(stderr, " [-g] [-q] [-W bytes] [-L bytes] [-T [separator]]");
+ fprintf(stderr, " \\\n");
+ fprintf(stderr, " [-V] [-x|-X current|quit|word [<word>] <seconds>] ");
+ fprintf(stderr, "[input_file]\n\n");
+ fprintf(stderr, " <col selectors> ::= col1[-col2]...|<RE>...\n");
+ fprintf(stderr, " <row selectors> ::= row1[-row2]...|<RE>...\n");
+ fprintf(stderr, " <prefix> ::= e|i|c|b|s|t|sf|st\n");
+ fprintf(stderr, " <attr> ::= [fg][/bg][,style] \n");
+ fprintf(stderr, " (ex: 7/4,bu)\n");
+ fprintf(stderr, " <RE> ::= <char>regex<char> \n");
+ fprintf(stderr, " (ex: /regex/ or :regex:)\n\n");
+ fprintf(stderr, " <col/row selectors> and <RE> can be freely mixed ");
+ fprintf(stderr, "when used\n");
+ fprintf(stderr, " with -C and -R (ex: 2,/x/,4-5).\n");
}
/* ====================== */
/* Usage display and exit */
/* ====================== */
-void
+static void
usage(void)
{
short_usage();
fprintf(stderr, "\nThis is a filter that gets words from stdin ");
- fprintf(stderr, "and outputs the\n");
- fprintf(stderr, "selected word (or nothing) on stdout.\n\n");
+ fprintf(stderr, "and outputs the selected\n");
+ fprintf(stderr, "words (or nothing) on stdout in a nice selection ");
+ fprintf(stderr, "window\n\n");
fprintf(stderr, "The selection window appears on /dev/tty ");
- fprintf(stderr, "immediately after the current line.\n\n");
+ fprintf(stderr, "immediately after the current line\n");
+ fprintf(stderr, "(no clear screen!).\n\n");
fprintf(stderr, "The following options are available:\n\n");
fprintf(stderr, "-h displays this help.\n");
+ fprintf(stderr, "-f selects an alternative configuration file.\n");
fprintf(stderr, "-n sets the number of lines in the selection window.\n");
fprintf(stderr,
"-t tabulates the items. The number of columns can be limited "
@@ -551,12 +745,14 @@ usage(void)
"-r enables ENTER to validate the selection even in "
"search mode.\n");
fprintf(stderr, "-b displays the non printable characters as space.\n");
+ fprintf(stderr, "-a sets the attributes for the various displayed ");
+ fprintf(stderr, "elements.\n");
fprintf(stderr,
"-i sets the regex input filter to match the selectable words.\n");
fprintf(stderr,
"-e sets the regex input filter to match the non-selectable "
"words.\n");
- fprintf(stderr, "-C sets column restrictions for selections.\n");
+ fprintf(stderr, "-C sets columns restrictions for selections.\n");
fprintf(stderr, "-R sets rows restrictions for selections.\n");
fprintf(stderr,
"-S sets the post-processing action to apply to all words.\n");
@@ -585,6 +781,8 @@ usage(void)
fprintf(stderr, "on the output.\n");
fprintf(stderr, " A single space is the default separator.\n");
fprintf(stderr, "-V displays the current version and quits.\n");
+ fprintf(stderr,
+ "-x|-X sets a timeout and specifies what to do when it expires.\n");
fprintf(stderr, "\nNavigation keys are:\n");
fprintf(stderr, " - Left/Down/Up/Right arrows or h/j/k/l.\n");
fprintf(stderr, " - Home/End.\n");
@@ -626,7 +824,7 @@ usage(void)
/* ==================== */
/* Help message display */
/* ==================== */
-void
+static void
help(win_t * win, term_t * term, int last_line, toggle_t * toggle)
{
int index; /* used to identify the objects int the help line */
@@ -640,24 +838,23 @@ help(win_t * win, term_t * term, int last_line, toggle_t * toggle)
struct entry_s
{
char attr; /* r=reverse, n=normal, b=bold */
- char * str; /* string to be displayed for un object in the help line */
+ char * str; /* string to be displayed for an object in the help line */
int len; /* length of one of these objects */
};
- struct entry_s entries[] = {
- { 'r', "HLP", 3 }, { 'n', " ", 1 }, { 'n', "Move:", 5 },
- { 'b', "Arrows", 6 }, { 'n', "|", 1 }, { 'b', "h", 1 },
- { 'b', "j", 1 }, { 'b', "k", 1 }, { 'b', "l", 1 },
- { 'n', ",", 1 }, { 'b', "PgUp", 4 }, { 'n', "/", 1 },
- { 'b', "PgDn", 4 }, { 'n', "/", 1 }, { 'b', "Home", 4 },
- { 'n', "/", 1 }, { 'b', "End", 3 }, { 'n', " ", 1 },
- { 'n', "Abort:", 6 }, { 'b', "q", 1 }, { 'n', " ", 1 },
- { 'n', "Select:", 7 }, { 'b', "CR", 2 }, { 'n', " ", 1 },
- { 'n', "Find:", 5 }, { 'b', "/", 1 }, { 'n', "|", 1 },
- { 'b', "^F", 2 }, { 'n', "|", 1 }, { 'b', "SP", 2 },
- { 'n', "|", 1 }, { 'b', "n", 1 }, { 'n', " ", 1 },
- { 'n', "Tag:", 4 }, { 'b', "t", 1 }
- };
+ struct entry_s entries[] =
+ { { 'r', "HLP", 3 }, { 'n', " ", 1 }, { 'n', "Move:", 5 },
+ { 'b', "Arrows", 6 }, { 'n', "|", 1 }, { 'b', "h", 1 },
+ { 'b', "j", 1 }, { 'b', "k", 1 }, { 'b', "l", 1 },
+ { 'n', ",", 1 }, { 'b', "PgUp", 4 }, { 'n', "/", 1 },
+ { 'b', "PgDn", 4 }, { 'n', "/", 1 }, { 'b', "Home", 4 },
+ { 'n', "/", 1 }, { 'b', "End", 3 }, { 'n', " ", 1 },
+ { 'n', "Abort:", 6 }, { 'b', "q", 1 }, { 'n', " ", 1 },
+ { 'n', "Select:", 7 }, { 'b', "CR", 2 }, { 'n', " ", 1 },
+ { 'n', "Find:", 5 }, { 'b', "/", 1 }, { 'n', "|", 1 },
+ { 'b', "^F", 2 }, { 'n', "|", 1 }, { 'b', "SP", 2 },
+ { 'n', "|", 1 }, { 'b', "n", 1 }, { 'n', " ", 1 },
+ { 'n', "Tag:", 4 }, { 'b', "t", 1 } };
entries_nb = sizeof(entries) / sizeof(struct entry_s);
@@ -739,7 +936,7 @@ help(win_t * win, term_t * term, int last_line, toggle_t * toggle)
/* ================= */
/* Customized malloc */
/* ================= */
-void *
+static void *
xmalloc(size_t size)
{
void * allocated;
@@ -762,7 +959,7 @@ xmalloc(size_t size)
/* ================= */
/* Customized calloc */
/* ================= */
-void *
+static void *
xcalloc(size_t n, size_t size)
{
void * allocated;
@@ -785,7 +982,7 @@ xcalloc(size_t n, size_t size)
/* ================== */
/* Customized realloc */
/* ================== */
-void *
+static void *
xrealloc(void * p, size_t size)
{
void * allocated;
@@ -806,7 +1003,7 @@ xrealloc(void * p, size_t size)
/* =================================== */
/* strdup implementation using xmalloc */
/* =================================== */
-char *
+static char *
xstrdup(const char * p)
{
char * allocated;
@@ -833,7 +1030,7 @@ xstrdup(const char * p)
/* Returns 0 if some unexpected */
/* toggle is found else 0 */
/* ================================ */
-int
+static int
decode_txt_attr_toggles(char * s, txt_attr_t * attr)
{
int rc = 1;
@@ -847,27 +1044,27 @@ decode_txt_attr_toggles(char * s, txt_attr_t * attr)
{
case 'b':
attr->bold = 1;
- attr->is_set = 1;
+ attr->is_set = SET;
break;
case 'd':
attr->dim = 1;
- attr->is_set = 1;
+ attr->is_set = SET;
break;
case 'r':
attr->reverse = 1;
- attr->is_set = 1;
+ attr->is_set = SET;
break;
case 's':
attr->standout = 1;
- attr->is_set = 1;
+ attr->is_set = SET;
break;
case 'u':
attr->underline = 1;
- attr->is_set = 1;
+ attr->is_set = SET;
break;
case 'i':
attr->italic = 1;
- attr->is_set = 1;
+ attr->is_set = SET;
break;
default:
rc = 0;
@@ -886,7 +1083,7 @@ decode_txt_attr_toggles(char * s, txt_attr_t * attr)
/* Returns 1 on success else 0 */
/* attr will be filled by the function */
/* ============================================================ */
-int
+static int
parse_txt_attr(char * str, txt_attr_t * attr, short max_color)
{
int n;
@@ -940,16 +1137,13 @@ parse_txt_attr(char * str, txt_attr_t * attr, short max_color)
if (n == 2)
rc = decode_txt_attr_toggles(s2, attr);
- if (!attr->is_set)
- attr->is_set = (d1 >= 0 || d2 >= 0);
-
return rc;
}
/* ============================================= */
/* Set the terminal attributes according to attr */
/* ============================================= */
-void
+static void
apply_txt_attr(term_t * term, txt_attr_t attr)
{
if (attr.fg >= 0)
@@ -986,7 +1180,7 @@ apply_txt_attr(term_t * term, txt_attr_t attr)
/* line of the ini file. */
/* Returns 0 if OK, 1 if not. */
/* ===================================================== */
-int
+static int
ini_cb(win_t * win, term_t * term, limits_t * limits, const char * section,
const char * name, char * value)
{
@@ -995,7 +1189,7 @@ ini_cb(win_t * win, term_t * term, limits_t * limits, const char * section,
if (strcmp(section, "colors") == 0)
{
- txt_attr_t v = { 0, -1, -1, -1, -1, -1, -1, -1, -1 };
+ txt_attr_t v = { UNSET, -1, -1, -1, -1, -1, -1, -1, -1 };
#define CHECK_ATTR(x) \
else if (strcmp(name, #x) == 0) \
@@ -1005,51 +1199,58 @@ ini_cb(win_t * win, term_t * term, limits_t * limits, const char * section,
goto out; \
else \
{ \
- win->x##_attr.is_set = v.is_set; \
- if (win->x##_attr.fg < 0) \
- win->x##_attr.fg = v.fg; \
- if (win->x##_attr.bg < 0) \
- win->x##_attr.bg = v.bg; \
- if (win->x##_attr.bold < 0) \
- win->x##_attr.bold = v.bold; \
- if (win->x##_attr.dim < 0) \
- win->x##_attr.dim = v.dim; \
- if (win->x##_attr.reverse < 0) \
- win->x##_attr.reverse = v.reverse; \
- if (win->x##_attr.standout < 0) \
- win->x##_attr.standout = v.standout; \
- if (win->x##_attr.underline < 0) \
- win->x##_attr.underline = v.underline; \
- if (win->x##_attr.italic < 0) \
- win->x##_attr.italic = v.italic; \
+ if (win->x##_attr.is_set != FORCED) \
+ { \
+ win->x##_attr.is_set = SET; \
+ if (v.fg >= 0) \
+ win->x##_attr.fg = v.fg; \
+ if (v.bg >= 0) \
+ win->x##_attr.bg = v.bg; \
+ if (v.bold >= 0) \
+ win->x##_attr.bold = v.bold; \
+ if (v.dim >= 0) \
+ win->x##_attr.dim = v.dim; \
+ if (v.reverse >= 0) \
+ win->x##_attr.reverse = v.reverse; \
+ if (v.standout >= 0) \
+ win->x##_attr.standout = v.standout; \
+ if (v.underline >= 0) \
+ win->x##_attr.underline = v.underline; \
+ if (v.italic >= 0) \
+ win->x##_attr.italic = v.italic; \
+ } \
} \
}
-#define CHECK_ATT_ATTR(x, y) \
- else if (strcmp(name, #x #y) == 0) \
- { \
- if ((error = !parse_txt_attr(value, &v, term->colors))) \
- goto out; \
- else \
- { \
- win->x##_attr[y - 1].is_set = v.is_set; \
- if (win->x##_attr[y - 1].fg < 0) \
- win->x##_attr[y - 1].fg = v.fg; \
- if (win->x##_attr[y - 1].bg < 0) \
- win->x##_attr[y - 1].bg = v.bg; \
- if (win->x##_attr[y - 1].bold < 0) \
- win->x##_attr[y - 1].bold = v.bold; \
- if (win->x##_attr[y - 1].dim < 0) \
- win->x##_attr[y - 1].dim = v.dim; \
- if (win->x##_attr[y - 1].reverse < 0) \
- win->x##_attr[y - 1].reverse = v.reverse; \
- if (win->x##_attr[y - 1].standout < 0) \
- win->x##_attr[y - 1].standout = v.standout; \
- if (win->x##_attr[y - 1].underline < 0) \
- win->x##_attr[y - 1].underline = v.underline; \
- if (win->x##_attr[y - 1].ital