Mattiassich Ákos wrote: > Hi, > > I've found this bug originaly in the ubuntu package, but it > is in 2.13-rc1 also reproducible. > The weekdays are not aligned to the columns of the calendar. > cal -3 has an awful output. Yes that is a long standing bug. Your proposed patch will break other locales though. It would be great if you could test the attached patch, which reuses my center_str() function to do the alignment. thanks, Pádraig.
>From db509369fcb57f3120a17cc5e6e7037628047e21 Mon Sep 17 00:00:00 2001 From: =?utf-8?q?P=C3=A1draig=20Brady?= <P@xxxxxxxxxxxxxx> Date: Wed, 2 Jan 2008 16:56:40 +0000 Subject: [PATCH] Fix weekday alignment for the case where single chars are used for weekday abbreviations in a user's locale. This was the case for the hu_HU.utf8 locale at least. Signed-off-by: Pádraig Brady <P@xxxxxxxxxxxxxx> --- misc-utils/cal.c | 34 +++++++++++++++------------------- 1 files changed, 15 insertions(+), 19 deletions(-) diff --git a/misc-utils/cal.c b/misc-utils/cal.c index fd2700f..3d308e8 100644 --- a/misc-utils/cal.c +++ b/misc-utils/cal.c @@ -241,7 +241,7 @@ struct fmt_st }; char * ascii_day(char *, int); -void center_str(const char* src, char* dest, size_t dest_size, int width); +int center_str(const char* src, char* dest, size_t dest_size, int width); void center(const char *, int, int); void day_array(int, int, int, int *); int day_in_week(int, int, int); @@ -399,11 +399,7 @@ void headers_init(void) { int i, wd; #ifdef HAVE_WIDECHAR - wchar_t day_headings_wc[22],j_day_headings_wc[29]; char *cur_dh = day_headings, *cur_j_dh = j_day_headings; - - wcscpy(day_headings_wc, L""); - wcscpy(j_day_headings_wc, L""); #endif strcpy(day_headings,""); @@ -418,19 +414,19 @@ void headers_init(void) for(i = 0 ; i < 7 ; i++ ) { ssize_t space_left; wd = (i + week1stday) % 7; -#ifdef HAVE_WIDECHAR - swprintf(day_headings_wc, SIZE(day_headings_wc), L"%1.2s ", weekday(wd)); - swprintf(j_day_headings_wc, SIZE(j_day_headings_wc), L"%3.3s ", weekday(wd)); +#ifdef HAVE_WIDECHAR space_left = sizeof(day_headings) - (cur_dh - day_headings); - if(space_left <= 0) + if(space_left <= 1) break; - cur_dh += wcstombs(cur_dh, day_headings_wc, space_left); + cur_dh += center_str(weekday(wd), cur_dh, space_left, 2); + strcat(cur_dh++, " "); - space_left = sizeof(j_day_headings)-(cur_j_dh-j_day_headings); - if(space_left <= 0) + space_left = sizeof(j_day_headings) - (cur_j_dh - j_day_headings); + if(space_left <= 1) break; - cur_j_dh += wcstombs(cur_j_dh,j_day_headings_wc, space_left); + cur_j_dh += center_str(weekday(wd), cur_j_dh, space_left, 3); + strcat(cur_j_dh++, " "); #else sprintf(eos(day_headings), "%2.2s ", weekday(wd)); sprintf(eos(j_day_headings), "%3.3s ", weekday(wd)); @@ -452,7 +448,7 @@ void headers_init(void) void do_monthly(int day, int month, int year, struct fmt_st *out) { - int col, row, len, days[MAXDAYS]; + int col, row, days[MAXDAYS]; char *p, lineout[FMT_ST_CHARS]; int width = (julian ? J_WEEK_LEN : WEEK_LEN) - 1; @@ -464,8 +460,8 @@ do_monthly(int day, int month, int year, struct fmt_st *out) { * Basque the translation should be: "%2$dko %1$s", and * the Vietnamese should be "%s na(m %d", etc. */ - len = sprintf(lineout, _("%s %d"), full_month[month - 1], year); - center_str(lineout, out->s[0], SIZE(out->s[0]), width); + sprintf(lineout, _("%s %d"), full_month[month - 1], year); + (void) center_str(lineout, out->s[0], SIZE(out->s[0]), width); sprintf(out->s[1],"%s", julian ? j_day_headings : day_headings); @@ -756,7 +752,7 @@ trim_trailing_spaces(s) * Center string, handling multibyte characters appropriately. * In addition if the string is too large for the width it's truncated. */ -void +int center_str(const char* src, char* dest, size_t dest_size, int width) { #ifdef HAVE_WIDECHAR @@ -790,7 +786,7 @@ center_str(const char* src, char* dest, size_t dest_size, int width) spaces = width - len; spaces = ( spaces < 0 ? 0 : spaces ); - snprintf(dest, dest_size, "%*s%s%*s", + return snprintf(dest, dest_size, "%*s%s%*s", spaces / 2, "", str_to_print, spaces / 2 + spaces % 2, "" ); @@ -803,7 +799,7 @@ center(str, len, separate) int separate; { char lineout[FMT_ST_CHARS]; - center_str(str, lineout, SIZE(lineout), len); + (void) center_str(str, lineout, SIZE(lineout), len); fputs(lineout, stdout); if (separate) (void)printf("%*s", separate, ""); -- 1.5.3.6