Multibyte character support for cal(1).
PR: 131578
This commit is contained in:
parent
24863729f9
commit
4646cea766
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=189804
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd October 23, 2005
|
||||
.Dd March 14, 2009
|
||||
.Dt CAL 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -142,7 +142,3 @@ command and manual were written by
|
||||
.Sh BUGS
|
||||
The assignment of Julian\(enGregorian switching dates to
|
||||
country codes is historically naive for many countries.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility does not recognize multibyte characters.
|
||||
|
@ -40,6 +40,8 @@ static const char rcsid[] =
|
||||
#include <sysexits.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
|
||||
/* Width of one month with backward compatibility */
|
||||
#define MONTH_WIDTH_B_J 27
|
||||
@ -53,13 +55,13 @@ static const char rcsid[] =
|
||||
typedef struct date date;
|
||||
|
||||
struct monthlines {
|
||||
char name[MAX_WIDTH + 1];
|
||||
wchar_t name[MAX_WIDTH + 1];
|
||||
char lines[7][MAX_WIDTH + 1];
|
||||
char weeks[MAX_WIDTH + 1];
|
||||
};
|
||||
|
||||
struct weekdays {
|
||||
char names[7][4];
|
||||
wchar_t names[7][4];
|
||||
};
|
||||
|
||||
/* The switches from Julian to Gregorian in some countries */
|
||||
@ -159,6 +161,7 @@ int nswitch; /* user defined switch date */
|
||||
int nswitchb; /* switch date for backward compatibility */
|
||||
|
||||
char *center(char *s, char *t, int w);
|
||||
wchar_t *wcenter(wchar_t *s, wchar_t *t, int w);
|
||||
void mkmonth(int year, int month, int jd_flag, struct monthlines * monthl);
|
||||
void mkmonthb(int year, int month, int jd_flag, struct monthlines * monthl);
|
||||
void mkweekdays(struct weekdays * wds);
|
||||
@ -418,9 +421,9 @@ printmonth(int y, int m, int jd_flag)
|
||||
|
||||
mkmonth(y, m - 1, jd_flag, &month);
|
||||
mkweekdays(&wds);
|
||||
printf(" %s %d\n", month.name, y);
|
||||
printf(" %ls %d\n", month.name, y);
|
||||
for (i = 0; i != 7; i++)
|
||||
printf("%.2s%s\n", wds.names[i], month.lines[i]);
|
||||
printf("%.2ls%s\n", wds.names[i], month.lines[i]);
|
||||
if (flag_weeks)
|
||||
printf(" %s\n", month.weeks);
|
||||
}
|
||||
@ -430,7 +433,7 @@ printmonthb(int y, int m, int jd_flag)
|
||||
{
|
||||
struct monthlines month;
|
||||
struct weekdays wds;
|
||||
char s[MAX_WIDTH], t[MAX_WIDTH];
|
||||
wchar_t s[MAX_WIDTH], t[MAX_WIDTH];
|
||||
int i;
|
||||
int mw;
|
||||
|
||||
@ -439,16 +442,17 @@ printmonthb(int y, int m, int jd_flag)
|
||||
|
||||
mw = jd_flag ? MONTH_WIDTH_B_J : MONTH_WIDTH_B;
|
||||
|
||||
sprintf(s, "%s %d", month.name, y);
|
||||
printf("%s\n", center(t, s, mw));
|
||||
swprintf(s, MAX_WIDTH, L"%ls %d", month.name, y);
|
||||
wprintf(L"%ls\n", wcenter(t, s, mw));
|
||||
|
||||
if (jd_flag)
|
||||
printf(" %s %s %s %s %s %s %.2s\n", wds.names[6], wds.names[0],
|
||||
wprintf(L" %ls %ls %ls %ls %ls %ls %.2ls\n",
|
||||
wds.names[6], wds.names[0],
|
||||
wds.names[1], wds.names[2], wds.names[3],
|
||||
wds.names[4], wds.names[5]);
|
||||
else
|
||||
printf("%s%s%s%s%s%s%.2s\n", wds.names[6], wds.names[0],
|
||||
wds.names[1], wds.names[2], wds.names[3],
|
||||
wprintf(L"%ls%ls%ls%ls%ls%ls%.2ls\n", wds.names[6],
|
||||
wds.names[0], wds.names[1], wds.names[2], wds.names[3],
|
||||
wds.names[4], wds.names[5]);
|
||||
|
||||
for (i = 0; i != 6; i++)
|
||||
@ -475,17 +479,17 @@ printyear(int y, int jd_flag)
|
||||
printf("%s\n", center(t, s, mpl * mw));
|
||||
|
||||
for (j = 0; j != 12; j += mpl) {
|
||||
printf(" %-*s%-*s",
|
||||
printf(" %-*ls%-*ls",
|
||||
mw, year[j].name,
|
||||
mw, year[j + 1].name);
|
||||
if (mpl == 3)
|
||||
printf("%s\n", year[j + 2].name);
|
||||
printf("%ls\n", year[j + 2].name);
|
||||
else
|
||||
printf("%-*s%s\n",
|
||||
printf("%-*ls%ls\n",
|
||||
mw, year[j + 2].name,
|
||||
year[j + 3].name);
|
||||
for (i = 0; i != 7; i++) {
|
||||
printf("%.2s%-*s%-*s",
|
||||
printf("%.2ls%-*s%-*s",
|
||||
wds.names[i],
|
||||
mw, year[j].lines[i],
|
||||
mw, year[j + 1].lines[i]);
|
||||
@ -518,6 +522,7 @@ printyearb(int y, int jd_flag)
|
||||
struct monthlines year[12];
|
||||
struct weekdays wds;
|
||||
char s[80], t[80];
|
||||
wchar_t ws[80], wt[80];
|
||||
int i, j;
|
||||
int mpl;
|
||||
int mw;
|
||||
@ -532,17 +537,17 @@ printyearb(int y, int jd_flag)
|
||||
printf("%s\n\n", center(t, s, mw * mpl + mpl));
|
||||
|
||||
for (j = 0; j != 12; j += mpl) {
|
||||
printf("%-*s ", mw, center(s, year[j].name, mw));
|
||||
printf("%-*ls ", mw, wcenter(ws, year[j].name, mw));
|
||||
if (mpl == 2)
|
||||
printf("%s\n", center(s, year[j + 1].name, mw));
|
||||
printf("%ls\n", wcenter(ws, year[j + 1].name, mw));
|
||||
else
|
||||
printf("%-*s %s\n", mw,
|
||||
center(s, year[j + 1].name, mw),
|
||||
center(t, year[j + 2].name, mw));
|
||||
printf("%-*ls %ls\n", mw,
|
||||
wcenter(ws, year[j + 1].name, mw),
|
||||
wcenter(wt, year[j + 2].name, mw));
|
||||
|
||||
if (mpl == 2)
|
||||
printf(" %s %s %s %s %s %s %s "
|
||||
" %s %s %s %s %s %s %.2s\n",
|
||||
wprintf(L" %ls %ls %ls %ls %ls %ls %ls "
|
||||
" %ls %ls %ls %ls %ls %ls %.2ls\n",
|
||||
wds.names[6], wds.names[0], wds.names[1],
|
||||
wds.names[2], wds.names[3], wds.names[4],
|
||||
wds.names[5],
|
||||
@ -550,9 +555,9 @@ printyearb(int y, int jd_flag)
|
||||
wds.names[2], wds.names[3], wds.names[4],
|
||||
wds.names[5]);
|
||||
else
|
||||
printf("%s%s%s%s%s%s%s "
|
||||
"%s%s%s%s%s%s%s "
|
||||
"%s%s%s%s%s%s%.2s\n",
|
||||
wprintf(L"%ls%ls%ls%ls%ls%ls%ls "
|
||||
"%ls%ls%ls%ls%ls%ls%ls "
|
||||
"%ls%ls%ls%ls%ls%ls%.2ls\n",
|
||||
wds.names[6], wds.names[0], wds.names[1],
|
||||
wds.names[2], wds.names[3], wds.names[4],
|
||||
wds.names[5],
|
||||
@ -596,8 +601,9 @@ mkmonth(int y, int m, int jd_flag, struct monthlines *mlines)
|
||||
/* Set name of month. */
|
||||
memset(&tm, 0, sizeof(tm));
|
||||
tm.tm_mon = m;
|
||||
strftime(mlines->name, sizeof(mlines->name), "%OB", &tm);
|
||||
mlines->name[0] = toupper((unsigned char)mlines->name[0]);
|
||||
wcsftime(mlines->name, sizeof(mlines->name) / sizeof(mlines->name[0]),
|
||||
L"%OB", &tm);
|
||||
mlines->name[0] = towupper(mlines->name[0]);
|
||||
|
||||
/*
|
||||
* Set first and last to the day number of the first day of this
|
||||
@ -688,8 +694,9 @@ mkmonthb(int y, int m, int jd_flag, struct monthlines *mlines)
|
||||
/* Set name of month centered */
|
||||
memset(&tm, 0, sizeof(tm));
|
||||
tm.tm_mon = m;
|
||||
strftime(mlines->name, sizeof(mlines->name), "%OB", &tm);
|
||||
mlines->name[0] = toupper((unsigned char)mlines->name[0]);
|
||||
wcsftime(mlines->name, sizeof(mlines->name) / sizeof(mlines->name[0]),
|
||||
L"%OB", &tm);
|
||||
mlines->name[0] = towupper(mlines->name[0]);
|
||||
|
||||
/*
|
||||
* Set first and last to the day number of the first day of this
|
||||
@ -754,18 +761,18 @@ mkweekdays(struct weekdays *wds)
|
||||
{
|
||||
int i, len;
|
||||
struct tm tm;
|
||||
char buf[20];
|
||||
wchar_t buf[20];
|
||||
|
||||
memset(&tm, 0, sizeof(tm));
|
||||
|
||||
for (i = 0; i != 7; i++) {
|
||||
tm.tm_wday = (i+1) % 7;
|
||||
strftime(buf, sizeof(buf), "%a", &tm);
|
||||
len = strlen(buf);
|
||||
wcsftime(buf, sizeof(buf), L"%a", &tm);
|
||||
len = wcslen(buf);
|
||||
if (len > 2)
|
||||
len = 2;
|
||||
strcpy(wds->names[i], " ");
|
||||
strncpy(wds->names[i] + 2 - len, buf, len);
|
||||
wcscpy(wds->names[i], L" ");
|
||||
wcsncpy(wds->names[i] + 2 - len, buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
@ -858,6 +865,17 @@ center(char *s, char *t, int w)
|
||||
return (s);
|
||||
}
|
||||
|
||||
/* Center string t in string s of length w by putting enough leading blanks */
|
||||
wchar_t *
|
||||
wcenter(wchar_t *s, wchar_t *t, int w)
|
||||
{
|
||||
char blanks[80];
|
||||
|
||||
memset(blanks, ' ', sizeof(blanks));
|
||||
swprintf(s, MAX_WIDTH, L"%.*s%ls", (int)(w - wcslen(t)) / 2, blanks, t);
|
||||
return (s);
|
||||
}
|
||||
|
||||
int
|
||||
parsemonth(const char *s, int *m, int *y)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user