• Skip to content
  • Skip to link menu
KDE 4.1 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 = QString();
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 
00305     // KDE options
00306     kde_options.add("caption <caption>",   ki18n("Use 'caption' as name in the titlebar"));
00307     kde_options.add("icon <icon>",         ki18n("Use 'icon' as the application icon"));
00308     kde_options.add("config <filename>",   ki18n("Use alternative configuration file"));
00309     kde_options.add("nocrashhandler",      ki18n("Disable crash handler, to get core dumps"));
00310 #ifdef Q_WS_X11
00311     kde_options.add("waitforwm",           ki18n("Waits for a WM_NET compatible windowmanager"));
00312 #endif
00313     kde_options.add("style <style>",       ki18n("sets the application GUI style"));
00314     kde_options.add("geometry <geometry>", ki18n("sets the client geometry of the main widget - see man X for the argument format"));
00315 #ifndef Q_WS_WIN
00316     kde_options.add("smkey <sessionKey>"); // this option is obsolete and exists only to allow smooth upgrades from sessions
00317 #endif
00318 }
00319 
00320 KCmdLineArgsStatic::~KCmdLineArgsStatic ()
00321 {
00322     delete argsList;
00323     // KAboutData object is deleted by ~KCleanUpGlobalStatic.
00324     //delete about;
00325 }
00326 
00327 //
00328 // KCmdLineArgs private data and methods
00329 //
00330 
00331 class KCmdLineArgsPrivate
00332 {
00333     friend class KCmdLineArgsStatic;
00334 public:
00335     KCmdLineArgsPrivate(const KCmdLineOptions &_options, const KLocalizedString &_name, const QString &_id)
00336         : options(_options)
00337         , name(_name)
00338         , id(_id)
00339         , parsedOptionList(0)
00340         , parsedArgList(0)
00341         , isQt(id == "qt")
00342     {}
00343     ~KCmdLineArgsPrivate()
00344     {
00345         delete parsedOptionList;
00346         delete parsedArgList;
00347     }
00348     const KCmdLineOptions options;
00349     const KLocalizedString name;
00350     const QString id;
00351     KCmdLineParsedOptions *parsedOptionList;
00352     KCmdLineParsedArgs *parsedArgList;
00353     bool isQt;
00354 
00360     void setOption(const QString &option, bool enabled);
00361 
00367     void setOption(const QString &option, const QString &value);
00368 
00374     void addArgument(const QString &argument);
00375 
00381     void save( QDataStream &) const;
00382 
00388     void load( QDataStream &);
00389 };
00390 
00391 //
00392 // Static functions
00393 //
00394 
00395 QString
00396 KCmdLineArgsStatic::decodeInput(const QByteArray &rawstr)
00397 {
00398     return s->codec->toUnicode(rawstr);
00399 }
00400 
00401 QByteArray
00402 KCmdLineArgsStatic::encodeOutput(const QString &str)
00403 {
00404     return s->codec->fromUnicode(str);
00405 }
00406 
00407 void
00408 KCmdLineArgsStatic::printQ(const QString &msg)
00409 {
00410    fprintf(stdout, "%s", encodeOutput(msg).data());
00411 }
00412 
00413 void
00414 KCmdLineArgs::init(int _argc, char **_argv,
00415                    const QByteArray &_appname,
00416                    const QByteArray &_catalog,
00417                    const KLocalizedString &_programName,
00418                    const QByteArray &_version,
00419                    const KLocalizedString &_description,
00420                    StdCmdLineArgs stdargs)
00421 {
00422    init(_argc, _argv,
00423         new KAboutData(_appname, _catalog, _programName, _version, _description),
00424         stdargs);
00425 }
00426 
00427 void
00428 KCmdLineArgs::initIgnore(int _argc, char **_argv, const QByteArray &_appname )
00429 {
00430    init(_argc, _argv,
00431         new KAboutData(_appname, 0, ki18n(_appname), "unknown", ki18n("KDE Application")));
00432    s->ignoreUnknown = true;
00433 }
00434 
00435 void
00436 KCmdLineArgs::init(const KAboutData* ab)
00437 {
00438    char **_argv = (char **) malloc(sizeof(char *));
00439    _argv[0] = (char *) s->encodeOutput(ab->appName()).data();
00440    init(1,_argv,ab, CmdLineArgNone);
00441 }
00442 
00443 
00444 void
00445 KCmdLineArgs::init(int _argc, char **_argv, const KAboutData *_about, StdCmdLineArgs stdargs)
00446 {
00447    s->argc = _argc;
00448    s->argv = _argv;
00449 
00450    if (!s->argv)
00451    {
00452       fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
00453       fprintf(stderr, "Passing null-pointer to 'argv' is not allowed.\n\n");
00454 
00455       assert( 0 );
00456       exit(255);
00457    }
00458 
00459    // Strip path from argv[0]
00460    if (s->argc) {
00461      char *p = strrchr( s->argv[0], '/');
00462      if (p)
00463        s->argv[0] = p+1;
00464    }
00465 
00466    s->about = _about;
00467    s->parsed = false;
00468    s->mCwd = QDir::currentPath();
00469    addStdCmdLineOptions(stdargs);
00470 }
00471 
00472 QString KCmdLineArgs::cwd()
00473 {
00474    return s->mCwd;
00475 }
00476 
00477 QString KCmdLineArgs::appName()
00478 {
00479    if (!s->argc) return QString();
00480    return s->decodeInput(s->argv[0]);
00481 }
00482 
00486 void KCmdLineArgs::addStdCmdLineOptions(StdCmdLineArgs stdargs) {
00487    if (stdargs & KCmdLineArgs::CmdLineArgQt) {
00488        KCmdLineArgs::addCmdLineOptions(s->qt_options, ki18n("Qt"), "qt");
00489    }
00490    if (stdargs & KCmdLineArgs::CmdLineArgKDE) {
00491        KCmdLineArgs::addCmdLineOptions(s->kde_options, ki18n("KDE"), "kde");
00492    }
00493    s->mStdargs = stdargs;
00494 }
00495 
00496 void
00497 KCmdLineArgs::addCmdLineOptions( const KCmdLineOptions &options, const KLocalizedString &name,
00498          const QByteArray &_id, const QByteArray &_afterId)
00499 {
00500    if (!s->argsList)
00501       s->argsList = new KCmdLineArgsList;
00502 
00503    QString id = QString::fromUtf8(_id);
00504    QString afterId = QString::fromUtf8(_afterId);
00505 
00506    int pos = s->argsList->count();
00507    // To make sure that the named options come before unnamed.
00508    if (pos > 0 && !id.isEmpty() && s->argsList->last()->d->name.isEmpty())
00509       pos--;
00510 
00511    KCmdLineArgsList::Iterator args;
00512    int i = 0;
00513    for(args = s->argsList->begin(); args != s->argsList->end(); ++args, i++)
00514    {
00515       if (id == (*args)->d->id)
00516          return; // Options already present.
00517 
00518       // Only check for afterId if it has been given non-empty, as the
00519       // unnamed option group should come after all named groups.
00520       if (!afterId.isEmpty() && afterId == (*args)->d->id)
00521          pos = i+1;
00522    }
00523 
00524    Q_ASSERT( s->parsed == false ); // You must add _ALL_ cmd line options
00525                                    // before accessing the arguments!
00526    s->argsList->insert(pos, new KCmdLineArgs(options, name, id.toUtf8()));
00527 }
00528 
00529 void
00530 KCmdLineArgs::saveAppArgs( QDataStream &ds)
00531 {
00532    if (!s->parsed)
00533       s->parseAllArgs();
00534 
00535    // Remove Qt and KDE options.
00536    s->removeArgs("qt");
00537    s->removeArgs("kde");
00538 
00539    QByteArray qCwd = QFile::encodeName(s->mCwd);
00540    ds << qCwd;
00541 
00542    uint count = s->argsList ? s->argsList->count() : 0;
00543    ds << count;
00544 
00545    if (!count) return;
00546 
00547    KCmdLineArgsList::Iterator args;
00548    for(args = s->argsList->begin(); args != s->argsList->end(); ++args)
00549    {
00550       ds << (*args)->d->id;
00551       (*args)->d->save(ds);
00552    }
00553 }
00554 
00555 void
00556 KCmdLineArgs::loadAppArgs( QDataStream &ds)
00557 {
00558    s->parsed = true; // don't reparse argc/argv!
00559 
00560    // Remove Qt and KDE options.
00561    s->removeArgs("qt");
00562    s->removeArgs("kde");
00563 
00564    KCmdLineArgsList::Iterator args;
00565    if ( s->argsList ) {
00566       for(args = s->argsList->begin(); args != s->argsList->end(); ++args)
00567       {
00568          (*args)->clear();
00569       }
00570    }
00571 
00572    if (ds.atEnd())
00573       return;
00574 
00575    QByteArray qCwd;
00576    ds >> qCwd;
00577 
00578    s->mCwd = QFile::decodeName(qCwd); //FIXME: Is this proper decoding?
00579 
00580    uint count;
00581    ds >> count;
00582 
00583    while(count--)
00584    {
00585      QByteArray idRaw;
00586      ds >> idRaw;
00587      QString id = idRaw;  //FIXME: What about decoding?
00588      Q_ASSERT( s->argsList );
00589      for(args = s->argsList->begin(); args != s->argsList->end(); ++args)
00590      {
00591        if ((*args)->d->id  == id)
00592        {
00593           (*args)->d->load(ds);
00594           break;
00595        }
00596      }
00597    }
00598    s->parsed = true;
00599 }
00600 
00601 KCmdLineArgs *KCmdLineArgs::parsedArgs(const QByteArray &_id)
00602 {
00603    QString id = QString::fromUtf8(_id);
00604    if (!s->argsList)
00605       return 0;
00606    KCmdLineArgsList::Iterator args = s->argsList->begin();
00607    while(args != s->argsList->end())
00608    {
00609       if ((*args)->d->id == id)
00610       {
00611           if (!s->parsed)
00612              s->parseAllArgs();
00613           return *args;
00614       }
00615       ++args;
00616    }
00617 
00618    return 0;
00619 }
00620 
00621 void KCmdLineArgsStatic::removeArgs(const QString &id)
00622 {
00623    if (!s->argsList)
00624       return;
00625    KCmdLineArgsList::Iterator args = s->argsList->begin();
00626    while(args != s->argsList->end())
00627    {
00628       if ((*args)->d->id == id)
00629       {
00630           if (!s->parsed)
00631              s->parseAllArgs();
00632           break;
00633       }
00634       ++args;
00635    }
00636 
00637    if (args != s->argsList->end()) {
00638       KCmdLineArgs *a = *args;
00639       s->argsList->erase(args);
00640       delete a;
00641    }
00642 }
00643 
00644 int
00645 KCmdLineArgsStatic::findOption(const KCmdLineOptions &options, QString &opt,
00646                                QString &opt_name, QString &def, bool &enabled)
00647 {
00648    int result;
00649    bool inverse;
00650 
00651    for (int i = 0; i < options.d->names.size(); i++)
00652    {
00653       result = 0;
00654       inverse = false;
00655       opt_name = options.d->names[i].toUtf8();
00656       if (opt_name.startsWith(':') || opt_name.isEmpty())
00657       {
00658          continue;
00659       }
00660       if (opt_name.startsWith('!'))
00661       {
00662          opt_name = opt_name.mid(1);
00663          result = 4;
00664       }
00665       if (opt_name.startsWith("no"))
00666       {
00667          opt_name = opt_name.mid(2);
00668          inverse = true;
00669       }
00670 
00671       int len = opt.length();
00672       if (opt == opt_name.left(len))
00673       {
00674          opt_name = opt_name.mid(len);
00675          if (opt_name.isEmpty())
00676          {
00677             if (inverse)
00678                return result+2;
00679 
00680             if (options.d->descriptions[i].isEmpty())
00681             {
00682                i++;
00683                if (i >= options.d->names.size())
00684                   return result+0;
00685                QString nextOption = options.d->names[i].toUtf8();
00686                int p = nextOption.indexOf(' ');
00687                if (p > 0)
00688                   nextOption = nextOption.left(p);
00689                if (nextOption.startsWith('!'))
00690                   nextOption = nextOption.mid(1);
00691                if (nextOption.startsWith("no"))
00692                {
00693                   nextOption = nextOption.mid(2);
00694                   enabled = !enabled;
00695                }
00696                result = findOption(options, nextOption, opt_name, def, enabled);
00697                Q_ASSERT(result);
00698                opt = nextOption;
00699                return result;
00700             }
00701 
00702             return 1;
00703          }
00704          if (opt_name.startsWith(' '))
00705          {
00706             opt_name = opt_name.mid(1);
00707             def = options.d->defaults[i].toUtf8();
00708             return result+3;
00709          }
00710       }
00711    }
00712    return 0;
00713 }
00714 
00715 void
00716 KCmdLineArgsStatic::findOption(const QString &optv, const QString &_opt,
00717                                int &i, bool _enabled, bool &moreOptions)
00718 {
00719    KCmdLineArgsList::Iterator args = s->argsList->begin();
00720    QString opt = _opt;
00721    QString opt_name;
00722    QString def;
00723    QString argument;
00724    int j = opt.indexOf('=');
00725    if (j != -1)
00726    {
00727       argument = opt.mid(j+1);
00728       opt = opt.left(j);
00729    }
00730 #ifdef Q_WS_MACX
00731    if(opt.startsWith("psn_"))
00732       opt = "psn";
00733 #endif
00734 
00735    bool enabled = true;
00736    int result = 0;
00737    while (args != s->argsList->end())
00738    {
00739       enabled = _enabled;
00740       result = findOption((*args)->d->options, opt, opt_name, def, enabled);
00741       if (result) break;
00742       ++args;
00743    }
00744    if ((args == s->argsList->end()) &&
00745        (optv.startsWith('-') && !optv.startsWith("--")))
00746    {
00747       // Option not found check if it is a valid option
00748       // in the style of -Pprinter1 or ps -aux
00749       int p = 1;
00750       while (true)
00751       {
00752          QString singleCharOption = " ";
00753          singleCharOption[0] = optv[p];
00754          args = s->argsList->begin();
00755          while (args != s->argsList->end())
00756          {
00757             enabled = _enabled;
00758             result = findOption((*args)->d->options, singleCharOption,
00759                       opt_name, def, enabled);
00760             if (result) break;
00761             ++args;
00762          }
00763          if (args == s->argsList->end())
00764             break; // Unknown argument
00765 
00766          p++;
00767          if (result == 1) // Single option
00768          {
00769             (*args)->d->setOption(singleCharOption, enabled);
00770             if (p < optv.length())
00771                continue; // Next option
00772             else
00773                return; // Finished
00774          }
00775          else if (result == 3) // This option takes an argument
00776          {
00777             if (argument.isEmpty())
00778             {
00779                argument = optv.mid(p);
00780             }
00781             (*args)->d->setOption(singleCharOption, argument);
00782             return;
00783          }
00784          break; // Unknown argument
00785       }
00786       args = s->argsList->end();
00787       result = 0;
00788    }
00789 
00790    if (args == s->argsList->end() || !result)
00791    {
00792       if (s->ignoreUnknown)
00793          return;
00794 #ifdef Q_WS_MACX
00795         if (_opt.startsWith("psn_", Qt::CaseInsensitive))
00796             return;
00797 #endif
00798       KCmdLineArgs::enable_i18n();
00799       KCmdLineArgs::usageError( i18n("Unknown option '%1'.", _opt));
00800    }
00801 
00802    if ((result & 4) != 0)
00803    {
00804       result &= ~4;
00805       moreOptions = false;
00806    }
00807 
00808    if (result == 3) // This option takes an argument
00809    {
00810       if (!enabled)
00811       {
00812          if (s->ignoreUnknown)
00813             return;
00814 #ifdef Q_WS_MACX
00815             if (_opt.startsWith("psn_", Qt::CaseInsensitive))
00816                 return;
00817 #endif
00818          KCmdLineArgs::enable_i18n();
00819          KCmdLineArgs::usageError( i18n("Unknown option '%1'.", _opt));
00820       }
00821       if (argument.isEmpty())
00822       {
00823          i++;
00824          if (i >= s->argc)
00825          {
00826             KCmdLineArgs::enable_i18n();
00827             KCmdLineArgs::usageError( i18nc("@info:shell %1 is cmdoption name","'%1' missing.",  opt_name));
00828          }
00829          argument = s->decodeInput(s->argv[i]);
00830       }
00831       (*args)->d->setOption(opt, argument);
00832    }
00833    else
00834    {
00835       (*args)->d->setOption(opt, enabled);
00836    }
00837 }
00838 
00839 void
00840 KCmdLineArgsStatic::parseAllArgs()
00841 {
00842    bool allowArgs = false;
00843    bool inOptions = true;
00844    bool everythingAfterArgIsArgs = false;
00845    KCmdLineArgs *appOptions = s->argsList->last();
00846    if (appOptions->d->id.isEmpty())
00847    {
00848      const KCmdLineOptions &option = appOptions->d->options;
00849      for (int i = 0; i < option.d->names.size(); i++)
00850      {
00851        if (option.d->names[i].startsWith('+'))
00852            allowArgs = true;
00853        if ( option.d->names[i].startsWith("!+") )
00854        {
00855            allowArgs = true;
00856            everythingAfterArgIsArgs = true;
00857        }
00858      }
00859    }
00860    for(int i = 1; i < s->argc; i++)
00861    {
00862       if (!s->argv[i])
00863          continue;
00864 
00865       if ((s->argv[i][0] == '-') && s->argv[i][1] && inOptions)
00866       {
00867          bool enabled = true;
00868          QString orig = decodeInput(s->argv[i]);
00869          QString option = orig.mid(1);
00870          if (option.startsWith('-'))
00871          {
00872             option = option.mid(1);
00873             s->argv[i]++;
00874             if (option.isEmpty())
00875             {
00876                inOptions = false;
00877                continue;
00878             }
00879          }
00880          if (option == "help")
00881          {
00882             KCmdLineArgs::usage();
00883          }
00884          else if (option.startsWith("help-"))
00885          {
00886             KCmdLineArgs::usage(option.mid(5).toUtf8());
00887          }
00888          else if ((option == "version") || (option == "v"))
00889          {
00890             s->printQ( QString("Qt: %1\n").arg(qVersion()));
00891             s->printQ( QString("KDE: %1\n").arg(KDE_VERSION_STRING));
00892             s->printQ( QString("%1: %2\n"). arg(s->about->programName()).arg(s->about->version()));
00893             exit(0);
00894          } else if (option == "license")
00895          {
00896             KCmdLineArgs::enable_i18n();
00897             s->printQ( s->about->license() );
00898             s->printQ( "\n" );
00899             exit(0);
00900          } else if (option == "author") {
00901              KCmdLineArgs::enable_i18n();
00902        if ( s->about ) {
00903          const QList<KAboutPerson> authors = s->about->authors();
00904          if ( !authors.isEmpty() ) {
00905            QString authorlist;
00906            for (QList<KAboutPerson>::ConstIterator it = authors.begin(); it != authors.end(); ++it ) {
00907              QString email;
00908              if ( !(*it).emailAddress().isEmpty() )
00909                email = " &lt;" + (*it).emailAddress() + "&gt;";
00910              authorlist += QString("    ") + (*it).name() + email + '\n';
00911            }
00912            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 ) );
00913          }
00914        } else {
00915          s->printQ( i18n("This application was written by somebody who wants to remain anonymous.") );
00916        }
00917        if (s->about)
00918        {
00919          if (!s->about->customAuthorTextEnabled ())
00920          {
00921            if (s->about->bugAddress().isEmpty() || s->about->bugAddress() == "submit@bugs.kde.org" )
00922              s->printQ( i18n( "Please use http://bugs.kde.org to report bugs.\n" ) );
00923            else {
00924              s->printQ( i18n( "Please report bugs to %1.\n" , s->about->bugAddress()) );
00925            }
00926          }
00927          else
00928          {
00929            s->printQ(s->about->customAuthorPlainText());
00930          }
00931        }
00932        exit(0);
00933          } else {
00934            if (option.startsWith("no"))
00935            {
00936               option = option.mid(2);
00937               enabled = false;
00938            }
00939            s->findOption(orig, option, i, enabled, inOptions);
00940          }
00941       }
00942       else
00943       {
00944          // Check whether appOptions allows these arguments
00945          if (!allowArgs)
00946          {
00947             if (s->ignoreUnknown)
00948                continue;
00949             KCmdLineArgs::enable_i18n();
00950             KCmdLineArgs::usageError(i18n("Unexpected argument '%1'.", KuitSemantics::escape(s->decodeInput(s->argv[i]))));
00951          }
00952          else
00953          {
00954             appOptions->d->addArgument(s->decodeInput(s->argv[i]));
00955             if (everythingAfterArgIsArgs)
00956                 inOptions = false;
00957          }
00958       }
00959    }
00960    s->parsed = true;
00961 }
00962 
00963 int & KCmdLineArgs::qtArgc()
00964 {
00965    if (!s->argsList)
00966       addStdCmdLineOptions(CmdLineArgKDE|CmdLineArgQt); // Lazy bastards!
00967 
00968    static int qt_argc = -1;
00969    if( qt_argc != -1 )
00970       return qt_argc;
00971 
00972    if (!(s->mStdargs & KCmdLineArgs::CmdLineArgQt))
00973    {
00974      qt_argc = 2;
00975      return qt_argc;
00976    }
00977 
00978    KCmdLineArgs *args = parsedArgs("qt");
00979    Q_ASSERT(args); // No qt options have been added!
00980    if (!s->argv)
00981    {
00982       fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
00983       fprintf(stderr, "Application has not called KCmdLineArgs::init(...).\n\n");
00984 
00985       assert( 0 );
00986       exit(255);
00987    }
00988 
00989    Q_ASSERT(s->argc >= (args->count()+1));
00990    qt_argc = args->count() +1;
00991    return qt_argc;
00992 }
00993 
00994 static char** s_qt_argv;
00995 
00996 char **
00997 KCmdLineArgs::qtArgv()
00998 {
00999    if (!s->argsList)
01000       addStdCmdLineOptions(CmdLineArgKDE|CmdLineArgQt); // Lazy bastards!
01001 
01002    if( s_qt_argv != NULL )
01003       return s_qt_argv;
01004 
01005    if (!(s->mStdargs & KCmdLineArgs::CmdLineArgQt))
01006    {
01007      s_qt_argv = new char*[2];
01008      s_qt_argv[0] = qstrdup(s->encodeOutput(appName()));
01009      s_qt_argv[1] = 0;
01010 
01011      return s_qt_argv;
01012    }
01013 
01014    KCmdLineArgs *args = parsedArgs("qt");
01015    Q_ASSERT(args); // No qt options have been added!
01016    if (!s->argv)
01017    {
01018       fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
01019       fprintf(stderr, "Application has not called KCmdLineArgs::init(...).\n\n");
01020 
01021       assert( 0 );
01022       exit(255);
01023    }
01024 
01025    s_qt_argv = new char*[ args->count() + 2 ];
01026    s_qt_argv[0] = qstrdup(s->encodeOutput(appName()));
01027    int i = 0;
01028    for(; i < args->count(); i++)
01029    {
01030       s_qt_argv[i+1] = qstrdup(s->encodeOutput(args->arg(i)));
01031    }
01032    s_qt_argv[i+1] = 0;
01033 
01034    return s_qt_argv;
01035 }
01036 
01037 const KAboutData *
01038 KCmdLineArgs::aboutData()
01039 {
01040     return s->about;
01041 }
01042 
01043 void
01044 KCmdLineArgs::enable_i18n()
01045 {
01046     // called twice or too late
01047     if (KGlobal::hasLocale())
01048       return;
01049 
01050     if (!KGlobal::hasMainComponent()) {
01051         KComponentData mainComponentData(s->about);
01052         mainComponentData.config();
01053         // mainComponentData is now the main component and won't disappear until KGlobal deletes it
01054     }
01055 }
01056 
01057 void
01058 KCmdLineArgs::usageError(const QString &error)
01059 {
01060     Q_ASSERT(KGlobal::hasLocale());
01061     QByteArray localError = s->encodeOutput(error);
01062     if (localError.endsWith('\n'))
01063         localError.chop(1);
01064     fprintf(stderr, "%s: %s\n", s->argv[0], localError.data());
01065 
01066     QString tmp = i18n("Use --help to get a list of available command line options.");
01067     localError = s->encodeOutput(tmp);
01068     fprintf(stderr, "%s: %s\n", s->argv[0], localError.data());
01069     exit(254);
01070 }
01071 
01072 void
01073 KCmdLineArgs::usage(const QByteArray &id)
01074 {
01075    enable_i18n();
01076    Q_ASSERT(s->argsList != 0); // It's an error to call usage(...) without
01077                                // having done addCmdLineOptions first!
01078 
01079    QString optionFormatString   = "  %1 %2\n";
01080    QString optionFormatStringDef  = "  %1 %2 [%3]\n";
01081    QString tmp;
01082    QString usage;
01083 
01084    KCmdLineArgsList::Iterator args = --(s->argsList->end());
01085 
01086    if ((*args)->d->id.isEmpty() && ((*args)->d->options.d->names.size() > 0) &&
01087        !(*args)->d->options.d->names[0].startsWith('+'))
01088    {
01089       usage = i18n("[options] ")+usage;
01090    }
01091 
01092    while(true)
01093    {
01094       if (!(*args)->d->name.isEmpty())
01095       {
01096          usage = i18n("[%1-options]", (*args)->d->name.toString())+' '+usage;
01097       }
01098       if (args == s->argsList->begin())
01099          break;
01100       --args;
01101    }
01102 
01103    KCmdLineArgs *appOptions = s->argsList->last();
01104    if (appOptions->d->id.isEmpty())
01105    {
01106      const KCmdLineOptions &option = appOptions->d->options;
01107      for (int i = 0; i < option.d->names.size(); i++)
01108      {
01109        QString opt_name = option.d->names[i];
01110        if (opt_name.startsWith('+'))
01111           usage = usage + (opt_name.mid(1)) + ' ';
01112        else if ( opt_name.startsWith("!+") )
01113           usage = usage + (opt_name.mid(2)) + ' ';
01114      }
01115    }
01116 
01117    s->printQ(i18n("Usage: %1 %2\n", s->argv[0], KuitSemantics::escape(usage)));
01118    s->printQ('\n'+s->about->shortDescription()+'\n');
01119 
01120    s->printQ(i18n("\nGeneric options:\n"));
01121    s->printQ(optionFormatString.arg("--help", -25).arg(i18n("Show help about options")));
01122 
01123    args = s->argsList->begin();
01124    while(args != s->argsList->end())
01125    {
01126       if (!(*args)->d->name.isEmpty() && !(*args)->d->id.isEmpty())
01127       {
01128          QString option = QString("--help-%1").arg((*args)->d->id);
01129          QString desc = i18n("Show %1 specific options", (*args)->d->name.toString());
01130 
01131          s->printQ(optionFormatString.arg(option, -25).arg(desc));
01132       }
01133       ++args;
01134    }
01135 
01136    s->printQ(optionFormatString.arg("--help-all",-25).arg(i18n("Show all options")));
01137    s->printQ(optionFormatString.arg("--author",-25).arg(i18n("Show author information")));
01138    s->printQ(optionFormatString.arg("-v, --version",-25).arg(i18n("Show version information")));
01139    s->printQ(optionFormatString.arg("--license",-25).arg(i18n("Show license information")));
01140    s->printQ(optionFormatString.arg("--", -25).arg(i18n("End of options")));
01141 
01142    args = s->argsList->begin(); // Sets current to 1st.
01143 
01144    bool showAll = (id == "all");
01145 
01146    if (!showAll)
01147    {
01148      while(args != s->argsList->end())
01149      {
01150        if (id == (*args)->d->id) break;
01151        ++args;
01152      }
01153    }
01154 
01155    while(args != s->argsList->end())
01156    {
01157      bool hasArgs = false;
01158      bool hasOptions = false;
01159      QString optionsHeader;
01160      if (!(*args)->d->name.isEmpty())
01161         optionsHeader = i18n("\n%1 options:\n", (*args)->d->name.toString());
01162      else
01163         optionsHeader = i18n("\nOptions:\n");
01164 
01165      while (args != s->argsList->end())
01166      {
01167        const KCmdLineOptions &option = (*args)->d->options;
01168        QString opt;
01169 
01170        for (int i = 0; i < option.d->names.size(); i++)
01171        {
01172          QString description;
01173          QStringList dl;
01174 
01175          QString descriptionFull;
01176          if (!option.d->descriptions[i].isEmpty()) {
01177             descriptionFull = option.d->descriptions[i].toString();
01178          }
01179 
01180          // Option header
01181          if (option.d->names[i].startsWith(':'))
01182          {
01183             if (!descriptionFull.isEmpty())
01184             {
01185                optionsHeader = '\n'+descriptionFull;
01186                if (!optionsHeader.endsWith('\n'))
01187                   optionsHeader.append('\n');
01188                hasOptions = false;
01189             }
01190             continue;
01191          }
01192 
01193          // Free-form comment
01194          if (option.d->names[i].isEmpty())
01195          {
01196             if (!descriptionFull.isEmpty())
01197             {
01198                tmp = '\n'+descriptionFull;
01199                if (!tmp.endsWith('\n'))
01200                   tmp.append('\n');
01201                s->printQ(tmp);
01202             }
01203             continue;
01204          }
01205 
01206          // Options
01207          if (!descriptionFull.isEmpty())
01208          {
01209             dl = descriptionFull.split( "\n", QString::KeepEmptyParts);
01210             description = dl.first();
01211             dl.erase( dl.begin() );
01212          }
01213          QString name = option.d->names[i];
01214          if (name.startsWith('!'))
01215              name = name.mid(1);
01216 
01217          if (name.startsWith('+'))
01218          {
01219             if (!hasArgs)
01220             {
01221                s->printQ(i18n("\nArguments:\n"));
01222                hasArgs = true;
01223             }
01224 
01225             name = name.mid(1);
01226             if (name.startsWith('[') && name.endsWith(']'))
01227                 name = name.mid(1, name.length()-2);
01228             s->printQ(optionFormatString.arg(name, -25).arg(description));
01229          }
01230          else
01231          {
01232             if (!hasOptions)
01233             {
01234                s->printQ(optionsHeader);
01235                hasOptions = true;
01236             }
01237 
01238             if ((name.length() == 1) || (name[1] == ' '))
01239                name = '-'+name;
01240             else
01241                name = "--"+name;
01242             if (descriptionFull.isEmpty())
01243             {
01244                opt = name + ", ";
01245             }
01246             else
01247             {
01248                opt = opt + name;
01249                if (option.d->defaults[i].isEmpty())
01250                {
01251                   s->printQ(optionFormatString.arg(QString( opt ), -25).arg(description));
01252                }
01253                else
01254                {
01255                   s->printQ(optionFormatStringDef.arg(QString( opt ), -25)
01256                             .arg(description, option.d->defaults[i]));
01257                }
01258                opt = "";
01259             }
01260          }
01261          for(QStringList::Iterator it = dl.begin();
01262              it != dl.end();
01263              ++it)
01264          {
01265             s->printQ(optionFormatString.arg("", -25).arg(*it));
01266          }
01267        }
01268 
01269        ++args;
01270        if (args == s->argsList->end() || !(*args)->d->name.isEmpty() || (*args)->d->id.isEmpty())
01271         break;
01272      }
01273      if (!showAll) break;
01274    }
01275 
01276    exit(0);
01277 }
01278 
01279 //
01280 // Member functions
01281 //
01282 
01288 KCmdLineArgs::KCmdLineArgs( const KCmdLineOptions &_options,
01289                             const KLocalizedString &_name,
01290                             const QByteArray &_id)
01291   : d(new KCmdLineArgsPrivate(_options, _name, _id))
01292 {
01293 }
01294 
01298 KCmdLineArgs::~KCmdLineArgs()
01299 {
01300   if (!s.isDestroyed() && s->argsList)
01301      s->argsList->removeAll(this);
01302   delete d;
01303 }
01304 
01305 void
01306 KCmdLineArgs::setCwd( const QByteArray &cwd )
01307 {
01308     s->mCwd = QString::fromUtf8(cwd);
01309 }
01310 
01311 void
01312 KCmdLineArgs::clear()
01313 {
01314    delete d->parsedArgList;
01315    d->parsedArgList = 0;
01316    delete d->parsedOptionList;
01317    d->parsedOptionList = 0;
01318 }
01319 
01320 void
01321 KCmdLineArgs::reset()
01322 {
01323    if ( s->argsList ) {
01324       delete s->argsList;
01325       s->argsList = 0;
01326    }
01327    s->parsed = false;
01328 }
01329 
01330 void
01331 KCmdLineArgsPrivate::save( QDataStream &ds) const
01332 {
01333    if (parsedOptionList)
01334       ds << (*(parsedOptionList));
01335    else
01336       ds << quint32(0);
01337 
01338    if (parsedArgList)
01339       ds << (*(parsedArgList));
01340    else
01341       ds << quint32(0);
01342 }
01343 
01344 void
01345 KCmdLineArgsPrivate::load( QDataStream &ds)
01346 {
01347    if (!parsedOptionList) parsedOptionList = new KCmdLineParsedOptions;
01348    if (!parsedArgList) parsedArgList = new KCmdLineParsedArgs;
01349 
01350    ds >> (*(parsedOptionList));
01351    ds >> (*(parsedArgList));
01352 
01353    if (parsedOptionList->count() == 0)
01354    {
01355       delete parsedOptionList;
01356       parsedOptionList = 0;
01357    }
01358    if (parsedArgList->count() == 0)
01359    {
01360       delete parsedArgList;
01361       parsedArgList = 0;
01362    }
01363 }
01364 
01365 void
01366 KCmdLineArgsPrivate::setOption(const QString &opt, bool enabled)
01367 {
01368    if (isQt)
01369    {
01370       // Qt does it own parsing.
01371       QString argString = "-";
01372       if( !enabled )
01373           argString += "no";
01374       argString += opt;
01375       addArgument(argString);
01376    }
01377    if (!parsedOptionList) {
01378       parsedOptionList = new KCmdLineParsedOptions;
01379    }
01380 
01381    if (enabled)
01382       parsedOptionList->insert( opt, QString::fromUtf8("t") );
01383    else
01384       parsedOptionList->insert( opt, QString::fromUtf8("f") );
01385 }
01386 
01387 void
01388 KCmdLineArgsPrivate::setOption(const QString &opt, const QString &value)
01389 {
01390    if (isQt)
01391    {
01392       // Qt does it's own parsing.
01393       QString argString = "-";
01394       argString += opt;
01395       addArgument(argString);
01396       addArgument(value);
01397 
01398 #if defined(Q_WS_X11) || defined(Q_WS_QWS)
01399       // Hack coming up!
01400       if (argString == "-display")
01401       {
01402          setenv(DISPLAY, s->encodeOutput(value).data(), true);
01403       }
01404 #endif
01405    }
01406    if (!parsedOptionList) {
01407       parsedOptionList = new KCmdLineParsedOptions;
01408    }
01409 
01410    parsedOptionList->insertMulti( opt, value );
01411 }
01412 
01413 QString
01414 KCmdLineArgs::getOption(const QByteArray &_opt) const
01415 {
01416    QString opt = QString::fromUtf8(_opt);
01417    QString value;
01418    if (d->parsedOptionList)
01419    {
01420       value = d->parsedOptionList->value(opt);
01421    }
01422    if (!value.isEmpty())
01423       return value;
01424 
01425    // Look up the default.
01426    QString opt_name;
01427    QString def;
01428    bool dummy = true;
01429    int result = s->findOption( d->options, opt, opt_name, def, dummy) & ~4;
01430 
01431    if (result != 3)
01432    {
01433       fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
01434       fprintf(stderr, "Application requests for getOption(\"%s\") but the \"%s\" option\n",
01435                       s->encodeOutput(opt).data(), s->encodeOutput(opt).data());
01436       fprintf(stderr, "has never been specified via addCmdLineOptions( ... )\n\n");
01437 
01438       Q_ASSERT( 0 );
01439       exit(255);
01440    }
01441    return def;
01442 }
01443 
01444 QStringList
01445 KCmdLineArgs::getOptionList(const QByteArray &_opt) const
01446 {
01447    QString opt = QString::fromUtf8(_opt);
01448 
01449    QStringList result;
01450    if (!d->parsedOptionList)
01451       return result;
01452 
01453    while(true)
01454    {
01455       QString value = d->parsedOptionList->take(opt);
01456       if (value.isEmpty())
01457          break;
01458       result.prepend(value);
01459    }
01460 
01461    // Reinsert items in dictionary
01462    // WABA: This is rather silly, but I don't want to add restrictions
01463    // to the API like "you can only call this function once".
01464    // I can't access all items without taking them out of the list.
01465    // So taking them out and then putting them back is the only way.
01466    for(QStringList::ConstIterator it=result.begin();
01467        it != result.end();
01468        ++it)
01469    {
01470       d->parsedOptionList->insertMulti(opt, *it);
01471    }
01472    return result;
01473 }
01474 
01475 bool
01476 KCmdLineArgs::isSet(const QByteArray &_opt) const
01477 {
01478    // Look up the default.
01479    QString opt = QString::fromUtf8(_opt);
01480    QString opt_name;
01481    QString def;
01482    int result = 0;
01483    KCmdLineArgsList::Iterator args = s->argsList->begin();
01484    while (args != s->argsList->end())
01485    {
01486       bool dummy = true;
01487       result = s->findOption((*args)->d->options, opt, opt_name, def, dummy) & ~4;
01488       if (result) break;
01489       ++args;
01490    }
01491 
01492    if (result == 0)
01493    {
01494       fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
01495       fprintf(stderr, "Application requests for isSet(\"%s\") but the \"%s\" option\n",
01496                       s->encodeOutput(opt).data(), s->encodeOutput(opt).data());
01497       fprintf(stderr, "has never been specified via addCmdLineOptions( ... )\n\n");
01498 
01499       Q_ASSERT( 0 );
01500       exit(255);
01501    }
01502 
01503    QString value;
01504    if (d->parsedOptionList)
01505    {
01506       value = d->parsedOptionList->value(opt);
01507    }
01508 
01509    if (!value.isEmpty())
01510    {
01511       if (result == 3)
01512          return true;
01513       else
01514          return (value[0] == 't');
01515    }
01516 
01517    if (result == 3)
01518       return false; // String option has 'false' as default.
01519 
01520    // We return 'true' as default if the option was listed as '-nofork'
01521    // We return 'false' as default if the option was listed as '-fork'
01522    return (result == 2);
01523 }
01524 
01525 int
01526 KCmdLineArgs::count() const
01527 {
01528    if (!d->parsedArgList)
01529       return 0;
01530    return d->parsedArgList->count();
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 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(urlArg);
01562         return result; // Absolute path.
01563     }
01564 
01565     if ( KUrl::isRelativeUrl(urlArg) || fileInfo.exists() ) {
01566         KUrl result;
01567         result.setPath( cwd()+'/'+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 QString &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     if ( args )
01596         return args->isSet( "tempfile" );
01597     return false;
01598 }

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
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
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