bug 13972 : use of wildcard '*' in printf expressions was not managed
[scilab.git] / scilab / modules / fileio / sci_gateway / cpp / sci_mfprintf.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 * This file must be used under the terms of the CeCILL.
9 * This source file is licensed as described in the file COPYING, which
10 * you should have received as part of this distribution.  The terms
11 * are also available at
12 * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
13 *
14 */
15 /*--------------------------------------------------------------------------*/
16 #include "filemanager.hxx"
17 #include "fileio_gw.hxx"
18 #include "function.hxx"
19 #include "double.hxx"
20 #include "string.hxx"
21 #include "scilab_sprintf.hxx"
22 #include "overload.hxx"
23 #include "execvisitor.hxx"
24
25 extern "C"
26 {
27 #include <stdio.h>
28 #include "localization.h"
29 #include "Scierror.h"
30 #include "sci_malloc.h"
31 #include "configvariable_interface.h"
32 #include "mputl.h"
33 }
34 /*--------------------------------------------------------------------------*/
35 #ifdef _MSC_VER
36 static BOOL forceSTDERRredirect = TRUE;
37 #endif
38
39 using namespace types;
40 using namespace ast;
41 /*--------------------------------------------------------------------------*/
42
43 Function::ReturnValue sci_mfprintf(types::typed_list &in, int _iRetCount, types::typed_list &out)
44 {
45     BOOL isSTD                      = FALSE;
46     BOOL isSTDErr                   = FALSE;
47     int iFile                       = -1; //default file : last opened file
48     unsigned int iNumberPercent     = 0;
49     unsigned int iNumberCols        = 0;
50     int nbrOfLines                  = 0;
51     int ifileMode                   = 0;
52     wchar_t* wcsInput               = NULL;
53     wchar_t** wcsStringToWrite      = NULL;
54
55     if (in.size() < 2)
56     {
57         Scierror(77, _("%s: Wrong number of input argument(s): At least %d expected.\n"), "mfprintf", 2);
58         return types::Function::Error;
59     }
60
61     if (in[0]->isDouble() == false)
62     {
63         Scierror(999, _("%s: Wrong type for input argument #%d: A Real expected.\n"), "mfprintf", 1);
64         return types::Function::Error;
65     }
66
67     types::Double* pFileId = in[0]->getAs<types::Double>();
68     if (pFileId->isScalar() == false || pFileId->isComplex())
69     {
70         Scierror(999, _("%s: Wrong type for input argument #%d: A Real expected.\n"), "mfprintf", 1);
71         return types::Function::Error;
72     }
73
74     if (in[1]->isString() == false)
75     {
76         Scierror(999, _("%s: Wrong type for input argument #%d: A String expected.\n"), "mfprintf", 2);
77         return types::Function::Error;
78     }
79
80     types::String* pFileStr = in[1]->getAs<types::String>();
81     if (pFileStr->isScalar() == false)
82     {
83         Scierror(999, _("%s: Wrong type for input argument #%d: A String expected.\n"), "mfprintf", 2);
84         return types::Function::Error;
85     }
86
87     for (unsigned int i = 2 ; i < in.size() ; i++)
88     {
89         if (in[i]->isDouble() == false && in[i]->isString() == false)
90         {
91             ast::ExecVisitor exec;
92             std::wstring wstFuncName = L"%" + in[i]->getShortTypeStr() + L"_mfprintf";
93             return Overload::call(wstFuncName, in, _iRetCount, out, &exec);
94         }
95     }
96
97     // checking ID of file
98     iFile = static_cast<int>(pFileId->get(0));
99
100     if (FileManager::getFile(iFile) == NULL)
101     {
102         Scierror(999, _("%s: Wrong file descriptor: %d.\n"), "mfprintf", iFile);
103         return types::Function::Error;
104     }
105
106     switch (iFile)
107     {
108         case 0:
109 #ifdef _MSC_VER
110             if ((getScilabMode()  == SCILAB_STD) && (forceSTDERRredirect == TRUE))
111             {
112                 //  Console redirect stderr --> CONOUT$
113                 freopen("CONOUT$", "wb", stderr);
114                 forceSTDERRredirect = FALSE;
115             }
116 #endif
117             isSTDErr = TRUE;
118         case 6:
119             isSTD = TRUE;
120             break;
121         case 5:
122             Scierror(999, _("%s: Wrong file descriptor: %d.\n"), "mfprintf", iFile);
123             return types::Function::Error;
124         default:
125             isSTD = FALSE;
126             types::File* pFile = FileManager::getFile(iFile);
127             // file opened with fortran open function
128             if (pFile->getFileType() == 1)
129             {
130                 Scierror(999, _("%s: Wrong file descriptor: %d.\n"), "mfprintf", iFile);
131                 return types::Function::Error;
132             }
133             ifileMode = pFile->getFileModeAsInt();
134             break;
135     }
136
137     /* checks file mode */
138     /* bug 3898 */
139     /* read only attrib 1xx*/
140     if ((ifileMode >= 100) && (ifileMode < 200) && ((ifileMode % 100) < 10) /* check that it is not r+ */ && !isSTD)
141     {
142         Scierror(999, _("%s: Wrong file mode: READ only.\n"), "mfprintf");
143         return types::Function::Error;
144     }
145
146     // Checking input string to write in file
147     int iNewLine = 0;
148     wcsInput = pFileStr->get(0);
149     wcsStringToWrite = scilab_sprintf("mfprintf", wcsInput, in, &nbrOfLines, &iNewLine);
150
151     if (isSTD)
152     {
153         for (int i = 0; i < nbrOfLines; i++)
154         {
155             if (isSTDErr)
156             {
157                 std::wcerr << wcsStringToWrite[i];
158             }
159             else
160             {
161                 scilabForcedWriteW(wcsStringToWrite[i]);
162             }
163         }
164         scilabForcedWriteW(L"\n");
165     }
166     else
167     {
168         int iRet = mputl(iFile, wcsStringToWrite, nbrOfLines, (BOOL)iNewLine); // FALSE = don't add the "\n" at the end.
169         if (iRet)
170         {
171             Scierror(999, _("%s: Error while writing in file: disk full or deleted file.\n"), "mprintf");
172             return types::Function::Error;
173         }
174     }
175
176     for (int i = 0; i < nbrOfLines; i++)
177     {
178         FREE(wcsStringToWrite[i]);
179     }
180
181     FREE(wcsStringToWrite);
182     return types::Function::OK;
183 }
184 /*--------------------------------------------------------------------------*/