--- ./glib/glib.symbols.intl_numbers	2006-06-02 06:06:30.000000000 +0330
+++ ./glib/glib.symbols	2007-01-24 23:42:58.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-02-28 15:54:33.000000000 +0330
@@ -22,6 +22,8 @@
  * file for a list of people on the GLib Team.  See the ChangeLog
  * files for a list of changes.  These files are distributed with
  * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ *
+ * Support for localized digits added by Amir Hedayaty.
  */
 
 /*
@@ -38,6 +40,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 +49,7 @@
 #include "glib.h"
 #include "gprintf.h"
 #include "gprintfint.h"
+#include "glibintl.h"
 
 #include "galias.h"
 
@@ -114,6 +118,25 @@
   return new_mem;
 }
 
+/**
+ * g_strndup:
+ * @str: the string to duplicate
+ * @n: the maximum number of bytes to copy from @str
+ *
+ * Duplicates the first @n bytes of a string, returning a newly-allocated
+ * buffer @n + 1 bytes long which will always be nul-terminated.
+ * If @str is less than @n bytes long the buffer is padded with nuls.
+ * If @str is %NULL it returns %NULL.
+ * The returned value should be freed when no longer needed.
+ * 
+ * <note><para>
+ * To copy a number of characters from a UTF-8 encoded string, use
+ * g_utf8_strncpy() instead.
+ * </para></note>
+ * 
+ * Returns: a newly-allocated buffer containing the first @n bytes 
+ *          of @str, nul-terminated 
+ */
 gchar*
 g_strndup (const gchar *str,
 	   gsize        n)    
@@ -132,6 +155,16 @@
   return new_str;
 }
 
+/**
+ * g_strnfill:
+ * @length: the length of the new string
+ * @fill_char: the byte to fill the string with
+ *
+ * Creates a new string @length bytes long filled with @fill_char.
+ * The returned string should be freed when no longer needed.
+ * 
+ * Returns: a newly-allocated string filled the @fill_char
+ */
 gchar*
 g_strnfill (gsize length,     
 	    gchar fill_char)
@@ -242,6 +275,497 @@
   return concat;
 }
 
