--- ./glib/glib.symbols.intl_numbers	2006-06-02 06:06:30.000000000 +0330
+++ ./glib/glib.symbols	2006-12-29 22:12:04.000000000 +0330
@@ -1024,6 +1024,13 @@
 g_ascii_xdigit_value G_GNUC_CONST
 g_ascii_strcasecmp
 g_ascii_strncasecmp
+g_dtostr
+g_formatd
+g_formati
+g_lltostr
+g_locale_strtod
+g_locale_strtoll
+g_locale_strtoull
 g_memdup G_GNUC_MALLOC
 g_stpcpy
 g_strcanon
@@ -1055,6 +1062,8 @@
 g_strsplit_set G_GNUC_MALLOC
 g_strstr_len
 g_strtod
+g_strtoll
+g_strtoull
 #ifndef G_DISABLE_DEPRECATED
 g_strcasecmp
 g_strncasecmp
@@ -1063,6 +1072,7 @@
 #endif
 g_strv_length
 g_strip_context
+g_ulltostr
 #endif
 #endif
 
--- ./glib/gstrfuncs.c.intl_numbers	2006-06-05 19:08:04.000000000 +0330
+++ ./glib/gstrfuncs.c	2007-01-24 13:24:55.000000000 +0330
@@ -38,6 +38,7 @@
 #include <string.h>
 #include <locale.h>
 #include <errno.h>
+#include <math.h>		/* For HUGE_VAL */
 #include <ctype.h>		/* For tolower() */
 #if !defined (HAVE_STRSIGNAL) || !defined(NO_SYS_SIGLIST_DECL)
 #include <signal.h>
@@ -46,6 +47,7 @@
 #include "glib.h"
 #include "gprintf.h"
 #include "gprintfint.h"
+#include "glibintl.h"
 
 #include "galias.h"
 
@@ -242,6 +244,542 @@
   return concat;
 }
 
