top: introduce relational operators with other filters
When I originally entertained thoughts of maybe adding relational operators to the new 'Other Filter' feature the programming challenges seemed just too great. Yet, when Jaromir suggests its desirability it now suddenly becomes a reality. Another of life's little mysteries! At any rate what was already an extremely powerful new feature is even better by several orders of magnitude! (everything is perfectly justified plus right margins) (are completely filled, but of course it must be luck) References: http://www.freelists.org/post/procps/top-beyond-infinity,1 Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
parent
f9a208b273
commit
2c2c5f5cd2
62
top/top.c
62
top/top.c
@ -1299,19 +1299,21 @@ static inline const char *hex_make (KLONG num, int noz) {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The sructure hung from a WIN_t when 'other' filtering is active. */
|
* This sructure is hung from a WIN_t when other filtering is active */
|
||||||
struct osel_s {
|
struct osel_s {
|
||||||
int flg; // include == 1, exclude == 0
|
|
||||||
FLG_t enu; // field (procflag) to filter
|
|
||||||
char *val; // value included or excluded
|
|
||||||
char *(*cmp)(const char *, const char *); // string comparison function
|
|
||||||
char *raw; // raw user input (dup check)
|
|
||||||
struct osel_s *nxt; // the next criteria or NULL.
|
struct osel_s *nxt; // the next criteria or NULL.
|
||||||
|
int (*rel)(const char *, const char *); // relational strings compare
|
||||||
|
char *(*sel)(const char *, const char *); // for selection str compares
|
||||||
|
char *raw; // raw user input (dup check)
|
||||||
|
char *val; // value included or excluded
|
||||||
|
int ops; // filter delimiter/operation
|
||||||
|
int flg; // include == 1, exclude == 0
|
||||||
|
int enu; // field (procflag) to filter
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A function to turn off any 'other' filtering in the given window */
|
* A function to turn off entire other filtering in the given window */
|
||||||
static void osel_clear (WIN_t *q) {
|
static void osel_clear (WIN_t *q) {
|
||||||
struct osel_s *osel = q->osel_1st;
|
struct osel_s *osel = q->osel_1st;
|
||||||
|
|
||||||
@ -1333,17 +1335,30 @@ static void osel_clear (WIN_t *q) {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine if there's a matching value among the 'other' criteria
|
* Determine if there is a matching value or releationship among the
|
||||||
* in a given window -- it's called from only one place, and likely
|
* other criteria in the passed window -- it's called from only one
|
||||||
* inlined even without the directive */
|
* place, and likely inlined even without the directive */
|
||||||
static inline int osel_matched (const WIN_t *q, FLG_t enu, const char *str) {
|
static inline int osel_matched (const WIN_t *q, FLG_t enu, const char *str) {
|
||||||
struct osel_s *osel = q->osel_1st;
|
struct osel_s *osel = q->osel_1st;
|
||||||
|
|
||||||
while (osel) {
|
while (osel) {
|
||||||
if (osel->enu == enu) {
|
if (osel->enu == enu) {
|
||||||
char *p = osel->cmp(str, osel->val);
|
int r;
|
||||||
if (p && !osel->flg) return 0;
|
switch (osel->ops) {
|
||||||
if (!p && osel->flg) return 0;
|
case '<': // '<' needs the r < 0 unless
|
||||||
|
r = osel->rel(str, osel->val); // '!' which needs an inverse
|
||||||
|
if ((0 <= r && osel->flg) || (0 >= r && !osel->flg)) return 0;
|
||||||
|
break;
|
||||||
|
case '>': // '>' needs the r > 0 unless
|
||||||
|
r = osel->rel(str, osel->val); // '!' which needs an inverse
|
||||||
|
if ((0 >= r && osel->flg) || (0 <= r && !osel->flg)) return 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{ char *p = osel->sel(str, osel->val);
|
||||||
|
if ((!p && osel->flg) || (p && !osel->flg)) return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
osel = osel->nxt;
|
osel = osel->nxt;
|
||||||
}
|
}
|
||||||
@ -4051,18 +4066,21 @@ signify_that:
|
|||||||
|
|
||||||
|
|
||||||
static void other_selection (int ch) {
|
static void other_selection (int ch) {
|
||||||
char *(*cmp)(const char *, const char *);
|
int (*rel)(const char *, const char *);
|
||||||
char raw[MEDBUFSIZ], *glob, *pval;
|
char *(*sel)(const char *, const char *);
|
||||||
|
char raw[MEDBUFSIZ], ops, *glob, *pval;
|
||||||
struct osel_s *osel;
|
struct osel_s *osel;
|
||||||
const char *typ;
|
const char *typ;
|
||||||
int flg, enu;
|
int flg, enu;
|
||||||
|
|
||||||
if (ch == 'o') {
|
if (ch == 'o') {
|
||||||
typ = N_txt(OSEL_casenot_txt);
|
typ = N_txt(OSEL_casenot_txt);
|
||||||
cmp = strcasestr;
|
rel = strcasecmp;
|
||||||
|
sel = strcasestr;
|
||||||
} else {
|
} else {
|
||||||
typ = N_txt(OSEL_caseyes_txt);
|
typ = N_txt(OSEL_caseyes_txt);
|
||||||
cmp = strstr;
|
rel = strcmp;
|
||||||
|
sel = strstr;
|
||||||
}
|
}
|
||||||
glob = ioline(fmtmk(N_fmt(OSEL_prompts_fmt), Curwin->osel_tot + 1, typ));
|
glob = ioline(fmtmk(N_fmt(OSEL_prompts_fmt), Curwin->osel_tot + 1, typ));
|
||||||
if (!snprintf(raw, sizeof(raw), "%s", glob)) return;
|
if (!snprintf(raw, sizeof(raw), "%s", glob)) return;
|
||||||
@ -4075,11 +4093,12 @@ static void other_selection (int ch) {
|
|||||||
}
|
}
|
||||||
if (*glob != '!') flg = 1; // #2: is it include/exclude?
|
if (*glob != '!') flg = 1; // #2: is it include/exclude?
|
||||||
else { ++glob; flg = 0; }
|
else { ++glob; flg = 0; }
|
||||||
if (!(pval = strchr(glob, ':'))) { // #3: do we see a delimiter?
|
if (!(pval = strpbrk(glob, "<=>"))) { // #3: do we see a delimiter?
|
||||||
show_msg(fmtmk(N_fmt(OSEL_errdelm_fmt)
|
show_msg(fmtmk(N_fmt(OSEL_errdelm_fmt)
|
||||||
, flg ? N_txt(WORD_include_txt) : N_txt(WORD_exclude_txt)));
|
, flg ? N_txt(WORD_include_txt) : N_txt(WORD_exclude_txt)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ops = *(pval);
|
||||||
*(pval++) = '\0';
|
*(pval++) = '\0';
|
||||||
for (enu = 0; enu < P_MAXPFLGS; enu++) // #4: is this a valid field?
|
for (enu = 0; enu < P_MAXPFLGS; enu++) // #4: is this a valid field?
|
||||||
if (!STRCMP(N_col(enu), glob)) break;
|
if (!STRCMP(N_col(enu), glob)) break;
|
||||||
@ -4095,8 +4114,11 @@ static void other_selection (int ch) {
|
|||||||
osel = alloc_c(sizeof(struct osel_s));
|
osel = alloc_c(sizeof(struct osel_s));
|
||||||
osel->flg = flg;
|
osel->flg = flg;
|
||||||
osel->enu = enu;
|
osel->enu = enu;
|
||||||
osel->val = alloc_s(pval);
|
osel->ops = ops;
|
||||||
osel->cmp = cmp;
|
if (ops == '=') osel->val = alloc_s(pval);
|
||||||
|
else osel->val = alloc_s(justify_pad(pval, Fieldstab[enu].width, Fieldstab[enu].align));
|
||||||
|
osel->rel = rel;
|
||||||
|
osel->sel = sel;
|
||||||
osel->raw = alloc_s(raw);
|
osel->raw = alloc_s(raw);
|
||||||
osel->nxt = Curwin->osel_1st;
|
osel->nxt = Curwin->osel_1st;
|
||||||
Curwin->osel_1st = osel;
|
Curwin->osel_1st = osel;
|
||||||
|
@ -431,7 +431,7 @@ static void build_norm_nlstab (void) {
|
|||||||
Norm_nlstab[YINSP_workin_txt] = _("patience please, working...");
|
Norm_nlstab[YINSP_workin_txt] = _("patience please, working...");
|
||||||
/* Translation Hint: Below are 2 abbreviations which can be as long as needed:
|
/* Translation Hint: Below are 2 abbreviations which can be as long as needed:
|
||||||
. FLD = FIELD, VAL = VALUE */
|
. FLD = FIELD, VAL = VALUE */
|
||||||
Norm_nlstab[OSEL_prompts_fmt] = _("add filter #%d (%s) as: [!]FLD:VAL");
|
Norm_nlstab[OSEL_prompts_fmt] = _("add filter #%d (%s) as: [!]FLD?VAL");
|
||||||
Norm_nlstab[OSEL_casenot_txt] = _("ignoring case");
|
Norm_nlstab[OSEL_casenot_txt] = _("ignoring case");
|
||||||
Norm_nlstab[OSEL_caseyes_txt] = _("case sensitive");
|
Norm_nlstab[OSEL_caseyes_txt] = _("case sensitive");
|
||||||
Norm_nlstab[OSEL_errdups_txt] = _("duplicate filter was ignored");
|
Norm_nlstab[OSEL_errdups_txt] = _("duplicate filter was ignored");
|
||||||
@ -439,7 +439,7 @@ static void build_norm_nlstab (void) {
|
|||||||
Norm_nlstab[OSEL_errvalu_fmt] = _("'%s' filter value is missing");
|
Norm_nlstab[OSEL_errvalu_fmt] = _("'%s' filter value is missing");
|
||||||
Norm_nlstab[WORD_include_txt] = _("include");
|
Norm_nlstab[WORD_include_txt] = _("include");
|
||||||
Norm_nlstab[WORD_exclude_txt] = _("exclude");
|
Norm_nlstab[WORD_exclude_txt] = _("exclude");
|
||||||
Norm_nlstab[OSEL_statlin_fmt] = _("<Enter> to resume, filters = %s");
|
Norm_nlstab[OSEL_statlin_fmt] = _("<Enter> to resume, filters: %s");
|
||||||
Norm_nlstab[WORD_noneone_txt] = _("none");
|
Norm_nlstab[WORD_noneone_txt] = _("none");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user