+/* The following functions (g_locale_*) are used to get the locale's
+ * numbering information for writing localized numbers.
+ */
+const 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. Only the first character of the
+   * translated string will be used, the rest will be thrown away.
+   *
+   * Do not translate the "locale|" part, remove it. In a Spanish locale, for
+   * example, this should be translated to "0", while in a Persian or Urdu
+   * locale, it should be translated to "\u06F0". Use the real character 
+   * instead of \uXXXX.
+   */
+
+  return Q_("locale|0");
+}
+
+const static gchar *
+get_locale_positive_str ()
+{
+  /* Translators: This message is for handling the localized positive sign.  
+   * Translate this to your local positive sign.
+   * If several positive signs are used in your locale's numeric system,
+   * you can include a string of acceptable characters. This will make 
+   * glib accept any of them as a positive sign, but only the first
+   * character will be used to generate the output. 
+   *
+   * Do not translate the "locale|" part, remove it. In most locales this
+   * should be translated to "+". But, for example, in a Hebrew locale this
+   * could be translated to include "\uFB29", or in a CJK locale this can also
+   * include "\uFF0B". Use the real characters instead of \uXXXX.
+   */
+  return Q_("locale|+");
+}
+
+const static gchar *
+get_locale_negative_str ()
+{
+  /* Translators: This message is for handling the localized negative sign.
+   * Translate this to your local negative sign. 
+   * If several negative signs are used in your locale's numeric system,
+   * you can include a string of acceptable characters. This will make
+   * glib accept any of them as a negative sign, but only the first
+   * character will be used to generate the output.  
+   *
+   * Do not translate the "locale|" part, remove it. In many locales this
+   * should be translated to "-\u2012\u2212", while on some locales, where
+   * the Unicode minus sign (U+2212) is preferred to the ASCII minus sign,
+   * this string should be translated to "\u2212-\u2012". Use the real
+   * characters instead of \uXXXX.
+   */
+  return Q_("locale|-");
+}
+
+const static gchar *
+get_locale_decimal_point_str ()
+{
+  /* Translators: This message is for handling the localized decimal point 
+   * separator. Translate this to your local decimal separator. 
+   * If several decimal separators are used in your locale's numeric system,
+   * you can include a string of acceptable characters. This will make
+   * glib accept any of them as a decimal separator, but only the first 
+   * character is used to generate the output.
+   *
+   * Do not translate the "locale|" part, remove it. In most locales that
+   * do not have localized numbers this string should be translated to "."
+   * or ",", while for example in a Persian locale this could be translated
+   * to "\u066B/". Use the real characters instead of \uXXXX.
+   */
+  gchar *decimal_point = N_("locale|.");
+  gchar *translated_decimal_point = _(decimal_point);
+  if (decimal_point == translated_decimal_point)
+    {
+      struct lconv *locale_data;
+      const char *decimal_point;
+
+      locale_data = localeconv ();
+      decimal_point = locale_data->decimal_point;
+
+      g_assert (strlen(decimal_point) != 0);
+      
+      return decimal_point;
+    }
+  else
+    return translated_decimal_point;
+}
+
+const static gchar *
+get_locale_exp_str ()
+{
+  /* Translators: This message is for handling the localized scientific number
+   * representation. In many locales "e" is used for this purpose, but in 
+   * some locales another notation is preferred, which can be a longer string.
+   * Translate this to the string which is used to separate the parts of the
+   * scientific number representation in your locale.
+   *
+   * Do not translate the "locale|" part, remove it. For example in a Persian 
+   * locale this should be translated to "\u00D7\u06F1\u06F0^" (something like 
+   * "*10^"). Use the real characters instead of \uXXXX.
+   */
+  const gchar *exp = Q_("locale|e");
+  if (strlen(exp) > G_MAX_EXP_SIZE)
+    {
+      g_warning ("locae|e has been translated to a long string.\n");
+      return "e";
+    }
+
+  return exp;
+}
+
+
+#define g_unichar_no_error(c) \
+  (!((c) & 0x80000000) && (c) != 0)
+
+static gunichar
+get_locale_zero_char ()
+{
+  gunichar zero = g_utf8_get_char_validated (get_locale_zero_str (), -1);
+  if (g_unichar_no_error (zero) && g_unichar_digit_value (zero) == 0)
+    return zero;
+  g_warning ("Mistranslated string locale|0\n");
+  return (gunichar) '0';
+}
+
+#define g_return_if_valid_unichar(c) \
+  if (g_unichar_no_error(c)) \
+    return c
+
+static gunichar
+get_locale_positive_char ()
+{
+  gunichar positive_sign = g_utf8_get_char_validated ( get_locale_positive_str (), -1);
+  g_return_if_valid_unichar (positive_sign);
+  g_warning ("Mistranslated string locale|+\n");
+  return (gunichar) '+';
+}
+
+static gunichar
+get_locale_negative_char ()
+{
+  gunichar negative_sign = g_utf8_get_char_validated (get_locale_negative_str (), -1);
+  g_return_if_valid_unichar (negative_sign);
+  g_warning ("Mistranslated 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);
+  g_return_if_valid_unichar (decimal_point);
+  g_warning ("Mistranslated string locale|.\n");
+  return (gunichar) '.';
+}
+
+#define g_progress_unichar(p, c)   G_STMT_START{ \
+  p = g_utf8_next_char(p); \
+  c = g_utf8_get_char_validated (p, -1); } G_STMT_END
+
+#define g_progress_spaces(p, c) \
+  while (g_unichar_isspace (c)) \
+    g_progress_unichar(p, c)
+
+#define g_set_if_not_null(endptr, p) \
+  if (endptr != NULL) \
+    *endptr = (char*)(p)
+
+#define g_is_localized_digit(c, zero, base)\
+  ((zero) <= (c) && (c) < (zero) + (base))
+
+#define g_utf8_is_in(c, set) (g_utf8_strchr (set, -1, c) != NULL)
+
+/**
+ * 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 the string to a number.
+ * The local number system information is gathered from available
+ * translations for '0', '+', '-', '.', and 'e'.
+ *
+ * This function is useful for software internationalization. This function is
+ * not able to read ASCII numbers if there is a non-English translation
+ * available for the above strings in the locale. This function is also called
+ * inside #g_strtod to make that function support internationalized numbers.
+ *
+ * Return value: the #gdouble value.
+ **/
+
+gdouble 
+g_locale_strtod (const gchar        *nptr,
+	         gchar              **endptr)
+{
+  const gchar *p;
+  gunichar c;
+  gunichar zero;
+  const gchar *positive_signs;
+  const gchar *negative_signs;
+  const gchar *decimal_points;
+  const gchar *exp;
+  gint sign = 1;
+  gchar english[G_ASCII_DTOSTR_BUF_SIZE + 10]; 
+  gchar *output_pointer = english;
+  gint writen_digits = 0;
+  gboolean decimal_point_is_read = FALSE;
+  gboolean any_digit_read = FALSE;
+  gint exponential = 0;
+
+  g_return_val_if_fail (nptr != NULL, 0);
+
+  p = nptr;
+  /* c always is the first character of p */
+  c  = g_utf8_get_char_validated (p, -1);
+
+  /* Skip Spaces in the beginning */
+  g_progress_spaces (p, c);
+  
+  if (!g_unichar_no_error (c))
+    goto nothing_read;
+
+  /* Check for sign */
+  positive_signs = get_locale_positive_str ();
+  negative_signs = get_locale_negative_str ();
+  if (g_utf8_is_in (c, positive_signs))
+    g_progress_unichar (p, c);
+  else if (g_utf8_is_in (c, negative_signs))
+    {
+      (*output_pointer++) = '-';
+      sign = -1;
+      g_progress_unichar (p, c);
+    }
+
+  zero = get_locale_zero_char ();
+  decimal_points = get_locale_decimal_point_str ();
+  if (!g_is_localized_digit (c, zero, 10) &&
+      !g_utf8_is_in(c, decimal_points))
+    goto nothing_read;
+  
+  while (1)
+    {
+      if (g_is_localized_digit (c, zero, 10))
+        {
+	  any_digit_read = TRUE;
+	  if (writen_digits > 20)
+	    {
+	      if (!decimal_point_is_read)
+		++exponential;
+	    }
+	  else
+	    { 
+	      if (!(writen_digits == 0 && c == zero))
+	        {
+	          *(output_pointer++) = (c - zero) + '0';
+	          ++writen_digits;
+	        }
+	      if (decimal_point_is_read)
+		--exponential;
+	    }
+	}
+      else if (g_utf8_is_in (c, decimal_points))
+        {
+	  if (decimal_point_is_read)
+	    {
+	      if (any_digit_read)
+	        goto finish;
+	      else
+	        goto nothing_read;
+	    }
+	  decimal_point_is_read = 1;
+	}
+      else
+	break;
+      g_progress_unichar (p, c);
+    }
+
+  if (!any_digit_read)
+    goto nothing_read;
+
+  /* Check for decimal exponent */
+  exp = get_locale_exp_str ();
+  if (g_str_has_prefix (p, exp))
+    {
+      gchar *new_p;
+      gint olderrno = errno;
+      gint exp_value;
+      errno = 0;
+      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); 
+          exponential += exp_value;
+        }
+      errno = olderrno;
+    }
+  
+
+finish:
+  g_set_if_not_null (endptr, p);
+  if (exponential > 400)
+    goto overflowed;
+  else if (exponential < -400)
+    goto underflowed;
+  snprintf (output_pointer, 7, "0e%d", exponential - 1);
+  return strtod (english, NULL);
+
+overflowed:
+    errno = ERANGE;
+    return sign == 1 ? HUGE_VAL : -HUGE_VAL;
+
+underflowed:
+    errno = ERANGE;
+    return 0;
+
+nothing_read:
+  /* POSIX requires endptr, errno, Return value to be as followed */
+  g_set_if_not_null (endptr, nptr);
+  errno = EINVAL;
+  return 0;
+}
+
+#define g_read_localized_digits(p, c, zero, base) \
+  while (g_is_localized_digit(c, zero, base)) \
+    g_progress_unichar (p, c)
+
+static gint64
+g_read_locale_integer  (const gchar	*nptr,
+	          	gchar        **endptr,
+	          	guint          base,
+	          	gint is_signed)
+{
+  gint64 val;
+  gint sign;
+  guint64 cutoff;
+  gint cutlim;
+  gunichar zero;
+  const gchar *p;
+  gunichar c;
+  const gchar *positive_signs;
+  const gchar *negative_signs;
+
+  g_return_val_if_fail (nptr != NULL, 0);
+  
+  if (base == 0)
+    base = 10;
+
+  /* Only 2 <= base <= 10, are supported for localized numbers */
+  if (!(2 <= base && base <= 10))
+    goto nothing_read;
+
+  p  = nptr;
+  /* c always is the first character of p */
+  c = g_utf8_get_char_validated (p, -1); 
+
+  /* Skip Spaces in the beginning */
+  g_progress_spaces (p, c);
+
+  if (!g_unichar_no_error (c))
+    goto nothing_read;
+
+  /* Read the Sign */
+  positive_signs = get_locale_positive_str ();
+  negative_signs = get_locale_negative_str ();
+
+  sign = 1;
+
+  if (g_utf8_strchr (positive_signs, -1, c) != NULL)
+    g_progress_unichar (p, c);
+
+  else if (g_utf8_strchr (negative_signs, -1, c) != NULL)
+    {
+      sign = -1;
+      g_progress_unichar (p, c);
+    }
+
+  /* Read the numbers */
+  zero  = get_locale_zero_char ();
+  
+  if (! g_is_localized_digit (c, zero, base))
+    goto nothing_read;
+  if (is_signed == 0)
+    {
+      cutoff = G_MAXUINT64 / base;
+      cutlim = G_MAXUINT64 % base;
+    }
+  else if  (sign == 1)
+    {
+      cutoff = G_MAXINT64 / base;
+      cutlim = G_MAXINT64 % base;
+    }
+  else
+    {
+      cutoff = -(G_MININT64 / base);
+      cutlim = -(G_MININT64 % base);
+    }
+
+  val = 0;
+  while (! g_is_localized_digit (c, zero, base))
+    {
+      gint digit = c - zero;
+      /* avoid overflow */
+      if (val < cutoff || (val == cutoff && digit <= cutlim))
+	val = base * val + digit;
+      else 
+	goto overflowed;
+
+      g_progress_unichar (p, c);
+    }
+
+  g_set_if_not_null (endptr, p);
+
+  return sign == 1 ? val : -val;
+
+overflowed:
+  g_read_localized_digits (p, c, zero, base);
+  g_set_if_not_null (endptr, p);
+  errno = ERANGE;
+  if (is_signed == 0)
+    return G_MAXUINT64;
+  else 
+    return sign == 1 ? G_MAXINT64 : G_MININT64;
+
+nothing_read:
+  /* POSIX requires endptr, errno, and return value to be as followed */
+  g_set_if_not_null (endptr, nptr);
+  errno = EINVAL;
+  return 0;
+}
+
+/**
+ * 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 (which will mean 10)
+ *
+ * Converts a local string to a #guint64 value.
+ * It will use the local number system to convert local 
+ * string to number. Local number system information is gathered from available
+ * translations for "locele|0", "locale|+", "locale|-", locale|.", 
+ * and locale|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 is 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 )
+{
+  return g_read_locale_integer (nptr, endptr, base, 0);
+}
+
+/**
+ * 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(means 10)
+ *
+ * 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 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 is 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)
+{
+  return g_read_locale_integer (nptr, endptr, base, 1);
+}
+
 /**
  * g_strtod:
  * @nptr:    the string to convert to a numeric value.
@@ -251,7 +775,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(), then 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,31 +793,170 @@
 {
   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;
+      g_set_if_not_null (endptr, fail_pos_1);
       return val_1;
     }
+  else if (!fail_pos_2 || fail_pos_2[0] == 0 || fail_pos_2 >= fail_pos_3)
+    {
+      g_set_if_not_null (endptr, fail_pos_2);
+      return val_2;
+    }
   else
     {
-      if (endptr)
-	*endptr = fail_pos_2;
+      g_set_if_not_null (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 
+ * but if the string is not completely converted it attempts the 
+ * conversion then with g_locale_strtoull(), and returns the best match.
+ *
+ * This function is useful for software internationalization. But 
+ * 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;
+  gchar *fail_pos_3;
+  guint64 val_1;
+  guint64 val_2;
+  guint64 val_3;
+
+  g_return_val_if_fail (nptr != NULL, 0);
+
+  fail_pos_1 = NULL;
+  fail_pos_2 = NULL;
+  fail_pos_3 = NULL;
+
+  val_1 = strtoull (nptr, &fail_pos_1, base);
+
+  if (fail_pos_1 && fail_pos_1[0] != 0)
+    {
+      val_2 = g_ascii_strtoull (nptr, &fail_pos_2, base);
+      if (fail_pos_2 && fail_pos_2[0] != 0)
+	val_3 = g_locale_strtoull (nptr, &fail_pos_3, base);
+    }
+
+  if (!fail_pos_1 || fail_pos_1[0] == 0 || 
+     (fail_pos_1 >= fail_pos_2 && fail_pos_1 >= fail_pos_3))
+    {
+      g_set_if_not_null (endptr, fail_pos_1);
+      return val_1;
+    }
+  else if (!fail_pos_2 || fail_pos_2[0] == 0 || fail_pos_2 >= fail_pos_3)
+    {
+      g_set_if_not_null (endptr, fail_pos_2);
+      return val_2;
+    }
+  else
+    {
+      g_set_if_not_null (endptr, fail_pos_3);
+      return val_3;
+    }
+}
+
+/**
+ * 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 
+ * but if the string is not completely converted it attempts the 
+ * conversion again with g_locale_strtoll(), 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 #gint64 value.
+ **/
+gint64
+g_strtoll (const gchar* nptr,
+	   gchar       **endptr,
+	   guint         base)
+{
+  gchar *fail_pos_1;
+  gchar *fail_pos_2;
+  gchar *fail_pos_3;
+  gint64 val_1;
+  gint64 val_2;
+  gint64 val_3;
+
+  g_return_val_if_fail (nptr != NULL, 0);
+
+  fail_pos_1 = NULL;
+  fail_pos_2 = NULL;
+  fail_pos_3 = NULL;
+
+  val_1 = strtoll (nptr, &fail_pos_1, base);
+
+  if (fail_pos_1 && fail_pos_1[0] != 0)
+    {
+      val_2 = g_ascii_strtoll (nptr, &fail_pos_2, base);
+      if (fail_pos_2 && fail_pos_2[0] != 0)
+	val_3 = g_locale_strtoll (nptr, &fail_pos_3, base);
+    }
+
+  if (!fail_pos_1 || fail_pos_1[0] == 0 || 
+     (fail_pos_1 >= fail_pos_2 && fail_pos_1 >= fail_pos_3))
+    {
+      g_set_if_not_null (endptr, fail_pos_1);
+      return val_1;
+    }
+  else if (!fail_pos_2 || fail_pos_2[0] == 0 || fail_pos_2 >= fail_pos_3)
+    {
+      g_set_if_not_null (endptr, fail_pos_2);
       return val_2;
     }
+  else
+    {
+      g_set_if_not_null (endptr, fail_pos_3);
+      return val_3;
+    }
 }
 
 /**
@@ -425,7 +1089,7 @@
       memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1));
       c += end - (decimal_point_pos + 1);
       *c = 0;
-
+      
       errno = 0;
       val = strtod (copy, &fail_pos);
       strtod_errno = errno;
@@ -475,6 +1139,306 @@
   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, "%"G_GUINT64_FORMAT, 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, "%"G_GINT64_FORMAT, ll);
+}
+
+/* Don't use this macro outside this function! */
+#define add_char_to_output_and_check(ch) \
+  len = g_unichar_to_utf8 (ch, NULL); \
+  if (len > buf_len) \
+    goto buffer_full; \
+  g_unichar_to_utf8 (ch, output_pointer); 
+
+/**
+ * g_get_locale_number:
+ * @english: A String containing numbers in to convert
+ * @buffer: A buffer to place the resulting string in
+ * @buf_len: The length of the buffer.
+ *
+ * Converts an ASCII English numeric string (which uses +,.,-,ascii...) 
+ * to a locale numeric string.
+ *
+ * This function acts assuming that a correct number is 
+ * given in the input and does not check for syntax. It just converts '+', '-', 
+ * ASCII digits, and 'e' to their local equivalents, also guaranteeing that it
+ * will never write more than @buf_len bytes in the output. It leaves other
+ * characters unchanged.
+ *
+ * Return value: The pointer to the buffer with the converted string. Will
+ * return if any of given buffers are NULL.
+ **/
+
+static gchar *
+g_get_locale_number    (gchar       *english,
+			gchar       *buffer,
+			gint         buf_len)  // -1? TODO
+{
+  gunichar positive_sign;
+  gunichar negative_sign;
+  gunichar zero;
+  gunichar decimal_point;
+  const gchar *expstr;
+  gchar *input_pointer;
+  gchar *output_pointer;
+
+  struct lconv *locale_data;
+  const char *libc_decimal_point;
+  int libc_decimal_point_len;
+
+
+  g_return_val_if_fail (english != NULL, NULL);
+  g_return_val_if_fail (buffer != NULL, NULL);
+
+  positive_sign = get_locale_positive_char ();
+  negative_sign = get_locale_negative_char ();
+  zero = get_locale_zero_char ();
+  decimal_point = get_locale_decimal_point_char ();
+  expstr = get_locale_exp_str ();
+
+  output_pointer = buffer;
+  locale_data = localeconv ();
+  libc_decimal_point = locale_data->decimal_point;
+  libc_decimal_point_len = strlen(libc_decimal_point);
+
+  g_assert (libc_decimal_point != 0);
+
+  for (input_pointer =  english; *input_pointer != 0; input_pointer++)
+    {
+      gint len;
+      gunichar digit = 0;
+      switch (*input_pointer)
+        {
+	  case '+':
+	    add_char_to_output_and_check (positive_sign);
+	    break;
+
+	  case '-':
+	    add_char_to_output_and_check (negative_sign);
+	    break;
+
+	  case '0'...'9':
+	    digit = zero + (*input_pointer - '0');
+	    add_char_to_output_and_check (digit);
+	    break;
+
+	  case 'e':
+	  case 'E':
+	    len = strlen (expstr);
+	    if (len > buf_len)
+	      goto buffer_full;
+
+	    strcpy (output_pointer, expstr);
+	    break;
+
+	  default:
+	    if (strncmp (input_pointer, 
+		  	 libc_decimal_point, 
+		  	 strlen(libc_decimal_point)
+		  	) == 0)
+	      {
+		add_char_to_output_and_check (digit);
+		break;
+	      }
+	    len = 1;
+	    if (len > buf_len)
+	      goto buffer_full;
+	    
+
+	    *output_pointer = *input_pointer;
+	}
+      buf_len -= len;
+      output_pointer += len;
+    }
+buffer_full:
+  *output_pointer = '\0';
+  return buffer; 
+}
+
+#undef add_char_to_output_and_check
+
+/**
+ * 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.
+ * @ll: The #guint64 or #gint64 value 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', 'i', and 'd'.
+ *
+ * If you just 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;
+  gchar temp_buffer[G_ASCII_ITOSTR_BUF_SIZE];
+
+  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);
+  /* I don't know why? TODO */
+  /* Maybe replace with strchr (format + 1, '%') and add a translation for ','*/
+
+  format_char = format[strlen (format) - 1];
+
+  g_return_val_if_fail (format_char == 'u' ||
+	                format_char == 'd' ||
+	                format_char == 'i',
+	                NULL);
+
+/*
+  if (format[0] != '%')
+    return NULL;
+
+  if (strpbrk (format + 1, "'%"))
+    return NULL;
+
+  if (!(format_char == 'u' || 
+	format_char == 'd' ||
+        format_char == 'i')
+     )
+    return NULL;
+ * Should be removed!!? TODO
+ */ 
+  _g_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;
+  gchar temp_buffer[G_ASCII_DTOSTR_BUF_SIZE];
+
+  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); 
+  /* I don't know why? */
+  /* Maybe remove ' and add support for it! */
+
+  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;
+ *  Should be removed
+ */
+  _g_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	2007-02-22 19:47:22.000000000 +0330
@@ -29,6 +29,7 @@
 
 #include <stdarg.h>
 #include <glib/gtypes.h>