+/* These function are used to get numbering local information */
+static gchar *
+get_locale_zero_str ()
+{
+  /* Translators: This message is for handling localized digits. If the
+   * preferred digit forms to be used for displaying decimal numbers in your
+   * locale are not the European digits 0, 1, 2, etc, translate this to your
+   * local digit zero. glib will assume that the other digits are the next
+   * Unicode characters after the local zero.
+   *
+   * Do not translate the "locale|" part, remove it. In a Spanish locale, for
+   * example, this should be translated to "0", while in a Persian locale, it
+   * should be translated to "\u06F0".
+   */
+
+  return Q_("locale|0");
+}
+
+static gchar *
+get_locale_positive_str ()
+{
+  /* Translators: This message is for handling localized plus sign. If your
+   * preferred numeric system for your locale is not the European 
+   * system translate this to your local plus sign. 
+   * If several plus signs are used in your preferred numeric system you can
+   * include a string of acceptable characters for your numeric system. This
+   * will make the library accept any of them for plus sign but the first char
+   * is used to generate the output.     
+   *
+   * Do not translate the "locale|" part, remove it. In most locales this
+   * should be translated to "+".
+   */
+  return Q_("locale|+");
+}
+
+static gchar *
+get_locale_negative_str ()
+{
+  /* Translators: This message is for handling localized negative sign. If your
+   * preferred numeric  system for your locale is not the European 
+   * system translate this to your local negative sign. 
+   * If several negative signs are used in your preferred numeric system you
+   * can include a string of acceptable characters for your numeric system. 
+   * This will make the library accept any of them for negative but the
+   * first char is used to generate the output.     
+   *
+   * Do not translate the "locale|" part, remove it. In most locales this
+   * should be translated to "-", while on some locales the Unicode minus sign 
+   * is preferred to this for example in Persian locale this will be translated 
+   * to "\u2212-".
+   */
+  return Q_("locale|-");
+}
+
+static gchar *
+get_locale_decimal_point_str ()
+{
+  /* Translators: This message is for handling localized decimal point 
+   * separator. If your preferred numeric number system for your locale
+   * is not the European system translate this to your local decimal separator. 
+   * If several decimal separators are used in your preferred numeric system
+   * you can include a string of acceptable characters for your numeric system.
+   * This will make the library accept any of them for decimal separator but 
+   * the first char is used to generate the output.     
+   *
+   * Do not translate the "locale|" part, remove it. In most locales this
+   * should be translated to ".", while on some locales there are several 
+   * characters acceptable for this. For example in Persian locale this will
+   * be translated to "\u066B/\uFEAD."(four characters are used!).
+   */
+  return Q_("locale|.");
+}
+
+static gchar *
+get_locale_exp_str ()
+{
+  /* Translators: This message is for handling localized scientific number
+   * representation. If your preferred numeric number system for your locale
+   * is not the European system translate this to your preferred string. 
+   *
+   * In European system "e" is used for this purpose but on some locales a
+   * string is used for this. Translate this to the string which is used 
+   * to represent your locale string.
+   *
+   * Do not translate the "locale|" part, remove it. For example is Persian 
+   * locale this will be translated to "\u00D7\u06F1\u06F0^" (which is "*10^")
+   */
+  return Q_("locale|e");
+}
+
+static gunichar
+get_locale_zero_char ()
+{
+  gunichar zero = g_utf8_get_char_validated (get_locale_zero_str (), -1);
+ if (!(zero & 0x80000000) && g_unichar_digit_value (zero) == 0)
+   return zero;
+
+ g_warning("Miss translated string locale|0\n");
+ return (gunichar) '0';
+}
+
+static gunichar
+get_locale_positive_char ()
+{
+  gunichar positive_sign = g_utf8_get_char_validated ( get_locale_positive_str (), -1);
+  if (!( positive_sign & 0x80000000) && positive_sign > 0)
+    return positive_sign;
+  g_warning("Miss translated string locale|+\n");
+  return (gunichar) '+';
+}
+
+static gunichar
+get_locale_negative_char ()
+{
+  gunichar negative_sign = g_utf8_get_char_validated (get_locale_negative_str (), -1);
+  if (!( negative_sign & 0x80000000) && negative_sign > 0)
+    return negative_sign;
+  g_warning("Miss translated string locale|-\n");
+  return (gunichar) '-';
+}
+
+static gunichar
+get_locale_decimal_point_char ()
+{
+  gunichar decimal_point = g_utf8_get_char_validated (get_locale_decimal_point_str (), -1);
+  if (!( decimal_point & 0x80000000) && decimal_point > 0)
+    return decimal_point;
+  g_warning("Miss translated string locale|.\n");
+  return (gunichar) '.';
+}
+
+/**
+ * g_locale_strtod:
+ * @nptr:    the string to convert to a numeric value.
+ * @endptr:  if non-%NULL, it returns the character after
+ *	   the last character used in the conversion.
+ *
+ * Converts a string to a #gdouble value.
+ * It will use the local number system to convert to convert local 
+ * string to number. Local number system information is gathered from available
+ * translations for '0', '+', '-', '.', and 'e'.
+ *
+ * This function is useful for software internationalization. This functions is
+ * not able to read the default English numbers if there is a non-english translation 
+ * available for your locale. It can be called inside #g_strtod function to make it 
+ * work for internationalized numbers.
+ *
+ * Return value: the #gdouble value.
+ **/
+gdouble 
+g_locale_strtod (const gchar        *nptr,
+	        gchar              **endptr)
+{
+  g_return_val_if_fail (nptr != NULL, 0);
+  gboolean read_flag = FALSE;
+
+  gchar *p = nptr;
+  gunichar c = g_utf8_get_char_validated (p, -1); /* c always is the first character of p */
+
+  /* Skip Spaces in the beginning */
+  while (g_unichar_isspace (c))
+    {
+      p = g_utf8_next_char (p);
+      c = g_utf8_get_char_validated (p, -1);
+    }
+
+  /* Check for sign */
+  gchar *positive_signs = get_locale_positive_str ();
+  gchar *negative_signs = get_locale_negative_str ();
+  gint sign = 1;
+
+  if (c != 0 && g_utf8_strchr (positive_signs, -1, c) != NULL)
+  {
+    p = g_utf8_next_char (p);
+    c = g_utf8_get_char_validated (p, -1);
+  }
+  else if (c != 0 && g_utf8_strchr (negative_signs, -1, c) != NULL)
+    {
+      sign = -1;
+      p = g_utf8_next_char (p);
+      c = g_utf8_get_char_validated (p, -1);
+    }
+
+  /* Read numbers */
+  gunichar zero = get_locale_zero_char ();
+  gchar *decimal_point = get_locale_decimal_point_str ();
+  gboolean read_radix = FALSE;
+  gint value_of_first_digit = -1;
+
+  while (c == zero || 
+	(c != 0 && g_utf8_strchr (decimal_point, -1, c) != NULL))
+    {
+      if (g_utf8_strchr (decimal_point, -1, c) != NULL)
+	{
+	  if (read_flag == FALSE || read_radix == TRUE)
+	    break;
+	  read_radix = TRUE;
+	}
+      else
+	{
+	  read_flag = TRUE;
+          if (read_radix == TRUE)
+	    --value_of_first_digit;
+	}
+
+      p = g_utf8_next_char (p);
+      c = g_utf8_get_char_validated (p, -1);
+
+    }
+
+  gchar *dig_start = p; /* Save the current place for second pass */
+  gboolean radix_state = read_radix; /* Save the radix status too */
+
+  while ((c >= zero && c < zero + 10) ||
+	 (c != 0 && g_utf8_strchr (decimal_point, -1, c) != NULL))
+    {
+      if (g_utf8_strchr (decimal_point, -1, c) != NULL)
+	{
+	  if (read_radix == TRUE)
+	    break;
+	  read_radix = TRUE;
+	}
+      else
+	{
+	  read_flag = TRUE;
+	  if (read_radix == FALSE)
+	    ++value_of_first_digit;
+	}
+      p = g_utf8_next_char (p);
+      c = g_utf8_get_char_validated (p, -1);
+    }
+
+  /* Check if any digit is read */
+  if (read_flag == FALSE)
+  {
+      /* Standard requires endptr, errno, Return value to be as followed */
+      if (endptr != NULL)
+	*endptr = nptr;
+      errno = EINVAL;
+      return 0;
+  }
+
+  /* Check for decimal exponent */
+  gchar *exp = get_locale_exp_str ();
+  if (g_str_has_prefix (p, exp))
+    {
+      gchar *new_p;
+      gint exp_value = g_locale_strtoll (p + strlen(exp), &new_p, 10);
+      if (errno == 0)
+        {
+          p = new_p;
+          c = g_utf8_get_char_validated (p, -1); 
+          value_of_first_digit += exp_value;
+        }
+    }
+
+  /* Set The endptr */
+  if (endptr != NULL)
+    *endptr = p;
+
+  gdouble val = 0;
+  p = dig_start;	/* restore the value */
+  read_radix = radix_state; /* restore the radix state */
+  c = g_utf8_get_char_validated (p, -1);
+
+  if (value_of_first_digit > 308) /* No way infinite! */
+  {
+    errno = ERANGE;
+    return sign == 1 ? HUGE_VAL : -HUGE_VAL;
+  }
+  
+  /* A small trick to get rid of pow10 function or somethis simillar.
+   * we will simply use the glibc internal functions!
+   */
+  char smallbuf[10];
+  gdouble persision;
+  sprintf (smallbuf, "1e%d", value_of_first_digit);
+  sscanf (smallbuf, "%lf", persision);
+
+  /* Read numbers */
+  while ((c >= zero && c < zero + 10) || 
+	 (c != 0 && g_utf8_strchr (decimal_point, -1, c) != NULL))
+  {
+    if (c != 0 && g_utf8_strchr (decimal_point, -1, c) != NULL)
+      {
+	if (read_radix == TRUE)
+	  break;
+	else
+	  read_radix = TRUE;
+      }
+    else
+      {
+	val = val + persision * (c - zero);
+	persision /= 10;
+      }
+    p = g_utf8_next_char (p);
+    c = g_utf8_get_char_validated (p, -1);
+
+  }
+  /* If the value is Inf or -Inf error should be reported */
+  if (val == HUGE_VAL)
+    errno = ERANGE;
+  else /* no error */
+    errno = 0;
+
+  /* Set The endptr */
+  if (endptr != NULL)
+    *endptr = p;
+
+  return sign == 1 ?  val : -val;
+}
+
+
+/**
+ * g_locale_strtoull:
+ * @nptr:    the string to convert to a numeric value.
+ * @endptr:  if non-%NULL, it returns the character after
+ *           the last character used in the conversion.
+ * @base:     to be used for the conversion, 2..10 or 0
+ *
+ * Converts a local string to a #guint64 value.
+ * It will use the local number system to convert to convert local 
+ * string to number. Local number system information is gathered from available
+ * translations for '0', '+', '-', '.', and 'e'.
+ *
+ * This function is useful for software internationalization. This functions is
+ * not able to read the default English numbers if there is a non-english translation 
+ * available for your locale. It can be called inside #g_strtoull function to make it 
+ * work for internationalized numbers.
+ *
+ * Return value: the #guint64 value.
+ **/
+guint64
+g_locale_strtoull (const gchar	*nptr,
+	          gchar        **endptr,
+	          guint          base )
+{
+  g_return_val_if_fail (nptr != NULL, 0);
+  
+  if (base == 0)
+    base = 10;
+
+  if (base < 2 || base > 10)
+    errno = EINVAL;
+  g_return_val_if_fail (base >= 2 && base <= 10, 0);
+
+  guint64 val = 0;
+  gboolean read_flag = FALSE;
+  
+  gchar *p = nptr;
+  gunichar c = g_utf8_get_char_validated (p, -1); /* c always is the first character of p */
+
+  /* Skip Spaces in the beginning */
+  while (g_unichar_isspace (c))
+    {
+      p = g_utf8_next_char (p);
+      c = g_utf8_get_char_validated (p, -1);
+    }
+
+  /* Read the Sign */
+  gchar *positive_signs = get_locale_positive_str ();
+  gchar *negative_signs = get_locale_negative_str ();
+
+  gint sign = 1;
+  guint64 cutoff = G_MAXUINT64 / base;
+  gint cutlim = G_MAXUINT64 % base;
+
+  if (c != 0 && g_utf8_strchr (positive_signs, -1, c) != NULL)
+    {
+      p = g_utf8_next_char (p);
+      c = g_utf8_get_char_validated (p, -1);
+    }
+  else if (c != 0 && g_utf8_strchr (negative_signs, -1, c) != NULL)
+    {
+      sign = -1;
+      p = g_utf8_next_char (p);
+      c = g_utf8_get_char_validated (p, -1);
+    }
+
+  /* Read the numbers */
+  gunichar zero = get_locale_zero_char ();
+  gboolean overflow = FALSE;
+
+  while (c >= zero && c < zero + base)
+    {
+      gint num = c - zero;
+      read_flag = TRUE;
+      /* avoid overflow */
+      if (!overflow && (val < cutoff || (val == cutoff && num <= cutlim)))
+	val = base * val + num;
+      else
+	overflow = TRUE;
+
+      p = g_utf8_next_char (p);
+      c = g_utf8_get_char_validated (p, -1);
+    }
+
+  /* If no number is read 0 should be returned */
+  if (read_flag == FALSE)
+    {
+      /* Standard requires endptr, errno, Return value to be as followed */
+      if (endptr != NULL)
+	*endptr = nptr;
+      errno = EINVAL;
+      return 0;
+    } 
+
+  if (endptr != NULL)
+    *endptr = p;
+
+  if (overflow)
+    {
+      errno = ERANGE;
+      return G_MAXUINT64;
+    }
+
+  if (sign == -1 && val > G_MAXINT64)
+    {
+      errno = ERANGE;
+      return val;
+    }
+  else
+    {
+      errno = 0;
+      return sign == 1 ? val : -val;
+    }
+}
+
+/**
+ * g_locale_strtoll:
+ * @nptr:    the string to convert to a numeric value.
+ * @endptr:  if non-%NULL, it returns the character after
+ *           the last character used in the conversion.
+ * @base:     to be used for the conversion, 2..10 or 0
+ *
+ * Converts a local string to a #gint64 value.
+ * It will use the local number system to convert to convert local 
+ * string to number. Local number system information is gathered from available
+ * translations for '0', '+', '-', '.', and 'e'.
+ *
+ * This function is usefull for software internationalization. This functions is
+ * not able to read the default english numbers if there is a non-english translation 
+ * available for your locale. It can be called inside #g_strtoll function to make it 
+ * work for internationalized numbers.
+ *
+ * Return value: the #gint64 value.
+ **/
+gint64
+g_locale_strtoll (const gchar* nptr,
+	         gchar       **endptr,
+		 guint         base)
+{
+  g_return_val_if_fail (nptr != NULL, 0);
+
+  if (base == 0)
+    base = 10;
+
+  if (base < 2 || base > 10)
+    errno = EINVAL;
+  g_return_val_if_fail (base >= 2 && base <= 10, 0);
+
+  gboolean read_flag = FALSE;
+  gint64 val = 0;
+  
+  gchar *p = nptr;
+  gunichar c = g_utf8_get_char_validated (p, -1); /* c always is the first character of p */
+
+  /* Skip Spaces in the beginning */
+  while (g_unichar_isspace (c))
+    {
+      p = g_utf8_next_char (p);
+      c = g_utf8_get_char_validated (p, -1);
+    }
+
+  /* Read the sign */
+  gchar *positive_signs = get_locale_positive_str ();
+  gchar *negative_signs = get_locale_negative_str ();
+
+  gint sign = 1;
+  guint64 cutoff;
+  gint cutlim;
+  cutoff = G_MAXINT64 / base;
+  cutlim = G_MAXINT64 % base;
+  if (c != 0 && g_utf8_strchr (positive_signs, -1, c) != NULL)
+  {
+    p = g_utf8_next_char (p);
+    c = g_utf8_get_char_validated (p, -1);
+  }
+  else if (c != 0 && g_utf8_strchr (negative_signs, -1, c) != NULL)
+    {
+      sign = -1;
+      p = g_utf8_next_char (p);
+      c = g_utf8_get_char_validated (p, -1);
+      cutoff = -(G_MININT64 / base);
+      cutlim = -(G_MININT64 % base);
+    }
+
+  gunichar zero = get_locale_zero_char ();
+
+  gboolean overflow = FALSE;
+
+  while (c >= zero && c < zero + base)
+    {
+      gint num = c - zero;
+      read_flag = TRUE;
+      /* avoid overflow and underflow */
+      if (!overflow && (val < cutoff || (val == cutoff && num < cutlim)))
+	val = base * val + num;
+      else
+	overflow = TRUE;
+      p = g_utf8_next_char (p);
+      c = g_utf8_get_char_validated (p, -1);
+    }
+
+  if (read_flag == FALSE)
+    {
+      /* Standard requires endptr, errno, Return value to be as followed */
+      if (endptr != NULL)
+	*endptr = nptr;
+      errno = EINVAL;
+      return 0;
+    } 
+
+  if (endptr != NULL)
+    *endptr = p;
+
+  if (overflow)
+    {
+      errno = ERANGE;
+      return (sign == 1 ? G_MAXINT64: G_MININT64);
+    }
+
+  errno = 0;
+  return sign == 1 ?  val : -val;
+}
+
 /**
  * g_strtod:
  * @nptr:    the string to convert to a numeric value.
@@ -251,7 +789,8 @@
  * Converts a string to a #gdouble value.
  * It calls the standard strtod() function to handle the conversion, but
  * if the string is not completely converted it attempts the conversion
- * again with g_ascii_strtod(), and returns the best match.
+ * again with g_ascii_strtod(), again if the conversion is not complete
+ * it will use g_locale_strtod(), and returns the best match.
  *
  * This function should seldomly be used. The normal situation when reading
  * numbers not for human consumption is to use g_ascii_strtod(). Only when
@@ -268,28 +807,148 @@
 {
   gchar *fail_pos_1;
   gchar *fail_pos_2;
+  gchar *fail_pos_3;
   gdouble val_1;
   gdouble val_2 = 0;
+  gdouble val_3 = 0;
 
   g_return_val_if_fail (nptr != NULL, 0);
 
   fail_pos_1 = NULL;
   fail_pos_2 = NULL;
+  fail_pos_3 = NULL;
 
   val_1 = strtod (nptr, &fail_pos_1);
 
   if (fail_pos_1 && fail_pos_1[0] != 0)
-    val_2 = g_ascii_strtod (nptr, &fail_pos_2);
+    {
+      val_2 = g_ascii_strtod (nptr, &fail_pos_2);
+      if (fail_pos_2 && fail_pos_2[0] != 0)
+	val_3 = g_locale_strtod (nptr, &fail_pos_3);
+    }
 
-  if (!fail_pos_1 || fail_pos_1[0] == 0 || fail_pos_1 >= fail_pos_2)
+  if (!fail_pos_1 || fail_pos_1[0] == 0 || 
+     (fail_pos_1 >= fail_pos_2 && fail_pos_1 >= fail_pos_3))
     {
       if (endptr)
 	*endptr = fail_pos_1;
       return val_1;
     }
+  else if (!fail_pos_2 || fail_pos_2[0] == 0 || fail_pos_2 >= fail_pos_3)
+    {
+      if (endptr)
+	*endptr = fail_pos_2;
+      return val_2;
+    }
   else
     {
       if (endptr)
+	*endptr = fail_pos_3;
+      return val_3;
+    }
+}
+
+/**
+ * g_strtoull:
+ * @nptr:    the string to convert to a numeric value.
+ * @endptr:  if non-%NULL, it returns the character after
+ *           the last character used in the conversion.
+ * @base:     to be used for the conversion, 2..10 or 0
+ *
+ * Converts a string to a #guint64 value.
+ * It calls the standard strtoull function to handle the conversion 
+ * buf if the string is not completely converted it attempts the 
+ * conversion again with g_locale_strtoull(), and returns the best match.
+ *
+ * This function is useful for software internationalization. But of course
+ * there is a cost for second call if the number is not fully converted. This
+ * function is recommended to use when reading information from 
+ * internationalized UI.
+ *
+ * Return value: the #guint64 value.
+ **/
+guint64
+g_strtoull (const gchar *nptr,
+	    gchar       **endptr,
+	    guint	  base)
+{
+  gchar *fail_pos_1;
+  gchar *fail_pos_2;
+  guint64 val_1;
+  guint64 val_2 = 0;
+
+  g_return_val_if_fail (nptr != NULL, 0);
+
+  fail_pos_1 = NULL;
+  fail_pos_2 = NULL;
+
+  val_1 = strtoull (nptr, &fail_pos_1, base);
+
+  if (fail_pos_1 && fail_pos_1[0] != 0)
+      val_2 = g_locale_strtoull (nptr, &fail_pos_2, base);
+
+  if (!fail_pos_1 || fail_pos_1[0] == 0 || fail_pos_1 >= fail_pos_2)
+    {
+      if (endptr)
+        *endptr = fail_pos_1;
+      return val_1;
+    }
+  else 
+    {
+      if (endptr)
+	*endptr = fail_pos_2;
+      return val_2;
+    }
+}
+
+/**
+ * g_strtoll:
+ * @nptr:    the string to convert to a numeric value.
+ * @endptr:  if non-%NULL, it returns the character after
+ *           the last character used in the conversion.
+ * @base:     to be used for the conversion, 2..10 or 0
+ *
+ * Converts a string to a #gint64 value.
+ * It calls the standard strtoull function to handle the conversion 
+ * buf if the string is not completely converted it attempts the 
+ * conversion again with g_locale_strtoll(), and returns the best match.
+ *
+ * This function is usefull for software internationalization. But of course
+ * there is a cost for second call if the number is not fully converted. This
+ * function is recommended to use when reading information from 
+ * internationalized UI.
+ *
+ * Return value: the #gint64 value.
+ **/
+gint64
+g_strtoll (const gchar* nptr,
+	   gchar       **endptr,
+	   guint         base)
+{
+  gchar *fail_pos_1;
+  gchar *fail_pos_2;
+  gint64 val_1;
+  gint64 val_2 = 0;
+
+  g_return_val_if_fail (nptr != NULL, 0);
+
+  fail_pos_1 = NULL;
+  fail_pos_2 = NULL;
+
+  val_1 = strtoll (nptr, &fail_pos_1, base);
+
+  if (fail_pos_1 && fail_pos_1[0] != 0)
+      val_2 = g_locale_strtoll (nptr, &fail_pos_2, base);
+
+  if (!fail_pos_1 || fail_pos_1[0] == 0 || fail_pos_1 >= fail_pos_2)
+    {
+      if (endptr)
+	*endptr = fail_pos_1;
+      return val_1;
+    }
+  else 
+    {
+      if (endptr)
 	*endptr = fail_pos_2;
       return val_2;
     }
@@ -475,6 +1134,298 @@
   return val;
 }
 
