Bug 13721 fixed: Could not write in a file opened in r+ mode
[scilab.git] / scilab / modules / fileio / sci_gateway / c / sci_mfprintf.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) INRIA
4  * ...
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.1-en.txt
11  *
12  */
13 #include "Scierror.h"
14 #include "stack-c.h"
15 #include "do_xxprintf.h"
16 #include "gw_fileio.h"
17 #include "filesmanagement.h"
18 #include "localization.h"
19 #include "BOOL.h"
20 #include "scilabmode.h"
21 /*--------------------------------------------------------------------------*/
22 #ifdef _MSC_VER
23 static BOOL forceSTDERRredirect = TRUE;
24 #endif
25 /*--------------------------------------------------------------------------*/
26 int sci_mfprintf(char *fname, unsigned long fname_len)
27 {
28     FILE *f;
29     BOOL isSTD = FALSE;
30     int fileMode = 0;
31     int l1 = 0, m1 = 0, n1 = 0;
32     int l2 = 0, m2 = 0, n2 = 0;
33     int lcount = 0, rval = 0, mx = 0, mk = 0, nk = 0, k = 0;
34     char *ptrFormat = NULL;
35     int lenptrFormat = 0;
36     int i = 0;
37     int NumberPercent = 0;
38     int param1 = 0;
39
40     Nbvars = 0;
41     CheckRhs(1, 1000);
42     CheckLhs(0, 1);
43     if ( Rhs < 2 )
44     {
45         Scierror(999, _("%s: Wrong number of input arguments: At least %d expected.\n"), fname, 2);
46         return 0;
47     }
48     for ( k = 3; k <= Rhs; k++)
49     {
50         if (VarType(k) != sci_matrix && VarType(k) != sci_strings)
51         {
52             OverLoad(k);
53             return 0;
54         }
55     }
56     GetRhsVar(1, MATRIX_OF_INTEGER_DATATYPE, &m1, &n1, &l1); /* file id */
57     GetRhsVar(2, STRING_DATATYPE, &m2, &n2, &l2); /* format */
58     ptrFormat = cstk(l2);
59
60     param1 = *istk(l1);
61
62     switch (param1)
63     {
64         case 0:
65 #ifdef _MSC_VER
66             if ( (getScilabMode()  == SCILAB_STD) && (forceSTDERRredirect == TRUE) )
67             {
68                 /*  Console redirect stderr --> CONOUT$*/
69                 freopen("CONOUT$", "wb", stderr);
70                 forceSTDERRredirect = FALSE;
71             }
72 #endif
73             f = stderr;
74             break;
75         case 5:
76             // stdin;
77             f = (FILE *)0;
78             break;
79         case 6:
80             f = stdout;
81             break;
82         default:
83             f = GetFileOpenedInScilab(param1);
84             break;
85     }
86
87     if (f == (FILE *)0 )
88     {
89         Scierror(999, _("%s: Wrong file descriptor: %d.\n"), fname, *istk(l1));
90         return 0;
91     }
92
93     switch (param1)
94     {
95         case 0:
96         case 6:
97             isSTD = TRUE;
98             break;
99         default:
100             isSTD = FALSE;
101             fileMode = GetFileModeOpenedInScilab(param1);
102             break;
103     }
104
105
106     /* checks file mode */
107     /* bug 3898 */
108     /* read only attrib 1xx*/
109     if ( (fileMode >= 100) && (fileMode < 200) && ((fileMode % 100) < 10) /* check that it is not r+ */ &&  !isSTD)
110     {
111         Scierror(999, _("%s: Wrong file mode: READ only.\n"), fname);
112         return 0;
113     }
114
115     lenptrFormat = (int)strlen(ptrFormat);
116     for (i = 0; i < lenptrFormat; i++)
117     {
118         if (ptrFormat[i] == '%')
119         {
120             NumberPercent++;
121             if (ptrFormat[i + 1] == '%')
122             {
123                 NumberPercent--;
124                 i++;
125             }
126         }
127     }
128
129     if (NumberPercent < Rhs - 2)
130     {
131         Scierror(999, _("%s: Wrong number of input arguments: %d expected.\n"), fname, NumberPercent + 2);
132         return 0;
133     }
134
135     mx = 0;
136     if (Rhs >= 3)
137     {
138         GetMatrixdims(3, &mx, &nk);
139         for (k = 4; k <= Rhs; k++)
140         {
141             GetMatrixdims(k, &mk, &nk);
142             mx = Min(mx, mk);
143         }
144     }
145     lcount = 1;
146     if (Rhs == 2)
147     {
148         rval = do_xxprintf("fprintf", f, cstk(l2), Rhs, 2, lcount, (char **)0);
149     }
150     else while (1)
151         {
152             if ((rval = do_xxprintf("fprintf", f, cstk(l2), Rhs, 2, lcount, (char **)0)) < 0)
153             {
154                 break;
155             }
156             lcount++;
157             if (lcount > mx)
158             {
159                 break;
160             }
161         }
162     if (rval == RET_BUG)
163     {
164         return 0;
165     }
166     LhsVar(1) = 0; /** No return value **/
167     PutLhsVar();
168     return 0;
169 }
170 /*--------------------------------------------------------------------------*/