eOn client
Long-timescale dynamics: aKMC, NEB, parallel replica
☾
Toggle main menu visibility
Loading...
Searching...
No Matches
ExtPotCommand.h
Go to the documentation of this file.
1
/*
2
** This file is part of eOn.
3
**
4
** SPDX-License-Identifier: BSD-3-Clause
5
**
6
** Copyright (c) 2010--present, eOn Development Team
7
** All rights reserved.
8
**
9
** Repo:
10
** https://github.com/TheochemUI/eOn
11
*/
12
#pragma once
13
14
#include <cctype>
15
#include <filesystem>
16
#include <fstream>
17
#include <string>
18
#include <string_view>
19
#include <system_error>
20
21
namespace
eonc::pot
{
22
25
inline
std::string
shellQuote
(
const
std::string &text) {
26
#ifdef _WIN32
27
// cmd.exe takes double quotes and offers no escape for an embedded one,
28
// which a Windows path cannot hold anyway.
29
return
"\""
+ text +
"\""
;
30
#else
31
std::string quoted{
"'"
};
32
for
(
const
char
c : text) {
33
if
(c ==
'\''
) {
34
quoted +=
"'\\''"
;
35
}
else
{
36
quoted += c;
37
}
38
}
39
quoted +=
"'"
;
40
return
quoted;
41
#endif
42
}
43
48
inline
std::string
shebangInterpreter
(
const
std::filesystem::path &path) {
49
std::ifstream in(path);
50
std::string line;
51
if
(!in || !std::getline(in, line)) {
52
return
{};
53
}
54
if
(!line.empty() && line.back() ==
'\r'
) {
55
line.pop_back();
56
}
57
if
(line.size() < 2 || line[0] !=
'#'
|| line[1] !=
'!'
) {
58
return
{};
59
}
60
std::string rest = line.substr(2);
61
auto
take = [](std::string &s) -> std::string {
62
const
auto
begin = s.find_first_not_of(
" \t"
);
63
if
(begin == std::string::npos) {
64
s.clear();
65
return
{};
66
}
67
const
auto
end = s.find_first_of(
" \t"
, begin);
68
std::string tok = end == std::string::npos ? s.substr(begin)
69
: s.substr(begin, end - begin);
70
if
(end == std::string::npos) {
71
s.clear();
72
}
else
{
73
s.erase(0, end);
74
}
75
return
tok;
76
};
77
const
std::string first = take(rest);
78
if
(first.empty()) {
79
return
{};
80
}
81
std::string name = std::filesystem::path(first).filename().string();
82
if
(name ==
"env"
) {
83
std::string tok = take(rest);
84
while
(!tok.empty() && tok.front() ==
'-'
) {
85
tok = take(rest);
86
}
87
if
(tok.empty()) {
88
return
{};
89
}
90
name = std::filesystem::path(tok).filename().string();
91
}
92
return
name;
93
}
94
96
inline
bool
isPythonInterpreterName
(std::string name) {
97
for
(
char
&c : name) {
98
c =
static_cast<
char
>
(std::tolower(
static_cast<
unsigned
char
>
(c)));
99
}
100
constexpr
std::string_view exe{
".exe"
};
101
if
(name.size() > exe.size() &&
102
name.compare(name.size() - exe.size(), exe.size(), exe.data()) == 0) {
103
name.resize(name.size() - exe.size());
104
}
105
return
name.rfind(
"python"
, 0) == 0;
106
}
107
115
inline
std::string
wrapResolvedProgram
(
const
std::string &command,
116
const
std::string &python) {
117
std::error_code ec;
118
if
(!std::filesystem::is_regular_file(command, ec) || ec) {
119
return
command;
120
}
121
#ifdef _WIN32
122
const
std::filesystem::path named{command};
123
std::string ext = named.extension().string();
124
for
(
char
&c : ext) {
125
c =
static_cast<
char
>
(std::tolower(
static_cast<
unsigned
char
>
(c)));
126
}
127
if
(ext ==
".exe"
|| ext ==
".com"
|| ext ==
".bat"
|| ext ==
".cmd"
) {
128
return
shellQuote
(command);
129
}
130
const
std::string interp =
shebangInterpreter
(named);
131
if
(
isPythonInterpreterName
(interp) || ext ==
".py"
|| ext ==
".pyw"
) {
132
const
std::string runner = python.empty() ? std::string{
"python"
} : python;
133
return
runner +
" "
+
shellQuote
(command);
134
}
135
if
(!interp.empty()) {
136
return
interp +
" "
+
shellQuote
(command);
137
}
138
return
shellQuote
(command);
139
#else
140
(void)python;
141
return
shellQuote
(command);
142
#endif
143
}
144
145
}
// namespace eonc::pot
eonc::pot
Definition
ExternalCommand.h:22
eonc::pot::isPythonInterpreterName
bool isPythonInterpreterName(std::string name)
True when name is python, python3, python3.12, python.exe, ...
Definition
ExtPotCommand.h:96
eonc::pot::shellQuote
std::string shellQuote(const std::string &text)
Wrap a path for the shell system() hands the command to, so spaces in it survive.
Definition
ExtPotCommand.h:25
eonc::pot::shebangInterpreter
std::string shebangInterpreter(const std::filesystem::path &path)
Return the interpreter name from a #! line, or empty.
Definition
ExtPotCommand.h:48
eonc::pot::wrapResolvedProgram
std::string wrapResolvedProgram(const std::string &command, const std::string &python)
Quote a resolved program path, and on Windows prefix a script so cmd.exe can start it.
Definition
ExtPotCommand.h:115
include
eon
potentials
ExtPot
ExtPotCommand.h
Generated by
1.17.0
Generated by
Doxygen 1.17.0
Analytics by
Antics
provided by
TurtleTech ehf