QuasarAppLib 1.0.530.c9fba11
params.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2018-2026 QuasarApp.
3 * Distributed under the lgplv3 software license, see the accompanying
4 * Everyone is permitted to copy and distribute verbatim copies
5 * of this license document, but changing it is not allowed.
6*/
7
8#include "params.h"
9#include <QVariantMap>
10#include <QDebug>
11#include <QFileInfo>
12#include <QDateTime>
13#include <QCoreApplication>
14#include "qaglobalutils.h"
15#include <QtLogging>
16
17#ifdef Q_OS_DARWIN
18#include <mach-o/dyld.h>
19#endif
20
21#ifdef Q_OS_WIN
22#include "windows.h"
23#else
24#include <unistd.h>
25#endif
26
27using namespace QuasarAppUtils;
28QMap<QString, QString> Params::params = QMap<QString, QString>();
29QString Params::appPath = "";
30QString Params::appName = "";
31Help::Section Params::userHelp = {};
32OptionsDataList Params::inputOptions = {};
33
34
35bool Params::isEndable(const QString& key) {
36 return params.contains(key);
37}
38
39void Params::log(const QString &log, VerboseLvl vLvl) {
40
41 auto lvl = getVerboseLvl();
42 if (vLvl <= lvl) {
43
44 switch (vLvl) {
45
47 qCritical().noquote() << log;
48 break;
49
51 qWarning().noquote() << log;
52 break;
53 }
54 case VerboseLvl::Debug: {
55 qDebug().noquote() << log;
56 break;
57 }
58
60 default: {
61 qInfo().noquote() << log;
62 break;
63 }
64
65 }
66
67 }
68}
69
70
72 return static_cast<VerboseLvl>(getArg("verbose", DEFAULT_VERBOSE_LVL).toInt());
73}
74
77}
78
80#ifdef QT_DEBUG
81 return true;
82#else
83 return false;
84#endif
85}
86
88
89 if (inputOptions.size() > 1) {
91 } else {
92 Help::print(userHelp);
93 }
94}
95
99
101
102 if (inputOptions.size() <= 1 ) {
103 return {};
104 }
105
106 Help::Options help;
107 for (const auto &optionData: std::as_const(inputOptions) ) {
108 help.unite(optionData.toHelp());
109 }
110
111 return Help::Section{{"Information about using options", help}};
112}
113
115 return userHelp;
116}
117
118const QMap<QString, QString>& Params::getUserParamsMap() {
119 return params;
120}
121
123 params.clear();
124 appPath = "";
125 appName = "";
126}
127
129 return getCurrentExecutableDir() + "/" + appName;
130}
131
133 return appPath;
134}
135
137 return OptionsDataList{
138 {
139 "Base Options",
141 {"-verbose"}, "(level 1 - 3)", "Shows debug log"
142 }
143
144 },
145 {
146 "Base Options",
148 {"-fileLog"}, "(path to file)", "Sets path of log file. Default it is path to executable file with suffix '.log'"
149 }
150 }
151 };
152}
153
155 return params.size();
156}
157
158bool Params::optionsForEach(const QStringList &paramsArray,
159 const OptionsDataList& availableOptions) {
160
161 for (int i = 0 ; i < paramsArray.size(); ++i) {
162
163 QStringList virtualOptionsList = paramsArray[i].split('=');
164
165 if (virtualOptionsList.size() > 1) {
166 return optionsForEach(virtualOptionsList, availableOptions);
167 }
168
169 auto optionData = availableOptions.value(paramsArray[i], {{}});
170 if (!checkOption(optionData, paramsArray[i])) {
171 return false;
172 }
173
174 inputOptions.insert(paramsArray[i], optionData);
175
176 if (paramsArray[i][0] == '-') {
177
178 if (i < (paramsArray.size() - 1) && paramsArray[i + 1][0] != '-') {
179 params[paramsArray[i].mid(1)] = paramsArray[i + 1];
180 i++;
181 } else {
182 qCritical() << "Missing argument for " + paramsArray[i];
183 return false;
184 }
185 } else {
186 params[paramsArray[i]] = "";
187 }
188 }
189
190 return true;
191}
192
193bool Params::parseParams(const int argc, const char *argv[], const OptionsDataList& options) {
194
195 QStringList params;
196 for (int i = 1; i < argc; i++) {
197 params.push_back(argv[i]);
198 }
199
200 return parseParams(params, options);
201}
202
203bool Params::parseParams(int argc, char *argv[], const OptionsDataList& options) {
204 return parseParams(argc, const_cast<const char**>(argv), options);
205}
206
207bool Params::parseParams(const QStringList &paramsArray, const OptionsDataList &options) {
208 params.clear();
209 OptionsDataList availableOptions;
210
211 parseAvailableOptions(OptionsDataList{}.unite(options).unite(availableArguments()),
212 &availableOptions,
213 &userHelp);
214
215#ifdef Q_OS_WIN
216 char buffer[MAX_PATH];
217 memset(buffer, 0, sizeof buffer);
218
219 GetModuleFileNameA(nullptr, buffer, MAX_PATH);
220 appPath = QFileInfo(buffer).absolutePath();
221 appName = QFileInfo(buffer).fileName();
222#endif
223
224#ifdef Q_OS_LINUX
225 char path[2048];
226 memset(path, 0, sizeof path);
227
228 if (readlink("/proc/self/exe", path, 2048) < 0) {
229 qCritical() << "parseParams can't get self path!";
230 return false;
231 }
232 appPath = QFileInfo(path).absolutePath();
233 appName = QFileInfo(path).fileName();
234
235#endif
236#ifdef Q_OS_DARWIN
237 uint32_t size = 0;
238 _NSGetExecutablePath(nullptr, &size); // request to buffer size
239 std::vector<char> buffer(size);
240 if (_NSGetExecutablePath(buffer.data(), &size) == 0) {
241 appPath = QString::fromUtf8(buffer.data());
242 } else {
243 appPath = QString();
244 }
245
246 appName = QCoreApplication::applicationName();
247#endif
248
249 if (!appPath.size()) {
250 return false;
251 }
252
253 if (!optionsForEach(paramsArray, availableOptions)) {
254 return false;
255 }
256
257 printWorkingOptions();
258
259 return true;
260}
261
262void Params::printWorkingOptions() {
263 qDebug() << "--- Working options table start ---";
264
265 QMap<QString, QString>::const_iterator iter = params.constBegin();
266 while (iter != params.constEnd()) {
267
268 QString row = QString{"Option[%0]"}.arg(iter.key());
269
270 QString value = iter.value();
271 if (!value.isEmpty()) {
272 row += QString{": %1"}.arg(value);
273 }
274
275 qDebug() << row;
276
277 ++iter;
278 }
279
280 qDebug() << "--- Working options table end ---";
281}
282
283bool Params::checkOption(const OptionData& optionData, const QString& rawOptionName) {
284
285#ifndef QA_ALLOW_NOT_SUPPORTED_OPTIONS
286 if (!optionData.isValid()) {
287
288 qCritical() << QString("The '%0' option not exists!"
289 " You use wrong option name,"
290 " please check the help before run your command.").
291 arg(rawOptionName);
292
293 return false;
294 }
295#else
296 Q_UNUSED(rawOptionName);
297#endif
298
299 if (optionData.isDeprecated()) {
300
301
302
303 if (optionData.isRemoved()) {
304 qCritical() << optionData.deprecatedMsg();
305
306 return false;
307 }
308
309 qWarning() << QString("The %0 option(s) marked as deprecated! "
310 "And most likely will be removed in next release.").
311 arg(optionData.names().join("/"));
312
313 qWarning() << QString("Option message: %0").arg(optionData.deprecatedMsg());
314
315 }
316
317 return true;
318}
319
320void Params::parseAvailableOptions(const OptionsDataList &availableOptionsListIn,
321 OptionsDataList *availableOptionsListOut,
322 Help::Section *helpOut) {
323
324 if (!(availableOptionsListOut && helpOut))
325 return;
326
327 helpOut->clear();
328
329 QHash<QString, Help::Options> options;
330 for (auto it = availableOptionsListIn.begin(); it != availableOptionsListIn.end(); ++it) {
331
332 if (availableOptionsListOut) {
333 for (const auto &name : std::as_const(it.value().names())) {
334 availableOptionsListOut->insert(name, it.value());
335 }
336 }
337
338 if (helpOut) {
339 options[it.key()].unite(it.value().toHelp());
340 }
341 }
342
343 for (auto it = options.begin(); it != options.end(); ++it) {
344 helpOut->insert(it.key(), it.value());
345 }
346}
347
348QString Params::getArg(const QString& key,const QString& def) {
349 return params.value(key, def);
350}
351
352void Params::setArg(const QString &key, const QString &val) {
353 params.insert(key, val);
354}
355
356void Params::setEnable(const QString &key, bool enable) {
357 if (enable) {
358 params.insert(key, "");
359 } else {
360 params.remove(key);
361 }
362}
The OptionData class contains information about one option.
Definition optiondata.h:21
bool isDeprecated() const
isDeprecated This method return true if this option is deprecated.
const QString & deprecatedMsg() const
deprecatedWarning This is a message that will be printed as a warning if user will use this option....
bool isValid() const
isValid This method return true if the option is valid. If option do not contain a name then it is in...
bool isRemoved() const
isRemoved This method return true if the option is removed.
const QStringList & names() const
name This is name of the option. It is a required argument and cannot be empty.
static void clearParsedData()
clearParsedData This method clear all parsed data.
Definition params.cpp:122
static void showHelpForInputOptions()
showHelpForInputOptions This method show help for each input option.
Definition params.cpp:96
static void showHelp()
showHelp This method shows all help message.
Definition params.cpp:87
static void setArg(const QString &key, const QString &val)
setArg sets a new value of a key.
Definition params.cpp:352
static QString getCurrentExecutableDir()
getCurrentExecutableDir This method return a path to a folder with the current executable.
Definition params.cpp:132
static void setEnable(const QString &key, bool enable)
setEnable This method sets boolean value of key.
Definition params.cpp:356
static bool isEndable(const QString &key)
isEndable This method check if enable a key argument.
Definition params.cpp:35
static const Help::Section & getHelp()
getHelp This method return options help page.
Definition params.cpp:114
static bool isDebug()
isDebug This method return true if the application verbose level >= VerboseLvl::Debug.
Definition params.cpp:75
static VerboseLvl getVerboseLvl()
getVerboseLvl This method return the verbose log level.
Definition params.cpp:71
static OptionsDataList availableArguments()
availableArguments This method return list of the available arguments of QuasarAppLibrary
Definition params.cpp:136
static QString getArg(const QString &key, const QString &def={})
getArg return string value of a key if key is exits else return a def value. If a def value not defin...
Definition params.cpp:348
static Help::Section getHelpOfInputOptions()
getHelpOfInputOptions This method return help abut input options only. Except help and h options.
Definition params.cpp:100
static int size()
size This method return count of the all input arguments.
Definition params.cpp:154
static void log(const QString &log, VerboseLvl vLvl=VerboseLvl::Debug)
log This method print log text on console.
Definition params.cpp:39
static QString getCurrentExecutable()
getCurrentExecutable This method return path to the current executable.
Definition params.cpp:128
static bool isDebugBuild()
isDebugBuild This method return true if the library buildet in debug mode.
Definition params.cpp:79
static bool parseParams(const int argc, const char *argv[], const OptionsDataList &options={})
parseParams Parse input data of started application.
Definition params.cpp:193
static const QMap< QString, QString > & getUserParamsMap()
getUserParamsMap This method return const reference to the parsed arguments map.
Definition params.cpp:118
QMultiMap< QString, QString > Options
Options this is list of key-descriptions pairs of help. The key is name of the available argument and...
Definition helpdata.h:32
void print(const QString &key, const QString &value, int keyLength)
Definition helpdata.cpp:37
QMultiMap< QString, Options > Section
Section This is list of the help Sections. The one section it is Title of the section and Help::Optio...
Definition helpdata.h:45
The QuasarAppUtils namespace contains the base functions for all applications of the QuasarApp group....
QMultiHash< QString, OptionData > OptionsDataList
OptionsList is Hash map of the OptionData items. Where the key it is group name and value it is optio...
Definition optiondata.h:150
VerboseLvl
The VerboseLvl enum uses for sets log level.
Definition params.h:23
@ Error
Error message. This logs will marked as a Error and printing if the verbose lvl >= 0.
Definition params.h:25
@ Warning
Warning message. This logs will marked as a Warning and printing if the verbose lvl >= 1.
Definition params.h:27
@ Info
General information. This logs will marked as a Info and and printing if the verbose lvl >= 2.
Definition params.h:29
@ Debug
Debug message. This logs will marked as a Debug and printing if the verbose lvl >= 3.
Definition params.h:31
#define DEFAULT_VERBOSE_LVL
Definition params.h:40
QHashType & unite(QHashType &left, const QHashType &right)
Simplified union operation for QHash.