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

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
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
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