Fix CIDs #1371081 & #1371077
[scilab.git] / scilab / modules / spreadsheet / src / c / csvRead.c
index 451d035..7c2d61d 100644 (file)
@@ -2,17 +2,20 @@
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2010-2011 - DIGITEO - Allan CORNET
  *
- * This file must be used under the terms of the CeCILL.
- * This source file is licensed as described in the file COPYING, which
- * you should have received as part of this distribution.  The terms
- * are also available at
- * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ * Copyright (C) 2012 - 2016 - Scilab Enterprises
+ *
+ * This file is hereby licensed under the terms of the GNU GPL v2.0,
+ * pursuant to article 5.3.4 of the CeCILL v.2.1.
+ * This file was originally licensed under the terms of the CeCILL v2.1,
+ * and continues to be available under such terms.
+ * For more information, see the COPYING file which you should have received
+ * along with this program.
  *
  */
 #include <string.h>
 #include <stdio.h>
 #include "csvRead.h"
-#include "MALLOC.h"
+#include "sci_malloc.h"
 #include "freeArrayOfString.h"
 #include "mopen.h"
 #include "mgetl.h"
 #include "expandPathVariable.h"
 #include "FileExist.h"
 #include "mclose.h"
-#include "sci_warning.h"
+#include "configvariable_interface.h"
 #include "pcre_private.h"
 #include "sciprint.h"
 #include "splitLine.h"
-#include "csv_strsubst.h"
-#include "os_strdup.h"
+#include "os_string.h"
 #include "csvDefault.h"
+#include "strsubst.h"
+#include "Sciwarning.h"
 // =============================================================================
 #if _MSC_VER
 #define READ_ONLY_TEXT_MODE "rt"
