All of lore.kernel.org
 help / color / mirror / Atom feed
From: Carles Pina i Estany <carles@pina.cat>
To: grub-devel@gnu.org
Subject: Re: gettext.c patch: reuse memory
Date: Sun, 29 Nov 2009 18:36:34 +0000	[thread overview]
Message-ID: <20091129183634.GA19323@pina.cat> (raw)
In-Reply-To: <20091129103625.GA31541@pina.cat>

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


Hi,

On Nov/29/2009, Carles Pina i Estany wrote:

> Find attached a new version of the same patch (same approach).

new one. Original strings can be free-ed.

Just some numbers: if there are 1000 strings used (far too much! Grub
loader will not have so much or users will not use in the same session)
and each string is 50 characters (far too much too :-) ) strings are
usually shorter) and the translation is 50 characters the list will use
aprox. 100 KB.

(50 + 50) * 1000 / 1024 = 97.65 KB

(very rough numbers discarting 1000 pointers to next and 2000 pointers
to the original and translation strings, this would be aprox. 11.71 KB
more)

Cheers,

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

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

=== modified file 'gettext/gettext.c'
--- gettext/gettext.c	2009-11-24 21:42:14 +0000
+++ gettext/gettext.c	2009-11-29 18:29:02 +0000
@@ -17,6 +17,7 @@
  *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <grub/list.h>
 #include <grub/types.h>
 #include <grub/misc.h>
 #include <grub/mm.h>
@@ -33,7 +34,6 @@
    http://www.gnu.org/software/autoconf/manual/gettext/MO-Files.html .
 */
 
-
 static grub_file_t fd_mo;
 
 static int grub_gettext_offsetoriginal;
@@ -41,6 +41,16 @@ static int grub_gettext_max;
 
 static const char *(*grub_gettext_original) (const char *s);
 
+struct grub_gettext_msg
+{
+  struct grub_gettext_msg *next;
+  const char *name;
+
+  const char *translated;
+};
+
+struct grub_gettext_msg *grub_gettext_msg_list = NULL;
+
 #define GETTEXT_MAGIC_NUMBER 		0
 #define GETTEXT_FILE_FORMAT		4
 #define GETTEXT_NUMBER_OF_STRINGS 	8
@@ -79,7 +89,7 @@ grub_gettext_getstring_from_offset (grub
   translation[length] = '\0';
 }
 
-static char *
+static const char *
 grub_gettext_gettranslation_from_position (int position)
 {
   int offsettranslation;
@@ -130,9 +140,18 @@ static const char *
 grub_gettext_translate (const char *orig)
 {
   char *current_string;
-  char *ret;
+  const char *ret;
 
   int min, max, current;
+  int found = 0;
+
+  struct grub_gettext_msg *cur;
+
+  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_gettext_msg_list),
+			      orig);
+
+  if (cur)
+    return cur->translated;
 
   if (fd_mo == 0)
     return orig;
@@ -142,7 +161,7 @@ grub_gettext_translate (const char *orig
 
   current = (max + min) / 2;
 
-  while (current != min && current != max)
+  while (current != min && current != max && found == 0)
     {
       current_string = grub_gettext_getstring_from_position (current);
 
@@ -160,13 +179,31 @@ grub_gettext_translate (const char *orig
       else if (grub_strcmp (current_string, orig) == 0)
 	{
 	  grub_free (current_string);
-	  return grub_gettext_gettranslation_from_position (current);
+	  found = 1;
 	}
       current = (max + min) / 2;
     }
 
-  ret = grub_malloc (grub_strlen (orig) + 1);
-  grub_strcpy (ret, orig);
+  ret = found ? grub_gettext_gettranslation_from_position (current) : orig;
+
+  if (found)
+    {
+      cur = grub_zalloc (sizeof (*cur));
+
+      if (cur)
+	{
+	  cur->name = grub_strdup (orig);
+	  if (cur->name)
+	    {
+	      cur->translated = ret;
+	      grub_list_push (GRUB_AS_LIST_P (&grub_gettext_msg_list),
+			      GRUB_AS_LIST (cur));
+	    }
+	}
+      else
+	grub_errno = GRUB_ERR_NONE;
+    }
+
   return ret;
 }
 
@@ -259,12 +296,29 @@ grub_gettext_init_ext (const char *lang)
     }
 }
 
+static void
+grub_gettext_delete_list ()
+{
+  struct grub_gettext_msg *item;
+
+  while ((item =
+	  grub_list_pop (GRUB_AS_LIST_P (&grub_gettext_msg_list))) != 0)
+    {
+      char* original = (char*) ((struct grub_gettext_msg *) item)->name;
+      grub_free (original);
+
+      // Don't delete the translated message because could be in use.
+    }
+}
+
 static char *
 grub_gettext_env_write_lang (struct grub_env_var *var
 			     __attribute__ ((unused)), const char *val)
 {
   grub_gettext_init_ext (val);
 
+  grub_gettext_delete_list ();
+
   return grub_strdup (val);
 }
 
@@ -307,5 +361,7 @@ GRUB_MOD_FINI (gettext)
   if (fd_mo != 0)
     grub_file_close (fd_mo);
 
+  grub_gettext_delete_list ();
+
   grub_gettext = grub_gettext_original;
 }


[-- Attachment #3: ChangeLog.memory --]
[-- Type: text/plain, Size: 520 bytes --]

2009-11-29  Carles Pina i Estany <carles@pina.cat>

	* gettext/gettext.c: Include `<grub/list.h>'. Define grub_gettext_msg,
	grub_gettext_msg_list.
	(grub_gettext_gettranslation_from_position): Return static const char *
	and not static char *
	(grub_gettext_translate): Add the translated strings into a list, 
	returns from the list if existing there.
	(grub_gettext_delete_list): Delete the list.
	(grub_gettext_env_write_lang): Call grub_gettext_delete_list changes
	the language.
	(GRUB_MOD_FINI): Delete the list.

  reply	other threads:[~2009-11-29 18:36 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-11-29  0:49 gettext.c patch: reuse memory Carles Pina i Estany
2009-11-29  3:28 ` Robert Millan
2009-11-29  9:36   ` Carles Pina i Estany
2009-11-29 10:36 ` Carles Pina i Estany
2009-11-29 18:36   ` Carles Pina i Estany [this message]
2009-11-29 19:40     ` 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=20091129183634.GA19323@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.