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?= <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
---
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