fix fullpath with wildcard in file part
[scilab.git] / scilab / modules / fileio / sci_gateway / cpp / sci_mopen.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2010-2010 - DIGITEO - Antoine ELIAS
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15
16 #include "string.hxx"
17 #include "double.hxx"
18 #include "function.hxx"
19 #include "filemanager.hxx"
20 #include "fileio_gw.hxx"
21
22 extern "C"
23 {
24 #include <PATH_MAX.h>
25 #include "Scierror.h"
26 #include "localization.h"
27 #include "expandPathVariable.h"
28 #include "mopen.h"
29 #include "charEncoding.h"
30 #include "sci_malloc.h"
31 #include "fullpath.h"
32 }
33
34 types::Function::ReturnValue sci_mopen(types::typed_list &in, int _iRetCount, types::typed_list &out)
35 {
36     int iErr                = 0;
37     int iID                 = 0;
38     wchar_t* pstFilename    = NULL;
39     const wchar_t* pstMode  = L"rb";
40     int iSwap               = 0;
41
42     //check output parameters
43     if (_iRetCount > 2)
44     {
45         Scierror(78, _("%s: Wrong number of output argument(s): %d to %d expected.\n"), "mopen", 1, 2);
46         return types::Function::Error;
47     }
48
49     //check input parameters
50     if (in.size() >= 1)
51     {
52         //filename
53         if (in[0]->isString() == false)
54         {
55             Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), "mopen", 1);
56             return types::Function::Error;
57         }
58
59         types::String* pS1 = in[0]->getAs<types::String>();
60         if (pS1->getSize() != 1)
61         {
62             Scierror(999, _("%s: Wrong size for input argument #%d: string expected.\n"), "mopen", 1);
63             return types::Function::Error;
64         }
65
66         pstFilename = expandPathVariableW(pS1->get(0));
67
68         if (in.size() >= 2)
69         {
70             //mode
71             if (in[1]->isString() == false)
72             {
73                 Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), "mopen", 2);
74                 FREE(pstFilename);
75                 return types::Function::Error;
76             }
77
78             types::String* pS2 = in[1]->getAs<types::String>();
79             if (pS2->getSize() != 1)
80             {
81                 Scierror(999, _("%s: Wrong size for input argument #%d: string expected.\n"), "mopen", 2);
82                 FREE(pstFilename);
83                 return types::Function::Error;
84             }
85
86             pstMode = pS2->get(0);
87
88             if (in.size() >= 3)
89             {
90                 //swap
91                 if (in[2]->isDouble() == false)
92                 {
93                     Scierror(999, _("%s: Wrong type for input argument #%d: An integer expected.\n"), "mopen", 3);
94                     FREE(pstFilename);
95                     return types::Function::Error;
96                 }
97
98                 types::Double* pD3 = in[2]->getAs<types::Double>();
99                 if (pD3->getSize() != 1 || pD3->isComplex())
100                 {
101                     Scierror(999, _("%s: Wrong size for input argument #%d: An integer expected.\n"), "mopen", 3);
102                     FREE(pstFilename);
103                     return types::Function::Error;
104                 }
105
106                 //if value == 0 set swap to 0 otherwise let to 1
107                 if (pD3->getReal(0, 0) == 0)
108                 {
109                     iSwap = 0;
110                 }
111
112                 if (in.size() >= 4)
113                 {
114                     Scierror(999, _("%s: Wrong number of input arguments: %d to %d expected.\n"), "mopen", 1, 3);
115                     FREE(pstFilename);
116                     return types::Function::Error;
117                 }
118
119             }
120         }
121     }
122     else
123     {
124         Scierror(999, _("%s: Wrong number of input arguments: %d to %d expected.\n"), "mopen", 1, 3);
125         return types::Function::Error;
126     }
127
128     wchar_t* pwstTemp = get_full_pathW(pstFilename);
129     iErr = mopen(pwstTemp, pstMode, iSwap, &iID);
130     if (iErr != MOPEN_NO_ERROR)
131     {
132         //mange file open errors
133         if (_iRetCount <= 1)
134         {
135             switch (iErr)
136             {
137                 case MOPEN_CAN_NOT_OPEN_FILE:
138                 {
139                     char* pst = wide_string_to_UTF8(pstFilename);
140                     Scierror(999, _("%s: Cannot open file %s.\n"), "mopen", pst);
141                     FREE(pst);
142                     FREE(pstFilename);
143                     FREE(pwstTemp);
144                     pstFilename = NULL;
145                     return types::Function::Error;
146                 }
147                 case MOPEN_INVALID_FILENAME:
148                 {
149                     Scierror(999, _("%s: invalid filename.\n"), "mopen");
150                     FREE(pstFilename);
151                     FREE(pwstTemp);
152                     pstFilename = NULL;
153                     return types::Function::Error;
154                 }
155                 case MOPEN_INVALID_STATUS:
156                 {
157                     Scierror(999, _("%s: invalid status.\n"), "mopen");
158                     FREE(pstFilename);
159                     FREE(pwstTemp);
160                     pstFilename = NULL;
161                     return types::Function::Error;
162                 }
163             }
164         }
165     }
166
167     FREE(pwstTemp);
168     FREE(pstFilename);
169
170     types::Double* pD = new types::Double(static_cast<double>(iID));
171     out.push_back(pD);
172
173     if (_iRetCount == 2)
174     {
175         types::Double* pD2 = new types::Double(iErr);
176         out.push_back(pD2);
177     }
178     return types::Function::OK;
179 }