From 7db19e430c8d10a34f0f2db574e37d4c54299e20 Mon Sep 17 00:00:00 2001 From: Leah Neukirchen Date: Fri, 3 Apr 2020 20:59:59 +0200 Subject: write own -d parser with better defaults --- README | 7 ++++--- wcal.1 | 7 +++++-- wcal.c | 37 ++++++++++++++++++++++++++++++++++--- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/README b/README index ee15776..9f0a548 100644 --- a/README +++ b/README @@ -4,7 +4,7 @@ NAME wcal – ISO weekly calendar SYNOPSIS - wcal [-13yci] [-d YYYY-MM-DD] + wcal [-13yci] [-d YYYY[-MM[-DD]]] DESCRIPTION The wcal utility prints a week-oriented calendar. Each week is prefixed @@ -24,8 +24,9 @@ DESCRIPTION -i Show the calendar starting from the current week indefinitely. - -d YYYY-MM-DDD - Show the calendar for a different date than today. + -d YYYY[-MM[-DD]] + Show the calendar for a different date than today. Implies -y in + case only a year is passed. EXIT STATUS The wcal utility exits 0 on success, and >0 if an error occurs. diff --git a/wcal.1 b/wcal.1 index 4371958..28885bf 100644 --- a/wcal.1 +++ b/wcal.1 @@ -7,7 +7,7 @@ .Sh SYNOPSIS .Nm .Op Fl 13yci -.Op Fl d Ar YYYY-MM-DD +.Op Fl d Ar YYYY Ns Op Ar -MM Ns Op Ar -DD .Sh DESCRIPTION The .Nm @@ -29,8 +29,11 @@ Show the calendar for the whole year. Show the calendar for the current week. .It Fl i Show the calendar starting from the current week indefinitely. -.It Fl d Ar YYYY-MM-DDD +.It Fl d Ar YYYY Ns Op Ar -MM Ns Op Ar -DD Show the calendar for a different date than today. +Implies +.Fl y +in case only a year is passed. .El .Sh EXIT STATUS .Ex -std diff --git a/wcal.c b/wcal.c index 9390f22..1435996 100644 --- a/wcal.c +++ b/wcal.c @@ -16,12 +16,44 @@ */ #define _XOPEN_SOURCE 700 -#include +#include #include +#include +#include #include int flag1, flag3, flagc, flagi, flagy; +void +parse_isodate(char *optarg, struct tm *tm) +{ + tm->tm_hour = 12; /* avoid DST problems */ + tm->tm_min = tm->tm_sec = 0; + tm->tm_mday = 1; + tm->tm_mon = 0; + + if (isdigit(optarg[0]) && + isdigit(optarg[1]) && + isdigit(optarg[2]) && + isdigit(optarg[3]) && + (!optarg[4] || optarg[4] == '-')) { + tm->tm_year = atoi(optarg) - 1900; + + if (!optarg[4]) { + flagy = 1; + } else if (isdigit(optarg[5]) && isdigit(optarg[6]) && + (!optarg[7] || optarg[7] == '-')) { + tm->tm_mon = atoi(optarg+5) - 1; + + if (isdigit(optarg[8]) && isdigit(optarg[9]) && + (!optarg[10] || optarg[10] == '-')) + tm->tm_mday = atoi(optarg+8); + } + } + + mktime(tm); +} + int main(int argc, char *argv[]) { @@ -36,8 +68,7 @@ main(int argc, char *argv[]) case 'c': flagc = 1; break; case 'y': flagy = 1; break; case 'i': flagi = 1; break; - // XXX error handling, or write a parser oneself... - case 'd': strptime(optarg, "%Y-%m-%d", tm); break; + case 'd': parse_isodate(optarg, tm); break; } tm->tm_hour = 12; /* avoid DST problems */ -- cgit 1.4.1