Bug 10645 fixed: File encoding could not be given as argument in xmlRead 31/13331/4
Calixte DENIZET [Fri, 6 Dec 2013 13:29:28 +0000 (14:29 +0100)]
Change-Id: I39428e43aca1069f5ebc29c4c545ac84182294b8

SEP/INDEX
SEP/SEP_119_xml_encoding.odt [new file with mode: 0644]
scilab/CHANGES_5.5.X
scilab/modules/xml/help/en_US/xmlRead.xml
scilab/modules/xml/sci_gateway/cpp/sci_xmlRead.cpp
scilab/modules/xml/src/cpp/XMLDocument.cpp
scilab/modules/xml/src/cpp/XMLDocument.hxx
scilab/modules/xml/tests/nonreg_tests/bug_10645.dia.ref [new file with mode: 0644]
scilab/modules/xml/tests/nonreg_tests/bug_10645.tst [new file with mode: 0644]
scilab/modules/xml/tests/nonreg_tests/bug_10645.xml [new file with mode: 0644]

index af1824f..c023d28 100644 (file)
--- a/SEP/INDEX
+++ b/SEP/INDEX
@@ -114,3 +114,4 @@ SEP #115: New function bode_asymp.
 SEP #116: conjgrad function, to regroup the Conjugate Gradient solvers. pcg obsolete as it is.
 SEP #117: New function ilib_build_jar
 SEP #118: New function ifftshift
+SEP #119: Management of encoding in xmlRead
diff --git a/SEP/SEP_119_xml_encoding.odt b/SEP/SEP_119_xml_encoding.odt
new file mode 100644 (file)
index 0000000..8d06e92
Binary files /dev/null and b/SEP/SEP_119_xml_encoding.odt differ
index cb8e885..934f1d0 100644 (file)
@@ -135,6 +135,8 @@ Scilab Bug Fixes
 
 * Bug #10273 fixed - spchol help page now displays an example showing how to use its output arguments.
 
+* Bug #10645 fixed - File encoding could not be given as argument in xmlRead.
+
 * Bug #10936 fixed - Scilab hung with invalid strf in plot2d.
 
 * Bug #10998 fixed - matrix*hypermatrix and hypermatrix*matrix operations failed.
index 48472ff..334f4c9 100644 (file)
@@ -18,7 +18,7 @@
     <refsynopsisdiv>
         <title>Calling Sequence</title>
         <synopsis>
-            doc = xmlRead(path [, validateDTD])
+            doc = xmlRead(path [, encoding] [, validateDTD])
         </synopsis>
     </refsynopsisdiv>
     <refsection>
                 </listitem>
             </varlistentry>
             <varlistentry>
+                <term>encoding</term>
+                <listitem>
+                    <para>a string, the file encoding.</para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
                 <term>validateDTD</term>
                 <listitem>
                     <para>a boolean to indicate if the document must be validated.</para>
@@ -48,6 +54,7 @@
         <title>Description</title>
         <para>Read and parse a XML file. The returned document allows to access to the DOM tree which is kept in memory.</para>
         <para>If validateDTD is set to true, the document will be validated or not during the parsing operation.</para>
+       <para>The encoding argument is used to precise the file encoding.</para>
         <para>
             It is important to notice that the tree must be freed (to avoid memory leaks) with the function <link linkend="xmlDelete">xmlDelete</link>.
         </para>
                 <revnumber>5.4.0</revnumber>
                 <revremark>XML module introduced.</revremark>
             </revision>
+            <revision>
+                <revnumber>5.5.0</revnumber>
+                <revremark>Add new argument to select file encoding.</revremark>
+            </revision>
         </revhistory>
     </refsection>
 </refentry>
index 475334c..04e0a86 100644 (file)
@@ -35,13 +35,14 @@ int sci_xmlRead(char *fname, unsigned long fname_len)
     SciErr err;
     int *addr = 0;
     char *path = 0;
+    char *encoding = 0;
 
     std::string error;
     bool validate = false;
     int validateParam;
 
     CheckLhs(1, 1);
-    CheckRhs(1, 2);
+    CheckRhs(1, 3);
 
     err = getVarAddressFromPosition(pvApiCtx, 1, &addr);
     if (err.iErr)
@@ -63,8 +64,10 @@ int sci_xmlRead(char *fname, unsigned long fname_len)
         return 0;
     }
 
