From c2a9292bf457b3119c4e141d28d6c629d08de71d Mon Sep 17 00:00:00 2001
From: Lukas Fleischer <calcurse@cryptocrack.de>
Date: Thu, 7 Aug 2014 16:34:48 +0200
Subject: Add a grep mode

This allows for printing a subset of the items in the data files by
using filters.

Signed-off-by: Lukas Fleischer <calcurse@cryptocrack.de>
---
 src/args.c | 21 ++++++++++++++++++---
 src/io.c   | 32 ++++++++++++++++++++++----------
 2 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/src/args.c b/src/args.c
index 17b3c10..4ef644d 100644
--- a/src/args.c
+++ b/src/args.c
@@ -365,7 +365,8 @@ cleanup:
 int parse_args(int argc, char **argv)
 {
 	/* Command-line flags */
-	int status = 0, query = 0, next = 0, gc = 0, import = 0, export = 0;
+	int grep = 0, query = 0, next = 0;
+	int status = 0, gc = 0, import = 0, export = 0;
 	/* Query ranges */
 	long from = -1, range = -1, to = -1;
 	int limit = INT_MAX;
@@ -386,7 +387,7 @@ int parse_args(int argc, char **argv)
 	int ch;
 	regex_t reg;
 
-	static const char *optstr = "ghvnNax::t::d:c:r::s::S:D:i:l:Q";
+	static const char *optstr = "gGhvnNax::t::d:c:r::s::S:D:i:l:Q";
 
 	struct option longopts[] = {
 		{"appointment", no_argument, NULL, 'a'},
@@ -394,6 +395,7 @@ int parse_args(int argc, char **argv)
 		{"day", required_argument, NULL, 'd'},
 		{"directory", required_argument, NULL, 'D'},
 		{"gc", no_argument, NULL, 'g'},
+		{"grep", no_argument, NULL, 'G'},
 		{"help", no_argument, NULL, 'h'},
 		{"import", required_argument, NULL, 'i'},
 		{"limit", required_argument, NULL, 'l'},
@@ -463,6 +465,9 @@ int parse_args(int argc, char **argv)
 		case 'g':
 			gc = 1;
 			break;
+		case 'G':
+			grep = 1;
+			break;
 		case 'i':
 			import = 1;
 			ifile = optarg;
@@ -629,7 +634,7 @@ int parse_args(int argc, char **argv)
 	if (filter.type_mask == 0)
 		filter.type_mask = TYPE_MASK_ALL;
 
-	if (status + query + next + gc + import + export > 1) {
+	if (status + grep + query + next + gc + import + export > 1) {
 		ERROR_MSG(_("invalid argument combination"));
 		usage();
 		usage_try();
@@ -654,6 +659,16 @@ int parse_args(int argc, char **argv)
 
 	if (status) {
 		status_arg();
+	} else if (grep) {
+		io_check_file(path_apts);
+		io_check_file(path_todo);
+		io_check_file(path_conf);
+		vars_init();
+		config_load();	/* To get output date format. */
+		io_load_app(&filter);
+		io_load_todo(&filter);
+		io_save_todo(NULL);
+		io_save_apts(NULL);
 	} else if (query) {
 		io_check_file(path_apts);
 		io_check_file(path_todo);
diff --git a/src/io.c b/src/io.c
index a6f5958..dca23d1 100644
--- a/src/io.c
+++ b/src/io.c
@@ -303,11 +303,15 @@ unsigned io_save_apts(const char *aptsfile)
 	llist_item_t *i;
 	FILE *fp;
 
-	if (read_only)
-		return 1;
+	if (aptsfile) {
+		if (read_only)
+			return 1;
 
-	if ((fp = fopen(aptsfile, "w")) == NULL)
-		return 0;
+		if ((fp = fopen(aptsfile, "w")) == NULL)
+			return 0;
+	} else {
+		fp = stdout;
+	}
 
 	recur_save_data(fp);
 
@@ -324,7 +328,9 @@ unsigned io_save_apts(const char *aptsfile)
 		struct event *ev = LLIST_TS_GET_DATA(i);
 		event_write(ev, fp);
 	}
-	file_close(fp, __FILE_POS__);
+
+	if (aptsfile)
+		file_close(fp, __FILE_POS__);
 
 	return 1;
 }
@@ -335,17 +341,23 @@ unsigned io_save_todo(const char *todofile)
 	llist_item_t *i;
 	FILE *fp;
 
-	if (read_only)
-		return 1;
+	if (todofile) {
+		if (read_only)
+			return 1;
 
-	if ((fp = fopen(todofile, "w")) == NULL)
-		return 0;
+		if ((fp = fopen(todofile, "w")) == NULL)
+			return 0;
+	} else {
+		fp = stdout;
+	}
 
 	LLIST_FOREACH(&todolist, i) {
 		struct todo *todo = LLIST_TS_GET_DATA(i);
 		todo_write(todo, fp);
 	}
-	file_close(fp, __FILE_POS__);
+
+	if (todofile)
+		file_close(fp, __FILE_POS__);
 
 	return 1;
 }
-- 
cgit v1.2.3-70-g09d2