Fix some easy to fix warnings
[scilab.git] / scilab / modules / fileio / sci_gateway / cpp / sci_mscanf.cpp
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2006 - INRIA - Allan CORNET
4 * Copyright (C) 2009 - DIGITEO - Allan CORNET
5 * Copyright (C) 2010 - DIGITEO - Antoine ELIAS
6 * Copyright (C) 2011 - DIGITEO - Cedric DELAMARRE
7 *
8  * Copyright (C) 2012 - 2016 - Scilab Enterprises
9  *
10  * This file is hereby licensed under the terms of the GNU GPL v2.0,
11  * pursuant to article 5.3.4 of the CeCILL v.2.1.
12  * This file was originally licensed under the terms of the CeCILL v2.1,
13  * and continues to be available under such terms.
14  * For more information, see the COPYING file which you should have received
15  * along with this program.
16 *
17 */
18 /*--------------------------------------------------------------------------*/
19 #include "fileio_gw.hxx"
20 #include "string.hxx"
21 #include "scilabWrite.hxx"
22 #include "cell.hxx"
23 #include "function.hxx"
24 #include "double.hxx"
25 #include "configvariable.hxx"
26 #include "threadmanagement.hxx"
27
28 extern "C"
29 {
30 #include "sci_malloc.h"
31 #include "localization.h"
32 #include "Scierror.h"
33 #include "do_xxscanf.h"
34 #include "scanf_functions.h"
35 #include "scilabRead.h"
36 }
37
38 types::Function::ReturnValue sci_mscanf(types::typed_list &in, int _iRetCount, types::typed_list &out)
39 {
40     int size                    = (int)in.size();
41     int iNiter                  = 1;
42     wchar_t* wcsFormat          = NULL;
43     wchar_t* wcsRead            = NULL;
44     int dimsArray[2]            = {1, 1};
45     std::vector<types::InternalType*>* pIT = new std::vector<types::InternalType*>();
46
47     int args        = 0;
48     int nrow        = 0;
49     int ncol        = 0;
50     int retval      = 0;
51     int retval_s    = 0;
52     int rowcount    = -1;
53     rec_entry buf[MAXSCAN];
54     entry *data;
55     sfdir type[MAXSCAN], type_s[MAXSCAN];
56
57     if (size < 1 || size > 2)
58     {
59         Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "mscanf", 1, 2);
60         return types::Function::Error;
61     }
62
63     if (size == 2)
64     {
65         if (in[0]->isDouble() == false || in[0]->getAs<types::Double>()->isScalar() == false || in[0]->getAs<types::Double>()->isComplex())
66         {
67             Scierror(999, _("%s: Wrong type for input argument #%d: A Real expected.\n"), "mscanf", 1);
68             return types::Function::Error;
69         }
70         iNiter = static_cast<int>(in[0]->getAs<types::Double>()->get(0));
71         if (iNiter < 0)
72         {
73             iNiter = 1;
74         }
75     }
76
77     if (in[size - 1]->isString() == false || in[size - 1]->getAs<types::String>()->isScalar() == false)
78     {
79         Scierror(999, _("%s: Wrong type for input argument #%d: A String expected.\n"), "mscanf", size);
80         return types::Function::Error;
81     }
82
83     wcsFormat = in[size - 1]->getAs<types::String>()->get(0);
84     nrow = iNiter;
85     while (++rowcount < iNiter)
86     {
87         if ((iNiter >= 0) && (rowcount >= iNiter))
88         {
89             break;
90         }
91
92         // get data
93         // The console thread must not parse the next console input.
94         ConfigVariable::setScilabCommand(0);
95
96         // Get the console input filled by the console thread.
97         char* pcConsoleReadStr = ConfigVariable::getConsoleReadStr();
98         ThreadManagement::SendConsoleExecDoneSignal();
99         while (pcConsoleReadStr == NULL)
100         {
101             pcConsoleReadStr = ConfigVariable::getConsoleReadStr();
102             ThreadManagement::SendConsoleExecDoneSignal();
103         }
104
105         // reset flag to default value
106         ConfigVariable::setScilabCommand(1);
107
108         wcsRead = to_wide_string(pcConsoleReadStr);
109         FREE(pcConsoleReadStr);
110         int err = do_xxscanf(L"sscanf", (FILE *)0, wcsFormat, &args, wcsRead, &retval, buf, type);
111         FREE(wcsRead);
112         if (err < 0)
113         {
114             return types::Function::Error;
115         }
116         err = Store_Scan(&nrow, &ncol, type_s, type, &retval, &retval_s, buf, &data, rowcount, args);
117         if (err < 0)
118         {
119             switch (err)
120             {
121                 case DO_XXPRINTF_MISMATCH:
122                     if (iNiter >= 0)
123                     {
124                         Free_Scan(rowcount, ncol, type_s, &data);
125                         Scierror(999, _("%s: Data mismatch.\n"), "mscanf");
126                         return types::Function::Error;
127                     }
128                     break;
129
130                 case DO_XXPRINTF_MEM_LACK:
131                     Free_Scan(rowcount, ncol, type_s, &data);
132                     Scierror(999, _("%s: No more memory.\n"), "mscanf");
133                     return types::Function::Error;
134                     break;
135             }
136             if (err == DO_XXPRINTF_MISMATCH)
137             {
138                 break;
139             }
140         }
141     }
142
143     unsigned int uiFormatUsed = 0;
144     for (int i = 0; i < ncol; i++)
145     {
146         switch ( type_s[i] )
147         {
148             case SF_C:
149             case SF_S:
150             {
151                 types::String* ps = new types::String(iNiter, 1);
152                 for (int j = 0; j < iNiter; j++)
153                 {
154                     ps->set(j, data[i + ncol * j].s);
155                 }
156                 pIT->push_back(ps);
157                 uiFormatUsed |= (1 << 1);
158             }
159             break;
160             case SF_LUI:
161             case SF_SUI:
162             case SF_UI:
163             case SF_LI:
164             case SF_SI:
165             case SF_I:
166             case SF_LF:
167             case SF_F:
168             {
169                 types::Double* p = new types::Double(iNiter, 1);
170                 for (int j = 0; j < iNiter; j++)
171                 {
172                     p->set(j, data[i + ncol * j].d);
173                 }
174                 pIT->push_back(p);
175                 uiFormatUsed |= (1 << 2);
176             }
177             break;
178             case NONE:
179                 break;
180         }
181     }
182
183     int sizeOfVector = (int)pIT->size();
184     if (_iRetCount > 1)
185     {
186         types::Double* pDouble = new types::Double(2, dimsArray);
187         pDouble->set(0, retval);
188         out.push_back(pDouble);
189
190         for (int i = 0; i < sizeOfVector; i++)
191         {
192             out.push_back((*pIT)[i]);
193         }
194         for (int i = sizeOfVector + 1; i < _iRetCount; i++)
195         {
196             out.push_back(types::Double::Empty());
197         }
198     }
199     else
200     {
201         if (sizeOfVector == 0)
202         {
203             out.push_back(new types::String(L""));
204             return types::Function::OK;
205         }
206
207         switch (uiFormatUsed)
208         {
209             case (1 << 1) :
210             {
211                 int sizeOfString = (*pIT)[0]->getAs<types::String>()->getRows();
212                 int dimsArrayOfRes[2] = {sizeOfString, sizeOfVector};
213                 types::String* pString = new types::String(2, dimsArrayOfRes);
214                 for (int i = 0; i < sizeOfVector; i++)
215                 {
216                     for (int j = 0; j < sizeOfString; j++)
217                     {
218                         pString->set(i * sizeOfString + j, (*pIT)[i]->getAs<types::String>()->get(j));
219                     }
220                 }
221                 out.push_back(pString);
222             }
223             break;
224             case (1 << 2) :
225             {
226                 int sizeOfDouble = (*pIT)[0]->getAs<types::Double>()->getRows();
227                 int dimsArrayOfRes[2] = {sizeOfDouble, sizeOfVector};
228                 types::Double* pDouble = new types::Double(2, dimsArrayOfRes);
229                 for (int i = 0; i < sizeOfVector; i++)
230                 {
231                     for (int j = 0; j < sizeOfDouble; j++)
232                     {
233                         pDouble->set(i * sizeOfDouble + j, (*pIT)[i]->getAs<types::Double>()->get(j));
234                     }
235                 }
236                 out.push_back(pDouble);
237             }
238             break;
239             default :
240             {
241                 std::vector<types::InternalType*>* pITTemp = new std::vector<types::InternalType*>();
242                 pITTemp->push_back((*pIT)[0]);
243
244                 // sizeOfVector always > 1
245                 for (int i = 1; i < sizeOfVector; i++) // concatenates the Cells. ex : [String 4x1] [String 4x1] = [String 4x2]
246                 {
247                     if (pITTemp->back()->getType() == (*pIT)[i]->getType())
248                     {
249                         switch (pITTemp->back()->getType())
250                         {
251                             case types::InternalType::ScilabString :
252                             {
253                                 int iRows               = pITTemp->back()->getAs<types::String>()->getRows();
254                                 int iCols               = pITTemp->back()->getAs<types::String>()->getCols();
255                                 int arrayOfType[2]      = {iRows, iCols + 1};
256                                 types::String* pType    = new types::String(2, arrayOfType);
257
258                                 for (int k = 0; k < pITTemp->back()->getAs<types::String>()->getSize(); k++)
259                                 {
260                                     pType->set(k, pITTemp->back()->getAs<types::String>()->get(k));
261                                 }
262                                 for (int k = 0; k < (*pIT)[i]->getAs<types::String>()->getSize(); k++)
263                                 {
264                                     pType->set(iRows * iCols + k, (*pIT)[i]->getAs<types::String>()->get(k));
265                                 }
266                                 pITTemp->pop_back();
267                                 pITTemp->push_back(pType);
268                             }
269                             break;
270                             case types::InternalType::ScilabDouble :
271                             {
272                                 int iRows               = pITTemp->back()->getAs<types::Double>()->getRows();
273                                 int iCols               = pITTemp->back()->getAs<types::Double>()->getCols();
274                                 int arrayOfType[2]      = {iRows, iCols + 1};
275                                 types::Double* pType    = new types::Double(2, arrayOfType);
276
277                                 pType->set(pITTemp->back()->getAs<types::Double>()->get());
278                                 for (int k = 0; k < (*pIT)[i]->getAs<types::Double>()->getSize(); k++)
279                                 {
280                                     pType->set(iRows * iCols + k, (*pIT)[i]->getAs<types::Double>()->get(k));
281                                 }
282                                 pITTemp->pop_back();
283                                 pITTemp->push_back(pType);
284                             }
285                             break;
286                             default :
287                                 return types::Function::Error;
288                         }
289                     }
290                     else
291                     {
292                         pITTemp->push_back((*pIT)[i]);
293                     }
294                 }
295
296                 int dimsArrayOfCell[2] = {1, (int)pITTemp->size()};
297                 types::Cell* pCell = new types::Cell(2, dimsArrayOfCell);
298                 for (int i = 0; i < dimsArrayOfCell[1]; i++)
299                 {
300                     pCell->set(i, (*pITTemp)[i]);
301                 }
302                 out.push_back(pCell);
303             }
304         }
305     }
306     Free_Scan(rowcount, ncol, type_s, &data);
307     return types::Function::OK;
308 }
309 /*--------------------------------------------------------------------------*/