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

KDECore

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

KDECore

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.5
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