+/**
+ * g_dtostr:
+ * @buffer: A buffer to place the resulting string in
+ * @buf_len: The length of the buffer.
+ * @d: The #gdouble to convert
+ *
+ * Converts a #gdouble to a string, using the '.' as
+ * decimal point.
+ *
+ * This functions generates enough precision that converting
+ * the string back using g_strtod() gives the same machine-number
+ * (on machines with IEEE compatible 64bit doubles). It is
+ * guaranteed that the size of the resulting string will never
+ * be larger than @G_DTOSTR_BUF_SIZE bytes.
+ *
+ * Return value: The pointer to the buffer with the converted string.
+ **/
+gchar *
+g_dtostr (gchar       *buffer,
+          gint         buf_len,
+          gdouble      d)
+{
+  return g_formatd (buffer, buf_len, "%.17g", d);
+}
+
+/**
+ * g_ulltostr:
+ * @buffer: A buffer to place the resulting string in
+ * @buf_len: The length of the buffer.
+ * @ull: The #guint64 to convert
+ *
+ * Converts a #guint64 to a string
+ *
+ * It is guaranteed that the size of the resulting string will never
+ * be larger than @G_ITOSTR_BUF_SIZE bytes.
+ *
+ * Return value: The pointer to the buffer with the converted string.
+ **/
+gchar *
+g_ulltostr (gchar       *buffer,
+	    gint         buf_len,
+	    guint64      ull)
+{
+  return g_formati (buffer, buf_len, "%llu", ull);
+}
+
+/**
+ * g_lltostr:
+ * @buffer: A buffer to place the resulting string in
+ * @buf_len: The length of the buffer.
+ * @ll: The #gint64 to convert
+ *
+ * Converts a #gint64 to a string, using the '.' as
+ * decimal point.
+ *
+ * This functions generates enough precision that converting
+ * the string back using g_strtod() gives the same machine-number
+ * (on machines with IEEE compatible 64bit doubles). It is
+ * guaranteed that the size of the resulting string will never
+ * be larger than @G_ITOSTR_BUF_SIZE bytes.
+ *
+ * Return value: The pointer to the buffer with the converted string.
+ **/
+gchar *
+g_lltostr (gchar       *buffer,
+	   gint         buf_len,
+	   gint64       ll)
+{
+  return g_formati (buffer, buf_len, "%lld", ll);
+}
+
+/**
+ * g_get_locale_number:
+ * @english: A String with 
+ * @buffer: A buffer to place the resulting string in
+ * @buf_len: The length of the buffer.
+ *
+ * Converts a English numeric string to a local numeric string.
+ *
+ * This functions generates acts assuming that a correct number is 
+ * given and does not check for syntax. Just converts '+', '-', 
+ * numbers, and 'e' to local ones, guaranteed that the size of the resulting 
+ * local string will never be larger than @buf_len bytes.
+ *
+ * Return value: The pointer to the buffer with the converted string.
+ **/
+
+static gchar *
+g_get_locale_number (gchar       *english,
+	            gchar       *buffer,
+	            gint         buf_len)
+{
+
+  g_return_val_if_fail (english != NULL, NULL);
+  g_return_val_if_fail (buffer != NULL, NULL);
+
+  gchar *input_pointer = english;
+  gchar *output_pointer = buffer;
+
+  gunichar positive_sign = get_locale_positive_char ();
+  gunichar negative_sign = get_locale_negative_char ();
+  gunichar zero = get_locale_zero_char ();
+  gunichar decimal_point = get_locale_decimal_point_char ();
+  gchar *exp = get_locale_exp_str ();
+
+  while (*input_pointer)
+    {
+      gint len;
+      gunichar digit;
+      switch (*input_pointer)
+        {
+	  case '+':
+	    len = g_unichar_to_utf8 (positive_sign, NULL);
+	    if (len > buf_len)
+	      goto buffer_full;
+
+	    g_unichar_to_utf8 (positive_sign, output_pointer);
+	    output_pointer += len;
+	    buf_len -= len;
+	    input_pointer++;
+	    break;
+
+	  case '-':
+	    len = g_unichar_to_utf8 (negative_sign, NULL);
+	    if (len > buf_len)
+	      goto buffer_full;
+
+	    g_unichar_to_utf8 (negative_sign, output_pointer);
+	    output_pointer += len;
+	    buf_len -= len;
+	    input_pointer++;
+	    break;
+
+	  case '0'...'9':
+	    digit = zero + *input_pointer - '0';
+	    len = g_unichar_to_utf8 (digit, NULL);
+	    if (len > buf_len)
+	      goto buffer_full;
+
+	    g_unichar_to_utf8 (digit, output_pointer);
+	    output_pointer += len;
+	    buf_len -= len;
+	    input_pointer++;
+	    break;
+
+	  case '.':
+	    len = g_unichar_to_utf8 (decimal_point, NULL);
+	    if (len > buf_len)
+	      goto buffer_full;
+
+	    g_unichar_to_utf8 (decimal_point, output_pointer);
+	    output_pointer += len;
+	    buf_len -= len;
+	    input_pointer++;
+	    break;
+
+	  case 'e':
+	  case 'E':
+	    len = strlen (exp);
+	    if (len > buf_len)
+	      goto buffer_full;
+
+	    strcpy (output_pointer, exp);
+	    output_pointer += len;
+	    buf_len -= len;
+	    ++input_pointer;
+	    break;
+
+	  default:
+	    len = 1;
+	    if (len > buf_len)
+	      goto buffer_full;
+
+	    *output_pointer = *input_pointer;
+	    output_pointer += len;
+	    buf_len -= len;
+	    ++input_pointer;
+	}
+    }
+
+buffer_full:
+  *output_pointer = '\0';
+  return buffer;
+}
+
+/**
+ * g_formati:
+ * @buffer: A buffer to place the resulting string in
+ * @buf_len: The length of the buffer.
+ * @format: The printf()-style format to use for the
+ *          code to use for converting.
+ * @i: The #guint64 or #gint64 to convert
+ *
+ * Converts a #guint64 or #gint64 to a string, using the current locale
+ * To format the number you pass in a printf()-style format 
+ * string. Allowed conversion specifiers are 'u', 'U', 'i', 'I', 'd', and 'D'.
+ *
+ * If you just want to want to serialize the value into a
+ * string, use g_lltostr() or g_ulltostr.
+ *
+ * Return value: The pointer to the buffer with the converted string.
+ **/
+gchar *
+g_formati (gchar          *buffer,
+	   gint            buf_len,
+	   const gchar    *format,
+	   gint64          ll)
+{
+  gchar format_char;
+
+  g_return_val_if_fail (buffer != NULL, NULL);
+  g_return_val_if_fail (format[0] == '%', NULL);
+  g_return_val_if_fail (strpbrk (format + 1, "'%") == NULL, NULL);
+
+  format_char = format[strlen (format) - 1];
+
+  g_return_val_if_fail (format_char == 'u' || format_char == 'U' ||
+	                format_char == 'd' || format_char == 'D' ||
+	                format_char == 'i' || format_char == 'I',
+	                NULL);
+
+  if (format[0] != '%')
+    return NULL;
+
+  if (strpbrk (format + 1, "'%"))
+    return NULL;
+
+  if (!(format_char == 'u' || format_char == 'U' ||
+        format_char == 'd' || format_char == 'D' ||
+        format_char == 'i' || format_char == 'I')
+)
+    return NULL;
+
+  gchar temp_buffer[G_ASCII_ITOSTR_BUF_SIZE];
+  snprintf (temp_buffer, G_ASCII_ITOSTR_BUF_SIZE, format, ll);
+
+  return g_get_locale_number (temp_buffer, buffer, buf_len);
+}
+
+/**
+ * g_formatd:
+ * @buffer: A buffer to place the resulting string in
+ * @buf_len: The length of the buffer.
+ * @format: The printf()-style format to use for the
+ *          code to use for converting.
+ * @d: The #gdouble to convert
+ *
+ * Converts a #gdouble to a string, using the current locale
+ * To format the number you pass in a printf()-style format 
+ * string. Allowed conversion specifiers are 'e', 'E', 
+ * 'f', 'F', 'g' and 'G'.
+ *
+ * If you just want to want to serialize the value into a
+ * string, use g_dtostr().
+ *
+ * Return value: The pointer to the buffer with the converted string.
+ **/
+gchar *
+g_formatd (gchar          *buffer,
+	   gint           buf_len,
+	   const gchar    *format,
+	   gdouble        d)
+{
+  gchar format_char;
+
+  g_return_val_if_fail (buffer != NULL, NULL);
+  g_return_val_if_fail (format[0] == '%', NULL);
+  g_return_val_if_fail (strpbrk (format + 1, "'l%") == NULL, NULL);
+
+  format_char = format[strlen (format) - 1];
+
+  g_return_val_if_fail (format_char == 'e' || format_char == 'E' ||
+	                format_char == 'f' || format_char == 'F' ||
+	                format_char == 'g' || format_char == 'G',
+	                NULL);
+
+  if (format[0] != '%')
+    return NULL;
+
+  if (strpbrk (format + 1, "'l%"))
+    return NULL;
+
+  if (!(format_char == 'e' || format_char == 'E' ||
+	format_char == 'f' || format_char == 'F' ||
+	format_char == 'g' || format_char == 'G'))
+    return NULL;
+
+  gchar temp_buffer[G_ASCII_DTOSTR_BUF_SIZE];
+  snprintf (temp_buffer, G_ASCII_DTOSTR_BUF_SIZE, format, d);
+
+  return g_get_locale_number (temp_buffer, buffer, buf_len);
+}
 
 /**
  * g_ascii_dtostr:
--- ./glib/gstrfuncs.h.intl_numbers	2006-05-16 09:16:36.000000000 +0330
+++ ./glib/gstrfuncs.h	2006-12-29 22:12:04.000000000 +0330
@@ -29,6 +29,7 @@
 
 #include <stdarg.h>
 #include <glib/gtypes.h>
+#include "gunicode.h"
 
 G_BEGIN_DECLS
 
@@ -125,6 +126,23 @@
 
 gdouble	              g_strtod         (const gchar  *nptr,
 					gchar	    **endptr);
+gdouble               g_locale_strtod  (const gchar  *nptr,
+					gchar       **endptr);
+guint64               g_locale_strtoull(const gchar  *nptr,
+					gchar       **endptr,
+					guint         base);
+
+gint64               g_locale_strtoll  (const gchar  *nptr,
+					gchar       **endptr,
+					guint         base);
+
+guint64               g_strtoull       (const gchar  *nptr,
+					gchar       **endptr,
+					guint         base);
+gint64                g_strtoll        (const gchar  *nptr,
+					gchar       **endptr,
+					guint         base);
+ 
 gdouble	              g_ascii_strtod   (const gchar  *nptr,
 					gchar	    **endptr);
 guint64		      g_ascii_strtoull (const gchar *nptr,
@@ -137,6 +155,15 @@
  * g_ascii_dtostr can produce.
  * Then add 10 for good measure */
 #define G_ASCII_DTOSTR_BUF_SIZE (29 + 10)
