de3e96f0ce93addd8a86e635d42f466d9be087ad
[scilab.git] / scilab / modules / output_stream / sci_gateway / cpp / sci_mprintf.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 "scilabWrite.hxx"
18 #include "function.hxx"
19 #include "string.hxx"
20 #include "overload.hxx"
21 #include "execvisitor.hxx"
22
23 extern "C"
24 {
25 #include <stdio.h>
26 #include "Scierror.h"
27 #include "localization.h"
28 }
29
30 /*--------------------------------------------------------------------------*/
31 types::Callable::ReturnValue sci_mprintf(types::typed_list &in, int _iRetCount, types::typed_list &out)
32 {
33     //Structure to store, link between % and input value
34     ArgumentPosition* pArgs = NULL;
35
36     if (in.size() < 1)
37     {
38         Scierror(999, _("%s: Wrong number of input arguments: at least %d expected.\n"), "mprintf", 1);
39         return types::Function::Error;
40     }
41
42     if (in[0]->isString() == false || in[0]->getAs<types::String>()->getSize() != 1)
43     {
44         Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), "mprintf" , 1);
45         return types::Function::Error;
46     }
47
48     for (int i = 1 ; i < in.size() ; i++)
49     {
50         if (in[i]->isDouble() == false && in[i]->isString() == false)
51         {
52             ast::ExecVisitor exec;
53             std::wstring wstFuncName = L"%" + in[i]->getShortTypeStr() + L"_mprintf";
54             return Overload::call(wstFuncName, in, _iRetCount, out, &exec);
55         }
56     }
57
58     wchar_t* pwstInput = in[0]->getAs<types::String>()->get()[0];
59     int iNumberPercent = 0;
60     int iNumberPercentPercent = 0;
61     for (int i = 0 ; i < wcslen(pwstInput) ; i++)
62     {
63         if (pwstInput[i] == L'%')
64         {
65             iNumberPercent++;
66             if (pwstInput[i + 1] == L'%')
67             {
68                 //it is a %%, not a %_
69                 iNumberPercentPercent++;
70                 //force incremantation to bypass the second % of %%
71                 i++;
72             }
73         }
74     }
75
76     //Input values must be less or equal than excepted
77     if ((in.size() - 1) > iNumberPercent - iNumberPercentPercent)
78     {
79         Scierror(999, _("%s: Wrong number of input arguments: at most %d expected.\n"), "mprintf", iNumberPercent);
80         return types::Function::Error;
81     }
82
83     //determine if imput values are ... multiple values
84     int iNumberCols = 0;
85     if ( in.size() > 1 )
86     {
87         int iRefRows = in[1]->getAs<GenericType>()->getRows();
88         for (int i = 1 ; i < in.size() ; i++)
89         {
90             iNumberCols += in[i]->getAs<GenericType>()->getCols();
91         }
92     }
93
94     if (iNumberCols != iNumberPercent - iNumberPercentPercent)
95     {
96         Scierror(999, _("%s: Wrong number of input arguments: data doesn't fit with format.\n"), "mprintf");
97         return types::Function::Error;
98     }
99
100     //fill ArgumentPosition structure
101     pArgs = new ArgumentPosition[iNumberPercent - iNumberPercentPercent];
102     int idx = 0;
103     for (int i = 1 ; i < in.size() ; i++)
104     {
105         for (int j = 0 ; j < in[i]->getAs<GenericType>()->getCols() ; j++)
106         {
107             pArgs[idx].iArg = i;
108             pArgs[idx].iPos = j;
109             pArgs[idx].type = in[i]->getType();
110             idx++;
111         }
112     }
113
114     int iOutputRows = 0;
115     int iNewLine = 0;
116     wchar_t** pwstOutput = scilab_sprintf("mprintf", pwstInput, in, pArgs, iNumberPercent, &iOutputRows, &iNewLine);
117
118     if (pwstOutput == NULL)
119     {
120         delete[] pArgs;
121         return types::Function::Error;
122     }
123
124     for (int i = 0 ; i < iOutputRows ; i++)
125     {
126         if (i)
127         {
128             scilabForcedWriteW(L"\n");
129         }
130
131         scilabForcedWriteW(pwstOutput[i]);
132
133         fflush(NULL);
134         FREE(pwstOutput[i]);
135     }
136
137     if (iNewLine)
138     {
139         scilabForcedWriteW(L"\n");
140     }
141
142     FREE(pwstOutput);
143     delete[] pArgs;
144     return types::Function::OK;
145 }
146 /*--------------------------------------------------------------------------*/