Added wrapper for the xmlURIPtr type, provided accessors, fixed the

* python/generator.py python/libxml.c python/libxml2-python-api.xml
  python/libxml2class.txt python/libxml_wrap.h python/types.c:
  Added wrapper for the xmlURIPtr type, provided accessors, fixed
  the accessor generator for strings
* python/tests/Makefile.am python/tests/tstURI.py: added a specific
  regression test.
Daniel
diff --git a/ChangeLog b/ChangeLog
index a4e84f5..6e97280 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Sat Feb 23 11:08:09 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/libxml.c python/libxml2-python-api.xml
+	  python/libxml2class.txt python/libxml_wrap.h python/types.c:
+	  Added wrapper for the xmlURIPtr type, provided accessors, fixed
+	  the accessor generator for strings
+	* python/tests/Makefile.am python/tests/tstURI.py: added a specific
+	  regression test.
+
 Fri Feb 22 23:44:57 CET 2002 Daniel Veillard <daniel@veillard.com>
 
 	* python/README python/generator.py python/libxml.c python/setup.py:
diff --git a/python/generator.py b/python/generator.py
index 7a575c5..6aad6b0 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -267,6 +267,7 @@
     'htmlParserCtxt *': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
     'xmlCatalogPtr': ('O', "catalog", "xmlCatalogPtr", "xmlCatalogPtr"),
     'FILE *': ('O', "File", "FILEPtr", "FILE *"),
+    'xmlURIPtr': ('O', "URI", "xmlURIPtr", "xmlURIPtr"),
 }
 
 py_return_types = {
@@ -346,8 +347,14 @@
 
     if ret[0] == 'void':
         if file == "python_accessor":
-            c_call = "\n    %s->%s = %s;\n" % (args[0][0], args[1][0],
-                                               args[1][0])
+	    if args[1][1] == "char *" or args[1][1] == "xmlChar *":
+		c_call = "\n    if (%s->%s != NULL) xmlFree(%s->%s);\n" % (
+		                 args[0][0], args[1][0], args[0][0], args[1][0])
+		c_call = c_call + "    %s->%s = xmlStrdup(%s);\n" % (args[0][0],
+		                 args[1][0], args[1][0])
+	    else:
+		c_call = "\n    %s->%s = %s;\n" % (args[0][0], args[1][0],
+						   args[1][0])
         else:
             c_call = "\n    %s(%s);\n" % (name, c_call);
         ret_convert = "    Py_INCREF(Py_None);\n    return(Py_None);\n"
@@ -519,6 +526,7 @@
     "xmlParserCtxtPtr": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
     "xmlParserCtxt *": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
     "xmlCatalogPtr": ("._o", "catalog(_obj=%s)", "catalog"),
+    "xmlURIPtr": ("._o", "URI(_obj=%s)", "URI"),
 }
 
 converter_type = {
@@ -540,6 +548,7 @@
 classes_destructors = {
     "parserCtxt": "xmlFreeParserCtxt",
     "catalog": "xmlFreeCatalog",
+    "URI": "xmlFreeURI",
 }
 
 function_classes = {}
@@ -562,6 +571,12 @@
     elif name[0:10] == "xmlNodeGet" and file == "python_accessor":
         func = name[10:]
         func = string.lower(func[0:1]) + func[1:]
+    elif name[0:9] == "xmlURIGet" and file == "python_accessor":
+        func = name[9:]
+        func = string.lower(func[0:1]) + func[1:]
+    elif name[0:9] == "xmlURISet" and file == "python_accessor":
+        func = name[6:]
+        func = string.lower(func[0:1]) + func[1:]
     elif name[0:17] == "xmlXPathParserGet" and file == "python_accessor":
         func = name[17:]
         func = string.lower(func[0:1]) + func[1:]
diff --git a/python/libxml.c b/python/libxml.c
index e6a9eb8..f81ebb7 100644
--- a/python/libxml.c
+++ b/python/libxml.c
@@ -1422,13 +1422,14 @@
 };
 
 #ifdef MERGED_MODULES
