]> git.lyx.org Git - lyx.git/blob - src/support/os.cpp
Detect the correct version of python at runtime and store the result
[lyx.git] / src / support / os.cpp
1 /**
2  * \file os.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Ruurd A. Reitsma
7  * \author Enrico Forestieri
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "filetools.h"
15 #include "qstring_helpers.h"
16
17 #include <QDir>
18
19 #if defined(__CYGWIN__)
20 #include "support/os_cygwin.cpp"
21 #elif defined(_WIN32)
22 #include "support/os_win32.cpp"
23 #else
24 #include "support/os_unix.cpp"
25 #endif
26
27 // Static assert to break compilation on platforms where
28 // int/unsigned int is not 4 bytes. Added to make sure that
29 // e.g., the author hash is always 32-bit.
30 template<bool Condition> struct static_assert_helper;
31 template <> struct static_assert_helper<true> {};
32 enum { 
33         dummy = sizeof(static_assert_helper<sizeof(int) == 4>)
34 };
35
36 namespace lyx {
37 namespace support {
38 namespace os {
39
40 static string const python2(string const & binary, bool verbose = false)
41 {
42         if (verbose)
43                 lyxerr << "Examining " << binary << "\n";
44
45         // Check whether this is a python 2 binary.
46         cmd_ret const out = runCommand(binary + " -V 2>&1");
47         if (out.first < 0 || !prefixIs(out.second, "Python 2"))
48                 return string();
49
50         if (verbose)
51                 lyxerr << "Found " << out.second << "\n";
52         return binary;
53 }
54
55
56 string const python()
57 {
58         // Check whether the first python in PATH is the right one.
59         static string command = python2("python -tt");
60
61         if (command.empty()) {
62                 // It was not, so check whether we can find it elsewhere in
63                 // PATH, maybe with some suffix appended.
64                 vector<string> const path = getEnvPath("PATH");
65                 vector<string>::const_iterator it = path.begin();
66                 vector<string>::const_iterator const end = path.end();
67                 lyxerr << "Looking for python v2.x ...\n";
68                 for (; it != end; ++it) {
69                         QString const dir = toqstr(*it);
70                         string const localdir = dir.toLocal8Bit().constData();
71                         QDir qdir(dir);
72                         qdir.setFilter(QDir::Files | QDir::Executable);
73                         QStringList list = qdir.entryList(QStringList("python*"));
74                         for (int i = 0; i < list.size() && command.empty(); ++i) {
75                                 string const binary = addName(localdir,
76                                         list.at(i).toLocal8Bit().constData());
77                                 command = python2(binary, true);
78                         }
79                 }
80
81                 // Default to "python" if no usable binary was found.
82                 if (command.empty()) {
83                         lyxerr << "Warning: No python v2.x binary found.\n";
84                         command = "python";
85                 }
86
87                 // Add the -tt switch so that mixed tab/whitespace
88                 // indentation is an error
89                 command += " -tt";
90         }
91         return command;
92 }
93
94 }
95 }
96 }