38#include <QtCore/QFile>
39#include <QtCore/QHash>
40#include <QtCore/QTextCodec>
44#include "kdeversion.h"
75#define DISPLAY "DISPLAY"
76#elif defined(Q_WS_QWS)
77#define DISPLAY "QWS_DISPLAY"
79#define DISPLAY "NODISPLAY"
86class KCmdLineParsedOptions :
public QHash<QByteArray,QByteArray>
89 KCmdLineParsedOptions() { }
92class KCmdLineParsedArgs :
public QList<QByteArray>
95 KCmdLineParsedArgs() { }
99class KCmdLineArgsList:
public QList<KCmdLineArgs*>
102 KCmdLineArgsList() { }
103 ~KCmdLineArgsList() {
113class KCmdLineOptionsPrivate {
121: d(
new KCmdLineOptionsPrivate)
130: d(
new KCmdLineOptionsPrivate(*(options.d)))
136 if (
this != &options) {
146 d->names.append(name);
147 d->descriptions.append(description);
154 d->names +=
other.d->names;
155 d->descriptions +=
other.d->descriptions;
156 d->defaults +=
other.d->defaults;
164class KCmdLineArgsStatic {
167 KCmdLineArgsList *argsList;
174 bool ignoreUnknown : 1;
176 KCmdLineArgs::StdCmdLineArgs mStdargs;
181 KCmdLineArgsStatic ();
183 ~KCmdLineArgsStatic ();
203 static QByteArray encodeOutput(
const QString &str);
209 void printQ(
const QString &msg);
232 static void findOption(
const QByteArray &
optv,
const QByteArray &
_opt,
241 static void parseAllArgs();
250 static void removeArgs(
const QByteArray &
id);
255KCmdLineArgsStatic::KCmdLineArgsStatic () {
264 ignoreUnknown =
false;
268 codec = QTextCodec::codecForLocale();
273 qt_options.add(
"display <displayname>",
ki18n(
"Use the X-server display 'displayname'"));
274#elif defined(Q_WS_QWS)
275 qt_options.add(
"display <displayname>",
ki18n(
"Use the QWS display 'displayname'"));
278 qt_options.add(
"session <sessionId>",
ki18n(
"Restore the application for the given 'sessionId'"));
279 qt_options.add(
"cmap",
ki18n(
"Causes the application to install a private color\nmap on an 8-bit display"));
280 qt_options.add(
"ncols <count>",
ki18n(
"Limits the number of colors allocated in the color\ncube on an 8-bit display, if the application is\nusing the QApplication::ManyColor color\nspecification"));
281 qt_options.add(
"nograb",
ki18n(
"tells Qt to never grab the mouse or the keyboard"));
282 qt_options.add(
"dograb",
ki18n(
"running under a debugger can cause an implicit\n-nograb, use -dograb to override"));
283 qt_options.add(
"sync",
ki18n(
"switches to synchronous mode for debugging"));
284 qt_options.add(
"fn");
285 qt_options.add(
"font <fontname>",
ki18n(
"defines the application font"));
286 qt_options.add(
"bg");
287 qt_options.add(
"background <color>",
ki18n(
"sets the default background color and an\napplication palette (light and dark shades are\ncalculated)"));
288 qt_options.add(
"fg");
289 qt_options.add(
"foreground <color>",
ki18n(
"sets the default foreground color"));
290 qt_options.add(
"btn");
291 qt_options.add(
"button <color>",
ki18n(
"sets the default button color"));
292 qt_options.add(
"name <name>",
ki18n(
"sets the application name"));
293 qt_options.add(
"title <title>",
ki18n(
"sets the application title (caption)"));
294 qt_options.add(
"testability",
ki18n(
"load the testability framework"));
296 qt_options.add(
"visual TrueColor",
ki18n(
"forces the application to use a TrueColor visual on\nan 8-bit display"));
297 qt_options.add(
"inputstyle <inputstyle>",
ki18n(
"sets XIM (X Input Method) input style. Possible\nvalues are onthespot, overthespot, offthespot and\nroot"));
298 qt_options.add(
"im <XIM server>",
ki18n(
"set XIM server"));
299 qt_options.add(
"noxim",
ki18n(
"disable XIM"));
302 qt_options.add(
"qws",
ki18n(
"forces the application to run as QWS Server"));
304 qt_options.add(
"reverse",
ki18n(
"mirrors the whole layout of widgets"));
305 qt_options.add(
"stylesheet <file.qss>",
ki18n(
"applies the Qt stylesheet to the application widgets"));
306 qt_options.add(
"graphicssystem <system>",
ki18n(
"use a different graphics system instead of the default one, options are raster and opengl (experimental)"));
307 qt_options.add(
"qmljsdebugger <port>",
ki18n(
"QML JS debugger information. Application must be\nbuilt with -DQT_DECLARATIVE_DEBUG for the debugger to be\nenabled"));
309 kde_options.add(
"caption <caption>",
ki18n(
"Use 'caption' as name in the titlebar"));
310 kde_options.add(
"icon <icon>",
ki18n(
"Use 'icon' as the application icon"));
311 kde_options.add(
"config <filename>",
ki18n(
"Use alternative configuration file"));
312 kde_options.add(
"nocrashhandler",
ki18n(
"Disable crash handler, to get core dumps"));
314 kde_options.add(
"waitforwm",
ki18n(
"Waits for a WM_NET compatible windowmanager"));
316 kde_options.add(
"style <style>",
ki18n(
"sets the application GUI style"));
317 kde_options.add(
"geometry <geometry>",
ki18n(
"sets the client geometry of the main widget - see man X for the argument format (usually WidthxHeight+XPos+YPos)"));
319 kde_options.add(
"smkey <sessionKey>");
323KCmdLineArgsStatic::~KCmdLineArgsStatic ()
334class KCmdLineArgsPrivate
336 friend class KCmdLineArgsStatic;
342 , parsedOptionList(0)
347 ~KCmdLineArgsPrivate()
349 delete parsedOptionList;
350 delete parsedArgList;
355 KCmdLineParsedOptions *parsedOptionList;
356 KCmdLineParsedArgs *parsedArgList;
371 void setOption(
const QByteArray &
option,
const QByteArray &value);
378 void addArgument(
const QByteArray &
argument);
400KCmdLineArgsStatic::decodeInput(
const QByteArray &
rawstr)
402 return s->codec->toUnicode(
rawstr);
406KCmdLineArgsStatic::encodeOutput(
const QString &str)
408 return s->codec->fromUnicode(str);
412KCmdLineArgsStatic::printQ(
const QString &msg)
422 const QByteArray &_version,
436 s->ignoreUnknown =
true;
443 _argv[0] = (
char *)
s->encodeOutput(
ab->appName()).data();
457 fprintf(
stderr,
"Passing null-pointer to 'argv' is not allowed.\n\n");
465 char *p =
strrchr(
s->all_argv[0], QDir::separator().toLatin1());
469 s->appName =
s->all_argv[0];
474 s->mCwd = QDir::currentPath().toLocal8Bit();
480 return QString::fromLocal8Bit(
s->mCwd);
486 return s->decodeInput(
s->appName);
504 const QByteArray &
id,
const QByteArray &
afterId)
507 s->argsList =
new KCmdLineArgsList;
509 int pos =
s->argsList->count();
511 if (pos > 0 && !
id.isEmpty() &&
s->argsList->last()->d->name.isEmpty())
514 KCmdLineArgsList::Iterator args;
516 for(args =
s->argsList->begin(); args !=
s->argsList->end(); ++args, i++)
518 if (
id == (*args)->d->id) {
530 s->argsList->insert(pos,
new KCmdLineArgs(options, name,
id));
541 s->removeArgs(
"kde");
542 s->removeArgs(
"kuniqueapp");
546 uint
count =
s->argsList ?
s->argsList->count() : 0;
551 KCmdLineArgsList::Iterator args;
552 for(args =
s->argsList->begin(); args !=
s->argsList->end(); ++args)
554 ds << (*args)->d->id;
555 (*args)->d->save(
ds);
566 s->removeArgs(
"kde");
567 s->removeArgs(
"kuniqueapp");
569 KCmdLineArgsList::Iterator args;
571 for(args =
s->argsList->begin(); args !=
s->argsList->end(); ++args)
594 for(args =
s->argsList->begin(); args !=
s->argsList->end(); ++args)
596 if ((*args)->d->id ==
id)
598 (*args)->d->load(
ds);
604 kWarning() <<
"Argument definitions for" <<
id <<
"not found!";
615 KCmdLineArgsList::Iterator args =
s->argsList->begin();
616 while(args !=
s->argsList->end())
618 if ((*args)->d->id ==
id)
630void KCmdLineArgsStatic::removeArgs(
const QByteArray &
id)
634 KCmdLineArgsList::Iterator args =
s->argsList->begin();
635 while(args !=
s->argsList->end())
637 if ((*args)->d->id ==
id)
646 if (args !=
s->argsList->end()) {
648 s->argsList->erase(args);
660 for (
int i = 0; i < options.d->names.size(); i++)
680 int len =
opt.length();
689 if (options.d->descriptions[i].isEmpty())
692 if (i >= options.d->names.size())
716 def = options.d->defaults[i];
725KCmdLineArgsStatic::findOption(
const QByteArray &
optv,
const QByteArray &
_opt,
728 KCmdLineArgsList::Iterator args =
s->argsList->begin();
733 int j =
opt.indexOf(
'=');
742 while (args !=
s->argsList->end())
749 if ((args ==
s->argsList->end()) &&
750 (
optv.startsWith(
'-') && !
optv.startsWith(
"--")))
759 args =
s->argsList->begin();
760 while (args !=
s->argsList->end())
768 if (args ==
s->argsList->end())
775 if (p <
optv.length())
780 else if (result == 3)
791 args =
s->argsList->end();
795 if (args ==
s->argsList->end() || !result)
797 if (
s->ignoreUnknown)
803 if ((result & 4) != 0)
813 if (
s->ignoreUnknown)
821 if (i >=
s->all_argc)
837KCmdLineArgsStatic::parseAllArgs()
845 foreach(
const QByteArray& name,
appOptions->d->options.d->names)
851 for(
int i = 1; i <
s->all_argc; i++)
856 if ((
s->all_argv[i][0] ==
'-') &&
s->all_argv[i][1] &&
inOptions)
859 QByteArray
orig =
s->all_argv[i];
861 if (
option.startsWith(
'-'))
874 else if (
option.startsWith(
"help-"))
880 else if (
option.startsWith(
"psn_"))
888 s->printQ(
i18nc(
"@info:shell message on appcmd --version; do not translate 'Development Platform'"
889 "%3 application name, other %n version strings",
891 "KDE Development Platform: %2\n"
895 s->about->programName(),
s->about->version()));
897 }
else if (
option ==
"license")
900 s->printQ(
s->about->license());
901 s->printQ(QString::fromLatin1(
"\n"));
903 }
else if (
option ==
"author") {
907 if ( !authors.isEmpty() ) {
911 if ( !(*it).emailAddress().isEmpty() )
912 email = QString::fromLatin1(
" <") + (*it).emailAddress() +
QLatin1String(
">");
915 s->printQ(
i18nc(
"the 2nd argument is a list of name+address, one on each line",
"%1 was written by\n%2",
QString(
s->about->programName()) ,
authorlist ) );
918 s->printQ(
i18n(
"This application was written by somebody who wants to remain anonymous.") );
922 if (!
s->about->customAuthorTextEnabled ())
924 if (
s->about->bugAddress().isEmpty() ||
s->about->bugAddress() ==
QLatin1String(
"submit@bugs.kde.org") )
925 s->printQ(
i18n(
"Please use http://bugs.kde.org to report bugs.\n" ) );
927 s->printQ(
i18n(
"Please report bugs to %1.\n" ,
s->about->bugAddress()) );
931 s->printQ(
s->about->customAuthorPlainText()+
QLatin1Char(
'\n'));
936 if (
option.startsWith(
"no"))
939 foreach(
const QByteArray& name,
appOptions->d->options.d->names)
941 if (name.contains(
option + QByteArray(
" ")) && name.contains(
'<'))
961 if (
s->ignoreUnknown)
997 fprintf(
stderr,
"Application has not called KCmdLineArgs::init(...).\n\n");
1032 fprintf(
stderr,
"The \"qt\" options have not be added to KCmdLineArgs!\n\n");
1040 fprintf(
stderr,
"Application has not called KCmdLineArgs::init(...).\n\n");
1050 for(; i < count; i++)
1088 QString tmp =
i18n(
"Use --help to get a list of available command line options.");
1106 KCmdLineArgsList::Iterator args = --(
s->argsList->end());
1108 if ((*args)->d->id.isEmpty() && ((*args)->d->options.d->names.size() > 0) &&
1109 !(*args)->d->options.d->names[0].startsWith(
'+'))
1111 usage =
i18n(
"[options] ")+usage;
1116 if (!(*args)->d->name.isEmpty())
1118 usage =
i18n(
"[%1-options]", (*args)->d->name.toString())+
QLatin1Char(
' ')+usage;
1120 if (args ==
s->argsList->begin())
1129 for (
int i = 0; i <
option.d->names.size(); i++)
1134 else if (
opt_name.startsWith(
"!+") )
1142 s->printQ(
i18n(
"\nGeneric options:\n"));
1144 .arg(
i18n(
"Show help about options")));
1146 args =
s->argsList->begin();
1147 while(args !=
s->argsList->end())
1149 if (!(*args)->d->name.isEmpty() && !(*args)->d->id.isEmpty())
1151 QString option = QString::fromLatin1(
"--help-%1").arg(QString::fromLatin1((*args)->d->id));
1152 QString desc =
i18n(
"Show %1 specific options", (*args)->d->name.toString());
1161 s->printQ(
optionFormatString.arg(QString::fromLatin1(
"-v, --version"),-25).arg(
i18n(
"Show version information")));
1162 s->printQ(
optionFormatString.arg(QString::fromLatin1(
"--license"),-25).arg(
i18n(
"Show license information")));
1165 args =
s->argsList->begin();
1171 while(args !=
s->argsList->end())
1173 if (
id == (*args)->d->id)
break;
1178 while(args !=
s->argsList->end())
1183 if (!(*args)->d->name.isEmpty())
1188 while (args !=
s->argsList->end())
1193 for (
int i = 0; i <
option.d->names.size(); i++)
1199 if (!
option.d->descriptions[i].isEmpty()) {
1204 if (
option.d->names[i].startsWith(
':'))
1217 if (
option.d->names[i].isEmpty())
1233 description =
dl.first();
1234 dl.erase(
dl.begin() );
1236 QByteArray name =
option.d->names[i];
1237 if (name.startsWith(
'!'))
1240 if (name.startsWith(
'+'))
1244 s->printQ(
i18n(
"\nArguments:\n"));
1249 if (name.startsWith(
'[') && name.endsWith(
']'))
1250 name = name.mid(1, name.length()-2);
1261 if ((name.length() == 1) || (name[1] ==
' '))
1272 if (
option.d->defaults[i].isEmpty())
1279 .arg(description,
option.d->defaults[i]));
1284 for(QStringList::Iterator
it =
dl.begin();
1293 if (args ==
s->argsList->end() || !(*args)->d->name.isEmpty() || (*args)->d->id.isEmpty())
1313 const QByteArray &
_id)
1323 if (!
s.isDestroyed() &&
s->argsList)
1324 s->argsList->removeAll(
this);
1337 delete d->parsedArgList; d->parsedArgList = 0;
1338 delete d->parsedOptionList; d->parsedOptionList = 0;
1344 delete s->argsList;
s->argsList = 0;
1351 if (parsedOptionList)
1352 ds << (*(parsedOptionList));
1357 ds << (*(parsedArgList));
1365 if (!parsedOptionList) parsedOptionList =
new KCmdLineParsedOptions;
1366 if (!parsedArgList) parsedArgList =
new KCmdLineParsedArgs;
1368 ds >> (*(parsedOptionList));
1369 ds >> (*(parsedArgList));
1371 if (parsedOptionList->count() == 0)
1373 delete parsedOptionList; parsedOptionList = 0;
1375 if (parsedArgList->count() == 0)
1377 delete parsedArgList; parsedArgList = 0;
1382KCmdLineArgsPrivate::setOption(
const QByteArray &
opt,
bool enabled)
1393 if (!parsedOptionList) {
1394 parsedOptionList =
new KCmdLineParsedOptions;
1398 parsedOptionList->insert(
opt,
"t" );
1400 parsedOptionList->insert(
opt,
"f" );
1404KCmdLineArgsPrivate::setOption(
const QByteArray &
opt,
const QByteArray &value)
1411 if (
opt ==
"qmljsdebugger") {
1422#if defined(Q_WS_X11) || defined(Q_WS_QWS)
1430 if (!parsedOptionList) {
1431 parsedOptionList =
new KCmdLineParsedOptions;
1434 parsedOptionList->insertMulti(
opt, value );
1442 if (d->parsedOptionList)
1444 value = d->parsedOptionList->value(
opt);
1446 if (!value.isEmpty())
1447 return QString::fromLocal8Bit(value);
1453 int result =
s->findOption( d->options,
opt,
opt_name,
def, dummy) & ~4;
1458 fprintf(
stderr,
"Application requests for getOption(\"%s\") but the \"%s\" option\n",
1460 fprintf(
stderr,
"has never been specified via addCmdLineOptions( ... )\n\n");
1472 if (!d->parsedOptionList)
1477 QByteArray value = d->parsedOptionList->take(
opt);
1478 if (value.isEmpty())
1480 result.prepend(QString::fromLocal8Bit(value));
1490 d->parsedOptionList->insertMulti(
opt, str.toLocal8Bit());
1503 KCmdLineArgsList::Iterator args =
s->argsList->begin();
1504 while (args !=
s->argsList->end())
1507 result =
s->findOption((*args)->d->options,
opt,
opt_name,
def, dummy) & ~4;
1515 fprintf(
stderr,
"Application requests for isSet(\"%s\") but the \"%s\" option\n",
1517 fprintf(
stderr,
"has never been specified via addCmdLineOptions( ... )\n\n");
1524 if (d->parsedOptionList)
1526 value = d->parsedOptionList->value(
opt);
1529 if (!value.isEmpty())
1534 return (value.at(0) ==
't');
1542 return (result == 2);
1548 return d->parsedArgList?d->parsedArgList->count():0;
1554 if (!d->parsedArgList || (
n >= (
int) d->parsedArgList->count()))
1556 fprintf(
stderr,
"\n\nFAILURE (KCmdLineArgs): Argument out of bounds\n");
1557 fprintf(
stderr,
"Application requests for arg(%d) without checking count() first.\n",
1564 return QString::fromLocal8Bit(d->parsedArgList->at(
n));
1594KCmdLineArgsPrivate::addArgument(
const QByteArray &
argument)
1597 parsedArgList =
new KCmdLineParsedArgs;
1606 tmpopt.add(
"tempfile",
ki18n(
"The files/URLs opened by the application will be deleted after use") );
1613 return args && args->
isSet(
"tempfile" );
1620 for(
int i = 0; i <
s->all_argc; i++) {
1621 char*
arg =
s->all_argv[i];
1624 lst.append(QString::fromLocal8Bit(arg));
This class is used to store information about a program.
A class for command-line argument handling.
bool isSet(const QByteArray &option) const
Read out a boolean option or check for the presence of string option.
static QStringList allArguments()
Returns the list of command-line arguments.
QStringList getOptionList(const QByteArray &option) const
Read out all occurrences of a string option.
~KCmdLineArgs()
Destructor.
KUrl url(int n) const
Read out an argument representing a URL.
KCmdLineArgs(const KCmdLineOptions &_options, const KLocalizedString &_name, const QByteArray &_id)
Constructor.
static char ** qtArgv()
Returns command line options for consumption by Qt after parsing them in a way that is consistent wit...
static void reset()
Reset all option definitions, i.e.
static void usageError(const QString &error)
Print an error to stderr and the usage help to stdout and exit.
static void addTempFileOption()
Add standard option –tempfile.
void clear()
Clear all options and arguments.
static void enable_i18n()
Enable i18n to be able to print a translated error message.
static void saveAppArgs(QDataStream &)
static QString cwd()
Get the CWD (Current Working Directory) associated with the current command line arguments.
static void usage(const QByteArray &id=QByteArray())
Print the usage help to stdout and exit.
static bool isTempFileSet()
static KUrl makeURL(const QByteArray &urlArg)
Used by url().
static int & qtArgc()
Returns the number of arguments returned by qtArgv()
static QString appName()
Get the appname according to argv[0].
static const KAboutData * aboutData()
Returns the KAboutData for consumption by KComponentData.
static void init(int argc, char **argv, const QByteArray &appname, const QByteArray &catalog, const KLocalizedString &programName, const QByteArray &version, const KLocalizedString &description=KLocalizedString(), StdCmdLineArgs stdargs=StdCmdLineArgs(CmdLineArgQt|CmdLineArgKDE))
Initialize class.
static void setCwd(const QByteArray &cwd)
Made public for apps that don't use KCmdLineArgs To be done before makeURL, to set the current workin...
static KCmdLineArgs * parsedArgs(const QByteArray &id=QByteArray())
Access parsed arguments.
int count() const
Read the number of arguments that aren't options (but, for example, filenames).
static void addCmdLineOptions(const KCmdLineOptions &options, const KLocalizedString &name=KLocalizedString(), const QByteArray &id=QByteArray(), const QByteArray &afterId=QByteArray())
Add options to your application.
static void addStdCmdLineOptions(StdCmdLineArgs stdargs=StdCmdLineArgs(CmdLineArgQt|CmdLineArgKDE))
add standard Qt/KDE command-line args
QString arg(int n) const
Read out an argument.
QString getOption(const QByteArray &option) const
Read out a string option.
static void loadAppArgs(QDataStream &)
Load arguments from a stream.
Class that holds command line options.
KCmdLineOptions & operator=(const KCmdLineOptions &options)
Assignment operator.
KCmdLineOptions()
Constructor.
KCmdLineOptions & add(const QByteArray &name, const KLocalizedString &description=KLocalizedString(), const QByteArray &defaultValue=QByteArray())
Add command line option, by providing its name, description, and possibly a default value.
~KCmdLineOptions()
Destructor.
Class for producing and handling localized messages.
Represents and parses a URL.
void cleanPath(const CleanPathOption &options=SimplifyDirSeparators)
Resolves "." and ".." components in path.
void setPath(const QString &path)
static bool isRelativeUrl(const QString &_url)
Convenience function.
static QString escape(const QString &text)
Convert &, ", ', <, > characters into XML entities &, <, >, ', ", respectively.
#define K_GLOBAL_STATIC(TYPE, NAME)
This macro makes it easy to use non-POD types as global statics.
QString defaultValue(const QString &t)
KLocalizedString ki18n(const char *msg)
Creates localized string from a given message.
QString i18n(const char *text)
Returns a localized version of a string.
QString i18nc(const char *ctxt, const char *text)
Returns a localized version of a string and a context.