Re: cal(1): faulty weekday alignment for hungarian locale

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux