Karel Zak wrote: > Hi Pádraig, > > On Wed, Jan 02, 2008 at 04:55:59PM +0000, Pádraig Brady wrote: >> 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. > > really? That's news for me. Well just inspecting the code implied to me that it was a long standing bug, not something recently introduced. >> 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. > > Please, try > > LANG=cs_CZ.utf8 ./cal -j 2008 > > weekday alignment in the second column is incorrect. True. Can you try the attached patch instead. It also biases the alignment in center_str() to right alignment which makes sense I think, since we're usually aligning to numbers. > >> - center_str(str, lineout, SIZE(lineout), len); >> + (void) center_str(str, lineout, SIZE(lineout), len); > ^^^^ > why (void)? Just explicitly ignoring the new returned value. thanks, Pádraig.
>From e283e24e50f6f76d5cf1705a2f14105d9a99860b Mon Sep 17 00:00:00 2001 From: =?utf-8?q?P=C3=A1draig=20Brady?= <P@xxxxxxxxxxxxxx> Date: Fri, 4 Jan 2008 10:44:53 +0000 Subject: [PATCH] Fix weekday alignment for certain locales For example this had too much padding: LANG=zh_CN.utf8 cal -j while this had too little padding: LANG=hu_HU.utf8 cal Signed-off-by: Pádraig Brady <P@xxxxxxxxxxxxxx> --- misc-utils/cal.c | 52 ++++++++++++++++++++++------------------------------ 1 files changed, 22 insertions(+), 30 deletions(-) diff --git a/misc-utils/cal.c b/misc-utils/cal.c index fd2700f..716dfd7 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,27 +414,22 @@ 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)); + if (i) + strcat(cur_dh++, " "); space_left = sizeof(day_headings) - (cur_dh - day_headings); - if(space_left <= 0) - break; - cur_dh += wcstombs(cur_dh, day_headings_wc, space_left); - - space_left = sizeof(j_day_headings)-(cur_j_dh-j_day_headings); - if(space_left <= 0) - break; - cur_j_dh += wcstombs(cur_j_dh,j_day_headings_wc, space_left); -#else - sprintf(eos(day_headings), "%2.2s ", weekday(wd)); - sprintf(eos(j_day_headings), "%3.3s ", weekday(wd)); -#endif + if(space_left <= 2) + break; + cur_dh += center_str(weekday(wd), cur_dh, space_left, 2); + + if (i) + strcat(cur_j_dh++, " "); + space_left = sizeof(j_day_headings) - (cur_j_dh - j_day_headings); + if(space_left <= 3) + break; + cur_j_dh += center_str(weekday(wd), cur_j_dh, space_left, 3); } - trim_trailing_spaces(day_headings); - trim_trailing_spaces(j_day_headings); #undef weekday for (i = 0; i < 12; i++) { @@ -452,7 +443,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 +455,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); + (void) 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); @@ -755,8 +746,9 @@ trim_trailing_spaces(s) /* * Center string, handling multibyte characters appropriately. * In addition if the string is too large for the width it's truncated. + * The number of trailing spaces may be 1 less than the number of leading spaces. */ -void +int center_str(const char* src, char* dest, size_t dest_size, int width) { #ifdef HAVE_WIDECHAR @@ -790,10 +782,10 @@ 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", - spaces / 2, "", + return snprintf(dest, dest_size, "%*s%s%*s", + spaces / 2 + spaces % 2, "", str_to_print, - spaces / 2 + spaces % 2, "" ); + spaces / 2, "" ); } void @@ -803,7 +795,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