-extern void initlibxml2mod(void);
+extern void initlibxsltmod(void);
 #endif
 
 void initlibxml2mod(void) {
     PyObject *m;
     m = Py_InitModule("libxml2mod", libxmlMethods);
     libxml_xmlErrorInitialize();
+
 #ifdef MERGED_MODULES
     initlibxsltmod();
 #endif
diff --git a/python/libxml2-python-api.xml b/python/libxml2-python-api.xml
index 24e28af..4777319 100644
--- a/python/libxml2-python-api.xml
+++ b/python/libxml2-python-api.xml
@@ -138,5 +138,105 @@
       <return type='const xmlChar *' info="The function name URI" field="functionURI"/>
       <arg name='ctxt' type='xmlXPathContextPtr' info='the XPath context'/>
     </function>
+    <!-- xmlURIPtr accessors -->
+    <function name='xmlURIGetScheme' file='python_accessor'>
+      <info>Get the scheme part from an URI</info>
+      <return type='const char *' info="The URI scheme" field="scheme"/>
+      <arg name='URI' type='xmlURIPtr' info='the URI'/>
+    </function>
+    <function name='xmlURISetScheme' file='python_accessor'>
+      <info>Set the scheme part of an URI.</info>
+      <return type='void'/>
+      <arg name='URI' type='xmlURIPtr' info='the URI'/>
+      <arg name='scheme' type='char *' info='The URI scheme part'/>
+    </function>
+    <function name='xmlURIGetOpaque' file='python_accessor'>
+      <info>Get the opaque part from an URI</info>
+      <return type='const char *' info="The URI opaque" field="opaque"/>
+      <arg name='URI' type='xmlURIPtr' info='the URI'/>
+    </function>
+    <function name='xmlURISetOpaque' file='python_accessor'>
+      <info>Set the opaque part of an URI.</info>
+      <return type='void'/>
+      <arg name='URI' type='xmlURIPtr' info='the URI'/>
+      <arg name='opaque' type='char *' info='The URI opaque part'/>
+    </function>
+    <function name='xmlURIGetAuthority' file='python_accessor'>
+      <info>Get the authority part from an URI</info>
+      <return type='const char *' info="The URI authority" field="authority"/>
+      <arg name='URI' type='xmlURIPtr' info='the URI'/>
+    </function>
+    <function name='xmlURISetAuthority' file='python_accessor'>
+      <info>Set the authority part of an URI.</info>
+      <return type='void'/>
+      <arg name='URI' type='xmlURIPtr' info='the URI'/>
+      <arg name='authority' type='char *' info='The URI authority part'/>
+    </function>
+    <function name='xmlURIGetServer' file='python_accessor'>
+      <info>Get the server part from an URI</info>
+      <return type='const char *' info="The URI server" field="server"/>
+      <arg name='URI' type='xmlURIPtr' info='the URI'/>
+    </function>
+    <function name='xmlURISetServer' file='python_accessor'>
+      <info>Set the server part of an URI.</info>
+      <return type='void'/>
+      <arg name='URI' type='xmlURIPtr' info='the URI'/>
+      <arg name='server' type='char *' info='The URI server part'/>
+    </function>
+    <function name='xmlURIGetUser' file='python_accessor'>
+      <info>Get the user part from an URI</info>
+      <return type='const char *' info="The URI user" field="user"/>
+      <arg name='URI' type='xmlURIPtr' info='the URI'/>
+    </function>
+    <function name='xmlURISetUser' file='python_accessor'>
+      <info>Set the user part of an URI.</info>
+      <return type='void'/>
+      <arg name='URI' type='xmlURIPtr' info='the URI'/>
+      <arg name='user' type='char *' info='The URI user part'/>
+    </function>
+    <function name='xmlURIGetPath' file='python_accessor'>
+      <info>Get the path part from an URI</info>
+      <return type='const char *' info="The URI path" field="path"/>
+      <arg name='URI' type='xmlURIPtr' info='the URI'/>
+    </function>
+    <function name='xmlURISetPath' file='python_accessor'>
+      <info>Set the path part of an URI.</info>
+      <return type='void'/>
+      <arg name='URI' type='xmlURIPtr' info='the URI'/>
+      <arg name='path' type='char *' info='The URI path part'/>
+    </function>
+    <function name='xmlURIGetQuery' file='python_accessor'>
+      <info>Get the query part from an URI</info>
+      <return type='const char *' info="The URI query" field="query"/>
+      <arg name='URI' type='xmlURIPtr' info='the URI'/>
+    </function>
+    <function name='xmlURISetQuery' file='python_accessor'>
+      <info>Set the query part of an URI.</info>
+      <return type='void'/>
+      <arg name='URI' type='xmlURIPtr' info='the URI'/>
+      <arg name='query' type='char *' info='The URI query part'/>
+    </function>
+    <function name='xmlURIGetFragment' file='python_accessor'>
+      <info>Get the fragment part from an URI</info>
+      <return type='const char *' info="The URI fragment" field="fragment"/>
+      <arg name='URI' type='xmlURIPtr' info='the URI'/>
+    </function>
+    <function name='xmlURISetFragment' file='python_accessor'>
+      <info>Set the fragment part of an URI.</info>
+      <return type='void'/>
+      <arg name='URI' type='xmlURIPtr' info='the URI'/>
+      <arg name='fragment' type='char *' info='The URI fragment part'/>
+    </function>
+    <function name='xmlURIGetPort' file='python_accessor'>
+      <info>Get the port part from an URI</info>
+      <return type='int' info="The URI port" field="port"/>
+      <arg name='URI' type='xmlURIPtr' info='the URI'/>
+    </function>
+    <function name='xmlURISetPort' file='python_accessor'>
+      <info>Set the port part of an URI.</info>
+      <return type='void'/>
+      <arg name='URI' type='xmlURIPtr' info='the URI'/>
+      <arg name='port' type='int' info='The URI port part'/>
+    </function>
   </symbols>
 </api>
diff --git a/python/libxml2class.txt b/python/libxml2class.txt
index 642df7c..0b78625 100644
--- a/python/libxml2class.txt
+++ b/python/libxml2class.txt
@@ -137,7 +137,9 @@
 URIEscapeStr()
 URIUnescapeString()
 buildURI()
+createURI()
 normalizeURIPath()
+parseURI()
 
 # functions from module xmlIO
 cleanupInputCallbacks()
@@ -506,6 +508,32 @@
     freeProp()
     freePropList()
     removeProp()
+Class URI()
+    # accessors
+    authority()
+    fragment()
+    opaque()
+    path()
+    port()
+    query()
+    scheme()
+    server()
+    setAuthority()
+    setFragment()
+    setOpaque()
+    setPath()
+    setPort()
+    setQuery()
+    setScheme()
+    setServer()
+    setUser()
+    user()
+
+    # functions from module uri
+    freeURI()
+    parseURIReference()
+    printURI()
+    saveUri()
 Class xpathContext()
     # accessors
     contextDoc()
diff --git a/python/libxml_wrap.h b/python/libxml_wrap.h
index 77c0736..1877deb 100644
--- a/python/libxml_wrap.h
+++ b/python/libxml_wrap.h
@@ -55,9 +55,19 @@
     xmlCatalogPtr obj;
 } Pycatalog_Object;
 
