[gjs] gjs_value_debug_string: Always return UTF-8
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs] gjs_value_debug_string: Always return UTF-8
- Date: Wed, 1 Dec 2010 22:12:48 +0000 (UTC)
commit 52593563c9e9873231f5fdae3dc1668460bee37e
Author: Colin Walters <walters verbum org>
Date: Wed Dec 1 17:11:16 2010 -0500
gjs_value_debug_string: Always return UTF-8
Returning whatever JS_GetStringBytes gave us will blow up if
the string contains non-UTF8 characters and we're trying to g_print
to a UTF-8 terminal (the standard case). Since this is just a
debugging string, import a copy of _g_utf8_make_valid which
squashes it to UTF-8 in a useful way.
gjs/jsapi-util.c | 33 +++++++++++++++++++++++++--------
gjs/jsapi-util.h | 2 +-
util/glib.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
util/glib.h | 2 ++
4 files changed, 71 insertions(+), 10 deletions(-)
---
diff --git a/gjs/jsapi-util.c b/gjs/jsapi-util.c
index 11c890a..714b91e 100644
--- a/gjs/jsapi-util.c
+++ b/gjs/jsapi-util.c
@@ -755,12 +755,20 @@ gjs_define_string_array(JSContext *context,
return array;
}
-const char*
+/**
+ * gjs_value_debug_string:
+ * @context:
+ * @value: Any JavaScript value
+ *
+ * Returns: A UTF-8 encoded string describing @value
+ */
+char*
gjs_value_debug_string(JSContext *context,
jsval value)
{
JSString *str;
const char *bytes;
+ char *debugstr;
JS_BeginRequest(context);
@@ -778,14 +786,14 @@ gjs_value_debug_string(JSContext *context,
str = JS_NewStringCopyZ(context, klass->name);
JS_ClearPendingException(context);
if (str == NULL) {
- return "[out of memory copying class name]";
+ return g_strdup("[out of memory copying class name]");
}
} else {
gjs_log_exception(context, NULL);
- return "[unknown object]";
+ return g_strdup("[unknown object]");
}
} else {
- return "[unknown non-object]";
+ return g_strdup("[unknown non-object]");
}
}
@@ -795,7 +803,9 @@ gjs_value_debug_string(JSContext *context,
JS_EndRequest(context);
- return bytes;
+ debugstr = _gjs_g_utf8_make_valid(bytes);
+
+ return debugstr;
}
void
@@ -829,6 +839,7 @@ gjs_log_object_props(JSContext *context,
while (!JSID_IS_VOID(prop_id)) {
jsval propval;
const char *name;
+ char *debugstr;
if (!gjs_get_string_id(context, prop_id, &name))
goto next;
@@ -836,10 +847,12 @@ gjs_log_object_props(JSContext *context,
if (!gjs_object_get_property(context, obj, name, &propval))
goto next;
+ debugstr = gjs_value_debug_string(context, propval);
gjs_debug(topic,
"%s%s = '%s'",
prefix, name,
- gjs_value_debug_string(context, propval));
+ debugstr);
+ g_free(debugstr);
next:
prop_id = JSID_VOID;
@@ -859,6 +872,7 @@ gjs_explain_scope(JSContext *context,
JSObject *global;
JSObject *parent;
GString *chain;
+ char *debugstr;
gjs_debug(GJS_DEBUG_SCOPE,
"=== %s ===",
@@ -874,14 +888,16 @@ gjs_explain_scope(JSContext *context,
"");
global = JS_GetGlobalObject(context);
+ debugstr = gjs_value_debug_string(context, OBJECT_TO_JSVAL(global));
gjs_debug(GJS_DEBUG_SCOPE,
" Global: %p %s",
- global, gjs_value_debug_string(context, OBJECT_TO_JSVAL(global)));
+ global, debugstr);
+ g_free(debugstr);
parent = JS_GetScopeChain(context);
chain = g_string_new(NULL);
while (parent != NULL) {
- const char *debug;
+ char *debug;
debug = gjs_value_debug_string(context, OBJECT_TO_JSVAL(parent));
if (chain->len > 0)
@@ -889,6 +905,7 @@ gjs_explain_scope(JSContext *context,
g_string_append_printf(chain, "%p %s",
parent, debug);
+ g_free(debug);
parent = JS_GetParent(context, parent);
}
gjs_debug(GJS_DEBUG_SCOPE,
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index 424cded..b7c6a8b 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -267,7 +267,7 @@ void gjs_log_object_props (JSContext *context,
GjsDebugTopic topic,
const char *prefix);
#endif
-const char* gjs_value_debug_string (JSContext *context,
+char* gjs_value_debug_string (JSContext *context,
jsval value);
void gjs_explain_scope (JSContext *context,
const char *title);
diff --git a/util/glib.c b/util/glib.c
index 316e6e0..b79e75f 100644
--- a/util/glib.c
+++ b/util/glib.c
@@ -21,10 +21,12 @@
* IN THE SOFTWARE.
*/
-#include <config.h>
+#include <string.h>
#include "glib.h"
+#include <config.h>
+
typedef struct {
void *key;
void *value;
@@ -125,6 +127,46 @@ gjs_g_strv_concat(char ***strv_array, int len)
return (char**)g_ptr_array_free(array, FALSE);
}
+gchar *
+_gjs_g_utf8_make_valid (const gchar *name)
+{
+ GString *string;
+ const gchar *remainder, *invalid;
+ gint remaining_bytes, valid_bytes;
+
+ g_return_val_if_fail (name != NULL, NULL);
+
+ string = NULL;
+ remainder = name;
+ remaining_bytes = strlen (name);
+
+ while (remaining_bytes != 0)
+ {
+ if (g_utf8_validate (remainder, remaining_bytes, &invalid))
+ break;
+ valid_bytes = invalid - remainder;
+
+ if (string == NULL)
+ string = g_string_sized_new (remaining_bytes);
+
+ g_string_append_len (string, remainder, valid_bytes);
+ /* append U+FFFD REPLACEMENT CHARACTER */
+ g_string_append (string, "\357\277\275");
+
+ remaining_bytes -= valid_bytes + 1;
+ remainder = invalid + 1;
+ }
+
+ if (string == NULL)
+ return g_strdup (name);
+
+ g_string_append (string, remainder);
+
+ g_assert (g_utf8_validate (string->str, -1, NULL));
+
+ return g_string_free (string, FALSE);
+}
+
#if GJS_BUILD_TESTS
void
diff --git a/util/glib.h b/util/glib.h
index 7bdc01a..5be171f 100644
--- a/util/glib.h
+++ b/util/glib.h
@@ -28,6 +28,8 @@
G_BEGIN_DECLS
+gchar * _gjs_g_utf8_make_valid (const gchar *name);
+
gboolean gjs_g_hash_table_remove_one (GHashTable *hash,
void **key_p,
void **value_p);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]