All of lore.kernel.org
 help / color / mirror / Atom feed
From: Carles Pina i Estany <carles@pina.cat>
To: grub-devel@gnu.org
Subject: gettext: print_timeout
Date: Sun, 13 Dec 2009 01:31:55 +0000	[thread overview]
Message-ID: <20091213013155.GA13074@pina.cat> (raw)

[-- Attachment #1: Type: text/plain, Size: 1249 bytes --]


Hello,

Find attached a patch about print_timeout.

Until now print_timeout had some problems with multi-byte / multi-width
characters. Now it's fixed, printing all sentence every time as
commented in the IRC.

I would like to comment two things:

+  char *msg_formatted = grub_malloc (sizeof (char) *
+                        (grub_strlen (msg) + 1 + 6));
+                        /* 5: max string length that `timeout' can
have.  */

timeout is a int, so the maximum string length that can do is -32768
(makes, no sense, I know). I could calculate the length of the string of
the int in base 10 dividing by 10 multiple times but I think that
allocating space for 6 position is more than enough, actually
grub_strlen already allocates 2 sizeof (char) (because %d). I mean, I
can add code to save some bytes in memory. Any better and simpler way?

Other thing to clarify:
+  print_spaces (GRUB_TERM_WIDTH - strwidth - 3);

The line is printing spaces from the end of the string until the end of
the line (GRUB_TERM_WIDTH). I'm not assuming that the new string with
the new timeout is one char shorter like it happens in English because
the plurals in some languages can break it.

If ok I would commit.

-- 
Carles Pina i Estany
	http://pinux.info

[-- Attachment #2: print_timeout.patch --]
[-- Type: text/x-diff, Size: 3894 bytes --]

=== modified file 'ChangeLog'
--- ChangeLog	2009-12-12 00:43:32 +0000
+++ ChangeLog	2009-12-13 00:44:09 +0000
@@ -1,3 +1,10 @@
+2009-12-13  Carles Pina i Estany  <carles@pina.cat>
+
+	* normal/menu_text.c (utf8_to_ucs4): New definition.
+	(print_message_indented): Use `utf8_to_ucs'.
+	(print_timeout): Prints the whole string so avoid problems with
+	multi-byte and multi-width characters.
+
 2009-12-12  Robert Millan  <rmh@aybabtu.com>
 
 	* gendistlist.sh (EXTRA_DISTFILES): Add `genvideolist.sh'.

=== modified file 'normal/menu_text.c'
--- normal/menu_text.c	2009-12-08 00:08:52 +0000
+++ normal/menu_text.c	2009-12-13 01:26:09 +0000
@@ -77,35 +77,50 @@ getstringwidth (grub_uint32_t * str, con
   return width;
 }
 
+static int
+utf8_to_ucs4 (const char *msg, grub_uint32_t **unicode_msg,
+			grub_uint32_t **last_position)
+{
+  grub_ssize_t msg_len = grub_strlen (msg);
+
+  *unicode_msg = grub_malloc (grub_strlen (msg) * sizeof (grub_uint32_t));
+  
+  if (!*unicode_msg)
+    {
+      grub_printf ("utf8_to_ucs4 ERROR1: %s", msg);
+      return -1;
+    }
+
+  msg_len = grub_utf8_to_ucs4 (*unicode_msg, msg_len,
+  			      (grub_uint8_t *) msg, -1, 0);
+
+  *last_position = *unicode_msg + msg_len;
+
+  if (msg_len < 0)
+    {
+      grub_printf ("utf8_to_ucs4 ERROR2: %s", msg);
+      grub_free (*unicode_msg);
+    }
+  return msg_len;
+}
+
 static void
 print_message_indented (const char *msg)
 {
   const int line_len = GRUB_TERM_WIDTH - grub_getcharwidth ('m') * 15;
 
   grub_uint32_t *unicode_msg;
+  grub_uint32_t *last_position;
 
-  grub_ssize_t msg_len = grub_strlen (msg);
-
-  unicode_msg = grub_malloc (msg_len * sizeof (*unicode_msg));
+  int msg_len;
 
-  msg_len = grub_utf8_to_ucs4 (unicode_msg, msg_len,
-                              (grub_uint8_t *) msg, -1, 0);
-
-  if (!unicode_msg)
-    {
-      grub_printf ("print_message_indented ERROR1: %s", msg);
-      return;
-    }
+  msg_len = utf8_to_ucs4 (msg, &unicode_msg, &last_position);
 
   if (msg_len < 0)
     {
-      grub_printf ("print_message_indented ERROR2: %s", msg);
-      grub_free (unicode_msg);
       return;
     }
 
-  const grub_uint32_t *last_position = unicode_msg + msg_len;
-
   grub_uint32_t *current_position = unicode_msg;
 
   grub_uint32_t *next_new_line = unicode_msg;
@@ -368,22 +383,39 @@ get_entry_number (const char *name)
 }
 
 static void
-print_timeout (int timeout, int offset, int second_stage)
+print_timeout (int timeout, int offset,
+	       int second_stage __attribute__ ((unused)))
 {
   const char *msg =
     _("The highlighted entry will be booted automatically in %ds.");
-  const int msg_localized_len = grub_strlen (msg);
-  const int number_spaces = GRUB_TERM_WIDTH - msg_localized_len - 3;
 
-  char *msg_end = grub_strchr (msg, '%');
+  char *msg_formatted = grub_malloc (sizeof (char) *
+                        (grub_strlen (msg) + 1 + 6));
+                        /* 5: max string length that `timeout' can have.  */
+
+  grub_sprintf (msg_formatted, msg, timeout);
+
+  grub_uint32_t *unicode_msg;
+  grub_uint32_t *last_position;
+
+  int msg_len = utf8_to_ucs4 (msg_formatted, &unicode_msg, &last_position);
+  if (msg_len < 0)
+    {
+      return;
+    }
 
-  grub_gotoxy (second_stage ? (msg_end - msg + 3) : 3, GRUB_TERM_HEIGHT - 3);
-  grub_printf (second_stage ? msg_end : msg, timeout);
-  print_spaces (second_stage ? number_spaces : 0);
+  grub_gotoxy (3, GRUB_TERM_HEIGHT - 3);
+  grub_print_ucs4 (unicode_msg, last_position);
+
+  int strwidth = getstringwidth (unicode_msg, last_position);
+
+  print_spaces (GRUB_TERM_WIDTH - strwidth - 3);
+  
+  grub_free(unicode_msg);
 
   grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset);
   grub_refresh ();
-};
+}
 
 /* Show the menu and handle menu entry selection.  Returns the menu entry
    index that should be executed or -1 if no entry should be executed (e.g.,


             reply	other threads:[~2009-12-13  1:31 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-12-13  1:31 Carles Pina i Estany [this message]
2009-12-24 21:23 ` gettext: print_timeout Robert Millan
2009-12-24 22:38   ` Carles Pina i Estany
  -- strict thread matches above, loose matches on Subject: below --
2009-12-11 23:53 Carles Pina i Estany

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20091213013155.GA13074@pina.cat \
    --to=carles@pina.cat \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.