ncal: add -M to start week on Monday in cal mode

MFC after: 2 weeks
Reviewed by: imp, Alexander Ziaee,
Pull Request: https://github.com/freebsd/freebsd-src/pull/1294
This commit is contained in:
Valentine Astakhov 2024-06-17 20:58:02 +03:00 committed by Warner Losh
parent 0bff716674
commit 8c108b341c
2 changed files with 33 additions and 17 deletions

View file

@ -1,3 +1,6 @@
.\"-
.\" SPDX-License-Identifier: BSD-2-Clause
.\"
.\" Copyright (c) 1997 Wolfgang Helbig
.\" All rights reserved.
.\"
@ -31,7 +34,7 @@
.Nd displays a calendar and the date of Easter
.Sh SYNOPSIS
.Nm
.Op Fl 3hjy
.Op Fl 3hjMy
.Op Fl A Ar number
.Op Fl B Ar number
.Oo
@ -39,7 +42,7 @@
.Ar year
.Oc
.Nm
.Op Fl 3hj
.Op Fl 3hjM
.Op Fl A Ar number
.Op Fl B Ar number
.Fl m Ar month
@ -85,6 +88,10 @@ option, display date of Easter according to the Julian Calendar.
Display date of Easter (for western churches).
.It Fl j
Display Julian days (days one-based, numbered from January 1).
.It Fl M
Display Monday as the first day of the week in
.Nm cal
mode.
.It Fl m Ar month
Display the specified
.Ar month .
@ -186,7 +193,7 @@ X/Open System Interfaces option of the
specification.
.Pp
The flags
.Op Fl 3hyJeopw ,
.Op Fl 3ehJMopwy ,
as well as the ability to specify a month name as a single argument,
are extensions to that specification.
.Pp
@ -215,6 +222,3 @@ codes is historically naive for many countries.
.Pp
Not all options are compatible and using them in different orders
will give varying results.
.Pp
It is not possible to display Monday as the first day of the week with
.Nm cal .

View file

@ -36,6 +36,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <sysexits.h>
#include <time.h>
#include <unistd.h>
@ -162,6 +163,7 @@ static int flag_weeks; /* user wants number of week */
static int nswitch; /* user defined switch date */
static int nswitchb; /* switch date for backward compatibility */
static int highlightdate;
static bool flag_monday; /* user wants week starts on Monday */
static char *center(char *s, char *t, int w);
static wchar_t *wcenter(wchar_t *s, wchar_t *t, int w);
@ -216,6 +218,7 @@ main(int argc, char *argv[])
flag_nohighlight = 0;
flag_weeks = 0;
flag_monday = false;
/*
* Use locale to determine the country code,
@ -256,7 +259,7 @@ main(int argc, char *argv[])
before = after = -1;
while ((ch = getopt(argc, argv, "3A:B:Cd:eH:hjJm:Nops:wy")) != -1)
while ((ch = getopt(argc, argv, "3A:B:Cd:eH:hjJm:Nops:wyM")) != -1)
switch (ch) {
case '3':
flag_3months = 1;
@ -306,6 +309,9 @@ main(int argc, char *argv[])
case 'j':
flag_julian_day = 1;
break;
case 'M':
flag_monday = true;
break;
case 'm':
if (flag_specifiedmonth)
errx(EX_USAGE, "Double -m specified");
@ -509,7 +515,7 @@ usage(void)
" cal [general options] [-hj] [-m month] [year]\n"
" ncal [general options] [-hJjpwy] [-s country_code] [[month] year]\n"
" ncal [general options] [-hJeo] [year]\n"
"General options: [-NC3] [-A months] [-B months]\n"
"General options: [-NCM3] [-A months] [-B months]\n"
"For debug the highlighting: [-H yyyy-mm-dd] [-d yyyy-mm]\n",
stderr);
exit(EX_USAGE);
@ -652,10 +658,13 @@ monthrangeb(int y, int m, int jd_flag, int before, int after)
/* Day of the week names. */
for (i = 0; i < count; i++) {
wprintf(L"%s%ls%s%ls%s%ls%s%ls%s%ls%s%ls%s%ls ",
wdss, wds.names[6], wdss, wds.names[0],
wdss, wds.names[1], wdss, wds.names[2],
wdss, wds.names[3], wdss, wds.names[4],
wdss, wds.names[5]);
wdss, wds.names[flag_monday ? 0 : 6],
wdss, wds.names[flag_monday ? 1 : 0],
wdss, wds.names[flag_monday ? 2 : 1],
wdss, wds.names[flag_monday ? 3 : 2],
wdss, wds.names[flag_monday ? 4 : 3],
wdss, wds.names[flag_monday ? 5 : 4],
wdss, wds.names[flag_monday ? 6 : 5]);
}
printf("\n");
@ -860,7 +869,7 @@ mkmonthb(int y, int m, int jd_flag, struct monthlines *mlines)
date dt; /* handy date */
int dw; /* width of numbers */
int first; /* first day of month */
int firsts; /* sunday of first week of month */
int firstsm; /* sunday or monday of first week of month */
int i, j, k, l; /* just indices */
int jan1 = 0; /* the first day of this year */
int last; /* the first day of next month */
@ -911,10 +920,13 @@ mkmonthb(int y, int m, int jd_flag, struct monthlines *mlines)
}
/*
* Set firsts to the day number of sunday of the first week of
* this month. (This might be in the last month)
* Set firstsm to the day number of sunday or monday of the first week
* of this month. (This might be in the last month)
*/
firsts = first - (weekday(first)+1) % 7;
if (flag_monday)
firstsm = first - weekday(first);
else
firstsm = first - (weekday(first) + 1) % 7;
/*
* Fill the lines with day of month or day of year (Julian day)
@ -923,7 +935,7 @@ mkmonthb(int y, int m, int jd_flag, struct monthlines *mlines)
*/
for (i = 0; i != 6; i++) {
l = 0;
for (j = firsts + 7 * i, k = 0; j < last && k != dw * 7;
for (j = firstsm + 7 * i, k = 0; j < last && k != dw * 7;
j++, k += dw) {
if (j >= first) {
if (jd_flag)