Update ooo320-m1
[ooovba.git] / pyuno / zipcore / python.cxx
blobbec3529e36f2e3b357c21d0dd6bc7751b48b8329
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: python.cxx,v $
10 * $Revision: 1.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include <cstddef>
32 #include <stdlib.h>
33 #include <wchar.h>
35 #define WIN32_LEAN_AND_MEAN
36 #if defined _MSC_VER
37 #pragma warning(push, 1)
38 #endif
39 #include <windows.h>
40 #if defined _MSC_VER
41 #pragma warning(pop)
42 #endif
44 #include "tools/pathutils.hxx"
46 #include "pyversion.hxx"
48 #define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1)
49 #define MY_STRING(s) (s), MY_LENGTH(s)
51 wchar_t * encode(wchar_t * buffer, wchar_t const * text) {
52 *buffer++ = L'"';
53 std::size_t n = 0;
54 for (;;) {
55 wchar_t c = *text++;
56 if (c == L'\0') {
57 break;
58 } else if (c == L'"') {
59 // Double any preceding backslashes as required by Windows:
60 for (std::size_t i = 0; i < n; ++i) {
61 *buffer++ = L'\\';
63 *buffer++ = L'\\';
64 *buffer++ = L'"';
65 n = 0;
66 } else if (c == L'\\') {
67 *buffer++ = L'\\';
68 ++n;
69 } else {
70 *buffer++ = c;
71 n = 0;
74 // The command line will continue with a double quote, so double any
75 // preceding backslashes as required by Windows:
76 for (std::size_t i = 0; i < n; ++i) {
77 *buffer++ = L'\\';
79 *buffer++ = L'"';
80 return buffer;
83 #ifdef __MINGW32__
84 int main(int argc, char ** argv, char **) {
85 #else
86 int wmain(int argc, wchar_t ** argv, wchar_t **) {
87 #endif
88 wchar_t path[MAX_PATH];
89 DWORD n = GetModuleFileNameW(NULL, path, MAX_PATH);
90 if (n == 0 || n >= MAX_PATH) {
91 exit(EXIT_FAILURE);
93 wchar_t * pathEnd = tools::filename(path);
94 *pathEnd = L'\0';
95 n = GetEnvironmentVariableW(L"UNO_PATH", NULL, 0);
96 if (n == 0) {
97 if (GetLastError() != ERROR_ENVVAR_NOT_FOUND ||
98 !SetEnvironmentVariableW(L"UNO_PATH", path))
100 exit(EXIT_FAILURE);
103 wchar_t bootstrap[MY_LENGTH(L"vnd.sun.star.pathname:") + MAX_PATH] =
104 L"vnd.sun.star.pathname:"; //TODO: overflow
105 wchar_t * bootstrapEnd = tools::buildPath(
106 bootstrap + MY_LENGTH(L"vnd.sun.star.pathname:"), path, pathEnd,
107 MY_STRING(L"fundamental.ini"));
108 if (bootstrapEnd == NULL ||
109 (tools::buildPath(path, path, pathEnd, MY_STRING(L"..\\basis-link"))
110 == NULL))
112 exit(EXIT_FAILURE);
114 pathEnd = tools::resolveLink(path);
115 wchar_t path1[MAX_PATH];
116 wchar_t * path1End = tools::buildPath(
117 path1, path, pathEnd, MY_STRING(L"\\program"));
118 if (path1End == NULL) {
119 exit(EXIT_FAILURE);
121 wchar_t pythonpath2[MAX_PATH];
122 wchar_t * pythonpath2End = tools::buildPath(
123 pythonpath2, path, pathEnd,
124 MY_STRING(L"\\program\\python-core-" MY_PYVERSION L"\\lib"));
125 if (pythonpath2End == NULL) {
126 exit(EXIT_FAILURE);
128 wchar_t pythonpath3[MAX_PATH];
129 wchar_t * pythonpath3End = tools::buildPath(
130 pythonpath3, path, pathEnd,
131 MY_STRING(
132 L"\\program\\python-core-" MY_PYVERSION L"\\lib\\site-packages"));
133 if (pythonpath3End == NULL) {
134 exit(EXIT_FAILURE);
136 #ifdef __MINGW32__
137 wchar_t pythonpath4[MAX_PATH];
138 wchar_t * pythonpath4End = tools::buildPath(
139 pythonpath4, path, pathEnd,
140 MY_STRING(L"\\program\\python-core-" MY_PYVERSION L"\\lib\\lib-dynload"));
141 if (pythonpath4End == NULL) {
142 exit(EXIT_FAILURE);
144 wchar_t pythonpath5[MAX_PATH];
145 wchar_t * pythonpath5End = tools::buildPath(
146 pythonpath5, path, pathEnd,
147 MY_STRING(L"\\program\\python-core-" MY_PYVERSION L"\\lib\\lib-dynload"));
148 if (pythonpath5End == NULL) {
149 exit(EXIT_FAILURE);
151 #endif
152 wchar_t pythonhome[MAX_PATH];
153 wchar_t * pythonhomeEnd = tools::buildPath(
154 pythonhome, path, pathEnd,
155 MY_STRING(L"\\program\\python-core-" MY_PYVERSION));
156 if (pythonhomeEnd == NULL) {
157 exit(EXIT_FAILURE);
159 wchar_t pythonexe[MAX_PATH];
160 wchar_t * pythonexeEnd = tools::buildPath(
161 pythonexe, path, pathEnd,
162 #ifdef __MINGW32__
163 MY_STRING(
164 L"\\program\\python-core-" MY_PYVERSION L"\\bin\\python.bin"));
165 #else
166 MY_STRING(
167 L"\\program\\python-core-" MY_PYVERSION L"\\bin\\python.exe"));
168 #endif
169 if (pythonexeEnd == NULL) {
170 exit(EXIT_FAILURE);
172 if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\ure-link")) == NULL)
174 exit(EXIT_FAILURE);
176 pathEnd = tools::resolveLink(path);
177 if (pathEnd == NULL) {
178 exit(EXIT_FAILURE);
180 pathEnd = tools::buildPath(path, path, pathEnd, MY_STRING(L"\\bin"));
181 if (pathEnd == NULL) {
182 exit(EXIT_FAILURE);
184 std::size_t clSize = MY_LENGTH(L"\"") + 4 * (pythonexeEnd - pythonexe) +
185 MY_LENGTH(L"\"\0"); //TODO: overflow
186 // 4 * len: each char preceded by backslash, each trailing backslash
187 // doubled
188 for (int i = 1; i < argc; ++i) {
189 #ifdef __MINGW32__
190 clSize += MY_LENGTH(L" \"") + 4 * strlen(argv[i]) +
191 #else
192 clSize += MY_LENGTH(L" \"") + 4 * wcslen(argv[i]) +
193 #endif
194 MY_LENGTH(L"\""); //TODO: overflow
196 wchar_t * cl = new wchar_t[clSize];
197 if (cl == NULL) {
198 exit(EXIT_FAILURE);
200 wchar_t * cp = encode(cl, pythonhome);
201 for (int i = 1; i < argc; ++i) {
202 *cp++ = L' ';
203 #ifdef __MINGW32__
204 int nNeededWStrBuffSize = MultiByteToWideChar(CP_ACP, 0, argv[i], -1, NULL, 0);
205 WCHAR *buff = new WCHAR[nNeededWStrBuffSize+1];
206 MultiByteToWideChar(CP_ACP, 0, argv[i], -1, buff, nNeededWStrBuffSize);
207 buff[nNeededWStrBuffSize] = 0;
208 cp = encode(cp, buff);
209 delete buff;
210 #else
211 cp = encode(cp, argv[i]);
212 #endif
214 *cp = L'\0';
215 n = GetEnvironmentVariableW(L"PATH", NULL, 0);
216 wchar_t * orig;
217 if (n == 0) {
218 if (GetLastError() != ERROR_ENVVAR_NOT_FOUND) {
219 exit(EXIT_FAILURE);
221 orig = L"";
222 } else {
223 orig = new wchar_t[n];
224 if (orig == NULL ||
225 GetEnvironmentVariableW(L"PATH", orig, n) != n - 1)
227 exit(EXIT_FAILURE);
230 wchar_t * value = new wchar_t[
231 (pathEnd - path) + MY_LENGTH(L";") + (path1End - path1) +
232 (n == 0 ? 0 : MY_LENGTH(L";") + (n - 1)) + 1]; //TODO: overflow
233 wsprintfW(value, L"%s;%s%s%s", path, path1, n == 0 ? L"" : L";", orig);
234 if (!SetEnvironmentVariableW(L"PATH", value)) {
235 exit(EXIT_FAILURE);
237 if (n != 0) {
238 delete orig;
240 delete value;
241 n = GetEnvironmentVariableW(L"PYTHONPATH", NULL, 0);
242 if (n == 0) {
243 if (GetLastError() != ERROR_ENVVAR_NOT_FOUND) {
244 exit(EXIT_FAILURE);
246 orig = L"";
247 } else {
248 orig = new wchar_t[n];
249 if (orig == NULL ||
250 GetEnvironmentVariableW(L"PYTHONPATH", orig, n) != n - 1)
252 exit(EXIT_FAILURE);
255 #ifdef __MINGW32__
256 value = new wchar_t[
257 (path1End - path1) + MY_LENGTH(L";") + (pythonpath2End - pythonpath2) +
258 MY_LENGTH(L";") + (pythonpath4End - pythonpath4) +
259 MY_LENGTH(L";") + (pythonpath5End - pythonpath5) +
260 MY_LENGTH(L";") + (pythonpath3End - pythonpath3) +
261 (n == 0 ? 0 : MY_LENGTH(L";") + (n - 1)) + 1]; //TODO: overflow
262 wsprintfW(
263 value, L"%s;%s;%s;%s;%s%s%s", path1, pythonpath2, pythonpath4,
264 pythonpath5, pythonpath3,
265 n == 0 ? L"" : L";", orig);
266 #else
267 value = new wchar_t[
268 (path1End - path1) + MY_LENGTH(L";") + (pythonpath2End - pythonpath2) +
269 MY_LENGTH(L";") + (pythonpath3End - pythonpath3) +
270 (n == 0 ? 0 : MY_LENGTH(L";") + (n - 1)) + 1]; //TODO: overflow
271 wsprintfW(
272 value, L"%s;%s;%s%s%s", path1, pythonpath2, pythonpath3,
273 n == 0 ? L"" : L";", orig);
274 #endif
275 if (!SetEnvironmentVariableW(L"PYTHONPATH", value)) {
276 exit(EXIT_FAILURE);
278 if (n != 0) {
279 delete orig;
281 delete value;
282 if (!SetEnvironmentVariableW(L"PYTHONHOME", pythonhome)) {
283 exit(EXIT_FAILURE);
285 n = GetEnvironmentVariableW(L"URE_BOOTSTRAP", NULL, 0);
286 if (n == 0) {
287 if (GetLastError() != ERROR_ENVVAR_NOT_FOUND ||
288 !SetEnvironmentVariableW(L"URE_BOOTSTRAP", bootstrap))
290 exit(EXIT_FAILURE);
293 STARTUPINFOW startinfo;
294 ZeroMemory(&startinfo, sizeof (STARTUPINFOW));
295 startinfo.cb = sizeof (STARTUPINFOW);
296 PROCESS_INFORMATION procinfo;
297 if (!CreateProcessW(
298 pythonexe, cl, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT, NULL,
299 NULL, &startinfo, &procinfo)) {
300 exit(EXIT_FAILURE);
302 WaitForSingleObject(procinfo.hProcess,INFINITE);
303 DWORD exitStatus;
304 GetExitCodeProcess(procinfo.hProcess,&exitStatus);
305 exit(exitStatus);