• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • sources
  • kde-4.14
  • kdelibs
  • kdecore
  • kernel
kcmdlineargs.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 1999 Waldo Bastian <bastian@kde.org>
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Library General Public
6  License version 2 as published by the Free Software Foundation.
7 
8  This library is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  Library General Public License for more details.
12 
13  You should have received a copy of the GNU Library General Public License
14  along with this library; see the file COPYING.LIB. If not, write to
15  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16  Boston, MA 02110-1301, USA.
17 */
18 
19 #include "kcmdlineargs.h"
20 #include <kdebug.h>
21 
22 #include <config.h>
23 
24 #include <sys/param.h>
25 
26 #include <assert.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <locale.h>
32 
33 #ifdef HAVE_LIMITS_H
34 #include <limits.h>
35 #endif
36 
37 #include <QtCore/QDir>
38 #include <QtCore/QFile>
39 #include <QtCore/QHash>
40 #include <QtCore/QTextCodec>
41 
42 #include "kaboutdata.h"
43 #include "klocale.h"
44 #include "kdeversion.h"
45 #include "kcomponentdata.h"
46 #include "kglobal.h"
47 #include "kurl.h"
48 
49 #include "kuitsemantics_p.h" // for escaping arguments in i18n
50 
51 // -----------------------------------------------------------------------------
52 // Design notes:
53 //
54 // These classes deal with a lot of text, some of which needs to be
55 // marked for translation. Since at the time when these object and calls are
56 // made the translation catalogs are usually still not initialized, the
57 // translation has to be delayed. This is achieved by using KLocalizedString
58 // for translatable strings. KLocalizedStrings are produced by ki18n* calls,
59 // instead of the more usuall i18n* calls which produce QString by trying to
60 // translate immediately.
61 //
62 // All the non-translatable string arguments to methods are taken QByteArray,
63 // all the translatable are KLocalizedString. The getter methods always return
64 // proper QString: the non-translatable strings supplied by the code are
65 // treated with QString::fromUtf8(), those coming from the outside with
66 // QTextCodec::toUnicode(), and translatable strings are finalized to QStrings
67 // at the point of getter calls (i.e. delayed translation).
68 //
69 // The code below uses locally defined s->decodeInput(QByteArray) and
70 // s->encodeOutput(QString) calls to centralize the conversion of raw external
71 // bytes (instead of QString::to/fromLocal8Bit(), QFile::decodeName, etc.)
72 // -----------------------------------------------------------------------------
73 
74 #ifdef Q_WS_X11
75 #define DISPLAY "DISPLAY"
76 #elif defined(Q_WS_QWS)
77 #define DISPLAY "QWS_DISPLAY"
78 #else
79 #define DISPLAY "NODISPLAY"
80 #endif
81 
82 //
83 // Helper classes
84 //
85 
86 class KCmdLineParsedOptions : public QHash<QByteArray,QByteArray>
87 {
88 public:
89  KCmdLineParsedOptions() { }
90 };
91 
92 class KCmdLineParsedArgs : public QList<QByteArray>
93 {
94 public:
95  KCmdLineParsedArgs() { }
96 };
97 
98 
99 class KCmdLineArgsList: public QList<KCmdLineArgs*>
100 {
101 public:
102  KCmdLineArgsList() { }
103  ~KCmdLineArgsList() {
104  while (count())
105  delete takeFirst();
106  }
107 };
108 
109 //
110 // KCmdLineOptions
111 //
112 
113 class KCmdLineOptionsPrivate {
114  public:
115  QList<QByteArray> names;
116  QList<KLocalizedString> descriptions;
117  QStringList defaults;
118 };
119 
120 KCmdLineOptions::KCmdLineOptions ()
121 : d(new KCmdLineOptionsPrivate)
122 {}
123 
124 KCmdLineOptions::~KCmdLineOptions ()
125 {
126  delete d;
127 }
128 
129 KCmdLineOptions::KCmdLineOptions (const KCmdLineOptions &options)
130 : d(new KCmdLineOptionsPrivate(*(options.d)))
131 {
132 }
133 
134 KCmdLineOptions& KCmdLineOptions::operator= (const KCmdLineOptions &options)
135 {
136  if (this != &options) {
137  *d = *(options.d);
138  }
139  return *this;
140 }
141 
142 KCmdLineOptions &KCmdLineOptions::add (const QByteArray &name,
143  const KLocalizedString &description,
144  const QByteArray &defaultValue)
145 {
146  d->names.append(name);
147  d->descriptions.append(description);
148  d->defaults.append(QString::fromUtf8(defaultValue));
149  return *this;
150 }
151 
152 KCmdLineOptions &KCmdLineOptions::add (const KCmdLineOptions &other)
153 {
154  d->names += other.d->names;
155  d->descriptions += other.d->descriptions;
156  d->defaults += other.d->defaults;
157  return *this;
158 }
159 
160 //
161 // KCmdLineArgs static data and methods
162 //
163 
164 class KCmdLineArgsStatic {
165  public:
166 
167  KCmdLineArgsList *argsList; // All options.
168  const KAboutData *about;
169 
170  int all_argc; // The original argc
171  char **all_argv; // The original argv
172  char *appName;
173  bool parsed : 1; // Whether we have parsed the arguments since calling init
174  bool ignoreUnknown : 1; // Ignore unknown options and arguments
175  QByteArray mCwd; // Current working directory. Important for KUnqiueApp!
176  KCmdLineArgs::StdCmdLineArgs mStdargs;
177 
178  KCmdLineOptions qt_options;
179  KCmdLineOptions kde_options;
180 
181  KCmdLineArgsStatic ();
182 
183  ~KCmdLineArgsStatic ();
184 
185  QTextCodec *codec; // codec for converting raw input to QString
186 
194  static QString decodeInput(const QByteArray &rawstr);
195 
203  static QByteArray encodeOutput(const QString &str);
204 
209  void printQ(const QString &msg);
210 
224  static int findOption(const KCmdLineOptions &options, QByteArray &opt,
225  QByteArray &opt_name, QString &def, bool &enabled);
226 
232  static void findOption(const QByteArray &optv, const QByteArray &_opt,
233  int &i, bool _enabled, bool &moreOptions);
234 
241  static void parseAllArgs();
242 
250  static void removeArgs(const QByteArray &id);
251 };
252 
253 K_GLOBAL_STATIC(KCmdLineArgsStatic, s)
254 
255 KCmdLineArgsStatic::KCmdLineArgsStatic () {
256  // Global data
257  argsList = 0;
258  all_argc = 0;
259  all_argv = 0;
260  appName = 0;
261  mCwd.clear();
262  about = 0;
263  parsed = false;
264  ignoreUnknown = false;
265  mStdargs = 0;
266 
267  // Text codec.
268  codec = QTextCodec::codecForLocale();
269 
270  // Qt options
271  //FIXME: Check if other options are specific to Qt/X11
272 #ifdef Q_WS_X11
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'"));
276 #else
277 #endif
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"));
295 #ifdef Q_WS_X11
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"));
300 #endif
301 #ifdef Q_WS_QWS
302  qt_options.add("qws", ki18n("forces the application to run as QWS Server"));
303 #endif
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"));
308  // KDE options
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"));
313 #ifdef Q_WS_X11
314  kde_options.add("waitforwm", ki18n("Waits for a WM_NET compatible windowmanager"));
315 #endif
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)"));
318 #ifndef Q_WS_WIN
319  kde_options.add("smkey <sessionKey>"); // this option is obsolete and exists only to allow smooth upgrades from sessions
320 #endif
321 }
322 
323 KCmdLineArgsStatic::~KCmdLineArgsStatic ()
324 {
325  delete argsList;
326  // KAboutData object is deleted by ~KCleanUpGlobalStatic.
327  //delete about;
328 }
329 
330 //
331 // KCmdLineArgs private data and methods
332 //
333 
334 class KCmdLineArgsPrivate
335 {
336  friend class KCmdLineArgsStatic;
337 public:
338  KCmdLineArgsPrivate(const KCmdLineOptions &_options, const KLocalizedString &_name, const QByteArray &_id)
339  : options(_options)
340  , name(_name)
341  , id(_id)
342  , parsedOptionList(0)
343  , parsedArgList(0)
344  , isQt(id == "qt")
345  {
346  }
347  ~KCmdLineArgsPrivate()
348  {
349  delete parsedOptionList;
350  delete parsedArgList;
351  }
352  const KCmdLineOptions options;
353  const KLocalizedString name;
354  const QByteArray id;
355  KCmdLineParsedOptions *parsedOptionList;
356  KCmdLineParsedArgs *parsedArgList;
357  bool isQt;
358 
364  void setOption(const QByteArray &option, bool enabled);
365 
371  void setOption(const QByteArray &option, const QByteArray &value);
372 
378  void addArgument(const QByteArray &argument);
379 
385  void save( QDataStream &) const;
386 
392  void load( QDataStream &);
393 };
394 
395 //
396 // Static functions
397 //
398 
399 QString
400 KCmdLineArgsStatic::decodeInput(const QByteArray &rawstr)
401 {
402  return s->codec->toUnicode(rawstr);
403 }
404 
405 QByteArray
406 KCmdLineArgsStatic::encodeOutput(const QString &str)
407 {
408  return s->codec->fromUnicode(str);
409 }
410 
411 void
412 KCmdLineArgsStatic::printQ(const QString &msg)
413 {
414  fprintf(stdout, "%s", encodeOutput(msg).data());
415 }
416 
417 void
418 KCmdLineArgs::init(int _argc, char **_argv,
419  const QByteArray &_appname,
420  const QByteArray &_catalog,
421  const KLocalizedString &_programName,
422  const QByteArray &_version,
423  const KLocalizedString &_description,
424  StdCmdLineArgs stdargs)
425 {
426  init(_argc, _argv,
427  new KAboutData(_appname, _catalog, _programName, _version, _description),
428  stdargs);
429 }
430 
431 void
432 KCmdLineArgs::initIgnore(int _argc, char **_argv, const QByteArray &_appname )
433 {
434  init(_argc, _argv,
435  new KAboutData(_appname, 0, ki18n(_appname), "unknown", ki18n("KDE Application")));
436  s->ignoreUnknown = true;
437 }
438 
439 void
440 KCmdLineArgs::init(const KAboutData* ab)
441 {
442  char **_argv = (char **) malloc(sizeof(char *));
443  _argv[0] = (char *) s->encodeOutput(ab->appName()).data();
444  init(1,_argv,ab, CmdLineArgNone);
445 }
446 
447 
448 void
449 KCmdLineArgs::init(int _argc, char **_argv, const KAboutData *_about, StdCmdLineArgs stdargs)
450 {
451  s->all_argc = _argc;
452  s->all_argv = _argv;
453 
454  if (!s->all_argv)
455  {
456  fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
457  fprintf(stderr, "Passing null-pointer to 'argv' is not allowed.\n\n");
458 
459  assert( 0 );
460  exit(255);
461  }
462 
463  // Strip path from argv[0]
464  if (s->all_argc) {
465  char *p = strrchr(s->all_argv[0], QDir::separator().toLatin1());
466  if (p)
467  s->appName = p+1;
468  else
469  s->appName = s->all_argv[0];
470  }
471 
472  s->about = _about;
473  s->parsed = false;
474  s->mCwd = QDir::currentPath().toLocal8Bit(); //currentPath() uses fromLocal8Bit internally apparently
475  addStdCmdLineOptions(stdargs);
476 }
477 
478 QString KCmdLineArgs::cwd()
479 {
480  return QString::fromLocal8Bit(s->mCwd);
481 }
482 
483 QString KCmdLineArgs::appName()
484 {
485  if (!s->appName) return QString();
486  return s->decodeInput(s->appName);
487 }
488 
492 void KCmdLineArgs::addStdCmdLineOptions(StdCmdLineArgs stdargs) {
493  if (stdargs & KCmdLineArgs::CmdLineArgQt) {
494  KCmdLineArgs::addCmdLineOptions(s->qt_options, ki18n("Qt"), "qt");
495  }
496  if (stdargs & KCmdLineArgs::CmdLineArgKDE) {
497  KCmdLineArgs::addCmdLineOptions(s->kde_options, ki18n("KDE"), "kde");
498  }
499  s->mStdargs = stdargs;
500 }
501 
502 void
503 KCmdLineArgs::addCmdLineOptions( const KCmdLineOptions &options, const KLocalizedString &name,
504  const QByteArray &id, const QByteArray &afterId)
505 {
506  if (!s->argsList)
507  s->argsList = new KCmdLineArgsList;
508 
509  int pos = s->argsList->count();
510  // To make sure that the named options come before unnamed.
511  if (pos > 0 && !id.isEmpty() && s->argsList->last()->d->name.isEmpty())
512  pos--;
513 
514  KCmdLineArgsList::Iterator args;
515  int i = 0;
516  for(args = s->argsList->begin(); args != s->argsList->end(); ++args, i++)
517  {
518  if (id == (*args)->d->id) {
519  return; // Options already present.
520  }
521 
522  // Only check for afterId if it has been given non-empty, as the
523  // unnamed option group should come after all named groups.
524  if (!afterId.isEmpty() && afterId == (*args)->d->id)
525  pos = i+1;
526  }
527 
528  Q_ASSERT( s->parsed == false ); // You must add _ALL_ cmd line options
529  // before accessing the arguments!
530  s->argsList->insert(pos, new KCmdLineArgs(options, name, id));
531 }
532 
533 void
534 KCmdLineArgs::saveAppArgs( QDataStream &ds)
535 {
536  if (!s->parsed)
537  s->parseAllArgs();
538 
539  // Remove Qt and KDE options.
540  s->removeArgs("qt");
541  s->removeArgs("kde");
542  s->removeArgs("kuniqueapp");
543 
544  ds << s->mCwd;
545 
546  uint count = s->argsList ? s->argsList->count() : 0;
547  ds << count;
548 
549  if (!count) return;
550 
551  KCmdLineArgsList::Iterator args;
552  for(args = s->argsList->begin(); args != s->argsList->end(); ++args)
553  {
554  ds << (*args)->d->id;
555  (*args)->d->save(ds);
556  }
557 }
558 
559 void
560 KCmdLineArgs::loadAppArgs( QDataStream &ds)
561 {
562  s->parsed = true; // don't reparse argc/argv!
563 
564  // Remove Qt and KDE options.
565  s->removeArgs("qt");
566  s->removeArgs("kde");
567  s->removeArgs("kuniqueapp");
568 
569  KCmdLineArgsList::Iterator args;
570  if ( s->argsList ) {
571  for(args = s->argsList->begin(); args != s->argsList->end(); ++args)
572  {
573  (*args)->clear();
574  }
575  }
576 
577  if (ds.atEnd())
578  return;
579 
580  QByteArray qCwd;
581  ds >> qCwd;
582 
583  s->mCwd = qCwd;
584 
585  uint count;
586  ds >> count;
587 
588  while(count--)
589  {
590  QByteArray id;
591  ds >> id;
592  Q_ASSERT( s->argsList );
593  bool found = false;
594  for(args = s->argsList->begin(); args != s->argsList->end(); ++args)
595  {
596  if ((*args)->d->id == id)
597  {
598  (*args)->d->load(ds);
599  found = true;
600  break;
601  }
602  }
603  if (!found) {
604  kWarning() << "Argument definitions for" << id << "not found!";
605  // The next ds >> id will do nonsensical things...
606  }
607  }
608  s->parsed = true;
609 }
610 
611 KCmdLineArgs *KCmdLineArgs::parsedArgs(const QByteArray &id)
612 {
613  if (!s->argsList)
614  return 0;
615  KCmdLineArgsList::Iterator args = s->argsList->begin();
616  while(args != s->argsList->end())
617  {
618  if ((*args)->d->id == id)
619  {
620  if (!s->parsed)
621  s->parseAllArgs();
622  return *args;
623  }
624  ++args;
625  }
626 
627  return 0;
628 }
629 
630 void KCmdLineArgsStatic::removeArgs(const QByteArray &id)
631 {
632  if (!s->argsList)
633  return;
634  KCmdLineArgsList::Iterator args = s->argsList->begin();
635  while(args != s->argsList->end())
636  {
637  if ((*args)->d->id == id)
638  {
639  if (!s->parsed)
640  s->parseAllArgs();
641  break;
642  }
643  ++args;
644  }
645 
646  if (args != s->argsList->end()) {
647  KCmdLineArgs *a = *args;
648  s->argsList->erase(args);
649  delete a;
650  }
651 }
652 
653 int
654 KCmdLineArgsStatic::findOption(const KCmdLineOptions &options, QByteArray &opt,
655  QByteArray &opt_name, QString &def, bool &enabled)
656 {
657  int result;
658  bool inverse;
659 
660  for (int i = 0; i < options.d->names.size(); i++)
661  {
662  result = 0;
663  inverse = false;
664  opt_name = options.d->names[i];
665  if (opt_name.startsWith(':') || opt_name.isEmpty())
666  {
667  continue;
668  }
669  if (opt_name.startsWith('!'))
670  {
671  opt_name = opt_name.mid(1);
672  result = 4;
673  }
674  if (opt_name.startsWith("no") && !opt_name.contains('<')) // krazy:exclude=strings
675  {
676  opt_name = opt_name.mid(2);
677  inverse = true;
678  }
679 
680  int len = opt.length();
681  if (opt == opt_name.left(len))
682  {
683  opt_name = opt_name.mid(len);
684  if (opt_name.isEmpty())
685  {
686  if (inverse)
687  return result+2;
688 
689  if (options.d->descriptions[i].isEmpty())
690  {
691  i++;
692  if (i >= options.d->names.size())
693  return result+0;
694  QByteArray nextOption = options.d->names[i];
695  int p = nextOption.indexOf(' ');
696  if (p > 0)
697  nextOption = nextOption.left(p);
698  if (nextOption.startsWith('!'))
699  nextOption = nextOption.mid(1);
700  if (nextOption.startsWith("no") && !nextOption.contains('<')) // krazy:exclude=strings
701  {
702  nextOption = nextOption.mid(2);
703  enabled = !enabled;
704  }
705  result = findOption(options, nextOption, opt_name, def, enabled);
706  Q_ASSERT(result);
707  opt = nextOption;
708  return result;
709  }
710 
711  return 1;
712  }
713  if (opt_name.startsWith(' '))
714  {
715  opt_name = opt_name.mid(1);
716  def = options.d->defaults[i];
717  return result+3;
718  }
719  }
720  }
721  return 0;
722 }
723 
724 void
725 KCmdLineArgsStatic::findOption(const QByteArray &optv, const QByteArray &_opt,
726  int &i, bool _enabled, bool &moreOptions)
727 {
728  KCmdLineArgsList::Iterator args = s->argsList->begin();
729  QByteArray opt = _opt;
730  QByteArray opt_name;
731  QString def;
732  QByteArray argument;
733  int j = opt.indexOf('=');
734  if (j != -1)
735  {
736  argument = opt.mid(j+1);
737  opt = opt.left(j);
738  }
739 
740  bool enabled = true;
741  int result = 0;
742  while (args != s->argsList->end())
743  {
744  enabled = _enabled;
745  result = findOption((*args)->d->options, opt, opt_name, def, enabled);
746  if (result) break;
747  ++args;
748  }
749  if ((args == s->argsList->end()) &&
750  (optv.startsWith('-') && !optv.startsWith("--"))) // krazy:exclude=strings
751  {
752  // Option not found check if it is a valid option
753  // in the style of -Pprinter1 or ps -aux
754  int p = 1;
755  while (true)
756  {
757  QByteArray singleCharOption = " "; // krazy:exclude=doublequote_chars
758  singleCharOption[0] = optv[p];
759  args = s->argsList->begin();
760  while (args != s->argsList->end())
761  {
762  enabled = _enabled;
763  result = findOption((*args)->d->options, singleCharOption,
764  opt_name, def, enabled);
765  if (result) break;
766  ++args;
767  }
768  if (args == s->argsList->end())
769  break; // Unknown argument
770 
771  p++;
772  if (result == 1) // Single option
773  {
774  (*args)->d->setOption(singleCharOption, enabled);
775  if (p < optv.length())
776  continue; // Next option
777  else
778  return; // Finished
779  }
780  else if (result == 3) // This option takes an argument
781  {
782  if (argument.isEmpty())
783  {
784  argument = optv.mid(p);
785  }
786  (*args)->d->setOption(singleCharOption, argument);
787  return;
788  }
789  break; // Unknown argument
790  }
791  args = s->argsList->end();
792  result = 0;
793  }
794 
795  if (args == s->argsList->end() || !result)
796  {
797  if (s->ignoreUnknown)
798  return;
799  KCmdLineArgs::enable_i18n();
800  KCmdLineArgs::usageError( i18n("Unknown option '%1'.", QString::fromLocal8Bit(_opt)));
801  }
802 
803  if ((result & 4) != 0)
804  {
805  result &= ~4;
806  moreOptions = false;
807  }
808 
809  if (result == 3) // This option takes an argument
810  {
811  if (!enabled)
812  {
813  if (s->ignoreUnknown)
814  return;
815  KCmdLineArgs::enable_i18n();
816  KCmdLineArgs::usageError( i18n("Unknown option '%1'.", QString::fromLocal8Bit(_opt)));
817  }
818  if (argument.isEmpty())
819  {
820  i++;
821  if (i >= s->all_argc)
822  {
823  KCmdLineArgs::enable_i18n();
824  KCmdLineArgs::usageError( i18nc("@info:shell %1 is cmdoption name","'%1' missing.", QString::fromLocal8Bit(opt_name)));
825  }
826  argument = s->all_argv[i];
827  }
828  (*args)->d->setOption(opt, argument);
829  }
830  else
831  {
832  (*args)->d->setOption(opt, enabled);
833  }
834 }
835 
836 void
837 KCmdLineArgsStatic::parseAllArgs()
838 {
839  bool allowArgs = false;
840  bool inOptions = true;
841  bool everythingAfterArgIsArgs = false;
842  KCmdLineArgs *appOptions = s->argsList->last();
843  if (appOptions->d->id.isEmpty())
844  {
845  foreach(const QByteArray& name, appOptions->d->options.d->names)
846  {
847  everythingAfterArgIsArgs = everythingAfterArgIsArgs || name.startsWith("!+");
848  allowArgs = allowArgs || name.startsWith('+') || everythingAfterArgIsArgs;
849  }
850  }
851  for(int i = 1; i < s->all_argc; i++)
852  {
853  if (!s->all_argv[i])
854  continue;
855 
856  if ((s->all_argv[i][0] == '-') && s->all_argv[i][1] && inOptions)
857  {
858  bool enabled = true;
859  QByteArray orig = s->all_argv[i];
860  QByteArray option = orig.mid(1);
861  if (option.startsWith('-'))
862  {
863  option = option.mid(1);
864  if (option.isEmpty())
865  {
866  inOptions = false;
867  continue;
868  }
869  }
870  if (option == "help")
871  {
872  KCmdLineArgs::usage();
873  }
874  else if (option.startsWith("help-")) // krazy:exclude=strings
875  {
876  KCmdLineArgs::usage(option.mid(5));
877  }
878 #ifdef Q_WS_MAC
879  // skip the finder -psn_* hint
880  else if (option.startsWith("psn_")) // krazy:exclude=strings
881  {
882  continue;
883  }
884 #endif
885  else if ((option == "version") || (option == "v"))
886  {
887  KCmdLineArgs::enable_i18n();
888  s->printQ(i18nc("@info:shell message on appcmd --version; do not translate 'Development Platform'"
889  "%3 application name, other %n version strings",
890  "Qt: %1\n"
891  "KDE Development Platform: %2\n"
892  "%3: %4\n",
893  QString::fromLatin1(qVersion()),
894  QString::fromLatin1(KDE_VERSION_STRING),
895  s->about->programName(), s->about->version()));
896  exit(0);
897  } else if (option == "license")
898  {
899  KCmdLineArgs::enable_i18n();
900  s->printQ(s->about->license());
901  s->printQ(QString::fromLatin1("\n"));
902  exit(0);
903  } else if (option == "author") {
904  KCmdLineArgs::enable_i18n();
905  if ( s->about ) {
906  const QList<KAboutPerson> authors = s->about->authors();
907  if ( !authors.isEmpty() ) {
908  QString authorlist;
909  for (QList<KAboutPerson>::ConstIterator it = authors.begin(); it != authors.end(); ++it ) {
910  QString email;
911  if ( !(*it).emailAddress().isEmpty() )
912  email = QString::fromLatin1(" &lt;") + (*it).emailAddress() + QLatin1String("&gt;");
913  authorlist += QString::fromLatin1(" ") + (*it).name() + email + QLatin1Char('\n');
914  }
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 ) );
916  }
917  } else {
918  s->printQ( i18n("This application was written by somebody who wants to remain anonymous.") );
919  }
920  if (s->about)
921  {
922  if (!s->about->customAuthorTextEnabled ())
923  {
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" ) );
926  else
927  s->printQ( i18n( "Please report bugs to %1.\n" , s->about->bugAddress()) );
928  }
929  else
930  {
931  s->printQ(s->about->customAuthorPlainText()+QLatin1Char('\n'));
932  }
933  }
934  exit(0);
935  } else {
936  if (option.startsWith("no")) // krazy:exclude=strings
937  {
938  bool noHasParameter=false;
939  foreach(const QByteArray& name, appOptions->d->options.d->names)
940  {
941  if (name.contains(option + QByteArray(" ")) && name.contains('<'))
942  {
943  noHasParameter=true;
944  break;
945  }
946  }
947  if (!noHasParameter)
948  {
949  option = option.mid(2);
950  enabled = false;
951  }
952  }
953  s->findOption(orig, option, i, enabled, inOptions);
954  }
955  }
956  else
957  {
958  // Check whether appOptions allows these arguments
959  if (!allowArgs)
960  {
961  if (s->ignoreUnknown)
962  continue;
963  KCmdLineArgs::enable_i18n();
964  KCmdLineArgs::usageError(i18n("Unexpected argument '%1'.", KuitSemantics::escape(s->decodeInput(s->all_argv[i]))));
965  }
966  else
967  {
968  appOptions->d->addArgument(s->all_argv[i]);
969  if (everythingAfterArgIsArgs)
970  inOptions = false;
971  }
972  }
973  }
974  s->parsed = true;
975 }
976 
977 int & KCmdLineArgs::qtArgc()
978 {
979  if (!s->argsList)
980  addStdCmdLineOptions(CmdLineArgKDE|CmdLineArgQt); // Lazy bastards!
981 
982  static int qt_argc = -1;
983  if( qt_argc != -1 )
984  return qt_argc;
985 
986  if (!(s->mStdargs & KCmdLineArgs::CmdLineArgQt))
987  {
988  qt_argc = 2;
989  return qt_argc;
990  }
991 
992  KCmdLineArgs *args = parsedArgs("qt");
993  Q_ASSERT(args); // No qt options have been added!
994  if (!s->all_argv)
995  {
996  fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
997  fprintf(stderr, "Application has not called KCmdLineArgs::init(...).\n\n");
998 
999  assert( 0 );
1000  exit(255);
1001  }
1002 
1003  Q_ASSERT(s->all_argc >= (args->count()+1));
1004  qt_argc = args->count() +1;
1005  return qt_argc;
1006 }
1007 
1008 static char** s_qt_argv;
1009 
1010 char **
1011 KCmdLineArgs::qtArgv()
1012 {
1013  if (!s->argsList)
1014  addStdCmdLineOptions(CmdLineArgKDE|CmdLineArgQt); // Lazy bastards!
1015 
1016  if( s_qt_argv != NULL )
1017  return s_qt_argv;
1018 
1019  if (!(s->mStdargs & KCmdLineArgs::CmdLineArgQt))
1020  {
1021  s_qt_argv = new char*[2];
1022  s_qt_argv[0] = qstrdup(s->all_argc?s->all_argv[0]:"");
1023  s_qt_argv[1] = 0;
1024 
1025  return s_qt_argv;
1026  }
1027 
1028  KCmdLineArgs *args = parsedArgs("qt");
1029  if (!args)
1030  {
1031  fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
1032  fprintf(stderr, "The \"qt\" options have not be added to KCmdLineArgs!\n\n");
1033 
1034  assert( 0 );
1035  exit(255);
1036  }
1037  if (!s->all_argv)
1038  {
1039  fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
1040  fprintf(stderr, "Application has not called KCmdLineArgs::init(...).\n\n");
1041 
1042  assert( 0 );
1043  exit(255);
1044  }
1045 
1046  int count=args->count();
1047  s_qt_argv = new char*[ count + 2 ];
1048  s_qt_argv[0] = qstrdup(s->all_argc?s->all_argv[0]:"");
1049  int i = 0;
1050  for(; i < count; i++)
1051  {
1052  s_qt_argv[i+1] = qstrdup(args->d->parsedArgList->at(i));
1053  }
1054  s_qt_argv[i+1] = 0;
1055 
1056  return s_qt_argv;
1057 }
1058 
1059 const KAboutData *
1060 KCmdLineArgs::aboutData()
1061 {
1062  return s->about;
1063 }
1064 
1065 void
1066 KCmdLineArgs::enable_i18n()
1067 {
1068  // called twice or too late
1069  if (KGlobal::hasLocale())
1070  return;
1071 
1072  if (!KGlobal::hasMainComponent()) {
1073  KComponentData mainComponentData(s->about);
1074  mainComponentData.config();
1075  // mainComponentData is now the main component and won't disappear until KGlobal deletes it
1076  }
1077 }
1078 
1079 void
1080 KCmdLineArgs::usageError(const QString &error)
1081 {
1082  Q_ASSERT(KGlobal::hasLocale());
1083  QByteArray localError = s->encodeOutput(error);
1084  if (localError.endsWith('\n'))
1085  localError.chop(1);
1086  fprintf(stderr, "%s: %s\n", s->appName, localError.data());
1087 
1088  QString tmp = i18n("Use --help to get a list of available command line options.");
1089  localError = s->encodeOutput(tmp);
1090  fprintf(stderr, "%s: %s\n", s->appName, localError.data());
1091  exit(254);
1092 }
1093 
1094 void
1095 KCmdLineArgs::usage(const QByteArray &id)
1096 {
1097  enable_i18n();
1098  Q_ASSERT(s->argsList != 0); // It's an error to call usage(...) without
1099  // having done addCmdLineOptions first!
1100 
1101  QString optionFormatString = QString::fromLatin1(" %1 %2\n");
1102  QString optionFormatStringDef = QString::fromLatin1(" %1 %2 [%3]\n");
1103  QString tmp;
1104  QString usage;
1105 
1106  KCmdLineArgsList::Iterator args = --(s->argsList->end());
1107 
1108  if ((*args)->d->id.isEmpty() && ((*args)->d->options.d->names.size() > 0) &&
1109  !(*args)->d->options.d->names[0].startsWith('+'))
1110  {
1111  usage = i18n("[options] ")+usage;
1112  }
1113 
1114  while(true)
1115  {
1116  if (!(*args)->d->name.isEmpty())
1117  {
1118  usage = i18n("[%1-options]", (*args)->d->name.toString())+QLatin1Char(' ')+usage;
1119  }
1120  if (args == s->argsList->begin())
1121  break;
1122  --args;
1123  }
1124 
1125  KCmdLineArgs *appOptions = s->argsList->last();
1126  if (appOptions->d->id.isEmpty())
1127  {
1128  const KCmdLineOptions &option = appOptions->d->options;
1129  for (int i = 0; i < option.d->names.size(); i++)
1130  {
1131  QByteArray opt_name = option.d->names[i];
1132  if (opt_name.startsWith('+'))
1133  usage += QString::fromLatin1(opt_name.mid(1)) + QLatin1Char(' ');
1134  else if ( opt_name.startsWith("!+") )
1135  usage += QString::fromLatin1(opt_name.mid(2)) + QLatin1Char(' ');
1136  }
1137  }
1138 
1139  s->printQ(i18n("Usage: %1 %2\n", QString::fromLocal8Bit(s->appName), KuitSemantics::escape(usage)));
1140  s->printQ(QLatin1Char('\n')+s->about->shortDescription()+QLatin1Char('\n'));
1141 
1142  s->printQ(i18n("\nGeneric options:\n"));
1143  s->printQ(optionFormatString.arg(QString::fromLatin1("--help"), -25)
1144  .arg(i18n("Show help about options")));
1145 
1146  args = s->argsList->begin();
1147  while(args != s->argsList->end())
1148  {
1149  if (!(*args)->d->name.isEmpty() && !(*args)->d->id.isEmpty())
1150  {
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());
1153 
1154  s->printQ(optionFormatString.arg(option, -25).arg(desc));
1155  }
1156  ++args;
1157  }
1158 
1159  s->printQ(optionFormatString.arg(QString::fromLatin1("--help-all"),-25).arg(i18n("Show all options")));
1160  s->printQ(optionFormatString.arg(QString::fromLatin1("--author"),-25).arg(i18n("Show author information")));
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")));
1163  s->printQ(optionFormatString.arg(QString::fromLatin1("--"), -25).arg(i18n("End of options")));
1164 
1165  args = s->argsList->begin(); // Sets current to 1st.
1166 
1167  bool showAll = (id == "all");
1168 
1169  if (!showAll)
1170  {
1171  while(args != s->argsList->end())
1172  {
1173  if (id == (*args)->d->id) break;
1174  ++args;
1175  }
1176  }
1177 
1178  while(args != s->argsList->end())
1179  {
1180  bool hasArgs = false;
1181  bool hasOptions = false;
1182  QString optionsHeader;
1183  if (!(*args)->d->name.isEmpty())
1184  optionsHeader = i18n("\n%1 options:\n", (*args)->d->name.toString());
1185  else
1186  optionsHeader = i18n("\nOptions:\n");
1187 
1188  while (args != s->argsList->end())
1189  {
1190  const KCmdLineOptions &option = (*args)->d->options;
1191  QByteArray opt;
1192 
1193  for (int i = 0; i < option.d->names.size(); i++)
1194  {
1195  QString description;
1196  QStringList dl;
1197 
1198  QString descriptionFull;
1199  if (!option.d->descriptions[i].isEmpty()) {
1200  descriptionFull = option.d->descriptions[i].toString();
1201  }
1202 
1203  // Option header
1204  if (option.d->names[i].startsWith(':'))
1205  {
1206  if (!descriptionFull.isEmpty())
1207  {
1208  optionsHeader = QLatin1Char('\n')+descriptionFull;
1209  if (!optionsHeader.endsWith(QLatin1Char('\n')))
1210  optionsHeader.append(QLatin1Char('\n'));
1211  hasOptions = false;
1212  }
1213  continue;
1214  }
1215 
1216  // Free-form comment
1217  if (option.d->names[i].isEmpty())
1218  {
1219  if (!descriptionFull.isEmpty())
1220  {
1221  tmp = QLatin1Char('\n')+descriptionFull;
1222  if (!tmp.endsWith(QLatin1Char('\n')))
1223  tmp.append(QLatin1Char('\n'));
1224  s->printQ(tmp);
1225  }
1226  continue;
1227  }
1228 
1229  // Options
1230  if (!descriptionFull.isEmpty())
1231  {
1232  dl = descriptionFull.split(QLatin1Char('\n'), QString::KeepEmptyParts);
1233  description = dl.first();
1234  dl.erase( dl.begin() );
1235  }
1236  QByteArray name = option.d->names[i];
1237  if (name.startsWith('!'))
1238  name = name.mid(1);
1239 
1240  if (name.startsWith('+'))
1241  {
1242  if (!hasArgs)
1243  {
1244  s->printQ(i18n("\nArguments:\n"));
1245  hasArgs = true;
1246  }
1247 
1248  name = name.mid(1);
1249  if (name.startsWith('[') && name.endsWith(']'))
1250  name = name.mid(1, name.length()-2);
1251  s->printQ(optionFormatString.arg(QString::fromLocal8Bit(name), -25).arg(description));
1252  }
1253  else
1254  {
1255  if (!hasOptions)
1256  {
1257  s->printQ(optionsHeader);
1258  hasOptions = true;
1259  }
1260 
1261  if ((name.length() == 1) || (name[1] == ' '))
1262  name = '-'+name;
1263  else
1264  name = "--"+name;
1265  if (descriptionFull.isEmpty())
1266  {
1267  opt = name + ", ";
1268  }
1269  else
1270  {
1271  opt = opt + name;
1272  if (option.d->defaults[i].isEmpty())
1273  {
1274  s->printQ(optionFormatString.arg(QString::fromLatin1(opt), -25).arg(description));
1275  }
1276  else
1277  {
1278  s->printQ(optionFormatStringDef.arg(QString::fromLatin1(opt), -25)
1279  .arg(description, option.d->defaults[i]));
1280  }
1281  opt.clear();
1282  }
1283  }
1284  for(QStringList::Iterator it = dl.begin();
1285  it != dl.end();
1286  ++it)
1287  {
1288  s->printQ(optionFormatString.arg(QString(), -25).arg(*it));
1289  }
1290  }
1291 
1292  ++args;
1293  if (args == s->argsList->end() || !(*args)->d->name.isEmpty() || (*args)->d->id.isEmpty())
1294  break;
1295  }
1296  if (!showAll) break;
1297  }
1298 
1299  exit(0);
1300 }
1301 
1302 //
1303 // Member functions
1304 //
1305 
1311 KCmdLineArgs::KCmdLineArgs( const KCmdLineOptions &_options,
1312  const KLocalizedString &_name,
1313  const QByteArray &_id)
1314  : d(new KCmdLineArgsPrivate(_options, _name, _id))
1315 {
1316 }
1317 
1321 KCmdLineArgs::~KCmdLineArgs()
1322 {
1323  if (!s.isDestroyed() && s->argsList)
1324  s->argsList->removeAll(this);
1325  delete d;
1326 }
1327 
1328 void
1329 KCmdLineArgs::setCwd( const QByteArray &cwd )
1330 {
1331  s->mCwd = cwd;
1332 }
1333 
1334 void
1335 KCmdLineArgs::clear()
1336 {
1337  delete d->parsedArgList; d->parsedArgList = 0;
1338  delete d->parsedOptionList; d->parsedOptionList = 0;
1339 }
1340 
1341 void
1342 KCmdLineArgs::reset()
1343 {
1344  delete s->argsList; s->argsList = 0;
1345  s->parsed = false;
1346 }
1347 
1348 void
1349 KCmdLineArgsPrivate::save( QDataStream &ds) const
1350 {
1351  if (parsedOptionList)
1352  ds << (*(parsedOptionList));
1353  else
1354  ds << quint32(0);
1355 
1356  if (parsedArgList)
1357  ds << (*(parsedArgList));
1358  else
1359  ds << quint32(0);
1360 }
1361 
1362 void
1363 KCmdLineArgsPrivate::load( QDataStream &ds)
1364 {
1365  if (!parsedOptionList) parsedOptionList = new KCmdLineParsedOptions;
1366  if (!parsedArgList) parsedArgList = new KCmdLineParsedArgs;
1367 
1368  ds >> (*(parsedOptionList));
1369  ds >> (*(parsedArgList));
1370 
1371  if (parsedOptionList->count() == 0)
1372  {
1373  delete parsedOptionList; parsedOptionList = 0;
1374  }
1375  if (parsedArgList->count() == 0)
1376  {
1377  delete parsedArgList; parsedArgList = 0;
1378  }
1379 }
1380 
1381 void
1382 KCmdLineArgsPrivate::setOption(const QByteArray &opt, bool enabled)
1383 {
1384  if (isQt)
1385  {
1386  // Qt does it own parsing.
1387  QByteArray argString = "-"; // krazy:exclude=doublequote_chars
1388  if( !enabled )
1389  argString += "no";
1390  argString += opt;
1391  addArgument(argString);
1392  }
1393  if (!parsedOptionList) {
1394  parsedOptionList = new KCmdLineParsedOptions;
1395  }
1396 
1397  if (enabled)
1398  parsedOptionList->insert( opt, "t" ); // krazy:exclude=doublequote_chars
1399  else
1400  parsedOptionList->insert( opt, "f" ); // krazy:exclude=doublequote_chars
1401 }
1402 
1403 void
1404 KCmdLineArgsPrivate::setOption(const QByteArray &opt, const QByteArray &value)
1405 {
1406  if (isQt)
1407  {
1408  // Qt does it's own parsing.
1409  QByteArray argString = "-"; // krazy:exclude=doublequote_chars
1410  argString += opt;
1411  if (opt == "qmljsdebugger") {
1412  // hack: Qt expects the value of the "qmljsdebugger" option to be
1413  // passed using a '=' separator rather than a space, so we recreate it
1414  // correctly.
1415  // See code of QCoreApplicationPrivate::processCommandLineArguments()
1416  addArgument(argString + "=" + value);
1417  } else {
1418  addArgument(argString);
1419  addArgument(value);
1420  }
1421 
1422 #if defined(Q_WS_X11) || defined(Q_WS_QWS)
1423  // Hack coming up!
1424  if (argString == "-display")
1425  {
1426  setenv(DISPLAY, value.data(), true);
1427  }
1428 #endif
1429  }
1430  if (!parsedOptionList) {
1431  parsedOptionList = new KCmdLineParsedOptions;
1432  }
1433 
1434  parsedOptionList->insertMulti( opt, value );
1435 }
1436 
1437 QString
1438 KCmdLineArgs::getOption(const QByteArray &_opt) const
1439 {
1440  QByteArray opt = _opt;
1441  QByteArray value;
1442  if (d->parsedOptionList)
1443  {
1444  value = d->parsedOptionList->value(opt);
1445  }
1446  if (!value.isEmpty())
1447  return QString::fromLocal8Bit(value);
1448 
1449  // Look up the default.
1450  QByteArray opt_name;
1451  QString def;
1452  bool dummy = true;
1453  int result = s->findOption( d->options, opt, opt_name, def, dummy) & ~4;
1454 
1455  if (result != 3)
1456  {
1457  fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
1458  fprintf(stderr, "Application requests for getOption(\"%s\") but the \"%s\" option\n",
1459  opt.data(), opt.data());
1460  fprintf(stderr, "has never been specified via addCmdLineOptions( ... )\n\n");
1461 
1462  Q_ASSERT( 0 );
1463  exit(255);
1464  }
1465  return def;
1466 }
1467 
1468 QStringList
1469 KCmdLineArgs::getOptionList(const QByteArray &opt) const
1470 {
1471  QStringList result;
1472  if (!d->parsedOptionList)
1473  return result;
1474 
1475  while(true)
1476  {
1477  QByteArray value = d->parsedOptionList->take(opt);
1478  if (value.isEmpty())
1479  break;
1480  result.prepend(QString::fromLocal8Bit(value));
1481  }
1482 
1483  // Reinsert items in dictionary
1484  // WABA: This is rather silly, but I don't want to add restrictions
1485  // to the API like "you can only call this function once".
1486  // I can't access all items without taking them out of the list.
1487  // So taking them out and then putting them back is the only way.
1488  Q_FOREACH(const QString &str, result)
1489  {
1490  d->parsedOptionList->insertMulti(opt, str.toLocal8Bit());
1491  }
1492  return result;
1493 }
1494 
1495 bool
1496 KCmdLineArgs::isSet(const QByteArray &_opt) const
1497 {
1498  // Look up the default.
1499  QByteArray opt = _opt;
1500  QByteArray opt_name;
1501  QString def;
1502  int result = 0;
1503  KCmdLineArgsList::Iterator args = s->argsList->begin();
1504  while (args != s->argsList->end())
1505  {
1506  bool dummy = true;
1507  result = s->findOption((*args)->d->options, opt, opt_name, def, dummy) & ~4;
1508  if (result) break;
1509  ++args;
1510  }
1511 
1512  if (result == 0)
1513  {
1514  fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
1515  fprintf(stderr, "Application requests for isSet(\"%s\") but the \"%s\" option\n",
1516  opt.data(), opt.data());
1517  fprintf(stderr, "has never been specified via addCmdLineOptions( ... )\n\n");
1518 
1519  Q_ASSERT( 0 );
1520  exit(255);
1521  }
1522 
1523  QByteArray value;
1524  if (d->parsedOptionList)
1525  {
1526  value = d->parsedOptionList->value(opt);
1527  }
1528 
1529  if (!value.isEmpty())
1530  {
1531  if (result == 3)
1532  return true;
1533  else
1534  return (value.at(0) == 't');
1535  }
1536 
1537  if (result == 3)
1538  return false; // String option has 'false' as default.
1539 
1540  // We return 'true' as default if the option was listed as '-nofork'
1541  // We return 'false' as default if the option was listed as '-fork'
1542  return (result == 2);
1543 }
1544 
1545 int
1546 KCmdLineArgs::count() const
1547 {
1548  return d->parsedArgList?d->parsedArgList->count():0;
1549 }
1550 
1551 QString
1552 KCmdLineArgs::arg(int n) const
1553 {
1554  if (!d->parsedArgList || (n >= (int) d->parsedArgList->count()))
1555  {
1556  fprintf(stderr, "\n\nFAILURE (KCmdLineArgs): Argument out of bounds\n");
1557  fprintf(stderr, "Application requests for arg(%d) without checking count() first.\n",
1558  n);
1559 
1560  Q_ASSERT( 0 );
1561  exit(255);
1562  }
1563 
1564  return QString::fromLocal8Bit(d->parsedArgList->at(n));
1565 }
1566 
1567 KUrl
1568 KCmdLineArgs::url(int n) const
1569 {
1570  return makeURL( arg(n).toUtf8() );
1571 }
1572 
1573 KUrl KCmdLineArgs::makeURL(const QByteArray &_urlArg)
1574 {
1575  const QString urlArg = QString::fromUtf8(_urlArg);
1576  QFileInfo fileInfo(urlArg);
1577  if (!fileInfo.isRelative()) { // i.e. starts with '/', on unix
1578  KUrl result;
1579  result.setPath(QDir::fromNativeSeparators(urlArg));
1580  return result; // Absolute path.
1581  }
1582 
1583  if ( KUrl::isRelativeUrl(urlArg) || fileInfo.exists() ) {
1584  KUrl result;
1585  result.setPath(cwd()+QLatin1Char('/')+urlArg);
1586  result.cleanPath();
1587  return result; // Relative path
1588  }
1589 
1590  return KUrl(urlArg); // Argument is a URL
1591 }
1592 
1593 void
1594 KCmdLineArgsPrivate::addArgument(const QByteArray &argument)
1595 {
1596  if (!parsedArgList)
1597  parsedArgList = new KCmdLineParsedArgs;
1598 
1599  parsedArgList->append(argument);
1600 }
1601 
1602 void
1603 KCmdLineArgs::addTempFileOption()
1604 {
1605  KCmdLineOptions tmpopt;
1606  tmpopt.add( "tempfile", ki18n("The files/URLs opened by the application will be deleted after use") );
1607  KCmdLineArgs::addCmdLineOptions( tmpopt, ki18n("KDE-tempfile"), "kde-tempfile" );
1608 }
1609 
1610 bool KCmdLineArgs::isTempFileSet()
1611 {
1612  KCmdLineArgs* args = KCmdLineArgs::parsedArgs( "kde-tempfile" );
1613  return args && args->isSet( "tempfile" );
1614 }
1615 
1616 QStringList KCmdLineArgs::allArguments()
1617 {
1618  QStringList lst;
1619 
1620  for(int i = 0; i < s->all_argc; i++) {
1621  char* arg = s->all_argv[i];
1622  if (!arg)
1623  continue;
1624  lst.append(QString::fromLocal8Bit(arg));
1625  }
1626  return lst;
1627 }
i18n
QString i18n(const char *text)
Returns a localized version of a string.
Definition: klocalizedstring.h:630
KCmdLineArgs::addCmdLineOptions
static void addCmdLineOptions(const KCmdLineOptions &options, const KLocalizedString &name=KLocalizedString(), const QByteArray &id=QByteArray(), const QByteArray &afterId=QByteArray())
Add options to your application.
Definition: kcmdlineargs.cpp:503
KCmdLineArgs::allArguments
static QStringList allArguments()
Returns the list of command-line arguments.
Definition: kcmdlineargs.cpp:1616
QString::append
QString & append(QChar ch)
QByteArray::clear
void clear()
KCmdLineArgs::getOptionList
QStringList getOptionList(const QByteArray &option) const
Read out all occurrences of a string option.
Definition: kcmdlineargs.cpp:1469
KCmdLineArgs::isTempFileSet
static bool isTempFileSet()
Definition: kcmdlineargs.cpp:1610
kdebug.h
KCmdLineArgs::qtArgc
static int & qtArgc()
Returns the number of arguments returned by qtArgv()
Definition: kcmdlineargs.cpp:977
KAboutData::appName
QString appName() const
Returns the application's internal name.
Definition: kaboutdata.cpp:678
QDir::fromNativeSeparators
QString fromNativeSeparators(const QString &pathName)
kurl.h
KCmdLineArgs::makeURL
static KUrl makeURL(const QByteArray &urlArg)
Used by url().
Definition: kcmdlineargs.cpp:1573
KCmdLineOptions::add
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...
Definition: kcmdlineargs.cpp:142
QByteArray
QByteArray::at
char at(int i) const
kuitsemantics_p.h
KCmdLineArgs::~KCmdLineArgs
~KCmdLineArgs()
Destructor.
Definition: kcmdlineargs.cpp:1321
KCmdLineOptions::~KCmdLineOptions
~KCmdLineOptions()
Destructor.
Definition: kcmdlineargs.cpp:124
KCmdLineArgs::aboutData
static const KAboutData * aboutData()
Returns the KAboutData for consumption by KComponentData.
Definition: kcmdlineargs.cpp:1060
KuitSemantics::escape
static QString escape(const QString &text)
Convert &, ", ', <, > characters into XML entities &, <, >, ', ", respectively.
Definition: kuitsemantics.cpp:1633
ki18n
KLocalizedString ki18n(const char *msg)
Creates localized string from a given message.
Definition: klocalizedstring.cpp:924
QDataStream
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
KCmdLineArgs::parsedArgs
static KCmdLineArgs * parsedArgs(const QByteArray &id=QByteArray())
Access parsed arguments.
Definition: kcmdlineargs.cpp:611
KUrl::isRelativeUrl
static bool isRelativeUrl(const QString &_url)
Convenience function.
Definition: kurl.cpp:160
K_GLOBAL_STATIC
#define K_GLOBAL_STATIC(TYPE, NAME)
This macro makes it easy to use non-POD types as global statics.
Definition: kglobal.h:221
QList::count
int count() const
KCmdLineArgs::cwd
static QString cwd()
Get the CWD (Current Working Directory) associated with the current command line arguments.
Definition: kcmdlineargs.cpp:478
KCmdLineArgs
A class for command-line argument handling.
Definition: kcmdlineargs.h:281
QByteArray::chop
void chop(int n)
KUrl::cleanPath
void cleanPath(const CleanPathOption &options=SimplifyDirSeparators)
Resolves "." and ".." components in path.
Definition: kurl.cpp:759
QByteArray::isEmpty
bool isEmpty() const
KCmdLineArgs::url
KUrl url(int n) const
Read out an argument representing a URL.
Definition: kcmdlineargs.cpp:1568
QByteArray::startsWith
bool startsWith(const QByteArray &ba) const
QList::erase
iterator erase(iterator pos)
quint32
QByteArray::length
int length() const
QDir::currentPath
QString currentPath()
KCmdLineArgs::arg
QString arg(int n) const
Read out an argument.
Definition: kcmdlineargs.cpp:1552
KCmdLineArgs::qtArgv
static char ** qtArgv()
Returns command line options for consumption by Qt after parsing them in a way that is consistent wit...
Definition: kcmdlineargs.cpp:1011
klocale.h
KDE_VERSION_STRING
#define KDE_VERSION_STRING
Version of KDE as string, at compile time.
Definition: kdeversion.h.cmake:47
QDir::separator
QChar separator()
KCmdLineArgs::addTempFileOption
static void addTempFileOption()
Add standard option –tempfile.
Definition: kcmdlineargs.cpp:1603
KCmdLineArgs::usageError
static void usageError(const QString &error)
Print an error to stderr and the usage help to stdout and exit.
Definition: kcmdlineargs.cpp:1080
QTextCodec::codecForLocale
QTextCodec * codecForLocale()
KCmdLineArgs::isSet
bool isSet(const QByteArray &option) const
Read out a boolean option or check for the presence of string option.
Definition: kcmdlineargs.cpp:1496
KUrl
Represents and parses a URL.
Definition: kurl.h:111
i18nc
QString i18nc(const char *ctxt, const char *text)
Returns a localized version of a string and a context.
Definition: klocalizedstring.h:797
KCmdLineArgs::count
int count() const
Read the number of arguments that aren't options (but, for example, filenames).
Definition: kcmdlineargs.cpp:1546
KUrl::setPath
void setPath(const QString &path)
Definition: kurl.cpp:1772
KCmdLineArgs::KCmdLineArgs
KCmdLineArgs(const KCmdLineOptions &_options, const KLocalizedString &_name, const QByteArray &_id)
Constructor.
Definition: kcmdlineargs.cpp:1311
KCmdLineArgs::loadAppArgs
static void loadAppArgs(QDataStream &)
Load arguments from a stream.
Definition: kcmdlineargs.cpp:560
KCmdLineArgs::reset
static void reset()
Reset all option definitions, i.e.
Definition: kcmdlineargs.cpp:1342
QByteArray::indexOf
int indexOf(char ch, int from) const
kglobal.h
KComponentData::config
const KSharedConfig::Ptr & config() const
Returns the general config object ("appnamerc").
Definition: kcomponentdata.cpp:201
QString::fromLocal8Bit
QString fromLocal8Bit(const char *str, int size)
QList::append
void append(const T &value)
QString::fromUtf8
QString fromUtf8(const char *str, int size)
DISPLAY
#define DISPLAY
Definition: kcmdlineargs.cpp:75
QHash
Definition: ksycocafactory.h:28
KCmdLineOptions::KCmdLineOptions
KCmdLineOptions()
Constructor.
Definition: kcmdlineargs.cpp:120
KCmdLineArgs::appName
static QString appName()
Get the appname according to argv[0].
Definition: kcmdlineargs.cpp:483
QList::isEmpty
bool isEmpty() const
KCmdLineArgs::CmdLineArgNone
Definition: kcmdlineargs.h:293
kcmdlineargs.h
QString::isEmpty
bool isEmpty() const
KCmdLineArgs::CmdLineArgQt
Definition: kcmdlineargs.h:290
QString::endsWith
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
QList< KCmdLineArgs * >::Iterator
typedef Iterator
KAboutData
This class is used to store information about a program.
Definition: kaboutdata.h:192
KCmdLineArgs::KCmdLineArgsList
friend class KCmdLineArgsList
Definition: kcmdlineargs.h:284
KCmdLineArgs::usage
static void usage(const QByteArray &id=QByteArray())
Print the usage help to stdout and exit.
Definition: kcmdlineargs.cpp:1095
QList::first
T & first()
QString
QList
Definition: kaboutdata.h:33
s_qt_argv
static char ** s_qt_argv
Definition: kcmdlineargs.cpp:1008
QTextCodec
KCmdLineArgs::CmdLineArgKDE
Definition: kcmdlineargs.h:291
QByteArray::mid
QByteArray mid(int pos, int len) const
QDataStream::atEnd
bool atEnd() const
QStringList
QFileInfo
QList::end
iterator end()
QString::toLocal8Bit
QByteArray toLocal8Bit() const
QFileInfo::exists
bool exists() const
QLatin1Char
kWarning
#define kWarning
Definition: kdebug.h:322
QChar::toLatin1
char toLatin1() const
KCmdLineArgs::setCwd
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...
Definition: kcmdlineargs.cpp:1329
KCmdLineArgs::saveAppArgs
static void saveAppArgs(QDataStream &)
Definition: kcmdlineargs.cpp:534
QByteArray::left
QByteArray left(int len) const
QFileInfo::isRelative
bool isRelative() const
QList::takeFirst
T takeFirst()
QLatin1String
QByteArray::contains
bool contains(char ch) const
KCmdLineArgs::init
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.
Definition: kcmdlineargs.cpp:418
KGlobal::hasMainComponent
bool hasMainComponent()
Definition: kglobal.cpp:151
QByteArray::data
char * data()
QString::fromLatin1
QString fromLatin1(const char *str, int size)
KCmdLineArgs::getOption
QString getOption(const QByteArray &option) const
Read out a string option.
Definition: kcmdlineargs.cpp:1438
QList::prepend
void prepend(const T &value)
kaboutdata.h
KCmdLineArgs::addStdCmdLineOptions
static void addStdCmdLineOptions(StdCmdLineArgs stdargs=StdCmdLineArgs(CmdLineArgQt|CmdLineArgKDE))
add standard Qt/KDE command-line args
Definition: kcmdlineargs.cpp:492
QString::begin
iterator begin()
kcomponentdata.h
KCmdLineOptions
Class that holds command line options.
Definition: kcmdlineargs.h:48
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
KLocalizedString
Class for producing and handling localized messages.
Definition: klocalizedstring.h:299
QList::begin
iterator begin()
KGlobal::hasLocale
bool hasLocale()
Definition: kglobal.cpp:205
KComponentData
Per component data.
Definition: kcomponentdata.h:46
QByteArray::endsWith
bool endsWith(const QByteArray &ba) const
KCmdLineArgs::clear
void clear()
Clear all options and arguments.
Definition: kcmdlineargs.cpp:1335
KCmdLineArgs::enable_i18n
static void enable_i18n()
Enable i18n to be able to print a translated error message.
Definition: kcmdlineargs.cpp:1066
defaultValue
QString defaultValue(const QString &t)
Definition: kconfig_compiler.cpp:950
KCmdLineOptions::operator=
KCmdLineOptions & operator=(const KCmdLineOptions &options)
Assignment operator.
Definition: kcmdlineargs.cpp:134
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:22:10 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal