* Bug #13144 fixed - spreadsheet: header comments for csvRead 07/13407/2
Paul Bignier [Tue, 7 Jan 2014 10:25:21 +0000 (11:25 +0100)]
csvRead could not ignore header comments.
It is now possible thanks to a eighth input argument 'header'.

This commit also fixes the case when csvRead has two output arguments but no 'regexpcomments' argument,
because the bug report's test case also had that issue.

Change-Id: Ib37ad6f77006fab746a09bb2aa24d6acd664034d

SEP/INDEX
SEP/SEP_124_csvRead_header.odt [new file with mode: 0644]
scilab/CHANGES_5.5.X
scilab/modules/spreadsheet/help/en_US/csvRead.xml
scilab/modules/spreadsheet/help/en_US/csvWrite.xml
scilab/modules/spreadsheet/sci_gateway/c/sci_csvRead.c
scilab/modules/spreadsheet/src/c/csvRead.c
scilab/modules/spreadsheet/src/c/csvRead.h
scilab/modules/spreadsheet/tests/nonreg_tests/bug_13144.dia.ref [new file with mode: 0644]
scilab/modules/spreadsheet/tests/nonreg_tests/bug_13144.tst [new file with mode: 0644]

index 13c6d86..0765191 100644 (file)
--- a/SEP/INDEX
+++ b/SEP/INDEX
@@ -119,4 +119,5 @@ SEP #120: New function tbx_build_pal_loader
 SEP #121: New rect property for matplot handle
 SEP #122: Customized mark draw
 SEP #123: Grid improvements
+SEP #124: New input argument for csvRead(), to ignore header comments.
 
diff --git a/SEP/SEP_124_csvRead_header.odt b/SEP/SEP_124_csvRead_header.odt
new file mode 100644 (file)
index 0000000..da14b4f
Binary files /dev/null and b/SEP/SEP_124_csvRead_header.odt differ
index 911644a..36c3e99 100644 (file)
@@ -405,6 +405,8 @@ Scilab Bug Fixes
 
 * Bug #13140 fixed - Various typos fixed.
 
+* Bug #13144 fixed - csvRead can now ignore header comments thanks to a new input argument.
+
 * Bug #13146 fixed - profile failed when a comment was on the same line as a function declaration.
 
 * Bug #13152 fixed - Typo fixed in syslin french help page.
index 2660064..59db070 100644 (file)
           xmlns:ns3="http://www.w3.org/1999/xhtml"
           xmlns:mml="http://www.w3.org/1998/Math/MathML"
           xmlns:db="http://docbook.org/ns/docbook">
-    
     <refnamediv>
         <refname>csvRead</refname>
-        
         <refpurpose>Read comma-separated value file</refpurpose>
     </refnamediv>
-    
     <refsynopsisdiv>
         <title>Calling Sequence</title>
-        
         <synopsis>
             M = csvRead(filename)
             M = csvRead(filename, separator)
             M = csvRead(filename, separator, decimal)
             M = csvRead(filename, separator, decimal, conversion)
             M = csvRead(filename, separator, decimal, conversion, substitute)
-            M = csvRead(filename, separator, decimal, conversion, substitute, rexgepcomments, range)
-            [M, comments] = csvRead(filename, separator, decimal, conversion, substitute, rexgepcomments, range)
+            M = csvRead(filename, separator, decimal, conversion, substitute, regexpcomments, range)
+            M = csvRead(filename, separator, decimal, conversion, substitute, regexpcomments, range, header)
+            [M, comments] = csvRead(filename, separator, decimal, conversion, substitute, regexpcomments, range, header)
         </synopsis>
     </refsynopsisdiv>
-    
     <refsection>
-        <title>Parameters</title>
-        
+        <title>Arguments</title>
         <variablelist>
             <varlistentry>
                 <term>filename</term>
-                
                 <listitem>
                     <para>a 1-by-1 matrix of strings, the file path.</para>
                 </listitem>
             </varlistentry>
-            
             <varlistentry>
                 <term>separator</term>
-                
                 <listitem>
                     <para>a 1-by-1 matrix of strings, the field separator used.</para>
                 </listitem>
             </varlistentry>
-            
             <varlistentry>
                 <term>decimal</term>
-                
                 <listitem>
                     <para>a 1-by-1 matrix of strings, the decimal used.</para>
                     <para>
                     </para>
                 </listitem>
             </varlistentry>
