void g_logv (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, va_list args1) { gboolean was_fatal = (log_level & G_LOG_FLAG_FATAL) != 0; gboolean was_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0; gint i; log_level &= G_LOG_LEVEL_MASK; if (!log_level) return; for (i = g_bit_nth_msf (log_level, -1); i >= 0; i = g_bit_nth_msf (log_level, i)) { register GLogLevelFlags test_level; test_level = 1 << i; if (log_level & test_level) { guint depth = GPOINTER_TO_UINT (g_private_get (g_log_depth)); GLogDomain *domain; GLogFunc log_func; GLogLevelFlags domain_fatal_mask; gpointer data = NULL; gboolean masquerade_fatal = FALSE; if (was_fatal) test_level |= G_LOG_FLAG_FATAL; if (was_recursion) test_level |= G_LOG_FLAG_RECURSION; /* check recursion and lookup handler */ g_mutex_lock (g_messages_lock); domain = g_log_find_domain_L (log_domain ? log_domain : ""); if (depth) test_level |= G_LOG_FLAG_RECURSION; depth++; domain_fatal_mask = domain ? domain->fatal_mask : G_LOG_FATAL_MASK; if ((domain_fatal_mask | g_log_always_fatal) & test_level) test_level |= G_LOG_FLAG_FATAL; if (test_level & G_LOG_FLAG_RECURSION) log_func = _g_log_fallback_handler; else log_func = g_log_domain_get_handler_L (domain, test_level, &data); domain = NULL; g_mutex_unlock (g_messages_lock); g_private_set (g_log_depth, GUINT_TO_POINTER (depth)); /* had to defer debug initialization until we can keep track of recursion */ if (!(test_level & G_LOG_FLAG_RECURSION) && !_g_debug_initialized) { GLogLevelFlags orig_test_level = test_level; _g_debug_init (); if ((domain_fatal_mask | g_log_always_fatal) & test_level) test_level |= G_LOG_FLAG_FATAL; if (test_level != orig_test_level) { /* need a relookup, not nice, but not too bad either */ g_mutex_lock (g_messages_lock); domain = g_log_find_domain_L (log_domain ? log_domain : ""); log_func = g_log_domain_get_handler_L (domain, test_level, &data); domain = NULL; g_mutex_unlock (g_messages_lock); } } if (test_level & G_LOG_FLAG_RECURSION) { /* we use a stack buffer of fixed size, since we're likely * in an out-of-memory situation */ gchar buffer[1025]; gsize size G_GNUC_UNUSED; va_list args2; G_VA_COPY (args2, args1); size = _g_vsnprintf (buffer, 1024, format, args2); va_end (args2); log_func (log_domain, test_level, buffer, data); } else { gchar *msg; va_list args2; G_VA_COPY (args2, args1); msg = g_strdup_vprintf (format, args2); va_end (args2); log_func (log_domain, test_level, msg, data); if ((test_level & G_LOG_FLAG_FATAL) && !(test_level & G_LOG_LEVEL_ERROR)) { masquerade_fatal = fatal_log_func && !fatal_log_func (log_domain, test_level, msg, data); } g_free (msg); } if ((test_level & G_LOG_FLAG_FATAL) && !masquerade_fatal) { #ifdef G_OS_WIN32 gchar *locale_msg = g_locale_from_utf8 (fatal_msg_buf, -1, NULL, NULL, NULL); MessageBox (NULL, locale_msg, NULL, MB_ICONERROR|MB_SETFOREGROUND); if (IsDebuggerPresent () && !(test_level & G_LOG_FLAG_RECURSION)) G_BREAKPOINT (); else abort (); #else if (!(test_level & G_LOG_FLAG_RECURSION)) G_BREAKPOINT (); else abort (); #endif /* !G_OS_WIN32 */ } depth--; g_private_set (g_log_depth, GUINT_TO_POINTER (depth)); } } }
void g_logv (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, va_list args1) { va_list args2; gchar buffer[1025]; register gint i; log_level &= G_LOG_LEVEL_MASK; if (!log_level) return; /* we use a stack buffer of fixed size, because we might get called * recursively. */ G_VA_COPY (args2, args1); if (g_printf_string_upper_bound (format, args1) < 1024) vsprintf (buffer, format, args2); else { /* since we might be out of memory, we can't use g_vsnprintf(). */ #ifdef HAVE_VSNPRINTF vsnprintf (buffer, 1024, format, args2); #else /* !HAVE_VSNPRINTF */ /* we are out of luck here */ strncpy (buffer, format, 1024); #endif /* !HAVE_VSNPRINTF */ buffer[1024] = 0; } va_end (args2); for (i = g_bit_nth_msf (log_level, -1); i >= 0; i = g_bit_nth_msf (log_level, i)) { register GLogLevelFlags test_level; test_level = 1 << i; if (log_level & test_level) { guint depth = GPOINTER_TO_UINT (g_private_get (g_log_depth)); GLogDomain *domain; GLogFunc log_func; gpointer data = NULL; domain = g_log_find_domain (log_domain ? log_domain : ""); if (depth) test_level |= G_LOG_FLAG_RECURSION; depth++; g_private_set (g_log_depth, GUINT_TO_POINTER (depth)); g_mutex_lock (g_messages_lock); if ((((domain ? domain->fatal_mask : G_LOG_FATAL_MASK) | g_log_always_fatal) & test_level) != 0) test_level |= G_LOG_FLAG_FATAL; g_mutex_unlock (g_messages_lock); log_func = g_log_domain_get_handler (domain, test_level, &data); log_func (log_domain, test_level, buffer, data); /* *domain can be cluttered now */ if (test_level & G_LOG_FLAG_FATAL) abort (); depth--; g_private_set (g_log_depth, GUINT_TO_POINTER (depth)); } } }
/** * tracker_sparql_escape_uri_vprintf: * @format: a standard printf() format string, but notice * <link linkend="string-precision">string precision pitfalls</link> documented in g_strdup_printf() * @args: the list of parameters to insert into the format string * * Similar to the standard C vsprintf() function but safer, since it * calculates the maximum space required and allocates memory to hold * the result. * * The result is escaped using g_uri_escape_string(). * * Returns: a newly-allocated string holding the result. The returned string * should be freed with g_free() when no longer needed. * * Since: 0.10 */ gchar * tracker_sparql_escape_uri_vprintf (const gchar *format, va_list args) { GString *format1; GString *format2; GString *result = NULL; gchar *output1 = NULL; gchar *output2 = NULL; const char *p; gchar *op1, *op2; va_list args2; format1 = g_string_new (NULL); format2 = g_string_new (NULL); p = format; while (TRUE) { const char *after; const char *conv = find_conversion (p, &after); if (!conv) break; g_string_append_len (format1, conv, after - conv); g_string_append_c (format1, 'X'); g_string_append_len (format2, conv, after - conv); g_string_append_c (format2, 'Y'); p = after; } /* Use them to format the arguments */ G_VA_COPY (args2, args); output1 = g_strdup_vprintf (format1->str, args); va_end (args); if (!output1) { va_end (args2); goto cleanup; } output2 = g_strdup_vprintf (format2->str, args2); va_end (args2); if (!output2) goto cleanup; result = g_string_new (NULL); op1 = output1; op2 = output2; p = format; while (TRUE) { const char *after; const char *output_start; const char *conv = find_conversion (p, &after); char *escaped; if (!conv) { g_string_append_len (result, p, after - p); break; } g_string_append_len (result, p, conv - p); output_start = op1; while (*op1 == *op2) { op1++; op2++; } *op1 = '\0'; escaped = g_uri_escape_string (output_start, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT, FALSE); g_string_append (result, escaped); g_free (escaped); p = after; op1++; op2++; } cleanup: g_string_free (format1, TRUE); g_string_free (format2, TRUE); g_free (output1); g_free (output2); if (result) return g_string_free (result, FALSE); else return NULL; }