From 0199f75bbdfe8ace02c5d38f4cfa27791eb97e44 Mon Sep 17 00:00:00 2001
From: Gabriel <g2p.code@gmail.com>
Date: Wed, 13 Mar 2013 13:51:03 +0100
Subject: [PATCH] Convert unicode at the C boundary.

---
 augeas.py | 57 +++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 36 insertions(+), 21 deletions(-)

--- a/augeas.py
+++ b/augeas.py
@@ -43,6 +43,19 @@ import ctypes
 import ctypes.util
 from sys import version_info as _pyver
 
+AUGENC = 'utf8'
+
+
+def enc(st):
+    if st:
+        return st.encode(AUGENC)
+
+
+def dec(st):
+    if st:
+        return st.decode(AUGENC)
+
+
 def _dlopen(*args):
     """Search for one of the libraries given as arguments and load it.
     Returns the library.
@@ -99,7 +112,7 @@ class Augeas(object):
             raise TypeError("flag MUST be a flag!")
 
         # Create the Augeas object
-        self.__handle = Augeas._libaugeas.aug_init(root, loadpath, flags)
+        self.__handle = Augeas._libaugeas.aug_init(enc(root), enc(loadpath), flags)
         if not self.__handle:
             raise RuntimeError("Unable to create Augeas object!")
         # Make sure self.__handle is a void*, not an integer
@@ -123,12 +136,12 @@ class Augeas(object):
         value = ctypes.c_char_p()
 
         # Call the function and pass value by reference (char **)
-        ret = Augeas._libaugeas.aug_get(self.__handle, path,
+        ret = Augeas._libaugeas.aug_get(self.__handle, enc(path),
                                         ctypes.byref(value))
         if ret > 1:
             raise ValueError("path specified had too many matches!")
 
-        return value.value
+        return dec(value.value)
 
     def set(self, path, value):
         """Set the value associated with 'path' to 'value'.
@@ -144,7 +157,7 @@ class Augeas(object):
             raise RuntimeError("The Augeas object has already been closed!")
 
         # Call the function
-        ret = Augeas._libaugeas.aug_set(self.__handle, path, value)
+        ret = Augeas._libaugeas.aug_set(self.__handle, enc(path), enc(value))
         if ret != 0:
             raise ValueError("Unable to set value to path!")
 
@@ -166,7 +179,8 @@ class Augeas(object):
             raise RuntimeError, "The Augeas object has already been closed!"
 
         # Call the function
-        ret = Augeas._libaugeas.aug_setm(self.__handle, base, sub, value)
+        ret = Augeas._libaugeas.aug_setm(
+            self.__handle, enc(base), enc(sub), enc(value))
         if ret < 0:
             raise ValueError, "Unable to set value to path!"
         return ret
@@ -175,10 +189,10 @@ class Augeas(object):
         """Define a variable 'name' whose value is the result of
         evaluating 'expr'. If a variable 'name' already exists, its
         name will be replaced with the result of evaluating 'expr'.
- 
+
         If 'expr' is None, the variable 'name' will be removed if it
         is defined.
- 
+
         Path variables can be used in path expressions later on by
         prefixing them with '$'."""
 
@@ -191,7 +205,7 @@ class Augeas(object):
             raise RuntimeError, "The Augeas object has already been closed!"
 
         # Call the function
-        ret = Augeas._libaugeas.aug_defvar(self.__handle, name, expr)
+        ret = Augeas._libaugeas.aug_defvar(self.__handle, enc(name), enc(expr))
         if ret < 0:
             raise ValueError, "Unable to register variable!"
         return ret
@@ -201,7 +215,7 @@ class Augeas(object):
         evaluating 'expr', which must not be None and evaluate to a
         nodeset. If a variable 'name' already exists, its name will
         be replaced with the result of evaluating 'expr'.
- 
+
         If 'expr' evaluates to an empty nodeset, a node is created,
         equivalent to calling set(expr, value) and 'name' will be the
         nodeset containing that single node."""
@@ -217,7 +231,8 @@ class Augeas(object):
             raise RuntimeError, "The Augeas object has already been closed!"
 
         # Call the function
-        ret = Augeas._libaugeas.aug_defnode(self.__handle, name, expr, value, None)
+        ret = Augeas._libaugeas.aug_defnode(
+            self.__handle, enc(name), enc(expr), enc(value), None)
         if ret < 0:
             raise ValueError, "Unable to register node!"
         return ret
@@ -238,7 +253,7 @@ class Augeas(object):
             raise RuntimeError("The Augeas object has already been closed!")
 
         # Call the function
-        ret = Augeas._libaugeas.aug_mv(self.__handle, src, dst)
+        ret = Augeas._libaugeas.aug_mv(self.__handle, enc(src), enc(dst))
         if ret != 0:
             raise ValueError("Unable to move src to dst!")
 
@@ -260,8 +275,8 @@ class Augeas(object):
             raise RuntimeError("The Augeas object has already been closed!")
 
         # Call the function
-        ret = Augeas._libaugeas.aug_insert(self.__handle, path,
-                                           label, before and 1 or 0)
+        ret = Augeas._libaugeas.aug_insert(self.__handle, enc(path),
+                                           enc(label), before and 1 or 0)
         if ret != 0:
             raise ValueError("Unable to insert label!")
 
@@ -277,7 +292,7 @@ class Augeas(object):
             raise RuntimeError("The Augeas object has already been closed!")
 
         # Call the function
-        return Augeas._libaugeas.aug_rm(self.__handle, path)
+        return Augeas._libaugeas.aug_rm(self.__handle, enc(path))
 
     def match(self, path):
         """Return the matches of the path expression 'path'. The returned paths
@@ -306,7 +321,7 @@ class Augeas(object):
         array = ctypes.POINTER(ctypes.c_void_p)()
 
         # Call the function and pass the void ** by reference (void ***)
-        ret = Augeas._libaugeas.aug_match(self.__handle, path,
+        ret = Augeas._libaugeas.aug_match(self.__handle, enc(path),
                                           ctypes.byref(array))
         if ret < 0:
             raise RuntimeError("Error during match procedure!")
@@ -316,7 +331,7 @@ class Augeas(object):
         for i in range(ret):
             if array[i]:
                 # Create a python string and append it to our matches list
-                matches.append(str(ctypes.cast(array[i],
+                matches.append(dec(ctypes.cast(array[i],
                                                ctypes.c_char_p).value))
 
                 # Free the string at this point in the array
@@ -351,14 +366,14 @@ class Augeas(object):
 
         r = ctypes.byref
 
-        ret = Augeas._libaugeas.aug_span(self.__handle, path, r(filename),
+        ret = Augeas._libaugeas.aug_span(self.__handle, enc(path), r(filename),
                                          r(label_start), r(label_end),
                                          r(value_start), r(value_end),
                                          r(span_start), r(span_end))
         if (ret < 0):
             raise ValueError("Error during span procedure")
 
-        return (filename.value, label_start.value, label_end.value,
+        return (dec(filename.value), label_start.value, label_end.value,
                 value_start.value, value_end.value,
                 span_start.value, span_end.value)
 
