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

KDECore

kcmdlineargs.cpp

Go to the documentation of this file.
00001 /*
00002    Copyright (C) 1999 Waldo Bastian <bastian@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License version 2 as published by the Free Software Foundation.
00007 
00008    This library is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011    Library General Public License for more details.
00012 
00013    You should have received a copy of the GNU Library General Public License
00014    along with this library; see the file COPYING.LIB.  If not, write to
00015    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016    Boston, MA 02110-1301, USA.
00017 */
00018 
00019 #include "kcmdlineargs.h"
00020 #include <kdebug.h>
00021 
00022 #include <config.h>
00023 
00024 #include <sys/param.h>
00025 
00026 #include <assert.h>
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030 #include <unistd.h>
00031 #include <locale.h>
00032 
00033 #ifdef HAVE_LIMITS_H
00034 #include <limits.h>
00035 #endif
00036 
00037 #include <QtCore/QDir>
00038 #include <QtCore/QFile>
00039 #include <QtCore/QHash>
00040 #include <QtCore/QTextCodec>
00041 
00042 #include "kaboutdata.h"
00043 #include "klocale.h"
00044 #include "kdeversion.h"
00045 #include "kcomponentdata.h"
00046 #include "kglobal.h"
00047 #include "kstringhandler.h"
00048 #include "kurl.h"
00049 
00050 #include "kuitsemantics_p.h" // for escaping arguments in i18n
00051 
00052 // -----------------------------------------------------------------------------
00053 // Design notes:
00054 //
00055 // These classes deal with a lot of text, some of which needs to be
00056 // marked for translation. Since at the time when these object and calls are
00057 // made the translation catalogs are usually still not initialized, the
00058 // translation has to be delayed. This is achieved by using KLocalizedString
00059 // for translatable strings. KLocalizedStrings are produced by ki18n* calls,
00060 // instead of the more usuall i18n* calls which produce QString by trying to
00061 // translate immediately.
00062 //
00063 // All the non-translatable string arguments to methods are taken QByteArray,
00064 // all the translatable are KLocalizedString. The getter methods always return
00065 // proper QString: the non-translatable strings supplied by the code are
00066 // treated with QString::fromUtf8(), those coming from the outside with
00067 // QTextCodec::toUnicode(), and translatable strings are finalized to QStrings
00068 // at the point of getter calls (i.e. delayed translation).
00069 //
00070 // The code below uses locally defined s->decodeInput(QByteArray) and
00071 // s->encodeOutput(QString) calls to centralize the conversion of raw external
00072 // bytes (instead of QString::to/fromLocal8Bit(), QFile::decodeName, etc.)
00073 // -----------------------------------------------------------------------------
00074 
00075 #ifdef Q_WS_X11
00076 #define DISPLAY "DISPLAY"
00077 #elif defined(Q_WS_QWS)
00078 #define DISPLAY "QWS_DISPLAY"
00079 #else
00080 #define DISPLAY "NODISPLAY"
00081 #endif
00082 
00083 //
00084 // Helper classes
00085 //
00086 
00087 class KCmdLineParsedOptions : public QHash<QByteArray,QByteArray>
00088 {
00089 public:
00090    KCmdLineParsedOptions() { }
00091 };
00092 
00093 class KCmdLineParsedArgs : public QList<QByteArray>
00094 {
00095 public:
00096    KCmdLineParsedArgs() { }
00097 };
00098 
00099 
00100 class KCmdLineArgsList: public QList<KCmdLineArgs*>
00101 {
00102 public:
00103    KCmdLineArgsList() { }
00104    ~KCmdLineArgsList() {
00105        while (count())
00106         delete takeFirst();
00107    }
00108 };
00109 
00110 //
00111 // KCmdLineOptions
00112 //
00113 
00114 class KCmdLineOptionsPrivate {
00115     public:
00116     QList<QByteArray> names;
00117     QList<KLocalizedString> descriptions;
00118     QStringList defaults;
00119 };
00120 
00121 KCmdLineOptions::KCmdLineOptions ()
00122 : d(new KCmdLineOptionsPrivate)
00123 {}
00124 
00125 KCmdLineOptions::~KCmdLineOptions ()
00126 {
00127     delete d;
00128 }
00129 
00130 KCmdLineOptions::KCmdLineOptions (const KCmdLineOptions &options)
00131 : d(new KCmdLineOptionsPrivate(*(options.d)))
00132 {
00133 }
00134 
00135 KCmdLineOptions& KCmdLineOptions::operator= (const KCmdLineOptions &options)
00136 {
00137     if (this != &options) {
00138         *d = *(options.d);
00139     }
00140     return *this;
00141 }
00142 
00143 KCmdLineOptions &KCmdLineOptions::add (const QByteArray &name,
00144                                        const KLocalizedString &description,
00145                                        const QByteArray &defaultValue)
00146 {
00147     d->names.append(name);
00148     d->descriptions.append(description);
00149     d->defaults.append(QString::fromUtf8(defaultValue));
00150     return *this;
00151 }
00152 
00153 KCmdLineOptions &KCmdLineOptions::add (const KCmdLineOptions &other)
00154 {
00155     d->names += other.d->names;
00156     d->descriptions += other.d->descriptions;
00157     d->defaults += other.d->defaults;
00158     return *this;
00159 }
00160 
00161 //
00162 // KCmdLineArgs static data and methods
00163 //
00164 
00165 class KCmdLineArgsStatic {
00166     public:
00167 
00168     KCmdLineArgsList *argsList; // All options.
00169     const KAboutData *about;
00170 
00171     int all_argc; // The original argc
00172     char **all_argv; // The original argv
00173     char *appName;
00174     bool parsed : 1; // Whether we have parsed the arguments since calling init
00175     bool ignoreUnknown : 1; // Ignore unknown options and arguments
00176     QByteArray mCwd; // Current working directory. Important for KUnqiueApp!
00177     KCmdLineArgs::StdCmdLineArgs mStdargs;
00178 
00179     KCmdLineOptions qt_options;
00180     KCmdLineOptions kde_options;
00181 
00182     KCmdLineArgsStatic ();
00183 
00184     ~KCmdLineArgsStatic ();
00185 
00186     QTextCodec *codec; // codec for converting raw input to QString
00187 
00195     static QString decodeInput(const QByteArray &rawstr);
00196 
00204     static QByteArray encodeOutput(const QString &str);
00205 
00210     void printQ(const QString &msg);
00211 
00225     static int findOption(const KCmdLineOptions &options, QByteArray &opt,
00226                           QByteArray &opt_name, QString &def, bool &enabled);
00227 
00233     static void findOption(const QByteArray &optv, const QByteArray &_opt,
00234                            int &i, bool _enabled, bool &moreOptions);
00235 
00242     static void parseAllArgs();
00243 
00251     static void removeArgs(const QByteArray &id);
00252 };
00253 
00254 K_GLOBAL_STATIC(KCmdLineArgsStatic, s)
00255 
00256 KCmdLineArgsStatic::KCmdLineArgsStatic () {
00257     // Global data
00258     argsList = 0;
00259     all_argc = 0;
00260     all_argv = 0;
00261     appName = 0;
00262     mCwd.clear();
00263     about = 0;
00264     parsed = false;
00265     ignoreUnknown = false;
00266     mStdargs = 0;
00267 
00268     // Text codec.
00269     codec = QTextCodec::codecForLocale();
00270 
00271     // Qt options
00272     //FIXME: Check if other options are specific to Qt/X11
00273 #ifdef Q_WS_X11
00274     qt_options.add("display <displayname>", ki18n("Use the X-server display 'displayname'"));
00275 #elif defined(Q_WS_QWS)
00276     qt_options.add("display <displayname>", ki18n("Use the QWS display 'displayname'"));
00277 #else
00278 #endif
00279     qt_options.add("session <sessionId>", ki18n("Restore the application for the given 'sessionId'"));
00280     qt_options.add("cmap", ki18n("Causes the application to install a private color\nmap on an 8-bit display"));
00281     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"));
00282     qt_options.add("nograb", ki18n("tells Qt to never grab the mouse or the keyboard"));
00283     qt_options.add("dograb", ki18n("running under a debugger can cause an implicit\n-nograb, use -dograb to override"));
00284     qt_options.add("sync", ki18n("switches to synchronous mode for debugging"));
00285     qt_options.add("fn");
00286     qt_options.add("font <fontname>", ki18n("defines the application font"));
00287     qt_options.add("bg");
00288     qt_options.add("background <color>", ki18n("sets the default background color and an\napplication palette (light and dark shades are\ncalculated)"));
00289     qt_options.add("fg");
00290     qt_options.add("foreground <color>", ki18n("sets the default foreground color"));
00291     qt_options.add("btn");
00292     qt_options.add("button <color>", ki18n("sets the default button color"));
00293     qt_options.add("name <name>", ki18n("sets the application name"));
00294     qt_options.add("title <title>", ki18n("sets the application title (caption)"));
00295 #ifdef Q_WS_X11
00296     qt_options.add("visual TrueColor", ki18n("forces the application to use a TrueColor visual on\nan 8-bit display"));
00297     qt_options.add("inputstyle <inputstyle>", ki18n("sets XIM (X Input Method) input style. Possible\nvalues are onthespot, overthespot, offthespot and\nroot"));
00298     qt_options.add("im <XIM server>", ki18n("set XIM server"));
00299     qt_options.add("noxim", ki18n("disable XIM"));
00300 #endif
00301 #ifdef Q_WS_QWS
00302     qt_options.add("qws", ki18n("forces the application to run as QWS Server"));
00303 #endif
00304     qt_options.add("reverse", ki18n("mirrors the whole layout of widgets"));
00305     qt_options.add("stylesheet <file.qss>", ki18n("applies the Qt stylesheet to the application widgets"));
00306     qt_options.add("graphicssystem <system>", ki18n("use a different graphics system instead of the default one, options are raster and opengl (experimental)"));
00307     // KDE options
00308     kde_options.add("caption <caption>",   ki18n("Use 'caption' as name in the titlebar"));
00309     kde_options.add("icon <icon>",         ki18n("Use 'icon' as the application icon"));
00310     kde_options.add("config <filename>",   ki18n("Use alternative configuration file"));
00311     kde_options.add("nocrashhandler",      ki18n("Disable crash handler, to get core dumps"));
00312 #ifdef Q_WS_X11
00313     kde_options.add("waitforwm",           ki18n("Waits for a WM_NET compatible windowmanager"));
00314 #endif
00315     kde_options.add("style <style>",       ki18n("sets the application GUI style"));
00316     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)"));
00317 #ifndef Q_WS_WIN
00318     kde_options.add("smkey <sessionKey>"); // this option is obsolete and exists only to allow smooth upgrades from sessions
00319 #endif
00320 }
00321 
00322 KCmdLineArgsStatic::~KCmdLineArgsStatic ()
00323 {
00324     delete argsList;
00325     // KAboutData object is deleted by ~KCleanUpGlobalStatic.
00326     //delete about;
00327 }
00328 
00329 //
00330 // KCmdLineArgs private data and methods
00331 //
00332 
00333 class KCmdLineArgsPrivate
00334 {
00335     friend class KCmdLineArgsStatic;
00336 public:
00337     KCmdLineArgsPrivate(const KCmdLineOptions &_options, const KLocalizedString &_name, const QByteArray &_id)
00338         : options(_options)
00339         , name(_name)
00340         , id(_id)
00341         , parsedOptionList(0)
00342         , parsedArgList(0)
00343         , isQt(id == "qt")
00344     {
00345     }
00346     ~KCmdLineArgsPrivate()
00347     {
00348         delete parsedOptionList;
00349         delete parsedArgList;
00350     }
00351     const KCmdLineOptions options;
00352     const KLocalizedString name;
00353     const QByteArray id;
00354     KCmdLineParsedOptions *parsedOptionList;
00355     KCmdLineParsedArgs *parsedArgList;
00356     bool isQt;
00357 
00363     void setOption(const QByteArray &option, bool enabled);
00364 
00370     void setOption(const QByteArray &option, const QByteArray &value);
00371 
00377     void addArgument(const QByteArray &argument);
00378 
00384     void save( QDataStream &) const;
00385 
00391     void load( QDataStream &);
00392 };
00393 
00394 //
00395 // Static functions
00396 //
00397 
00398 QString
00399 KCmdLineArgsStatic::decodeInput(const QByteArray &rawstr)
00400 {
00401     return s->codec->toUnicode(rawstr);
00402 }
00403 
00404 QByteArray
00405 KCmdLineArgsStatic::encodeOutput(const QString &str)
00406 {
00407     return s->codec->fromUnicode(str);
00408 }
00409 
00410 void
00411 KCmdLineArgsStatic::printQ(const QString &msg)
00412 {
00413    fprintf(stdout, "%s", encodeOutput(msg).data());
00414 }
00415 
00416 void
00417 KCmdLineArgs::init(int _argc, char **_argv,
00418                    const QByteArray &_appname,
00419                    const QByteArray &_catalog,
00420                    const KLocalizedString &_programName,
00421                    const QByteArray &_version,
00422                    const KLocalizedString &_description,
00423                    StdCmdLineArgs stdargs)
00424 {
00425    init(_argc, _argv,
00426         new KAboutData(_appname, _catalog, _programName, _version, _description),
00427         stdargs);
00428 }
00429 
00430 void
00431 KCmdLineArgs::initIgnore(int _argc, char **_argv, const QByteArray &_appname )
00432 {
00433    init(_argc, _argv,
00434         new KAboutData(_appname, 0, ki18n(_appname), "unknown", ki18n("KDE Application")));
00435    s->ignoreUnknown = true;
00436 }
00437 
00438 void
00439 KCmdLineArgs::init(const KAboutData* ab)
00440 {
00441    char **_argv = (char **) malloc(sizeof(char *));
00442    _argv[0] = (char *) s->encodeOutput(ab->appName()).data();
00443    init(1,_argv,ab, CmdLineArgNone);
00444 }
00445 
00446 
00447 void
00448 KCmdLineArgs::init(int _argc, char **_argv, const KAboutData *_about, StdCmdLineArgs stdargs)
00449 {
00450    s->all_argc = _argc;
00451    s->all_argv = _argv;
00452 
00453    if (!s->all_argv)
00454    {
00455       fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
00456       fprintf(stderr, "Passing null-pointer to 'argv' is not allowed.\n\n");
00457 
00458       assert( 0 );
00459       exit(255);
00460    }
00461 
00462    // Strip path from argv[0]
00463    if (s->all_argc) {
00464      char *p = strrchr(s->all_argv[0], QDir::separator().toAscii());
00465      if (p)
00466        s->appName = p+1;
00467      else
00468        s->appName = s->all_argv[0];
00469    }
00470 
00471    s->about = _about;
00472    s->parsed = false;
00473    s->mCwd = QDir::currentPath().toLocal8Bit(); //currentPath() uses fromLocal8Bit internally apparently
00474    addStdCmdLineOptions(stdargs);
00475 }
00476 
00477 QString KCmdLineArgs::cwd()
00478 {
00479    return QString::fromLocal8Bit(s->mCwd);
00480 }
00481 
00482 QString KCmdLineArgs::appName()
00483 {
00484    if (!s->appName) return QString();
00485    return s->decodeInput(s->appName);
00486 }
00487 
00491 void KCmdLineArgs::addStdCmdLineOptions(StdCmdLineArgs stdargs) {
00492    if (stdargs & KCmdLineArgs::CmdLineArgQt) {
00493        KCmdLineArgs::addCmdLineOptions(s->qt_options, ki18n("Qt"), "qt");
00494    }
00495    if (stdargs & KCmdLineArgs::CmdLineArgKDE) {
00496        KCmdLineArgs::addCmdLineOptions(s->kde_options, ki18n("KDE"), "kde");
00497    }
00498    s->mStdargs = stdargs;
00499 }
00500 
00501 void
00502 KCmdLineArgs::addCmdLineOptions( const KCmdLineOptions &options, const KLocalizedString &name,
00503          const QByteArray &id, const QByteArray &afterId)
00504 {
00505    if (!s->argsList)
00506       s->argsList = new KCmdLineArgsList;
00507 
00508    int pos = s->argsList->count();
00509    // To make sure that the named options come before unnamed.
00510    if (pos > 0 && !id.isEmpty() && s->argsList->last()->d->name.isEmpty())
00511       pos--;
00512 
00513    KCmdLineArgsList::Iterator args;
00514    int i = 0;
00515    for(args = s->argsList->begin(); args != s->argsList->end(); ++args, i++)
00516    {
00517        if (id == (*args)->d->id) {
00518          return; // Options already present.
00519       }
00520 
00521       // Only check for afterId if it has been given non-empty, as the
00522       // unnamed option group should come after all named groups.
00523       if (!afterId.isEmpty() && afterId == (*args)->d->id)
00524          pos = i+1;
00525    }
00526 
00527    Q_ASSERT( s->parsed == false ); // You must add _ALL_ cmd line options
00528                                    // before accessing the arguments!
00529    s->argsList->insert(pos, new KCmdLineArgs(options, name, id));
00530 }
00531 
00532 void
00533 KCmdLineArgs::saveAppArgs( QDataStream &ds)
00534 {
00535    if (!s->parsed)
00536       s->parseAllArgs();
00537 
00538    // Remove Qt and KDE options.
00539    s->removeArgs("qt");
00540    s->removeArgs("kde");
00541    s->removeArgs("kuniqueapp");
00542 
00543    ds << s->mCwd;
00544 
00545    uint count = s->argsList ? s->argsList->count() : 0;
00546    ds << count;
00547 
00548    if (!count) return;
00549 
00550    KCmdLineArgsList::Iterator args;
00551    for(args = s->argsList->begin(); args != s->argsList->end(); ++args)
00552    {
00553       ds << (*args)->d->id;
00554       (*args)->d->save(ds);
00555    }
00556 }
00557 
00558 void
00559 KCmdLineArgs::loadAppArgs( QDataStream &ds)
00560 {
00561    s->parsed = true; // don't reparse argc/argv!
00562 
00563    // Remove Qt and KDE options.
00564    s->removeArgs("qt");
00565    s->removeArgs("kde");
00566    s->removeArgs("kuniqueapp");
00567 
00568    KCmdLineArgsList::Iterator args;
00569    if ( s->argsList ) {
00570       for(args = s->argsList->begin(); args != s->argsList->end(); ++args)
00571       {
00572          (*args)->clear();
00573       }
00574    }
00575 
00576    if (ds.atEnd())
00577       return;
00578 
00579    QByteArray qCwd;
00580    ds >> qCwd;
00581 
00582    s->mCwd = qCwd;
00583 
00584    uint count;
00585    ds >> count;
00586 
00587    while(count--)
00588    {
00589      QByteArray id;
00590      ds >> id;
00591      Q_ASSERT( s->argsList );
00592      bool found = false;
00593      for(args = s->argsList->begin(); args != s->argsList->end(); ++args)
00594      {
00595        if ((*args)->d->id  == id)
00596        {
00597           (*args)->d->load(ds);
00598           found = true;
00599           break;
00600        }
00601      }
00602      if (!found) {
00603          kWarning() << "Argument definitions for" << id << "not found!";
00604          // The next ds >> id will do nonsensical things...
00605      }
00606    }
00607    s->parsed = true;
00608 }
00609 
00610 KCmdLineArgs *KCmdLineArgs::parsedArgs(const QByteArray &id)
00611 {
00612    if (!s->argsList)
00613       return 0;
00614    KCmdLineArgsList::Iterator args = s->argsList->begin();
00615    while(args != s->argsList->end())
00616    {
00617       if ((*args)->d->id == id)
00618       {
00619           if (!s->parsed)
00620              s->parseAllArgs();
00621           return *args;
00622       }
00623       ++args;
00624    }
00625 
00626    return 0;
00627 }
00628 
00629 void KCmdLineArgsStatic::removeArgs(const QByteArray &id)
00630 {
00631    if (!s->argsList)
00632       return;
00633    KCmdLineArgsList::Iterator args = s->argsList->begin();
00634    while(args != s->argsList->end())
00635    {
00636       if ((*args)->d->id == id)
00637       {
00638           if (!s->parsed)
00639              s->parseAllArgs();
00640           break;
00641       }
00642       ++args;
00643    }
00644 
00645    if (args != s->argsList->end()) {
00646       KCmdLineArgs *a = *args;
00647       s->argsList->erase(args);
00648       delete a;
00649    }
00650 }
00651 
00652 int
00653 KCmdLineArgsStatic::findOption(const KCmdLineOptions &options, QByteArray &opt,
00654                                QByteArray &opt_name, QString &def, bool &enabled)
00655 {
00656    int result;
00657    bool inverse;
00658 
00659    for (int i = 0; i < options.d->names.size(); i++)
00660    {
00661       result = 0;
00662       inverse = false;
00663       opt_name = options.d->names[i];
00664       if (opt_name.startsWith(':') || opt_name.isEmpty())
00665       {
00666          continue;
00667       }
00668       if (opt_name.startsWith('!'))
00669       {
00670          opt_name = opt_name.mid(1);
00671          result = 4;
00672       }
00673       if (opt_name.startsWith("no") && !opt_name.contains('<')) // krazy:exclude=strings
00674       {
00675          opt_name = opt_name.mid(2);
00676          inverse = true;
00677       }
00678 
00679       int len = opt.length();
00680       if (opt == opt_name.left(len))
00681       {
00682          opt_name = opt_name.mid(len);
00683          if (opt_name.isEmpty())
00684          {
00685             if (inverse)
00686                return result+2;
00687 
00688             if (options.d->descriptions[i].isEmpty())
00689             {
00690                i++;
00691                if (i >= options.d->names.size())
00692                   return result+0;
00693                QByteArray nextOption = options.d->names[i];
00694                int p = nextOption.indexOf(' ');
00695                if (p > 0)
00696                   nextOption = nextOption.left(p);
00697                if (nextOption.startsWith('!'))
00698                   nextOption = nextOption.mid(1);
00699                if (nextOption.startsWith("no") && !nextOption.contains('<')) // krazy:exclude=strings
00700                {
00701                   nextOption = nextOption.mid(2);
00702                   enabled = !enabled;
00703                }
00704                result = findOption(options, nextOption, opt_name, def, enabled);
00705                Q_ASSERT(result);
00706                opt = nextOption;
00707                return result;
00708             }
00709 
00710             return 1;
00711          }
00712          if (opt_name.startsWith(' '))
00713          {
00714             opt_name = opt_name.mid(1);
00715             def = options.d->defaults[i];
00716             return result+3;
00717          }
00718       }
00719    }
00720    return 0;
00721 }
00722 
00723 void
00724 KCmdLineArgsStatic::findOption(const QByteArray &optv, const QByteArray &_opt,
00725                                int &i, bool _enabled, bool &moreOptions)
00726 {
00727    KCmdLineArgsList::Iterator args = s->argsList->begin();
00728    QByteArray opt = _opt;
00729    QByteArray opt_name;
00730    QString def;
00731    QByteArray argument;
00732    int j = opt.indexOf('=');
00733    if (j != -1)
00734    {
00735       argument = opt.mid(j+1);
00736       opt = opt.left(j);
00737    }
00738 
00739    bool enabled = true;
00740    int result = 0;
00741    while (args != s->argsList->end())
00742    {
00743       enabled = _enabled;
00744       result = findOption((*args)->d->options, opt, opt_name, def, enabled);
00745       if (result) break;
00746       ++args;
00747    }
00748    if ((args == s->argsList->end()) &&
00749        (optv.startsWith('-') && !optv.startsWith("--")))
00750    {
00751       // Option not found check if it is a valid option
00752       // in the style of -Pprinter1 or ps -aux
00753       int p = 1;
00754       while (true)
00755       {
00756          QByteArray singleCharOption = " "; // krazy:exclude=doublequote_chars
00757          singleCharOption[0] = optv[p];
00758          args = s->argsList->begin();
00759          while (args != s->argsList->end())
00760          {
00761             enabled = _enabled;
00762             result = findOption((*args)->d->options, singleCharOption,
00763                       opt_name, def, enabled);
00764             if (result) break;
00765             ++args;
00766          }
00767          if (args == s->argsList->end())
00768             break; // Unknown argument
00769 
00770          p++;
00771          if (result == 1) // Single option
00772          {
00773             (*args)->d->setOption(singleCharOption, enabled);
00774             if (p < optv.length())
00775                continue; // Next option
00776             else
00777                return; // Finished
00778          }
00779          else if (result == 3) // This option takes an argument
00780          {
00781             if (argument.isEmpty())
00782             {
00783                argument = optv.mid(p);
00784             }
00785             (*args)->d->setOption(singleCharOption, argument);
00786             return;
00787          }
00788          break; // Unknown argument
00789       }
00790       args = s->argsList->end();
00791       result = 0;
00792    }
00793 
00794    if (args == s->argsList->end() || !result)
00795    {
00796       if (s->ignoreUnknown)
00797          return;
00798       KCmdLineArgs::enable_i18n();
00799       KCmdLineArgs::usageError( i18n("Unknown option '%1'.", QString::fromLocal8Bit(_opt)));
00800    }
00801 
00802    if ((result & 4) != 0)
00803    {
00804       result &= ~4;
00805       moreOptions = false;
00806    }
00807 
00808    if (result == 3) // This option takes an argument
00809    {
00810       if (!enabled)
00811       {
00812          if (s->ignoreUnknown)
00813             return;
00814          KCmdLineArgs::enable_i18n();
00815          KCmdLineArgs::usageError( i18n("Unknown option '%1'.", QString::fromLocal8Bit(_opt)));
00816       }
00817       if (argument.isEmpty())
00818       {
00819          i++;
00820          if (i >= s->all_argc)
00821          {
00822             KCmdLineArgs::enable_i18n();
00823             KCmdLineArgs::usageError( i18nc("@info:shell %1 is cmdoption name","'%1' missing.",  QString::fromLocal8Bit(opt_name)));
00824          }
00825          argument = s->all_argv[i];
00826       }
00827       (*args)->d->setOption(opt, argument);
00828    }
00829    else
00830    {
00831       (*args)->d->setOption(opt, enabled);
00832    }
00833 }
00834 
00835 void
00836 KCmdLineArgsStatic::parseAllArgs()
00837 {
00838    bool allowArgs = false;
00839    bool inOptions = true;
00840    bool everythingAfterArgIsArgs = false;
00841    KCmdLineArgs *appOptions = s->argsList->last();
00842    if (appOptions->d->id.isEmpty())
00843    {
00844      foreach(const QByteArray& name, appOptions->d->options.d->names)
00845      {
00846        everythingAfterArgIsArgs = everythingAfterArgIsArgs || name.startsWith("!+");
00847        allowArgs = allowArgs || name.startsWith('+') || everythingAfterArgIsArgs;
00848      }
00849    }
00850    for(int i = 1; i < s->all_argc; i++)
00851    {
00852       if (!s->all_argv[i])
00853          continue;
00854 
00855       if ((s->all_argv[i][0] == '-') && s->all_argv[i][1] && inOptions)
00856       {
00857          bool enabled = true;
00858          QByteArray orig = s->all_argv[i];
00859          QByteArray option = orig.mid(1);
00860          if (option.startsWith('-'))
00861          {
00862             option = option.mid(1);
00863             if (option.isEmpty())
00864             {
00865                inOptions = false;
00866                continue;
00867             }
00868          }
00869          if (option == "help")
00870          {
00871             KCmdLineArgs::usage();
00872          }
00873          else if (option.startsWith("help-")) // krazy:exclude=strings
00874          {
00875             KCmdLineArgs::usage(option.mid(5));
00876          }
00877 #ifdef Q_WS_MAC
00878          // skip the finder -psn_* hint
00879          else if (option.startsWith("psn_")) // krazy:exclude=strings
00880          {
00881             continue;
00882          }
00883 #endif
00884          else if ((option == "version") || (option == "v"))
00885          {
00886             KCmdLineArgs::enable_i18n();
00887             s->printQ(i18nc("@info:shell message on appcmd --version; do not translate 'Development Platform'"
00888                             "%3 application name, other %n version strings",
00889                             "Qt: %1\n"
00890                             "KDE Development Platform: %2\n"
00891                             "%3: %4\n",
00892                             QString::fromLatin1(qVersion()),
00893                             QString::fromLatin1(KDE_VERSION_STRING),
00894                             s->about->programName(), s->about->version()));
00895             exit(0);
00896          } else if (option == "license")
00897          {
00898             KCmdLineArgs::enable_i18n();
00899             s->printQ(s->about->license());
00900             s->printQ(QString::fromLatin1("\n"));
00901             exit(0);
00902          } else if (option == "author") {
00903              KCmdLineArgs::enable_i18n();
00904        if ( s->about ) {
00905          const QList<KAboutPerson> authors = s->about->authors();
00906          if ( !authors.isEmpty() ) {
00907            QString authorlist;
00908            for (QList<KAboutPerson>::ConstIterator it = authors.begin(); it != authors.end(); ++it ) {
00909              QString email;
00910              if ( !(*it).emailAddress().isEmpty() )
00911                email = QString::fromLatin1(" &lt;") + (*it).emailAddress() + QLatin1String("&gt;");
00912              authorlist += QString::fromLatin1("    ") + (*it).name() + email + QLatin1Char('\n');
00913            }
00914            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 ) );
00915          }
00916        } else {
00917          s->printQ( i18n("This application was written by somebody who wants to remain anonymous.") );
00918        }
00919        if (s->about)
00920        {
00921          if (!s->about->customAuthorTextEnabled ())
00922          {
00923            if (s->about->bugAddress().isEmpty() || s->about->bugAddress() == QLatin1String("submit@bugs.kde.org") )
00924              s->printQ( i18n( "Please use http://bugs.kde.org to report bugs.\n" ) );
00925            else
00926              s->printQ( i18n( "Please report bugs to %1.\n" , s->about->bugAddress()) );
00927          }
00928          else
00929          {
00930            s->printQ(s->about->customAuthorPlainText()+QLatin1Char('\n'));
00931          }
00932        }
00933        exit(0);
00934          } else {
00935            if (option.startsWith("no")) // krazy:exclude=strings
00936            {
00937               bool noHasParameter=false;
00938               foreach(const QByteArray& name, appOptions->d->options.d->names)
00939               {
00940                  if (name.contains(option + QByteArray(" ")) && name.contains('<'))
00941                  {
00942                     noHasParameter=true;
00943                     break;
00944                   }
00945               }
00946               if (!noHasParameter)
00947               {
00948                  option = option.mid(2);
00949                  enabled = false;
00950               }
00951            }
00952            s->findOption(orig, option, i, enabled, inOptions);
00953          }
00954       }
00955       else
00956       {
00957          // Check whether appOptions allows these arguments
00958          if (!allowArgs)
00959          {
00960             if (s->ignoreUnknown)
00961                continue;
00962             KCmdLineArgs::enable_i18n();
00963             KCmdLineArgs::usageError(i18n("Unexpected argument '%1'.", KuitSemantics::escape(s->decodeInput(s->all_argv[i]))));
00964          }
00965          else
00966          {
00967             appOptions->d->addArgument(s->all_argv[i]);
00968             if (everythingAfterArgIsArgs)
00969                 inOptions = false;
00970          }
00971       }
00972    }
00973    s->parsed = true;
00974 }
00975 
00976 int & KCmdLineArgs::qtArgc()
00977 {
00978    if (!s->argsList)
00979       addStdCmdLineOptions(CmdLineArgKDE|CmdLineArgQt); // Lazy bastards!
00980 
00981    static int qt_argc = -1;
00982    if( qt_argc != -1 )
00983       return qt_argc;
00984 
00985    if (!(s->mStdargs & KCmdLineArgs::CmdLineArgQt))
00986    {
00987      qt_argc = 2;
00988      return qt_argc;
00989    }
00990 
00991    KCmdLineArgs *args = parsedArgs("qt");
00992    Q_ASSERT(args); // No qt options have been added!
00993    if (!s->all_argv)
00994    {
00995       fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
00996       fprintf(stderr, "Application has not called KCmdLineArgs::init(...).\n\n");
00997 
00998       assert( 0 );
00999       exit(255);
01000    }
01001 
01002    Q_ASSERT(s->all_argc >= (args->count()+1));
01003    qt_argc = args->count() +1;
01004    return qt_argc;
01005 }
01006 
01007 static char** s_qt_argv;
01008 
01009 char **
01010 KCmdLineArgs::qtArgv()
01011 {
01012    if (!s->argsList)
01013       addStdCmdLineOptions(CmdLineArgKDE|CmdLineArgQt); // Lazy bastards!
01014 
01015    if( s_qt_argv != NULL )
01016       return s_qt_argv;
01017 
01018    if (!(s->mStdargs & KCmdLineArgs::CmdLineArgQt))
01019    {
01020      s_qt_argv = new char*[2];
01021      s_qt_argv[0] = qstrdup(s->all_argc?s->all_argv[0]:"");
01022      s_qt_argv[1] = 0;
01023 
01024      return s_qt_argv;
01025    }
01026 
01027    KCmdLineArgs *args = parsedArgs("qt");
01028    if (!args)
01029    {
01030       fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
01031       fprintf(stderr, "The \"qt\" options have not be added to KCmdLineArgs!\n\n");
01032 
01033       assert( 0 );
01034       exit(255);
01035    }
01036    if (!s->all_argv)
01037    {
01038       fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
01039       fprintf(stderr, "Application has not called KCmdLineArgs::init(...).\n\n");
01040 
01041       assert( 0 );
01042       exit(255);
01043    }
01044 
01045    int count=args->count();
01046    s_qt_argv = new char*[ count + 2 ];
01047    s_qt_argv[0] = qstrdup(s->all_argc?s->all_argv[0]:"");
01048    int i = 0;
01049    for(; i < count; i++)
01050    {
01051       s_qt_argv[i+1] = qstrdup(args->d->parsedArgList->at(i));
01052    }
01053    s_qt_argv[i+1] = 0;
01054 
01055    return s_qt_argv;
01056 }
01057 
01058 const KAboutData *
01059 KCmdLineArgs::aboutData()
01060 {
01061     return s->about;
01062 }
01063 
01064 void
01065 KCmdLineArgs::enable_i18n()
01066 {
01067     // called twice or too late
01068     if (KGlobal::hasLocale())
01069       return;
01070 
01071     if (!KGlobal::hasMainComponent()) {
01072         KComponentData mainComponentData(s->about);
01073         mainComponentData.config();
01074         // mainComponentData is now the main component and won't disappear until KGlobal deletes it
01075     }
01076 }
01077 
01078 void
01079 KCmdLineArgs::usageError(const QString &error)
01080 {
01081     Q_ASSERT(KGlobal::hasLocale());
01082     QByteArray localError = s->encodeOutput(error);
01083     if (localError.endsWith('\n'))
01084         localError.chop(1);
01085     fprintf(stderr, "%s: %s\n", s->appName, localError.data());
01086 
01087     QString tmp = i18n("Use --help to get a list of available command line options.");
01088     localError = s->encodeOutput(tmp);
01089     fprintf(stderr, "%s: %s\n", s->appName, localError.data());
01090     exit(254);
01091 }
01092 
01093 void
01094 KCmdLineArgs::usage(const QByteArray &id)
01095 {
01096    enable_i18n();
01097    Q_ASSERT(s->argsList != 0); // It's an error to call usage(...) without
01098                                // having done addCmdLineOptions first!
01099 
01100    QString optionFormatString = QString::fromLatin1("  %1 %2\n");
01101    QString optionFormatStringDef = QString::fromLatin1("  %1 %2 [%3]\n");
01102    QString tmp;
01103    QString usage;
01104 
01105    KCmdLineArgsList::Iterator args = --(s->argsList->end());
01106 
01107    if ((*args)->d->id.isEmpty() && ((*args)->d->options.d->names.size() > 0) &&
01108        !(*args)->d->options.d->names[0].startsWith('+'))
01109    {
01110       usage = i18n("[options] ")+usage;
01111    }
01112 
01113    while(true)
01114    {
01115       if (!(*args)->d->name.isEmpty())
01116       {
01117          usage = i18n("[%1-options]", (*args)->d->name.toString())+QLatin1Char(' ')+usage;
01118       }
01119       if (args == s->argsList->begin())
01120          break;
01121       --args;
01122    }
01123 
01124    KCmdLineArgs *appOptions = s->argsList->last();
01125    if (appOptions->d->id.isEmpty())
01126    {
01127      const KCmdLineOptions &option = appOptions->d->options;
01128      for (int i = 0; i < option.d->names.size(); i++)
01129      {
01130        QByteArray opt_name = option.d->names[i];
01131        if (opt_name.startsWith('+'))
01132            usage += QString::fromLatin1(opt_name.mid(1)) + QLatin1Char(' ');
01133        else if ( opt_name.startsWith("!+") )
01134           usage += QString::fromLatin1(opt_name.mid(2)) + QLatin1Char(' ');
01135      }
01136    }
01137 
01138    s->printQ(i18n("Usage: %1 %2\n", QString::fromLocal8Bit(s->appName), KuitSemantics::escape(usage)));
01139    s->printQ(QLatin1Char('\n')+s->about->shortDescription()+QLatin1Char('\n'));
01140 
01141    s->printQ(i18n("\nGeneric options:\n"));
01142    s->printQ(optionFormatString.arg(QString::fromLatin1("--help"), -25)
01143              .arg(i18n("Show help about options")));
01144 
01145    args = s->argsList->begin();
01146    while(args != s->argsList->end())
01147    {
01148       if (!(*args)->d->name.isEmpty() && !(*args)->d->id.isEmpty())
01149       {
01150           QString option = QString::fromLatin1("--help-%1").arg(QString::fromLatin1((*args)->d->id));
01151          QString desc = i18n("Show %1 specific options", (*args)->d->name.toString());
01152 
01153          s->printQ(optionFormatString.arg(option, -25).arg(desc));
01154       }
01155       ++args;
01156    }
01157 
01158    s->printQ(optionFormatString.arg(QString::fromLatin1("--help-all"),-25).arg(i18n("Show all options")));
01159    s->printQ(optionFormatString.arg(QString::fromLatin1("--author"),-25).arg(i18n("Show author information")));
01160    s->printQ(optionFormatString.arg(QString::fromLatin1("-v, --version"),-25).arg(i18n("Show version information")));
01161    s->printQ(optionFormatString.arg(QString::fromLatin1("--license"),-25).arg(i18n("Show license information")));
01162    s->printQ(optionFormatString.arg(QString::fromLatin1("--"), -25).arg(i18n("End of options")));
01163 
01164    args = s->argsList->begin(); // Sets current to 1st.
01165 
01166    bool showAll = (id == "all");
01167 
01168    if (!showAll)
01169    {
01170      while(args != s->argsList->end())
01171      {
01172        if (id == (*args)->d->id) break;
01173        ++args;
01174      }
01175    }
01176 
01177    while(args != s->argsList->end())
01178    {
01179      bool hasArgs = false;
01180      bool hasOptions = false;
01181      QString optionsHeader;
01182      if (!(*args)->d->name.isEmpty())
01183         optionsHeader = i18n("\n%1 options:\n", (*args)->d->name.toString());
01184      else
01185         optionsHeader = i18n("\nOptions:\n");
01186 
01187      while (args != s->argsList->end())
01188      {
01189        const KCmdLineOptions &option = (*args)->d->options;
01190        QByteArray opt;
01191 
01192        for (int i = 0; i < option.d->names.size(); i++)
01193        {
01194          QString description;
01195          QStringList dl;
01196 
01197          QString descriptionFull;
01198          if (!option.d->descriptions[i].isEmpty()) {
01199             descriptionFull = option.d->descriptions[i].toString();
01200          }
01201 
01202          // Option header
01203          if (option.d->names[i].startsWith(':'))
01204          {
01205             if (!descriptionFull.isEmpty())
01206             {
01207                optionsHeader = QLatin1Char('\n')+descriptionFull;
01208                if (!optionsHeader.endsWith(QLatin1Char('\n')))
01209                   optionsHeader.append(QLatin1Char('\n'));
01210                hasOptions = false;
01211             }
01212             continue;
01213          }
01214 
01215          // Free-form comment
01216          if (option.d->names[i].isEmpty())
01217          {
01218             if (!descriptionFull.isEmpty())
01219             {
01220                tmp = QLatin1Char('\n')+descriptionFull;
01221                if (!tmp.endsWith(QLatin1Char('\n')))
01222                   tmp.append(QLatin1Char('\n'));
01223                s->printQ(tmp);
01224             }
01225             continue;
01226          }
01227 
01228          // Options
01229          if (!descriptionFull.isEmpty())
01230          {
01231             dl = descriptionFull.split(QLatin1Char('\n'), QString::KeepEmptyParts);
01232             description = dl.first();
01233             dl.erase( dl.begin() );
01234          }
01235          QByteArray name = option.d->names[i];
01236          if (name.startsWith('!'))
01237              name = name.mid(1);
01238 
01239          if (name.startsWith('+'))
01240          {
01241             if (!hasArgs)
01242             {
01243                s->printQ(i18n("\nArguments:\n"));
01244                hasArgs = true;
01245             }
01246 
01247             name = name.mid(1);
01248             if (name.startsWith('[') && name.endsWith(']'))
01249                 name = name.mid(1, name.length()-2);
01250             s->printQ(optionFormatString.arg(QString::fromLocal8Bit(name), -25).arg(description));
01251          }
01252          else
01253          {
01254             if (!hasOptions)
01255             {
01256                s->printQ(optionsHeader);
01257                hasOptions = true;
01258             }
01259 
01260             if ((name.length() == 1) || (name[1] == ' '))
01261                name = '-'+name;
01262             else
01263                name = "--"+name;
01264             if (descriptionFull.isEmpty())
01265             {
01266                opt = name + ", ";
01267             }
01268             else
01269             {
01270                opt = opt + name;
01271                if (option.d->defaults[i].isEmpty())
01272                {
01273                    s->printQ(optionFormatString.arg(QString::fromLatin1(opt), -25).arg(description));
01274                }
01275                else
01276                {
01277                    s->printQ(optionFormatStringDef.arg(QString::fromLatin1(opt), -25)
01278                             .arg(description, option.d->defaults[i]));
01279                }
01280                opt.clear();
01281             }
01282          }
01283          for(QStringList::Iterator it = dl.begin();
01284              it != dl.end();
01285              ++it)
01286          {
01287             s->printQ(optionFormatString.arg(QString(), -25).arg(*it));
01288          }
01289        }
01290 
01291        ++args;
01292        if (args == s->argsList->end() || !(*args)->d->name.isEmpty() || (*args)->d->id.isEmpty())
01293         break;
01294      }
01295      if (!showAll) break;
01296    }
01297 
01298    exit(0);
01299 }
01300 
01301 //
01302 // Member functions
01303 //
01304 
01310 KCmdLineArgs::KCmdLineArgs( const KCmdLineOptions &_options,
01311                             const KLocalizedString &_name,
01312                             const QByteArray &_id)
01313   : d(new KCmdLineArgsPrivate(_options, _name, _id))
01314 {
01315 }
01316 
01320 KCmdLineArgs::~KCmdLineArgs()
01321 {
01322   if (!s.isDestroyed() && s->argsList)
01323      s->argsList->removeAll(this);
01324   delete d;
01325 }
01326 
01327 void
01328 KCmdLineArgs::setCwd( const QByteArray &cwd )
01329 {
01330     s->mCwd = cwd;
01331 }
01332 
01333 void
01334 KCmdLineArgs::clear()
01335 {
01336    delete d->parsedArgList;     d->parsedArgList = 0;
01337    delete d->parsedOptionList;  d->parsedOptionList = 0;
01338 }
01339 
01340 void
01341 KCmdLineArgs::reset()
01342 {
01343    delete s->argsList; s->argsList = 0;
01344    s->parsed = false;
01345 }
01346 
01347 void
01348 KCmdLineArgsPrivate::save( QDataStream &ds) const
01349 {
01350    if (parsedOptionList)
01351       ds << (*(parsedOptionList));
01352    else
01353       ds << quint32(0);
01354 
01355    if (parsedArgList)
01356       ds << (*(parsedArgList));
01357    else
01358       ds << quint32(0);
01359 }
01360 
01361 void
01362 KCmdLineArgsPrivate::load( QDataStream &ds)
01363 {
01364    if (!parsedOptionList) parsedOptionList = new KCmdLineParsedOptions;
01365    if (!parsedArgList) parsedArgList = new KCmdLineParsedArgs;
01366 
01367    ds >> (*(parsedOptionList));
01368    ds >> (*(parsedArgList));
01369 
01370    if (parsedOptionList->count() == 0)
01371    {
01372       delete parsedOptionList;  parsedOptionList = 0;
01373    }
01374    if (parsedArgList->count() == 0)
01375    {
01376       delete parsedArgList;     parsedArgList = 0;
01377    }
01378 }
01379 
01380 void
01381 KCmdLineArgsPrivate::setOption(const QByteArray &opt, bool enabled)
01382 {
01383    if (isQt)
01384    {
01385       // Qt does it own parsing.
01386       QByteArray argString = "-"; // krazy:exclude=doublequote_chars
01387       if( !enabled )
01388           argString += "no";
01389       argString += opt;
01390       addArgument(argString);
01391    }
01392    if (!parsedOptionList) {
01393       parsedOptionList = new KCmdLineParsedOptions;
01394    }
01395 
01396    if (enabled)
01397       parsedOptionList->insert( opt, "t" ); // krazy:exclude=doublequote_chars
01398    else
01399       parsedOptionList->insert( opt, "f" ); // krazy:exclude=doublequote_chars
01400 }
01401 
01402 void
01403 KCmdLineArgsPrivate::setOption(const QByteArray &opt, const QByteArray &value)
01404 {
01405    if (isQt)
01406    {
01407       // Qt does it's own parsing.
01408       QByteArray argString = "-"; // krazy:exclude=doublequote_chars
01409       argString += opt;
01410       addArgument(argString);
01411       addArgument(value);
01412 
01413 #if defined(Q_WS_X11) || defined(Q_WS_QWS)
01414       // Hack coming up!
01415       if (argString == "-display")
01416       {
01417          setenv(DISPLAY, value.data(), true);
01418       }
01419 #endif
01420    }
01421    if (!parsedOptionList) {
01422       parsedOptionList = new KCmdLineParsedOptions;
01423    }
01424 
01425    parsedOptionList->insertMulti( opt, value );
01426 }
01427 
01428 QString
01429 KCmdLineArgs::getOption(const QByteArray &_opt) const
01430 {
01431    QByteArray opt = _opt;
01432    QByteArray value;
01433    if (d->parsedOptionList)
01434    {
01435       value = d->parsedOptionList->value(opt);
01436    }
01437    if (!value.isEmpty())
01438        return QString::fromLocal8Bit(value);
01439 
01440    // Look up the default.
01441    QByteArray opt_name;
01442    QString def;
01443    bool dummy = true;
01444    int result = s->findOption( d->options, opt, opt_name, def, dummy) & ~4;
01445 
01446    if (result != 3)
01447    {
01448       fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
01449       fprintf(stderr, "Application requests for getOption(\"%s\") but the \"%s\" option\n",
01450                       opt.data(), opt.data());
01451       fprintf(stderr, "has never been specified via addCmdLineOptions( ... )\n\n");
01452 
01453       Q_ASSERT( 0 );
01454       exit(255);
01455    }
01456    return def;
01457 }
01458 
01459 QStringList
01460 KCmdLineArgs::getOptionList(const QByteArray &opt) const
01461 {
01462    QStringList result;
01463    if (!d->parsedOptionList)
01464       return result;
01465 
01466    while(true)
01467    {
01468       QByteArray value = d->parsedOptionList->take(opt);
01469       if (value.isEmpty())
01470          break;
01471       result.prepend(QString::fromLocal8Bit(value));
01472    }
01473 
01474    // Reinsert items in dictionary
01475    // WABA: This is rather silly, but I don't want to add restrictions
01476    // to the API like "you can only call this function once".
01477    // I can't access all items without taking them out of the list.
01478    // So taking them out and then putting them back is the only way.
01479    Q_FOREACH(const QString &str, result)
01480    {
01481       d->parsedOptionList->insertMulti(opt, str.toLocal8Bit());
01482    }
01483    return result;
01484 }
01485 
01486 bool
01487 KCmdLineArgs::isSet(const QByteArray &_opt) const
01488 {
01489    // Look up the default.
01490    QByteArray opt = _opt;
01491    QByteArray opt_name;
01492    QString def;
01493    int result = 0;
01494    KCmdLineArgsList::Iterator args = s->argsList->begin();
01495    while (args != s->argsList->end())
01496    {
01497       bool dummy = true;
01498       result = s->findOption((*args)->d->options, opt, opt_name, def, dummy) & ~4;
01499       if (result) break;
01500       ++args;
01501    }
01502 
01503    if (result == 0)
01504    {
01505       fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
01506       fprintf(stderr, "Application requests for isSet(\"%s\") but the \"%s\" option\n",
01507                       opt.data(), opt.data());
01508       fprintf(stderr, "has never been specified via addCmdLineOptions( ... )\n\n");
01509 
01510       Q_ASSERT( 0 );
01511       exit(255);
01512    }
01513 
01514    QByteArray value;
01515    if (d->parsedOptionList)
01516    {
01517       value = d->parsedOptionList->value(opt);
01518    }
01519 
01520    if (!value.isEmpty())
01521    {
01522       if (result == 3)
01523          return true;
01524       else
01525          return (value.at(0) == 't');
01526    }
01527 
01528    if (result == 3)
01529       return false; // String option has 'false' as default.
01530 
01531    // We return 'true' as default if the option was listed as '-nofork'
01532    // We return 'false' as default if the option was listed as '-fork'
01533    return (result == 2);
01534 }
01535 
01536 int
01537 KCmdLineArgs::count() const
01538 {
01539    return d->parsedArgList?d->parsedArgList->count():0;
01540 }
01541 
01542 QString
01543 KCmdLineArgs::arg(int n) const
01544 {
01545    if (!d->parsedArgList || (n >= (int) d->parsedArgList->count()))
01546    {
01547       fprintf(stderr, "\n\nFAILURE (KCmdLineArgs): Argument out of bounds\n");
01548       fprintf(stderr, "Application requests for arg(%d) without checking count() first.\n",
01549                       n);
01550 
01551       Q_ASSERT( 0 );
01552       exit(255);
01553    }
01554 
01555    return QString::fromLocal8Bit(d->parsedArgList->at(n));
01556 }
01557 
01558 KUrl
01559 KCmdLineArgs::url(int n) const
01560 {
01561    return makeURL( arg(n).toUtf8() );
01562 }
01563 
01564 KUrl KCmdLineArgs::makeURL(const QByteArray &_urlArg)
01565 {
01566     const QString urlArg = QString::fromUtf8(_urlArg);
01567     QFileInfo fileInfo(urlArg);
01568     if (!fileInfo.isRelative()) { // i.e. starts with '/', on unix
01569         KUrl result;
01570         result.setPath(QDir::fromNativeSeparators(urlArg));
01571         return result; // Absolute path.
01572     }
01573 
01574     if ( KUrl::isRelativeUrl(urlArg) || fileInfo.exists() ) {
01575         KUrl result;
01576         result.setPath(cwd()+QLatin1Char('/')+urlArg);
01577         result.cleanPath();
01578         return result;  // Relative path
01579     }
01580 
01581     return KUrl(urlArg); // Argument is a URL
01582 }
01583 
01584 void
01585 KCmdLineArgsPrivate::addArgument(const QByteArray &argument)
01586 {
01587    if (!parsedArgList)
01588       parsedArgList = new KCmdLineParsedArgs;
01589 
01590    parsedArgList->append(argument);
01591 }
01592 
01593 void
01594 KCmdLineArgs::addTempFileOption()
01595 {
01596     KCmdLineOptions tmpopt;
01597     tmpopt.add( "tempfile", ki18n("The files/URLs opened by the application will be deleted after use") );
01598     KCmdLineArgs::addCmdLineOptions( tmpopt, ki18n("KDE-tempfile"), "kde-tempfile" );
01599 }
01600 
01601 bool KCmdLineArgs::isTempFileSet()
01602 {
01603     KCmdLineArgs* args = KCmdLineArgs::parsedArgs( "kde-tempfile" );
01604     return args && args->isSet( "tempfile" );
01605 }
01606 
01607 QStringList KCmdLineArgs::allArguments()
01608 {
01609     QStringList lst;
01610 
01611     for(int i = 0; i < s->all_argc; i++) {
01612         char* arg = s->all_argv[i];
01613         if (!arg)
01614             continue;
01615         lst.append(QString::fromLocal8Bit(arg));
01616     }
01617     return lst;
01618 }

KDECore

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • 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
Generated for kdelibs by doxygen 1.7.3
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal