fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / pyuno / zipcore / python.cxx
blob2d090fc6d07dea98b6318d5b4cde7d8cd7aeb5db
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <cstddef>
21 #include <stdlib.h>
22 #include <wchar.h>
24 #define WIN32_LEAN_AND_MEAN
25 #if defined _MSC_VER
26 #pragma warning(push, 1)
27 #endif
28 #include <windows.h>
29 #if defined _MSC_VER
30 #pragma warning(pop)
31 #endif
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) {
39 *buffer++ = L'"';
40 std::size_t n = 0;
41 for (;;) {
42 wchar_t c = *text++;
43 if (c == L'\0') {
44 break;
45 } else if (c == L'"') {
46 // Double any preceding backslashes as required by Windows:
47 for (std::size_t i = 0; i < n; ++i) {
48 *buffer++ = L'\\';
50 *buffer++ = L'\\';
51 *buffer++ = L'"';
52 n = 0;
53 } else if (c == L'\\') {
54 *buffer++ = L'\\';
55 ++n;
56 } else {
57 *buffer++ = c;
58 n = 0;
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) {
64 *buffer++ = L'\\';
66 *buffer++ = L'"';
67 return buffer;
70 #ifdef __MINGW32__
71 int main(int argc, char ** argv, char **) {
72 #else
73 int wmain(int argc, wchar_t ** argv, wchar_t **) {
74 #endif
75 wchar_t path[MAX_PATH];
76 DWORD n = GetModuleFileNameW(NULL, path, MAX_PATH);
77 if (n == 0 || n >= MAX_PATH) {
78 exit(EXIT_FAILURE);
80 wchar_t * pathEnd = tools::filename(path);
81 *pathEnd = L'\0';
82 n = GetEnvironmentVariableW(L"UNO_PATH", NULL, 0);
83 if (n == 0) {
84 if (GetLastError() != ERROR_ENVVAR_NOT_FOUND ||
85 !SetEnvironmentVariableW(L"UNO_PATH", path))
87 exit(EXIT_FAILURE);
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) {
96 exit(EXIT_FAILURE);
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) {
103 exit(EXIT_FAILURE);
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) {
110 exit(EXIT_FAILURE);
112 #ifdef __MINGW32__
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) {
118 exit(EXIT_FAILURE);
120 #endif
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) {
125 exit(EXIT_FAILURE);
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) {
132 exit(EXIT_FAILURE);
134 wchar_t urepath[MAX_PATH];
135 if (tools::buildPath(urepath, path, pathEnd, MY_STRING(L"..\\ure-link"))
136 == NULL)
138 exit(EXIT_FAILURE);
140 wchar_t * urepathEnd = tools::resolveLink(urepath);
141 if (urepathEnd == NULL) {
142 exit(EXIT_FAILURE);
144 urepathEnd = tools::buildPath(
145 urepath, urepath, urepathEnd, MY_STRING(L"\\bin"));
146 if (urepathEnd == NULL) {
147 exit(EXIT_FAILURE);
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
152 // doubled
153 for (int i = 1; i < argc; ++i) {
154 #ifdef __MINGW32__
155 clSize += MY_LENGTH(L" \"") + 4 * strlen(argv[i]) +
156 #else
157 clSize += MY_LENGTH(L" \"") + 4 * wcslen(argv[i]) +
158 #endif
159 MY_LENGTH(L"\""); //TODO: overflow
161 wchar_t * cl = new wchar_t[clSize];
162 if (cl == NULL) {
163 exit(EXIT_FAILURE);
165 wchar_t * cp = encode(cl, pythonhome);
166 for (int i = 1; i < argc; ++i) {
167 *cp++ = L' ';
168 #ifdef __MINGW32__
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);
174 delete [] buff;
175 #else
176 cp = encode(cp, argv[i]);
177 #endif
179 *cp = L'\0';
180 n = GetEnvironmentVariableW(L"PATH", NULL, 0);
181 wchar_t * orig;
182 if (n == 0) {
183 if (GetLastError() != ERROR_ENVVAR_NOT_FOUND) {
184 exit(EXIT_FAILURE);
186 orig = L"";
187 } else {
188 orig = new wchar_t[n];
189 if (orig == NULL ||
190 GetEnvironmentVariableW(L"PATH", orig, n) != n - 1)
192 exit(EXIT_FAILURE);
195 std::size_t len = (urepathEnd - urepath) + MY_LENGTH(L";") +
196 (pathEnd - path) + (n == 0 ? 0 : MY_LENGTH(L";") + (n - 1)) + 1;
197 //TODO: overflow
198 wchar_t * value = new wchar_t[len];
199 _snwprintf(
200 value, len, L"%s;%s%s%s", urepath, path, n == 0 ? L"" : L";", orig);
201 if (!SetEnvironmentVariableW(L"PATH", value)) {
202 exit(EXIT_FAILURE);
204 if (n != 0) {
205 delete [] orig;
207 delete [] value;
208 n = GetEnvironmentVariableW(L"PYTHONPATH", NULL, 0);
209 if (n == 0) {
210 if (GetLastError() != ERROR_ENVVAR_NOT_FOUND) {
211 exit(EXIT_FAILURE);
213 orig = L"";
214 } else {
215 orig = new wchar_t[n];
216 if (orig == NULL ||
217 GetEnvironmentVariableW(L"PYTHONPATH", orig, n) != n - 1)
219 exit(EXIT_FAILURE);
222 #ifdef __MINGW32__
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];
228 _snwprintf(
229 value, len, L"%s;%s;%s;%s%s%s", path, pythonpath2, pythonpath4,
230 pythonpath3, n == 0 ? L"" : L";", orig);
231 #else
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];
236 _snwprintf(
237 value, len, L"%s;%s;%s%s%s", path, pythonpath2, pythonpath3,
238 n == 0 ? L"" : L";", orig);
239 #endif
240 if (!SetEnvironmentVariableW(L"PYTHONPATH", value)) {
241 exit(EXIT_FAILURE);
243 if (n != 0) {
244 delete [] orig;
246 delete [] value;
247 if (!SetEnvironmentVariableW(L"PYTHONHOME", pythonhome)) {
248 exit(EXIT_FAILURE);
250 n = GetEnvironmentVariableW(L"URE_BOOTSTRAP", NULL, 0);
251 if (n == 0) {
252 if (GetLastError() != ERROR_ENVVAR_NOT_FOUND ||
253 !SetEnvironmentVariableW(L"URE_BOOTSTRAP", bootstrap))
255 exit(EXIT_FAILURE);
258 STARTUPINFOW startinfo;
259 ZeroMemory(&startinfo, sizeof (STARTUPINFOW));
260 startinfo.cb = sizeof (STARTUPINFOW);
261 PROCESS_INFORMATION procinfo;
262 if (!CreateProcessW(
263 pythonexe, cl, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT, NULL,
264 NULL, &startinfo, &procinfo)) {
265 exit(EXIT_FAILURE);
267 WaitForSingleObject(procinfo.hProcess,INFINITE);
268 DWORD exitStatus;
269 GetExitCodeProcess(procinfo.hProcess,&exitStatus);
270 exit(exitStatus);
273 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */