From 731441ac5bfa846cdbd99e3903f11393eaeb2e53 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 31 May 2016 13:53:58 +0200 Subject: cal: allow to specify month by name For example: $ cal August 2016 Signed-off-by: Karel Zak --- misc-utils/cal.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) (limited to 'misc-utils/cal.c') diff --git a/misc-utils/cal.c b/misc-utils/cal.c index 3e2053025..c48de69f5 100644 --- a/misc-utils/cal.c +++ b/misc-utils/cal.c @@ -219,6 +219,7 @@ struct cal_month { /* function prototypes */ static int leap_year(int32_t year); +static int monthname_to_number(struct cal_control *ctl, const char *name); static void headers_init(struct cal_control *ctl); static void cal_fill_month(struct cal_month *month, const struct cal_control *ctl); static void cal_output_header(struct cal_month *month, const struct cal_control *ctl); @@ -411,7 +412,10 @@ int main(int argc, char **argv) errx(EXIT_FAILURE, _("illegal day value: use 1-%d"), DAYS_IN_MONTH); /* FALLTHROUGH */ case 2: - ctl.req.month = strtos32_or_err(*argv++, _("illegal month value: use 1-12")); + if (isdigit(**argv)) + ctl.req.month = strtos32_or_err(*argv++, _("illegal month value: use 1-12")); + else + ctl.req.month = monthname_to_number(&ctl, *argv++); if (ctl.req.month < 1 || MONTHS_IN_YEAR < ctl.req.month) errx(EXIT_FAILURE, _("illegal month value: use 1-12")); /* FALLTHROUGH */ @@ -509,6 +513,30 @@ static int leap_year(int32_t year) return ( !(year % 4) && (year % 100) ) || !(year % 400); } +static void init_monthnames(struct cal_control *ctl) +{ + size_t i; + + if (ctl->full_month[0] != '\0') + return; /* already initialized */ + + for (i = 0; i < MONTHS_IN_YEAR; i++) + ctl->full_month[i] = nl_langinfo(MON_1 + i); +} + +static int monthname_to_number(struct cal_control *ctl, const char *name) +{ + size_t i; + + init_monthnames(ctl); + + for (i = 0; i < MONTHS_IN_YEAR; i++) + if (strcasecmp(ctl->full_month[i], name) == 0) + return i + 1; + + errx(EXIT_FAILURE, _("unknown month name: %s"), name); +} + static void headers_init(struct cal_control *ctl) { size_t i, wd; @@ -537,8 +565,9 @@ static void headers_init(struct cal_control *ctl) space_left, ctl->day_width - 1); } + init_monthnames(ctl); + for (i = 0; i < MONTHS_IN_YEAR; i++) { - ctl->full_month[i] = nl_langinfo(MON_1 + i); /* The +1 after year_len is space in between month and year. */ if (ctl->week_width < strlen(ctl->full_month[i]) + year_len + 1) ctl->header_hint = 1; -- cgit v1.2.3-55-g7522