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"
22 #include "function.hxx"
27 #include "localization.h"
29 #include "do_xxscanf.h"
30 #include "scanf_functions.h"
33 types::Function::ReturnValue sci_msscanf(types::typed_list &in, int _iRetCount, types::typed_list &out)
35 int size = (int)in.size();
37 wchar_t* wcsFormat = NULL;
38 types::String* pStrRead = NULL;
39 int dimsArray[2] = {1, 1};
40 std::vector<types::InternalType*> IT;
48 rec_entry buf[MAXSCAN];
50 sfdir type[MAXSCAN] = {NONE};
51 sfdir type_s[MAXSCAN] = {NONE};
53 if (size < 2 || size > 3)
55 Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "msscanf", 2, 3);
56 return types::Function::Error;
61 if (in[0]->isDouble() == false || in[0]->getAs<types::Double>()->isScalar() == false || in[0]->getAs<types::Double>()->isComplex())
63 Scierror(999, _("%s: Wrong type for input argument #%d: A Real expected.\n"), "msscanf", 1);
64 return types::Function::Error;
66 iNiter = static_cast<int>(in[0]->getAs<types::Double>()->get(0));
69 if (in[size - 2]->isString() == false)
71 Scierror(999, _("%s: Wrong type for input argument #%d: A Strings expected.\n"), "msscanf", size - 1);
72 return types::Function::Error;
75 if (in[size - 1]->isString() == false || in[size - 1]->getAs<types::String>()->isScalar() == false)
77 Scierror(999, _("%s: Wrong type for input argument #%d: A String expected.\n"), "msscanf", size);
78 return types::Function::Error;
81 pStrRead = in[size - 2]->getAs<types::String>();
84 iNiter = pStrRead->getRows();
86 wcsFormat = in[size - 1]->getAs<types::String>()->get(0);
88 while (++rowcount < iNiter)
90 if ((iNiter >= 0) && (rowcount >= iNiter))
94 int err = do_xxscanf(L"sscanf", (FILE *)0, wcsFormat, &args, pStrRead->get(rowcount), &retval, buf, type);
95 if (err == DO_XXPRINTF_MISMATCH)
101 return types::Function::Error;
103 err = Store_Scan(&nrow, &ncol, type_s, type, &retval, &retval_s, buf, &data, rowcount, args);
108 case DO_XXPRINTF_MISMATCH:
109 Free_Scan(rowcount, ncol, type_s, &data);
110 Scierror(999, _("%s: Data mismatch.\n"), "msscanf");
111 return types::Function::Error;
113 case DO_XXPRINTF_MEM_LACK:
114 Free_Scan(rowcount, ncol, type_s, &data);
115 Scierror(999, _("%s: No more memory.\n"), "msscanf");
116 return types::Function::Error;
121 unsigned int uiFormatUsed = 0;
122 for (int i = 0; i < ncol; i++)
129 types::String* ps = new types::String(iNiter, 1);
130 for (int j = 0; j < iNiter; j++)
132 ps->set(j, data[i + ncol * j].s);
136 uiFormatUsed |= (1 << 1);
148 types::Double* p = new types::Double(iNiter, 1);
149 for (int j = 0; j < iNiter; j++)
151 p->set(j, data[i + ncol * j].d);
155 uiFormatUsed |= (1 << 2);
163 int sizeOfVector = (int)IT.size();
166 out.push_back(new types::Double((double)retval));
168 for (int i = 0; i < sizeOfVector; i++)
170 out.push_back(IT[i]);
172 for (int i = sizeOfVector + 1; i < _iRetCount; i++)
174 out.push_back(types::Double::Empty());
179 if (sizeOfVector == 0)
181 out.push_back(types::Double::Empty());
182 return types::Function::OK;
185 switch (uiFormatUsed)
189 int sizeOfString = IT[0]->getAs<types::String>()->getRows();
190 int dimsArrayOfRes[2] = {sizeOfString, sizeOfVector};
191 types::String* pString = new types::String(2, dimsArrayOfRes);
192 for (int i = 0; i < sizeOfVector; i++)
194 for (int j = 0; j < sizeOfString; j++)
196 pString->set(i * sizeOfString + j, IT[i]->getAs<types::String>()->get(j));
199 out.push_back(pString);
204 int sizeOfDouble = IT[0]->getAs<types::Double>()->getRows();
205 int dimsArrayOfRes[2] = {sizeOfDouble, sizeOfVector};
206 types::Double* pDouble = new types::Double(2, dimsArrayOfRes);
207 for (int i = 0; i < sizeOfVector; i++)
209 types::Double* pdbl = IT[i]->getAs<types::Double>();
210 double* dbl = pdbl->get();
211 for (int j = 0; j < sizeOfDouble; j++)
213 pDouble->set(i * sizeOfDouble + j, dbl[j]);
218 out.push_back(pDouble);
223 std::vector<types::InternalType*>* pITTemp = new std::vector<types::InternalType*>();
224 pITTemp->push_back(IT[0]);
226 // sizeOfVector always > 1
227 for (int i = 1; i < sizeOfVector; i++) // concatenates the Cells. ex : [String 4x1] [String 4x1] = [String 4x2]
229 if (pITTemp->back()->getType() == IT[i]->getType())
231 switch (pITTemp->back()->getType())
233 case types::InternalType::ScilabString :
235 int iRows = pITTemp->back()->getAs<types::String>()->getRows();
236 int iCols = pITTemp->back()->getAs<types::String>()->getCols();
237 int arrayOfType[2] = {iRows, iCols + 1};
238 types::String* pType = new types::String(2, arrayOfType);
240 for (int k = 0; k < pITTemp->back()->getAs<types::String>()->getSize(); k++)
242 pType->set(k, pITTemp->back()->getAs<types::String>()->get(k));
244 for (int k = 0; k < IT[i]->getAs<types::String>()->getSize(); k++)
246 pType->set(iRows * iCols + k, IT[i]->getAs<types::String>()->get(k));
249 pITTemp->push_back(pType);
252 case types::InternalType::ScilabDouble :
254 int iRows = pITTemp->back()->getAs<types::Double>()->getRows();
255 int iCols = pITTemp->back()->getAs<types::Double>()->getCols();
256 int arrayOfType[2] = {iRows, iCols + 1};
257 types::Double* pType = new types::Double(2, arrayOfType);
259 pType->set(pITTemp->back()->getAs<types::Double>()->get());
260 for (int k = 0; k < IT[i]->getAs<types::Double>()->getSize(); k++)
262 pType->set(iRows * iCols + k, IT[i]->getAs<types::Double>()->get(k));
265 pITTemp->push_back(pType);
270 return types::Function::Error;
275 pITTemp->push_back(IT[i]);
279 types::MList* pMList = new types::MList();
280 pMList->append(new types::String(L"cblock"));
281 for (int i = 0 ; i < pITTemp->size() ; i++)
283 pMList->append((*pITTemp)[i]);
285 out.push_back(pMList);
287 // int dimsArrayOfCell[2] = {1, (int)pITTemp->size()};
288 // types::Cell* pCell = new types::Cell(2, dimsArrayOfCell);
289 // for (int i = 0; i < pITTemp->size(); i++)
291 // pCell->set(i, (*pITTemp)[i]);
293 // out.push_back(pCell);
297 Free_Scan(rowcount, ncol, type_s, &data);
298 return types::Function::OK;
300 /*--------------------------------------------------------------------------*/