+#define PyURI_Get(v) (((v) == Py_None) ? NULL : \
+	(((PyURI_Object *)(v))->obj))
+
+typedef struct {
+    PyObject_HEAD
+    xmlURIPtr obj;
+} PyURI_Object;
+
+/* FILE * have their own internal representation */
 #define PyFile_Get(v) (((v) == Py_None) ? NULL : \
 	(PyFile_Check(v) ? NULL : (PyFile_AsFile(v))))
 
+
 PyObject * libxml_intWrap(int val);
 PyObject * libxml_longWrap(long val);
 PyObject * libxml_xmlCharPtrWrap(xmlChar *str);
@@ -78,5 +88,6 @@
 PyObject * libxml_xmlXPathParserContextPtrWrap(xmlXPathParserContextPtr ctxt);
 PyObject * libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj);
 PyObject * libxml_xmlCatalogPtrWrap(xmlCatalogPtr obj);
+PyObject * libxml_xmlURIPtrWrap(xmlURIPtr uri);
 
 xmlXPathObjectPtr libxml_xmlXPathObjectPtrConvert(PyObject * obj);
diff --git a/python/tests/Makefile.am b/python/tests/Makefile.am
index d4e937c..f865c6b 100644
--- a/python/tests/Makefile.am
+++ b/python/tests/Makefile.am
@@ -9,6 +9,7 @@
     pushSAX.py	\
     error.py	\
     validate.py	\
+    tstURI.py	\
     xpath.py
 
 XMLS=		\
diff --git a/python/tests/tstURI.py b/python/tests/tstURI.py
new file mode 100755
index 0000000..58b7ad8
--- /dev/null
+++ b/python/tests/tstURI.py
@@ -0,0 +1,41 @@
+#!/usr/bin/python -u
+import sys
+import libxml2
+
+# Memory debug specific
+libxml2.debugMemory(1)
+
+uri = libxml2.parseURI("http://example.org:8088/foo/bar?query=simple#fragid")
+if uri.scheme() != 'http':
+    print "Error parsing URI: wrong scheme"
+    sys.exit(1)
+if uri.server() != 'example.org':
+    print "Error parsing URI: wrong server"
+    sys.exit(1)
+if uri.port() != 8088:
+    print "Error parsing URI: wrong port"
+    sys.exit(1)
+if uri.path() != '/foo/bar':
+    print "Error parsing URI: wrong path"
+    sys.exit(1)
+if uri.query() != 'query=simple':
+    print "Error parsing URI: wrong query"
+    sys.exit(1)
+if uri.fragment() != 'fragid':
+    print "Error parsing URI: wrong query"
+    sys.exit(1)
+uri.setScheme("https")
+uri.setPort(223)
+uri.setFragment(None)
+result=uri.saveUri()
+if result != "https://example.org:223/foo/bar?query=simple":
+    print "Error modifying or saving the URI"
+uri = None
+
+# Memory debug specific
+libxml2.cleanupParser()
+if libxml2.debugMemory(1) == 0:
+    print "OK"
+else:
+    print "Memory leak %d bytes" % (libxml2.debugMemory(1))
+    libxml2.dumpMemory()
diff --git a/python/types.c b/python/types.c
index 7718d5f..d9fbd94 100644
--- a/python/types.c
+++ b/python/types.c
@@ -171,6 +171,21 @@
 }
 
 PyObject *
+libxml_xmlURIPtrWrap(xmlURIPtr uri) {
+    PyObject *ret;
+
+#ifdef DEBUG
+    printf("libxml_xmlURIPtrWrap: uri = %p\n", uri);
+#endif
+    if (uri == NULL) {
+	Py_INCREF(Py_None);
+	return(Py_None);
+    }
+    ret = PyCObject_FromVoidPtrAndDesc((void *) uri, "xmlURIPtr", NULL);
+    return(ret);
+}
+
+PyObject *
 libxml_xmlNsPtrWrap(xmlNsPtr ns) {
     PyObject *ret;