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

KDECore

  • 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  // KDE options
308  kde_options.add("caption <caption>", ki18n("Use 'caption' as name in the titlebar"));
309  kde_options.add("icon <icon>", ki18n("Use 'icon' as the application icon"));
310  kde_options.add("config <filename>", ki18n("Use alternative configuration file"));
311  kde_options.add("nocrashhandler", ki18n("Disable crash handler, to get core dumps"));
312 #ifdef Q_WS_X11
313  kde_options.add("waitforwm", ki18n("Waits for a WM_NET compatible windowmanager"));
314 #endif
315  kde_options.add("style <style>", ki18n("sets the application GUI style"));
316  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)"));
317 #ifndef Q_WS_WIN
318  kde_options.add("smkey <sessionKey>"); // this option is obsolete and exists only to allow smooth upgrades from sessions
319 #endif
320 }
321 
322 KCmdLineArgsStatic::~KCmdLineArgsStatic ()
323 {
324  delete argsList;
325  // KAboutData object is deleted by ~KCleanUpGlobalStatic.
326  //delete about;
327 }
328 
329 //
330 // KCmdLineArgs private data and methods
331 //
332 
333 class KCmdLineArgsPrivate
334 {
335  friend class KCmdLineArgsStatic;
336 public:
337  KCmdLineArgsPrivate(const KCmdLineOptions &_options, const KLocalizedString &_name, const QByteArray &_id)
338  : options(_options)
339  , name(_name)
340  , id(_id)
341  , parsedOptionList(0)
342  , parsedArgList(0)
343  , isQt(id == "qt")
344  {
345  }
346  ~KCmdLineArgsPrivate()
347  {
348  delete parsedOptionList;
349  delete parsedArgList;
350  }
351  const KCmdLineOptions options;
352  const KLocalizedString name;
353  const QByteArray id;
354  KCmdLineParsedOptions *parsedOptionList;
355  KCmdLineParsedArgs *parsedArgList;
356  bool isQt;
357 
363  void setOption(const QByteArray &option, bool enabled);
364 
370  void setOption(const QByteArray &option, const QByteArray &value);
371 
377  void addArgument(const QByteArray &argument);
378 
384  void save( QDataStream &) const;
385 
391  void load( QDataStream &);
392 };
393 
394 //
395 // Static functions
396 //
397 
398 QString
399 KCmdLineArgsStatic::decodeInput(const QByteArray &rawstr)
400 {
401  return s->codec->toUnicode(rawstr);
402 }
403 
404 QByteArray
405 KCmdLineArgsStatic::encodeOutput(const QString &str)
406 {
407  return s->codec->fromUnicode(str);
408 }
409 
410 void
411 KCmdLineArgsStatic::printQ(const QString &msg)
412 {
413  fprintf(stdout, "%s", encodeOutput(msg).data());
414 }
415 
416 void
417 KCmdLineArgs::init(int _argc, char **_argv,
418  const QByteArray &_appname,
419  const QByteArray &_catalog,
420  const KLocalizedString &_programName,
421  const QByteArray &_version,
422  const KLocalizedString &_description,
423  StdCmdLineArgs stdargs)
424 {
425  init(_argc, _argv,
426  new KAboutData(_appname, _catalog, _programName, _version, _description),
427  stdargs);
428 }
429 
430 void
431 KCmdLineArgs::initIgnore(int _argc, char **_argv, const QByteArray &_appname )
432 {
433  init(_argc, _argv,
434  new KAboutData(_appname, 0, ki18n(_appname), "unknown", ki18n("KDE Application")));
435  s->ignoreUnknown = true;
436 }
437 
438 void
439 KCmdLineArgs::init(const KAboutData* ab)
440 {
441  char **_argv = (char **) malloc(sizeof(char *));
442  _argv[0] = (char *) s->encodeOutput(ab->appName()).data();
443  init(1,_argv,ab, CmdLineArgNone);
444 }
445 
446 
447 void
448 KCmdLineArgs::init(int _argc, char **_argv, const KAboutData *_about, StdCmdLineArgs stdargs)
449 {
450  s->all_argc = _argc;
451  s->all_argv = _argv;
452 
453  if (!s->all_argv)
454  {
455  fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
456  fprintf(stderr, "Passing null-pointer to 'argv' is not allowed.\n\n");
457 
458  assert( 0 );
459  exit(255);
460  }
461 
462  // Strip path from argv[0]
463  if (s->all_argc) {
464  char *p = strrchr(s->all_argv[0], QDir::separator().toAscii());
465  if (p)
466  s->appName = p+1;
467  else
468  s->appName = s->all_argv[0];
469  }
470 
471  s->about = _about;
472  s->parsed = false;
473  s->mCwd = QDir::currentPath().toLocal8Bit(); //currentPath() uses fromLocal8Bit internally apparently
474  addStdCmdLineOptions(stdargs);
475 }
476 
477 QString KCmdLineArgs::cwd()
478 {
479  return QString::fromLocal8Bit(s->mCwd);
480 }
481 
482 QString KCmdLineArgs::appName()
483 {
484  if (!s->appName) return QString();
485  return s->decodeInput(s->appName);
486 }
487 
491 void KCmdLineArgs::addStdCmdLineOptions(StdCmdLineArgs stdargs) {
492  if (stdargs & KCmdLineArgs::CmdLineArgQt) {
493  KCmdLineArgs::addCmdLineOptions(s->qt_options, ki18n("Qt"), "qt");
494  }
495  if (stdargs & KCmdLineArgs::CmdLineArgKDE) {
496  KCmdLineArgs::addCmdLineOptions(s->kde_options, ki18n("KDE"), "kde");
497  }
498  s->mStdargs = stdargs;
499 }
500 
501 void
502 KCmdLineArgs::addCmdLineOptions( const KCmdLineOptions &options, const KLocalizedString &name,
503  const QByteArray &id, const QByteArray &afterId)
504 {
505  if (!s->argsList)
506  s->argsList = new KCmdLineArgsList;
507 
508  int pos = s->argsList->count();
509  // To make sure that the named options come before unnamed.
510  if (pos > 0 && !id.isEmpty() && s->argsList->last()->d->name.isEmpty())
511  pos--;
512 
513  KCmdLineArgsList::Iterator args;
514  int i = 0;
515  for(args = s->argsList->begin(); args != s->argsList->end(); ++args, i++)
516  {
517  if (id == (*args)->d->id) {
518  return; // Options already present.
519  }
520 
521  // Only check for afterId if it has been given non-empty, as the
522  // unnamed option group should come after all named groups.
523  if (!afterId.isEmpty() && afterId == (*args)->d->id)
524  pos = i+1;
525  }
526 
527  Q_ASSERT( s->parsed == false ); // You must add _ALL_ cmd line options
528  // before accessing the arguments!
529  s->argsList->insert(pos, new KCmdLineArgs(options, name, id));
530 }
531 
532 void
533 KCmdLineArgs::saveAppArgs( QDataStream &ds)
534 {
535  if (!s->parsed)
536  s->parseAllArgs();
537 
538  // Remove Qt and KDE options.
539  s->removeArgs("qt");
540  s->removeArgs("kde");
541  s->removeArgs("kuniqueapp");
542 
543  ds << s->mCwd;
544 
545  uint count = s->argsList ? s->argsList->count() : 0;
546  ds << count;
547 
548  if (!count) return;
549 
550  KCmdLineArgsList::Iterator args;
551  for(args = s->argsList->begin(); args != s->argsList->end(); ++args)
552  {
553  ds << (*args)->d->id;
554  (*args)->d->save(ds);
555  }
556 }
557 
558 void
559 KCmdLineArgs::loadAppArgs( QDataStream &ds)
560 {
561  s->parsed = true; // don't reparse argc/argv!
562 
563  // Remove Qt and KDE options.
564  s->removeArgs("qt");
565  s->removeArgs("kde");
566  s->removeArgs("kuniqueapp");
567 
568  KCmdLineArgsList::Iterator args;
569  if ( s->argsList ) {
570  for(args = s->argsList->begin(); args != s->argsList->end(); ++args)
571  {
572  (*args)->clear();
573  }
574  }
575 
576  if (ds.atEnd())
577  return;
578 
579  QByteArray qCwd;
580  ds >> qCwd;
581 
582  s->mCwd = qCwd;
583 
584  uint count;
585  ds >> count;
586 
587  while(count--)
588  {
589  QByteArray id;
590  ds >> id;
591  Q_ASSERT( s->argsList );
592  bool found = false;
593  for(args = s->argsList->begin(); args != s->argsList->end(); ++args)
594  {
595  if ((*args)->d->id == id)
596  {
597  (*args)->d->load(ds);
598  found = true;
599  break;
600  }
601  }
602  if (!found) {
603  kWarning() << "Argument definitions for" << id << "not found!";
604  // The next ds >> id will do nonsensical things...
605  }
606  }
607  s->parsed = true;
608 }
609 
610 KCmdLineArgs *KCmdLineArgs::parsedArgs(const QByteArray &id)
611 {
612  if (!s->argsList)
613  return 0;
614  KCmdLineArgsList::Iterator args = s->argsList->begin();
615  while(args != s->argsList->end())
616  {
617  if ((*args)->d->id == id)
618  {
619  if (!s->parsed)
620  s->parseAllArgs();
621  return *args;
622  }
623  ++args;
624  }
625 
626  return 0;
627 }
628 
629 void KCmdLineArgsStatic::removeArgs(const QByteArray &id)
630 {
631  if (!s->argsList)
632  return;
633  KCmdLineArgsList::Iterator args = s->argsList->begin();
634  while(args != s->argsList->end())
635  {
636  if ((*args)->d->id == id)
637  {
638  if (!s->parsed)
639  s->parseAllArgs();
640  break;
641  }
642  ++args;
643  }
644 
645  if (args != s->argsList->end()) {
646  KCmdLineArgs *a = *args;
647  s->argsList->erase(args);
648  delete a;
649  }
650 }
651 
652 int
653 KCmdLineArgsStatic::findOption(const KCmdLineOptions &options, QByteArray &opt,
654  QByteArray &opt_name, QString &def, bool &enabled)
655 {
656  int result;
657  bool inverse;
658 
659  for (int i = 0; i < options.d->names.size(); i++)
660  {
661  result = 0;
662  inverse = false;
663  opt_name = options.d->names[i];
664  if (opt_name.startsWith(':') || opt_name.isEmpty())
665  {
666  continue;
667  }
668  if (opt_name.startsWith('!'))
669  {
670  opt_name = opt_name.mid(1);
671  result = 4;
672  }
673  if (opt_name.startsWith("no") && !opt_name.contains('<')) // krazy:exclude=strings
674  {
675  opt_name = opt_name.mid(2);
676  inverse = true;
677  }
678 
679  int len = opt.length();
680  if (opt == opt_name.left(len))
681  {
682  opt_name = opt_name.mid(len);
683  if (opt_name.isEmpty())
684  {
685  if (inverse)
686  return result+2;
687 
688  if (options.d->descriptions[i].isEmpty())
689  {
690  i++;
691  if (i >= options.d->names.size())
692  return result+0;
693  QByteArray nextOption = options.d->names[i];
694  int p = nextOption.indexOf(' ');
695  if (p > 0)
696  nextOption = nextOption.left(p);
697  if (nextOption.startsWith('!'))
698  nextOption = nextOption.mid(1);
699  if (nextOption.startsWith("no") && !nextOption.contains('<')) // krazy:exclude=strings
700  {
701  nextOption = nextOption.mid(2);
702  enabled = !enabled;
703  }
704  result = findOption(options, nextOption, opt_name, def, enabled);
705  Q_ASSERT(result);
706  opt = nextOption;
707  return result;
708  }
709 
710  return 1;
711  }
712  if (opt_name.startsWith(' '))
713  {
714  opt_name = opt_name.mid(1);
715  def = options.d->defaults[i];
716  return result+3;
717  }
718  }
719  }
720  return 0;
721 }
722 
723 void
724 KCmdLineArgsStatic::findOption(const QByteArray &optv, const QByteArray &_opt,
725  int &i, bool _enabled, bool &moreOptions)
726 {
727  KCmdLineArgsList::Iterator args = s->argsList->begin();
728  QByteArray opt = _opt;
729  QByteArray opt_name;
730  QString def;
731  QByteArray argument;
732  int j = opt.indexOf('=');
733  if (j != -1)
734  {
735  argument = opt.mid(j+1);
736  opt = opt.left(j);
737  }
738 
739  bool enabled = true;
740  int result = 0;
741  while (args != s->argsList->end())
742  {
743  enabled = _enabled;
744  result = findOption((*args)->d->options, opt, opt_name, def, enabled);
745  if (result) break;
746  ++args;
747  }
748  if ((args == s->argsList->end()) &&
749  (optv.startsWith('-') && !optv.startsWith("--"))) // krazy:exclude=strings
750  {
751  // Option not found check if it is a valid option
752  // in the style of -Pprinter1 or ps -aux
753  int p = 1;
754  while (true)
755  {
756  QByteArray singleCharOption = " "; // krazy:exclude=doublequote_chars
757  singleCharOption[0] = optv[p];
758  args = s->argsList->begin();
759  while (args != s->argsList->end())
760  {
761  enabled = _enabled;
762  result = findOption((*args)->d->options, singleCharOption,
763  opt_name, def, enabled);
764  if (result) break;
765  ++args;
766  }
767  if (args == s->argsList->end())
768  break; // Unknown argument
769 
770  p++;
771  if (result == 1) // Single option
772  {
773  (*args)->d->setOption(singleCharOption, enabled);
774  if (p < optv.length())
775  continue; // Next option
776  else
777  return; // Finished
778  }
779  else if (result == 3) // This option takes an argument
780  {
781  if (argument.isEmpty())
782  {
783  argument = optv.mid(p);
784  }
785  (*args)->d->setOption(singleCharOption, argument);
786  return;
787  }
788  break; // Unknown argument
789  }
790  args = s->argsList->end();
791  result = 0;
792  }
793 
794  if (args == s->argsList->end() || !result)
795  {
796  if (s->ignoreUnknown)
797  return;
798  KCmdLineArgs::enable_i18n();
799  KCmdLineArgs::usageError( i18n("Unknown option '%1'.", QString::fromLocal8Bit(_opt)));
800  }
801 
802  if ((result & 4) != 0)
803  {
804  result &= ~4;
805  moreOptions = false;
806  }
807 
808  if (result == 3) // This option takes an argument
809  {
810  if (!enabled)
811  {
812  if (s->ignoreUnknown)
813  return;
814  KCmdLineArgs::enable_i18n();
815  KCmdLineArgs::usageError( i18n("Unknown option '%1'.", QString::fromLocal8Bit(_opt)));
816  }
817  if (argument.isEmpty())
818  {
819  i++;
820  if (i >= s->all_argc)
821  {
822  KCmdLineArgs::enable_i18n();
823  KCmdLineArgs::usageError( i18nc("@info:shell %1 is cmdoption name","'%1' missing.", QString::fromLocal8Bit(opt_name)));
824  }
825  argument = s->all_argv[i];
826  }
827  (*args)->d->setOption(opt, argument);
828  }
829  else
830  {
831  (*args)->d->setOption(opt, enabled);
832  }
833 }
834 
835 void
836 KCmdLineArgsStatic::parseAllArgs()
837 {
838  bool allowArgs = false;
839  bool inOptions = true;
840  bool everythingAfterArgIsArgs = false;
841  KCmdLineArgs *appOptions = s->argsList->last();
842  if (appOptions->d->id.isEmpty())
843  {
844  foreach(const QByteArray& name, appOptions->d->options.d->names)
845  {
846  everythingAfterArgIsArgs = everythingAfterArgIsArgs || name.startsWith("!+");
847  allowArgs = allowArgs || name.startsWith('+') || everythingAfterArgIsArgs;
848  }
849  }
850  for(int i = 1; i < s->all_argc; i++)
851  {
852  if (!s->all_argv[i])
853  continue;
854 
855  if ((s->all_argv[i][0] == '-') && s->all_argv[i][1] && inOptions)
856  {
857  bool enabled = true;
858  QByteArray orig = s->all_argv[i];
859  QByteArray option = orig.mid(1);
860  if (option.startsWith('-'))
861  {
862  option = option.mid(1);
863  if (option.isEmpty())
864  {
865  inOptions = false;
866  continue;
867  }
868  }
869  if (option == "help")
870  {
871  KCmdLineArgs::usage();
872  }
873  else if (option.startsWith("help-")) // krazy:exclude=strings
874  {
875  KCmdLineArgs::usage(option.mid(5));
876  }
877 #ifdef Q_WS_MAC
878  // skip the finder -psn_* hint
879  else if (option.startsWith("psn_")) // krazy:exclude=strings
880  {
881  continue;
882  }
883 #endif
884  else if ((option == "version") || (option == "v"))
885  {
886  KCmdLineArgs::enable_i18n();
887  s->printQ(i18nc("@info:shell message on appcmd --version; do not translate 'Development Platform'"
888  "%3 application name, other %n version strings",
889  "Qt: %1\n"
890  "KDE Development Platform: %2\n"
891  "%3: %4\n",
892  QString::fromLatin1(qVersion()),
893  QString::fromLatin1(KDE_VERSION_STRING),
894  s->about->programName(), s->about->version()));
895  exit(0);
896  } else if (option == "license")
897  {
898  KCmdLineArgs::enable_i18n();
899  s->printQ(s->about->license());
900  s->printQ(QString::fromLatin1("\n"));
901  exit(0);
902  } else if (option == "author") {
903  KCmdLineArgs::enable_i18n();
904  if ( s->about ) {
905  const QList<KAboutPerson> authors = s->about->authors();
906  if ( !authors.isEmpty() ) {
907  QString authorlist;
908  for (QList<KAboutPerson>::ConstIterator it = authors.begin(); it != authors.end(); ++it ) {
909  QString email;
910  if ( !(*it).emailAddress().isEmpty() )
911  email = QString::fromLatin1(" &lt;") + (*it).emailAddress() + QLatin1String("&gt;");
912  authorlist += QString::fromLatin1(" ") + (*it).name() + email + QLatin1Char('\n');
913  }
914  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 ) );
915  }
916  } else {
917  s->printQ( i18n("This application was written by somebody who wants to remain anonymous.") );
918  }
919  if (s->about)
920  {
921  if (!s->about->customAuthorTextEnabled ())
922  {
923  if (s->about->bugAddress().isEmpty() || s->about->bugAddress() == QLatin1String("submit@bugs.kde.org") )
924  s->printQ( i18n( "Please use http://bugs.kde.org to report bugs.\n" ) );
925  else
926  s->printQ( i18n( "Please report bugs to %1.\n" , s->about->bugAddress()) );
927  }
928  else
929  {
930  s->printQ(s->about->customAuthorPlainText()+QLatin1Char('\n'));
931  }
932  }
933  exit(0);
934  } else {
935  if (option.startsWith("no")) // krazy:exclude=strings
936  {
937  bool noHasParameter=false;
938  foreach(const QByteArray& name, appOptions->d->options.d->names)
939  {
940  if (name.contains(option + QByteArray(" ")) && name.contains('<'))
941  {
942  noHasParameter=true;
943  break;
944  }
945  }
946  if (!noHasParameter)
947  {
948  option = option.mid(2);
949  enabled = false;
950  }
951  }
952  s->findOption(orig, option, i, enabled, inOptions);
953  }
954  }
955  else
956  {
957  // Check whether appOptions allows these arguments
958  if (!allowArgs)
959  {
960  if (s->ignoreUnknown)
961  continue;
962  KCmdLineArgs::enable_i18n();
963  KCmdLineArgs::usageError(i18n("Unexpected argument '%1'.", KuitSemantics::escape(s->decodeInput(s->all_argv[i]))));
964  }
965  else
966  {
967  appOptions->d->addArgument(s->all_argv[i]);
968  if (everythingAfterArgIsArgs)
969  inOptions = false;
970  }
971  }
972  }
973  s->parsed = true;
974 }
975 
976 int & KCmdLineArgs::qtArgc()
977 {
978  if (!s->argsList)
979  addStdCmdLineOptions(CmdLineArgKDE|CmdLineArgQt); // Lazy bastards!
980 
981  static int qt_argc = -1;
982  if( qt_argc != -1 )
983  return qt_argc;
984 
985  if (!(s->mStdargs & KCmdLineArgs::CmdLineArgQt))
986  {
987  qt_argc = 2;
988  return qt_argc;
989  }
990 
991  KCmdLineArgs *args = parsedArgs("qt");
992  Q_ASSERT(args); // No qt options have been added!
993  if (!s->all_argv)
994  {
995  fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
996  fprintf(stderr, "Application has not called KCmdLineArgs::init(...).\n\n");
997 
998  assert( 0 );
999  exit(255);
1000  }
1001 
1002  Q_ASSERT(s->all_argc >= (args->count()+1));
1003  qt_argc = args->count() +1;
1004  return qt_argc;
1005 }
1006 
1007 static char** s_qt_argv;
1008 
1009 char **
1010 KCmdLineArgs::qtArgv()
1011 {
1012  if (!s->argsList)
1013  addStdCmdLineOptions(CmdLineArgKDE|CmdLineArgQt); // Lazy bastards!
1014 
1015  if( s_qt_argv != NULL )
1016  return s_qt_argv;
1017 
1018  if (!(s->mStdargs & KCmdLineArgs::CmdLineArgQt))
1019  {
1020  s_qt_argv = new char*[2];
1021  s_qt_argv[0] = qstrdup(s->all_argc?s->all_argv[0]:"");
1022  s_qt_argv[1] = 0;
1023 
1024  return s_qt_argv;
1025  }
1026 
1027  KCmdLineArgs *args = parsedArgs("qt");
1028  if (!args)
1029  {
1030  fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
1031  fprintf(stderr, "The \"qt\" options have not be added to KCmdLineArgs!\n\n");
1032 
1033  assert( 0 );
1034  exit(255);
1035  }
1036  if (!s->all_argv)
1037  {
1038  fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
1039  fprintf(stderr, "Application has not called KCmdLineArgs::init(...).\n\n");
1040 
1041  assert( 0 );
1042  exit(255);
1043  }
1044 
1045  int count=args->count();
1046  s_qt_argv = new char*[ count + 2 ];
1047  s_qt_argv[0] = qstrdup(s->all_argc?s->all_argv[0]:"");
1048  int i = 0;
1049  for(; i < count; i++)
1050  {
1051  s_qt_argv[i+1] = qstrdup(args->d->parsedArgList->at(i));
1052  }
1053  s_qt_argv[i+1] = 0;
1054 
1055  return s_qt_argv;
1056 }
1057 
1058 const KAboutData *
1059 KCmdLineArgs::aboutData()
1060 {
1061  return s->about;
1062 }
1063 
1064 void
1065 KCmdLineArgs::enable_i18n()
1066 {
1067  // called twice or too late
1068  if (KGlobal::hasLocale())
1069  return;
1070 
1071  if (!KGlobal::hasMainComponent()) {
1072  KComponentData mainComponentData(s->about);
1073  mainComponentData.config();
1074  // mainComponentData is now the main component and won't disappear until KGlobal deletes it
1075  }
1076 }
1077 
1078 void
1079 KCmdLineArgs::usageError(const QString &error)
1080 {
1081  Q_ASSERT(KGlobal::hasLocale());
1082  QByteArray localError = s->encodeOutput(error);
1083  if (localError.endsWith('\n'))
1084  localError.chop(1);
1085  fprintf(stderr, "%s: %s\n", s->appName, localError.data());
1086 
1087  QString tmp = i18n("Use --help to get a list of available command line options.");
1088  localError = s->encodeOutput(tmp);
1089  fprintf(stderr, "%s: %s\n", s->appName, localError.data());
1090  exit(254);
1091 }
1092 
1093 void
1094 KCmdLineArgs::usage(const QByteArray &id)
1095 {
1096  enable_i18n();
1097  Q_ASSERT(s->argsList != 0); // It's an error to call usage(...) without
1098  // having done addCmdLineOptions first!
1099 
1100  QString optionFormatString = QString::fromLatin1(" %1 %2\n");
1101  QString optionFormatStringDef = QString::fromLatin1(" %1 %2 [%3]\n");
1102  QString tmp;
1103  QString usage;
1104 
1105  KCmdLineArgsList::Iterator args = --(s->argsList->end());
1106 
1107  if ((*args)->d->id.isEmpty() && ((*args)->d->options.d->names.size() > 0) &&
1108  !(*args)->d->options.d->names[0].startsWith('+'))
1109  {
1110  usage = i18n("[options] ")+usage;
1111  }
1112 
1113  while(true)
1114  {
1115  if (!(*args)->d->name.isEmpty())
1116  {
1117  usage = i18n("[%1-options]", (*args)->d->name.toString())+QLatin1Char(' ')+usage;
1118  }
1119  if (args == s->argsList->begin())
1120  break;
1121  --args;
1122  }
1123 
1124  KCmdLineArgs *appOptions = s->argsList->last();
1125  if (appOptions->d->id.isEmpty())
1126  {
1127  const KCmdLineOptions &option = appOptions->d->options;
1128  for (int i = 0; i < option.d->names.size(); i++)
1129  {
1130  QByteArray opt_name = option.d->names[i];
1131  if (opt_name.startsWith('+'))
1132  usage += QString::fromLatin1(opt_name.mid(1)) + QLatin1Char(' ');
1133  else if ( opt_name.startsWith("!+") )
1134  usage += QString::fromLatin1(opt_name.mid(2)) + QLatin1Char(' ');
1135  }
1136  }
1137 
1138  s->printQ(i18n("Usage: %1 %2\n", QString::fromLocal8Bit(s->appName), KuitSemantics::escape(usage)));
1139  s->printQ(QLatin1Char('\n')+s->about->shortDescription()+QLatin1Char('\n'));
1140 
1141  s->printQ(i18n("\nGeneric options:\n"));
1142  s->printQ(optionFormatString.arg(QString::fromLatin1("--help"), -25)
1143  .arg(i18n("Show help about options")));
1144 
1145  args = s->argsList->begin();
1146  while(args != s->argsList->end())
1147  {
1148  if (!(*args)->d->name.isEmpty() && !(*args)->d->id.isEmpty())
1149  {
1150  QString option = QString::fromLatin1("--help-%1").arg(QString::fromLatin1((*args)->d->id));
1151  QString desc = i18n("Show %1 specific options", (*args)->d->name.toString());
1152 
1153  s->printQ(optionFormatString.arg(option, -25).arg(desc));
1154  }
1155  ++args;
1156  }
1157 
1158  s->printQ(optionFormatString.arg(QString::fromLatin1("--help-all"),-25).arg(i18n("Show all options")));
1159  s->printQ(optionFormatString.arg(QString::fromLatin1("--author"),-25).arg(i18n("Show author information")));
1160  s->printQ(optionFormatString.arg(QString::fromLatin1("-v, --version"),-25).arg(i18n("Show version information")));
1161  s->printQ(optionFormatString.arg(QString::fromLatin1("--license"),-25).arg(i18n("Show license information")));
1162  s->printQ(optionFormatString.arg(QString::fromLatin1("--"), -25).arg(i18n("End of options")));
1163 
1164  args = s->argsList->begin(); // Sets current to 1st.
1165 
1166  bool showAll = (id == "all");
1167 
1168  if (!showAll)
1169  {
1170  while(args != s->argsList->end())
1171  {
1172  if (id == (*args)->d->id) break;
1173  ++args;
1174  }
1175  }
1176 
1177  while(args != s->argsList->end())
1178  {
1179  bool hasArgs = false;
1180  bool hasOptions = false;
1181  QString optionsHeader;
1182  if (!(*args)->d->name.isEmpty())
1183  optionsHeader = i18n("\n%1 options:\n", (*args)->d->name.toString());
1184  else
1185  optionsHeader = i18n("\nOptions:\n");
1186 
1187  while (args != s->argsList->end())
1188  {
1189  const KCmdLineOptions &option = (*args)->d->options;
1190  QByteArray opt;
1191 
1192  for (int i = 0; i < option.d->names.size(); i++)
1193  {
1194  QString description;
1195  QStringList dl;
1196 
1197  QString descriptionFull;
1198  if (!option.d->descriptions[i].isEmpty()) {
1199  descriptionFull = option.d->descriptions[i].toString();
1200  }
1201 
1202  // Option header
1203  if (option.d->names[i].startsWith(':'))
1204  {
1205  if (!descriptionFull.isEmpty())
1206  {
1207  optionsHeader = QLatin1Char('\n')+descriptionFull;
1208  if (!optionsHeader.endsWith(QLatin1Char('\n')))
1209  optionsHeader.append(QLatin1Char('\n'));
1210  hasOptions = false;
1211  }
1212  continue;
1213  }
1214 
1215  // Free-form comment
1216  if (option.d->names[i].isEmpty())
1217  {
1218  if (!descriptionFull.isEmpty())
1219  {
1220  tmp = QLatin1Char('\n')+descriptionFull;
1221  if (!tmp.endsWith(QLatin1Char('\n')))
1222  tmp.append(QLatin1Char('\n'));
1223  s->printQ(tmp);
1224  }
1225  continue;
1226  }
1227 
1228  // Options
1229  if (!descriptionFull.isEmpty())
1230  {
1231  dl = descriptionFull.split(QLatin1Char('\n'), QString::KeepEmptyParts);
1232  description = dl.first();
1233  dl.erase( dl.begin() );
1234  }
1235  QByteArray name = option.d->names[i];
1236  if (name.startsWith('!'))
1237  name = name.mid(1);
1238 
1239  if (name.startsWith('+'))
1240  {
1241  if (!hasArgs)
1242  {
1243  s->printQ(i18n("\nArguments:\n"));
1244  hasArgs = true;
1245  }
1246 
1247  name = name.mid(1);
1248  if (name.startsWith('[') && name.endsWith(']'))
1249  name = name.mid(1, name.length()-2);
1250  s->printQ(optionFormatString.arg(QString::fromLocal8Bit(name), -25).arg(description));
1251  }
1252  else
1253  {
1254  if (!hasOptions)
1255  {
1256  s->printQ(optionsHeader);
1257  hasOptions = true;
1258  }
1259 
1260  if ((name.length() == 1) || (name[1] == ' '))
1261  name = '-'+name;
1262  else
1263  name = "--"+name;
1264  if (descriptionFull.isEmpty())
1265  {
1266  opt = name + ", ";
1267  }
1268  else
1269  {
1270  opt = opt + name;
1271  if (option.d->defaults[i].isEmpty())
1272  {
1273  s->printQ(optionFormatString.arg(QString::fromLatin1(opt), -25).arg(description));
1274  }
1275  else
1276  {
1277  s->printQ(optionFormatStringDef.arg(QString::fromLatin1(opt), -25)
1278  .arg(description, option.d->defaults[i]));
1279  }
1280  opt.clear();
1281  }
1282  }
1283  for(QStringList::Iterator it = dl.begin();
1284  it != dl.end();
1285  ++it)
1286  {
1287  s->printQ(optionFormatString.arg(QString(), -25).arg(*it));
1288  }
1289  }
1290 
1291  ++args;
1292  if (args == s->argsList->end() || !(*args)->d->name.isEmpty() || (*args)->d->id.isEmpty())
1293  break;
1294  }
1295  if (!showAll) break;
1296  }
1297 
1298  exit(0);
1299 }
1300 
1301 //
1302 // Member functions
1303 //
1304 
1310 KCmdLineArgs::KCmdLineArgs( const KCmdLineOptions &_options,
1311  const KLocalizedString &_name,
1312  const QByteArray &_id)
1313  : d(new KCmdLineArgsPrivate(_options, _name, _id))
1314 {
1315 }
1316 
1320 KCmdLineArgs::~KCmdLineArgs()
1321 {
1322  if (!s.isDestroyed() && s->argsList)
1323  s->argsList->removeAll(this);
1324  delete d;
1325 }
1326 
1327 void
1328 KCmdLineArgs::setCwd( const QByteArray &cwd )
1329 {
1330  s->mCwd = cwd;
1331 }
1332 
1333 void
1334 KCmdLineArgs::clear()
1335 {
1336  delete d->parsedArgList; d->parsedArgList = 0;
1337  delete d->parsedOptionList; d->parsedOptionList = 0;
1338 }
1339 
1340 void
1341 KCmdLineArgs::reset()
1342 {
1343  delete s->argsList; s->argsList = 0;
1344  s->parsed = false;
1345 }
1346 
1347 void
1348 KCmdLineArgsPrivate::save( QDataStream &ds) const
1349 {
1350  if (parsedOptionList)
1351  ds << (*(parsedOptionList));
1352  else
1353  ds << quint32(0);
1354 
1355  if (parsedArgList)
1356  ds << (*(parsedArgList));
1357  else
1358  ds << quint32(0);
1359 }
1360 
1361 void
1362 KCmdLineArgsPrivate::load( QDataStream &ds)
1363 {
1364  if (!parsedOptionList) parsedOptionList = new KCmdLineParsedOptions;
1365  if (!parsedArgList) parsedArgList = new KCmdLineParsedArgs;
1366 
1367  ds >> (*(parsedOptionList));
1368  ds >> (*(parsedArgList));
1369 
1370  if (parsedOptionList->count() == 0)
1371  {
1372  delete parsedOptionList; parsedOptionList = 0;
1373  }
1374  if (parsedArgList->count() == 0)
1375  {
1376  delete parsedArgList; parsedArgList = 0;
1377  }
1378 }
1379 
1380 void
1381 KCmdLineArgsPrivate::setOption(const QByteArray &opt, bool enabled)
1382 {
1383  if (isQt)
1384  {
1385  // Qt does it own parsing.
1386  QByteArray argString = "-"; // krazy:exclude=doublequote_chars
1387  if( !enabled )
1388  argString += "no";
1389  argString += opt;
1390  addArgument(argString);
1391  }
1392  if (!parsedOptionList) {
1393  parsedOptionList = new KCmdLineParsedOptions;
1394  }
1395 
1396  if (enabled)
1397  parsedOptionList->insert( opt, "t" ); // krazy:exclude=doublequote_chars
1398  else
1399  parsedOptionList->insert( opt, "f" ); // krazy:exclude=doublequote_chars
1400 }
1401 
1402 void
1403 KCmdLineArgsPrivate::setOption(const QByteArray &opt, const QByteArray &value)
1404 {
1405  if (isQt)
1406  {
1407  // Qt does it's own parsing.
1408  QByteArray argString = "-"; // krazy:exclude=doublequote_chars
1409  argString += opt;
1410  addArgument(argString);
1411  addArgument(value);
1412 
1413 #if defined(Q_WS_X11) || defined(Q_WS_QWS)
1414  // Hack coming up!
1415  if (argString == "-display")
1416  {
1417  setenv(DISPLAY, value.data(), true);
1418  }
1419 #endif
1420  }
1421  if (!parsedOptionList) {
1422  parsedOptionList = new KCmdLineParsedOptions;
1423  }
1424 
1425  parsedOptionList->insertMulti( opt, value );
1426 }
1427 
1428 QString
1429 KCmdLineArgs::getOption(const QByteArray &_opt) const
1430 {
1431  QByteArray opt = _opt;
1432  QByteArray value;
1433  if (d->parsedOptionList)
1434  {
1435  value = d->parsedOptionList->value(opt);
1436  }
1437  if (!value.isEmpty())
1438  return QString::fromLocal8Bit(value);
1439 
1440  // Look up the default.
1441  QByteArray opt_name;
1442  QString def;
1443  bool dummy = true;
1444  int result = s->findOption( d->options, opt, opt_name, def, dummy) & ~4;
1445 
1446  if (result != 3)
1447  {
1448  fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
1449  fprintf(stderr, "Application requests for getOption(\"%s\") but the \"%s\" option\n",
1450  opt.data(), opt.data());
1451  fprintf(stderr, "has never been specified via addCmdLineOptions( ... )\n\n");
1452 
1453  Q_ASSERT( 0 );
1454  exit(255);
1455  }
1456  return def;
1457 }
1458 
1459 QStringList
1460 KCmdLineArgs::getOptionList(const QByteArray &opt) const
1461 {
1462  QStringList result;
1463  if (!d->parsedOptionList)
1464  return result;
1465 
1466  while(true)
1467  {
1468  QByteArray value = d->parsedOptionList->take(opt);
1469  if (value.isEmpty())
1470  break;
1471  result.prepend(QString::fromLocal8Bit(value));
1472  }
1473 
1474  // Reinsert items in dictionary
1475  // WABA: This is rather silly, but I don't want to add restrictions
1476  // to the API like "you can only call this function once".
1477  // I can't access all items without taking them out of the list.
1478  // So taking them out and then putting them back is the only way.
1479  Q_FOREACH(const QString &str, result)
1480  {
1481  d->parsedOptionList->insertMulti(opt, str.toLocal8Bit());
1482  }
1483  return result;
1484 }
1485 
1486 bool
1487 KCmdLineArgs::isSet(const QByteArray &_opt) const
1488 {
1489  // Look up the default.
1490  QByteArray opt = _opt;
1491  QByteArray opt_name;
1492  QString def;
1493  int result = 0;
1494  KCmdLineArgsList::Iterator args = s->argsList->begin();
1495  while (args != s->argsList->end())
1496  {
1497  bool dummy = true;
1498  result = s->findOption((*args)->d->options, opt, opt_name, def, dummy) & ~4;
1499  if (result) break;
1500  ++args;
1501  }
1502 
1503  if (result == 0)
1504  {
1505  fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
1506  fprintf(stderr, "Application requests for isSet(\"%s\") but the \"%s\" option\n",
1507  opt.data(), opt.data());
1508  fprintf(stderr, "has never been specified via addCmdLineOptions( ... )\n\n");
1509 
1510  Q_ASSERT( 0 );
1511  exit(255);
1512  }
1513 
1514  QByteArray value;
1515  if (d->parsedOptionList)
1516  {
1517  value = d->parsedOptionList->value(opt);
1518  }
1519 
1520  if (!value.isEmpty())
1521  {
1522  if (result == 3)
1523  return true;
1524  else
1525  return (value.at(0) == 't');
1526  }
1527 
1528  if (result == 3)
1529  return false; // String option has 'false' as default.
1530 
1531  // We return 'true' as default if the option was listed as '-nofork'
1532  // We return 'false' as default if the option was listed as '-fork'
1533  return (result == 2);
1534 }
1535 
1536 int
1537 KCmdLineArgs::count() const
1538 {
1539  return d->parsedArgList?d->parsedArgList->count():0;
1540 }
1541 
1542 QString
1543 KCmdLineArgs::arg(int n) const
1544 {
1545  if (!d->parsedArgList || (n >= (int) d->parsedArgList->count()))
1546  {
1547  fprintf(stderr, "\n\nFAILURE (KCmdLineArgs): Argument out of bounds\n");
1548  fprintf(stderr, "Application requests for arg(%d) without checking count() first.\n",
1549  n);
1550 
1551  Q_ASSERT( 0 );
1552  exit(255);
1553  }
1554 
1555  return QString::fromLocal8Bit(d->parsedArgList->at(n));
1556 }
1557 
1558 KUrl
1559 KCmdLineArgs::url(int n) const
1560 {
1561  return makeURL( arg(n).toUtf8() );
1562 }
1563 
1564 KUrl KCmdLineArgs::makeURL(const QByteArray &_urlArg)
1565 {
1566  const QString urlArg = QString::fromUtf8(_urlArg);
1567  QFileInfo fileInfo(urlArg);
1568  if (!fileInfo.isRelative()) { // i.e. starts with '/', on unix
1569  KUrl result;
1570  result.setPath(QDir::fromNativeSeparators(urlArg));
1571  return result; // Absolute path.
1572  }
1573 
1574  if ( KUrl::isRelativeUrl(urlArg) || fileInfo.exists() ) {
1575  KUrl result;
1576  result.setPath(cwd()+QLatin1Char('/')+urlArg);
1577  result.cleanPath();
1578  return result; // Relative path
1579  }
1580 
1581  return KUrl(urlArg); // Argument is a URL
1582 }
1583 
1584 void
1585 KCmdLineArgsPrivate::addArgument(const QByteArray &argument)
1586 {
1587  if (!parsedArgList)
1588  parsedArgList = new KCmdLineParsedArgs;
1589 
1590  parsedArgList->append(argument);
1591 }
1592 
1593 void
1594 KCmdLineArgs::addTempFileOption()
1595 {
1596  KCmdLineOptions tmpopt;
1597  tmpopt.add( "tempfile", ki18n("The files/URLs opened by the application will be deleted after use") );
1598  KCmdLineArgs::addCmdLineOptions( tmpopt, ki18n("KDE-tempfile"), "kde-tempfile" );
1599 }
1600 
1601 bool KCmdLineArgs::isTempFileSet()
1602 {
1603  KCmdLineArgs* args = KCmdLineArgs::parsedArgs( "kde-tempfile" );
1604  return args && args->isSet( "tempfile" );
1605 }
1606 
1607 QStringList KCmdLineArgs::allArguments()
1608 {
1609  QStringList lst;
1610 
1611  for(int i = 0; i < s->all_argc; i++) {
1612  char* arg = s->all_argv[i];
1613  if (!arg)
1614  continue;
1615  lst.append(QString::fromLocal8Bit(arg));
1616  }
1617  return lst;
1618 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Fri Dec 7 2012 15:57:17 by doxygen 1.8.1 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-4.8.5 API Reference

Skip menu "kdelibs-4.8.5 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
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