diff options
author | Lars Henriksen <LarsHenriksen@get2net.dk> | 2017-12-29 20:59:53 +0100 |
---|---|---|
committer | Lukas Fleischer <lfleischer@calcurse.org> | 2019-01-07 16:57:48 +0100 |
commit | 3d7bb89c8886f6c318d26820ed4c0e6c25f9c959 (patch) | |
tree | d4733bdb3167356972511af71808c5b7e3ceb692 /src | |
parent | 215e90d348b10ffaa11b2a613388adc9285ea65a (diff) | |
download | calcurse-3d7bb89c8886f6c318d26820ed4c0e6c25f9c959.tar.gz calcurse-3d7bb89c8886f6c318d26820ed4c0e6c25f9c959.zip |
CLI: take input date format from configuration file, do not accept time
Before this patch the input date parsing accepts three formats:
yyyy/mm/dd, mm/dd/yyyy, yyyy-mm-dd. They are tried in sequence. It also
accepts an additional time (hh:mm), or a time without a date.
There are several issues with this:
- it is not documented
- the date format dd/mm/yyyy is not accepted
- print_date() and filter option settings (in parse_args()) can only
handle midnight times (which are the result of a date without time)
- it is highly uncertain what happens if a time (without a date) is
given; at least the -d option treats a time without colon (1215 for
12:15) as a number
It seems that acceptance of time input is a by-product and not needed.
For these reasons the input date parsing has been changed:
- the format is taken from the configuration file (as is the case for
the output date format)
- only a date, and no time, is accepted
Because the input date format is used during parsing of the command
line, the configuration file must be loaded first, i.e. the options -D
or -C must be parsed before the remaining ones. Loading the
configuration file may result in errors (e.g. caused by changes between
versions). For this reason config_load() has been made more tolerant and
issues warnings instead of exiting.
A followup patch will introduce two options to allow the configuration
file settings to be overridden for input and output date formats.
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/args.c | 115 | ||||
-rw-r--r-- | src/config.c | 7 |
2 files changed, 49 insertions, 73 deletions
@@ -274,57 +274,19 @@ date_arg_from_to(long from, long to, int add_line, const char *fmt_apt, } } +/* + * Convert a string with a date into the Unix time for midnight of that day. + * The date format is taken from the user configuration. + */ static time_t parse_datearg(const char *str) { struct date day; - if (parse_date(str, DATEFMT_YYYYMMDD, (int *)&day.yyyy, - (int *)&day.mm, (int *)&day.dd, NULL)) + if (parse_date(str, conf.input_datefmt, + (int *)&day.yyyy, (int *)&day.mm, (int *)&day.dd, NULL)) return date2sec(day, 0, 0); - - if (parse_date(str, DATEFMT_MMDDYYYY, (int *)&day.yyyy, - (int *)&day.mm, (int *)&day.dd, NULL)) - return date2sec(day, 0, 0); - - if (parse_date(str, DATEFMT_ISO, (int *)&day.yyyy, - (int *)&day.mm, (int *)&day.dd, NULL)) - return date2sec(day, 0, 0); - - return LONG_MAX; -} - -static time_t parse_datetimearg(const char *str) -{ - char *date = mem_strdup(str); - char *time; - unsigned hour, min; - time_t ret; - - time = strchr(date, ' '); - if (time) { - /* Date and time. */ - *time = '\0'; - time++; - - if (!parse_time(time, &hour, &min)) - return -1; - ret = parse_datearg(date); - if (ret == LONG_MAX) - return -1; - ret += hour * HOURINSEC + min * MININSEC; - - return ret; - } - - ret = parse_datearg(date); - if (ret == LONG_MAX) { - /* No date specified, use time only. */ - if (!parse_time(date, &hour, &min)) - return -1; - return get_today() + hour * HOURINSEC + min * MININSEC; - } - - return ret; + else + return -1; } static int parse_daterange(const char *str, time_t *date_from, time_t *date_to) @@ -340,7 +302,7 @@ static int parse_daterange(const char *str, time_t *date_from, time_t *date_to) p++; if (*s != '\0') { - *date_from = parse_datetimearg(s); + *date_from = parse_datearg(s); if (*date_from == -1) goto cleanup; } else { @@ -348,7 +310,7 @@ static int parse_daterange(const char *str, time_t *date_from, time_t *date_to) } if (*p != '\0') { - *date_to = parse_datetimearg(p); + *date_to = parse_datearg(p); if (*date_to == -1) goto cleanup; } else { @@ -395,10 +357,11 @@ cleanup: /* * Parse the command-line arguments and call the appropriate * routines to handle those arguments. Also initialize the data paths. + * Returns the non-interactive value. */ int parse_args(int argc, char **argv) { - /* Command-line flags */ + /* Command-line flags - NOTE that read_only is global */ int grep = 0, purge = 0, query = 0, next = 0; int status = 0, gc = 0, import = 0, export = 0, daemon = 0; int filter_opt = 0, format_opt = 0, query_range = 0; @@ -483,6 +446,28 @@ int parse_args(int argc, char **argv) {NULL, no_argument, NULL, 0} }; + /* + * Load the configuration file first to get the input date format for + * parsing the remaining options. + */ + while ((ch = getopt_long(argc, argv, optstr, longopts, NULL)) != -1) { + switch (ch) { + case 'C': + confdir = optarg; + break; + case 'D': + datadir = optarg; + break; + } + } + io_init(cfile, datadir, confdir); + vars_init(); + notify_init_vars(); + if (io_file_exists(path_conf)) + config_load(); + + /* Parse the remaining options. */ + optind = 1; while ((ch = getopt_long(argc, argv, optstr, longopts, NULL)) != -1) { switch (ch) { case 'a': @@ -491,9 +476,9 @@ int parse_args(int argc, char **argv) break; case 'c': cfile = optarg; + io_init(cfile, datadir, confdir); break; case 'C': - confdir = optarg; break; case 'd': if (is_all_digit(optarg) || @@ -502,7 +487,7 @@ int parse_args(int argc, char **argv) EXIT_IF(range == 0, _("invalid range: %s"), optarg); } else { - from = parse_datetimearg(optarg); + from = parse_datearg(optarg); EXIT_IF(from == -1, _("invalid date: %s"), optarg); } @@ -511,7 +496,6 @@ int parse_args(int argc, char **argv) query = 1; break; case 'D': - datadir = optarg; break; case 'F': purge = grep = 1; @@ -550,7 +534,7 @@ int parse_args(int argc, char **argv) case 's': if (!optarg) optarg = "today"; - from = parse_datetimearg(optarg); + from = parse_datearg(optarg); EXIT_IF(from == -1, _("invalid date: %s"), optarg); filter.type_mask |= TYPE_MASK_CAL; query = 1; @@ -613,25 +597,25 @@ int parse_args(int argc, char **argv) filter_opt = 1; break; case OPT_FILTER_START_FROM: - filter.start_from = parse_datetimearg(optarg); + filter.start_from = parse_datearg(optarg); EXIT_IF(filter.start_from == -1, _("invalid date: %s"), optarg); filter_opt = 1; break; case OPT_FILTER_START_TO: - filter.start_to = parse_datetimearg(optarg); + filter.start_to = parse_datearg(optarg); EXIT_IF(filter.start_to == -1, _("invalid date: %s"), optarg); filter_opt = 1; break; case OPT_FILTER_START_AFTER: - filter.start_from = parse_datetimearg(optarg) + 1; + filter.start_from = parse_datearg(optarg) + 1; EXIT_IF(filter.start_from == -1, _("invalid date: %s"), optarg); filter_opt = 1; break; case OPT_FILTER_START_BEFORE: - filter.start_to = parse_datetimearg(optarg) - 1; + filter.start_to = parse_datearg(optarg) - 1; EXIT_IF(filter.start_to == -1, _("invalid date: %s"), optarg); filter_opt = 1; @@ -643,25 +627,25 @@ int parse_args(int argc, char **argv) filter_opt = 1; break; case OPT_FILTER_END_FROM: - filter.end_from = parse_datetimearg(optarg); + filter.end_from = parse_datearg(optarg); EXIT_IF(filter.end_from == -1, _("invalid date: %s"), optarg); filter_opt = 1; break; case OPT_FILTER_END_TO: - filter.end_to = parse_datetimearg(optarg); + filter.end_to = parse_datearg(optarg); EXIT_IF(filter.end_to == -1, _("invalid date: %s"), optarg); filter_opt = 1; break; case OPT_FILTER_END_AFTER: - filter.end_from = parse_datetimearg(optarg) + 1; + filter.end_from = parse_datearg(optarg) + 1; EXIT_IF(filter.end_from == -1, _("invalid date: %s"), optarg); filter_opt = 1; break; case OPT_FILTER_END_BEFORE: - filter.end_to = parse_datetimearg(optarg) - 1; + filter.end_to = parse_datearg(optarg) - 1; EXIT_IF(filter.end_to == -1, _("invalid date: %s"), optarg); filter_opt = 1; @@ -687,12 +671,12 @@ int parse_args(int argc, char **argv) filter_opt = 1; break; case OPT_FROM: - from = parse_datetimearg(optarg); + from = parse_datearg(optarg); EXIT_IF(from == -1, _("invalid date: %s"), optarg); query_range = 1; break; case OPT_TO: - to = parse_datetimearg(optarg); + to = parse_datearg(optarg); EXIT_IF(to == -1, _("invalid date: %s"), optarg); query_range = 1; break; @@ -768,20 +752,17 @@ int parse_args(int argc, char **argv) else if (range < 0) from = date_sec_change(to, 0, range + 1); - io_init(cfile, datadir, confdir); io_check_dir(path_ddir); io_check_dir(path_notes); io_check_dir(path_cdir); io_check_dir(path_hooks); - vars_init(); if (status) { status_arg(); } else if (grep) { io_check_file(path_apts); io_check_file(path_todo); io_check_file(path_conf); - config_load(); /* To get output date format. */ io_load_data(&filter, FORCE); if (purge) { io_save_todo(path_todo); @@ -803,7 +784,6 @@ int parse_args(int argc, char **argv) io_check_file(path_apts); io_check_file(path_todo); io_check_file(path_conf); - config_load(); /* To get output date format. */ io_load_data(&filter, FORCE); /* Use default values for non-specified format strings. */ @@ -855,7 +835,6 @@ int parse_args(int argc, char **argv) io_load_data(&filter, FORCE); io_export_data(xfmt, export_uid); } else if (daemon) { - notify_init_vars(); dmon_stop(); dmon_start(0); } else { diff --git a/src/config.c b/src/config.c index 61527be..ca81c67 100644 --- a/src/config.c +++ b/src/config.c @@ -629,12 +629,9 @@ static int config_load_cb(const char *key, const char *value, void *dummy) int result = config_set_conf(key, value); if (result < 0) { - EXIT(_("configuration variable unknown: \"%s\""), key); - /* NOTREACHED */ + WARN_MSG(_("unknown user option: \"%s\""), key); } else if (result == 0) { - EXIT(_("wrong configuration variable format for \"%s\""), - key); - /* NOTREACHED */ + WARN_MSG(_("invalid option format: \"%s\""), key); } return 1; |