Date: Sat, 14 Mar 2009 18:55:51 +0000 (UTC) From: David Schultz <das@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r189804 - head/usr.bin/ncal Message-ID: <200903141855.n2EItpnp004551@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: das Date: Sat Mar 14 18:55:51 2009 New Revision: 189804 URL: http://svn.freebsd.org/changeset/base/189804 Log: Multibyte character support for cal(1). PR: 131578 Modified: head/usr.bin/ncal/ncal.1 head/usr.bin/ncal/ncal.c Modified: head/usr.bin/ncal/ncal.1 ============================================================================== --- head/usr.bin/ncal/ncal.1 Sat Mar 14 18:24:15 2009 (r189803) +++ head/usr.bin/ncal/ncal.1 Sat Mar 14 18:55:51 2009 (r189804) @@ -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. Modified: head/usr.bin/ncal/ncal.c ============================================================================== --- head/usr.bin/ncal/ncal.c Sat Mar 14 18:24:15 2009 (r189803) +++ head/usr.bin/ncal/ncal.c Sat Mar 14 18:55:51 2009 (r189804) @@ -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 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, struc /* 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, stru /* 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) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200903141855.n2EItpnp004551>