summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Henriksen <LarsHenriksen@get2net.dk>2018-12-06 09:56:45 +0100
committerLukas Fleischer <lfleischer@calcurse.org>2019-01-07 16:58:06 +0100
commit42abbf53463cbbdcd319063fcbfb91cf6ed5bdc5 (patch)
treea787439c222045a47484e30d6752c71635c41efc /src
parent9300e9154c5f70aa6fb858452f0c3563d100850d (diff)
downloadcalcurse-42abbf53463cbbdcd319063fcbfb91cf6ed5bdc5.tar.gz
calcurse-42abbf53463cbbdcd319063fcbfb91cf6ed5bdc5.zip
Filter option: invert
New filter option: --filter-invert. When present it inverts (negates) the other filter options combined. This is mostly useful with the -G option (with -Q the output is limited by the query range (day range)). The ouput from "calcurse -G <filter options>" is the (set) complement of "calcurse -G <filter options> --filter-invert". Here <filter options> may be any combination of filter options. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
Diffstat (limited to 'src')
-rw-r--r--src/apoint.c46
-rw-r--r--src/args.c10
-rw-r--r--src/calcurse.h1
-rw-r--r--src/event.c45
-rw-r--r--src/io.c46
-rw-r--r--src/recur.c101
6 files changed, 128 insertions, 121 deletions
diff --git a/src/apoint.c b/src/apoint.c
index e8f9ee8..c195559 100644
--- a/src/apoint.c
+++ b/src/apoint.c
@@ -200,7 +200,8 @@ struct apoint *apoint_scan(FILE * f, struct tm start, struct tm end,
{
char buf[BUFSIZ], *newline;
time_t tstart, tend;
- struct apoint *apt;
+ struct apoint *apt = NULL;
+ int cond;
EXIT_IF(!check_date(start.tm_year, start.tm_mon, start.tm_mday) ||
!check_date(end.tm_year, end.tm_mon, end.tm_mday) ||
@@ -230,31 +231,30 @@ struct apoint *apoint_scan(FILE * f, struct tm start, struct tm end,
/* Filter item. */
if (filter) {
- if (!(filter->type_mask & TYPE_MASK_APPT))
- return NULL;
- if (filter->regex && regexec(filter->regex, buf, 0, 0, 0))
- return NULL;
- if (filter->start_from != -1 && tstart < filter->start_from)
- return NULL;
- if (filter->start_to != -1 && tstart > filter->start_to)
- return NULL;
- if (filter->end_from != -1 && tend < filter->end_from)
- return NULL;
- if (filter->end_to != -1 && tend > filter->end_to)
- return NULL;
- }
-
- apt = apoint_new(buf, note, tstart, tend - tstart, state);
+ cond = (
+ !(filter->type_mask & TYPE_MASK_APPT) ||
+ (filter->regex && regexec(filter->regex, buf, 0, 0, 0)) ||
+ (filter->start_from != -1 && tstart < filter->start_from) ||
+ (filter->start_to != -1 && tstart > filter->start_to) ||
+ (filter->end_from != -1 && tend < filter->end_from) ||
+ (filter->end_to != -1 && tend > filter->end_to)
+ );
+ if (filter->hash) {
+ apt = apoint_new(
+ buf, note, tstart, tend - tstart, state);
+ char *hash = apoint_hash(apt);
+ cond = cond || !hash_matches(filter->hash, hash);
+ mem_free(hash);
+ }
- /* Filter by hash. */
- if (filter && filter->hash) {
- char *hash = apoint_hash(apt);
- if (!hash_matches(filter->hash, hash)) {
- apoint_delete(apt);
- apt = NULL;
+ if ((!filter->invert && cond) || (filter->invert && !cond)) {
+ if (filter->hash)
+ apoint_delete(apt);
+ return NULL;
}
- mem_free(hash);
}
+ if (!apt)
+ apt = apoint_new(buf, note, tstart, tend - tstart, state);
return apt;
}
diff --git a/src/args.c b/src/args.c
index 118ddc1..d2e4860 100644
--- a/src/args.c
+++ b/src/args.c
@@ -54,7 +54,8 @@ enum {
/* Long options */
enum {
- OPT_FILTER_TYPE = 1000,
+ OPT_FILTER_INVERT = 1000,
+ OPT_FILTER_TYPE,
OPT_FILTER_HASH,
OPT_FILTER_PATTERN,
OPT_FILTER_START_FROM,
@@ -410,7 +411,7 @@ int parse_args(int argc, char **argv)
int range = 0;
int limit = INT_MAX;
/* Filters */
- struct item_filter filter = { 0, NULL, NULL, -1, -1, -1, -1, 0, 0, 0 };
+ struct item_filter filter = { 0, 0, NULL, NULL, -1, -1, -1, -1, 0, 0, 0 };
/* Format strings */
const char *fmt_apt = NULL;
const char *fmt_rapt = NULL;
@@ -457,6 +458,7 @@ int parse_args(int argc, char **argv)
{"quiet", no_argument, NULL, 'q'},
{"query", optional_argument, NULL, 'Q'},
+ {"filter-invert", no_argument, NULL, OPT_FILTER_INVERT},
{"filter-type", required_argument, NULL, OPT_FILTER_TYPE},
{"filter-hash", required_argument, NULL, OPT_FILTER_HASH},
{"filter-pattern", required_argument, NULL, OPT_FILTER_PATTERN},
@@ -623,6 +625,10 @@ int parse_args(int argc, char **argv)
case 'Q':
query = 1;
break;
+ case OPT_FILTER_INVERT:
+ filter.invert = !filter.invert;
+ filter_opt = 1;
+ break;
case OPT_FILTER_TYPE:
filter.type_mask = parse_type_mask(optarg);
EXIT_IF(filter.type_mask == 0,
diff --git a/src/calcurse.h b/src/calcurse.h
index c6ddc8d..40e253e 100644
--- a/src/calcurse.h
+++ b/src/calcurse.h
@@ -427,6 +427,7 @@ enum item_type {
/* Filter settings. */
struct item_filter {
+ int invert;
int type_mask;
char *hash;
regex_t *regex;
diff --git a/src/event.c b/src/event.c
index fe8f883..65af662 100644
--- a/src/event.c
+++ b/src/event.c
@@ -152,7 +152,8 @@ struct event *event_scan(FILE * f, struct tm start, int id, char *note,
{
char buf[BUFSIZ], *nl;
time_t tstart, tend;
- struct event *ev;
+ struct event *ev = NULL;
+ int cond;
EXIT_IF(!check_date(start.tm_year, start.tm_mon, start.tm_mday) ||
!check_time(start.tm_hour, start.tm_min),
@@ -179,31 +180,29 @@ struct event *event_scan(FILE * f, struct tm start, int id, char *note,
/* Filter item. */
if (filter) {
- if (!(filter->type_mask & TYPE_MASK_EVNT))
- return NULL;
- if (filter->regex && regexec(filter->regex, buf, 0, 0, 0))
- return NULL;
- if (filter->start_from != -1 && tstart < filter->start_from)
- return NULL;
- if (filter->start_to != -1 && tstart > filter->start_to)
- return NULL;
- if (filter->end_from != -1 && tend < filter->end_from)
- return NULL;
- if (filter->end_to != -1 && tend > filter->end_to)
- return NULL;
- }
-
- ev = event_new(buf, note, tstart, id);
+ cond = (
+ !(filter->type_mask & TYPE_MASK_EVNT) ||
+ (filter->regex && regexec(filter->regex, buf, 0, 0, 0)) ||
+ (filter->start_from != -1 && tstart < filter->start_from) ||
+ (filter->start_to != -1 && tstart > filter->start_to) ||
+ (filter->end_from != -1 && tend < filter->end_from) ||
+ (filter->end_to != -1 && tend > filter->end_to)
+ );
+ if (filter->hash) {
+ ev = event_new(buf, note, tstart, id);
+ char *hash = event_hash(ev);
+ cond = cond || !hash_matches(filter->hash, hash);
+ mem_free(hash);
+ }
- /* Filter by hash. */
- if (filter && filter->hash) {
- char *hash = event_hash(ev);
- if (!hash_matches(filter->hash, hash)) {
- event_delete(ev);
- ev = NULL;
+ if ((!filter->invert && cond) || (filter->invert && !cond)) {
+ if (filter->hash)
+ event_delete(ev);
+ return NULL;
}
- mem_free(hash);
}
+ if (!ev)
+ ev = event_new(buf, note, tstart, id);
return ev;
}
diff --git a/src/io.c b/src/io.c
index 0e7baea..27c6a31 100644
--- a/src/io.c
+++ b/src/io.c
@@ -707,8 +707,7 @@ void io_load_todo(struct item_filter *filter)
{
FILE *data_file;
char *newline;
- int nb_tod = 0;
- int c, id, completed;
+ int c, id, completed, cond;
char buf[BUFSIZ], e_todo[BUFSIZ], note[MAX_NOTESIZ + 1];
unsigned line = 0;
@@ -760,34 +759,31 @@ void io_load_todo(struct item_filter *filter)
io_extract_data(e_todo, buf, sizeof buf);
/* Filter item. */
+ struct todo *todo = NULL;
if (filter) {
- if (!(filter->type_mask & TYPE_MASK_TODO))
- continue;
- if (filter->regex &&
- regexec(filter->regex, e_todo, 0, 0, 0))
- continue;
- if (filter->priority && id != filter->priority)
- continue;
- if (filter->completed && !completed)
- continue;
- if (filter->uncompleted && completed)
- continue;
- }
-
- struct todo *todo = todo_add(e_todo, id, completed, note);
+ cond = (
+ !(filter->type_mask & TYPE_MASK_TODO) ||
+ (filter->regex && regexec(filter->regex, e_todo, 0, 0, 0)) ||
+ (filter->priority && id != filter->priority) ||
+ (filter->completed && !completed) ||
+ (filter->uncompleted && completed)
+ );
+ if (filter->hash) {
+ todo = todo_add(e_todo, id, completed, note);
+ char *hash = todo_hash(todo);
+ cond = cond || !hash_matches(filter->hash, hash);
+ mem_free(hash);
+ }
- /* Filter by hash. */
- if (filter && filter->hash) {
- char *hash = todo_hash(todo);
- if (!hash_matches(filter->hash, hash)) {
- todo_delete(todo);
- todo = NULL;
+ if ((!filter->invert && cond) || (filter->invert && !cond)) {
+ if (filter->hash)
+ todo_delete(todo);
+ continue;
}
- mem_free(hash);
}
- if (todo)
- ++nb_tod;
+ if (!todo)
+ todo = todo_add(e_todo, id, completed, note);
}
file_close(data_file, __FILE_POS__);
}
diff --git a/src/recur.c b/src/recur.c
index ca99a21..e481c08 100644
--- a/src/recur.c
+++ b/src/recur.c
@@ -349,7 +349,8 @@ struct recur_apoint *recur_apoint_scan(FILE * f, struct tm start,
{
char buf[BUFSIZ], *nl;
time_t tstart, tend, tuntil;
- struct recur_apoint *rapt;
+ struct recur_apoint *rapt = NULL;
+ int cond;
EXIT_IF(!check_date(start.tm_year, start.tm_mon, start.tm_mday) ||
!check_date(end.tm_year, end.tm_mon, end.tm_mday) ||
@@ -393,32 +394,34 @@ struct recur_apoint *recur_apoint_scan(FILE * f, struct tm start,
/* Filter item. */
if (filter) {
- if (!(filter->type_mask & TYPE_MASK_RECUR_APPT))
- return NULL;
- if (filter->regex && regexec(filter->regex, buf, 0, 0, 0))
- return NULL;
- if (filter->start_from != -1 && tstart < filter->start_from)
- return NULL;
- if (filter->start_to != -1 && tstart > filter->start_to)
- return NULL;
- if (filter->end_from != -1 && tend < filter->end_from)
- return NULL;
- if (filter->end_to != -1 && tend > filter->end_to)
- return NULL;
- }
-
- rapt = recur_apoint_new(buf, note, tstart, tend - tstart, state,
- recur_char2def(type), freq, tuntil, exc);
+ cond = (
+ !(filter->type_mask & TYPE_MASK_RECUR_APPT) ||
+ (filter->regex && regexec(filter->regex, buf, 0, 0, 0)) ||
+ (filter->start_from != -1 && tstart < filter->start_from) ||
+ (filter->start_to != -1 && tstart > filter->start_to) ||
+ (filter->end_from != -1 && tend < filter->end_from) ||
+ (filter->end_to != -1 && tend > filter->end_to)
+ );
+ if (filter->hash) {
+ rapt = recur_apoint_new(buf, note, tstart,
+ tend - tstart, state,
+ recur_char2def(type),
+ freq, tuntil, exc);
+ char *hash = recur_apoint_hash(rapt);
+ cond = cond || !hash_matches(filter->hash, hash);
+ mem_free(hash);
+ }
- /* Filter by hash. */
- if (filter && filter->hash) {
- char *hash = recur_apoint_hash(rapt);
- if (!hash_matches(filter->hash, hash)) {
- recur_apoint_erase(rapt);
- rapt = NULL;
+ if ((!filter->invert && cond) || (filter->invert && !cond)) {
+ if (filter->hash)
+ recur_apoint_erase(rapt);
+ return NULL;
}
- mem_free(hash);
}
+ if (!rapt)
+ rapt = recur_apoint_new(buf, note, tstart, tend - tstart,
+ state, recur_char2def(type), freq,
+ tuntil, exc);
return rapt;
}
@@ -431,7 +434,8 @@ struct recur_event *recur_event_scan(FILE * f, struct tm start, int id,
{
char buf[BUFSIZ], *nl;
time_t tstart, tend, tuntil;
- struct recur_event *rev;
+ struct recur_event *rev = NULL;
+ int cond;
EXIT_IF(!check_date(start.tm_year, start.tm_mon, start.tm_mday) ||
!check_time(start.tm_hour, start.tm_min) ||
@@ -466,32 +470,33 @@ struct recur_event *recur_event_scan(FILE * f, struct tm start, int id,
/* Filter item. */
if (filter) {
- if (!(filter->type_mask & TYPE_MASK_RECUR_EVNT))
- return NULL;
- if (filter->regex && regexec(filter->regex, buf, 0, 0, 0))
- return NULL;
- if (filter->start_from != -1 && tstart < filter->start_from)
- return NULL;
- if (filter->start_to != -1 && tstart > filter->start_to)
- return NULL;
- if (filter->end_from != -1 && tend < filter->end_from)
- return NULL;
- if (filter->end_to != -1 && tend > filter->end_to)
- return NULL;
- }
-
- rev = recur_event_new(buf, note, tstart, id, recur_char2def(type),
- freq, tuntil, exc);
+ cond = (
+ !(filter->type_mask & TYPE_MASK_RECUR_EVNT) ||
+ (filter->regex && regexec(filter->regex, buf, 0, 0, 0)) ||
+ (filter->start_from != -1 && tstart < filter->start_from) ||
+ (filter->start_to != -1 && tstart > filter->start_to) ||
+ (filter->end_from != -1 && tend < filter->end_from) ||
+ (filter->end_to != -1 && tend > filter->end_to)
+ );
+ if (filter->hash) {
+ rev = recur_event_new(buf, note, tstart, id,
+ recur_char2def(type),
+ freq, tuntil, exc);
+ char *hash = recur_event_hash(rev);
+ cond = cond || !hash_matches(filter->hash, hash);
+ mem_free(hash);
+ }
- /* Filter by hash. */
- if (filter && filter->hash) {
- char *hash = recur_event_hash(rev);
- if (!hash_matches(filter->hash, hash)) {
- recur_event_erase(rev);
- rev = NULL;
+ if ((!filter->invert && cond) || (filter->invert && !cond)) {
+ if (filter->hash)
+ recur_event_erase(rev);
+ return NULL;
}
- mem_free(hash);
}
+ if (!rev)
+ rev = recur_event_new(buf, note, tstart, id,
+ recur_char2def(type),
+ freq, tuntil, exc);
return rev;
}