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

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

 



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


[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