From 5ad0019b2326e4012299e36682669ca767f39cd4 Mon Sep 17 00:00:00 2001
From: Lars Henriksen <LarsHenriksen@get2net.dk>
Date: Thu, 23 Aug 2018 20:45:38 +0200
Subject: Only reload if data files were changed (replacement)

This is a replacement for commits 57dd3d6 and 912124b.

The idea is to move the check for modified files and the list initialization
into io_load_data(), and let io_load_data() decide what to load. A new
argument is used to force a load.

The return code from new_data() (the renamed version of
io_check_data_files_modified()) tells which files have changed.

Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
---
 src/args.c     | 11 ++++---
 src/calcurse.c | 15 +---------
 src/calcurse.h |  4 ++-
 src/io.c       | 95 ++++++++++++++++++++++++++++++++++++----------------------
 4 files changed, 68 insertions(+), 57 deletions(-)

(limited to 'src')

diff --git a/src/args.c b/src/args.c
index 60de7da..9e22d8d 100644
--- a/src/args.c
+++ b/src/args.c
@@ -738,7 +738,7 @@ int parse_args(int argc, char **argv)
 		io_check_file(path_todo);
 		io_check_file(path_conf);
 		config_load();	/* To get output date format. */
-		io_load_data(&filter);
+		io_load_data(&filter, FORCE);
 		if (grep_filter) {
 			io_save_todo(path_todo);
 			io_save_apts(path_apts);
@@ -760,7 +760,7 @@ int parse_args(int argc, char **argv)
 		io_check_file(path_todo);
 		io_check_file(path_conf);
 		config_load();	/* To get output date format. */
-		io_load_data(&filter);
+		io_load_data(&filter, FORCE);
 
 		/* Use default values for non-specified format strings. */
 		fmt_apt = fmt_apt ? fmt_apt : " - %S -> %E\n\t%m\n";
@@ -779,13 +779,12 @@ int parse_args(int argc, char **argv)
 	} else if (gc) {
 		io_check_file(path_apts);
 		io_check_file(path_todo);
-		io_load_data(NULL);
+		io_load_data(NULL, FORCE);
 		note_gc();
 	} else if (import) {
 		io_check_file(path_apts);
 		io_check_file(path_todo);
-		/* Get default pager in case we need to show a log file. */
-		io_load_data(NULL);
+		io_load_data(NULL, FORCE);
 		if (dump_imported) {
 			/*
 			 * Use default values for non-specified format strings.
@@ -809,7 +808,7 @@ int parse_args(int argc, char **argv)
 	} else if (export) {
 		io_check_file(path_apts);
 		io_check_file(path_todo);
-		io_load_data(&filter);
+		io_load_data(&filter, FORCE);
 		io_export_data(xfmt, export_uid);
 	} else if (daemon) {
 		notify_init_vars();
diff --git a/src/calcurse.c b/src/calcurse.c
index 7739c0f..533f78c 100644
--- a/src/calcurse.c
+++ b/src/calcurse.c
@@ -551,15 +551,6 @@ int main(int argc, char **argv)
 	textdomain(PACKAGE);
 #endif /* ENABLE_NLS */
 
-	/* Thread-safe data structure init */
-	apoint_llist_init();
-	recur_apoint_llist_init();
-
-	/* Initialize non-thread-safe data structures. */
-	event_llist_init();
-	recur_event_llist_init();
-	todo_init_list();
-
 	/*
 	 * Begin by parsing and handling command line arguments.
 	 * The data path is also initialized here.
@@ -627,11 +618,7 @@ int main(int argc, char **argv)
 	config_load();
 	wins_erase_status_bar();
 	io_load_keys(conf.pager);
-
-	run_hook("pre-load");
-	io_load_data(NULL);
-	run_hook("post-load");
-
+	io_load_data(NULL, FORCE);
 	wins_slctd_set(conf.default_panel);
 	wins_resize();
 	/*
diff --git a/src/calcurse.h b/src/calcurse.h
index 9bb714c..ddeec21 100644
--- a/src/calcurse.h
+++ b/src/calcurse.h
@@ -172,6 +172,8 @@
 
 /* Mnemonics */
 #define NOHILT		0 	/* 'No highlight' argument */
+#define NOFORCE		0
+#define FORCE		1
 
 #define ERROR_MSG(...) do {                                                   \
   char msg[BUFSIZ];                                                           \
@@ -858,7 +860,7 @@ unsigned io_save_keys(void);
 int io_save_cal(enum save_display);
 void io_load_app(struct item_filter *);
 void io_load_todo(struct item_filter *);
-void io_load_data(struct item_filter *);
+void io_load_data(struct item_filter *, int);
 int io_reload_data(void);
 void io_load_keys(const char *);
 int io_check_dir(const char *);
diff --git a/src/io.c b/src/io.c
index 9ffd9a8..d21b1fc 100644
--- a/src/io.c
+++ b/src/io.c
@@ -503,7 +503,7 @@ static int resolve_save_conflict(void)
 {
 	char *msg_um_asktype = NULL;
 	const char *msg_um_prefix =
-			_("Data files were changed since loaded:");
+			_("Data have changed since loaded:");
 	const char *msg_um_overwrite = _("(o)verwrite");
 	const char *msg_um_merge = _("(m)erge");
 	const char *msg_um_keep = _("(c)ancel");
@@ -532,25 +532,37 @@ static int resolve_save_conflict(void)
 	return ret;
 }
 
-static int io_check_data_files_modified()
+/* Return codes for new_data(). */
+#define NONEW		0
+#define APTS		1
+#define TODO		2
+#define APTS_TODO	3
+#define NOKNOW		4
+static int new_data()
 {
 	char sha1_new[SHA1_DIGESTLEN * 2 + 1];
-	int ret = 1;
+	int ret = NONEW;
 
 	io_mutex_lock();
 
 	if (io_compute_hash(path_apts, sha1_new)) {
-		if (strncmp(sha1_new, apts_sha1, SHA1_DIGESTLEN * 2) != 0)
-			goto cleanup;
+		if (strncmp(sha1_new, apts_sha1, SHA1_DIGESTLEN * 2) != 0) {
+			ret |= APTS;
+		}
+	} else {
+		ret = NOKNOW;
+		goto cleanup;
 	}
 
 	if (io_compute_hash(path_todo, sha1_new)) {
-		if (strncmp(sha1_new, todo_sha1, SHA1_DIGESTLEN * 2) != 0)
-			goto cleanup;
+		if (strncmp(sha1_new, todo_sha1, SHA1_DIGESTLEN * 2) != 0) {
+			ret |= TODO;
+		}
+	} else {
+		ret = NOKNOW;
+		goto cleanup;
 	}
 
-	ret = 0;
-
 cleanup:
 	io_mutex_unlock();
 	return ret;
@@ -574,7 +586,7 @@ int io_save_cal(enum save_display display)
 	if (read_only)
 		return IO_SAVE_CANCEL;
 
-	if (io_check_data_files_modified() && (ret = resolve_save_conflict()))
+	if (new_data() && (ret = resolve_save_conflict()))
 		return ret;
 
 	run_hook("pre-save");
@@ -905,14 +917,42 @@ void io_load_todo(struct item_filter *filter)
 	file_close(data_file, __FILE_POS__);
 }
 
-/* Load appointments and todo items */
-void io_load_data(struct item_filter *filter)
+/*
+ * Load appointments and todo items.
+ * Unless told otherwise, the function will only load a file that has changed
+ * since last saved or loaded, see new_data() return codes.
+ */
+void io_load_data(struct item_filter *filter, int force)
 {
+	run_hook("pre-load");
+	if (force)
+		force = APTS_TODO;
+	else
+		force = new_data();
+
 	io_mutex_lock();
-	io_load_app(filter);
-	io_load_todo(filter);
-	io_mutex_unlock();
+
+	if (force & APTS) {
+		apoint_llist_free();
+		event_llist_free();
+		recur_apoint_llist_free();
+		recur_event_llist_free();
+		apoint_llist_init();
+		event_llist_init();
+		recur_apoint_llist_init();
+		recur_event_llist_init();
+		io_load_app(filter);
+	}
+	if (force & TODO) {
+		todo_free_list();
+		todo_init_list();
+		io_load_todo(filter);
+	}
+
 	io_unset_modified();
+
+	io_mutex_unlock();
+	run_hook("post-load");
 }
 
 int io_reload_data(void)
@@ -922,6 +962,7 @@ int io_reload_data(void)
 		_("The data files were reloaded successfully");
 	const char *enter = _("Press [ENTER] to continue");
 	int ret = 0;
+	int load = NOFORCE;
 
 	if (io_get_modified()) {
 		const char *msg_um_prefix =
@@ -936,9 +977,11 @@ int io_reload_data(void)
 
 		switch (status_ask_choice(msg_um_asktype, msg_um_choice, 3)) {
 		case 1:
+			load = FORCE;
 			break;
 		case 2:
 			io_merge_data();
+			load = FORCE;
 			break;
 		case 3:
 			/* FALLTHROUGH */
@@ -947,27 +990,7 @@ int io_reload_data(void)
 		}
 	}
 
-	run_hook("pre-load");
-
-	if (!io_check_data_files_modified())
-		goto cleanup;
-
-	/* Reinitialize data structures. */
-	apoint_llist_free();
-	event_llist_free();
-	recur_apoint_llist_free();
-	recur_event_llist_free();
-	todo_free_list();
-
-	apoint_llist_init();
-	event_llist_init();
-	recur_apoint_llist_init();
-	recur_event_llist_init();
-	todo_init_list();
-
-	io_load_data(NULL);
-
-	run_hook("post-load");
+	io_load_data(NULL, load);
 
 	if (show_dialogs()) {
 		status_mesg(reload_success, enter);
-- 
cgit v1.2.3-70-g09d2