1a2b865357db2c0d997ac14f26813b2a9ed339eb
[scilab.git] / scilab / modules / output_stream / sci_gateway / cpp / sci_msprintf.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) INRIA
4  * Copyright (C) 2010 - DIGITEO - ELIAS Antoine
5  *
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at
10  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11  *
12  */
13
14 #include "funcmanager.hxx"
15 #include "output_stream_gw.hxx"
16 #include "scilab_sprintf.hxx"
17 #include "function.hxx"
18 #include "string.hxx"
19 #include "overload.hxx"
20 #include "execvisitor.hxx"
21
22 extern "C"
23 {
24 #include "Scierror.h"
25 #include "localization.h"
26 #include "freeArrayOfString.h"
27 }
28
29 /*--------------------------------------------------------------------------*/
30 types::Callable::ReturnValue sci_msprintf(types::typed_list &in, int _iRetCount, types::typed_list &out)
31 {
32     //Structure to store, link between % and input value
33     ArgumentPosition* pArgs = NULL;
34
35     if (in.size() < 1)
36     {
37         Scierror(999, _("%s: Wrong number of input arguments: at least %d expected.\n"), "msprintf", 1);
38         return types::Function::Error;
39     }
40
41     if (in[0]->isString() == false || in[0]->getAs<types::String>()->getSize() != 1)
42     {
43         Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), "msprintf" , 1);
44         return types::Function::Error;
45     }
46
47     for (int i = 1 ; i < in.size() ; i++)
48     {
49         if (in[i]->isDouble() == false && in[i]->isString() == false)
50         {
51             ast::ExecVisitor exec;
52             std::wstring wstFuncName = L"%" + in[i]->getShortTypeStr() + L"_msprintf";
53             return Overload::call(wstFuncName, in, _iRetCount, out, &exec);
54         }
55     }
56
57     wchar_t* pwstInput = in[0]->getAs<types::String>()->get()[0];
58     int iNumberPercent = 0;
59     int iNumberPercentPercent = 0;
60     for (int i = 0; i < wcslen(pwstInput); i++)
61     {
62         if (pwstInput[i] == L'%')
63         {
64             iNumberPercent++;
65             if (pwstInput[i + 1] == L'%')
66             {
67                 //it is a %%, not a %_
68                 iNumberPercentPercent++;
69                 //force incremantation to bypass the second % of %%
70                 i++;
71             }
72         }
73     }
74
75     //Input values must be less or equal than excepted
76     if ((in.size() - 1) > iNumberPercent - iNumberPercentPercent)
77     {
78         Scierror(999, _("%s: Wrong number of input arguments: at most %d expected.\n"), "msprintf", iNumberPercent);
79         return types::Function::Error;
80     }
81
82     //determine if imput values are ... multiple values
83     int iNumberCols = 0;
84     if ( in.size() > 1 )
85     {
86         int iRefRows = in[1]->getAs<GenericType>()->getRows();
87         for (int i = 1 ; i < in.size() ; i++)
88         {
89             //all arguments must have the same numbers of rows !
90             if (iRefRows != in[i]->getAs<GenericType>()->getRows())
91             {
92                 Scierror(999, _("%s: Wrong number of input arguments: data doesn't fit with format.\n"), "msprintf");
93                 return types::Function::Error;
94             }
95
96             iNumberCols += in[i]->getAs<GenericType>()->getCols();
97         }
98     }
99
100     if (iNumberCols != iNumberPercent - iNumberPercentPercent)
101     {
102         Scierror(999, _("%s: Wrong number of input arguments: data doesn't fit with format.\n"), "msprintf");
103         return types::Function::Error;
104     }
105
106
107     //fill ArgumentPosition structure
108     pArgs = new ArgumentPosition[iNumberPercent - iNumberPercentPercent];
109     int idx = 0;
110     for (int i = 1 ; i < in.size() ; i++)
111     {
112         for (int j = 0 ; j < in[i]->getAs<GenericType>()->getCols() ; j++)
113         {
114             pArgs[idx].iArg = i;
115             pArgs[idx].iPos = j;
116             pArgs[idx].type = in[i]->getType();
117             idx++;
118         }
119     }
120
121     int iOutputRows = 0;
122     int iNewLine = 0;
123     wchar_t** pwstOutput = scilab_sprintf("msprintf", pwstInput, in, pArgs, iNumberPercent, &iOutputRows, &iNewLine);
124
125     delete[] pArgs;
126     if (pwstOutput == NULL)
127     {
128         return types::Function::Error;
129     }
130
131     types::String* pOut = new types::String(iOutputRows, 1);
132     pOut->set(pwstOutput);
133     freeArrayOfWideString(pwstOutput, iOutputRows);
134     out.push_back(pOut);
135     return types::Function::OK;
136 }
137 /*--------------------------------------------------------------------------*/