+
+#define G_ASCII_ITOSTR_BUF_SIZE (22 + 10)
+ 
+/* 1 * 2 sign + 16 * 2 digs + 1 * 2 radix + 8 for 'e' + 1 * 2 sign + 2 * 3 exp + 1 null + safety = 60 */
+#define G_DTOSTR_BUF_SIZE 60
+ 
+/* 1 * 2 sign + 20 * 2 digs + 1 null + safety = 60 */
+#define G_ITOSTR_BUF_SIZE 60
+
 gchar *               g_ascii_dtostr   (gchar        *buffer,
 					gint          buf_len,
 					gdouble       d);
@@ -145,6 +172,25 @@
 					const gchar  *format,
 					gdouble       d);
 
+gchar *               g_dtostr         (gchar        *buffer,
+					gint          buf_len,
+					gdouble       d);
+gchar *               g_formatd        (gchar        *buffer,
+					gint          buf_len,
+					const gchar  *format,
+					gdouble       d);
+
+gchar *               g_ulltostr       (gchar        *buffer,
+					gint          buf_len,
+					guint64       ull);
+gchar *               g_lltostr        (gchar        *buffer,
+					gint          buf_len,
+					gint64        ll);
+gchar *               g_formati        (gchar        *buffer,
+					gint          buf_len,
+					const gchar  *format,
+					gint64        ll);
+
 /* removes leading spaces */
 gchar*                g_strchug        (gchar        *string);
 /* removes trailing spaces */
