#include "glib.h"
#include "gprintf.h"
#include "gprintfint.h"
+#include "glibintl.h"
#include "galias.h"
* the last character used in the conversion.
*
* Converts a string to a #gdouble value.
+ *
* This function behaves like the standard strtod() function
- * does in the C locale. It does this without actually
- * changing the current locale, since that would not be
- * thread-safe.
+ * does in the C locale. It does this without actually changing
+ * the current locale, since that would not be thread-safe.
+ * A limitation of the implementation is that this function
+ * will still accept localized versions of infinities and NANs.
*
* This function is typically used when reading configuration
* files or other non-user input that should be locale independent.
{
*p = '.';
p++;
- if (decimal_point_len > 1) {
- rest_len = strlen (p + (decimal_point_len-1));
- memmove (p, p + (decimal_point_len-1),
- rest_len);
- p[rest_len] = 0;
-
- }
+ if (decimal_point_len > 1)
+ {
+ rest_len = strlen (p + (decimal_point_len-1));
+ memmove (p, p + (decimal_point_len-1), rest_len);
+ p[rest_len] = 0;
+ }
}
}
}
static guint64
-g_parse_long_long (const gchar *nptr,
- gchar **endptr,
- guint base,
- gboolean *negative)
+g_parse_long_long (const gchar *nptr,
+ const gchar **endptr,
+ guint base,
+ gboolean *negative)
{
/* this code is based on on the strtol(3) code from GNU libc released under
* the GNU Lesser General Public License.
g_return_val_if_fail (nptr != NULL, 0);
+ *negative = FALSE;
if (base == 1 || base > 36)
{
errno = EINVAL;
+ if (endptr)
+ *endptr = nptr;
return 0;
}
goto noconv;
/* Check for a sign. */
- *negative = FALSE;
if (*s == '-')
{
*negative = TRUE;
/* Store in ENDPTR the address of one character
past the last character we converted. */
if (endptr)
- *endptr = (gchar*) s;
+ *endptr = s;
if (G_UNLIKELY (overflow))
{
{
if (save - nptr >= 2 && TOUPPER (save[-1]) == 'X'
&& save[-2] == '0')
- *endptr = (gchar*) &save[-1];
+ *endptr = &save[-1];
else
/* There was no number to convert. */
- *endptr = (gchar*) nptr;
+ *endptr = nptr;
}
return 0;
}
gboolean negative;
guint64 result;
- result = g_parse_long_long (nptr, endptr, base, &negative);
+ result = g_parse_long_long (nptr, (const gchar **) endptr, base, &negative);
/* Return the result of the appropriate sign. */
return negative ? -result : result;
gboolean negative;
guint64 result;
- result = g_parse_long_long (nptr, endptr, base, &negative);
+ result = g_parse_long_long (nptr, (const gchar **) endptr, base, &negative);
if (negative && result > (guint64) G_MININT64)
{
errno = ERANGE;
return G_MAXINT64;
}
+ else if (negative)
+ return - (gint64) result;
else
return (gint64) result;
}
while (--max_tokens && s)
{
gsize len;
- gchar *new_string;
len = s - remainder;
- new_string = g_new (gchar, len + 1);
- strncpy (new_string, remainder, len);
- new_string[len] = 0;
- string_list = g_slist_prepend (string_list, new_string);
+ string_list = g_slist_prepend (string_list,
+ g_strndup (remainder, len));
n++;
remainder = s + delimiter_len;
s = strstr (remainder, delimiter);
{
int i;
- for(i = 0; str_array[i] != NULL; i++)
- g_free(str_array[i]);
+ for (i = 0; str_array[i] != NULL; i++)
+ g_free (str_array[i]);
g_free (str_array);
}
/**
* g_strstr_len:
* @haystack: a string.
- * @haystack_len: the maximum length of @haystack.
+ * @haystack_len: the maximum length of @haystack. Note that -1 is
+ * a valid length, if @haystack is nul-terminated, meaning it will
+ * search through the whole string.
* @needle: the string to search for.
*
* Searches the string @haystack for the first occurrence
{
g_return_val_if_fail (haystack != NULL, NULL);
g_return_val_if_fail (needle != NULL, NULL);
-
+
if (haystack_len < 0)
return strstr (haystack, needle);
else
end = haystack + haystack_len - needle_len;
- while (*p && p <= end)
+ while (p <= end && *p)
{
for (i = 0; i < needle_len; i++)
if (p[i] != needle[i])
return i;
}
+
+/**
+ * g_dpgettext:
+ * @domain: the translation domain to use, or %NULL to use
+ * the domain set with textdomain()
+ * @msgctxtid: a combined message context and message id, separated
+ * by a \004 character
+ * @msgidoffset: the offset of the message id in @msgctxid
+ *
+ * This function is a variant of g_dgettext() which supports
+ * a disambiguating message context. GNU gettext uses the
+ * '\004' character to separate the message context and
+ * message id in @msgctxtid.
+ * If 0 is passed as @msgidoffset, this function will fall back to
+ * trying to use the deprecated convention of using "|" as a separation
+ * character.
+ *
+ * This uses g_dgettext() internally. See that functions for differences
+ * with dgettext() proper.
+ *
+ * Applications should normally not use this function directly,
+ * but use the C_() macro for translations with context.
+ *
+ * Returns: The translated string
+ *
+ * Since: 2.16
+ */
+G_CONST_RETURN gchar *
+g_dpgettext (const gchar *domain,
+ const gchar *msgctxtid,
+ gsize msgidoffset)
+{
+ const gchar *translation;
+ gchar *sep;
+
+ translation = g_dgettext (domain, msgctxtid);
+
+ if (translation == msgctxtid)
+ {
+ if (msgidoffset > 0)
+ return msgctxtid + msgidoffset;
+
+ sep = strchr (msgctxtid, '|');
+
+ if (sep)
+ {
+ /* try with '\004' instead of '|', in case
+ * xgettext -kQ_:1g was used
+ */
+ gchar *tmp = g_alloca (strlen (msgctxtid) + 1);
+ strcpy (tmp, msgctxtid);
+ tmp[sep - msgctxtid] = '\004';
+
+ translation = g_dgettext (domain, tmp);
+
+ if (translation == tmp)
+ return sep + 1;
+ }
+ }
+
+ return translation;
+}
+
+/* This function is taken from gettext.h
+ * GNU gettext uses '\004' to separate context and msgid in .mo files.
+ */
+/**
+ * g_dpgettext2:
+ * @domain: the translation domain to use, or %NULL to use
+ * the domain set with textdomain()
+ * @context: the message context
+ * @msgid: the message
+ *
+ * This function is a variant of g_dgettext() which supports
+ * a disambiguating message context. GNU gettext uses the
+ * '\004' character to separate the message context and
+ * message id in @msgctxtid.
+ *
+ * This uses g_dgettext() internally. See that functions for differences
+ * with dgettext() proper.
+ *
+ * This function differs from C_() in that it is not a macro and
+ * thus you may use non-string-literals as context and msgid arguments.
+ *
+ * Returns: The translated string
+ *
+ * Since: 2.18
+ */
+G_CONST_RETURN char *
+g_dpgettext2 (const char *domain,
+ const char *msgctxt,
+ const char *msgid)
+{
+ size_t msgctxt_len = strlen (msgctxt) + 1;
+ size_t msgid_len = strlen (msgid) + 1;
+ const char *translation;
+ char* msg_ctxt_id;
+
+ msg_ctxt_id = g_alloca (msgctxt_len + msgid_len);
+
+ memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
+ msg_ctxt_id[msgctxt_len - 1] = '\004';
+ memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
+
+ translation = g_dgettext (domain, msg_ctxt_id);
+
+ if (translation == msg_ctxt_id)
+ {
+ /* try the old way of doing message contexts, too */
+ msg_ctxt_id[msgctxt_len - 1] = '|';
+ translation = g_dgettext (domain, msg_ctxt_id);
+
+ if (translation == msg_ctxt_id)
+ return msgid;
+ }
+
+ return translation;
+}
+
+static gboolean
+_g_dgettext_should_translate (void)
+{
+ static gsize translate = 0;
+ enum {
+ SHOULD_TRANSLATE = 1,
+ SHOULD_NOT_TRANSLATE = 2
+ };
+
+ if (G_UNLIKELY (g_once_init_enter (&translate)))
+ {
+ gboolean should_translate = TRUE;
+
+ const char *default_domain = textdomain (NULL);
+ const char *translator_comment = gettext ("");
+#ifndef G_OS_WIN32
+ const char *translate_locale = setlocale (LC_MESSAGES, NULL);
+#else
+ const char *translate_locale = g_win32_getlocale ();
+#endif
+ /* We should NOT translate only if all the following hold:
+ * - user has called textdomain() and set textdomain to non-default
+ * - default domain has no translations
+ * - locale does not start with "en_" and is not "C"
+ *
+ * Rationale:
+ * - If text domain is still the default domain, maybe user calls
+ * it later. Continue with old behavior of translating.
+ * - If locale starts with "en_", we can continue using the
+ * translations even if the app doesn't have translations for
+ * this locale. That is, en_UK and en_CA for example.
+ * - If locale is "C", maybe user calls setlocale(LC_ALL,"") later.
+ * Continue with old behavior of translating.
+ */
+ if (0 != strcmp (default_domain, "messages") &&
+ '\0' == *translator_comment &&
+ 0 != strncmp (translate_locale, "en_", 3) &&
+ 0 != strcmp (translate_locale, "C"))
+ should_translate = FALSE;
+
+ g_once_init_leave (&translate,
+ should_translate ?
+ SHOULD_TRANSLATE :
+ SHOULD_NOT_TRANSLATE);
+ }
+
+ return translate == SHOULD_TRANSLATE;
+}
+
+/**
+ * g_dgettext:
+ * @domain: the translation domain to use, or %NULL to use
+ * the domain set with textdomain()
+ * @msgid: message to translate
+ *
+ * This function is a wrapper of dgettext() which does not translate
+ * the message if the default domain as set with textdomain() has no
+ * translations for the current locale.
+ *
+ * The advantage of using this function over dgettext() proper is that
+ * libraries using this function (like GTK+) will not use translations
+ * if the application using the library does not have translations for
+ * the current locale. This results in a consistent English-only
+ * interface instead of one having partial translations. For this
+ * feature to work, the call to textdomain() and setlocale() should
+ * precede any g_dgettext() invocations. For GTK+, it means calling
+ * textdomain() before gtk_init or its variants.
+ *
+ * This function disables translations if and only if upon its first
+ * call all the following conditions hold:
+ * <itemizedlist>
+ * <listitem>@domain is not %NULL</listitem>
+ * <listitem>textdomain() has been called to set a default text domain</listitem>
+ * <listitem>there is no translations available for the default text domain
+ * and the current locale</listitem>
+ * <listitem>current locale is not "C" or any English locales (those
+ * starting with "en_")</listitem>
+ * </itemizedlist>
+ *
+ * Note that this behavior may not be desired for example if an application
+ * has its untranslated messages in a language other than English. In those
+ * cases the application should call textdomain() after initializing GTK+.
+ *
+ * Applications should normally not use this function directly,
+ * but use the _() macro for translations.
+ *
+ * Returns: The translated string
+ *
+ * Since: 2.18
+ */
+G_CONST_RETURN gchar *
+g_dgettext (const gchar *domain,
+ const gchar *msgid)
+{
+ if (domain && G_UNLIKELY (!_g_dgettext_should_translate ()))
+ return msgid;
+
+ return dgettext (domain, msgid);
+}
+
+/**
+ * g_dngettext:
+ * @domain: the translation domain to use, or %NULL to use
+ * the domain set with textdomain()
+ * @msgid: message to translate
+ * @msgid_plural: plural form of the message
+ * @n: the quantity for which translation is needed
+ *
+ * This function is a wrapper of dngettext() which does not translate
+ * the message if the default domain as set with textdomain() has no
+ * translations for the current locale.
+ *
+ * See g_dgettext() for details of how this differs from dngettext()
+ * proper.
+ *
+ * Returns: The translated string
+ *
+ * Since: 2.18
+ */
+G_CONST_RETURN gchar *
+g_dngettext (const gchar *domain,
+ const gchar *msgid,
+ const gchar *msgid_plural,
+ gulong n)
+{
+ if (domain && G_UNLIKELY (!_g_dgettext_should_translate ()))
+ return n == 1 ? msgid : msgid_plural;
+
+ return dngettext (domain, msgid, msgid_plural, n);
+}
+
+
#define __G_STRFUNCS_C__
#include "galiasdef.c"