• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdecore
 

tdecore

tdecmdlineargs.cpp

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 <config.h>
00020 
00021 #include <sys/param.h>
00022 
00023 #include <assert.h>
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <string.h>
00027 #include <unistd.h>
00028 
00029 #ifdef HAVE_LIMITS_H
00030 #include <limits.h>
00031 #endif
00032 
00033 #include <tqdir.h>
00034 #include <tqfile.h>
00035 #include <tqasciidict.h>
00036 #include <tqstrlist.h>
00037 
00038 #include "tdecmdlineargs.h"
00039 #include <tdeaboutdata.h>
00040 #include <tdelocale.h>
00041 #include <tdeapplication.h>
00042 #include <tdeglobal.h>
00043 #include <kstringhandler.h>
00044 #include <kstaticdeleter.h>
00045 
00046 #ifdef Q_WS_X11
00047 #define DISPLAY "DISPLAY"
00048 #elif defined(Q_WS_QWS)
00049 #define DISPLAY "QWS_DISPLAY"
00050 #endif
00051 
00052 #ifdef Q_WS_WIN
00053 #include <win32_utils.h>
00054 #endif
00055 
00056 template class TQAsciiDict<TQCString>;
00057 template class TQPtrList<TDECmdLineArgs>;
00058 
00059 class TDECmdLineParsedOptions : public TQAsciiDict<TQCString>
00060 {
00061 public:
00062    TDECmdLineParsedOptions()
00063      : TQAsciiDict<TQCString>( 7 ) { }
00064 
00065    // WABA: Huh?
00066    // The compiler doesn't find TDECmdLineParsedOptions::write(s) by itself ???
00067    // WABA: No, because there is another write function that hides the
00068    // write function in the base class even though this function has a
00069    // different signature. (obscure C++ feature)
00070    TQDataStream& save( TQDataStream &s) const
00071    { return TQGDict::write(s); }
00072 
00073    TQDataStream& load( TQDataStream &s)
00074    { return TQGDict::read(s); }
00075 
00076 protected:
00077    virtual TQDataStream& write( TQDataStream &s, TQPtrCollection::Item data) const
00078    {
00079       TQCString *str = (TQCString *) data;
00080       s << (*str);
00081       return s;
00082    }
00083 
00084    virtual TQDataStream& read( TQDataStream &s, TQPtrCollection::Item &item)
00085    {
00086       TQCString *str = new TQCString;
00087       s >> (*str);
00088       item = (void *)str;
00089       return s;
00090    }
00091 
00092 };
00093 
00094 class TDECmdLineParsedArgs : public TQStrList
00095 {
00096 public:
00097    TDECmdLineParsedArgs()
00098      : TQStrList( true ) { }
00099    TQDataStream& save( TQDataStream &s) const
00100    { return TQGList::write(s); }
00101 
00102    TQDataStream& load( TQDataStream &s)
00103    { return TQGList::read(s); }
00104 };
00105 
00106 
00107 class TDECmdLineArgsList: public TQPtrList<TDECmdLineArgs>
00108 {
00109 public:
00110    TDECmdLineArgsList() { }
00111 };
00112 
00113 TDECmdLineArgsList *TDECmdLineArgs::argsList = 0;
00114 int TDECmdLineArgs::argc = 0;
00115 char **TDECmdLineArgs::argv = 0;
00116 char *TDECmdLineArgs::mCwd = 0;
00117 static KStaticDeleter <char> mCwdd;
00118 const TDEAboutData *TDECmdLineArgs::about = 0;
00119 bool TDECmdLineArgs::parsed = false;
00120 bool TDECmdLineArgs::ignoreUnknown = false;
00121 
00122 //
00123 // Static functions
00124 //
00125 
00126 void
00127 TDECmdLineArgs::init(int _argc, char **_argv, const char *_appname, const char* programName,
00128                    const char *_description, const char *_version, bool noKApp)
00129 {
00130    init(_argc, _argv,
00131         new TDEAboutData(_appname, programName, _version, _description),
00132         noKApp);
00133 }
00134 
00135 void
00136 TDECmdLineArgs::init(int _argc, char **_argv, const char *_appname,
00137                    const char *_description, const char *_version, bool noKApp)
00138 {
00139    init(_argc, _argv,
00140         new TDEAboutData(_appname, _appname, _version, _description),
00141         noKApp);
00142 }
00143 
00144 void
00145 TDECmdLineArgs::initIgnore(int _argc, char **_argv, const char *_appname )
00146 {
00147    init(_argc, _argv,
00148         new TDEAboutData(_appname, _appname, "unknown", "TDE Application", false));
00149    ignoreUnknown = true;
00150 }
00151 
00152 void
00153 TDECmdLineArgs::init(const TDEAboutData* ab)
00154 {
00155    char **_argv = (char **) malloc(sizeof(char *));
00156    _argv[0] = (char *) ab->appName();
00157    init(1,_argv,ab, true);
00158 }
00159 
00160 
00161 void
00162 TDECmdLineArgs::init(int _argc, char **_argv, const TDEAboutData *_about, bool noKApp)
00163 {
00164    argc = _argc;
00165    argv = _argv;
00166 
00167    if (!argv)
00168    {
00169       fprintf(stderr, "\n\nFAILURE (TDECmdLineArgs):\n");
00170       fprintf(stderr, "Passing null-pointer to 'argv' is not allowed.\n\n");
00171 
00172       assert( 0 );
00173       exit(255);
00174    }
00175 
00176    // Strip path from argv[0]
00177    if (argc) {
00178      char *p = strrchr( argv[0], '/');
00179      if (p)
00180        argv[0] = p+1;
00181    }
00182 
00183    about = _about;
00184    parsed = false;
00185    mCwd = mCwdd.setObject(mCwd, new char [PATH_MAX+1], true);
00186    (void) getcwd(mCwd, PATH_MAX);
00187 #ifdef Q_WS_WIN
00188    win32_slashify(mCwd, PATH_MAX);
00189 #endif
00190    if (!noKApp)
00191       TDEApplication::addCmdLineOptions();
00192 }
00193 
00194 TQString TDECmdLineArgs::cwd()
00195 {
00196    return TQFile::decodeName(TQCString(mCwd));
00197 }
00198 
00199 const char * TDECmdLineArgs::appName()
00200 {
00201    if (!argc) return 0;
00202    return argv[0];
00203 }
00204 
00205 void
00206 TDECmdLineArgs::addCmdLineOptions( const TDECmdLineOptions *options, const char *name,
00207          const char *id, const char *afterId)
00208 {
00209    if (!argsList)
00210       argsList = new TDECmdLineArgsList();
00211 
00212    int pos = argsList->count();
00213 
00214    if (pos && id && argsList->last() && !argsList->last()->name)
00215       pos--;
00216 
00217    TDECmdLineArgs *args;
00218    int i = 0;
00219    for(args = argsList->first(); args; args = argsList->next(), i++)
00220    {
00221       if (!id && !args->id)
00222          return; // Options already present.
00223 
00224       if (id && args->id && (::qstrcmp(id, args->id) == 0))
00225    return; // Options already present.
00226 
00227       if (afterId && args->id && (::qstrcmp(afterId, args->id) == 0))
00228          pos = i+1;
00229    }
00230 
00231    assert( parsed == false ); // You must add _ALL_ cmd line options
00232                               // before accessing the arguments!
00233    args = new TDECmdLineArgs(options, name, id);
00234    argsList->insert(pos, args);
00235 }
00236 
00237 void
00238 TDECmdLineArgs::saveAppArgs( TQDataStream &ds)
00239 {
00240    if (!parsed)
00241       parseAllArgs();
00242 
00243    // Remove Qt and TDE options.
00244    removeArgs("qt");
00245    removeArgs("tde");
00246 
00247    TQCString qCwd = mCwd;
00248    ds << qCwd;
00249 
00250    uint count = argsList ? argsList->count() : 0;
00251    ds << count;
00252 
00253    if (!count) return;
00254 
00255    TDECmdLineArgs *args;
00256    for(args = argsList->first(); args; args = argsList->next())
00257    {
00258       ds << TQCString(args->id);
00259       args->save(ds);
00260    }
00261 }
00262 
00263 void
00264 TDECmdLineArgs::loadAppArgs( TQDataStream &ds)
00265 {
00266    parsed = true; // don't reparse argc/argv!
00267 
00268    // Remove Qt and TDE options.
00269    removeArgs("qt");
00270    removeArgs("tde");
00271 
00272    TDECmdLineArgs *args;
00273    if ( argsList ) {
00274       for(args = argsList->first(); args; args = argsList->next())
00275       {
00276          args->clear();
00277       }
00278    }
00279 
00280    if (ds.atEnd())
00281       return;
00282 
00283    TQCString qCwd;
00284    ds >> qCwd;
00285    delete [] mCwd;
00286 
00287    mCwd = mCwdd.setObject(mCwd, new char[qCwd.length()+1], true);
00288    strncpy(mCwd, qCwd.data(), qCwd.length()+1);
00289 
00290    uint count;
00291    ds >> count;
00292 
00293    while(count--)
00294    {
00295      TQCString id;
00296      ds >> id;
00297      assert( argsList );
00298      for(args = argsList->first(); args; args = argsList->next())
00299      {
00300        if (args->id  == id)
00301        {
00302           args->load(ds);
00303           break;
00304        }
00305      }
00306    }
00307    parsed = true;
00308 }
00309 
00310 TDECmdLineArgs *TDECmdLineArgs::parsedArgs(const char *id)
00311 {
00312    TDECmdLineArgs *args = argsList ? argsList->first() : 0;
00313    while(args)
00314    {
00315       if ((id && ::qstrcmp(args->id, id) == 0) || (!id && !args->id))
00316       {
00317           if (!parsed)
00318              parseAllArgs();
00319           return args;
00320       }
00321       args = argsList->next();
00322    }
00323 
00324    return args;
00325 }
00326 
00327 void TDECmdLineArgs::removeArgs(const char *id)
00328 {
00329    TDECmdLineArgs *args = argsList ? argsList->first() : 0;
00330    while(args)
00331    {
00332       if (args->id && id && ::qstrcmp(args->id, id) == 0)
00333       {
00334           if (!parsed)
00335              parseAllArgs();
00336           break;
00337       }
00338       args = argsList->next();
00339    }
00340 
00341    if (args)
00342       delete args;
00343 }
00344 
00345 /*
00346  * @return:
00347  *  0 - option not found.
00348  *  1 - option found      // -fork
00349  *  2 - inverse option found ('no') // -nofork
00350  *  3 - option + arg found    // -fork now
00351  *
00352  *  +4 - no more options follow         // !fork
00353  */
00354 static int
00355 findOption(const TDECmdLineOptions *options, TQCString &opt,
00356            const char *&opt_name, const char *&def, bool &enabled)
00357 {
00358    int result;
00359    bool inverse;
00360    int len = opt.length();
00361    while(options && options->name)
00362    {
00363       result = 0;
00364       inverse = false;
00365       opt_name = options->name;
00366       if ((opt_name[0] == ':') || (opt_name[0] == 0))
00367       {
00368          options++;
00369          continue;
00370       }
00371 
00372       if (opt_name[0] == '!')
00373       {
00374          opt_name++;
00375          result = 4;
00376       }
00377       if ((opt_name[0] == 'n') && (opt_name[1] == 'o'))
00378       {
00379          opt_name += 2;
00380          inverse = true;
00381       }
00382       if (strncmp(opt.data(), opt_name, len) == 0)
00383       {
00384          opt_name += len;
00385          if (!opt_name[0])
00386          {
00387             if (inverse)
00388                return result+2;
00389 
00390             if (!options->description)
00391             {
00392                options++;
00393                if (!options->name)
00394                   return result+0;
00395                TQCString nextOption = options->name;
00396                int p = nextOption.find(' ');
00397                if (p > 0)
00398                   nextOption = nextOption.left(p);
00399                if (nextOption[0] == '!')
00400                   nextOption = nextOption.mid(1);
00401                if (strncmp(nextOption.data(), "no", 2) == 0)
00402                {
00403                   nextOption = nextOption.mid(2);
00404                   enabled = !enabled;
00405                }
00406                result = findOption(options, nextOption, opt_name, def, enabled);
00407                assert(result);
00408                opt = nextOption;
00409                return result;
00410             }
00411 
00412             return 1;
00413          }
00414          if (opt_name[0] == ' ')
00415          {
00416             opt_name++;
00417             def = options->def;
00418             return result+3;
00419          }
00420       }
00421 
00422       options++;
00423    }
00424    return 0;
00425 }
00426 
00427 
00428 void
00429 TDECmdLineArgs::findOption(const char *_opt, TQCString opt, int &i, bool _enabled, bool &moreOptions)
00430 {
00431    TDECmdLineArgs *args = argsList->first();
00432    const char *opt_name;
00433    const char *def;
00434    TQCString argument;
00435    int j = opt.find('=');
00436    if (j != -1)
00437    {
00438       argument = opt.mid(j+1);
00439       opt = opt.left(j);
00440    }
00441 
00442    bool enabled = true;
00443    int result = 0;
00444    while (args)
00445    {
00446       enabled = _enabled;
00447       result = ::findOption(args->options, opt, opt_name, def, enabled);
00448       if (result) break;
00449       args = argsList->next();
00450    }
00451    if (!args && (_opt[0] == '-') && _opt[1] && (_opt[1] != '-'))
00452    {
00453       // Option not found check if it is a valid option
00454       // in the style of -Pprinter1 or ps -aux
00455       int p = 1;
00456       while (true)
00457       {
00458          TQCString singleCharOption = " ";
00459          singleCharOption[0] = _opt[p];
00460          args = argsList->first();
00461          while (args)
00462          {
00463             enabled = _enabled;
00464             result = ::findOption(args->options, singleCharOption, opt_name, def, enabled);
00465             if (result) break;
00466             args = argsList->next();
00467          }
00468          if (!args)
00469             break; // Unknown argument
00470 
00471          p++;
00472          if (result == 1) // Single option
00473          {
00474             args->setOption(singleCharOption, enabled);
00475             if (_opt[p])
00476                continue; // Next option
00477             else
00478                return; // Finished
00479          }
00480          else if (result == 3) // This option takes an argument
00481          {
00482             if (argument.isEmpty())
00483             {
00484                argument = _opt+p;
00485             }
00486             args->setOption(singleCharOption, (const char*)argument);
00487             return;
00488          }
00489          break; // Unknown argument
00490       }
00491       args = 0;
00492       result = 0;
00493    }
00494 
00495    if (!args || !result)
00496    {
00497       if (ignoreUnknown)
00498          return;
00499       enable_i18n();
00500       usage( i18n("Unknown option '%1'.").arg(TQString::fromLocal8Bit(_opt)));
00501    }
00502 
00503    if ((result & 4) != 0)
00504    {
00505       result &= ~4;
00506       moreOptions = false;
00507    }
00508 
00509    if (result == 3) // This option takes an argument
00510    {
00511       if (!enabled)
00512       {
00513          if (ignoreUnknown)
00514             return;
00515          enable_i18n();
00516          usage( i18n("Unknown option '%1'.").arg(TQString::fromLocal8Bit(_opt)));
00517       }
00518       if (argument.isEmpty())
00519       {
00520          i++;
00521          if (i >= argc)
00522          {
00523             enable_i18n();
00524             usage( i18n("'%1' missing.").arg( opt_name));
00525          }
00526          argument = argv[i];
00527       }
00528       args->setOption(opt, (const char*)argument);
00529    }
00530    else
00531    {
00532       args->setOption(opt, enabled);
00533    }
00534 }
00535 
00536 void
00537 TDECmdLineArgs::printQ(const TQString &msg)
00538 {
00539    TQCString localMsg = msg.local8Bit();
00540    fprintf(stdout, "%s", localMsg.data());
00541 }
00542 
00543 void
00544 TDECmdLineArgs::parseAllArgs()
00545 {
00546    bool allowArgs = false;
00547    bool inOptions = true;
00548    bool everythingAfterArgIsArgs = false;
00549    TDECmdLineArgs *appOptions = argsList->last();
00550    if (!appOptions->id)
00551    {
00552      const TDECmdLineOptions *option = appOptions->options;
00553      while(option && option->name)
00554      {
00555        if (option->name[0] == '+')
00556            allowArgs = true;
00557        if ( option->name[0] == '!' && option->name[1] == '+' )
00558        {
00559            allowArgs = true;
00560            everythingAfterArgIsArgs = true;
00561        }
00562        option++;
00563      }
00564    }
00565    for(int i = 1; i < argc; i++)
00566    {
00567       if (!argv[i])
00568          continue;
00569 
00570       if ((argv[i][0] == '-') && argv[i][1] && inOptions)
00571       {
00572          bool enabled = true;
00573          const char *option = &argv[i][1];
00574          const char *orig = argv[i];
00575          if (option[0] == '-')
00576          {
00577             option++;
00578             argv[i]++;
00579             if (!option[0])
00580             {
00581                inOptions = false;
00582                continue;
00583             }
00584          }
00585          if (::qstrcmp(option, "help") == 0)
00586          {
00587             usage(0);
00588          }
00589          else if (strncmp(option, "help-",5) == 0)
00590          {
00591             usage(option+5);
00592          }
00593          else if ( (::qstrcmp(option, "version") == 0) ||
00594                    (::qstrcmp(option, "v") == 0))
00595          {
00596             printQ( TQString("Qt: %1\n").arg(tqVersion()));
00597             printQ( TQString("TDE: %1\n").arg(TDE_VERSION_STRING));
00598             printQ( TQString("%1: %2\n").
00599       arg(about->programName()).arg(about->version()));
00600             exit(0);
00601          } else if ( (::qstrcmp(option, "license") == 0) )
00602          {
00603             enable_i18n();
00604             printQ( about->license() );
00605             printQ( "\n" );
00606             exit(0);
00607          } else if ( ::qstrcmp( option, "author") == 0 ) {
00608              enable_i18n();
00609        if ( about ) {
00610          const TQValueList<TDEAboutPerson> authors = about->authors();
00611          if ( !authors.isEmpty() ) {
00612            TQString authorlist;
00613            for (TQValueList<TDEAboutPerson>::ConstIterator it = authors.begin(); it != authors.end(); ++it ) {
00614              TQString email;
00615              if ( !(*it).emailAddress().isEmpty() )
00616                email = " <" + (*it).emailAddress() + ">";
00617              authorlist += TQString("    ") + (*it).name() + email + "\n";
00618            }
00619            printQ( i18n("the 2nd argument is a list of name+address, one on each line","%1 was written by\n%2").arg ( TQString(about->programName()) ).arg( authorlist ) );
00620          }
00621        } else {
00622          printQ( i18n("This application was written by somebody who wants to remain anonymous.") );
00623        }
00624        if (about)
00625        {
00626          if (!about->customAuthorTextEnabled ())
00627          {
00628            if (about->bugAddress().isEmpty()
00629                  || about->bugAddress() == "submit@bugs.trinitydesktop.org"
00630                  || about->bugAddress() == "http://bugs.trinitydesktop.org" )
00631              printQ( i18n( "Please use http://bugs.trinitydesktop.org to report bugs.\n" ) );
00632            else {
00633              if( about->authors().count() == 1 && about->authors().first().emailAddress() == about->bugAddress() )
00634                printQ( i18n( "Please report bugs to %1.\n" ).arg( about->authors().first().emailAddress() ) );
00635              else
00636                printQ( i18n( "Please report bugs to %1.\n" ).arg(about->bugAddress()) );
00637            }
00638          }
00639          else
00640          {
00641            printQ(about->customAuthorPlainText());
00642          }
00643        }
00644        exit(0);
00645          } else {
00646            if ((option[0] == 'n') && (option[1] == 'o'))
00647            {
00648               option += 2;
00649               enabled = false;
00650            }
00651            findOption(orig, option, i, enabled, inOptions);
00652          }
00653       }
00654       else
00655       {
00656          // Check whether appOptions allows these arguments
00657          if (!allowArgs)
00658          {
00659             if (ignoreUnknown)
00660                continue;
00661             enable_i18n();
00662             usage( i18n("Unexpected argument '%1'.").arg(TQString::fromLocal8Bit(argv[i])));
00663          }
00664          else
00665          {
00666             appOptions->addArgument(argv[i]);
00667             if (everythingAfterArgIsArgs)
00668                 inOptions = false;
00669          }
00670       }
00671    }
00672    parsed = true;
00673 }
00674 
00680 int *
00681 TDECmdLineArgs::tqt_argc()
00682 {
00683    if (!argsList)
00684       TDEApplication::addCmdLineOptions(); // Lazy bastards!
00685 
00686    static int tqt_argc = -1;
00687    if( tqt_argc != -1 )
00688       return &tqt_argc;
00689 
00690    TDECmdLineArgs *args = parsedArgs("qt");
00691    assert(args); // No qt options have been added!
00692    if (!argv)
00693    {
00694       fprintf(stderr, "\n\nFAILURE (TDECmdLineArgs):\n");
00695       fprintf(stderr, "Application has not called TDECmdLineArgs::init(...).\n\n");
00696 
00697       assert( 0 );
00698       exit(255);
00699    }
00700 
00701    assert(argc >= (args->count()+1));
00702    tqt_argc = args->count() +1;
00703    return &tqt_argc;
00704 }
00705 
00711 char ***
00712 TDECmdLineArgs::tqt_argv()
00713 {
00714    if (!argsList)
00715       TDEApplication::addCmdLineOptions(); // Lazy bastards!
00716 
00717    static char** tqt_argv;
00718    if( tqt_argv != NULL )
00719       return &tqt_argv;
00720 
00721    TDECmdLineArgs *args = parsedArgs("qt");
00722    assert(args); // No qt options have been added!
00723    if (!argv)
00724    {
00725       fprintf(stderr, "\n\nFAILURE (TDECmdLineArgs):\n");
00726       fprintf(stderr, "Application has not called TDECmdLineArgs::init(...).\n\n");
00727 
00728       assert( 0 );
00729       exit(255);
00730    }
00731 
00732    tqt_argv = new char*[ args->count() + 2 ];
00733    tqt_argv[ 0 ] = tqstrdup( appName());
00734    int i = 0;
00735    for(; i < args->count(); i++)
00736    {
00737       tqt_argv[i+1] = tqstrdup((char *) args->arg(i));
00738    }
00739    tqt_argv[i+1] = 0;
00740 
00741    return &tqt_argv;
00742 }
00743 
00744 void
00745 TDECmdLineArgs::enable_i18n()
00746 {
00747     // called twice or too late
00748     if (TDEGlobal::_locale)
00749       return;
00750 
00751     if (!TDEGlobal::_instance) {
00752   TDEInstance *instance = new TDEInstance(about);
00753   (void) instance->config();
00754   // Don't delete instance!
00755     }
00756 }
00757 
00758 void
00759 TDECmdLineArgs::usage(const TQString &error)
00760 {
00761     assert(TDEGlobal::_locale);
00762     TQCString localError = error.local8Bit();
00763     if (localError[error.length()-1] == '\n')
00764   localError = localError.left(error.length()-1);
00765     fprintf(stderr, "%s: %s\n", argv[0], localError.data());
00766 
00767     TQString tmp = i18n("Use --help to get a list of available command line options.");
00768     localError = tmp.local8Bit();
00769     fprintf(stderr, "%s: %s\n", argv[0], localError.data());
00770     exit(254);
00771 }
00772 
00773 void
00774 TDECmdLineArgs::usage(const char *id)
00775 {
00776    enable_i18n();
00777    assert(argsList != 0); // It's an error to call usage(...) without
00778                           // having done addCmdLineOptions first!
00779 
00780    TQString optionFormatString   = "  %1 %2\n";
00781    TQString optionFormatStringDef  = "  %1 %2 [%3]\n";
00782    TQString optionHeaderString = i18n("\n%1:\n");
00783    TQString tmp;
00784    TQString usage;
00785 
00786    TDECmdLineArgs *args = argsList->last();
00787 
00788    if (!(args->id) && (args->options) &&
00789        (args->options->name) && (args->options->name[0] != '+'))
00790    {
00791       usage = i18n("[options] ")+usage;
00792    }
00793 
00794    while(args)
00795    {
00796       if (args->name)
00797       {
00798          usage = i18n("[%1-options]").arg(args->name)+" "+usage;
00799       }
00800       args = argsList->prev();
00801    }
00802 
00803    TDECmdLineArgs *appOptions = argsList->last();
00804    if (!appOptions->id)
00805    {
00806      const TDECmdLineOptions *option = appOptions->options;
00807      while(option && option->name)
00808      {
00809        if (option->name[0] == '+')
00810           usage = usage + (option->name+1) + " ";
00811        else if ( option->name[0] == '!' && option->name[1] == '+' )
00812           usage = usage + (option->name+2) + " ";
00813 
00814        option++;
00815      }
00816    }
00817 
00818    printQ(i18n("Usage: %1 %2\n").arg(argv[0]).arg(usage));
00819    printQ("\n"+about->shortDescription()+"\n");
00820 
00821    printQ(optionHeaderString.arg(i18n("Generic options")));
00822    printQ(optionFormatString.arg("--help", -25).arg(i18n("Show help about options")));
00823 
00824    args = argsList->first();
00825    while(args)
00826    {
00827       if (args->name && args->id)
00828       {
00829          TQString option = TQString("--help-%1").arg(args->id);
00830          TQString desc = i18n("Show %1 specific options").arg(args->name);
00831 
00832          printQ(optionFormatString.arg(option, -25).arg(desc));
00833       }
00834       args = argsList->next();
00835    }
00836 
00837    printQ(optionFormatString.arg("--help-all",-25).arg(i18n("Show all options")));
00838    printQ(optionFormatString.arg("--author",-25).arg(i18n("Show author information")));
00839    printQ(optionFormatString.arg("-v, --version",-25).arg(i18n("Show version information")));
00840    printQ(optionFormatString.arg("--license",-25).arg(i18n("Show license information")));
00841    printQ(optionFormatString.arg("--", -25).arg(i18n("End of options")));
00842 
00843    args = argsList->first(); // Sets current to 1st.
00844 
00845    bool showAll = id && (::qstrcmp(id, "all") == 0);
00846 
00847    if (!showAll)
00848    {
00849      while(args)
00850      {
00851        if (!id && !args->id) break;
00852        if (id && (::qstrcmp(args->id, id) == 0)) break;
00853        args = argsList->next();
00854      }
00855    }
00856 
00857    while(args)
00858    {
00859      bool hasArgs = false;
00860      bool hasOptions = false;
00861      TQString optionsHeader;
00862      if (args->name)
00863         optionsHeader = optionHeaderString.arg(i18n("%1 options").arg(TQString::fromLatin1(args->name)));
00864      else
00865         optionsHeader = i18n("\nOptions:\n");
00866 
00867      while (args)
00868      {
00869        const TDECmdLineOptions *option = args->options;
00870        TQCString opt = "";
00871 //
00872        while(option && option->name)
00873        {
00874          TQString description;
00875          TQString descriptionRest;
00876          TQStringList dl;
00877 
00878          // Option header
00879          if (option->name[0] == ':')
00880          {
00881             if (option->description)
00882             {
00883                optionsHeader = "\n"+i18n(option->description);
00884                if (!optionsHeader.endsWith("\n"))
00885                   optionsHeader.append("\n");
00886                hasOptions = false;
00887             }
00888             option++;
00889             continue;
00890          }
00891 
00892          // Free-form comment
00893          if (option->name[0] == 0)
00894          {
00895             if (option->description)
00896             {
00897                TQString tmp = "\n"+i18n(option->description);
00898                if (!tmp.endsWith("\n"))
00899                   tmp.append("\n");
00900                printQ(tmp);
00901             }
00902             option++;
00903             continue;
00904          }
00905 
00906          // Options
00907          if (option->description)
00908          {
00909             description = i18n(option->description);
00910             dl = TQStringList::split("\n", description, true);
00911             description = dl.first();
00912             dl.remove( dl.begin() );
00913          }
00914          TQCString name = option->name;
00915          if (name[0] == '!')
00916              name = name.mid(1);
00917 
00918          if (name[0] == '+')
00919          {
00920             if (!hasArgs)
00921             {
00922                printQ(i18n("\nArguments:\n"));
00923                hasArgs = true;
00924             }
00925 
00926             name = name.mid(1);
00927             if ((name[0] == '[') && (name[name.length()-1] == ']'))
00928          name = name.mid(1, name.length()-2);
00929             printQ(optionFormatString.arg(QString(name), -25)
00930      .arg(description));
00931          }
00932          else
00933          {
00934             if (!hasOptions)
00935             {
00936                printQ(optionsHeader);
00937                hasOptions = true;
00938             }
00939 
00940             if ((name.length() == 1) || (name[1] == ' '))
00941                name = "-"+name;
00942             else
00943                name = "--"+name;
00944             if (!option->description)
00945             {
00946                opt = name + ", ";
00947             }
00948             else
00949             {
00950                opt = opt + name;
00951                if (!option->def)
00952                {
00953                   printQ(optionFormatString.arg(QString(opt), -25)
00954                          .arg(description));
00955                }
00956                else
00957                {
00958                   printQ(optionFormatStringDef.arg(QString(opt), -25)
00959                          .arg(description).arg(option->def));
00960                }
00961                opt = "";
00962             }
00963          }
00964          for(TQStringList::Iterator it = dl.begin();
00965              it != dl.end();
00966              ++it)
00967          {
00968             printQ(optionFormatString.arg("", -25).arg(*it));
00969          }
00970 
00971          option++;
00972        }
00973        args = argsList->next();
00974        if (!args || args->name || !args->id) break;
00975      }
00976      if (!showAll) break;
00977    }
00978 
00979    exit(254);
00980 }
00981 
00982 //
00983 // Member functions
00984 //
00985 
00991 TDECmdLineArgs::TDECmdLineArgs( const TDECmdLineOptions *_options,
00992                             const char *_name, const char *_id)
00993   : options(_options), name(_name), id(_id)
00994 {
00995   parsedOptionList = 0;
00996   parsedArgList = 0;
00997   isQt = (::qstrcmp(id, "qt") == 0);
00998 }
00999 
01003 TDECmdLineArgs::~TDECmdLineArgs()
01004 {
01005   delete parsedOptionList;
01006   delete parsedArgList;
01007   if (argsList)
01008      argsList->removeRef(this);
01009 }
01010 
01011 void
01012 TDECmdLineArgs::clear()
01013 {
01014    delete parsedArgList;
01015    parsedArgList = 0;
01016    delete parsedOptionList;
01017    parsedOptionList = 0;
01018 }
01019 
01020 void
01021 TDECmdLineArgs::reset()
01022 {
01023    if ( argsList ) {
01024       argsList->setAutoDelete( true );
01025       argsList->clear();
01026       delete argsList;
01027       argsList = 0;
01028    }
01029    parsed = false;
01030 }
01031 
01032 void
01033 TDECmdLineArgs::save( TQDataStream &ds) const
01034 {
01035    uint count = 0;
01036    if (parsedOptionList)
01037       parsedOptionList->save( ds );
01038    else
01039       ds << count;
01040 
01041    if (parsedArgList)
01042       parsedArgList->save( ds );
01043    else
01044       ds << count;
01045 }
01046 
01047 void
01048 TDECmdLineArgs::load( TQDataStream &ds)
01049 {
01050    if (!parsedOptionList) parsedOptionList = new TDECmdLineParsedOptions;
01051    if (!parsedArgList) parsedArgList = new TDECmdLineParsedArgs;
01052 
01053    parsedOptionList->load( ds );
01054    parsedArgList->load( ds );
01055 
01056    if (parsedOptionList->count() == 0)
01057    {
01058       delete parsedOptionList;
01059       parsedOptionList = 0;
01060    }
01061    if (parsedArgList->count() == 0)
01062    {
01063       delete parsedArgList;
01064       parsedArgList = 0;
01065    }
01066 }
01067 
01068 void
01069 TDECmdLineArgs::setOption(const TQCString &opt, bool enabled)
01070 {
01071    if (isQt)
01072    {
01073       // Qt does it own parsing.
01074       TQCString arg = "-";
01075       if( !enabled )
01076           arg += "no";
01077       arg += opt;
01078       addArgument(arg);
01079    }
01080    if (!parsedOptionList) {
01081   parsedOptionList = new TDECmdLineParsedOptions;
01082   parsedOptionList->setAutoDelete(true);
01083    }
01084 
01085    if (enabled)
01086       parsedOptionList->replace( opt, new TQCString("t") );
01087    else
01088       parsedOptionList->replace( opt, new TQCString("f") );
01089 }
01090 
01091 void
01092 TDECmdLineArgs::setOption(const TQCString &opt, const char *value)
01093 {
01094    if (isQt)
01095    {
01096       // Qt does it's own parsing.
01097       TQCString arg = "-";
01098       arg += opt;
01099       addArgument(arg);
01100       addArgument(value);
01101 
01102 #ifdef Q_WS_X11
01103       // Hack coming up!
01104       if (arg == "-display")
01105       {
01106          setenv(DISPLAY, value, true);
01107       }
01108 #endif
01109    }
01110    if (!parsedOptionList) {
01111   parsedOptionList = new TDECmdLineParsedOptions;
01112   parsedOptionList->setAutoDelete(true);
01113    }
01114 
01115    parsedOptionList->insert( opt, new TQCString(value) );
01116 }
01117 
01118 TQCString
01119 TDECmdLineArgs::getOption(const char *_opt) const
01120 {
01121    TQCString *value = 0;
01122    if (parsedOptionList)
01123    {
01124       value = parsedOptionList->find(_opt);
01125    }
01126 
01127    if (value)
01128       return (*value);
01129 
01130    // Look up the default.
01131    const char *opt_name;
01132    const char *def;
01133    bool dummy = true;
01134    TQCString opt = _opt;
01135    int result = ::findOption( options, opt, opt_name, def, dummy) & ~4;
01136 
01137    if (result != 3)
01138    {
01139       fprintf(stderr, "\n\nFAILURE (TDECmdLineArgs):\n");
01140       fprintf(stderr, "Application requests for getOption(\"%s\") but the \"%s\" option\n",
01141                       _opt, _opt);
01142       fprintf(stderr, "has never been specified via addCmdLineOptions( ... )\n\n");
01143 
01144       assert( 0 );
01145       exit(255);
01146    }
01147    return TQCString(def);
01148 }
01149 
01150 QCStringList
01151 TDECmdLineArgs::getOptionList(const char *_opt) const
01152 {
01153    QCStringList result;
01154    if (!parsedOptionList)
01155       return result;
01156 
01157    while(true)
01158    {
01159       TQCString *value = parsedOptionList->take(_opt);
01160       if (!value)
01161          break;
01162       result.prepend(*value);
01163       delete value;
01164    }
01165 
01166    // Reinsert items in dictionary
01167    // WABA: This is rather silly, but I don't want to add restrictions
01168    // to the API like "you can only call this function once".
01169    // I can't access all items without taking them out of the list.
01170    // So taking them out and then putting them back is the only way.
01171    for(QCStringList::ConstIterator it=result.begin();
01172        it != result.end();
01173        ++it)
01174    {
01175       parsedOptionList->insert(_opt, new TQCString(*it));
01176    }
01177    return result;
01178 }
01179 
01180 bool
01181 TDECmdLineArgs::isSet(const char *_opt) const
01182 {
01183    // Look up the default.
01184    const char *opt_name;
01185    const char *def;
01186    bool dummy = true;
01187    TQCString opt = _opt;
01188    int result = ::findOption( options, opt, opt_name, def, dummy) & ~4;
01189 
01190    if (result == 0)
01191    {
01192       fprintf(stderr, "\n\nFAILURE (TDECmdLineArgs):\n");
01193       fprintf(stderr, "Application requests for isSet(\"%s\") but the \"%s\" option\n",
01194                       _opt, _opt);
01195       fprintf(stderr, "has never been specified via addCmdLineOptions( ... )\n\n");
01196 
01197       assert( 0 );
01198       exit(255);
01199    }
01200 
01201    TQCString *value = 0;
01202    if (parsedOptionList)
01203    {
01204       value = parsedOptionList->find(opt);
01205    }
01206 
01207    if (value)
01208    {
01209       if (result == 3)
01210          return true;
01211       else
01212          return ((*value)[0] == 't');
01213    }
01214 
01215    if (result == 3)
01216       return false; // String option has 'false' as default.
01217 
01218    // We return 'true' as default if the option was listed as '-nofork'
01219    // We return 'false' as default if the option was listed as '-fork'
01220    return (result == 2);
01221 }
01222 
01223 int
01224 TDECmdLineArgs::count() const
01225 {
01226    if (!parsedArgList)
01227       return 0;
01228    return parsedArgList->count();
01229 }
01230 
01231 const char *
01232 TDECmdLineArgs::arg(int n) const
01233 {
01234    if (!parsedArgList || (n >= (int) parsedArgList->count()))
01235    {
01236       fprintf(stderr, "\n\nFAILURE (TDECmdLineArgs): Argument out of bounds\n");
01237       fprintf(stderr, "Application requests for arg(%d) without checking count() first.\n",
01238                       n);
01239 
01240       assert( 0 );
01241       exit(255);
01242    }
01243 
01244    return parsedArgList->at(n);
01245 }
01246 
01247 KURL
01248 TDECmdLineArgs::url(int n) const
01249 {
01250    return makeURL( arg(n) );
01251 }
01252 
01253 KURL TDECmdLineArgs::makeURL(const char *_urlArg)
01254 {
01255    const TQString urlArg = TQFile::decodeName(_urlArg);
01256    TQFileInfo fileInfo(urlArg);
01257    if (!fileInfo.isRelative()) { // i.e. starts with '/', on unix
01258       KURL result;
01259       result.setPath(urlArg);
01260       return result; // Absolute path.
01261    }
01262 
01263    if ( KURL::isRelativeURL(urlArg) || fileInfo.exists() ) {
01264       KURL result;
01265       result.setPath( cwd()+'/'+urlArg );
01266       result.cleanPath();
01267       return result;  // Relative path
01268    }
01269 
01270    return KURL(urlArg); // Argument is a URL
01271 }
01272 
01273 void
01274 TDECmdLineArgs::addArgument(const char *argument)
01275 {
01276    if (!parsedArgList)
01277       parsedArgList = new TDECmdLineParsedArgs;
01278 
01279    parsedArgList->append(argument);
01280 }
01281 
01282 static const TDECmdLineOptions kde_tempfile_option[] =
01283 {
01284    { "tempfile",       I18N_NOOP("The files/URLs opened by the application will be deleted after use"), 0},
01285    TDECmdLineLastOption
01286 };
01287 
01288 void
01289 TDECmdLineArgs::addTempFileOption()
01290 {
01291     TDECmdLineArgs::addCmdLineOptions( kde_tempfile_option, "TDE-tempfile", "tde-tempfile" );
01292 }
01293 
01294 bool TDECmdLineArgs::isTempFileSet()
01295 {
01296     TDECmdLineArgs* args = TDECmdLineArgs::parsedArgs( "tde-tempfile" );
01297     if ( args )
01298         return args->isSet( "tempfile" );
01299     return false;
01300 }

tdecore

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

tdecore

Skip menu "tdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.6.3
This website is maintained by Timothy Pearson.