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
8 * Copyright (C) 2012 - 2016 - Scilab Enterprises
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.
18 /*--------------------------------------------------------------------------*/
19 #include "fileio_gw.hxx"
21 #include "scilabWrite.hxx"
23 #include "function.hxx"
25 #include "configvariable.hxx"
26 #include "threadmanagement.hxx"
30 #include "sci_malloc.h"
31 #include "localization.h"
33 #include "do_xxscanf.h"
34 #include "scanf_functions.h"
35 #include "scilabRead.h"
38 types::Function::ReturnValue sci_mscanf(types::typed_list &in, int _iRetCount, types::typed_list &out)
40 int size = (int)in.size();
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*>();
53 rec_entry buf[MAXSCAN];
55 sfdir type[MAXSCAN] = {NONE};
56 sfdir type_s[MAXSCAN] = {NONE};
58 if (size < 1 || size > 2)
60 Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "mscanf", 1, 2);
62 return types::Function::Error;
67 if (in[0]->isDouble() == false || in[0]->getAs<types::Double>()->isScalar() == false || in[0]->getAs<types::Double>()->isComplex())
69 Scierror(999, _("%s: Wrong type for input argument #%d: A Real expected.\n"), "mscanf", 1);
71 return types::Function::Error;
73 iNiter = static_cast<int>(in[0]->getAs<types::Double>()->get(0));
80 if (in[size - 1]->isString() == false || in[size - 1]->getAs<types::String>()->isScalar() == false)
82 Scierror(999, _("%s: Wrong type for input argument #%d: A String expected.\n"), "mscanf", size);
84 return types::Function::Error;
87 wcsFormat = in[size - 1]->getAs<types::String>()->get(0);
89 while (++rowcount < iNiter)
91 if ((iNiter >= 0) && (rowcount >= iNiter))
97 // The console thread must not parse the next console input.
98 ConfigVariable::setScilabCommand(0);
100 // Get the console input filled by the console thread.
101 char* pcConsoleReadStr = ConfigVariable::getConsoleReadStr();
102 ThreadManagement::SendConsoleExecDoneSignal();
103 while (pcConsoleReadStr == NULL)
105 pcConsoleReadStr = ConfigVariable::getConsoleReadStr();
106 ThreadManagement::SendConsoleExecDoneSignal();
109 // reset flag to default value
110 ConfigVariable::setScilabCommand(1);
112 wcsRead = to_wide_string(pcConsoleReadStr);
113 FREE(pcConsoleReadStr);
114 int err = do_xxscanf(L"sscanf", (FILE *)0, wcsFormat, &args, wcsRead, &retval, buf, type);
119 return types::Function::Error;
121 err = Store_Scan(&nrow, &ncol, type_s, type, &retval, &retval_s, buf, &data, rowcount, args);
126 case DO_XXPRINTF_MISMATCH:
127 Free_Scan(rowcount, ncol, type_s, &data);
128 Scierror(999, _("%s: Data mismatch.\n"), "mscanf");
129 return types::Function::Error;
131 case DO_XXPRINTF_MEM_LACK:
132 Free_Scan(rowcount, ncol, type_s, &data);
133 Scierror(999, _("%s: No more memory.\n"), "mscanf");
134 return types::Function::Error;
139 unsigned int uiFormatUsed = 0;
140 for (int i = 0; i < ncol; i++)
147 types::String* ps = new types::String(iNiter, 1);
148 for (int j = 0; j < iNiter; j++)
150 ps->set(j, data[i + ncol * j].s);
153 uiFormatUsed |= (1 << 1);
165 types::Double* p = new types::Double(iNiter, 1);
166 for (int j = 0; j < iNiter; j++)
168 p->set(j, data[i + ncol * j].d);
171 uiFormatUsed |= (1 << 2);
179 int sizeOfVector = (int)pIT->size();
182 types::Double* pDouble = new types::Double(2, dimsArray);
183 pDouble->set(0, retval);
184 out.push_back(pDouble);
186 for (int i = 0; i < sizeOfVector; i++)
188 out.push_back((*pIT)[i]);
190 for (int i = sizeOfVector + 1; i < _iRetCount; i++)
192 out.push_back(types::Double::Empty());
197 if (sizeOfVector == 0)
199 out.push_back(new types::String(L""));
201 return types::Function::OK;
204 switch (uiFormatUsed)
208 int sizeOfString = (*pIT)[0]->getAs<types::String>()->getRows();
209 int dimsArrayOfRes[2] = {sizeOfString, sizeOfVector};
210 types::String* pString = new types::String(2, dimsArrayOfRes);
211 for (int i = 0; i < sizeOfVector; i++)
213 for (int j = 0; j < sizeOfString; j++)
215 pString->set(i * sizeOfString + j, (*pIT)[i]->getAs<types::String>()->get(j));
218 out.push_back(pString);
223 int sizeOfDouble = (*pIT)[0]->getAs<types::Double>()->getRows();
224 int dimsArrayOfRes[2] = {sizeOfDouble, sizeOfVector};
225 types::Double* pDouble = new types::Double(2, dimsArrayOfRes);
226 for (int i = 0; i < sizeOfVector; i++)
228 for (int j = 0; j < sizeOfDouble; j++)
230 pDouble->set(i * sizeOfDouble + j, (*pIT)[i]->getAs<types::Double>()->get(j));
233 out.push_back(pDouble);
238 std::vector<types::InternalType*>* pITTemp = new std::vector<types::InternalType*>();
239 pITTemp->push_back((*pIT)[0]);
241 // sizeOfVector always > 1
242 for (int i = 1; i < sizeOfVector; i++) // concatenates the Cells. ex : [String 4x1] [String 4x1] = [String 4x2]
244 if (pITTemp->back()->getType() == (*pIT)[i]->getType())
246 switch (pITTemp->back()->getType())
248 case types::InternalType::ScilabString :
250 int iRows = pITTemp->back()->getAs<types::String>()->getRows();
251 int iCols = pITTemp->back()->getAs<types::String>()->getCols();
252 int arrayOfType[2] = {iRows, iCols + 1};
253 types::String* pType = new types::String(2, arrayOfType);
255 for (int k = 0; k < pITTemp->back()->getAs<types::String>()->getSize(); k++)
257 pType->set(k, pITTemp->back()->getAs<types::String>()->get(k));
259 for (int k = 0; k < (*pIT)[i]->getAs<types::String>()->getSize(); k++)
261 pType->set(iRows * iCols + k, (*pIT)[i]->getAs<types::String>()->get(k));
264 pITTemp->push_back(pType);
267 case types::InternalType::ScilabDouble :
269 int iRows = pITTemp->back()->getAs<types::Double>()->getRows();
270 int iCols = pITTemp->back()->getAs<types::Double>()->getCols();
271 int arrayOfType[2] = {iRows, iCols + 1};
272 types::Double* pType = new types::Double(2, arrayOfType);
274 pType->set(pITTemp->back()->getAs<types::Double>()->get());
275 for (int k = 0; k < (*pIT)[i]->getAs<types::Double>()->getSize(); k++)
277 pType->set(iRows * iCols + k, (*pIT)[i]->getAs<types::Double>()->get(k));
280 pITTemp->push_back(pType);
285 return types::Function::Error;
290 pITTemp->push_back((*pIT)[i]);
294 int dimsArrayOfCell[2] = {1, (int)pITTemp->size()};
295 types::Cell* pCell = new types::Cell(2, dimsArrayOfCell);
296 for (int i = 0; i < dimsArrayOfCell[1]; i++)
298 pCell->set(i, (*pITTemp)[i]);
300 out.push_back(pCell);
304 Free_Scan(rowcount, ncol, type_s, &data);
306 return types::Function::OK;
308 /*--------------------------------------------------------------------------*/