--- ./glib/glibintl.h.intl_numbers	2007-01-24 13:28:20.000000000 +0330
+++ ./glib/glibintl.h	2007-01-24 13:14:45.000000000 +0330
@@ -11,6 +11,7 @@
 
 #include <libintl.h>
 #define _(String) _glib_gettext(String)
+#define Q_(String) g_strip_context ((String), _(String))
 
 #ifdef gettext_noop
 #define N_(String) gettext_noop(String)
--- ./po/POTFILES.in.intl_numbers	2006-04-30 15:31:42.000000000 +0330
+++ ./po/POTFILES.in	2006-12-29 22:12:04.000000000 +0330
@@ -12,3 +12,4 @@
 glib/gutf8.c
 glib/goption.c
 glib/gkeyfile.c
+glib/gstrfuncs.c
--- ./po/Makefile.in.in.intl_numbers	2007-01-24 13:22:49.000000000 +0330
+++ ./po/Makefile.in.in	2007-01-24 13:23:04.000000000 +0330
@@ -92,7 +92,7 @@
 
 $(srcdir)/$(GETTEXT_PACKAGE).pot: $(POTFILES)
 	$(XGETTEXT) --default-domain=$(GETTEXT_PACKAGE) --directory=$(top_srcdir) \
-	  --add-comments --keyword=_ --keyword=N_ \
+	  --add-comments --keyword=_ --keyword=N_ --keyword=Q_\
           --flag=g_strdup_printf:1:c-format \
           --flag=g_string_printf:2:c-format \
           --flag=g_string_append_printf:2:c-format \