@@ -47,7 +51,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)
 {
     wchar_t *expandedFilename = NULL;
     wchar_t *wideFilename = NULL;
@@ -56,9 +60,9 @@ csvResult* csvRead(const char *filename, const char *separator, const char *deci
     int f_swap = 0;
     double res = 0.0;
     int errMOPEN = MOPEN_INVALID_STATUS;
-    int errMGETL = MGETL_ERROR;
-    char **lines = NULL;
-    int nblines = 0;
+    wchar_t **pwstLines = NULL;
+    char **pstLines = NULL;
+    int nbLines = 0;
     char **replacedInLines = NULL;
     char **pComments = NULL;
     int nbComments = 0;
@@ -84,21 +88,18 @@ csvResult* csvRead(const char *filename, const char *separator, const char *deci
             result->pstrComments = NULL;
             result->nbComments = 0;
         }
-        if (expandedFilename)
-        {
-            FREE(expandedFilename);
-            expandedFilename = NULL;
-        }
+
+        FREE(expandedFilename);
         return result;
     }
 
     errMOPEN = mopen(expandedFilename, L"rt", f_swap, &fd); // rt = read only
-    printf("error mopen : %d\n", errMOPEN);
     if (expandedFilename)
     {
         FREE(expandedFilename);
         expandedFilename = NULL;
     }
+
     if (errMOPEN != MOPEN_NO_ERROR)
     {
         result = (csvResult*)(MALLOC(sizeof(csvResult)));
@@ -115,27 +116,29 @@ csvResult* csvRead(const char *filename, const char *separator, const char *deci
         return result;
     }
 
-    lines = mgetl(fd, -1, &nblines, &errMGETL);
-
+    if (header != 0)
     {
-        int i = 0;
-        for (i = 0 ; i < nblines ; i++)
-        {
-            printf("mgetl %s\n", lines[i]);
-        }
-
+        wchar_t **pwstHeaderLines = NULL;
+        mgetl(fd, header, &pwstHeaderLines);
+        FREE(pwstHeaderLines);
     }
 
+    nbLines = mgetl(fd, -1, &pwstLines);
     mclose(fd);
 
-    if (errMGETL != MGETL_NO_ERROR)
+    if (nbLines >= 0)
     {
-        if (lines)
+        int i = 0;
+        pstLines = (char**)MALLOC(sizeof(char*) * nbLines);
+        for (i = 0 ; i < nbLines ; i++)
         {
-            freeArrayOfString(lines, nblines);
-            lines = NULL;
+            pstLines[i] = wide_string_to_UTF8(pwstLines[i]);
         }
-
+        freeArrayOfWideString(pwstLines, nbLines);
+        pwstLines = NULL;
+    }
+    else
+    {
         result = (csvResult*)(MALLOC(sizeof(csvResult)));
         if (result)
         {
@@ -153,7 +156,7 @@ csvResult* csvRead(const char *filename, const char *separator, const char *deci
     {
         int iErr = 0;
 
-        pComments = extractComments((const char**)lines, nblines, (const char*)regexpcomments, &nbComments, &iErr);
+        pComments = extractComments((const char**)pstLines, nbLines, regexpcomments, &nbComments, &iErr);
 
         if ((iErr == CAN_NOT_COMPILE_PATTERN) || (iErr == DELIMITER_NOT_ALPHANUMERIC))
         {
@@ -171,6 +174,7 @@ csvResult* csvRead(const char *filename, const char *separator, const char *deci
                 result->pstrComments = NULL;
                 result->nbComments = 0;
             }
+            freeArrayOfString(pstLines, nbLines);
             return result;
         }
 
@@ -180,12 +184,12 @@ csvResult* csvRead(const char *filename, const char *separator, const char *deci
             int nbCleanedLines = 0;
             int i = 0;
 
-            pCleanedLines = removeComments((const char**)lines, nblines, (const char*)regexpcomments, &nbCleanedLines, &iErr);
+            pCleanedLines = removeComments((const char**)pstLines, nbLines, (const char*)regexpcomments, &nbCleanedLines, &iErr);
             if (pCleanedLines)
             {
-                FREE(lines);
-                lines = pCleanedLines;
-                nblines = nbCleanedLines;
+                FREE(pstLines);
+                pstLines = pCleanedLines;
+                nbLines = nbCleanedLines;
             }
 
         }
@@ -193,34 +197,27 @@ csvResult* csvRead(const char *filename, const char *separator, const char *deci
 
     if (toreplace && (sizetoreplace > 0))
     {
-        replacedInLines = replaceStrings((const char**)lines, nblines, toreplace, sizetoreplace);
+        replacedInLines = replaceStrings((const char**)pstLines, nbLines, toreplace, sizetoreplace);
         if (replacedInLines)
         {
-            freeArrayOfString(lines, nblines);
-            lines = replacedInLines;
+            freeArrayOfString(pstLines, nbLines);
+            pstLines = replacedInLines;
         }
     }
 
-    {
-        int i = 0;
-        for (i = 0 ; i < nblines ; i++)
-        {
-            printf("csvtextscan %s\n", lines[i]);
-        }
-
-    }
-    result = csvTextScan((const char**)lines, nblines, (const char*)separator, (const char*)decimal);
-    if (lines)
-    {
-        freeArrayOfString(lines, nblines);
-        lines = NULL;
-    }
+    result = csvTextScan((const char**)pstLines, nbLines, (const char*)separator, (const char*)decimal);
+    freeArrayOfString(pstLines, nbLines);
+    freeArrayOfWideString(pwstLines, nbLines);
 
     if (result)
     {
         result->pstrComments = pComments;
         result->nbComments = nbComments;
     }
+    else
+    {
+        freeArrayOfString(pComments, nbComments);
+    }
 
     return result;
 }
@@ -268,14 +265,6 @@ csvResult* csvTextScan(const char **lines, int numberOfLines, const char *separa
         }
     }
 
-    {
-        int i = 0;
-        for (i = 0 ; i < nbLines ; i++)
-        {
-            printf("%s\n", cleanedLines[i]);
-        }
-
-    }
     nbColumns = getNumbersOfColumnsInLines((const char **)cleanedLines, nbLines, separator);
     if (nbColumns == 0)
     {
@@ -298,7 +287,6 @@ csvResult* csvTextScan(const char **lines, int numberOfLines, const char *separa
     }
 
     cellsStrings = getStringsFromLines((const char **)cleanedLines, nbLines, separator, decimal, nbColumns, nbRows);
-    printf("nbRows %d, nbColumns %d \n", nbRows, nbColumns);
     if (cleanedLines)
     {
         freeArrayOfString(cleanedLines, nbLines);
@@ -382,11 +370,7 @@ static int getNumbersOfColumnsInLines(const char **lines, int sizelines,
             {
                 if (previousNbColumns != NbColumns)
                 {
-                    if (getWarningMode())
-                    {
-                        sciprint(_("%s: Inconsistency found in the columns. At line %d, found %d columns while the previous had %d.\n"), "csvRead", i + 1, NbColumns, previousNbColumns);
-                    }
-
+                    Sciwarning(_("%s: Inconsistency found in the columns. At line %d, found %d columns while the previous had %d.\n"), _("Warning"), i + 1, NbColumns, previousNbColumns);
                     return 0;
                 }
             }
@@ -401,7 +385,7 @@ static int getNumbersOfColumnsInLine(const char *line, const char *separator)
     {
         int i = 0;
         int nbTokens = 0;
-        char **splittedStr = splitLineCSV(line, separator, &nbTokens, 0);
+        char **splittedStr = splitLineCSV(line, separator, &nbTokens);
         if (splittedStr)
         {
             freeArrayOfString(splittedStr, nbTokens);
@@ -447,7 +431,7 @@ static char **getStringsFromLines(const char **lines, int sizelines,
         for (i = 0; i < sizelines; i++)
         {
             int nbTokens = 0;
-            char **lineStrings = splitLineCSV(lines[i], separator, &nbTokens, 0);
+            char **lineStrings = splitLineCSV(lines[i], separator, &nbTokens);
             int j = 0;
 
             if (lineStrings == NULL)
@@ -475,7 +459,7 @@ static char **getStringsFromLines(const char **lines, int sizelines,
                 {
                     /* Proceed to the remplacement of the provided decimal to the default on
                      * usually, it converts "," => "." */
-                    results[i + n * j] = csv_strsubst(lineStrings[j], decimal, getCsvDefaultDecimal());
+                    results[i + n * j] = strsub(lineStrings[j], decimal, getCsvDefaultDecimal());
                 }
 
                 if (lineStrings[j])
@@ -484,6 +468,7 @@ static char **getStringsFromLines(const char **lines, int sizelines,
                     lineStrings[j] = NULL;
                 }
             }
+            FREE(lineStrings);
         }
     }
     return results;
@@ -588,16 +573,17 @@ static char *stripCharacters(const char *line)
     char *returnedLine = NULL;
     if (line)
     {
-        char *tmpLineWithoutTab = csv_strsubst((char*)line, "\t", "");
+        char *tmpLineWithoutTab = strsub((char*)line, "\t", "");
         if (tmpLineWithoutTab)
         {
-            char *tmpLineWithoutLF = csv_strsubst(tmpLineWithoutTab, "\r", "");
+            char *tmpLineWithoutLF = strsub(tmpLineWithoutTab, "\r", "");
             if (tmpLineWithoutLF)
             {
-                char *tmpLineWithoutCR = csv_strsubst(tmpLineWithoutTab, "\n", "");
+                char *tmpLineWithoutCR = strsub(tmpLineWithoutTab, "\n", "");
                 if (tmpLineWithoutCR)
                 {
-                    returnedLine = csv_strsubst(tmpLineWithoutCR, " ", "");
+                    returnedLine = strsub(tmpLineWithoutCR, " ", "");
+                    FREE(tmpLineWithoutCR);
                 }
                 else
                 {
@@ -643,11 +629,11 @@ static char **replaceStrings(const char **lines, int nbLines, const char **torep
                 replacedStrings[j] = os_strdup(lines[j]);
             }
             // Make replacements within the target replacedStrings.
-            for (i = 0; i < nr; i = i++)
+            for (i = 0; i < nr; i++)
             {
                 for (j = 0; j < nbLines; j++)
                 {
-                    replacedStrings[j] = csv_strsubst(replacedStrings[j], toreplace[i], toreplace[nr + i]);
+                    replacedStrings[j] = strsub(replacedStrings[j], toreplace[i], toreplace[nr + i]);
                 }
             }
         }
@@ -669,10 +655,17 @@ static char **extractComments(const char **lines, int nbLines,
 
         if ( (answer == CAN_NOT_COMPILE_PATTERN) || (answer == DELIMITER_NOT_ALPHANUMERIC))
         {
+            if (pComments)
+            {
+                freeArrayOfString(pComments, *nbcomments);
+            }
+
             *nbcomments = 0;
+
             *iErr = answer;
             return NULL;
         }
+
         if ( answer == PCRE_FINISHED_OK )
         {
             (*nbcomments)++;