1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
// SPDX-License-Identifier: GPL-3.0-only
// SPDX-FileCopyrightText: 2026 Project Tick
// SPDX-FileContributor: Project Tick Team
/*
* ProjT Launcher - Minecraft Launcher
* Copyright (C) 2026 Project Tick
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "LaunchVariableExpander.hpp"
namespace projt::launch
{
QString LaunchVariableExpander::expand(const QString& input, const QProcessEnvironment& env) const
{
QString output = input;
enum class Mode
{
Idle,
Sigil,
Name,
Brace
};
Mode mode = Mode::Idle;
int tokenStart = -1;
for (int idx = 0; idx < output.length();)
{
const QChar c = output.at(idx++);
switch (mode)
{
case Mode::Idle:
if (c == '$')
{
mode = Mode::Sigil;
}
break;
case Mode::Sigil:
if (c == '{')
{
mode = Mode::Brace;
tokenStart = idx;
}
else if (c.isLetterOrNumber() || c == '_')
{
mode = Mode::Name;
tokenStart = idx - 1;
}
else
{
mode = Mode::Idle;
}
break;
case Mode::Brace:
if (c == '}')
{
const auto key = output.mid(tokenStart, idx - 1 - tokenStart);
const auto value = env.value(key, "");
if (!value.isEmpty())
{
output.replace(tokenStart - 2, idx - tokenStart + 2, value);
idx = tokenStart - 2 + value.length();
}
mode = Mode::Idle;
}
break;
case Mode::Name:
if (!c.isLetterOrNumber() && c != '_')
{
const auto key = output.mid(tokenStart, idx - tokenStart - 1);
const auto value = env.value(key, "");
if (!value.isEmpty())
{
output.replace(tokenStart - 1, idx - tokenStart, value);
idx = tokenStart - 1 + value.length();
}
mode = Mode::Idle;
}
break;
}
}
if (mode == Mode::Name)
{
const auto value = env.value(output.mid(tokenStart), "");
if (!value.isEmpty())
{
output.replace(tokenStart - 1, output.length() - tokenStart + 1, value);
}
}
return output;
}
} // namespace projt::launch
|