Merge remote-tracking branch 'origin/9.0'

Change-Id: I13e71c3ac9fb11ce02af82b3b6e750dc7d7015d4
This commit is contained in:
Eike Ziller
2022-10-19 14:38:15 +02:00
26 changed files with 140 additions and 91 deletions

View File

@@ -45411,7 +45411,7 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e
</message>
</context>
<context>
<name>Core::Internal::SystemSettingsWidget</name>
<name>Core::Internal::SystemSettings</name>
<message>
<source>Command line arguments used for &quot;%1&quot;.</source>
<translation>Kommandozeilenargumente für &quot;%1&quot;.</translation>
@@ -45444,10 +45444,6 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e
<source>Variables</source>
<translation>Variablen</translation>
</message>
<message>
<source>System</source>
<translation>System</translation>
</message>
</context>
<context>
<name>Core::ListItemDelegate</name>

View File

@@ -35870,10 +35870,6 @@ Android 5 ではローカルの Qt ライブラリをデプロイできません
</context>
<context>
<name>Core::Internal::SystemSettings</name>
<message>
<source>System</source>
<translation></translation>
</message>
<message>
<source>Terminal:</source>
<translation>:</translation>
@@ -35941,30 +35937,6 @@ Android 5 ではローカルの Qt ライブラリをデプロイできません
<comment>Terminal</comment>
<translation></translation>
</message>
<message>
<source>Command used for reverting diff chunks.</source>
<translation>使</translation>
</message>
<message>
<source>Case Sensitive (Default)</source>
<translation> ()</translation>
</message>
<message>
<source>Case Sensitive</source>
<translation></translation>
</message>
<message>
<source>Case Insensitive (Default)</source>
<translation> ()</translation>
</message>
<message>
<source>Case Insensitive</source>
<translation></translation>
</message>
<message>
<source>Variables</source>
<translation></translation>
</message>
<message>
<source>Warn before opening text files greater than</source>
<translation></translation>
@@ -48174,7 +48146,7 @@ Continue?</source>
</message>
</context>
<context>
<name>Core::Internal::SystemSettingsWidget</name>
<name>Core::Internal::SystemSettings</name>
<message>
<source>Command line arguments used for &quot;%1&quot;.</source>
<translation>&quot;%1&quot; 使</translation>

View File

@@ -11187,7 +11187,7 @@ Do you want to kill it?</source>
</message>
</context>
<context>
<name>Core::Internal::SystemSettingsWidget</name>
<name>Core::Internal::SystemSettings</name>
<message>
<source>Command line arguments used for &quot;%1&quot;.</source>
<translation>Параметры командной строки для «%1».</translation>
@@ -11220,10 +11220,6 @@ Do you want to kill it?</source>
<source>Variables</source>
<translation>Переменные</translation>
</message>
<message>
<source>System</source>
<translation>Система</translation>
</message>
</context>
<context>
<name>Core::Internal::ThemeChooser</name>

View File

@@ -85,6 +85,7 @@ const char HELP_OPTION2[] = "-help";
const char HELP_OPTION3[] = "/h";
const char HELP_OPTION4[] = "--help";
const char VERSION_OPTION[] = "-version";
const char VERSION_OPTION2[] = "--version";
const char CLIENT_OPTION[] = "-client";
const char SETTINGS_OPTION[] = "-settingspath";
const char INSTALL_SETTINGS_OPTION[] = "-installsettingspath";
@@ -117,7 +118,7 @@ static void displayHelpText(const QString &t)
if (Utils::HostOsInfo::isWindowsHost() && qApp)
QMessageBox::information(nullptr, QLatin1String(Core::Constants::IDE_DISPLAY_NAME), toHtml(t));
else
qWarning("%s", qPrintable(t));
printf("%s", qPrintable(t));
}
static void displayError(const QString &t)
@@ -639,6 +640,7 @@ int main(int argc, char **argv)
appOptions.insert(QLatin1String(HELP_OPTION3), false);
appOptions.insert(QLatin1String(HELP_OPTION4), false);
appOptions.insert(QLatin1String(VERSION_OPTION), false);
appOptions.insert(QLatin1String(VERSION_OPTION2), false);
appOptions.insert(QLatin1String(CLIENT_OPTION), false);
appOptions.insert(QLatin1String(PID_OPTION), true);
appOptions.insert(QLatin1String(BLOCK_OPTION), false);
@@ -682,7 +684,8 @@ int main(int argc, char **argv)
displayError(msgCoreLoadFailure(coreplugin->errorString()));
return 1;
}
if (foundAppOptions.contains(QLatin1String(VERSION_OPTION))) {
if (foundAppOptions.contains(QLatin1String(VERSION_OPTION))
|| foundAppOptions.contains(QLatin1String(VERSION_OPTION2))) {
printVersion(coreplugin);
return 0;
}

View File

@@ -155,7 +155,7 @@ bool OptionsParser::checkForScenarioOption()
if (!m_pmPrivate->m_requestedScenario.isEmpty()) {
if (m_errorString) {
*m_errorString = QCoreApplication::translate("PluginManager",
"Cannot request scenario \"%1\" as the scenario \"%1\" was already requested.")
"Cannot request scenario \"%1\" as it was already requested.")
.arg(m_currentArg, m_pmPrivate->m_requestedScenario);
}
m_hasError = true;

View File

@@ -46,7 +46,7 @@ JsonRpcMessage::JsonRpcMessage()
constexpr int utf8mib = 106;
static QString docTypeName(const QJsonDocument &doc)
static QString docType(const QJsonDocument &doc)
{
if (doc.isArray())
return QString("array");
@@ -73,16 +73,12 @@ JsonRpcMessage::JsonRpcMessage(const BaseMessage &message)
content = message.content;
QJsonParseError error = {0, QJsonParseError::NoError};
const QJsonDocument doc = QJsonDocument::fromJson(content, &error);
if (doc.isObject()) {
if (doc.isObject())
m_jsonObject = doc.object();
} else if (doc.isNull()) {
m_parseError = tr("LanguageServerProtocol::JsonRpcMessage",
"Could not parse JSON message \"%1\".")
.arg(error.errorString());
} else {
m_parseError = tr("Expected a JSON object, but got a JSON \"%1\" value.")
.arg(docTypeName(doc));
}
else if (doc.isNull())
m_parseError = tr("Could not parse JSON message \"%1\".").arg(error.errorString());
else
m_parseError = tr("Expected a JSON object, but got a JSON \"%1\" value.").arg(docType(doc));
}
JsonRpcMessage::JsonRpcMessage(const QJsonObject &jsonObject)

View File

@@ -879,6 +879,9 @@ bool UnixDeviceFileAccess::iterateWithFind(
return true;
const FilePath fp = filePath.withNewPath(fileName);
// Do not return the entry for the directory we are searching in.
if (fp.path() == filePath.path())
return true;
return std::get<1>(callBack)(fp, fi);
};

View File

@@ -37,8 +37,10 @@ void dumpBacktrace(int maxdepth)
free(lines);
#elif defined(_MSC_VER)
DWORD machineType;
#if defined(Q_OS_WIN64) && !defined(_ARM64_)
#if defined(_M_X64)
machineType = IMAGE_FILE_MACHINE_AMD64;
#elif defined(_M_ARM64)
machineType = IMAGE_FILE_MACHINE_ARM64;
#else
return;
#endif
@@ -50,13 +52,17 @@ void dumpBacktrace(int maxdepth)
RtlCaptureContext(&ctx);
STACKFRAME64 frame;
memset(&frame, 0, sizeof(STACKFRAME64));
#if defined(Q_OS_WIN64) && !defined(_ARM64_)
frame.AddrPC.Offset = ctx.Rip;
frame.AddrPC.Mode = AddrModeFlat;
frame.AddrStack.Offset = ctx.Rsp;
frame.AddrStack.Mode = AddrModeFlat;
frame.AddrFrame.Offset = ctx.Rbp;
frame.AddrFrame.Mode = AddrModeFlat;
#if defined(_M_X64)
frame.AddrPC.Offset = ctx.Rip;
frame.AddrStack.Offset = ctx.Rsp;
frame.AddrFrame.Offset = ctx.Rbp;
#elif define(_M_ARM64)
frame.AddrPC.Offset = ctx.Pc;
frame.AddrStack.Offset = ctx.Sp;
frame.AddrFrame.Offset = ctx.Fp;
#endif
int depth = 0;

View File

@@ -18,18 +18,20 @@
#include "tasktimers.h"
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icore.h>
#include <cplusplus/AST.h>
#include <cplusplus/ASTPath.h>
#include <cplusplus/Icons.h>
#include <cppeditor/cppcodemodelsettings.h>
#include <cppeditor/cppeditorconstants.h>
#include <cppeditor/cppeditorwidget.h>
#include <cppeditor/cppmodelmanager.h>
#include <cppeditor/cpprefactoringchanges.h>
#include <cppeditor/cppsemanticinfo.h>
#include <cppeditor/cpptoolsreuse.h>
#include <cppeditor/cppvirtualfunctionassistprovider.h>
#include <cppeditor/cppvirtualfunctionproposalitem.h>
#include <cppeditor/semantichighlighter.h>
#include <cppeditor/cppsemanticinfo.h>
#include <languageclient/diagnosticmanager.h>
#include <languageclient/languageclienthoverhandler.h>
#include <languageclient/languageclientinterface.h>
@@ -389,6 +391,9 @@ ClangdClient::ClangdClient(Project *project, const Utils::FilePath &jsonDbDir)
setProgressTitleForToken(indexingToken(),
project ? tr("Indexing %1 with clangd").arg(project->displayName())
: tr("Indexing session with clangd"));
setClickHandlerForToken(indexingToken(), [] {
ICore::showOptionsDialog(CppEditor::Constants::CPP_CLANGD_SETTINGS_ID);
});
setCurrentProject(project);
setDocumentChangeUpdateThreshold(d->settings.documentUpdateThreshold);
setSymbolStringifier(displayNameFromDocumentSymbol);
@@ -430,7 +435,10 @@ ClangdClient::~ClangdClient()
delete d;
}
bool ClangdClient::isFullyIndexed() const { return d->isFullyIndexed; }
bool ClangdClient::isFullyIndexed() const
{
return d->isFullyIndexed;
}
void ClangdClient::openExtraFile(const Utils::FilePath &filePath, const QString &content)
{

View File

@@ -260,7 +260,7 @@ void doSemanticHighlighting(
};
const std::function<HighlightingResult(const ExpandedSemanticToken &)> toResult
= [&ast, &isOutputParameter, &tokenRange]
= [&ast, &isOutputParameter, &tokenRange, ver = clangdVersion.majorVersion()]
(const ExpandedSemanticToken &token) {
TextStyles styles;
if (token.type == "variable") {
@@ -275,7 +275,9 @@ void doSemanticHighlighting(
} else if (token.type == "function" || token.type == "method") {
styles.mainStyle = token.modifiers.contains(QLatin1String("virtual"))
? C_VIRTUAL_METHOD : C_FUNCTION;
if (ast.isValid()) {
if (token.modifiers.contains("definition")) {
styles.mixinStyles.push_back(C_FUNCTION_DEFINITION);
} else if (ver < 16 && ast.isValid()) {
const ClangdAstPath path = getAstPath(ast, tokenRange(token));
if (path.length() > 1) {
const ClangdAstNode declNode = path.at(path.length() - 2);

View File

@@ -427,9 +427,15 @@ static bool isProjectDataUpToDate(
return false;
if (sessionModeEnabled() && project)
return false;
const ProjectInfoList newProjectInfo = project
? ProjectInfoList{CppModelManager::instance()->projectInfo(project)}
: CppModelManager::instance()->projectInfos();
ProjectInfoList newProjectInfo;
if (project) {
if (const ProjectInfo::ConstPtr pi = CppModelManager::instance()->projectInfo(project))
newProjectInfo.append(pi);
else
return false;
} else {
newProjectInfo = CppModelManager::instance()->projectInfos();
}
if (newProjectInfo.size() != projectInfo.size())
return false;
for (int i = 0; i < projectInfo.size(); ++i) {
@@ -450,8 +456,10 @@ void ClangModelManagerSupport::updateLanguageClient(ProjectExplorer::Project *pr
if (sessionModeEnabled()) {
project = nullptr;
projectInfo = CppModelManager::instance()->projectInfos();
} else if (const ProjectInfo::ConstPtr pi = CppModelManager::instance()->projectInfo(project)) {
projectInfo.append(pi);
} else {
projectInfo.append(CppModelManager::instance()->projectInfo(project));
return;
}
const Utils::FilePath jsonDbDir = getJsonDbDir(project);

View File

@@ -166,8 +166,9 @@ GenerateCompilationDbResult generateCompilationDB(QList<ProjectInfo::ConstPtr> p
const UsePrecompiledHeaders usePch = getPchUsage();
const QJsonArray jsonProjectOptions = QJsonArray::fromStringList(projectOptions);
for (const ProjectInfo::ConstPtr &projectInfo : std::as_const(projectInfoList)) {
QTC_ASSERT(projectInfo, continue);
for (ProjectPart::ConstPtr projectPart : projectInfo->projectParts()) {
QTC_ASSERT(projectInfo, continue);
QTC_ASSERT(projectPart, continue);
QStringList args;
const CompilerOptionsBuilder optionsBuilder = clangOptionsBuilder(
*projectPart, warningsConfig, clangIncludeDir, {});

View File

@@ -677,7 +677,7 @@ QVariant CMakeGeneratorKitAspect::defaultValue(const Kit *k) const
return g.matches("Ninja");
});
if (it != known.constEnd()) {
const bool hasNinja = [k]() {
const bool hasNinja = [k, tool]() {
Internal::CMakeSpecificSettings *settings
= Internal::CMakeProjectPlugin::projectTypeSpecificSettings();
@@ -685,7 +685,7 @@ QVariant CMakeGeneratorKitAspect::defaultValue(const Kit *k) const
auto findNinja = [](const Environment &env) -> bool {
return !env.searchInPath("ninja").isEmpty();
};
if (!findNinja(Environment::systemEnvironment()))
if (!findNinja(tool->filePath().deviceEnvironment()))
return findNinja(k->buildEnvironment());
}
return true;

View File

@@ -135,7 +135,7 @@ FilePaths CMakeProjectImporter::importCandidates()
// If the binaryFilePath exists, do not try to import the existing build, so that
// we don't have duplicates, one from the preset and one from the previous configuration.
if (configPreset.binaryDir) {
Environment env = Environment::systemEnvironment();
Environment env = projectDirectory().deviceEnvironment();
CMakePresets::Macros::expand(configPreset, env, projectDirectory());
QString binaryDir = configPreset.binaryDir.value();
@@ -165,15 +165,15 @@ static CMakeConfig configurationFromPresetProbe(
cmake.setTimeoutS(30);
cmake.setDisableUnixTerminal();
Environment env = Environment::systemEnvironment();
const FilePath cmakeExecutable = FilePath::fromString(configurePreset.cmakeExecutable.value());
Environment env = cmakeExecutable.deviceEnvironment();
CMakePresets::Macros::expand(configurePreset, env, importPath);
env.setupEnglishOutput();
cmake.setEnvironment(env);
cmake.setTimeOutMessageBoxEnabled(false);
const FilePath cmakeExecutable = FilePath::fromString(configurePreset.cmakeExecutable.value());
QStringList args;
args.emplace_back("-S");
args.emplace_back(importPath.path());
@@ -428,7 +428,7 @@ QList<void *> CMakeProjectImporter::examineDirectory(const FilePath &importPath,
return preset.name == presetName;
});
Environment env = Environment::systemEnvironment();
Environment env = projectDirectory().deviceEnvironment();
CMakePresets::Macros::expand(configurePreset, env, projectDirectory());
if (configurePreset.displayName)

View File

@@ -280,7 +280,7 @@ bool evaluatePresetCondition(const PresetType &preset, const Utils::FilePath &so
if (!preset.condition)
return true;
Utils::Environment env = Utils::Environment::systemEnvironment();
Utils::Environment env = sourceDirectory.deviceEnvironment();
expand(preset, env, sourceDirectory);
PresetsDetails::Condition condition = preset.condition.value();

View File

@@ -6,6 +6,7 @@
#include "../iwizardfactory.h"
#include "newdialog.h"
#include <QCoreApplication>
#include <QDialog>
#include <QIcon>
#include <QList>
@@ -30,7 +31,7 @@ namespace Internal {
class NewDialogWidget : public QDialog, public NewDialog
{
Q_OBJECT
Q_DECLARE_TR_FUNCTIONS(Core::Internal::NewDialog)
public:
explicit NewDialogWidget(QWidget *parent);

View File

@@ -121,7 +121,12 @@ FutureProgress::FutureProgress(QWidget *parent) :
this, &FutureProgress::setProgressValue);
connect(&d->m_watcher, &QFutureWatcherBase::progressTextChanged,
this, &FutureProgress::setProgressText);
connect(d->m_progress, &Internal::ProgressBar::clicked, this, &FutureProgress::cancel);
connect(d->m_progress, &Internal::ProgressBar::clicked, this, [this] {
if (isCancelEnabled())
cancel();
else
emit clicked();
});
setMinimumWidth(100);
setMaximumWidth(300);
}
@@ -373,6 +378,16 @@ QSize FutureProgress::sizeHint() const
return QSize(QWidget::sizeHint().width(), minimumHeight());
}
bool FutureProgress::isCancelEnabled() const
{
return d->m_progress->isCancelEnabled();
}
void FutureProgress::setCancelEnabled(bool enabled)
{
d->m_progress->setCancelEnabled(enabled);
}
void FutureProgressPrivate::fadeAway()
{
m_isFading = true;

View File

@@ -59,6 +59,9 @@ public:
QSize sizeHint() const override;
bool isCancelEnabled() const;
void setCancelEnabled(bool enabled);
signals:
void clicked();
void finished();

View File

@@ -65,7 +65,7 @@ static QString formatSize(qint64 size)
class SystemSettingsWidget : public IOptionsPageWidget
{
Q_DECLARE_TR_FUNCTIONS(Core::Internal::SystemSettingsWidget)
Q_DECLARE_TR_FUNCTIONS(Core::Internal::SystemSettings)
public:
SystemSettingsWidget()

View File

@@ -879,6 +879,8 @@ void Client::deactivateDocument(TextEditor::TextDocument *document)
TextEditor::TextEditorWidget *widget = textEditor->editorWidget();
widget->removeHoverHandler(&d->m_hoverHandler);
widget->setExtraSelections(TextEditor::TextEditorWidget::CodeSemanticsSelection, {});
widget->setRefactorMarkers(
TextEditor::RefactorMarker::filterOutType(widget->refactorMarkers(), id()));
updateEditorToolBar(editor);
}
}
@@ -1573,6 +1575,12 @@ void Client::setProgressTitleForToken(const LanguageServerProtocol::ProgressToke
d->m_progressManager.setTitleForToken(token, message);
}
void Client::setClickHandlerForToken(const LanguageServerProtocol::ProgressToken &token,
const std::function<void()> &handler)
{
d->m_progressManager.setClickHandlerForToken(token, handler);
}
void Client::handleMessage(const LanguageServerProtocol::JsonRpcMessage &message)
{
LanguageClientManager::logJsonRpcMessage(LspLogMessage::ServerMessage, name(), message);

View File

@@ -197,6 +197,8 @@ protected:
void setError(const QString &message);
void setProgressTitleForToken(const LanguageServerProtocol::ProgressToken &token,
const QString &message);
void setClickHandlerForToken(const LanguageServerProtocol::ProgressToken &token,
const std::function<void()> &handler);
void handleMessage(const LanguageServerProtocol::JsonRpcMessage &message);
virtual void handleDiagnostics(const LanguageServerProtocol::PublishDiagnosticsParams &params);
virtual DiagnosticManager *createDiagnosticManager();

View File

@@ -41,6 +41,12 @@ void ProgressManager::setTitleForToken(const LanguageServerProtocol::ProgressTok
m_titles.insert(token, message);
}
void ProgressManager::setClickHandlerForToken(const LanguageServerProtocol::ProgressToken &token,
const std::function<void()> &handler)
{
m_clickHandlers.insert(token, handler);
}
void ProgressManager::reset()
{
const QList<ProgressToken> &tokens = m_progress.keys();
@@ -72,6 +78,10 @@ void ProgressManager::beginProgress(const ProgressToken &token, const WorkDonePr
const QString title = m_titles.value(token, begin.title());
Core::FutureProgress *progress = Core::ProgressManager::addTask(
interface->future(), title, languageClientProgressId(token));
progress->setCancelEnabled(false);
const std::function<void()> clickHandler = m_clickHandlers.value(token);
if (clickHandler)
QObject::connect(progress, &Core::FutureProgress::clicked, clickHandler);
m_progress[token] = {progress, interface};
if (LOGPROGRESS().isDebugEnabled())
m_timer[token].start();

View File

@@ -27,6 +27,8 @@ public:
void handleProgress(const LanguageServerProtocol::ProgressParams &params);
void setTitleForToken(const LanguageServerProtocol::ProgressToken &token,
const QString &message);
void setClickHandlerForToken(const LanguageServerProtocol::ProgressToken &token,
const std::function<void()> &handler);
void reset();
static bool isProgressEndMessage(const LanguageServerProtocol::ProgressParams &params);
@@ -48,6 +50,7 @@ private:
QMap<LanguageServerProtocol::ProgressToken, LanguageClientProgress> m_progress;
QMap<LanguageServerProtocol::ProgressToken, QString> m_titles;
QMap<LanguageServerProtocol::ProgressToken, QElapsedTimer> m_timer;
QMap<LanguageServerProtocol::ProgressToken, std::function<void()>> m_clickHandlers;
};
} // namespace LanguageClient

View File

@@ -152,7 +152,8 @@ bool AbstractProcessStep::init()
if (d->m_process)
return false;
setupProcessParameters(processParameters());
if (!setupProcessParameters(processParameters()))
return false;
return true;
}
@@ -233,7 +234,7 @@ ProcessParameters *AbstractProcessStep::processParameters()
return &d->m_param;
}
void AbstractProcessStep::setupProcessParameters(ProcessParameters *params) const
bool AbstractProcessStep::setupProcessParameters(ProcessParameters *params) const
{
params->setMacroExpander(macroExpander());
@@ -242,13 +243,21 @@ void AbstractProcessStep::setupProcessParameters(ProcessParameters *params) cons
d->m_environmentModifier(env);
params->setEnvironment(env);
if (d->m_workingDirectoryProvider)
params->setWorkingDirectory(d->m_workingDirectoryProvider());
else
params->setWorkingDirectory(buildDirectory());
if (d->m_commandLineProvider)
params->setCommandLine(d->m_commandLineProvider());
FilePath workingDirectory;
if (d->m_workingDirectoryProvider)
workingDirectory = d->m_workingDirectoryProvider();
else
workingDirectory = buildDirectory();
const FilePath executable = params->effectiveCommand();
QTC_ASSERT(executable.ensureReachable(workingDirectory), return false);
params->setWorkingDirectory(workingDirectory.onDevice(executable));
return true;
}
void AbstractProcessStep::Private::cleanUp(int exitCode, QProcess::ExitStatus status)

View File

@@ -21,7 +21,7 @@ class PROJECTEXPLORER_EXPORT AbstractProcessStep : public BuildStep
public:
ProcessParameters *processParameters();
void setupProcessParameters(ProcessParameters *params) const;
bool setupProcessParameters(ProcessParameters *params) const;
bool ignoreReturnValue() const;
void setIgnoreReturnValue(bool b);

View File

@@ -2085,16 +2085,23 @@ std::optional<QString> MsvcToolChain::generateEnvironmentSettings(const Utils::E
// Create a batch file to create and save the env settings
Utils::TempFileSaver saver(Utils::TemporaryDirectory::masterDirectoryPath() + "/XXXXXX.bat");
QByteArray call = "call ";
call += ProcessArgs::quoteArg(batchFile).toLocal8Bit();
if (!batchArgs.isEmpty()) {
call += ' ';
call += batchArgs.toLocal8Bit();
}
auto makeCall = [](const QString &batchFile, const QString &batchArgs) -> QByteArray {
QByteArray call = "call ";
call += ProcessArgs::quoteArg(batchFile).toLocal8Bit();
if (!batchArgs.isEmpty()) {
call += ' ';
call += batchArgs.toLocal8Bit();
}
return call;
};
QByteArray callCleanEnv = makeCall(batchFile, "/clean_env");
QByteArray call = makeCall(batchFile, batchArgs);
if (Utils::HostOsInfo::isWindowsHost())
saver.write("chcp 65001\r\n");
saver.write("set VSCMD_SKIP_SENDTELEMETRY=1\r\n");
saver.write("set CLINK_NOAUTORUN=1\r\n");
saver.write(callCleanEnv + "\r\n");
saver.write(call + "\r\n");
saver.write("@echo " + marker.toLocal8Bit() + "\r\n");
saver.write("set\r\n");