g_string_append_c (str, '&');
}
+static char*
+escape_special_chars (const char* identifier)
+{
+ size_t id_len = strlen (identifier);
+ // Assume the worst case, and thus only allocate once
+ char *res = g_malloc (id_len * 2 + 1);
+ char *res_ptr = res;
+ for (const char *s = identifier; *s != 0; s++) {
+ switch (*s) {
+ case ',':
+ case '+':
+ case '&':
+ case '*':
+ case '[':
+ case ']':
+ case '\\':
+ *res_ptr++ = '\\';
+ break;
+ }
+ *res_ptr++ = *s;
+ }
+ *res_ptr = '\0';
+ return res;
+}
+
/**
* mono_identifier_escape_type_name_chars:
- * \param str a destination string
- * \param identifier an IDENTIFIER in internal form
- *
- * \returns \p str
+ * \param identifier the display name of a mono type
*
- * The displayed form of the identifier is appended to str.
+ * \returns The name in external form, that is with escaping backslashes.
*
* The displayed form of an identifier has the characters ,+&*[]\
* that have special meaning in type names escaped with a preceeding
* backslash (\) character.
*/
-static GString*
-mono_identifier_escape_type_name_chars (GString* str, const char* identifier)
+char*
+mono_identifier_escape_type_name_chars (const char* identifier)
{
if (!identifier)
- return str;
-
- size_t n = str->len;
- // reserve space for common case: there will be no escaped characters.
- g_string_set_size(str, n + strlen(identifier));
- g_string_set_size(str, n);
+ return NULL;
- for (const char* s = identifier; *s != 0 ; s++) {
+ // If the string has any special characters escape the whole thing, otherwise just return the input
+ for (const char *s = identifier; *s != 0; s++) {
switch (*s) {
case ',':
case '+':
case '[':
case ']':
case '\\':
- g_string_append_c (str, '\\');
- g_string_append_c (str, *s);
- break;
- default:
- g_string_append_c (str, *s);
- break;
+ return escape_special_chars (identifier);
}
}
- return str;
+
+ return g_strdup (identifier);
}
static void
const char *klass_name_space = m_class_get_name_space (klass);
if (format == MONO_TYPE_NAME_FORMAT_IL)
g_string_append (str, klass_name_space);
- else
- mono_identifier_escape_type_name_chars (str, klass_name_space);
+ else {
+ char *escaped = mono_identifier_escape_type_name_chars (klass_name_space);
+ g_string_append (str, escaped);
+ g_free (escaped);
+ }
g_string_append_c (str, '.');
}
const char *klass_name = m_class_get_name (klass);
gssize len = s ? (s - klass_name) : (gssize)strlen (klass_name);
g_string_append_len (str, klass_name, len);
} else {
- mono_identifier_escape_type_name_chars (str, klass_name);
+ char *escaped = mono_identifier_escape_type_name_chars (klass_name);
+ g_string_append (str, escaped);
+ g_free (escaped);
}
if (is_recursed)
break;