Coverity: fileio module resource leaks fixed
[scilab.git] / scilab / modules / fileio / src / cpp / scilab_sscanf.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2011 - DIGITEO - Cedric DELAMARRE
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 #include "types.hxx"
17 #include "double.hxx"
18 #include "string.hxx"
19 #include "scilab_sscanf.hxx"
20 #include "int.hxx"
21
22 extern "C"
23 {
24 #include <stdio.h>
25 #include "Scierror.h"
26 #include "sci_malloc.h"
27 #include "localization.h"
28 #include "charEncoding.h"
29 #include "BOOL.h"
30 #include "os_wcstok.h"
31 }
32
33 static wchar_t* findChars(wchar_t*, BOOL*); // Use to find what is inside the [] when the format is %[...].
34
35 int scilab_sscanf(wchar_t* _wcsFormat, wchar_t* _wcsData, int _iIterrator, int _iNiter, std::vector<types::InternalType*> *_pITOut)
36 {
37     int i                       = 0;
38     int j                       = 0;
39     int nbrOfDigit              = 0;
40     int dims                    = 2;
41     int dimsArray[2]            = {_iNiter, 1};
42     BOOL bStar                  = FALSE;
43     BOOL bUnsigned              = FALSE;
44     BOOL bIgnoredChars          = TRUE;
45     int base                    = 0;
46     wchar_t wcsLLH              = L' ';
47     wchar_t* wcsData            = NULL;
48     int sizeOfData              = (int)wcslen(_wcsData);
49     int iCountDataRead          = 0;
50
51     wcsData = (wchar_t*)MALLOC((sizeOfData + 1) * sizeof(wchar_t));
52     memcpy(wcsData, _wcsData, sizeOfData * sizeof(wchar_t));
53     wcsData[sizeOfData] = '\0';
54
55     while (i < (int)wcslen(_wcsFormat))
56     {
57         while (bIgnoredChars && i < (int)wcslen(_wcsFormat)) // %da%s => 'a' is an ignored char.
58         {
59             if (wcsData != NULL && wcsData[0] != L'\0' && _wcsFormat[i] == wcsData[0])
60             {
61                 if (_wcsFormat[i] != L' ')
62                 {
63                     i++;
64                     wcsData++;
65                 }
66                 else
67                 {
68                     while (wcsData[0] == L' ')
69                     {
70                         wcsData++;
71                     }
72                     while (_wcsFormat[i] == L' ')
73                     {
74                         i++;
75                     }
76                 }
77             }
78             else if ((wcsData == NULL || wcsData[0] == L'\0') && i < (int)wcslen(_wcsFormat) && iCountDataRead == 0 && _pITOut->size() == 0)
79             {
80                 iCountDataRead = -1;
81             }
82             else
83             {
84                 if (_wcsFormat[i] == L' ')
85                 {
86                     do
87                     {
88                         i++;
89                     }
90                     while (i < (int)wcslen(_wcsFormat) && _wcsFormat[i] == L' ');
91                 }
92
93                 if (_wcsFormat[i] != L'%')
94                 {
95                     FREE(wcsData);
96                     wcsData = NULL;
97                     while (i < (int)wcslen(_wcsFormat) && _wcsFormat[i] != L'%')
98                     {
99                         i++;
100                     }
101                 }
102                 break;
103             }
104         }
105         if (i == (int)wcslen(_wcsFormat))
106         {
107             break;
108         }
109
110         if (iswdigit(_wcsFormat[i]))
111         {
112             nbrOfDigit = wcstol(&_wcsFormat[i], NULL, 10);
113             while (iswdigit(_wcsFormat[i]))
114             {
115                 i++;
116             }
117         }
118         else switch (_wcsFormat[i])
119             {
120                 case L' ' :
121                 case L'\n':
122                 case L'\t':
123                     i++;
124                     break;
125                 case L'%' :
126                     i++;
127                     bIgnoredChars = FALSE;
128                     break;
129                 case L'*' :
130                     bStar = TRUE;
131                     i++;
132                     break;
133                 case L'h' :
134                 case L'l' :
135                 case L'L' :
136                     wcsLLH = _wcsFormat[i];
137                     i++;
138                     break;
139                 case L'c' :
140                 {
141                     if (wcsData != NULL && wcsData[0] != L'\0') // If the end of data has not been reached we can get datas.
142                     {
143                         wchar_t wcSingleData[2];
144                         wcSingleData[0] = wcsData[0];
145                         wcSingleData[1] = 0;
146
147                         if (!bStar) // If this format is not ignored put the datas found.
148                         {
149                             if (_iIterrator == 0) // Create and initialize the container only the first time.
150                             {
151                                 types::String* pS = new types::String(dims, dimsArray);
152                                 for (int k = 0 ; k < pS->getSize(); k++)
153                                 {
154                                     pS->set(k, L"");
155                                 }
156                                 _pITOut->push_back(pS);
157                             }
158                             (*_pITOut)[j]->getAs<types::String>()->set(_iIterrator, wcSingleData);
159                             iCountDataRead++;
160                         }
161                         wcsData++;
162                     }
163                     else
164                     {
165                         if (_iIterrator == 0 && !bStar && _iNiter == 1)
166                         {
167                             _pITOut->push_back(types::Double::Empty());
168                         }
169                         else
170                         {
171                             FREE(wcsData);
172                             return -10;
173                         }
174                     }
175                     if (!bStar)
176                     {
177                         j++;
178                     }
179                     i++;
180                     bIgnoredChars = TRUE;
181                     bStar = FALSE;
182                 }
183                 break;
184                 case L's' :
185                 {
186                     if (wcsData != NULL && wcsData[0] != L'\0')
187                     {
188                         wchar_t* wcsSingleData  = NULL;
189                         wchar_t* wcsRes         = NULL;
190                         wchar_t seps[]          = L" \t\n";
191                         int sizeOfCurrentData   = (int)wcslen(wcsData);
192                         wchar_t* wcsTemp        = (wchar_t*)MALLOC((sizeOfCurrentData + 1) * sizeof(wchar_t));
193
194                         memcpy(wcsTemp, wcsData, sizeOfCurrentData * sizeof(wchar_t));
195                         wcsTemp[sizeOfCurrentData] = L'\0';
196                         wcsRes = os_wcstok(wcsTemp, seps, &wcsTemp); // the seps[] found is replaced by the '\0' char.
197
198                         if (wcsTemp == NULL || wcsTemp[0] == L'\0')
199                         {
200                             FREE(wcsData);
201                             wcsData = NULL;
202                         }
203                         else
204                         {
205                             wcsData += (wcslen(wcsData) - wcslen(wcsTemp) - 1); // set the pointer on the seps[] and not on the next char.
206                         }
207
208                         if (nbrOfDigit) // Get only the numbers of digit indicated in the format. (ex: %2d)
209                         {
210                             wcsSingleData = (wchar_t*)MALLOC(sizeof(wchar_t) * (nbrOfDigit + 1));
211                             memcpy(wcsSingleData, wcsRes, sizeof(wchar_t) * nbrOfDigit);
212                             wcsSingleData[nbrOfDigit] = L'\0';
213                             nbrOfDigit = 0;
214                         }
215                         else // Get all data find.
216                         {
217                             wcsSingleData = wcsRes;
218                         }
219
220                         if (!bStar)
221                         {
222                             if (_iIterrator == 0)
223                             {
224                                 types::String* pS = new types::String(dims, dimsArray);
225                                 for (int k = 0 ; k < pS->getSize(); k++)
226                                 {
227                                     pS->set(k, L"");
228                                 }
229                                 _pITOut->push_back(pS);
230                             }
231                             (*_pITOut)[j]->getAs<types::String>()->set(_iIterrator, wcsSingleData);
232                             iCountDataRead++;
233                         }
234
235                         if (nbrOfDigit)
236                         {
237                             FREE(wcsSingleData);
238                         }
239                     }
240                     else
241                     {
242                         if (_iIterrator == 0 && !bStar && _iNiter == 1)
243                         {
244                             _pITOut->push_back(types::Double::Empty());
245                         }
246                         else
247                         {
248                             FREE(wcsData);
249                             return -10;
250                         }
251                     }
252                     if (!bStar)
253                     {
254                         j++;
255                     }
256                     i++;
257                     bIgnoredChars = TRUE;
258                     bStar = FALSE;
259                 }
260                 break;
261                 case L'[' :
262                 {
263                     if (wcsData != NULL && wcsData[0] != L'\0')
264                     {
265                         wchar_t* wcsInside          = NULL;
266                         wchar_t* wcsCpyFormat       = NULL;
267                         unsigned int iPos           = 0;
268                         wchar_t* wcsSingleData      = NULL;
269                         wchar_t* wcsRes             = NULL;
270                         wchar_t* wscToFind          = NULL;
271                         BOOL bInv                   = FALSE;
272
273                         i++;
274                         wcsCpyFormat = (wchar_t*)MALLOC((wcslen(_wcsFormat) - i + 1) * sizeof(wchar_t));
275                         memcpy(wcsCpyFormat, &_wcsFormat[i], (wcslen(_wcsFormat) - i) * sizeof(wchar_t));
276                         wcsCpyFormat[wcslen(_wcsFormat) - i] = L'\0';
277
278                         wcsInside = os_wcstok(wcsCpyFormat, L"]", &wcsCpyFormat);
279                         i += (int)wcslen(wcsInside) + 1; // +1 => ]
280
281                         wscToFind = findChars(wcsInside, &bInv);
282                         if (wscToFind == NULL)
283                         {
284                             // MALLOC error
285                             FREE(wcsData);
286                             return -10;
287                         }
288
289                         if (bInv)
290                         {
291                             iPos = (int)wcscspn(wcsData, wscToFind);
292                         }
293                         else
294                         {
295                             iPos = (int)wcsspn(wcsData, wscToFind);
296                         }
297                         FREE(wscToFind);
298                         if (iPos == 0)
299                         {
300                             // The string begins with a character which is not in wscToFind
301                             if (_iIterrator == 0 && !bStar && _iNiter == 1)
302                             {
303                                 _pITOut->push_back(types::Double::Empty());
304                             }
305                             else
306                             {
307                                 FREE(wcsData);
308                                 return -10;
309                             }
310                         }
311                         else
312                         {
313                             wcsRes = (wchar_t*)MALLOC((iPos + 1) * sizeof(wchar_t));
314                             memcpy(wcsRes, wcsData, iPos * sizeof(wchar_t));
315                             wcsRes[iPos] = '\0';
316
317                             FREE(wcsInside);
318
319                             if (nbrOfDigit)
320                             {
321                                 wcsSingleData = (wchar_t*)MALLOC(sizeof(wchar_t) * (nbrOfDigit + 1));
322                                 memcpy(wcsSingleData, wcsRes, sizeof(wchar_t) * nbrOfDigit);
323                                 wcsSingleData[nbrOfDigit] = L'\0';
324                                 wcsData += nbrOfDigit;
325                             }
326                             else
327                             {
328                                 wcsSingleData = wcsRes;
329                                 wcsData += iPos;
330                             }
331                         }
332
333                         if (!bStar)
334                         {
335                             if (_iIterrator == 0)
336                             {
337                                 types::String* pS = new types::String(dims, dimsArray);
338                                 for (int k = 0 ; k < pS->getSize(); k++)
339                                 {
340                                     pS->set(k, L"");
341                                 }
342                                 _pITOut->push_back(pS);
343                             }
344                             if (wcsSingleData != NULL)
345                             {
346                                 (*_pITOut)[j]->getAs<types::String>()->set(_iIterrator, wcsSingleData);
347                                 iCountDataRead++;
348                             }
349                         }
350
351                         if (nbrOfDigit)
352                         {
353                             FREE(wcsSingleData);
354                         }
355                     }
356                     else
357                     {
358                         if (_iIterrator == 0 && !bStar && _iNiter == 1)
359                         {
360                             _pITOut->push_back(types::Double::Empty());
361                         }
362                         else
363                         {
364                             FREE(wcsData);
365                             return -10;
366                         }
367                     }
368                     if (!bStar)
369                     {
370                         j++;
371                     }
372                     bIgnoredChars   = TRUE;
373                     nbrOfDigit      = 0;
374                     bStar           = FALSE;
375                 }
376                 break;
377                 case L'x' :
378                 case L'X' :
379                     base += 6; // 6 + 2 + 8 = 16 // Compute the base of data to get.
380                 case L'u' :
381                     if (base == 0)
382                     {
383                         bUnsigned = TRUE;    // unsigned int
384                     }
385                 case L'i' :
386                 case L'd' :
387                     base += 2; // 2 + 8 = 10
388                 case L'o' :
389                     base += 8; // 8 = 8 :D
390                     {
391                         if (wcsData != NULL && wcsData[0] != L'\0')
392                         {
393                             long int iSingleData = 0;
394                             while (wcsData[0] == L' ')
395                             {
396                                 wcsData++;
397                             }
398                             if (nbrOfDigit)
399                             {
400                                 wchar_t* number = NULL;
401                                 if (wcslen(wcsData) < nbrOfDigit)
402                                 {
403                                     nbrOfDigit = (int)wcslen(wcsData);
404                                 }
405
406                                 number = (wchar_t*)MALLOC((nbrOfDigit + 1) * sizeof(wchar_t));
407                                 memcpy(number, wcsData, nbrOfDigit * sizeof(wchar_t));
408                                 number[nbrOfDigit] = L'\0';
409                                 iSingleData = wcstoul(number, &number, base);
410                                 if ((iSingleData == 0) && (number[0] == wcsData[0]))
411                                 {
412                                     if (_iIterrator == 0 && !bStar && _iNiter == 1)
413                                     {
414                                         FREE(wcsData);
415                                         wcsData = NULL;
416                                         _pITOut->push_back(types::Double::Empty());
417                                         bStar = TRUE;
418                                     }
419                                     else
420                                     {
421                                         FREE(wcsData);
422                                         return -10;
423                                     }
424                                 }
425                                 if (number == NULL)
426                                 {
427                                     wcsData += nbrOfDigit;
428                                 }
429                                 else
430                                 {
431                                     wcsData += (nbrOfDigit - wcslen(number));
432                                 }
433                                 nbrOfDigit = 0;
434                             }
435                             else
436                             {
437                                 wchar_t temp = wcsData[0];
438                                 iSingleData = wcstoul(wcsData, &wcsData, base);
439                                 if ((iSingleData == 0) && (temp == wcsData[0]))
440                                 {
441                                     if (_iIterrator == 0 && !bStar && _iNiter == 1)
442                                     {
443                                         wcsData = NULL;
444                                         _pITOut->push_back(types::Double::Empty());
445                                         bStar = TRUE;
446                                     }
447                                     else
448                                     {
449                                         FREE(wcsData);
450                                         return -10;
451                                     }
452                                 }
453                             }
454
455                             if (!bStar)
456                             {
457                                 if (_iIterrator == 0)
458                                 {
459                                     switch (wcsLLH)
460                                     {
461                                         case L'h' :
462                                         {
463                                             if (bUnsigned)
464                                             {
465                                                 types::UInt16* pUInt16 = new types::UInt16(dims, dimsArray);
466                                                 for (int k = 0; k < pUInt16->getSize(); k++)
467                                                 {
468                                                     pUInt16->set(k, 0);
469                                                 }
470                                                 _pITOut->push_back(pUInt16);
471                                             }
472                                             else
473                                             {
474                                                 types::Int16* pInt16 = new types::Int16(dims, dimsArray);
475                                                 for (int k = 0; k < pInt16->getSize(); k++)
476                                                 {
477                                                     pInt16->set(k, 0);
478                                                 }
479                                                 _pITOut->push_back(pInt16);
480                                             }
481                                         }
482                                         break;
483                                         case L'l' :
484                                         case L'L' :
485                                         {
486                                             if (bUnsigned)
487                                             {
488                                                 types::UInt64* pUInt64 = new types::UInt64(dims, dimsArray);
489                                                 for (int k = 0; k < pUInt64->getSize(); k++)
490                                                 {
491                                                     pUInt64->set(k, 0);
492                                                 }
493                                                 _pITOut->push_back(pUInt64);
494                                             }
495                                             else
496                                             {
497                                                 types::Int64* pInt64 = new types::Int64(dims, dimsArray);
498                                                 for (int k = 0; k < pInt64->getSize(); k++)
499                                                 {
500                                                     pInt64->set(k, 0);
501                                                 }
502                                                 _pITOut->push_back(pInt64);
503                                             }
504                                         }
505                                         break;
506                                         default :
507                                         {
508                                             if (bUnsigned)
509                                             {
510                                                 types::UInt32* pUInt32 = new types::UInt32(dims, dimsArray);
511                                                 for (int k = 0; k < pUInt32->getSize(); k++)
512                                                 {
513                                                     pUInt32->set(k, 0);
514                                                 }
515                                                 _pITOut->push_back(pUInt32);
516                                             }
517                                             else
518                                             {
519                                                 types::Int32* pInt32 = new types::Int32(dims, dimsArray);
520                                                 for (int k = 0; k < pInt32->getSize(); k++)
521                                                 {
522                                                     pInt32->set(k, 0);
523                                                 }
524                                                 _pITOut->push_back(pInt32);
525                                             }
526                                         }
527                                     }
528                                 }
529                                 switch (wcsLLH)
530                                 {
531                                     case L'h' :
532                                         if (bUnsigned)
533                                         {
534                                             (*_pITOut)[j]->getAs<types::UInt16>()->set(_iIterrator, static_cast<unsigned short int>(iSingleData));
535                                             iCountDataRead++;
536                                         }
537                                         else
538                                         {
539                                             (*_pITOut)[j]->getAs<types::Int16>()->set(_iIterrator, static_cast<short int>(iSingleData));
540                                             iCountDataRead++;
541                                         }
542                                         break;
543                                     case L'l' :
544                                     case L'L' :
545                                         if (bUnsigned)
546                                         {
547                                             (*_pITOut)[j]->getAs<types::UInt64>()->set(_iIterrator, iSingleData);
548                                             iCountDataRead++;
549                                         }
550                                         else
551                                         {
552                                             (*_pITOut)[j]->getAs<types::Int64>()->set(_iIterrator, static_cast<long int>(iSingleData));
553                                             iCountDataRead++;
554                                         }
555                                         break;
556                                     default :
557                                         if (bUnsigned)
558                                         {
559                                             (*_pITOut)[j]->getAs<types::UInt32>()->set(_iIterrator, static_cast<unsigned int>(iSingleData));
560                                             iCountDataRead++;
561                                         }
562                                         else
563                                         {
564                                             (*_pITOut)[j]->getAs<types::Int32>()->set(_iIterrator, static_cast<int>(iSingleData));
565                                             iCountDataRead++;
566                                         }
567                                 }
568                             }
569                         }
570                         else
571                         {
572                             if (_iIterrator == 0 && !bStar && _iNiter == 1)
573                             {
574                                 _pITOut->push_back(types::Double::Empty());
575                             }
576                             else
577                             {
578                                 FREE(wcsData);
579                                 return -10;
580                             }
581                         }
582                         if (!bStar)
583                         {
584                             j++;
585                         }
586                         wcsLLH          = L' ';
587                         bIgnoredChars   = TRUE;
588                         bUnsigned       = FALSE;
589                         bStar           = FALSE;
590                         base            = 0;
591                         i++;
592                     }
593                     break;
594                 case L'e' :
595                 case L'E' :
596                 case L'g' :
597                 case L'G' :
598                 case L'f' :
599                 {
600                     if (wcsData != NULL && wcsData[0] != L'\0')
601                     {
602                         double dSingleData  = 0;
603                         BOOL bSigne         = FALSE;
604                         while (wcsData[0] == L' ')
605                         {
606                             wcsData++;
607                         }
608                         if (nbrOfDigit)
609                         {
610                             int iSizeRead   = 0;
611                             wchar_t* number = NULL;
612                             wchar_t* next   = NULL;
613                             if (wcslen(wcsData) < nbrOfDigit)
614                             {
615                                 nbrOfDigit = (int)wcslen(wcsData);
616                             }
617                             number = (wchar_t*)MALLOC((nbrOfDigit + 1) * sizeof(wchar_t));
618                             memcpy(number, wcsData, nbrOfDigit * sizeof(wchar_t));
619                             number[nbrOfDigit] = L'\0';
620                             dSingleData = wcstod(number, &next);
621                             if (next)
622                             {
623                                 iSizeRead = nbrOfDigit - (int)wcslen(next);
624                             }
625                             else
626                             {
627                                 iSizeRead = nbrOfDigit;
628                             }
629                             if ((dSingleData == 0) && (number[0] == next[0]))
630                             {
631                                 if (_iIterrator == 0 && !bStar && _iNiter == 1)
632                                 {
633                                     wcsData = NULL;
634                                     _pITOut->push_back(types::Double::Empty());
635                                     bStar = TRUE;
636                                 }
637                                 else
638                                 {
639                                     FREE(wcsData);
640                                     return -10;
641                                 }
642                             }
643                             wcsData += iSizeRead;
644                             FREE(number);
645                             nbrOfDigit = 0;
646                         }
647                         else
648                         {
649                             int iLenData = (int)wcslen(wcsData);
650                             dSingleData = wcstod(wcsData, &wcsData);
651                             if ((dSingleData == 0) && (iLenData == wcslen(wcsData)))
652                             {
653                                 if (_iIterrator == 0 && !bStar && _iNiter == 1)
654                                 {
655                                     FREE(wcsData);
656                                     wcsData = NULL;
657                                     _pITOut->push_back(types::Double::Empty());
658                                     bStar = TRUE;
659                                 }
660                                 else
661                                 {
662                                     FREE(wcsData);
663                                     return -10;
664                                 }
665                             }
666                         }
667
668                         if (!bStar)
669                         {
670                             if (_iIterrator == 0)
671                             {
672                                 types::Double* pD = new types::Double(dims, dimsArray);
673                                 for (int k = 0 ; k < pD->getSize(); k++)
674                                 {
675                                     pD->set(k, 0);
676                                 }
677                                 _pITOut->push_back(pD);
678                             }
679                             (*_pITOut)[j]->getAs<types::Double>()->set(_iIterrator, dSingleData);
680                             iCountDataRead++;
681                         }
682                     }
683                     else
684                     {
685                         if (_iIterrator == 0 && !bStar && _iNiter == 1)
686                         {
687                             _pITOut->push_back(types::Double::Empty());
688                         }
689                         else
690                         {
691                             FREE(wcsData);
692                             return -10;
693                         }
694                     }
695                     if (!bStar)
696                     {
697                         j++;
698                     }
699                     i++;
700                     bIgnoredChars = TRUE;
701                     bStar = FALSE;
702                 }
703                 break;
704                 case L'n' :
705                 {
706                     double dSingleData = -1;
707                     if (_iIterrator == 0 && !bStar)
708                     {
709                         types::Double* pD = new types::Double(dims, dimsArray);
710                         for (int k = 0 ; k < pD->getSize(); k++)
711                         {
712                             pD->set(k, 0);
713                         }
714                         _pITOut->push_back(pD);
715                     }
716
717                     if (wcsData == NULL || wcsData[0] == L'\0')
718                     {
719                         dSingleData = (double)sizeOfData;
720                     }
721                     else
722                     {
723                         dSingleData = (double)sizeOfData - (double)wcslen(wcsData);
724                     }
725
726                     if (!bStar)
727                     {
728                         (*_pITOut)[j]->getAs<types::Double>()->set(_iIterrator, dSingleData);
729                         j++;
730                     }
731
732                     i++;
733                     bIgnoredChars = TRUE;
734                     bStar = FALSE;
735                 }
736                 break;
737                 default :
738                     printf("format read : %c\n", _wcsFormat[i]);
739                     FREE(wcsData);
740                     return -10;
741             }
742     }
743     FREE(wcsData);
744     return iCountDataRead;
745 }
746
747 wchar_t* findChars(wchar_t* chars, BOOL* _bInv) // ex: "123456789abc" = findChars("1-9abc")
748 {
749     unsigned int iIterChars = 0;
750     unsigned int iIterRes   = 0;
751     int iNbr                = 0;
752     int iLen                = 0;
753     wchar_t* wcsRes         = NULL;
754     int* piPos              = NULL;
755
756     piPos = (int*)MALLOC(wcslen(chars) * sizeof(int));
757
758     if (chars[0] == L'^')
759     {
760         *_bInv = TRUE;
761     }
762     else
763     {
764         *_bInv = FALSE;
765     }
766
767     for (iIterChars = 0; iIterChars < wcslen(chars); iIterChars++)
768     {
769         if (chars[iIterChars] == L'-' && iIterChars != 0 && iIterChars != wcslen(chars) - 1)
770         {
771             int iSize = chars[iIterChars + 1] - chars[iIterChars - 1] - 1;
772             if (iSize >= 0)
773             {
774                 iLen += iSize;
775                 iNbr++;
776                 piPos[iIterChars] = 1;
777             }
778             else
779             {
780                 piPos[iIterChars] = 0;
781                 iLen++;
782             }
783         }
784         else
785         {
786             piPos[iIterChars] = 0;
787             iLen++;
788         }
789     }
790
791     wcsRes = (wchar_t*)MALLOC((iLen + 1) * sizeof(wchar_t));
792
793     for (iIterChars = 0; iIterChars < wcslen(chars); iIterChars++)
794     {
795         if (piPos[iIterChars])
796         {
797             for (int i = 1; i < (chars[iIterChars + 1] - chars[iIterChars - 1]); i++, iIterRes++)
798             {
799                 wcsRes[iIterRes] = chars[iIterChars - 1] + i;
800             }
801         }
802         else
803         {
804             wcsRes[iIterRes] = chars[iIterChars];
805             iIterRes++;
806         }
807     }
808     wcsRes[iLen] = L'\0';
809
810     FREE(piPos);
811     return wcsRes;
812 }