-    if (Rhs == 2)
+    if (Rhs >= 2)
     {
+        int validatePos = 2;
+
         err = getVarAddressFromPosition(pvApiCtx, 2, &addr);
         if (err.iErr)
         {
@@ -74,19 +77,68 @@ int sci_xmlRead(char *fname, unsigned long fname_len)
             return 0;
         }
 
-        if (!isBooleanType(pvApiCtx, addr) || !checkVarDimension(pvApiCtx, addr, 1, 1))
+        if (!checkVarDimension(pvApiCtx, addr, 1, 1))
         {
             freeAllocatedSingleString(path);
-            Scierror(999, gettext("%s: Wrong type for input argument #%d: A boolean expected.\n"), fname, 2);
+            Scierror(999, gettext("%s: Wrong dimensions for input argument #%d: A single boolean or string expected.\n"), fname, 2);
             return 0;
         }
 
-        getScalarBoolean(pvApiCtx, addr, &validateParam);
-        validate = validateParam != 0;
+        if (isStringType(pvApiCtx, addr))
+        {
+            if (getAllocatedSingleString(pvApiCtx, addr, &encoding) != 0)
+            {
+                freeAllocatedSingleString(path);
+                Scierror(999, _("%s: No more memory.\n"), fname);
+                return 0;
+            }
+
+            if (Rhs == 3)
+            {
+                err = getVarAddressFromPosition(pvApiCtx, 3, &addr);
+                if (err.iErr)
+                {
+                    freeAllocatedSingleString(path);
+                    freeAllocatedSingleString(encoding);
+                    printError(&err, 0);
+                    Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 3);
+                    return 0;
+                }
+                validatePos = 3;
+            }
+        }
+
+        if (encoding == 0 && Rhs == 3)
+        {
+            freeAllocatedSingleString(path);
+            Scierror(999, _("%s: Invalid number of input arguments.\n"), fname);
+            return 0;
+        }
+
+        if (encoding == 0 || Rhs == 3)
+        {
+            if (!isBooleanType(pvApiCtx, addr) || !checkVarDimension(pvApiCtx, addr, 1, 1))
+            {
+                freeAllocatedSingleString(path);
+                if (encoding)
+                {
+                    freeAllocatedSingleString(encoding);
+                }
+                Scierror(999, gettext("%s: Wrong type for input argument #%d: A boolean expected.\n"), fname, validatePos);
+                return 0;
+            }
+
+            getScalarBoolean(pvApiCtx, addr, &validateParam);
+            validate = validateParam != 0;
+        }
     }
 
-    doc = new org_modules_xml::XMLDocument((const char *)path, validate, &error);
+    doc = new org_modules_xml::XMLDocument((const char *)path, validate, &error, encoding);
     freeAllocatedSingleString(path);