-            
             <varlistentry>
                 <term>conversion</term>
-                
                 <listitem>
                     <para>a 1-by-1 matrix of strings, the type of the output
                         <literal>M</literal>. Available values are "string" or "double" (by default).
                     </para>
                 </listitem>
             </varlistentry>
-            
             <varlistentry>
                 <term>substitute</term>
-                
                 <listitem>
                     <para>a m-by-2 matrix of strings, a replacing map (default = [],
                         meaning no replacements). The first column
                     </para>
                 </listitem>
             </varlistentry>
-            
             <varlistentry>
-                <term>rexgepcomments</term>
-                
+                <term>regexpcomments</term>
                 <listitem>
                     <para>a string: a regexp to remove lines which match. (default:
                         [])
                     </para>
                 </listitem>
             </varlistentry>
-            
             <varlistentry>
                 <term>range</term>
-                
                 <listitem>
                     <para>a 1-by-4 matrix of floating point integers, the range of rows
                         and columns which must be read (default range=[], meaning that all
                     </para>
                 </listitem>
             </varlistentry>
-            
+            <varlistentry>
+                <term>header</term>
+                <listitem>
+                    <para>a 1-by-1 matrix of floating point integers, the number of lines to be ignored
+                        at the beginning of the file.
+                    </para>
+                </listitem>
+            </varlistentry>
             <varlistentry>
                 <term>M</term>
-                
                 <listitem>
                     <para>a m-by-n matrix of strings or double.</para>
                 </listitem>
             </varlistentry>
-            
             <varlistentry>
                 <term>comments</term>
-                
                 <listitem>
                     <para>a m-by-n matrix of strings matched by regexp.</para>
                 </listitem>
             </varlistentry>
         </variablelist>
     </refsection>
-    
     <refsection>
         <title>Description</title>
-        
         <para>Given an ascii file with comma separated values delimited fields,
             this function returns the corresponding Scilab matrix of strings or
             doubles.
         </para>
-        
         <para>For example, the .csv data file may have been created by a
             spreadsheet software using "Text and comma" format.
         </para>
-        
         <para>It might happen that the columns are separated by a non-comma
             separator. In this case, use csvRead(filename, separator) for another
             choice of separator.
         </para>
-        
         <para>The default value of the optional input arguments are defined by the
             <literal>csvDefault</literal> function.
         </para>
-        
         <para>Any optional input argument equal to the empty matrix
             <literal>[]</literal> is set to its default value.
         </para>
-        
         <para>When the input argument "conversion" is equal to "double", the
             non-numeric fields within the .csv (e.g. strings) are converted into
             NaN.
         </para>
-        
         <para>csvRead is able to handle both UTF-8 and ASCII text files.
         </para>
     </refsection>
-    
     <refsection>
         <title>Examples</title>
-        
         <para>The following script presents some basic uses of the
             <literal>csvRead</literal> function.
         </para>
-        
         <programlisting role="example"><![CDATA[// Create a file with some data separated with tabs.
 M = 1:50;
 filename = fullfile(TMPDIR, "data.csv");
@@ -208,11 +183,9 @@ isnan(M(2,1)) // Expected=%t
 isnan(M(4,1)) // Expected=%t
 
         ]]></programlisting>
-        
         <para>The following script presents more practical uses of the
             <literal>csvRead</literal> function.
         </para>
-        
         <programlisting role="example"><![CDATA[// Define a matrix of strings
 Astr = [
 "1" "8" "15" "22" "29" "36" "43" "50"
@@ -232,7 +205,7 @@ for i = 1 : size(Astr,"r")
         mfprintf(fd,"%s\n",strcat(Astr(i,:),sep));
 end
 mclose(fd);
-// To see the file : edit(filename)
+// To see the file: edit(filename)
 
 // Read this file
 Bstr = csvRead ( filename )
@@ -248,13 +221,11 @@ mclose(fd);
 
 //
 // Read the file and customize the separator
-csvRead ( filename , sep )   
+csvRead ( filename , sep )
         ]]></programlisting>
-        
         <para>The following script shows how to remove lines with regexp argument
             of the <literal>csvRead</literal> function.
         </para>
-        
         <programlisting role="example"><![CDATA[
 CSV = ["// tata"; ..
 "1,0,0,0,0"; ..
@@ -270,17 +241,14 @@ mputl(CSV, filename);
 [M, comments] = csvRead(filename, [], [], [], [], '/\/\//')
         ]]></programlisting>
     </refsection>
-    
     <refsection>
         <para>Empty field are managed by csvRead</para>
-        
         <programlisting role="example"><![CDATA[
 csvWrite(['1','','3';'','','6'], TMPDIR + "/example.csv")
 csvRead(TMPDIR + "/example.csv", [], [], "string")
 csvRead(TMPDIR + "/example.csv", [], [], "double")
         ]]></programlisting>
     </refsection>
-    
     <programlisting role="example"><![CDATA[
 // Define a matrix of strings
 Astr = [
@@ -301,7 +269,7 @@ for i = 1 : size(Astr,"r")
         mfprintf(fd,"%s\n",strcat(Astr(i,:),sep));
 end
 mclose(fd);
-// To see the file : edit(filename)
+// To see the file: edit(filename)
 
 // Read this file
 Bstr = csvRead ( filename )
@@ -318,14 +286,12 @@ mclose(fd);
 // Read the file and customize the separator
 csvRead ( filename , sep )
     ]]></programlisting>
-    
     <refsection>
         <para>In the following script, the file "filename" is read by blocks of
             5000 rows. The algorithm stops when the number of rows actually read from
             the file differ from 5000, i.e. when the end of the file has been
             reached.
         </para>
-        
         <programlisting role="example"><![CDATA[blocksize = 5000;
 C1 = 1;
 C2 = 3;
@@ -353,9 +319,7 @@ end
 iblock = iblock + 1;
 end
         ]]></programlisting>
-        
-        <para>This produces :</para>
-        
+        <para>This produces:</para>
         <programlisting role="no-scilab-exec"><![CDATA[Block #1, rows #1 to #5000
 Actual #rows=5000
 T=3.135 (s)
@@ -370,7 +334,6 @@ T=3.151 (s)
 T=210.1 (ms/cell)
 etc....
         ]]></programlisting>
-        
         Example with range
         <programlisting role="example"><![CDATA[
 CSV = ["1,0,0,0,0"; ..
@@ -386,12 +349,20 @@ mputl(CSV, filename);
 // Extract a subset of the csv file
 csvRead(filename, [], [], "double", [], [], [5 3 7 6])
     ]]></programlisting>
+        Example with header
+        <programlisting role="example"><![CDATA[
+comments = [
+"// Copyright (C) INRIA"
+"// This file must be used under the terms of the CeCILL."];
+filename = fullfile(TMPDIR , 'foo.csv');
+csvWrite(rand(2,3), filename, ascii(9), ",", [], comments);
+
+header = 2;
+[M, c] = csvRead(filename, ascii(9), ",", "double", [], [], [], header) // Ignore the two first lines (the header)
+    ]]></programlisting>
     </refsection>
-    
-    
     <refsection>
         <title>See Also</title>
-        
         <simplelist type="inline">
             <member>
                 <link linkend="csvWrite">csvWrite</link>
@@ -404,18 +375,20 @@ csvRead(filename, [], [], "double", [], [], [5 3 7 6])
             <revision>
                 <revnumber>5.4.0</revnumber>
                 <revremark>
-                    Function introduced. Based on the 'csv_readwrite' module. The only difference in the behavior compared to <link linkend="read_csv">read_csv</link> is that csvRead will try to convert value to double by default when read_csv will return value as string. 
+                    Function introduced. Based on the 'csv_readwrite' module. The only difference in the behavior compared to <link linkend="read_csv">read_csv</link> is that csvRead will try to convert value to double by default when read_csv will return value as string.
                 </revremark>
                 <revision>
                     <revnumber>5.4.1</revnumber>
                     <revremark>
                         If <literal>decimal</literal> is different of <literal>[]</literal> and <literal>conversion</literal> is set to <literal>string</literal>, the decimal conversion will be done.
                     </revremark>
+                    <revision>
+                        <revnumber>5.5</revnumber>
+                        <revremark>
+                            Addition of the "header" input argument, to ignore headers.
+                        </revremark>
+                    </revision>
                 </revision>
-                
-            </revision>
-        </revhistory>
-    </refsection>
-    
-</refentry>
-
+            </revhistory>
+        </refsection>
+    </refentry>
index b106806..a7da01f 100644 (file)
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
+    <?xml version="1.0" encoding="UTF-8"?>
+    <!--
  * Copyright (C) 2010-2011 - INRIA - Allan CORNET
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  -->
-<refentry version="5.0-subset Scilab" xml:id="csvWrite" xml:lang="en"
+    <refentry version="5.0-subset Scilab" xml:id="csvWrite" xml:lang="en"
           xmlns="http://docbook.org/ns/docbook"
           xmlns:xlink="http://www.w3.org/1999/xlink"
           xmlns:svg="http://www.w3.org/2000/svg"
           xmlns:ns3="http://www.w3.org/1999/xhtml"
           xmlns:mml="http://www.w3.org/1998/Math/MathML"
           xmlns:db="http://docbook.org/ns/docbook">
-    <refnamediv>
-        <refname>csvWrite</refname>
-        
-        <refpurpose>Write comma-separated value file</refpurpose>
-    </refnamediv>
-    
-    <refsynopsisdiv>
-        <title>Calling Sequence</title>
-        
-        <synopsis>
-            csvWrite(M, filename)
-            csvWrite(M, filename, separator)
-            csvWrite(M, filename, separator, decimal)
-            csvWrite(M, filename, separator, decimal, precision)
-            csvWrite(M, filename, separator, decimal, precision, comments)
-        </synopsis>
-    </refsynopsisdiv>
-    
-    <refsection>
-        <title>Parameters</title>
-        
-        <variablelist>
-            <varlistentry>
-                <term>filename</term>
-                
-                <listitem>
-                    <para>a 1-by-1 matrix of strings, the file path.</para>
-                </listitem>
-            </varlistentry>
-            
-            <varlistentry>
-                <term>M</term>
-                
-                <listitem>
-                    <para>a m-by-n matrix of strings or double (complex
-                        supported).
-                    </para>
-                </listitem>
-            </varlistentry>
-            
-            <varlistentry>
-                <term>separator</term>
-                
-                <listitem>
-                    <para>a 1-by-1 matrix of strings, the column separator mark.</para>
-                </listitem>
-            </varlistentry>
-            
-            <varlistentry>
-                <term>decimal</term>
-                
-                <listitem>
-                    <para>a 1-by-1 matrix of strings, the decimal mark. The available
-                        values are "." or ",".
-                    </para>
-                </listitem>
-            </varlistentry>
-            
-            <varlistentry>
-                <term>precision</term>
-                
-                <listitem>
-                    <para>a 1-by-1 matrix of strings, the C format.</para>
-                </listitem>
-            </varlistentry>
-            
-            <varlistentry>
-                <term>comments</term>
-                
-                <listitem>
-                    <para>a m-by-1 matrix of strings, the comments stored at the
-                        beginning of the file. This option may be used, for example, to put
-                        a licence header in a data file.
-                    </para>
-                </listitem>
-            </varlistentry>
-        </variablelist>
-    </refsection>
-    
-    <refsection>
-        <title>Description</title>
-        
-        <para>This function writes matrix M into filename as comma-separated
-            values.
-        </para>
-        
-        <para>The default value of the optional input arguments are defined by the
-            <literal>csvDefault</literal> function.
-        </para>
-        
-        <para>Any optional input argument equal to the empty matrix
-            <literal>[]</literal> is set to its default value.
-        </para>
-        
-        <para>
-            If the file <literal>filename</literal> already exists, it is
-            overwritten.
-        </para>
-        
-        <para>
-            If relevant (ie with 'special' characters), the file will be saved as UTF-8.
-        </para>
-    </refsection>
-    
-    <refsection>
-        <title>Examples</title>
-        
-        <para>In the following example, we combine the
-            <literal>csvWrite</literal> and <literal>csvRead</literal>
-            functions.
-        </para>
-        
-        <programlisting role="example"><![CDATA[// Save a matrix as csv file format
+        <refnamediv>
+            <refname>csvWrite</refname>
+            <refpurpose>Write comma-separated value file</refpurpose>
+        </refnamediv>
+        <refsynopsisdiv>
+            <title>Calling Sequence</title>
+            <synopsis>
+                csvWrite(M, filename)
+                csvWrite(M, filename, separator)
+                csvWrite(M, filename, separator, decimal)
+                csvWrite(M, filename, separator, decimal, precision)
+                csvWrite(M, filename, separator, decimal, precision, comments)
+            </synopsis>
+        </refsynopsisdiv>
+        <refsection>
+            <title>Arguments</title>
+            <variablelist>
+                <varlistentry>
+                    <term>filename</term>
+                    <listitem>
+                        <para>a 1-by-1 matrix of strings, the file path.</para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term>M</term>
+                    <listitem>
+                        <para>a m-by-n matrix of strings or double (complex
+                            supported).
+                        </para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term>separator</term>
+                    <listitem>
+                        <para>a 1-by-1 matrix of strings, the column separator mark.</para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term>decimal</term>
+                    <listitem>
+                        <para>a 1-by-1 matrix of strings, the decimal mark. The available
+                            values are "." or ",".
+                        </para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term>precision</term>
+                    <listitem>
+                        <para>a 1-by-1 matrix of strings, the C format.</para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term>comments</term>
+                    <listitem>
+                        <para>a m-by-1 matrix of strings, the comments stored at the
+                            beginning of the file. This option may be used, for example, to put
+                            a licence header in a data file.
+                        </para>
+                    </listitem>
+                </varlistentry>
+            </variablelist>
+        </refsection>
+        <refsection>
+            <title>Description</title>
+            <para>This function writes matrix M into filename as comma-separated
+                values.
+            </para>
+            <para>The default value of the optional input arguments are defined by the
+                <literal>csvDefault</literal> function.
+            </para>
+            <para>Any optional input argument equal to the empty matrix
+                <literal>[]</literal> is set to its default value.
+            </para>
+            <para>
+                If the file <literal>filename</literal> already exists, it is
+                overwritten.
+            </para>
+            <para>
+                If relevant (ie with 'special' characters), the file will be saved as UTF-8.
+            </para>
+        </refsection>
+        <refsection>
+            <title>Examples</title>
+            <para>In the following example, we combine the
+                <literal>csvWrite</literal> and <literal>csvRead</literal>
+                functions.
+            </para>
+            <programlisting role="example"><![CDATA[// Save a matrix as csv file format
 M = [1:10] * 0.1;
 filename = fullfile(TMPDIR, "data.csv");
 csvWrite(M, filename);
@@ -130,14 +105,12 @@ csvWrite(M, filename);
 // Read as text
 mgetl(filename)
 
-r = csvRead(filename);    
+r = csvRead(filename);
         ]]></programlisting>
-        
-        <para>In the following example, we use various options of the
-            <literal>csvWrite</literal> function.
-        </para>
-        
-        <programlisting role="example"><![CDATA[// Save a matrix as csv file format
+            <para>In the following example, we use various options of the
+                <literal>csvWrite</literal> function.
+            </para>
+            <programlisting role="example"><![CDATA[// Save a matrix as csv file format
 M = rand(2,3);
 filename = fullfile(TMPDIR, "data.csv");
 //
@@ -151,7 +124,7 @@ csvWrite(M, filename," ",",");
 mgetl(filename)
 //
 // Configure the precision.
-// Caution: this lower precision may generate 
+// Caution: this lower precision may generate
 // errors in a write-read cycle!
 csvWrite(M, filename,[],[],"%.8e");
 mgetl(filename)
@@ -162,14 +135,12 @@ comments = [
 "//  This file must be used under the terms of the CeCILL."
 ];
 csvWrite(M, filename,[],[],[],comments);
-mgetl(filename)   
+mgetl(filename)
         ]]></programlisting>
-        
-        <para>The following examples are more advanced uses of the
-            <literal>csvWrite</literal> function.
-        </para>
-        
-        <programlisting role="example"><![CDATA[A = [
+            <para>The following examples are more advanced uses of the
+                <literal>csvWrite</literal> function.
+            </para>
+            <programlisting role="example"><![CDATA[A = [
 1 0 200 %inf 0
 1 1.e-300 200 %inf 0
 9.99999999999990010e-001 9.99999999999999980e-201 200 3.15e300 102
@@ -180,28 +151,24 @@ mgetl(filename)
 // Write into a file
 filename=fullfile(TMPDIR,"foo.csv");
 csvWrite ( A , filename );
-edit(filename)   
+edit(filename)
         ]]></programlisting>
-    </refsection>
-    
-    <refsection>
-        <title>See Also</title>
-        
-        <simplelist type="inline">
-            <member>
-                <link linkend="csvRead">csvRead</link>
-            </member>
-        </simplelist>
-    </refsection>
-    <refsection>
-        <title>History</title>
-        <revhistory>
-            <revision>
-                <revnumber>5.4.0</revnumber>
-                <revremark>Function introduced. Based on the 'csv_readwrite' module.</revremark>
-            </revision>
-        </revhistory>
-    </refsection>
-    
-</refentry>
-
+        </refsection>
+        <refsection>
+            <title>See Also</title>
+            <simplelist type="inline">
+                <member>
+                    <link linkend="csvRead">csvRead</link>
+                </member>
+            </simplelist>
+        </refsection>
+        <refsection>
+            <title>History</title>
+            <revhistory>
+                <revision>
+                    <revnumber>5.4.0</revnumber>
+                    <revremark>Function introduced. Based on the 'csv_readwrite' module.</revremark>
+                </revision>
+            </revhistory>
+        </refsection>
+    </refentry>
index 86b5f05..ab29e3d 100644 (file)
@@ -49,11 +49,13 @@ int sci_csvRead(char *fname, unsigned long fname_len)
     char *conversion = NULL;
     int *iRange = NULL;
     int haveRange = 0;
+    int header = 0;
 
     char **toreplace = NULL;
     int nbElementsToReplace = 0;
 
     char *regexp = NULL;
+    int haveRegexp = 0;
 
     csvResult *result = NULL;
 
@@ -61,9 +63,19 @@ int sci_csvRead(char *fname, unsigned long fname_len)
 
     sciErr.iErr = 0;
 
-    CheckRhs(1, 7);
+    CheckRhs(1, 8);
     CheckLhs(1, 2);
 
+    if (Rhs == 8)
+    {
+        header = (int) csv_getArgumentAsScalarDouble(pvApiCtx, 8, fname, &iErr);
+        if (iErr)
+        {
+            freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, 0, &regexp);
+            return 0;
+        }
+    }
+
     if (Rhs == 7)
     {
         int m7 = 0, n7 = 0;
@@ -112,6 +124,10 @@ int sci_csvRead(char *fname, unsigned long fname_len)
                 FREE(regexp);
                 regexp = NULL;
             }
+            else
+            {
+                haveRegexp = 1;
+            }
         }
 
         if (iErr)
@@ -243,7 +259,7 @@ int sci_csvRead(char *fname, unsigned long fname_len)
         return 0;
     }
 
-    result = csvRead(filename, separator, decimal, (const char**)toreplace, nbElementsToReplace * 2, regexp);
+    result = csvRead(filename, separator, decimal, (const char**)toreplace, nbElementsToReplace * 2, regexp, header);
     freeVar(NULL, &separator, &decimal, NULL, NULL, &toreplace, nbElementsToReplace, &regexp);
 
     if (result)
@@ -405,7 +421,18 @@ int sci_csvRead(char *fname, unsigned long fname_len)
 
                     if (Lhs == 2)
                     {
-                        sciErr = createMatrixOfString(pvApiCtx, Rhs + 2, result->nbComments, 1, result->pstrComments);
+                        if (haveRegexp == 0)
+                        {
+                            char **emptyStringMatrix = NULL;
+                            emptyStringMatrix = (char**) malloc(sizeof(char*));
+                            emptyStringMatrix[0] = "";
+                            sciErr = createMatrixOfString(pvApiCtx, Rhs + 2, 1, 1, emptyStringMatrix);
+                            free(emptyStringMatrix);
+                        }
+                        else
+                        {
+                            sciErr = createMatrixOfString(pvApiCtx, Rhs + 2, result->nbComments, 1, result->pstrComments);
+                        }
                         if (sciErr.iErr)
                         {
                             Scierror(999, _("%s: Memory allocation error.\n"), fname);
index 6456d5c..fb967c1 100644 (file)
@@ -49,7 +49,7 @@ static char **extractComments(const char **lines, int nbLines, const char *regex
 static char **removeComments(const char **lines, int nbLines, const char *regexpcomments, int *nbNewLine, int *iErr);
 static char **removeAllBlankLines(const char **lines, int *sizelines);
 // =============================================================================
-csvResult* csvRead(const char *filename, const char *separator, const char *decimal, const char **toreplace, int sizetoreplace, const char *regexpcomments)
+csvResult* csvRead(const char *filename, const char *separator, const char *decimal, const char **toreplace, int sizetoreplace, const char *regexpcomments, int header)
 {
     char *expandedFilename = NULL;
     csvResult *result = NULL;
@@ -107,6 +107,10 @@ csvResult* csvRead(const char *filename, const char *separator, const char *deci
         return result;
     }
 
+    if (header != 0)
+    {
+        mgetl(fd, header, &nblines, &errMGETL);
+    }
     lines = mgetl(fd, -1, &nblines, &errMGETL);
 
     C2F(mclose)(&fd, &dErrClose);
index 7f77c37..0d3b703 100644 (file)
@@ -40,7 +40,7 @@ extern "C" {
 #endif
 
     csvResult* csvRead(const char *filename, const char *separator, const char *decimal,
-                       const char **toreplace, int sizetoreplace, const char *regexpcomments);
+                       const char **toreplace, int sizetoreplace, const char *regexpcomments, int header);
 
     csvResult* csvTextScan(const char **lines, int numberOfLines, const char *separator, const char *decimal);
 
diff --git a/scilab/modules/spreadsheet/tests/nonreg_tests/bug_13144.dia.ref b/scilab/modules/spreadsheet/tests/nonreg_tests/bug_13144.dia.ref
new file mode 100644 (file)
index 0000000..1a639f0
--- /dev/null
@@ -0,0 +1,42 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2014 - Scilab Enterprises - Paul Bignier
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+//
+// <-- Non-regression test for bug 13146 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=13146
+//
+// <-- Short Description -->
+// csvRead could not ignore header comments.
+// It is now possible thanks to a eighth input argument 'header'.
+comments = [
+"// Copyright (C) INRIA"
+"// This file must be used under the terms of the CeCILL." ];
+filename = fullfile(TMPDIR , "foo.csv");
+rand("seed", 0);
+csvWrite(rand(2,3), filename, ascii(9), ",", [], comments);
+header = 2;
+[M, c] = csvRead(filename, ascii(9), ",", "double", [], [], [], header); // Ignore the two first lines (the header)
+refM = [
+0.211324865464121 0.000221134629101 0.665381104219705
+0.756043854169548 0.330327091738582 0.628391788341105 ];
+refC = "";
+assert_checkalmostequal(M, refM);
+assert_checkequal(c, refC);
+// Case when csvRead has two output arguments but no 'regexpcomments' argument.
+// This test case comes from the help page:
+M = 1:50;
+filename = fullfile(TMPDIR, "data.csv");
+csvWrite(M, filename, ascii(9), ".");
+// Read csv file
+[M1, c] = csvRead(filename,ascii(9), [], "string");
+refM1 = string(1:50);
+refC = "";
+assert_checkequal(M1, refM1);
+assert_checkequal(c, refC);
diff --git a/scilab/modules/spreadsheet/tests/nonreg_tests/bug_13144.tst b/scilab/modules/spreadsheet/tests/nonreg_tests/bug_13144.tst
new file mode 100644 (file)
index 0000000..15defd7
--- /dev/null
@@ -0,0 +1,52 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2014 - Scilab Enterprises - Paul Bignier
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+//
+// <-- Non-regression test for bug 13146 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=13146
+//
+// <-- Short Description -->
+// csvRead could not ignore header comments.
+// It is now possible thanks to a eighth input argument 'header'.
+
+comments = [
+"// Copyright (C) INRIA"
+"// This file must be used under the terms of the CeCILL." ];
+filename = fullfile(TMPDIR , "foo.csv");
+rand("seed", 0);
+csvWrite(rand(2,3), filename, ascii(9), ",", [], comments);
+
+header = 2;
+[M, c] = csvRead(filename, ascii(9), ",", "double", [], [], [], header); // Ignore the two first lines (the header)
+
+refM = [
+0.211324865464121 0.000221134629101 0.665381104219705
+0.756043854169548 0.330327091738582 0.628391788341105 ];
+refC = "";
+
+assert_checkalmostequal(M, refM);
+assert_checkequal(c, refC);
+
+
+// Case when csvRead has two output arguments but no 'regexpcomments' argument.
+// This test case comes from the help page:
+M = 1:50;
+filename = fullfile(TMPDIR, "data.csv");
+csvWrite(M, filename, ascii(9), ".");
+
+// Read csv file
+[M1, c] = csvRead(filename,ascii(9), [], "string");
+
+refM1 = string(1:50);
+refC = "";
+
+assert_checkequal(M1, refM1);
+assert_checkequal(c, refC);
+