Rework command line argument handling
Add a new range query mode (--days) and refactor the command line argument parser. Note: This slightly changes the behavior of some command line parameters, since date arguments no longer use the input date format from the configuration file! Signed-off-by: Lukas Fleischer <calcurse@cryptocrack.de>
This commit is contained in:
parent
1878b7c4b0
commit
aa682f7a11
535
src/args.c
535
src/args.c
@ -61,12 +61,14 @@ enum {
|
|||||||
OPT_FILTER_UNCOMPLETED,
|
OPT_FILTER_UNCOMPLETED,
|
||||||
OPT_FROM,
|
OPT_FROM,
|
||||||
OPT_TO,
|
OPT_TO,
|
||||||
|
OPT_DAYS,
|
||||||
OPT_FMT_APT,
|
OPT_FMT_APT,
|
||||||
OPT_FMT_RAPT,
|
OPT_FMT_RAPT,
|
||||||
OPT_FMT_EV,
|
OPT_FMT_EV,
|
||||||
OPT_FMT_REV,
|
OPT_FMT_REV,
|
||||||
OPT_FMT_TODO,
|
OPT_FMT_TODO,
|
||||||
OPT_READ_ONLY
|
OPT_READ_ONLY,
|
||||||
|
OPT_STATUS
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -215,51 +217,27 @@ static void status_arg(void)
|
|||||||
puts(_("calcurse is not running\n"));
|
puts(_("calcurse is not running\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Print TODO list and exit. */
|
||||||
* Print todo list and exit. If a priority number is given, then only todo
|
static void todo_arg(const char *format, int *limit,
|
||||||
* then only todo items that have this priority will be displayed.
|
struct item_filter *filter)
|
||||||
* If priority is < 0, all todos will be displayed.
|
|
||||||
* If priority == 0, only completed tasks will be displayed.
|
|
||||||
*/
|
|
||||||
static void todo_arg(int priority, const char *format, int *limit)
|
|
||||||
{
|
{
|
||||||
llist_item_t *i;
|
const char *titlestr =
|
||||||
|
filter->completed ? _("completed tasks:\n") : _("to do:\n");
|
||||||
int title = 1;
|
int title = 1;
|
||||||
const char *titlestr;
|
llist_item_t *i;
|
||||||
const char *all_todos_title = _("to do:\n");
|
|
||||||
const char *completed_title = _("completed tasks:\n");
|
|
||||||
|
|
||||||
titlestr = priority == 0 ? completed_title : all_todos_title;
|
|
||||||
|
|
||||||
#define DISPLAY_TITLE do { \
|
|
||||||
if (title) \
|
|
||||||
{ \
|
|
||||||
fputs (titlestr, stdout); \
|
|
||||||
title = 0; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
LLIST_FOREACH(&todolist, i) {
|
LLIST_FOREACH(&todolist, i) {
|
||||||
if (*limit == 0)
|
if (*limit == 0)
|
||||||
return;
|
return;
|
||||||
struct todo *todo = LLIST_TS_GET_DATA(i);
|
struct todo *todo = LLIST_TS_GET_DATA(i);
|
||||||
|
|
||||||
if (todo->id < 0) { /* completed task */
|
if (title) {
|
||||||
if (priority == 0) {
|
fputs(titlestr, stdout);
|
||||||
DISPLAY_TITLE;
|
title = 0;
|
||||||
|
}
|
||||||
print_todo(format, todo);
|
print_todo(format, todo);
|
||||||
(*limit)--;
|
(*limit)--;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (priority < 0 || todo->id == priority) {
|
|
||||||
DISPLAY_TITLE;
|
|
||||||
print_todo(format, todo);
|
|
||||||
(*limit)--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef DISPLAY_TITLE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print the next appointment within the upcoming 24 hours. */
|
/* Print the next appointment within the upcoming 24 hours. */
|
||||||
@ -273,8 +251,8 @@ static void next_arg(void)
|
|||||||
next_app.got_app = 0;
|
next_app.got_app = 0;
|
||||||
next_app.txt = NULL;
|
next_app.txt = NULL;
|
||||||
|
|
||||||
next_app =
|
next_app = *recur_apoint_check_next(&next_app, current_time,
|
||||||
*recur_apoint_check_next(&next_app, current_time, get_today());
|
get_today());
|
||||||
next_app = *apoint_check_next(&next_app, current_time);
|
next_app = *apoint_check_next(&next_app, current_time);
|
||||||
|
|
||||||
if (next_app.got_app) {
|
if (next_app.got_app) {
|
||||||
@ -302,184 +280,27 @@ static void arg_print_date(long date)
|
|||||||
fputs(":\n", stdout);
|
fputs(":\n", stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Print appointments for given day and exit.
|
|
||||||
* If no day is given, the given date is used.
|
|
||||||
* If there is also no date given, current date is considered.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
app_arg(int add_line, struct date *day, long date, const char *fmt_apt,
|
|
||||||
const char *fmt_rapt, const char *fmt_ev, const char *fmt_rev,
|
|
||||||
int *limit)
|
|
||||||
{
|
|
||||||
if (*limit == 0)
|
|
||||||
return 0;
|
|
||||||
if (date == 0)
|
|
||||||
date = get_sec_date(*day);
|
|
||||||
|
|
||||||
day_store_items(date, 0);
|
|
||||||
|
|
||||||
int n = day_item_count(0);
|
|
||||||
|
|
||||||
if (n > 0) {
|
|
||||||
if (add_line)
|
|
||||||
fputs("\n", stdout);
|
|
||||||
arg_print_date(date);
|
|
||||||
day_write_stdout(date, fmt_apt, fmt_rapt, fmt_ev, fmt_rev,
|
|
||||||
limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For a given date, print appointments for each day
|
|
||||||
* in the chosen interval. app_found and add_line are used
|
|
||||||
* to format the output correctly.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
display_app(struct tm *t, int numdays, int add_line, const char *fmt_apt,
|
|
||||||
const char *fmt_rapt, const char *fmt_ev, const char *fmt_rev,
|
|
||||||
int *limit)
|
|
||||||
{
|
|
||||||
int i, app_found;
|
|
||||||
struct date day;
|
|
||||||
|
|
||||||
for (i = 0; i < numdays; i++) {
|
|
||||||
day.dd = t->tm_mday;
|
|
||||||
day.mm = t->tm_mon + 1;
|
|
||||||
day.yyyy = t->tm_year + 1900;
|
|
||||||
app_found =
|
|
||||||
app_arg(add_line, &day, 0, fmt_apt, fmt_rapt, fmt_ev,
|
|
||||||
fmt_rev, limit);
|
|
||||||
if (app_found)
|
|
||||||
add_line = 1;
|
|
||||||
t->tm_mday++;
|
|
||||||
mktime(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Print appointment for the given date or for the given n upcoming
|
|
||||||
* days.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
date_arg(const char *ddate, int add_line, const char *fmt_apt,
|
|
||||||
const char *fmt_rapt, const char *fmt_ev, const char *fmt_rev,
|
|
||||||
int *limit)
|
|
||||||
{
|
|
||||||
struct date day;
|
|
||||||
static struct tm t;
|
|
||||||
time_t timer;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check (with the argument length) if a date or a number of days
|
|
||||||
* was entered, and then call app_arg() to print appointments
|
|
||||||
*/
|
|
||||||
if (strlen(ddate) <= 4 && is_all_digit(ddate)) {
|
|
||||||
/*
|
|
||||||
* A number of days was entered. Get current date and print appointments
|
|
||||||
* for each day in the chosen interval. app_found and add_line are used to
|
|
||||||
* format the output correctly.
|
|
||||||
*/
|
|
||||||
timer = time(NULL);
|
|
||||||
localtime_r(&timer, &t);
|
|
||||||
display_app(&t, atoi(ddate), add_line, fmt_apt, fmt_rapt,
|
|
||||||
fmt_ev, fmt_rev, limit);
|
|
||||||
} else {
|
|
||||||
/* A date was entered. */
|
|
||||||
if (parse_date(ddate, conf.input_datefmt, (int *)&day.yyyy,
|
|
||||||
(int *)&day.mm, (int *)&day.dd, NULL)) {
|
|
||||||
app_arg(add_line, &day, 0, fmt_apt, fmt_rapt,
|
|
||||||
fmt_ev, fmt_rev, limit);
|
|
||||||
} else {
|
|
||||||
fputs(_("Argument to the '-d' flag is not valid\n"),
|
|
||||||
stderr);
|
|
||||||
fprintf(stdout,
|
|
||||||
_("Possible argument format are: '%s' or 'n'\n"),
|
|
||||||
DATEFMT_DESC(conf.input_datefmt));
|
|
||||||
more_info();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Print appointment from the given date 'startday' for the 'range' upcoming
|
|
||||||
* days.
|
|
||||||
* If no starday is given (NULL), today is considered
|
|
||||||
* If no range is given (NULL), 1 day is considered
|
|
||||||
*
|
|
||||||
* Many thanks to Erik Saule for providing this function.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
date_arg_extended(const char *startday, const char *range, int add_line,
|
|
||||||
const char *fmt_apt, const char *fmt_rapt,
|
|
||||||
const char *fmt_ev, const char *fmt_rev, int *limit)
|
|
||||||
{
|
|
||||||
int numdays = 1, error = 0;
|
|
||||||
static struct tm t;
|
|
||||||
time_t timer;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check arguments and extract information
|
|
||||||
*/
|
|
||||||
if (range != NULL) {
|
|
||||||
if (is_all_digit(range)) {
|
|
||||||
numdays = atoi(range);
|
|
||||||
} else {
|
|
||||||
error = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
timer = time(NULL);
|
|
||||||
localtime_r(&timer, &t);
|
|
||||||
if (startday != NULL) {
|
|
||||||
if (parse_date
|
|
||||||
(startday, conf.input_datefmt, (int *)&t.tm_year,
|
|
||||||
(int *)&t.tm_mon, (int *)&t.tm_mday, NULL)) {
|
|
||||||
t.tm_year -= 1900;
|
|
||||||
t.tm_mon--;
|
|
||||||
mktime(&t);
|
|
||||||
} else {
|
|
||||||
error = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!error) {
|
|
||||||
display_app(&t, numdays, add_line, fmt_apt, fmt_rapt,
|
|
||||||
fmt_ev, fmt_rev, limit);
|
|
||||||
} else {
|
|
||||||
fputs(_("Argument is not valid\n"), stderr);
|
|
||||||
fprintf(stdout,
|
|
||||||
_("Argument format for -s and --startday is: '%s'\n"),
|
|
||||||
DATEFMT_DESC(conf.input_datefmt));
|
|
||||||
fputs(_("Argument format for -r and --range is: 'n'\n"),
|
|
||||||
stdout);
|
|
||||||
more_info();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print appointments inside the given query range.
|
* Print appointments inside the given query range.
|
||||||
* If no start day is given (-1), today is considered.
|
* If no start day is given (-1), today is considered.
|
||||||
* If no end date is given (-1), a range of 1 day is considered.
|
* If no end date is given (-1), a range of 1 day is considered.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
date_arg_from_to(long from, long to, int add_line, const char *fmt_apt,
|
date_arg_from_to(long from, long to, const char *fmt_apt, const char *fmt_rapt,
|
||||||
const char *fmt_rapt, const char *fmt_ev, const char *fmt_rev,
|
const char *fmt_ev, const char *fmt_rev, int *limit)
|
||||||
int *limit)
|
|
||||||
{
|
{
|
||||||
long date;
|
long date;
|
||||||
|
int add_line = 0;
|
||||||
if (from == -1) {
|
|
||||||
struct date day = { 0, 0, 0 };
|
|
||||||
from = get_sec_date(day);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (to == -1)
|
|
||||||
to = from + DAYINSEC;
|
|
||||||
|
|
||||||
for (date = from; date < to; date += DAYINSEC) {
|
for (date = from; date < to; date += DAYINSEC) {
|
||||||
if (app_arg(add_line, NULL, date, fmt_apt, fmt_rapt,
|
day_store_items(date, 0);
|
||||||
fmt_ev, fmt_rev, limit))
|
if (day_item_count(0) == 0)
|
||||||
|
continue;
|
||||||
|
if (add_line)
|
||||||
|
fputs("\n", stdout);
|
||||||
|
arg_print_date(date);
|
||||||
|
day_write_stdout(date, fmt_apt, fmt_rapt, fmt_ev,
|
||||||
|
fmt_rev, limit);
|
||||||
add_line = 1;
|
add_line = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -540,48 +361,28 @@ cleanup:
|
|||||||
*/
|
*/
|
||||||
int parse_args(int argc, char **argv)
|
int parse_args(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ch, add_line = 0;
|
|
||||||
int unknown_flag = 0;
|
|
||||||
/* Command-line flags */
|
/* Command-line flags */
|
||||||
int aflag = 0; /* -a: print appointments for current day */
|
int status = 0, query = 0, next = 0, gc = 0, import = 0, export = 0;
|
||||||
int dflag = 0; /* -d: print appointments for a specified days */
|
|
||||||
int hflag = 0; /* -h: print help text */
|
|
||||||
int gflag = 0; /* -g: run garbage collector */
|
|
||||||
int iflag = 0; /* -i: import data */
|
|
||||||
int nflag = 0; /* -n: print next appointment */
|
|
||||||
int Qflag = 0; /* -Q: query mode */
|
|
||||||
int rflag = 0; /* -r: specify the range of days to consider */
|
|
||||||
int sflag = 0; /* -s: specify the first day to consider */
|
|
||||||
int Sflag = 0; /* -S: specify a regex to search for */
|
|
||||||
int tflag = 0; /* -t: print todo list */
|
|
||||||
int vflag = 0; /* -v: print version number */
|
|
||||||
int xflag = 0; /* -x: export data */
|
|
||||||
/* Query ranges */
|
/* Query ranges */
|
||||||
long from = -1, to = -1;
|
long from = -1, range = -1, to = -1;
|
||||||
|
int limit = INT_MAX;
|
||||||
/* Filters */
|
/* Filters */
|
||||||
struct item_filter filter =
|
struct item_filter filter = { 0, NULL, -1, -1, -1, -1, 0, 0, 0 };
|
||||||
{ TYPE_MASK_ALL, NULL, -1, -1, -1, -1, 0, 0, 0 };
|
|
||||||
/* Format strings */
|
/* Format strings */
|
||||||
const char *fmt_apt = " - %S -> %E\n\t%m\n";
|
const char *fmt_apt = " - %S -> %E\n\t%m\n";
|
||||||
const char *fmt_rapt = " - %S -> %E\n\t%m\n";
|
const char *fmt_rapt = " - %S -> %E\n\t%m\n";
|
||||||
const char *fmt_ev = " * %m\n";
|
const char *fmt_ev = " * %m\n";
|
||||||
const char *fmt_rev = " * %m\n";
|
const char *fmt_rev = " * %m\n";
|
||||||
const char *fmt_todo = "%p. %m\n";
|
const char *fmt_todo = "%p. %m\n";
|
||||||
|
/* Import and export parameters */
|
||||||
|
int xfmt = IO_EXPORT_ICAL;
|
||||||
|
/* Data file locations */
|
||||||
|
const char *cfile = NULL, *datadir = NULL, *ifile = NULL;
|
||||||
|
|
||||||
int limit = INT_MAX; /* indicates no limit requested. */
|
int non_interactive = 1;
|
||||||
int tnum = 0, xfmt = 0, non_interactive = 0, multiple_flag =
|
int ch;
|
||||||
0, load_data = 0;
|
|
||||||
const char *ddate = "", *cfile = NULL, *range = NULL, *startday =
|
|
||||||
NULL;
|
|
||||||
const char *datadir = NULL, *ifile = NULL;
|
|
||||||
regex_t reg;
|
regex_t reg;
|
||||||
|
|
||||||
/* Long options only */
|
|
||||||
int statusflag = 0; /* --status: get the status of running instances */
|
|
||||||
enum {
|
|
||||||
STATUS_OPT = CHAR_MAX + 1
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *optstr = "ghvnNax::t::d:c:r::s::S:D:i:l:Q";
|
static const char *optstr = "ghvnNax::t::d:c:r::s::S:D:i:l:Q";
|
||||||
|
|
||||||
struct option longopts[] = {
|
struct option longopts[] = {
|
||||||
@ -598,7 +399,6 @@ int parse_args(int argc, char **argv)
|
|||||||
{"range", optional_argument, NULL, 'r'},
|
{"range", optional_argument, NULL, 'r'},
|
||||||
{"startday", optional_argument, NULL, 's'},
|
{"startday", optional_argument, NULL, 's'},
|
||||||
{"search", required_argument, NULL, 'S'},
|
{"search", required_argument, NULL, 'S'},
|
||||||
{"status", no_argument, NULL, STATUS_OPT},
|
|
||||||
{"todo", optional_argument, NULL, 't'},
|
{"todo", optional_argument, NULL, 't'},
|
||||||
{"version", no_argument, NULL, 'v'},
|
{"version", no_argument, NULL, 'v'},
|
||||||
{"export", optional_argument, NULL, 'x'},
|
{"export", optional_argument, NULL, 'x'},
|
||||||
@ -619,115 +419,104 @@ int parse_args(int argc, char **argv)
|
|||||||
{"filter-uncompleted", no_argument, NULL, OPT_FILTER_UNCOMPLETED},
|
{"filter-uncompleted", no_argument, NULL, OPT_FILTER_UNCOMPLETED},
|
||||||
{"from", required_argument, NULL, OPT_FROM},
|
{"from", required_argument, NULL, OPT_FROM},
|
||||||
{"to", required_argument, NULL, OPT_TO},
|
{"to", required_argument, NULL, OPT_TO},
|
||||||
|
{"days", required_argument, NULL, OPT_DAYS},
|
||||||
{"format-apt", required_argument, NULL, OPT_FMT_APT},
|
{"format-apt", required_argument, NULL, OPT_FMT_APT},
|
||||||
{"format-recur-apt", required_argument, NULL, OPT_FMT_RAPT},
|
{"format-recur-apt", required_argument, NULL, OPT_FMT_RAPT},
|
||||||
{"format-event", required_argument, NULL, OPT_FMT_EV},
|
{"format-event", required_argument, NULL, OPT_FMT_EV},
|
||||||
{"format-recur-event", required_argument, NULL, OPT_FMT_REV},
|
{"format-recur-event", required_argument, NULL, OPT_FMT_REV},
|
||||||
{"format-todo", required_argument, NULL, OPT_FMT_TODO},
|
{"format-todo", required_argument, NULL, OPT_FMT_TODO},
|
||||||
{"read-only", no_argument, NULL, OPT_READ_ONLY},
|
{"read-only", no_argument, NULL, OPT_READ_ONLY},
|
||||||
|
{"status", no_argument, NULL, OPT_STATUS},
|
||||||
{NULL, no_argument, NULL, 0}
|
{NULL, no_argument, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
while ((ch =
|
while ((ch = getopt_long(argc, argv, optstr, longopts, NULL)) != -1) {
|
||||||
getopt_long(argc, argv, optstr, longopts, NULL)) != -1) {
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case STATUS_OPT:
|
|
||||||
statusflag = 1;
|
|
||||||
break;
|
|
||||||
case 'a':
|
case 'a':
|
||||||
aflag = 1;
|
filter.type_mask |= TYPE_MASK_CAL;
|
||||||
multiple_flag++;
|
query = 1;
|
||||||
load_data++;
|
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
multiple_flag++;
|
|
||||||
cfile = optarg;
|
cfile = optarg;
|
||||||
load_data++;
|
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
dflag = 1;
|
if (is_all_digit(optarg)) {
|
||||||
multiple_flag++;
|
range = atoi(optarg);
|
||||||
load_data++;
|
} else {
|
||||||
ddate = optarg;
|
from = parse_datearg(optarg);
|
||||||
|
EXIT_IF(from == -1, _("invalid date: %s"),
|
||||||
|
optarg);
|
||||||
|
}
|
||||||
|
|
||||||
|
filter.type_mask |= TYPE_MASK_CAL;
|
||||||
|
query = 1;
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
datadir = optarg;
|
datadir = optarg;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
hflag = 1;
|
help_arg();
|
||||||
break;
|
goto cleanup;
|
||||||
case 'g':
|
case 'g':
|
||||||
gflag = 1;
|
gc = 1;
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
iflag = 1;
|
import = 1;
|
||||||
multiple_flag++;
|
|
||||||
load_data++;
|
|
||||||
ifile = optarg;
|
ifile = optarg;
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
limit = atoi(optarg);
|
limit = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
nflag = 1;
|
next = 1;
|
||||||
multiple_flag++;
|
|
||||||
load_data++;
|
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
rflag = 1;
|
if (optarg)
|
||||||
multiple_flag++;
|
range = atoi(optarg);
|
||||||
load_data++;
|
else
|
||||||
range = optarg;
|
range = 1;
|
||||||
|
EXIT_IF(range == 0, _("invalid range: %s"), optarg);
|
||||||
|
filter.type_mask |= TYPE_MASK_CAL;
|
||||||
|
query = 1;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
sflag = 1;
|
from = parse_datearg(optarg);
|
||||||
multiple_flag++;
|
EXIT_IF(from == -1, _("invalid date: %s"), optarg);
|
||||||
load_data++;
|
filter.type_mask |= TYPE_MASK_CAL;
|
||||||
startday = optarg;
|
query = 1;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
tflag = 1;
|
if (optarg) {
|
||||||
multiple_flag++;
|
EXIT_IF(!is_all_digit(optarg),
|
||||||
load_data++;
|
_("invalid priority: %s"), optarg);
|
||||||
add_line = 1;
|
filter.priority = atoi(optarg);
|
||||||
if (optarg != NULL) {
|
if (filter.priority == 0)
|
||||||
tnum = atoi(optarg);
|
filter.completed = 1;
|
||||||
if (tnum < 0 || tnum > 9) {
|
EXIT_IF(filter.priority > 9,
|
||||||
usage();
|
_("invalid priority: %s"), optarg);
|
||||||
usage_try();
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
tnum = -1;
|
filter.uncompleted = 1;
|
||||||
}
|
}
|
||||||
|
filter.type_mask |= TYPE_MASK_TODO;
|
||||||
|
query = 1;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
vflag = 1;
|
version_arg();
|
||||||
break;
|
goto cleanup;
|
||||||
case 'x':
|
case 'x':
|
||||||
xflag = 1;
|
export = 1;
|
||||||
multiple_flag++;
|
if (optarg) {
|
||||||
load_data++;
|
if (!strcmp(optarg, "ical"))
|
||||||
if (optarg != NULL) {
|
|
||||||
if (strcmp(optarg, "ical") == 0) {
|
|
||||||
xfmt = IO_EXPORT_ICAL;
|
xfmt = IO_EXPORT_ICAL;
|
||||||
} else if (strcmp(optarg, "pcal") == 0) {
|
else if (!strcmp(optarg, "pcal"))
|
||||||
xfmt = IO_EXPORT_PCAL;
|
xfmt = IO_EXPORT_PCAL;
|
||||||
} else {
|
else
|
||||||
fputs(_("Argument for '-x' should be either "
|
EXIT(_("invalid export format: %s"),
|
||||||
"'ical' or 'pcal'\n"),
|
optarg);
|
||||||
stderr);
|
|
||||||
usage();
|
|
||||||
usage_try();
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
xfmt = IO_EXPORT_ICAL;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'Q':
|
case 'Q':
|
||||||
Qflag = 1;
|
query = 1;
|
||||||
load_data++;
|
|
||||||
break;
|
break;
|
||||||
case OPT_FILTER_TYPE:
|
case OPT_FILTER_TYPE:
|
||||||
filter.type_mask = parse_type_mask(optarg);
|
filter.type_mask = parse_type_mask(optarg);
|
||||||
@ -735,8 +524,6 @@ int parse_args(int argc, char **argv)
|
|||||||
_("invalid filter mask"));
|
_("invalid filter mask"));
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
Sflag = 1;
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
case OPT_FILTER_PATTERN:
|
case OPT_FILTER_PATTERN:
|
||||||
EXIT_IF(filter.regex,
|
EXIT_IF(filter.regex,
|
||||||
_("Can not handle more than one regular expression."));
|
_("Can not handle more than one regular expression."));
|
||||||
@ -803,6 +590,10 @@ int parse_args(int argc, char **argv)
|
|||||||
to = parse_datearg(optarg);
|
to = parse_datearg(optarg);
|
||||||
EXIT_IF(to == -1, _("invalid end date"));
|
EXIT_IF(to == -1, _("invalid end date"));
|
||||||
break;
|
break;
|
||||||
|
case OPT_DAYS:
|
||||||
|
range = atoi(optarg);
|
||||||
|
EXIT_IF(range == 0, _("invalid range"));
|
||||||
|
break;
|
||||||
case OPT_FMT_APT:
|
case OPT_FMT_APT:
|
||||||
fmt_apt = optarg;
|
fmt_apt = optarg;
|
||||||
break;
|
break;
|
||||||
@ -821,65 +612,46 @@ int parse_args(int argc, char **argv)
|
|||||||
case OPT_READ_ONLY:
|
case OPT_READ_ONLY:
|
||||||
read_only = 1;
|
read_only = 1;
|
||||||
break;
|
break;
|
||||||
|
case OPT_STATUS:
|
||||||
|
status = 1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
usage_try();
|
usage_try();
|
||||||
unknown_flag = 1;
|
goto cleanup;
|
||||||
non_interactive = 1;
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
|
|
||||||
if (argc >= 1) {
|
if (filter.type_mask == 0)
|
||||||
|
filter.type_mask = TYPE_MASK_ALL;
|
||||||
|
|
||||||
|
if (status + query + next + gc + import + export > 1) {
|
||||||
|
ERROR_MSG(_("invalid argument combination"));
|
||||||
usage();
|
usage();
|
||||||
usage_try();
|
usage_try();
|
||||||
return EXIT_FAILURE;
|
goto cleanup;
|
||||||
/* Incorrect arguments */
|
|
||||||
} else if (Sflag && !(aflag || dflag || rflag || sflag || tflag)) {
|
|
||||||
fputs(_("Option '-S' must be used with either '-d', '-r', '-s', "
|
|
||||||
"'-a' or '-t'\n"), stderr);
|
|
||||||
usage();
|
|
||||||
usage_try();
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
} else if ((limit != INT_MAX) && !(aflag || dflag || rflag || sflag || tflag)) {
|
|
||||||
fputs(_("Option '-l' must be used with either '-d', '-r', '-s', "
|
|
||||||
"'-a' or '-t'\n"), stderr);
|
|
||||||
usage();
|
|
||||||
usage_try();
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
} else {
|
|
||||||
if (load_data) {
|
|
||||||
io_init(cfile, datadir);
|
|
||||||
io_check_dir(path_dir);
|
|
||||||
io_check_dir(path_notes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unknown_flag) {
|
if (from == -1) {
|
||||||
non_interactive = 1;
|
struct date day = { 0, 0, 0 };
|
||||||
} else if (hflag) {
|
from = get_sec_date(day);
|
||||||
help_arg();
|
}
|
||||||
non_interactive = 1;
|
|
||||||
} else if (vflag) {
|
if (to == -1 && range == -1)
|
||||||
version_arg();
|
to = from + DAYINSEC;
|
||||||
non_interactive = 1;
|
else if (to == -1 && range >= 0)
|
||||||
} else if (statusflag) {
|
to = from + range * DAYINSEC;
|
||||||
io_init(cfile, datadir);
|
else if (to >= 0 && range >= 0)
|
||||||
status_arg();
|
EXIT_IF(to >= 0, _("cannot specify a range and an end date"));
|
||||||
non_interactive = 1;
|
|
||||||
} else if (gflag) {
|
|
||||||
io_init(cfile, datadir);
|
io_init(cfile, datadir);
|
||||||
io_check_dir(path_dir);
|
io_check_dir(path_dir);
|
||||||
io_check_dir(path_notes);
|
io_check_dir(path_notes);
|
||||||
io_check_file(path_apts);
|
|
||||||
io_check_file(path_todo);
|
|
||||||
io_load_app(&filter);
|
|
||||||
io_load_todo(&filter);
|
|
||||||
note_gc();
|
|
||||||
non_interactive = 1;
|
|
||||||
} else if (Qflag) {
|
|
||||||
struct date day;
|
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
status_arg();
|
||||||
|
} else if (query) {
|
||||||
io_check_file(path_apts);
|
io_check_file(path_apts);
|
||||||
io_check_file(path_todo);
|
io_check_file(path_todo);
|
||||||
io_check_file(path_conf);
|
io_check_file(path_conf);
|
||||||
@ -887,13 +659,20 @@ int parse_args(int argc, char **argv)
|
|||||||
config_load(); /* To get output date format. */
|
config_load(); /* To get output date format. */
|
||||||
io_load_app(&filter);
|
io_load_app(&filter);
|
||||||
io_load_todo(&filter);
|
io_load_todo(&filter);
|
||||||
day.dd = day.mm = day.yyyy = 0;
|
date_arg_from_to(from, to, fmt_apt, fmt_rapt, fmt_ev, fmt_rev,
|
||||||
date_arg_from_to(from, to, 1, fmt_apt, fmt_rapt,
|
&limit);
|
||||||
fmt_ev, fmt_rev, &limit);
|
todo_arg(fmt_todo, &limit, &filter);
|
||||||
todo_arg(-1, fmt_todo, &limit);
|
} else if (next) {
|
||||||
non_interactive = 1;
|
io_check_file(path_apts);
|
||||||
} else if (multiple_flag) {
|
io_load_app(&filter);
|
||||||
if (iflag) {
|
next_arg();
|
||||||
|
} else if (gc) {
|
||||||
|
io_check_file(path_apts);
|
||||||
|
io_check_file(path_todo);
|
||||||
|
io_load_app(&filter);
|
||||||
|
io_load_todo(&filter);
|
||||||
|
note_gc();
|
||||||
|
} else if (import) {
|
||||||
io_check_file(path_apts);
|
io_check_file(path_apts);
|
||||||
io_check_file(path_todo);
|
io_check_file(path_todo);
|
||||||
/* Get default pager in case we need to show a log file. */
|
/* Get default pager in case we need to show a log file. */
|
||||||
@ -903,64 +682,18 @@ int parse_args(int argc, char **argv)
|
|||||||
io_import_data(IO_IMPORT_ICAL, ifile);
|
io_import_data(IO_IMPORT_ICAL, ifile);
|
||||||
io_save_apts(path_apts);
|
io_save_apts(path_apts);
|
||||||
io_save_todo(path_todo);
|
io_save_todo(path_todo);
|
||||||
non_interactive = 1;
|
} else if (export) {
|
||||||
}
|
|
||||||
if (xflag) {
|
|
||||||
io_check_file(path_apts);
|
io_check_file(path_apts);
|
||||||
io_check_file(path_todo);
|
io_check_file(path_todo);
|
||||||
io_load_app(&filter);
|
io_load_app(&filter);
|
||||||
io_load_todo(&filter);
|
io_load_todo(&filter);
|
||||||
io_export_data(xfmt);
|
io_export_data(xfmt);
|
||||||
non_interactive = 1;
|
|
||||||
return non_interactive;
|
|
||||||
}
|
|
||||||
if (tflag) {
|
|
||||||
io_check_file(path_todo);
|
|
||||||
io_load_todo(&filter);
|
|
||||||
todo_arg(tnum, fmt_todo, &limit);
|
|
||||||
non_interactive = 1;
|
|
||||||
}
|
|
||||||
if (nflag) {
|
|
||||||
io_check_file(path_apts);
|
|
||||||
io_load_app(&filter);
|
|
||||||
next_arg();
|
|
||||||
non_interactive = 1;
|
|
||||||
}
|
|
||||||
if (dflag || rflag || sflag) {
|
|
||||||
io_check_file(path_apts);
|
|
||||||
io_check_file(path_conf);
|
|
||||||
io_load_app(&filter);
|
|
||||||
config_load(); /* To get output date format. */
|
|
||||||
if (dflag)
|
|
||||||
date_arg(ddate, add_line, fmt_apt,
|
|
||||||
fmt_rapt, fmt_ev, fmt_rev,
|
|
||||||
&limit);
|
|
||||||
if (rflag || sflag)
|
|
||||||
date_arg_extended(startday, range,
|
|
||||||
add_line,
|
|
||||||
fmt_apt,
|
|
||||||
fmt_rapt, fmt_ev,
|
|
||||||
fmt_rev, &limit);
|
|
||||||
non_interactive = 1;
|
|
||||||
} else if (aflag) {
|
|
||||||
struct date day;
|
|
||||||
|
|
||||||
io_check_file(path_apts);
|
|
||||||
io_check_file(path_conf);
|
|
||||||
vars_init();
|
|
||||||
config_load(); /* To get output date format. */
|
|
||||||
io_load_app(&filter);
|
|
||||||
day.dd = day.mm = day.yyyy = 0;
|
|
||||||
app_arg(add_line, &day, 0, fmt_apt, fmt_rapt,
|
|
||||||
fmt_ev, fmt_rev, &limit);
|
|
||||||
non_interactive = 1;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
|
/* interactive mode */
|
||||||
non_interactive = 0;
|
non_interactive = 0;
|
||||||
io_init(cfile, datadir);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
/* Free filter parameters. */
|
/* Free filter parameters. */
|
||||||
if (filter.regex)
|
if (filter.regex)
|
||||||
regfree(filter.regex);
|
regfree(filter.regex);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user