+    if (encoding)
+    {
+        freeAllocatedSingleString(encoding);
+    }
 
     if (!error.empty())
     {
index 6e76b2f..78dd360 100644 (file)
@@ -34,12 +34,12 @@ std::string * XMLDocument::errorBuffer = 0;
 std::string * XMLDocument::errorXPathBuffer = 0;
 std::list < XMLDocument * >&XMLDocument::openDocs = *new std::list < XMLDocument * >();
 
-XMLDocument::XMLDocument(const char *path, bool validate, std::string * error): XMLObject()
+XMLDocument::XMLDocument(const char *path, bool validate, std::string * error, const char * encoding): XMLObject()
 {
     char *expandedPath = expandPathVariable(const_cast<char *>(path));
     if (expandedPath)
     {
-        document = readDocument(const_cast<const char *>(expandedPath), validate, error);
+        document = readDocument(const_cast<const char *>(expandedPath), encoding, validate, error);
         FREE(expandedPath);
         if (document)
         {
@@ -57,9 +57,9 @@ XMLDocument::XMLDocument(const char *path, bool validate, std::string * error):
     scilabType = XMLDOCUMENT;
 }
 
-XMLDocument::XMLDocument(const std::string & xmlCode, bool validate, std::string * error): XMLObject()
+XMLDocument::XMLDocument(const std::string & xmlCode, bool validate, std::string * error, const char * encoding): XMLObject()
 {
-    document = readDocument(xmlCode, validate, error);
+    document = readDocument(xmlCode, encoding, validate, error);
     if (document)
     {
         openDocs.push_back(this);
@@ -296,7 +296,7 @@ void XMLDocument::closeAllDocuments()
     delete[]arr;
 }
 
-xmlDoc *XMLDocument::readDocument(const char *filename, bool validate, std::string * error)
+xmlDoc *XMLDocument::readDocument(const char *filename, const char * encoding, bool validate, std::string * error)
 {
     xmlParserCtxt *ctxt = initContext(error, validate);
     xmlDoc *doc = 0;
@@ -304,7 +304,7 @@ xmlDoc *XMLDocument::readDocument(const char *filename, bool validate, std::stri
 
     if (validate)
     {
-        options = options | XML_PARSE_DTDVALID;
+        options |= XML_PARSE_DTDVALID;
     }
 
     if (!ctxt)
@@ -313,7 +313,7 @@ xmlDoc *XMLDocument::readDocument(const char *filename, bool validate, std::stri
         return 0;
     }
 
-    doc = xmlCtxtReadFile(ctxt, filename, 0, options);
+    doc = xmlCtxtReadFile(ctxt, filename, encoding, options);
     if (!doc || !ctxt->valid)
     {
         *error = *errorBuffer;
@@ -325,7 +325,7 @@ xmlDoc *XMLDocument::readDocument(const char *filename, bool validate, std::stri
     return doc;
 }
 
-xmlDoc *XMLDocument::readDocument(const std::string & xmlCode, bool validate, std::string * error)
+xmlDoc *XMLDocument::readDocument(const std::string & xmlCode, const char * encoding, bool validate, std::string * error)
 {
     xmlParserCtxt *ctxt = initContext(error, validate);
     xmlDoc *doc = 0;
@@ -333,7 +333,7 @@ xmlDoc *XMLDocument::readDocument(const std::string & xmlCode, bool validate, st
 
     if (validate)
     {
-        options = options | XML_PARSE_DTDVALID;
+        options |= XML_PARSE_DTDVALID;
     }
 
     if (!ctxt)
index 69827e2..d473b38 100644 (file)
@@ -67,7 +67,7 @@ public:
      * @param validate a boolean to indicate if the document must be validated in using a DTD
      * @param error a pointer to a string which will receive the error message
      */
-    XMLDocument(const char *path, bool validate, std::string * error);
+    XMLDocument(const char *path, bool validate, std::string * error, const char * encoding = 0);
 
     /**
      * Builds a document with a given code
@@ -75,7 +75,7 @@ public:
      * @param validate a boolean to indicate if the document must be validated in using a DTD
      * @param error a pointer to a string which will receive the error message
      */
-    XMLDocument(const std::string & xmlCode, bool validate, std::string * error);
+    XMLDocument(const std::string & xmlCode, bool validate, std::string * error, const char * encoding = 0);
 
     /**
      * Builds a simple document
@@ -162,11 +162,12 @@ private:
     /**
      * Reads and parses a document given in a file.
      * @param filename the file name
+     * @param encoding the file encoding
      * @param validate a boolean to indicate if the document must be validated in using a DTD
      * @param error a string where to write the parsing errors
      * @return a pointer on a xmlDoc
      */
-    static xmlDoc *readDocument(const char *filename, bool validate, std::string * error);
+    static xmlDoc *readDocument(const char *filename, const char * encoding, bool validate, std::string * error);
 
     /**
      * Read and parse a document given in a string.
@@ -175,7 +176,7 @@ private:
      * @param error a string where to write the parsing errors
      * @return a pointer on a xmlDoc
      */
-    static xmlDoc *readDocument(const std::string & xmlCode, bool validate, std::string * error);
+    static xmlDoc *readDocument(const std::string & xmlCode, const char * encoding, bool validate, std::string * error);
 
     /**
      * Initializes the context
diff --git a/scilab/modules/xml/tests/nonreg_tests/bug_10645.dia.ref b/scilab/modules/xml/tests/nonreg_tests/bug_10645.dia.ref
new file mode 100644 (file)
index 0000000..08f4feb
--- /dev/null
@@ -0,0 +1,21 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2013 - Scilab Enterprises - Calixte DENIZET
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+//
+// <-- Non-regression test for bug 10645 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/10645
+//
+// <-- Short Description -->
+// File encoding could not be given as argument in xmlRead.
+//
+assert_checkerror("doc=xmlRead(""SCI/modules/xml/tests/nonreg_tests/bug_10645.xml"")",[],999);
+doc = xmlRead("SCI/modules/xml/tests/nonreg_tests/bug_10645.xml","iso-8859-1");
+assert_checkequal(doc.root.content, "Clément");
+xmlDelete(doc);
diff --git a/scilab/modules/xml/tests/nonreg_tests/bug_10645.tst b/scilab/modules/xml/tests/nonreg_tests/bug_10645.tst
new file mode 100644 (file)
index 0000000..805b6c5
--- /dev/null
@@ -0,0 +1,22 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2013 - Scilab Enterprises - Calixte DENIZET
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+//
+// <-- Non-regression test for bug 10645 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/10645
+//
+// <-- Short Description -->
+// File encoding could not be given as argument in xmlRead.
+//
+
+assert_checkerror("doc=xmlRead(""SCI/modules/xml/tests/nonreg_tests/bug_10645.xml"")",[],999);
+doc = xmlRead("SCI/modules/xml/tests/nonreg_tests/bug_10645.xml","iso-8859-1");
+assert_checkequal(doc.root.content, "Clément");
+xmlDelete(doc);
\ No newline at end of file
diff --git a/scilab/modules/xml/tests/nonreg_tests/bug_10645.xml b/scilab/modules/xml/tests/nonreg_tests/bug_10645.xml
new file mode 100644 (file)
index 0000000..e3fb26e
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root>
+Clément
+</root>
\ No newline at end of file