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

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
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
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