* Bug #14824 fixed - Incorrect error message with mfprintf(fd, '%d', [])
[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  * Copyright (C) 2012 - 2016 - Scilab Enterprises
9  *
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.
16 *
17 */
18 /*--------------------------------------------------------------------------*/
19 #include "filemanager.hxx"
20 #include "fileio_gw.hxx"
21 #include "function.hxx"
22 #include "double.hxx"
23 #include "string.hxx"
24 #include "scilab_sprintf.hxx"
25 #include "overload.hxx"
26 #include "scilabWrite.hxx"
27
28 extern "C"
29 {
30 #include <stdio.h>
31 #include "localization.h"
32 #include "Scierror.h"
33 #include "sci_malloc.h"
34 #include "configvariable_interface.h"
35 #include "mputl.h"
36 }
37 /*--------------------------------------------------------------------------*/
38 #ifdef _MSC_VER
39 static BOOL forceSTDERRredirect = TRUE;
40 #endif
41
42 /*--------------------------------------------------------------------------*/
43 types::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             std::wstring wstFuncName = L"%" + in[i]->getShortTypeStr() + L"_mfprintf";
92             return Overload::call(wstFuncName, in, _iRetCount, out);
93         }
94     }
95
96     // checking ID of file
97     iFile = static_cast<int>(pFileId->get(0));
98
99     if (FileManager::getFile(iFile) == NULL)
100     {
101         Scierror(999, _("%s: Wrong file descriptor: %d.\n"), "mfprintf", iFile);
102         return types::Function::Error;
103     }
104
105     switch (iFile)
106     {
107         case 0:
108 #ifdef _MSC_VER
109             if ((getScilabMode()  == SCILAB_STD) && (forceSTDERRredirect == TRUE))
110             {
111                 //  Console redirect stderr --> CONOUT$
112                 freopen("CONOUT$", "wb", stderr);
113                 forceSTDERRredirect = FALSE;
114             }
115 #endif
116             isSTDErr = TRUE;
117             break;
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 || 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 (wcsStringToWrite == NULL)
152     {
153         return types::Function::Error;
154     }
155
156     if (isSTD)
157     {
158         for (int i = 0; i < nbrOfLines; i++)
159         {
160             if (isSTDErr)
161             {
162                 std::wcerr << wcsStringToWrite[i];
163             }
164             else
165             {
166                 scilabForcedWriteW(wcsStringToWrite[i]);
167             }
168             scilabForcedWriteW(L"\n");
169         }
170     }
171     else
172     {
173         int iRet = mputl(iFile, wcsStringToWrite, nbrOfLines, (BOOL)iNewLine); // FALSE = don't add the "\n" at the end.
174         if (iRet)
175         {
176             Scierror(999, _("%s: Error while writing in file: disk full or deleted file.\n"), "mprintf");
177             for (int i = 0; i < nbrOfLines; i++)
178             {
179                 FREE(wcsStringToWrite[i]);
180             }
181             FREE(wcsStringToWrite);
182             return types::Function::Error;
183         }
184     }
185
186     for (int i = 0; i < nbrOfLines; i++)
187     {
188         FREE(wcsStringToWrite[i]);
189     }
190
191     FREE(wcsStringToWrite);
192     return types::Function::OK;
193 }
194 /*--------------------------------------------------------------------------*/