Add proper unicode support to the source scanner
authorJohan Dahlin <johan@gnome.org>
Thu, 2 Dec 2010 16:10:33 +0000 (14:10 -0200)
committerJohan Dahlin <johan@gnome.org>
Thu, 2 Dec 2010 16:10:33 +0000 (14:10 -0200)
The assumption is that the only allowed source encoding
is utf-8. Always strings as unicode and fix up the transformer
and xml writer to properly output utf-8.

giscanner/giscannermodule.c
giscanner/transformer.py
giscanner/xmlwriter.py

index a8061dbc6f3519d73a87d632938cb4fbb29e86eb..0f94240f180657df028371aa959447cba6ffd061 100644 (file)
@@ -564,7 +564,7 @@ static int calc_attrs_length(PyObject *attributes, int indent,
 
   for (i = 0; i < PyList_Size (attributes); ++i)
     {
-      PyObject *tuple;
+      PyObject *tuple, *pyvalue;
       char *attr, *value;
       char *escaped;
 
@@ -572,9 +572,24 @@ static int calc_attrs_length(PyObject *attributes, int indent,
       if (PyTuple_GetItem(tuple, 1) == Py_None)
        continue;
 
-      if (!PyArg_ParseTuple(tuple, "ss", &attr, &value))
+      if (!PyArg_ParseTuple(tuple, "sO", &attr, &pyvalue))
         return -1;
 
+      if (PyUnicode_Check(pyvalue)) {
+        PyObject *s = PyUnicode_AsUTF8String(pyvalue);
+        if (!s) {
+          return -1;
+        }
+        value = PyString_AsString(s);
+        Py_DECREF(s);
+      } else if (PyString_Check(pyvalue)) {
+        value = PyString_AsString(pyvalue);
+      } else {
+        PyErr_SetString(PyExc_TypeError,
+                        "value must be string or unicode");
+        return -1;
+      }
+
       escaped = g_markup_escape_text (value, -1);
       attr_length += 2 + strlen(attr) + strlen(escaped) + 2;
       g_free(escaped);
@@ -605,7 +620,7 @@ pygi_collect_attributes (PyObject *self,
     return NULL;
 
   if (attributes == Py_None || !PyList_Size(attributes))
-    return PyString_FromString("");
+    return PyUnicode_FromString("");
 
   len = calc_attrs_length(attributes, indent, self_indent);
   if (len < 0)
@@ -620,7 +635,7 @@ pygi_collect_attributes (PyObject *self,
 
   for (i = 0; i < PyList_Size (attributes); ++i)
     {
-      PyObject *tuple;
+      PyObject *tuple, *pyvalue;
       char *attr, *value, *escaped;
 
       tuple = PyList_GetItem (attributes, i);
@@ -643,9 +658,24 @@ pygi_collect_attributes (PyObject *self,
        continue;
 
       /* this leaks, but we exit after, so */
-      if (!PyArg_ParseTuple(tuple, "ss", &attr, &value))
+      if (!PyArg_ParseTuple(tuple, "sO", &attr, &pyvalue))
         return NULL;
 
+      if (PyUnicode_Check(pyvalue)) {
+        PyObject *s = PyUnicode_AsUTF8String(pyvalue);
+        if (!s) {
+          return NULL;
+        }
+        value = PyString_AsString(s);
+        Py_DECREF(s);
+      } else if (PyString_Check(pyvalue)) {
+        value = PyString_AsString(pyvalue);
+      } else {
+        PyErr_SetString(PyExc_TypeError,
+                        "value must be string or unicode");
+        return NULL;
+      }
+
       if (indent_len && !first)
        {
          g_string_append_c (attr_value, '\n');
@@ -663,7 +693,7 @@ pygi_collect_attributes (PyObject *self,
        first = FALSE;
   }
 
-  return PyString_FromString (g_string_free (attr_value, FALSE));
+  return PyUnicode_FromString (g_string_free (attr_value, FALSE));
 }
 
 /* Module */
index f07e8d17725c8f781d21846b252aa354712e90d5..4cd24484ca29dfa81a934dd2758f31825f9d8f67 100644 (file)
@@ -608,7 +608,7 @@ raise ValueError."""
             return None
         if symbol.const_string is not None:
             typeval = ast.TYPE_STRING
-            value = symbol.const_string
+            value = unicode(symbol.const_string, 'utf-8')
         elif symbol.const_int is not None:
             typeval = ast.TYPE_INT
             value = '%d' % (symbol.const_int, )
index a418cc40931db53970a9e2e4fc58fd44280e1301..84c24c0f3e291d5a16bfb5d10c71d2e6e02e1c73 100755 (executable)
@@ -120,7 +120,7 @@ class XMLWriter(object):
         if indent:
             self._data.write('%s%s%s' % (
                     self._indent_char * self._indent,
-                    line,
+                    line.encode('utf-8'),
                     self._newline_char))
         else:
             self._data.write('%s%s' % (line, self._newline_char))