1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010-2011 - DIGITEO - Allan CORNET
4 *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13 *
14 */
15 /*--------------------------------------------------------------------------*/
16 #if defined(__linux__)
17 #define _GNU_SOURCE /* Bug 5673 fix: avoid dependency on GLIBC_2.7 */
18 #endif
19 /*--------------------------------------------------------------------------*/
20 #include <ctype.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include "sci_malloc.h"
25 #include "fscanfMat.h"
26 #include "charEncoding.h"
27 #include "BOOL.h"
28 #include "localization.h"
29 #include "Scierror.h"
30 #include "os_string.h"
31 #include "freeArrayOfString.h"
32 #include "mgetl.h"
33 #include "mopen.h"
34 #include "mclose.h"
35 #include "numericconstants_interface.h"
36 /*--------------------------------------------------------------------------*/
37 #define EOL "\n"
38 #define NanString "Nan"
39 #define InfString "Inf"
40 #define NegInfString "-Inf"
41 /*--------------------------------------------------------------------------*/
42 #if _MSC_VER
43 #define READ_ONLY_TEXT_MODE L"rt"
44 #else
45 #define READ_ONLY_TEXT_MODE L"r"
46 #endif
47 /*--------------------------------------------------------------------------*/
48 #define NB_FORMAT_SUPPORTED 7
49 static char *supportedFormat[NB_FORMAT_SUPPORTED] =
50 {"lf", "lg", "d", "i", "e", "f", "g"};
51 /*--------------------------------------------------------------------------*/
52 static BOOL itCanBeMatrixLine(char *line, char *format, char *separator);
53 static int getNbColumnsInLine(char *line, char *format, char *separator);
54 static int getNumbersColumnsInLines(char **lines, int sizelines,
55                                     int nbLinesText,
56                                     char *format, char *separator);
57 static int getNumbersLinesOfText(char **lines, int sizelines,
58                                  char *format, char *separator);
59 static char **splitLine(char *str, char *sep, int *toks, char meta);
60 static double *getDoubleValuesFromLines(char **lines, int sizelines,
61                                         int nbLinesText,
62                                         char *format, char *separator,
63                                         int m, int n);
64 static double *getDoubleValuesInLine(char *line,
65                                      char *format, char *separator,
66                                      int nbColumnsMax);
67 static BOOL checkFscanfMatFormat(char *format);
68 static char *getCleanedFormat(char *format);
69 static BOOL isOnlyBlankLine(const char *line);
70 static char **removeEmptyLinesAtTheEnd(char **lines, int *sizelines);
71 static BOOL isValidLineWithOnlyOneNumber(char *line);
72 static char ** removeTextLinesAtTheEnd(char **lines, int *sizelines, char *format, char *separator);
73 /*--------------------------------------------------------------------------*/
fscanfMat(char * filename,char * format,char * separator)74 fscanfMatResult *fscanfMat(char *filename, char *format, char *separator)
75 {
76     int fd = 0;
77     int f_swap = 0;
78     double res = 0.0;
79     int errMOPEN = MOPEN_INVALID_STATUS;
80     int i = 0;
81     int nbLinesTextDetected = 0;
82     int nbColumns = 0;
83     int nbRows = 0;
84 
85 
86     fscanfMatResult *resultFscanfMat = NULL;
87     wchar_t **pwstLines = NULL;
88     char **lines = NULL;
89     int nblines = 0;
90     double *dValues = NULL;
91     wchar_t* filenameW = NULL;
92 
93     if ((filename == NULL) || (format == NULL) || (separator == NULL))
94     {
95         return NULL;
96     }
97 
98     if (!checkFscanfMatFormat(format))
99     {
100         resultFscanfMat = (fscanfMatResult*)(MALLOC(sizeof(fscanfMatResult)));
101         if (resultFscanfMat)
102         {
103             resultFscanfMat->err = FSCANFMAT_FORMAT_ERROR;
104             resultFscanfMat->m = 0;
105             resultFscanfMat->n = 0;
106             resultFscanfMat->sizeText = 0;
107             resultFscanfMat->text = NULL;
108             resultFscanfMat->values = NULL;
109         }
110         return resultFscanfMat;
111     }
112 
113     filenameW = to_wide_string(filename);
114     errMOPEN = mopen(filenameW, READ_ONLY_TEXT_MODE, f_swap, &fd);
115     FREE(filenameW);
116     if (errMOPEN != MOPEN_NO_ERROR)
117     {
118         resultFscanfMat = (fscanfMatResult*)(MALLOC(sizeof(fscanfMatResult)));
119         if (resultFscanfMat)
120         {
121             resultFscanfMat->err = FSCANFMAT_MOPEN_ERROR;
122             resultFscanfMat->m = 0;
123             resultFscanfMat->n = 0;
124             resultFscanfMat->sizeText = 0;
125             resultFscanfMat->text = NULL;
126             resultFscanfMat->values = NULL;
127         }
128         return resultFscanfMat;
129     }
130 
131     nblines = mgetl(fd, -1, &pwstLines);
132     mclose(fd);
133 
134     if (nblines < 0)
135     {
136         resultFscanfMat = (fscanfMatResult*)(MALLOC(sizeof(fscanfMatResult)));
137         if (resultFscanfMat)
138         {
139             resultFscanfMat->err = FSCANFMAT_READLINES_ERROR;
140             resultFscanfMat->m = 0;
141             resultFscanfMat->n = 0;
142             resultFscanfMat->sizeText = 0;
143             resultFscanfMat->text = NULL;
144             resultFscanfMat->values = NULL;
145         }
146         freeArrayOfWideString(pwstLines, nblines);
147         return resultFscanfMat;
148     }
149 
150     lines = (char**)MALLOC(sizeof(char*) * nblines);
151     for (i = 0; i < nblines; i++)
152     {
153         lines[i] = wide_string_to_UTF8(pwstLines[i]);
154     }
155 
156     freeArrayOfWideString(pwstLines, nblines);
157 
158     lines = removeEmptyLinesAtTheEnd(lines, &nblines);
159     lines = removeTextLinesAtTheEnd(lines, &nblines, format, separator);
160 
161     nbLinesTextDetected = getNumbersLinesOfText(lines, nblines, format, separator);
162     nbRows = nblines - nbLinesTextDetected;
163     nbColumns = getNumbersColumnsInLines(lines, nblines, nbLinesTextDetected, format, separator);
164 
165     dValues = getDoubleValuesFromLines(lines, nblines,
166                                        nbLinesTextDetected,
167                                        format, separator,
168                                        nbColumns, nbRows);
169     if (dValues)
170     {
171         resultFscanfMat = (fscanfMatResult*)(MALLOC(sizeof(fscanfMatResult)));
172         if (resultFscanfMat)
173         {
174             if (nbLinesTextDetected > 0)
175             {
176                 if (lines)
177                 {
178                     for (i = nbLinesTextDetected; i < nblines; i++)
179                     {
180                         if (lines[i])
181                         {
182                             FREE(lines[i]);
183                             lines[i] = NULL;
184                         }
185                     }
186                 }
187                 resultFscanfMat->text = lines;
188             }
189             else
190             {
191                 freeArrayOfString(lines, nblines);
192                 resultFscanfMat->text = NULL;
193             }
194             resultFscanfMat->sizeText = nbLinesTextDetected;
195             resultFscanfMat->m = nbRows;
196             resultFscanfMat->n = nbColumns;
197             resultFscanfMat->values = dValues;
198             resultFscanfMat->err = FSCANFMAT_NO_ERROR;
199         }
200         else
201         {
202             FREE(dValues);
203             freeArrayOfString(lines, nblines);
204         }
205     }
206     else
207     {
208         freeArrayOfString(lines, nblines);
209         if (nbColumns == 0 || nbRows == 0)
210         {
211             resultFscanfMat = (fscanfMatResult*)(MALLOC(sizeof(fscanfMatResult)));
212             if (resultFscanfMat)
213             {
214                 resultFscanfMat->err = FSCANFMAT_READLINES_ERROR;
215                 resultFscanfMat->m = 0;
216                 resultFscanfMat->n = 0;
217                 resultFscanfMat->sizeText = 0;
218                 resultFscanfMat->text = NULL;
219                 resultFscanfMat->values = NULL;
220             }
221         }
222     }
223     return resultFscanfMat;
224 }
225 /*--------------------------------------------------------------------------*/
freeFscanfMatResult(fscanfMatResult * resultStruct)226 void freeFscanfMatResult(fscanfMatResult *resultStruct)
227 {
228     if (resultStruct)
229     {
230         if (resultStruct->text)
231         {
232             freeArrayOfString(resultStruct->text, resultStruct->sizeText);
233             resultStruct->text = NULL;
234         }
235 
236         if (resultStruct->values)
237         {
238             FREE(resultStruct->values);
239             resultStruct->values = NULL;
240         }
241 
242         resultStruct->err = FSCANFMAT_ERROR;
243         resultStruct->m = 0;
244         resultStruct->n = 0;
245         resultStruct->sizeText = 0;
246 
247         FREE(resultStruct);
248         resultStruct = NULL;
249     }
250 }
251 /*--------------------------------------------------------------------------*/
itCanBeMatrixLine(char * line,char * format,char * separator)252 static BOOL itCanBeMatrixLine(char *line, char *format, char *separator)
253 {
254     if (line)
255     {
256         int ierr = 0;
257         double dValue = 0.;
258 
259         ierr = sscanf(line, format, &dValue);
260 
261         if ((ierr == EOF) || (ierr == 0))
262         {
263             char *str = os_strdup(line);
264             if (str)
265             {
266                 ierr = sscanf(line, "%4s", str);
267 
268                 if ((ierr != 0) && (ierr != EOF))
269                 {
270                     if ((strncmp(str, NanString, (int)strlen(NanString)) == 0) ||
271                             (strncmp(str, NegInfString, (int)strlen(NegInfString)) == 0) ||
272                             (strncmp(str, InfString, (int)strlen(InfString)) == 0))
273                     {
274                         FREE(str);
275                         str = NULL;
276                         return TRUE;
277                     }
278                 }
279                 FREE(str);
280                 str = NULL;
281             }
282         }
283         else
284         {
285             return TRUE;
286         }
287     }
288     return FALSE;
289 }
290 /*--------------------------------------------------------------------------*/
getNumbersLinesOfText(char ** lines,int sizelines,char * format,char * separator)291 static int getNumbersLinesOfText(char **lines, int sizelines,
292                                  char *format, char *separator)
293 {
294     int numberOfLines = 0;
295     if (lines)
296     {
297         int i = 0;
298         for (i = 0; i < sizelines; i++)
299         {
300             if (!itCanBeMatrixLine(lines[i], format, separator))
301             {
302                 numberOfLines++;
303             }
304             else
305             {
306                 return numberOfLines;
307             }
308         }
309     }
310     return numberOfLines;
311 }
312 /*--------------------------------------------------------------------------*/
getNumbersColumnsInLines(char ** lines,int sizelines,int nbLinesText,char * format,char * separator)313 static int getNumbersColumnsInLines(char **lines, int sizelines,
314                                     int nbLinesText,
315                                     char *format, char *separator)
316 {
317     int previousNbColumns = 0;
318     int NbColumns = 0;
319     BOOL firstLine = TRUE;
320     if (lines)
321     {
322         int i = 0;
323         int firstLinesMatrix = nbLinesText;
324         for (i = firstLinesMatrix; i < sizelines; i++)
325         {
326             NbColumns = getNbColumnsInLine(lines[i], format, separator);
327             if (firstLine)
328             {
329                 previousNbColumns = NbColumns;
330                 firstLine = FALSE;
331             }
332             else
333             {
334                 if (previousNbColumns != NbColumns)
335                 {
336                     return 0;
337                 }
338             }
339         }
340     }
341     return NbColumns;
342 }
343 /*--------------------------------------------------------------------------*/
getNbColumnsInLine(char * line,char * format,char * separator)344 static int getNbColumnsInLine(char *line, char *format, char *separator)
345 {
346     int nbColums = 0;
347 
348     if (line && format && separator)
349     {
350         int i = 0;
351         int nbTokens = 0;
352         char **splittedStr = splitLine(line, separator, &nbTokens, 0);
353         if (nbTokens == 0)
354         {
355             freeArrayOfString(splittedStr, nbTokens);
356             return nbColums;
357         }
358         if (splittedStr)
359         {
360             for (i = 0; i < nbTokens; i++)
361             {
362                 double dValue = 0.;
363                 int ierr = sscanf(splittedStr[i], format, &dValue);
364                 if ((ierr != 0) && (ierr != EOF))
365                 {
366                     nbColums++;
367                 }
368                 else
369                 {
370                     char *str = os_strdup(splittedStr[i]);
371                     strcpy(str, "");
372 
373                     ierr = sscanf(splittedStr[i], "%4s", str);
374 
375                     if ((ierr != 0) && (ierr != EOF))
376                     {
377                         if ( (strcmp(str, NanString) == 0) ||
378                                 (strcmp(str, NegInfString) == 0) ||
379                                 (strcmp(str, InfString) == 0) )
380                         {
381                             nbColums++;
382                         }
383                         else
384                         {
385                             freeArrayOfString(splittedStr, nbTokens);
386                             /* bug 6889 */
387                             if (nbColums)
388                             {
389                                 nbColums--;
390                             }
391                             FREE(str);
392                             str = NULL;
393                             return nbColums;
394                         }
395                     }
396                     else
397                     {
398                         FREE(str);
399                         str = NULL;
400                         freeArrayOfString(splittedStr, nbTokens);
401                         return nbColums;
402                     }
403 
404                     FREE(str);
405                     str = NULL;
406                 }
407             }
408             freeArrayOfString(splittedStr, nbTokens);
409         }
410     }
411     return nbColums;
412 }
413 /*--------------------------------------------------------------------------*/
splitLine(char * str,char * sep,int * toks,char meta)414 static char **splitLine(char *str, char *sep, int *toks, char meta)
415 {
416     char **retstr = NULL;
417     char *idx = NULL;
418     char *end = NULL;
419     char *sep_end = NULL;
420     char *sep_idx = NULL;
421     int len = 0;
422     int curr_str = 0;
423     char last_char = 0xFF;
424 
425     *toks = 0;
426 
427     if ((sep == NULL) || (str == NULL))
428     {
429         return NULL;
430     }
431 
432     sep_end = sep + strlen(sep);
433     end = str + strlen(str);
434 
435     sep_idx = sep;
436     idx = str;
437 
438     if (strstr(str, sep) == NULL)
439     {
440         if ((int)strlen(str) > 0)
441         {
442             if (isValidLineWithOnlyOneNumber(str))
443             {
444                 retstr = (char **) MALLOC(sizeof(char *));
445                 if (retstr)
446                 {
447                     retstr[0] = os_strdup(str);
448                     *toks = 1;
449                 }
450             }
451         }
452         return retstr;
453     }
454 
455     retstr = (char **) MALLOC((sizeof(char *) * (int)strlen(str)));
456     if (retstr == NULL)
457     {
458         *toks = 0;
459         return NULL;
460     }
461 
462     while (idx < end)
463     {
464         while (sep_idx < sep_end)
465         {
466             if ((*idx == *sep_idx) && (last_char != meta))
467             {
468                 if (len > 0)
469                 {
470                     if (curr_str < (int)strlen(str))
471                     {
472                         retstr[curr_str] = (char *) MALLOC((sizeof(char) * len) + 1);
473 
474                         if (retstr[curr_str] == NULL)
475                         {
476                             freeArrayOfString(retstr, curr_str);
477                             *toks = 0;
478                             return NULL;
479                         }
480                         memcpy(retstr[curr_str], (idx - len), len);
481                         retstr[curr_str][len] = 0;
482                         len = 0;
483                         curr_str++;
484                         last_char = *idx;
485                         idx++;
486                     }
487 
488                     if (curr_str >= (int)strlen(str))
489                     {
490                         *toks = curr_str + 1;
491                         return retstr;
492                     }
493                 }
494                 else
495                 {
496                     last_char = *idx;
497                     idx++;
498                     sep_idx = sep;
499                     len = 0;
500                 }
501             }
502             else
503             {
504                 sep_idx++;
505             }
506         }
507 
508         sep_idx = sep;
509         len++;
510         last_char = *idx;
511         idx++;
512     }
513 
514     if (len > 0)
515     {
516         retstr[curr_str] = (char *) MALLOC((sizeof(char) * len) + 1);
517 
518         if (retstr[curr_str] == NULL)
519         {
520             *toks = 0;
521             FREE(retstr);
522             return NULL;
523         }
524 
525         memcpy(retstr[curr_str], (idx - len), len);
526         retstr[curr_str][len] = 0;
527 
528         *toks = curr_str + 1;
529     }
530     return retstr;
531 }
532 /*--------------------------------------------------------------------------*/
getDoubleValuesFromLines(char ** lines,int sizelines,int nbLinesText,char * format,char * separator,int m,int n)533 static double *getDoubleValuesFromLines(char **lines, int sizelines,
534                                         int nbLinesText,
535                                         char *format, char *separator,
536                                         int m, int n)
537 {
538     double *dValues = NULL;
539 
540     if (m == 0 || n == 0)
541     {
542         return NULL;
543     }
544 
545     dValues = (double*) MALLOC(sizeof(double) * (m * n));
546     if (dValues)
547     {
548         int i = 0;
549         int firstLinesMatrix = nbLinesText;
550         for (i = firstLinesMatrix; i < sizelines; i++)
551         {
552             double *dValsTmp = getDoubleValuesInLine(lines[i], format, separator, m);
553             if (dValsTmp)
554             {
555                 int j = 0;
556                 for (j = 0; j < m; j++)
557                 {
558                     dValues[(i - firstLinesMatrix) + n * j] = dValsTmp[j];
559                 }
560                 FREE(dValsTmp);
561                 dValsTmp = NULL;
562             }
563         }
564     }
565     return dValues;
566 }
567 /*--------------------------------------------------------------------------*/
getDoubleValuesInLine(char * line,char * format,char * separator,int nbColumnsMax)568 static double *getDoubleValuesInLine(char *line,
569                                      char *format, char *separator,
570                                      int nbColumnsMax)
571 {
572     double *dValues = NULL;
573 
574     if (line && format && separator)
575     {
576         int nbTokens = 0;
577         char **splittedStr = splitLine(line, separator, &nbTokens, 0);
578         if (splittedStr)
579         {
580             int i = 0;
581             dValues = (double*)MALLOC(sizeof(double) * nbColumnsMax);
582             for (i = 0; i < nbColumnsMax; i++)
583             {
584                 int ierr = 0;
585                 double dValue = 0.;
586                 char *cleanedFormat = getCleanedFormat(format);
587                 int iLen = (int)strlen(cleanedFormat);
588                 switch (cleanedFormat[iLen - 1])
589                 {
590                     case 'e' :
591                     case 'g' :
592                     case 'f' :
593                     {
594                         if (cleanedFormat[iLen - 2] == 'l')
595                         {
596                             double tmp = 0.;
597                             ierr = sscanf(splittedStr[i], cleanedFormat, &tmp);
598                             dValue = tmp;
599                         }
600                         else
601                         {
602                             float tmp = 0.;
603                             ierr = sscanf(splittedStr[i], cleanedFormat, &tmp);
604                             dValue = tmp;
605                         }
606                         break;
607                     }
608                     case 'd' :
609                     case 'i' :
610                     {
611                         int tmp = 0;
612                         ierr = sscanf(splittedStr[i], cleanedFormat, &tmp);
613                         dValue = tmp;
614                         break;
615                     }
616                 }
617 
618                 FREE(cleanedFormat);
619 
620                 if ((ierr != 0) && (ierr != EOF))
621                 {
622                     dValues[i] = dValue;
623                 }
624                 else
625                 {
626                     char *str = os_strdup(line);
627                     strcpy(str, "");
628                     ierr = sscanf(splittedStr[i], "%4s", str);
629                     if ((ierr != 0) && (ierr != EOF))
630                     {
631                         if ( (strcmp(str, NanString) == 0) ||
632                                 (strcmp(str, NegInfString) == 0) ||
633                                 (strcmp(str, InfString) == 0) )
634                         {
635                             if (strcmp(str, NanString) == 0)
636                             {
637                                 dValues[i] = nc_nan();
638                             }
639 
640                             if (strcmp(str, NegInfString) == 0)
641                             {
642                                 dValues[i] = nc_neginf();
643                             }
644 
645                             if (strcmp(str, InfString) == 0)
646                             {
647                                 dValues[i] = nc_inf();
648                             }
649                         }
650                         else
651                         {
652                             freeArrayOfString(splittedStr, nbTokens);
653                             FREE(dValues);
654                             dValues = NULL;
655                             FREE(str);
656                             str = NULL;
657                             return NULL;
658                         }
659                     }
660                     else
661                     {
662                         freeArrayOfString(splittedStr, nbTokens);
663                         FREE(dValues);
664                         dValues = NULL;
665                         FREE(str);
666                         str = NULL;
667                         return NULL;
668                     }
669                     FREE(str);
670                     str = NULL;
671                 }
672             }
673             freeArrayOfString(splittedStr, nbTokens);
674         }
675     }
676 
677     return dValues;
678 }
679 /*--------------------------------------------------------------------------*/
checkFscanfMatFormat(char * format)680 static BOOL checkFscanfMatFormat(char *format)
681 {
682     if (format)
683     {
684         char *tokenPercent1 = strchr(format, '%');
685         char *tokenPercent2 = strrchr(format, '%');
686         if ((tokenPercent2 && tokenPercent1) && (tokenPercent1 == tokenPercent2))
687         {
688             char *cleanedFormat = getCleanedFormat(format);
689             if (cleanedFormat)
690             {
691                 FREE(cleanedFormat);
692                 cleanedFormat = NULL;
693                 return TRUE;
694             }
695         }
696     }
697     return FALSE;
698 }
699 /*--------------------------------------------------------------------------*/
getCleanedFormat(char * format)700 static char *getCleanedFormat(char *format)
701 {
702     char *cleanedFormat = NULL;
703     if (format)
704     {
705         char *percent = strchr(format, '%');
706         if (percent)
707         {
708             int i = 0;
709             for (i = 0; i < NB_FORMAT_SUPPORTED; i++)
710             {
711                 char *token = strstr(percent, supportedFormat[i]);
712                 if (token)
713                 {
714                     int nbcharacters = (int)(strlen(percent) - strlen(token));
715                     cleanedFormat = os_strdup(percent);
716                     cleanedFormat[nbcharacters] = 0;
717                     if ( (nbcharacters - 1 > 0) && (isdigit(cleanedFormat[nbcharacters - 1]) ||
718                                                     (cleanedFormat[nbcharacters - 1]) == '.') ||
719                             (cleanedFormat[nbcharacters - 1]) == '%')
720                     {
721                         strcat(cleanedFormat, supportedFormat[i]);
722                         return cleanedFormat;
723                     }
724                     else
725                     {
726                         FREE(cleanedFormat);
727                         cleanedFormat = NULL;
728                     }
729                 }
730             }
731         }
732     }
733     return cleanedFormat;
734 }
735 /*--------------------------------------------------------------------------*/
removeEmptyLinesAtTheEnd(char ** lines,int * sizelines)736 static char **removeEmptyLinesAtTheEnd(char **lines, int *sizelines)
737 {
738     int i = 0;
739     int nbLinesToRemove = 0;
740     if (lines)
741     {
742         for (i = *sizelines - 1; i >= 0; i--)
743         {
744             if (lines[i])
745             {
746                 if ( (strcmp(lines[i], "") == 0) || (isOnlyBlankLine(lines[i])) )
747                 {
748                     FREE(lines[i]);
749                     lines[i] = NULL;
750                     nbLinesToRemove++;
751                 }
752                 else
753                 {
754                     break;
755                 }
756             }
757         }
758 
759         if (nbLinesToRemove > 0)
760         {
761             lines = (char**)REALLOC(lines, sizeof(char*) * (*sizelines - nbLinesToRemove));
762             *sizelines = *sizelines - nbLinesToRemove;
763         }
764     }
765     else
766     {
767         *sizelines = 0;
768     }
769     return lines;
770 }
771 /*--------------------------------------------------------------------------*/
isValidLineWithOnlyOneNumber(char * line)772 static BOOL isValidLineWithOnlyOneNumber(char *line)
773 {
774     if (line)
775     {
776         char *pEnd = NULL;
777         strtod(line, &pEnd);
778         if ((pEnd) && ((int)strlen(pEnd) == 0))
779         {
780             return TRUE;
781         }
782         else
783         {
784             if ((strncmp(line, NanString, (int)strlen(NanString)) == 0) ||
785                     (strncmp(line, NegInfString, (int)strlen(NegInfString)) == 0) ||
786                     (strncmp(line, InfString, (int)strlen(InfString)) == 0))
787             {
788                 return TRUE;
789             }
790         }
791     }
792     return FALSE;
793 }
794 /*--------------------------------------------------------------------------*/
isOnlyBlankLine(const char * line)795 static BOOL isOnlyBlankLine(const char *line)
796 {
797     if (line)
798     {
799         int i = 0;
800         for (i = 0; i < (int) strlen(line); i++)
801         {
802             if (line[i] != ' ')
803             {
804                 return FALSE;
805             }
806         }
807     }
808     return TRUE;
809 }
810 /*--------------------------------------------------------------------------*/
removeTextLinesAtTheEnd(char ** lines,int * sizelines,char * format,char * separator)811 static char ** removeTextLinesAtTheEnd(char **lines, int *sizelines, char *format, char *separator)
812 {
813     char **linesReturned = NULL;
814     int i = 0;
815     int nbLinesToRemove = 0;
816 
817     for (i = *sizelines - 1; i > 0; i--)
818     {
819         if (itCanBeMatrixLine(lines[i], format, separator) == FALSE)
820         {
821             nbLinesToRemove++;
822             FREE(lines[i]);
823             lines[i] = NULL;
824         }
825         else
826         {
827             break;
828         }
829     }
830 
831     if (nbLinesToRemove > 0)
832     {
833         //must free last lines.
834         *sizelines = *sizelines - nbLinesToRemove;
835         linesReturned = lines;
836     }
837     else
838     {
839         linesReturned = lines;
840     }
841 
842     return linesReturned;
843 
844 }
845 /*--------------------------------------------------------------------------*/
846