]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
cal: fix --week use and colors
authorKarel Zak <kzak@redhat.com>
Mon, 20 May 2024 13:07:24 +0000 (15:07 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 20 May 2024 13:27:23 +0000 (15:27 +0200)
* don't overwrite --week=<number> by the current date, default only
  to the current year, if the year is not specified

* introduce "weeks" color sequence to colorize all week numbers.

Note that the man page suggests using "weeknumber" to colorize all
week numbers, but the code only uses this sequence for the week
requested by the --week option. This commit maintains backward
compatibility, although it would be better to use "weeknumber" for all
week numbers and "weekwanted" for the desired week.

Signed-off-by: Karel Zak <kzak@redhat.com>
misc-utils/cal.1.adoc
misc-utils/cal.c

index fd508bc02c1578f4d4e9b705a0a8e5b5e5e7f9ce..fe4f7e6708a38739fb9c6f5cef7912c0576c9e5e 100644 (file)
@@ -112,7 +112,12 @@ Display a calendar for the whole year.
 Display a calendar for the next twelve months.
 
 *-w*, *--week*[=_number_]::
-Display week numbers in the calendar (US or ISO-8601). See the *NOTES* section for more details.
+Display week numbers in the calendar according to the US or ISO-8601 format. If
+a _number_ is specified, the requested week will be printed in the desired or
+current year. The _number_ may be overwritten if _day_ and _month_ are also
+specified.
++
+See the *NOTES* section for more details.
 
 *--color*[=_when_]::
 Colorize the output. The optional argument _when_ can be *auto*, *never* or *always*. If the _when_ argument is omitted, it defaults to *auto*. The colors can be disabled; for the current built-in default see the *--help* output. See also the *COLORS* section.
@@ -154,6 +159,9 @@ The logical color names supported by *cal* are:
 The current day.
 
 *weeknumber*::
+The week number requested by the --week=<number> command line option.
+
+*weeks*::
 The number of the week.
 
 *header*::
index 900f7277da615cc70d578a51aa0c6aabc795f81f..65517512e960fdffc4795ca20225841f1d921c3a 100644 (file)
@@ -85,15 +85,17 @@ enum {
        CAL_COLOR_TODAY,
        CAL_COLOR_HEADER,
        CAL_COLOR_WEEKNUMBER,
+       CAL_COLOR_WEEKS,
        CAL_COLOR_WORKDAY,
        CAL_COLOR_WEEKEND
 };
 
 static const struct { const char * const scheme; const char * dflt; } colors[] =
 {
-        [CAL_COLOR_TODAY]      = { "today",      UL_COLOR_REVERSE },
-        [CAL_COLOR_WEEKNUMBER] = { "weeknumber", UL_COLOR_REVERSE },
-        [CAL_COLOR_HEADER]     = { "header",     ""               },
+       [CAL_COLOR_TODAY]      = { "today",      UL_COLOR_REVERSE },
+       [CAL_COLOR_WEEKNUMBER] = { "weeknumber", UL_COLOR_REVERSE },    /* requested week */
+       [CAL_COLOR_WEEKS]      = { "weeks",      ""               },    /* week numbers */
+       [CAL_COLOR_HEADER]     = { "header",     ""               },
        [CAL_COLOR_WORKDAY]    = { "workday",    ""               },
        [CAL_COLOR_WEEKEND]    = { "weekend",    ""               }
 };
@@ -407,6 +409,8 @@ int main(int argc, char **argv)
                        break;
                case 'w':
                        if (optarg) {
+                               if (*optarg == '=')
+                                       optarg++;
                                ctl.req.week = strtos32_or_err(optarg,
                                                _("invalid week argument"));
                                if (ctl.req.week < 1 || 54 < ctl.req.week)
@@ -517,10 +521,13 @@ int main(int argc, char **argv)
                }
                break;
        case 0:
-               ctl.req.day = local_time.tm_yday + 1;
+               if (!ctl.req.week) {
+                       ctl.req.day = local_time.tm_yday + 1;
+                       if (!ctl.req.month)
+                               ctl.req.month = local_time.tm_mon + 1;
+               }
                ctl.req.year = local_time.tm_year + 1900;
-               if (!ctl.req.month)
-                       ctl.req.month = local_time.tm_mon + 1;
+
                break;
        default:
                warnx(_("bad usage"));
@@ -859,6 +866,13 @@ static void cal_output_months(struct cal_month *month, const struct cal_control
        const char *seq_we_start = cal_get_color_sequence(CAL_COLOR_WEEKEND);
        const char *seq_we_end = cal_get_color_disable_sequence(CAL_COLOR_WEEKEND);
 
+       const char *seq_ws_start = NULL, *seq_ws_end = NULL;
+
+       if (ctl->weektype) {
+               seq_ws_start = cal_get_color_sequence(CAL_COLOR_WEEKS);
+               seq_ws_end = cal_get_color_disable_sequence(CAL_COLOR_WEEKS);
+       }
+
        for (week_line = 0; week_line < MAXDAYS / DAYS_IN_WEEK; week_line++) {
                for (i = month; i; i = i->next) {
                        /* Determine the day that should be highlighted. */
@@ -874,11 +888,21 @@ static void cal_output_months(struct cal_month *month, const struct cal_control
 
                        if (ctl->weektype) {
                                if (0 < i->weeks[week_line]) {
-                                       if ((ctl->weektype & WEEK_NUM_MASK) == i->weeks[week_line])
-                                               printf("%s%2d%s",
-                                                      cal_get_color_sequence(CAL_COLOR_WEEKNUMBER),
-                                                      i->weeks[week_line],
-                                                      cal_get_color_disable_sequence(CAL_COLOR_WEEKNUMBER));
+                                       const char *seq_start, *seq_end;
+
+                                       /* colorize by requested week-number or generic weeks color */
+                                       if (ctl->req.week &&
+                                           ctl->req.week == i->weeks[week_line]) {
+                                               seq_start = cal_get_color_sequence(CAL_COLOR_WEEKNUMBER);
+                                               seq_end = cal_get_color_disable_sequence(CAL_COLOR_WEEKNUMBER);
+                                       } else {
+                                               seq_start = seq_ws_start;
+                                               seq_end = seq_ws_end;
+                                       }
+
+                                       if (seq_start && *seq_start)
+                                               printf("%s%2d%s", seq_start,
+                                                      i->weeks[week_line], seq_end);
                                        else
                                                printf("%2d", i->weeks[week_line]);
                                } else