+#include "gunicode.h"
 
 G_BEGIN_DECLS
 
@@ -82,6 +83,7 @@
 #define g_ascii_isxdigit(c) \
   ((g_ascii_table[(guchar) (c)] & G_ASCII_XDIGIT) != 0)
 
+
 gchar                 g_ascii_tolower  (gchar        c) G_GNUC_CONST;
 gchar                 g_ascii_toupper  (gchar        c) G_GNUC_CONST;
 
@@ -125,6 +127,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 +156,14 @@
  * 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)
+ 
+#define G_MAX_EXP_SIZE 20
+#define G_DTOSTR_BUF_SIZE ((29 - 1) * 4 + 1 + G_MAX_EXP_SIZE + 10)
+ 
+#define G_ITOSTR_BUF_SIZE ((22 - 1) * 4 + 1 + 10)
+
 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	2002-02-18 02:58:41.000000000 +0330
+++ ./glib/glibintl.h	2007-01-24 23:42:59.000000000 +0330
@@ -27,4 +27,6 @@
 #define bindtextdomain(Domain,Directory) (Domain) 
 #endif
 
+#define Q_(String) g_strip_context ((String), _(String))
+
 #endif /* __GLIBINTL_H__ */
--- ./po/POTFILES.in.intl_numbers	2006-04-30 15:31:42.000000000 +0330
+++ ./po/POTFILES.in	2007-01-24 23:42:59.000000000 +0330
@@ -12,3 +12,4 @@
 glib/gutf8.c
 glib/goption.c
 glib/gkeyfile.c
+glib/gstrfuncs.c
--- ./po/Makefile.in.in.intl_numbers	2005-09-06 21:03:28.000000000 +0430
+++ ./po/Makefile.in.in	2007-01-24 23:42:59.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 \
