expandPathVariable must return 'longpathname version' of scilab variables
[scilab.git] / scilab / modules / fileio / src / cpp / expandPathVariable.cpp
1 /*--------------------------------------------------------------------------*/
2 /*
3 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
4 * Copyright (C) 2009 - DIGITEO - Allan CORNET
5 *
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14 *
15 */
16 /*--------------------------------------------------------------------------*/
17
18 #include <wchar.h>
19 #include "context.hxx"
20 #include "string.hxx"
21 #include "expandPathVariable.h"
22
23 extern "C"
24 {
25 #include "charEncoding.h"
26 #include "sci_malloc.h"
27 #include "PATH_MAX.h"
28 #include "api_scilab.h"
29 #include "getlongpathname.h"
30 #include "os_string.h"
31 }
32
33
34
35 /*--------------------------------------------------------------------------*/
36 struct VARIABLEALIAS
37 {
38     const wchar_t *Alias;
39     const wchar_t *VariableName;
40     symbol::Variable* var;
41 };
42 /*--------------------------------------------------------------------------*/
43 #define NB_ALIAS 7
44 static struct VARIABLEALIAS VARIABLES_words[NB_ALIAS] =
45 {
46     {L"SCIHOME", L"SCIHOME", NULL},
47     {L"WSCI", L"WSCI", NULL},
48     {L"SCI", L"SCI", NULL},
49     {L"~", L"home", NULL},
50     {L"HOME", L"home", NULL},
51     {L"home", L"home", NULL},
52     {L"TMPDIR", L"TMPDIR", NULL}
53 };
54 /*--------------------------------------------------------------------------*/
55 static wchar_t *getVariableValueDefinedInScilab(VARIABLEALIAS* var);
56 static wchar_t *convertFileSeparators(wchar_t *wcStr);
57 /*--------------------------------------------------------------------------*/
58 wchar_t *expandPathVariableW(const wchar_t *wcstr)
59 {
60     wchar_t *wcexpanded = NULL;
61     if (wcstr)
62     {
63         int i = 0;
64         int lenStr = (int)wcslen(wcstr);
65
66         for (i = 0; i < NB_ALIAS; i++)
67         {
68             int lenAlias = 0;
69
70             /* input is ALIAS without subdirectory */
71             if (wcscmp(VARIABLES_words[i].Alias, wcstr) == 0)
72             {
73                 wchar_t *wcexpanded = getVariableValueDefinedInScilab(&VARIABLES_words[i]);
74                 if (wcexpanded)
75                 {
76                     return convertFileSeparators(wcexpanded);
77                 }
78             }
79
80             lenAlias = (int)wcslen(VARIABLES_words[i].Alias);
81
82             if (lenStr > lenAlias)
83             {
84                 wchar_t *wcBegin = (wchar_t *)MALLOC(sizeof(wchar_t) * (lenAlias + 1));
85                 if (wcBegin)
86                 {
87                     wcsncpy(wcBegin, wcstr, lenAlias);
88                     wcBegin[lenAlias] = 0;
89
90                     if (wcscmp(wcBegin, VARIABLES_words[i].Alias) == 0 )
91                     {
92                         if ( (wcstr[lenAlias] == L'/') || (wcstr[lenAlias] == L'\\') )
93                         {
94                             wchar_t * newBegin = getVariableValueDefinedInScilab(&VARIABLES_words[i]);
95                             if (newBegin)
96                             {
97                                 int lengthnewBegin = (int)wcslen(newBegin);
98                                 wcexpanded = (wchar_t *)MALLOC(sizeof(wchar_t) * (lengthnewBegin + (int)wcslen(&wcstr[lenAlias]) + 1));
99                                 if (wcexpanded)
100                                 {
101                                     wcscpy(wcexpanded, newBegin);
102                                     wcscat(wcexpanded, &wcstr[lenAlias]);
103                                     FREE(wcBegin);
104                                     wcBegin = NULL;
105                                     free(newBegin);
106                                     newBegin = NULL;
107                                     return convertFileSeparators(wcexpanded);
108                                 }
109                                 FREE(newBegin);
110                                 newBegin = NULL;
111                             }
112                         }
113                     }
114                     FREE(wcBegin);
115                     wcBegin = NULL;
116                 }
117             }
118         }
119
120         /* Variables not founded returns a copy of input */
121         wcexpanded = (wchar_t*)MALLOC(sizeof(wchar_t) * ((int)wcslen(wcstr) + 1));
122         if (wcexpanded)
123         {
124             wcscpy(wcexpanded, wcstr);
125             return convertFileSeparators(wcexpanded);
126         }
127     }
128     return wcexpanded;
129 }
130 /*--------------------------------------------------------------------------*/
131 char *expandPathVariable(const char* str)
132 {
133     char *expanded = NULL;
134     wchar_t *wstr = to_wide_string(str);
135
136     if (wstr)
137     {
138         wchar_t *wcexpanded = expandPathVariableW(wstr);
139         if (wcexpanded)
140         {
141             expanded = wide_string_to_UTF8(wcexpanded);
142             FREE(wcexpanded);
143             wcexpanded = NULL;
144         }
145         FREE(wstr);
146         wstr = NULL;
147     }
148     return expanded;
149 }
150 /*--------------------------------------------------------------------------*/
151 wchar_t *getVariableValueDefinedInScilab(VARIABLEALIAS* _var)
152 {
153     if (_var)
154     {
155         if (_var->var == NULL)
156         {
157             _var->var = symbol::Context::getInstance()->getOrCreate(symbol::Symbol(_var->VariableName));
158         }
159
160         types::InternalType *pIT = _var->var->get();
161         if (pIT == NULL || pIT->isString() == false)
162         {
163             return NULL;
164         }
165
166         BOOL bConvLong = FALSE;
167         types::String* pS = pIT->getAs<types::String>();
168         return getlongpathnameW( pS->get(0), &bConvLong);
169     }
170     return NULL;
171 }
172 /*--------------------------------------------------------------------------*/
173 void resetVariableValueDefinedInScilab(void)
174 {
175     for (int i = 0; i < NB_ALIAS; i++)
176     {
177         VARIABLES_words[i].var = NULL;
178     }
179 }
180 /*--------------------------------------------------------------------------*/
181 wchar_t *convertFileSeparators(wchar_t *wcStr)
182 {
183     if (wcStr)
184     {
185         int k = 0;
186         int len = (int)wcslen(wcStr);
187
188 #ifdef _MSC_VER
189         for (k = 0 ; k < len ; k++) if (wcStr[k] == L'/')
190             {
191                 wcStr[k] = L'\\';
192             }
193 #else
194         for (k = 0 ; k < len ; k++) if (wcStr[k] == L'\\')
195             {
196                 wcStr[k] = L'/';
197             }
198 #endif
199     }
200     return wcStr;
201 }
202 /*--------------------------------------------------------------------------*/