Simplified the way data are loaded and saved.

This commit is contained in:
Frederic Culot 2009-06-28 09:53:16 +00:00
parent 68381c95df
commit 6d67689b4f
4 changed files with 238 additions and 203 deletions

View File

@ -1,3 +1,15 @@
2009-06-28 Frederic Culot <frederic@culot.org>
* src/io.c (io_save_apts, io_save_conf, io_save_todo)
(io_save_keys): new functions
* src/args.c (parse_args): simplified the way data files are
loaded and saved
* src/args.c: it is now possible to export data from a given
apts file even if the user does not have any home directory
(thanks Ben for reporting this bug)
2009-06-27 Frederic Culot <frederic@culot.org> 2009-06-27 Frederic Culot <frederic@culot.org>
* src/io.c: do not export completed tasks * src/io.c: do not export completed tasks

View File

@ -1,4 +1,4 @@
/* $calcurse: args.c,v 1.50 2009/06/28 07:30:11 culot Exp $ */ /* $calcurse: args.c,v 1.51 2009/06/28 09:53:17 culot Exp $ */
/* /*
* Calcurse - text-based organizer * Calcurse - text-based organizer
@ -621,7 +621,6 @@ parse_args (int argc, char **argv, conf_t *conf)
int xflag = 0; /* -x: export data */ int xflag = 0; /* -x: export data */
int tnum = 0, xfmt = 0, non_interactive = 0, multiple_flag = 0, load_data = 0; int tnum = 0, xfmt = 0, non_interactive = 0, multiple_flag = 0, load_data = 0;
int no_file = 1;
char *ddate = "", *cfile = NULL, *range = NULL, *startday = NULL; char *ddate = "", *cfile = NULL, *range = NULL, *startday = NULL;
char *datadir = NULL, *ifile = NULL; char *datadir = NULL, *ifile = NULL;
@ -651,18 +650,18 @@ parse_args (int argc, char **argv, conf_t *conf)
case 'a': case 'a':
aflag = 1; aflag = 1;
multiple_flag++; multiple_flag++;
load_data++; load_data++;
break; break;
case 'c': case 'c':
cflag = 1; cflag = 1;
multiple_flag++; multiple_flag++;
load_data++;
cfile = optarg; cfile = optarg;
load_data++;
break; break;
case 'd': case 'd':
dflag = 1; dflag = 1;
multiple_flag++; multiple_flag++;
load_data++; load_data++;
ddate = optarg; ddate = optarg;
break; break;
case 'D': case 'D':
@ -675,13 +674,13 @@ parse_args (int argc, char **argv, conf_t *conf)
case 'i': case 'i':
iflag = 1; iflag = 1;
multiple_flag++; multiple_flag++;
load_data++; load_data++;
ifile = optarg; ifile = optarg;
break; break;
case 'n': case 'n':
nflag = 1; nflag = 1;
multiple_flag++; multiple_flag++;
load_data++; load_data++;
break; break;
case 'N': case 'N':
Nflag = 1; Nflag = 1;
@ -701,7 +700,7 @@ parse_args (int argc, char **argv, conf_t *conf)
case 't': case 't':
tflag = 1; tflag = 1;
multiple_flag++; multiple_flag++;
load_data++; load_data++;
add_line = 1; add_line = 1;
if (optarg != NULL) if (optarg != NULL)
{ {
@ -722,7 +721,7 @@ parse_args (int argc, char **argv, conf_t *conf)
case 'x': case 'x':
xflag = 1; xflag = 1;
multiple_flag++; multiple_flag++;
load_data++; load_data++;
if (optarg != NULL) if (optarg != NULL)
{ {
if (strcmp (optarg, "ical") == 0) if (strcmp (optarg, "ical") == 0)
@ -790,25 +789,18 @@ parse_args (int argc, char **argv, conf_t *conf)
if (load_data) if (load_data)
{ {
io_init (cfile, datadir); io_init (cfile, datadir);
no_file = io_check_data_files ();
if (dflag || aflag || nflag || iflag || xflag || rflag || sflag)
{
vars_init (conf);
custom_load_conf (conf, 0);
io_load_keys (conf->pager);
io_load_app ();
}
} }
if (iflag) if (iflag)
{ {
notify_init_vars (); io_check_file (path_apts, (int *)0);
io_load_app ();
io_import_data (IO_IMPORT_ICAL, conf, ifile); io_import_data (IO_IMPORT_ICAL, conf, ifile);
io_save_cal (conf, IO_SAVE_DISPLAY_NONE); io_save_apts ();
non_interactive = 1; non_interactive = 1;
} }
if (xflag) if (xflag)
{ {
notify_init_vars (); io_load_app ();
io_export_data (xfmt, conf); io_export_data (xfmt, conf);
non_interactive = 1; non_interactive = 1;
return non_interactive; return non_interactive;
@ -821,12 +813,13 @@ parse_args (int argc, char **argv, conf_t *conf)
} }
if (nflag) if (nflag)
{ {
io_load_app ();
next_arg (); next_arg ();
non_interactive = 1; non_interactive = 1;
} }
if (dflag || rflag || sflag) if (dflag || rflag || sflag)
{ {
notify_init_vars (); io_load_app ();
if (dflag) if (dflag)
date_arg (ddate, add_line, Nflag, conf); date_arg (ddate, add_line, Nflag, conf);
if (rflag || sflag) if (rflag || sflag)
@ -836,8 +829,11 @@ parse_args (int argc, char **argv, conf_t *conf)
else if (aflag) else if (aflag)
{ {
date_t day; date_t day;
vars_init (conf);
custom_load_conf (conf, 0); /* To get output date format. */
io_load_app ();
day.dd = day.mm = day.yyyy = 0; day.dd = day.mm = day.yyyy = 0;
notify_init_vars ();
app_found = app_arg (add_line, &day, 0, Nflag, conf); app_found = app_arg (add_line, &day, 0, Nflag, conf);
non_interactive = 1; non_interactive = 1;
} }
@ -845,8 +841,7 @@ parse_args (int argc, char **argv, conf_t *conf)
else else
{ {
non_interactive = 0; non_interactive = 0;
io_init (cfile, datadir); io_init (cfile, datadir);
no_file = io_check_data_files ();
} }
} }
return non_interactive; return non_interactive;

367
src/io.c
View File

@ -1,4 +1,4 @@
/* $calcurse: io.c,v 1.63 2009/06/27 08:38:56 culot Exp $ */ /* $calcurse: io.c,v 1.64 2009/06/28 09:53:17 culot Exp $ */
/* /*
* Calcurse - text-based organizer * Calcurse - text-based organizer
@ -783,16 +783,10 @@ display_mark (void)
static pthread_mutex_t io_save_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t io_save_mutex = PTHREAD_MUTEX_INITIALIZER;
/* Save the calendar data */ /* Save the user configuration. */
void unsigned
io_save_cal (conf_t *conf, io_save_display_t display) io_save_conf (conf_t *conf)
{ {
FILE *data_file;
struct event_s *k;
apoint_llist_node_t *j;
struct todo_s *i;
char theme_name[BUFSIZ];
char *access_pb = _("Problems accessing data file ...");
char *config_txt = char *config_txt =
"#\n" "#\n"
"# Calcurse configuration file\n#\n" "# Calcurse configuration file\n#\n"
@ -803,186 +797,214 @@ io_save_cal (conf_t *conf, io_save_display_t display)
"# For a variable to be unset its value must be blank.\n" "# For a variable to be unset its value must be blank.\n"
"# To set a variable to the empty string its value should be \"\".\n" "# To set a variable to the empty string its value should be \"\".\n"
"# Lines beginning with \"#\" are comments, and ignored by Calcurse.\n"; "# Lines beginning with \"#\" are comments, and ignored by Calcurse.\n";
char theme_name[BUFSIZ];
FILE *fp;
if ((fp = fopen (path_conf, "w")) == 0)
return 0;
custom_color_theme_name (theme_name);
(void)fprintf (fp, "%s\n", config_txt);
(void)fprintf (fp, "# If this option is set to yes, "
"automatic save is done when quitting\n");
(void)fprintf (fp, "auto_save=\n");
(void)fprintf (fp, "%s\n", (conf->auto_save) ? "yes" : "no");
(void)fprintf (fp, "\n# If not null, perform automatic saves every "
"'periodic_save' minutes\n");
(void)fprintf (fp, "periodic_save=\n");
(void)fprintf (fp, "%d\n", conf->periodic_save);
(void)fprintf (fp, "\n# If this option is set to yes, "
"confirmation is required before quitting\n");
(void)fprintf (fp, "confirm_quit=\n");
(void)fprintf (fp, "%s\n", (conf->confirm_quit) ? "yes" : "no");
(void)fprintf (fp, "\n# If this option is set to yes, "
"confirmation is required before deleting an event\n");
(void)fprintf (fp, "confirm_delete=\n");
(void)fprintf (fp, "%s\n", (conf->confirm_delete) ? "yes" : "no");
(void)fprintf (fp, "\n# If this option is set to yes, "
"messages about loaded and saved data will not be displayed\n");
(void)fprintf (fp, "skip_system_dialogs=\n");
(void)fprintf (fp, "%s\n", (conf->skip_system_dialogs) ? "yes" : "no");
(void)fprintf (fp,
"\n# If this option is set to yes, progress bar appearing "
"when saving data will not be displayed\n");
(void)fprintf (fp, "skip_progress_bar=\n");
(void)fprintf (fp, "%s\n", (conf->skip_progress_bar) ? "yes" : "no");
(void)fprintf (fp, "\n# If this option is set to yes, "
"monday is the first day of the week, else it is sunday\n");
(void)fprintf (fp, "week_begins_on_monday=\n");
(void)fprintf (fp, "%s\n",
(calendar_week_begins_on_monday ())? "yes" : "no");
(void)fprintf (fp, "\n# This is the color theme used for menus :\n");
(void)fprintf (fp, "color-theme=\n");
(void)fprintf (fp, "%s\n", theme_name);
(void)fprintf (fp, "\n# This is the layout of the calendar :\n");
(void)fprintf (fp, "layout=\n");
(void)fprintf (fp, "%d\n", wins_layout ());
if (ui_mode == UI_CURSES)
pthread_mutex_lock (&nbar.mutex);
(void)fprintf (fp,
"\n# If this option is set to yes, "
"notify-bar will be displayed :\n");
(void)fprintf (fp, "notify-bar_show=\n");
(void)fprintf (fp, "%s\n", (nbar.show) ? "yes" : "no");
(void)fprintf (fp,
"\n# Format of the date to be displayed inside notify-bar :\n");
(void)fprintf (fp, "notify-bar_date=\n");
(void)fprintf (fp, "%s\n", nbar.datefmt);
(void)fprintf (fp,
"\n# Format of the time to be displayed inside notify-bar :\n");
(void)fprintf (fp, "notify-bar_clock=\n");
(void)fprintf (fp, "%s\n", nbar.timefmt);
(void)fprintf (fp,
"\n# Warn user if he has an appointment within next "
"'notify-bar_warning' seconds :\n");
(void)fprintf (fp, "notify-bar_warning=\n");
(void)fprintf (fp, "%d\n", nbar.cntdwn);
(void)fprintf (fp, "\n# Command used to notify user of "
"an upcoming appointment :\n");
(void)fprintf (fp, "notify-bar_command=\n");
(void)fprintf (fp, "%s\n", nbar.cmd);
(void)fprintf (fp, "\n# Format of the date to be displayed "
"in non-interactive mode :\n");
(void)fprintf (fp, "output_datefmt=\n");
(void)fprintf (fp, "%s\n", conf->output_datefmt);
(void)fprintf (fp, "\n# Format to be used when entering a date "
"(1)mm/dd/yyyy (2)dd/mm/yyyy (3)yyyy/mm/dd) "
"(4)yyyy-mm-dd:\n");
(void)fprintf (fp, "input_datefmt=\n");
(void)fprintf (fp, "%d\n", conf->input_datefmt);
if (ui_mode == UI_CURSES)
pthread_mutex_unlock (&nbar.mutex);
file_close (fp, __FILE_POS__);
return 1;
}
/*
* Save the apts data file, which contains the
* appointments first, and then the events.
* Recursive items are written first.
*/
unsigned
io_save_apts (void)
{
apoint_llist_node_t *a;
struct event_s *e;
FILE *fp;
if ((fp = fopen (path_apts, "w")) == 0)
return 0;
recur_save_data (fp);
if (ui_mode == UI_CURSES)
pthread_mutex_lock (&(alist_p->mutex));
for (a = alist_p->root; a != 0; a = a->next)
apoint_write (a, fp);
if (ui_mode == UI_CURSES)
pthread_mutex_unlock (&(alist_p->mutex));
for (e = eventlist; e != 0; e = e->next)
event_write (e, fp);
file_close (fp, __FILE_POS__);
return 1;
}
/* Save the todo data file. */
unsigned
io_save_todo (void)
{
struct todo_s *t;
FILE *fp;
if ((fp = fopen (path_todo, "w")) == 0)
return 0;
for (t = todolist; t != 0; t = t->next)
{
if (t->note)
(void)fprintf (fp, "[%d]>%s %s\n", t->id, t->note, t->mesg);
else
(void)fprintf (fp, "[%d] %s\n", t->id, t->mesg);
}
file_close (fp, __FILE_POS__);
return 1;
}
/* Save user-defined keys */
unsigned
io_save_keys (void)
{
FILE *fp;
if ((fp = fopen (path_keys, "w")) == 0)
return 0;
keys_save_bindings (fp);
file_close (fp, __FILE_POS__);
return 1;
}
/* Save the calendar data */
void
io_save_cal (conf_t *conf, io_save_display_t display)
{
char *access_pb = _("Problems accessing data file ...");
char *save_success = _("The data files were successfully saved"); char *save_success = _("The data files were successfully saved");
char *enter = _("Press [ENTER] to continue"); char *enter = _("Press [ENTER] to continue");
bool show_bar = false; int show_bar;
pthread_mutex_lock (&io_save_mutex); pthread_mutex_lock (&io_save_mutex);
show_bar = 0;
if (ui_mode == UI_CURSES && display == IO_SAVE_DISPLAY_BAR if (ui_mode == UI_CURSES && display == IO_SAVE_DISPLAY_BAR
&& !conf->skip_progress_bar) && !conf->skip_progress_bar)
show_bar = true; show_bar = 1;
else if (ui_mode == UI_CURSES && display == IO_SAVE_DISPLAY_MARK) else if (ui_mode == UI_CURSES && display == IO_SAVE_DISPLAY_MARK)
display_mark (); display_mark ();
/* Save the user configuration. */
if (show_bar) if (show_bar)
progress_bar (PROGRESS_BAR_SAVE, PROGRESS_BAR_CONF); progress_bar (PROGRESS_BAR_SAVE, PROGRESS_BAR_CONF);
if (!io_save_conf (conf))
data_file = fopen (path_conf, "w");
if (data_file == NULL)
ERROR_MSG ("%s", access_pb); ERROR_MSG ("%s", access_pb);
else
{
custom_color_theme_name (theme_name);
(void)fprintf (data_file, "%s\n", config_txt);
(void)fprintf (data_file,
"# If this option is set to yes, "
"automatic save is done when quitting\n");
(void)fprintf (data_file, "auto_save=\n");
(void)fprintf (data_file, "%s\n", (conf->auto_save) ? "yes" : "no");
(void)fprintf (data_file,
"\n# If not null, perform automatic saves every "
"'periodic_save' minutes\n");
(void)fprintf (data_file, "periodic_save=\n");
(void)fprintf (data_file, "%d\n", conf->periodic_save);
(void)fprintf (data_file,
"\n# If this option is set to yes, "
"confirmation is required before quitting\n");
(void)fprintf (data_file, "confirm_quit=\n");
(void)fprintf (data_file, "%s\n", (conf->confirm_quit) ? "yes" : "no");
(void)fprintf (data_file,
"\n# If this option is set to yes, "
"confirmation is required before deleting an event\n");
(void)fprintf (data_file, "confirm_delete=\n");
(void)fprintf (data_file, "%s\n", (conf->confirm_delete) ? "yes" : "no");
(void)fprintf (data_file,
"\n# If this option is set to yes, "
"messages about loaded and saved data will not be displayed\n");
(void)fprintf (data_file, "skip_system_dialogs=\n");
(void)fprintf (data_file, "%s\n", (conf->skip_system_dialogs) ? "yes" : "no");
(void)fprintf (data_file,
"\n# If this option is set to yes, progress bar appearing "
"when saving data will not be displayed\n");
(void)fprintf (data_file, "skip_progress_bar=\n");
(void)fprintf (data_file, "%s\n", (conf->skip_progress_bar) ? "yes" : "no");
(void)fprintf (data_file,
"\n# If this option is set to yes, "
"monday is the first day of the week, else it is sunday\n");
(void)fprintf (data_file, "week_begins_on_monday=\n");
(void)fprintf (data_file, "%s\n",
(calendar_week_begins_on_monday ())? "yes" : "no");
(void)fprintf (data_file, "\n# This is the color theme used for menus :\n");
(void)fprintf (data_file, "color-theme=\n");
(void)fprintf (data_file, "%s\n", theme_name);
(void)fprintf (data_file, "\n# This is the layout of the calendar :\n");
(void)fprintf (data_file, "layout=\n");
(void)fprintf (data_file, "%d\n", wins_layout ());
if (ui_mode == UI_CURSES)
pthread_mutex_lock (&nbar.mutex);
(void)fprintf (data_file,
"\n# If this option is set to yes, "
"notify-bar will be displayed :\n");
(void)fprintf (data_file, "notify-bar_show=\n");
(void)fprintf (data_file, "%s\n", (nbar.show) ? "yes" : "no");
(void)fprintf (data_file,
"\n# Format of the date to be displayed inside notify-bar :\n");
(void)fprintf (data_file, "notify-bar_date=\n");
(void)fprintf (data_file, "%s\n", nbar.datefmt);
(void)fprintf (data_file,
"\n# Format of the time to be displayed inside notify-bar :\n");
(void)fprintf (data_file, "notify-bar_clock=\n");
(void)fprintf (data_file, "%s\n", nbar.timefmt);
(void)fprintf (data_file,
"\n# Warn user if he has an appointment within next "
"'notify-bar_warning' seconds :\n");
(void)fprintf (data_file, "notify-bar_warning=\n");
(void)fprintf (data_file, "%d\n", nbar.cntdwn);
(void)fprintf (data_file,
"\n# Command used to notify user of "
"an upcoming appointment :\n");
(void)fprintf (data_file, "notify-bar_command=\n");
(void)fprintf (data_file, "%s\n", nbar.cmd);
(void)fprintf (data_file,
"\n# Format of the date to be displayed "
"in non-interactive mode :\n");
(void)fprintf (data_file, "output_datefmt=\n");
(void)fprintf (data_file, "%s\n", conf->output_datefmt);
(void)fprintf (data_file,
"\n# Format to be used when entering a date "
"(1)mm/dd/yyyy (2)dd/mm/yyyy (3)yyyy/mm/dd) "
"(4)yyyy-mm-dd:\n");
(void)fprintf (data_file, "input_datefmt=\n");
(void)fprintf (data_file, "%d\n", conf->input_datefmt);
if (ui_mode == UI_CURSES)
pthread_mutex_unlock (&nbar.mutex);
file_close (data_file, __FILE_POS__);
}
/* Save the todo data file. */
if (show_bar) if (show_bar)
progress_bar (PROGRESS_BAR_SAVE, PROGRESS_BAR_TODO); progress_bar (PROGRESS_BAR_SAVE, PROGRESS_BAR_TODO);
data_file = fopen (path_todo, "w"); if (!io_save_todo ())
if (data_file == NULL)
ERROR_MSG ("%s", access_pb); ERROR_MSG ("%s", access_pb);
else
{
for (i = todolist; i != 0; i = i->next)
{
if (i->note != NULL)
(void)fprintf (data_file, "[%d]>%s %s\n", i->id, i->note, i->mesg);
else
(void)fprintf (data_file, "[%d] %s\n", i->id, i->mesg);
}
file_close (data_file, __FILE_POS__);
}
/*
* Save the apts data file, which contains the
* appointments first, and then the events.
* Recursive items are written first.
*/
if (show_bar) if (show_bar)
progress_bar (PROGRESS_BAR_SAVE, PROGRESS_BAR_APTS); progress_bar (PROGRESS_BAR_SAVE, PROGRESS_BAR_APTS);
data_file = fopen (path_apts, "w"); if (!io_save_apts ())
if (data_file == NULL)
ERROR_MSG ("%s", access_pb); ERROR_MSG ("%s", access_pb);
else
{
recur_save_data (data_file);
if (ui_mode == UI_CURSES)
pthread_mutex_lock (&(alist_p->mutex));
for (j = alist_p->root; j != 0; j = j->next)
apoint_write (j, data_file);
if (ui_mode == UI_CURSES)
pthread_mutex_unlock (&(alist_p->mutex));
for (k = eventlist; k != 0; k = k->next)
event_write (k, data_file);
file_close (data_file, __FILE_POS__);
}
/* Save user-defined keys */
if (show_bar) if (show_bar)
progress_bar (PROGRESS_BAR_SAVE, PROGRESS_BAR_KEYS); progress_bar (PROGRESS_BAR_SAVE, PROGRESS_BAR_KEYS);
data_file = fopen (path_keys, "w"); if (!io_save_keys ())
if (data_file == NULL)
ERROR_MSG ("%s", access_pb); ERROR_MSG ("%s", access_pb);
else
{
keys_save_bindings (data_file);
file_close (data_file, __FILE_POS__);
}
/* Print a message telling data were saved */ /* Print a message telling data were saved */
if (ui_mode == UI_CURSES && !conf->skip_system_dialogs if (ui_mode == UI_CURSES && !conf->skip_system_dialogs
@ -1432,15 +1454,16 @@ check_directory (char *dir, int *missing)
(*missing)++; (*missing)++;
} }
static void void
check_file (char *file, int *missing) io_check_file (char *file, int *missing)
{ {
FILE *fd; FILE *fd;
errno = 0; errno = 0;
if ((fd = fopen (file, "r")) == NULL) if ((fd = fopen (file, "r")) == NULL)
{ {
(*missing)++; if (missing)
(*missing)++;
if ((fd = fopen (file, "w")) == NULL) if ((fd = fopen (file, "w")) == NULL)
{ {
(void)fprintf (stderr, _("FATAL ERROR: could not create %s: %s\n"), (void)fprintf (stderr, _("FATAL ERROR: could not create %s: %s\n"),
@ -1472,10 +1495,10 @@ io_check_data_files (void)
errno = 0; errno = 0;
check_directory (path_dir, &missing); check_directory (path_dir, &missing);
check_directory (path_notes, &missing); check_directory (path_notes, &missing);
check_file (path_todo, &missing); io_check_file (path_todo, &missing);
check_file (path_apts, &missing); io_check_file (path_apts, &missing);
check_file (path_conf, &missing); io_check_file (path_conf, &missing);
check_file (path_keys, &missing_keys); io_check_file (path_keys, &missing_keys);
if (missing_keys) if (missing_keys)
{ {
missing++; missing++;

View File

@ -1,8 +1,8 @@
/* $calcurse: io.h,v 1.19 2009/06/21 18:16:22 culot Exp $ */ /* $calcurse: io.h,v 1.20 2009/06/28 09:53:17 culot Exp $ */
/* /*
* Calcurse - text-based organizer * Calcurse - text-based organizer
* Copyright (c) 2004-2008 Frederic Culot * Copyright (c) 2004-2009 Frederic Culot
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -53,10 +53,15 @@ typedef struct {
void io_init (char *, char *); void io_init (char *, char *);
void io_extract_data (char *, const char *, int); void io_extract_data (char *, const char *, int);
unsigned io_save_conf (conf_t *);
unsigned io_save_apts (void);
unsigned io_save_todo (void);
unsigned io_save_keys (void);
void io_save_cal (conf_t *, io_save_display_t); void io_save_cal (conf_t *, io_save_display_t);
void io_load_app (void); void io_load_app (void);
void io_load_todo (void); void io_load_todo (void);
void io_load_keys (char *); void io_load_keys (char *);
void io_check_file (char *, int *);
int io_check_data_files (void); int io_check_data_files (void);
void io_startup_screen (bool, int); void io_startup_screen (bool, int);
void io_export_data (export_type_t, conf_t *); void io_export_data (export_type_t, conf_t *);