1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
24 #define WIN32_LEAN_AND_MEAN
26 #pragma warning(push, 1)
33 #include "tools/pathutils.hxx"
35 #define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1)
36 #define MY_STRING(s) (s), MY_LENGTH(s)
38 wchar_t * encode(wchar_t * buffer
, wchar_t const * text
) {
45 } else if (c
== L
'"') {
46 // Double any preceding backslashes as required by Windows:
47 for (std::size_t i
= 0; i
< n
; ++i
) {
53 } else if (c
== L
'\\') {
61 // The command line will continue with a double quote, so double any
62 // preceding backslashes as required by Windows:
63 for (std::size_t i
= 0; i
< n
; ++i
) {
71 int main(int argc
, char ** argv
, char **) {
73 int wmain(int argc
, wchar_t ** argv
, wchar_t **) {
75 wchar_t path
[MAX_PATH
];
76 DWORD n
= GetModuleFileNameW(NULL
, path
, MAX_PATH
);
77 if (n
== 0 || n
>= MAX_PATH
) {
80 wchar_t * pathEnd
= tools::filename(path
);
82 n
= GetEnvironmentVariableW(L
"UNO_PATH", NULL
, 0);
84 if (GetLastError() != ERROR_ENVVAR_NOT_FOUND
||
85 !SetEnvironmentVariableW(L
"UNO_PATH", path
))
90 wchar_t bootstrap
[MY_LENGTH(L
"vnd.sun.star.pathname:") + MAX_PATH
] =
91 L
"vnd.sun.star.pathname:"; //TODO: overflow
92 wchar_t * bootstrapEnd
= tools::buildPath(
93 bootstrap
+ MY_LENGTH(L
"vnd.sun.star.pathname:"), path
, pathEnd
,
94 MY_STRING(L
"fundamental.ini"));
95 if (bootstrapEnd
== NULL
) {
98 wchar_t pythonpath2
[MAX_PATH
];
99 wchar_t * pythonpath2End
= tools::buildPath(
100 pythonpath2
, path
, pathEnd
,
101 MY_STRING(L
"\\python-core-" MY_PYVERSION L
"\\lib"));
102 if (pythonpath2End
== NULL
) {
105 wchar_t pythonpath3
[MAX_PATH
];
106 wchar_t * pythonpath3End
= tools::buildPath(
107 pythonpath3
, path
, pathEnd
,
108 MY_STRING(L
"\\python-core-" MY_PYVERSION L
"\\lib\\site-packages"));
109 if (pythonpath3End
== NULL
) {
113 wchar_t pythonpath4
[MAX_PATH
];
114 wchar_t * pythonpath4End
= tools::buildPath(
115 pythonpath4
, path
, pathEnd
,
116 MY_STRING(L
"\\python-core-" MY_PYVERSION L
"\\lib\\lib-dynload"));
117 if (pythonpath4End
== NULL
) {
121 wchar_t pythonhome
[MAX_PATH
];
122 wchar_t * pythonhomeEnd
= tools::buildPath(
123 pythonhome
, path
, pathEnd
, MY_STRING(L
"\\python-core-" MY_PYVERSION
));
124 if (pythonhomeEnd
== NULL
) {
127 wchar_t pythonexe
[MAX_PATH
];
128 wchar_t * pythonexeEnd
= tools::buildPath(
129 pythonexe
, path
, pathEnd
,
130 MY_STRING(L
"\\python-core-" MY_PYVERSION L
"\\bin\\python.exe"));
131 if (pythonexeEnd
== NULL
) {
134 wchar_t urepath
[MAX_PATH
];
135 if (tools::buildPath(urepath
, path
, pathEnd
, MY_STRING(L
"..\\ure-link"))
140 wchar_t * urepathEnd
= tools::resolveLink(urepath
);
141 if (urepathEnd
== NULL
) {
144 urepathEnd
= tools::buildPath(
145 urepath
, urepath
, urepathEnd
, MY_STRING(L
"\\bin"));
146 if (urepathEnd
== NULL
) {
149 std::size_t clSize
= MY_LENGTH(L
"\"") + 4 * (pythonexeEnd
- pythonexe
) +
150 MY_LENGTH(L
"\"\0"); //TODO: overflow
151 // 4 * len: each char preceded by backslash, each trailing backslash
153 for (int i
= 1; i
< argc
; ++i
) {
155 clSize
+= MY_LENGTH(L
" \"") + 4 * strlen(argv
[i
]) +
157 clSize
+= MY_LENGTH(L
" \"") + 4 * wcslen(argv
[i
]) +
159 MY_LENGTH(L
"\""); //TODO: overflow
161 wchar_t * cl
= new wchar_t[clSize
];
165 wchar_t * cp
= encode(cl
, pythonhome
);
166 for (int i
= 1; i
< argc
; ++i
) {
169 int nNeededWStrBuffSize
= MultiByteToWideChar(CP_ACP
, 0, argv
[i
], -1, NULL
, 0);
170 WCHAR
*buff
= new WCHAR
[nNeededWStrBuffSize
+1];
171 MultiByteToWideChar(CP_ACP
, 0, argv
[i
], -1, buff
, nNeededWStrBuffSize
);
172 buff
[nNeededWStrBuffSize
] = 0;
173 cp
= encode(cp
, buff
);
176 cp
= encode(cp
, argv
[i
]);
180 n
= GetEnvironmentVariableW(L
"PATH", NULL
, 0);
183 if (GetLastError() != ERROR_ENVVAR_NOT_FOUND
) {
188 orig
= new wchar_t[n
];
190 GetEnvironmentVariableW(L
"PATH", orig
, n
) != n
- 1)
195 std::size_t len
= (urepathEnd
- urepath
) + MY_LENGTH(L
";") +
196 (pathEnd
- path
) + (n
== 0 ? 0 : MY_LENGTH(L
";") + (n
- 1)) + 1;
198 wchar_t * value
= new wchar_t[len
];
200 value
, len
, L
"%s;%s%s%s", urepath
, path
, n
== 0 ? L
"" : L
";", orig
);
201 if (!SetEnvironmentVariableW(L
"PATH", value
)) {
208 n
= GetEnvironmentVariableW(L
"PYTHONPATH", NULL
, 0);
210 if (GetLastError() != ERROR_ENVVAR_NOT_FOUND
) {
215 orig
= new wchar_t[n
];
217 GetEnvironmentVariableW(L
"PYTHONPATH", orig
, n
) != n
- 1)
223 len
= (pathEnd
- path
) + MY_LENGTH(L
";") + (pythonpath2End
- pythonpath2
) +
224 MY_LENGTH(L
";") + (pythonpath4End
- pythonpath4
) +
225 MY_LENGTH(L
";") + (pythonpath3End
- pythonpath3
) +
226 (n
== 0 ? 0 : MY_LENGTH(L
";") + (n
- 1)) + 1; //TODO: overflow
227 value
= new wchar_t[len
];
229 value
, len
, L
"%s;%s;%s;%s%s%s", path
, pythonpath2
, pythonpath4
,
230 pythonpath3
, n
== 0 ? L
"" : L
";", orig
);
232 len
= (pathEnd
- path
) + MY_LENGTH(L
";") + (pythonpath2End
- pythonpath2
) +
233 MY_LENGTH(L
";") + (pythonpath3End
- pythonpath3
) +
234 (n
== 0 ? 0 : MY_LENGTH(L
";") + (n
- 1)) + 1; //TODO: overflow
235 value
= new wchar_t[len
];
237 value
, len
, L
"%s;%s;%s%s%s", path
, pythonpath2
, pythonpath3
,
238 n
== 0 ? L
"" : L
";", orig
);
240 if (!SetEnvironmentVariableW(L
"PYTHONPATH", value
)) {
247 if (!SetEnvironmentVariableW(L
"PYTHONHOME", pythonhome
)) {
250 n
= GetEnvironmentVariableW(L
"URE_BOOTSTRAP", NULL
, 0);
252 if (GetLastError() != ERROR_ENVVAR_NOT_FOUND
||
253 !SetEnvironmentVariableW(L
"URE_BOOTSTRAP", bootstrap
))
258 STARTUPINFOW startinfo
;
259 ZeroMemory(&startinfo
, sizeof (STARTUPINFOW
));
260 startinfo
.cb
= sizeof (STARTUPINFOW
);
261 PROCESS_INFORMATION procinfo
;
263 pythonexe
, cl
, NULL
, NULL
, FALSE
, CREATE_UNICODE_ENVIRONMENT
, NULL
,
264 NULL
, &startinfo
, &procinfo
)) {
267 WaitForSingleObject(procinfo
.hProcess
,INFINITE
);
269 GetExitCodeProcess(procinfo
.hProcess
,&exitStatus
);
273 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */