00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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 #if HAVE_LIMITS_H
00030 #include <limits.h>
00031 #endif
00032
00033 #include <qfile.h>
00034 #include <qasciidict.h>
00035 #include <qstrlist.h>
00036
00037 #include "kcmdlineargs.h"
00038 #include <kaboutdata.h>
00039 #include <klocale.h>
00040 #include <kapplication.h>
00041 #include <kglobal.h>
00042 #include <kstringhandler.h>
00043 #include <kstaticdeleter.h>
00044
00045 #ifdef Q_WS_X11
00046 #define DISPLAY "DISPLAY"
00047 #elif defined(Q_WS_QWS)
00048 #define DISPLAY "QWS_DISPLAY"
00049 #endif
00050
00051 template class QAsciiDict<QCString>;
00052 template class QPtrList<KCmdLineArgs>;
00053
00054 class KCmdLineParsedOptions : public QAsciiDict<QCString>
00055 {
00056 public:
00057 KCmdLineParsedOptions()
00058 : QAsciiDict<QCString>( 7 ) { }
00059
00060
00061
00062
00063
00064
00065 QDataStream& save( QDataStream &s) const
00066 { return QGDict::write(s); }
00067
00068 QDataStream& load( QDataStream &s)
00069 { return QGDict::read(s); }
00070
00071 protected:
00072 virtual QDataStream& write( QDataStream &s, QPtrCollection::Item data) const
00073 {
00074 QCString *str = (QCString *) data;
00075 s << (*str);
00076 return s;
00077 }
00078
00079 virtual QDataStream& read( QDataStream &s, QPtrCollection::Item &item)
00080 {
00081 QCString *str = new QCString;
00082 s >> (*str);
00083 item = (void *)str;
00084 return s;
00085 }
00086
00087 };
00088
00089 class KCmdLineParsedArgs : public QStrList
00090 {
00091 public:
00092 KCmdLineParsedArgs()
00093 : QStrList( true ) { }
00094 QDataStream& save( QDataStream &s) const
00095 { return QGList::write(s); }
00096
00097 QDataStream& load( QDataStream &s)
00098 { return QGList::read(s); }
00099 };
00100
00101
00102 class KCmdLineArgsList: public QPtrList<KCmdLineArgs>
00103 {
00104 public:
00105 KCmdLineArgsList() { }
00106 };
00107
00108 KCmdLineArgsList *KCmdLineArgs::argsList = 0;
00109 int KCmdLineArgs::argc = 0;
00110 char **KCmdLineArgs::argv = 0;
00111 char *KCmdLineArgs::mCwd = 0;
00112 static KStaticDeleter <char> mCwdd;
00113 const KAboutData *KCmdLineArgs::about = 0;
00114 bool KCmdLineArgs::parsed = false;
00115 bool KCmdLineArgs::ignoreUnknown = false;
00116
00117
00118
00119
00120
00121 void
00122 KCmdLineArgs::init(int _argc, char **_argv, const char *_appname,
00123 const char *_description, const char *_version, bool noKApp)
00124 {
00125 init(_argc, _argv,
00126 new KAboutData(_appname, _appname, _version, _description),
00127 noKApp);
00128 }
00129
00130 void
00131 KCmdLineArgs::initIgnore(int _argc, char **_argv, const char *_appname )
00132 {
00133 init(_argc, _argv,
00134 new KAboutData(_appname, _appname, "unknown", "KDE Application", false));
00135 ignoreUnknown = true;
00136 }
00137
00138 void
00139 KCmdLineArgs::init(const KAboutData* ab)
00140 {
00141 init(0,0,ab, true);
00142 }
00143
00144
00145 void
00146 KCmdLineArgs::init(int _argc, char **_argv, const KAboutData *_about, bool noKApp)
00147 {
00148 assert( argsList == 0 );
00149 assert( argc == 0 );
00150 assert( argv == 0 );
00151 assert( about == 0 );
00152 argc = _argc;
00153 argv = _argv;
00154
00155 if (!argv)
00156 {
00157 fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
00158 fprintf(stderr, "Passing null-pointer to 'argv' is not allowed.\n\n");
00159
00160 assert( 0 );
00161 exit(255);
00162 }
00163
00164
00165 if (argc) {
00166 char *p = strrchr( argv[0], '/');
00167 if (p)
00168 argv[0] = p+1;
00169 }
00170
00171 about = _about;
00172 parsed = false;
00173 mCwd = mCwdd.setObject(new char [PATH_MAX+1], true);
00174 getcwd(mCwd, PATH_MAX);
00175 if (!noKApp)
00176 KApplication::addCmdLineOptions();
00177 }
00178
00179 QString KCmdLineArgs::cwd()
00180 {
00181 return QFile::decodeName(QCString(mCwd));
00182 }
00183
00184 const char * KCmdLineArgs::appName()
00185 {
00186 if (!argc) return 0;
00187 return argv[0];
00188 }
00189
00190 void
00191 KCmdLineArgs::addCmdLineOptions( const KCmdLineOptions *options, const char *name,
00192 const char *id, const char *afterId)
00193 {
00194 if (!argsList)
00195 argsList = new KCmdLineArgsList();
00196
00197 int pos = argsList->count();
00198
00199 if (pos && id && argsList->last() && !argsList->last()->name)
00200 pos--;
00201
00202 KCmdLineArgs *args;
00203 int i = 0;
00204 for(args = argsList->first(); args; args = argsList->next(), i++)
00205 {
00206 if (!id && !args->id)
00207 return;
00208
00209 if (id && args->id && (::qstrcmp(id, args->id) == 0))
00210 return;
00211
00212 if (afterId && args->id && (::qstrcmp(afterId, args->id) == 0))
00213 pos = i+1;
00214 }
00215
00216 assert( parsed == false );
00217
00218 args = new KCmdLineArgs(options, name, id);
00219 argsList->insert(pos, args);
00220 }
00221
00222 void
00223 KCmdLineArgs::saveAppArgs( QDataStream &ds)
00224 {
00225 if (!parsed)
00226 parseAllArgs();
00227
00228
00229 removeArgs("qt");
00230 removeArgs("kde");
00231
00232 QCString qCwd = mCwd;
00233 ds << qCwd;
00234
00235 uint count = argsList ? argsList->count() : 0;
00236 ds << count;
00237
00238 if (!count) return;
00239
00240 KCmdLineArgs *args;
00241 for(args = argsList->first(); args; args = argsList->next())
00242 {
00243 args->save(ds);
00244 }
00245 }
00246
00247 void
00248 KCmdLineArgs::loadAppArgs( QDataStream &ds)
00249 {
00250
00251 removeArgs("qt");
00252 removeArgs("kde");
00253
00254 KCmdLineArgs *args;
00255 if (argsList)
00256 {
00257 for(args = argsList->first(); args; args = argsList->next())
00258 {
00259 args->clear();
00260 }
00261 }
00262
00263 QCString qCwd;
00264 ds >> qCwd;
00265 if (mCwd)
00266 delete [] mCwd;
00267
00268 mCwd = mCwdd.setObject(new char[qCwd.length()+1], true);
00269 strncpy(mCwd, qCwd.data(), qCwd.length()+1);
00270
00271 uint count;
00272 ds >> count;
00273
00274 if (count == 0)
00275 return;
00276
00277 if (!argsList || (count != argsList->count()))
00278 {
00279 fprintf(stderr, "loadAppArgs:: Unexpected number of command line sets "
00280 "(%d instead of %d)\n", count, argsList ? argsList->count() : 0);
00281 return;
00282 }
00283
00284 for(args = argsList->first(); args; args = argsList->next())
00285 {
00286 args->load(ds);
00287 }
00288 }
00289
00290 KCmdLineArgs *KCmdLineArgs::parsedArgs(const char *id)
00291 {
00292 KCmdLineArgs *args = argsList ? argsList->first() : 0;
00293 while(args)
00294 {
00295 if ((id && ::qstrcmp(args->id, id) == 0) || (!id && !args->id))
00296 {
00297 if (!parsed)
00298 parseAllArgs();
00299 return args;
00300 }
00301 args = argsList->next();
00302 }
00303
00304 if (!args)
00305 {
00306 #ifndef NDEBUG
00307 fprintf(stderr, "WARNING (KCmdLineArgs):\n");
00308 fprintf(stderr, "Application requests for parsedArgs(\"%s\") without a prior call\n", id?id:"null");
00309 fprintf(stderr, "to addCmdLineOptions( ..., \"%s\")\n\n", id?id:"null");
00310 #endif
00311 }
00312 return args;
00313 }
00314
00315 void KCmdLineArgs::removeArgs(const char *id)
00316 {
00317 KCmdLineArgs *args = argsList ? argsList->first() : 0;
00318 while(args)
00319 {
00320 if (args->id && id && ::qstrcmp(args->id, id) == 0)
00321 {
00322 if (!parsed)
00323 parseAllArgs();
00324 break;
00325 }
00326 args = argsList->next();
00327 }
00328
00329 if (args)
00330 delete args;
00331 }
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 static int
00343 findOption(const KCmdLineOptions *options, QCString &opt,
00344 const char *&opt_name, const char *&def, bool &enabled)
00345 {
00346 int result;
00347 bool inverse;
00348 int len = opt.length();
00349 while(options && options->name)
00350 {
00351 result = 0;
00352 inverse = false;
00353 opt_name = options->name;
00354 if (opt_name[0] == '!')
00355 {
00356 opt_name++;
00357 result = 4;
00358 }
00359 if ((opt_name[0] == 'n') && (opt_name[1] == 'o'))
00360 {
00361 opt_name += 2;
00362 inverse = true;
00363 }
00364 if (strncmp(opt.data(), opt_name, len) == 0)
00365 {
00366 opt_name += len;
00367 if (!opt_name[0])
00368 {
00369 if (inverse)
00370 return result+2;
00371
00372 if (!options->description)
00373 {
00374 options++;
00375 if (!options->name)
00376 return result+0;
00377 QCString nextOption = options->name;
00378 int p = nextOption.find(' ');
00379 if (p > 0)
00380 nextOption = nextOption.left(p);
00381 if (strncmp(nextOption.data(), "no", 2) == 0)
00382 {
00383 nextOption = nextOption.mid(2);
00384 enabled = !enabled;
00385 }
00386 result = findOption(options, nextOption, opt_name, def, enabled);
00387 assert(result);
00388 opt = nextOption;
00389 return result;
00390 }
00391
00392 return 1;
00393 }
00394 if (opt_name[0] == ' ')
00395 {
00396 opt_name++;
00397 def = options->def;
00398 return result+3;
00399 }
00400 }
00401
00402 options++;
00403 }
00404 return 0;
00405 }
00406
00407
00408 void
00409 KCmdLineArgs::findOption(const char *_opt, QCString opt, int &i, bool _enabled, bool &moreOptions)
00410 {
00411 KCmdLineArgs *args = argsList->first();
00412 const char *opt_name;
00413 const char *def;
00414 QCString argument;
00415 int j = opt.find('=');
00416 if (j != -1)
00417 {
00418 argument = opt.mid(j+1);
00419 opt = opt.left(j);
00420 }
00421
00422 bool enabled = true;
00423 int result = 0;
00424 while (args)
00425 {
00426 enabled = _enabled;
00427 result = ::findOption(args->options, opt, opt_name, def, enabled);
00428 if (result) break;
00429 args = argsList->next();
00430 }
00431 if (!args && (_opt[0] == '-') && _opt[1] && (_opt[1] != '-'))
00432 {
00433
00434
00435 int p = 1;
00436 while (true)
00437 {
00438 QCString singleCharOption = " ";
00439 singleCharOption[0] = _opt[p];
00440 args = argsList->first();
00441 while (args)
00442 {
00443 enabled = _enabled;
00444 result = ::findOption(args->options, singleCharOption, opt_name, def, enabled);
00445 if (result) break;
00446 args = argsList->next();
00447 }
00448 if (!args)
00449 break;
00450
00451 p++;
00452 if (result == 1)
00453 {
00454 args->setOption(singleCharOption, enabled);
00455 if (_opt[p])
00456 continue;
00457 else
00458 return;
00459 }
00460 else if (result == 3)
00461 {
00462 if (argument.isEmpty())
00463 {
00464 argument = _opt+p;
00465 }
00466 args->setOption(singleCharOption, argument);
00467 return;
00468 }
00469 break;
00470 }
00471 args = 0;
00472 result = 0;
00473 }
00474
00475 if (!args || !result)
00476 {
00477 if (ignoreUnknown)
00478 return;
00479 enable_i18n();
00480 usage( i18n("Unknown option '%1'.").arg(_opt));
00481 }
00482
00483 if ((result & 4) != 0)
00484 {
00485 result &= ~4;
00486 moreOptions = false;
00487 }
00488
00489 if (result == 3)
00490 {
00491 if (!enabled)
00492 {
00493 if (ignoreUnknown)
00494 return;
00495 enable_i18n();
00496 usage( i18n("Unknown option '%1'.").arg(_opt));
00497 }
00498 if (argument.isEmpty())
00499 {
00500 i++;
00501 if (i >= argc)
00502 {
00503 enable_i18n();
00504 usage( i18n("'%1' missing.").arg( opt_name));
00505 }
00506 argument = argv[i];
00507 }
00508 args->setOption(opt, argument);
00509 }
00510 else
00511 {
00512 args->setOption(opt, enabled);
00513 }
00514 }
00515
00516 void
00517 KCmdLineArgs::printQ(const QString &msg)
00518 {
00519 QCString localMsg = msg.local8Bit();
00520 fprintf(stdout, "%s", localMsg.data());
00521 }
00522
00523 void
00524 KCmdLineArgs::parseAllArgs()
00525 {
00526 bool allowArgs = false;
00527 bool inOptions = true;
00528 bool everythingAfterArgIsArgs = false;
00529 KCmdLineArgs *appOptions = argsList->last();
00530 if (!appOptions->id)
00531 {
00532 const KCmdLineOptions *option = appOptions->options;
00533 while(option && option->name)
00534 {
00535 if (option->name[0] == '+')
00536 allowArgs = true;
00537 if ( option->name[0] == '!' && option->name[1] == '+' )
00538 {
00539 allowArgs = true;
00540 everythingAfterArgIsArgs = true;
00541 }
00542 option++;
00543 }
00544 }
00545 for(int i = 1; i < argc; i++)
00546 {
00547 if (!argv[i])
00548 continue;
00549
00550 if ((argv[i][0] == '-') && argv[i][1] && inOptions)
00551 {
00552 bool enabled = true;
00553 const char *option = &argv[i][1];
00554 const char *orig = argv[i];
00555 if (option[0] == '-')
00556 {
00557 option++;
00558 argv[i]++;
00559 if (!option[0])
00560 {
00561 inOptions = false;
00562 continue;
00563 }
00564 }
00565 if (::qstrcmp(option, "help") == 0)
00566 {
00567 usage(0);
00568 }
00569 else if (strncmp(option, "help-",5) == 0)
00570 {
00571 usage(option+5);
00572 }
00573 else if ( (::qstrcmp(option, "version") == 0) ||
00574 (::qstrcmp(option, "v") == 0))
00575 {
00576 printQ( QString("Qt: %1\n").arg(qVersion()));
00577 printQ( QString("KDE: %1\n").arg(KDE_VERSION_STRING));
00578 printQ( QString("%1: %2\n").
00579 arg(about->programName()).arg(about->version()));
00580 exit(0);
00581 } else if ( (::qstrcmp(option, "license") == 0) )
00582 {
00583 enable_i18n();
00584 printQ( about->license() );
00585 printQ( "\n" );
00586 exit(0);
00587 } else if ( ::qstrcmp( option, "author") == 0 ) {
00588 enable_i18n();
00589 if ( about ) {
00590 const QValueList<KAboutPerson> authors = about->authors();
00591 if ( !authors.isEmpty() ) {
00592 QString authorlist;
00593 for (QValueList<KAboutPerson>::ConstIterator it = authors.begin(); it != authors.end(); ++it ) {
00594 authorlist += QString(" ") + (*it).name() + " <" + (*it).emailAddress() + ">\n";
00595 }
00596 printQ( i18n("the 2nd argument is a list of name+address, one on each line","%1 was written by\n%2").arg ( QString(about->programName()) ).arg( authorlist ) );
00597 }
00598 } else {
00599 printQ( i18n("%1 was written by somebody who wants to remain anonymous.").arg(about->programName()) );
00600 }
00601 printQ( i18n( "Please use http://bugs.kde.org to report bugs, do not mail the authors directly.\n" ) );
00602 exit(0);
00603 } else {
00604 if ((option[0] == 'n') && (option[1] == 'o'))
00605 {
00606 option += 2;
00607 enabled = false;
00608 }
00609 findOption(orig, option, i, enabled, inOptions);
00610 }
00611 }
00612 else
00613 {
00614
00615 if (!allowArgs)
00616 {
00617 if (ignoreUnknown)
00618 continue;
00619 enable_i18n();
00620 usage( i18n("Unexpected argument '%1'.").arg( argv[i]));
00621 }
00622 else
00623 {
00624 appOptions->addArgument(argv[i]);
00625 if (everythingAfterArgIsArgs)
00626 inOptions = false;
00627 }
00628 }
00629 }
00630 parsed = true;
00631 }
00632
00638 int *
00639 KCmdLineArgs::qt_argc()
00640 {
00641 if (!argsList)
00642 KApplication::addCmdLineOptions();
00643
00644 KCmdLineArgs *args = parsedArgs("qt");
00645
00646 assert(args);
00647 if (!argv)
00648 {
00649 fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
00650 fprintf(stderr, "Application has not called KCmdLineArgs::init(...).\n\n");
00651
00652 assert( 0 );
00653 exit(255);
00654 }
00655
00656 assert(argc >= (args->count()+1));
00657 argc = args->count() +1;
00658 return &argc;
00659 }
00660
00666 char ***
00667 KCmdLineArgs::qt_argv()
00668 {
00669 if (!argsList)
00670 KApplication::addCmdLineOptions();
00671
00672 KCmdLineArgs *args = parsedArgs("qt");
00673 assert(args);
00674 if (!argv)
00675 {
00676 fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
00677 fprintf(stderr, "Application has not called KCmdLineArgs::init(...).\n\n");
00678
00679 assert( 0 );
00680 exit(255);
00681 }
00682
00683 int i = 0;
00684 for(; i < args->count(); i++)
00685 {
00686 argv[i+1] = (char *) args->arg(i);
00687 }
00688 argv[i+1] = 0;
00689
00690 return &argv;
00691 }
00692
00693 void
00694 KCmdLineArgs::enable_i18n()
00695 {
00696
00697 if (KGlobal::_locale)
00698 return;
00699
00700 if (!KGlobal::_instance) {
00701 KInstance *instance = new KInstance(about);
00702 (void) instance->config();
00703
00704 }
00705 }
00706
00707 void
00708 KCmdLineArgs::usage(const QString &error)
00709 {
00710 assert(KGlobal::_locale);
00711 QCString localError = error.local8Bit();
00712 if (localError[error.length()-1] == '\n')
00713 localError = localError.left(error.length()-1);
00714 fprintf(stderr, "%s: %s\n", argv[0], localError.data());
00715
00716 QString tmp = i18n("Use --help to get a list of available command line options.");
00717 localError = tmp.local8Bit();
00718 fprintf(stderr, "%s: %s\n", argv[0], localError.data());
00719 exit(254);
00720 }
00721
00722 void
00723 KCmdLineArgs::usage(const char *id)
00724 {
00725 enable_i18n();
00726 assert(argsList != 0);
00727
00728
00729 QString optionFormatString = " %1 %2\n";
00730 QString optionFormatStringDef = " %1 %2 [%3]\n";
00731 QString optionHeaderString = i18n("\n%1:\n");
00732 QString tmp;
00733 QString usage;
00734
00735 KCmdLineArgs *args = argsList->last();
00736
00737 if (!(args->id) && (args->options) &&
00738 (args->options->name) && (args->options->name[0] != '+'))
00739 {
00740 usage = i18n("[options] ")+usage;
00741 }
00742
00743 while(args)
00744 {
00745 if (args->name)
00746 {
00747 usage = QString(i18n("[%1-options]")).arg(args->name)+" "+usage;
00748 }
00749 args = argsList->prev();
00750 }
00751
00752 KCmdLineArgs *appOptions = argsList->last();
00753 if (!appOptions->id)
00754 {
00755 const KCmdLineOptions *option = appOptions->options;
00756 while(option && option->name)
00757 {
00758 if (option->name[0] == '+')
00759 usage = usage + (option->name+1) + " ";
00760 else if ( option->name[0] == '!' && option->name[1] == '+' )
00761 usage = usage + (option->name+2) + " ";
00762
00763 option++;
00764 }
00765 }
00766
00767 printQ(i18n("Usage: %1 %2\n").arg(argv[0]).arg(usage));
00768 printQ("\n"+about->shortDescription()+"\n");
00769
00770 printQ(optionHeaderString.arg(i18n("Generic options")));
00771 printQ(optionFormatString.arg("--help", -25).arg(i18n("Show help about options")));
00772
00773 args = argsList->first();
00774 while(args)
00775 {
00776 if (args->name && args->id)
00777 {
00778 QString option = QString("--help-%1").arg(args->id);
00779 QString desc = i18n("Show %1 specific options").arg(args->name);
00780
00781 printQ(optionFormatString.arg(option, -25).arg(desc));
00782 }
00783 args = argsList->next();
00784 }
00785
00786 printQ(optionFormatString.arg("--help-all",-25).arg(i18n("Show all options")));
00787 printQ(optionFormatString.arg("--author",-25).arg(i18n("Show author information")));
00788 printQ(optionFormatString.arg("-v, --version",-25).arg(i18n("Show version information")));
00789 printQ(optionFormatString.arg("--license",-25).arg(i18n("Show license information")));
00790 printQ(optionFormatString.arg("--", -25).arg(i18n("End of options")));
00791
00792 args = argsList->first();
00793
00794 bool showAll = id && (::qstrcmp(id, "all") == 0);
00795
00796 if (!showAll)
00797 {
00798 while(args)
00799 {
00800 if (!id && !args->id) break;
00801 if (id && (::qstrcmp(args->id, id) == 0)) break;
00802 args = argsList->next();
00803 }
00804 }
00805
00806 while(args)
00807 {
00808 bool hasArgs = false;
00809 bool hasOptions = false;
00810 while (args)
00811 {
00812 const KCmdLineOptions *option = args->options;
00813 QCString opt = "";
00814
00815 while(option && option->name)
00816 {
00817 QString description;
00818 QString descriptionRest;
00819 QStringList dl;
00820 if (option->description)
00821 {
00822 description = i18n(option->description);
00823 dl = QStringList::split("\n", description, true);
00824 description = dl.first();
00825 dl.remove( dl.begin() );
00826 }
00827 QCString name = option->name;
00828 if (name[0] == '!')
00829 name = name.mid(1);
00830
00831 if (name[0] == '+')
00832 {
00833 if (!hasArgs)
00834 {
00835 printQ(i18n("\nArguments:\n"));
00836 hasArgs = true;
00837 }
00838
00839 name = name.mid(1);
00840 if ((name[0] == '[') && (name[name.length()-1] == ']'))
00841 name = name.mid(1, name.length()-2);
00842 printQ(optionFormatString.arg(name, -25)
00843 .arg(description));
00844 }
00845 else
00846 {
00847 if (!hasOptions)
00848 {
00849 if (!args->name)
00850 printQ(i18n("\nOptions:\n"));
00851 else if (args->name)
00852 printQ(optionHeaderString.arg(i18n("%1 options").arg(QString::fromLatin1(args->name))));
00853 hasOptions = true;
00854 }
00855
00856 if ((name.length() == 1) || (name[1] == ' '))
00857 name = "-"+name;
00858 else
00859 name = "--"+name;
00860 if (!option->description)
00861 {
00862 opt = name + ", ";
00863 }
00864 else
00865 {
00866 opt = opt + name;
00867 if (!option->def)
00868 {
00869 printQ(optionFormatString.arg(opt, -25)
00870 .arg(description));
00871 }
00872 else
00873 {
00874 printQ(optionFormatStringDef.arg(opt, -25)
00875 .arg(description).arg(option->def));
00876 }
00877 opt = "";
00878 }
00879 }
00880 for(QStringList::Iterator it = dl.begin();
00881 it != dl.end();
00882 it++)
00883 {
00884 printQ(optionFormatString.arg("", -25).arg(*it));
00885 }
00886
00887 option++;
00888 }
00889 args = argsList->next();
00890 if (!args || args->name || !args->id) break;
00891 }
00892 if (!showAll) break;
00893 }
00894
00895 exit(254);
00896 }
00897
00898
00899
00900
00901
00907 KCmdLineArgs::KCmdLineArgs( const KCmdLineOptions *_options,
00908 const char *_name, const char *_id)
00909 : options(_options), name(_name), id(_id)
00910 {
00911 parsedOptionList = 0;
00912 parsedArgList = 0;
00913 isQt = (::qstrcmp(id, "qt") == 0);
00914 }
00915
00919 KCmdLineArgs::~KCmdLineArgs()
00920 {
00921 delete parsedOptionList;
00922 delete parsedArgList;
00923 if (argsList)
00924 {
00925 argsList->removeRef(this);
00926 if (argsList->count() == 0)
00927 {
00928 delete argsList;
00929 argsList = 0;
00930 }
00931 }
00932 }
00933
00934 void
00935 KCmdLineArgs::clear()
00936 {
00937 delete parsedArgList;
00938 parsedArgList = 0;
00939 delete parsedOptionList;
00940 parsedOptionList = 0;
00941 }
00942
00943 void
00944 KCmdLineArgs::save( QDataStream &ds) const
00945 {
00946 uint count = 0;
00947 if (parsedOptionList)
00948 parsedOptionList->save( ds );
00949 else
00950 ds << count;
00951
00952 if (parsedArgList)
00953 parsedArgList->save( ds );
00954 else
00955 ds << count;
00956 }
00957
00958 void
00959 KCmdLineArgs::load( QDataStream &ds)
00960 {
00961 if (!parsedOptionList) parsedOptionList = new KCmdLineParsedOptions;
00962 if (!parsedArgList) parsedArgList = new KCmdLineParsedArgs;
00963
00964 parsedOptionList->load( ds );
00965 parsedArgList->load( ds );
00966
00967 if (parsedOptionList->count() == 0)
00968 {
00969 delete parsedOptionList;
00970 parsedOptionList = 0;
00971 }
00972 if (parsedArgList->count() == 0)
00973 {
00974 delete parsedArgList;
00975 parsedArgList = 0;
00976 }
00977 }
00978
00979 void
00980 KCmdLineArgs::setOption(const QCString &opt, bool enabled)
00981 {
00982 if (isQt)
00983 {
00984
00985 QCString arg = "-";
00986 if( !enabled )
00987 arg += "no";
00988 arg += opt;
00989 addArgument(arg);
00990 }
00991 if (!parsedOptionList) {
00992 parsedOptionList = new KCmdLineParsedOptions;
00993 parsedOptionList->setAutoDelete(true);
00994 }
00995
00996 if (enabled)
00997 parsedOptionList->replace( opt, new QCString("t") );
00998 else
00999 parsedOptionList->replace( opt, new QCString("f") );
01000 }
01001
01002 void
01003 KCmdLineArgs::setOption(const QCString &opt, const char *value)
01004 {
01005 if (isQt)
01006 {
01007
01008 QCString arg = "-";
01009 arg += opt;
01010 addArgument(arg);
01011 addArgument(value);
01012
01013
01014 if (arg == "-display")
01015 {
01016 setenv(DISPLAY, value, true);
01017 }
01018 }
01019 if (!parsedOptionList) {
01020 parsedOptionList = new KCmdLineParsedOptions;
01021 parsedOptionList->setAutoDelete(true);
01022 }
01023
01024 parsedOptionList->insert( opt, new QCString(value) );
01025 }
01026
01027 QCString
01028 KCmdLineArgs::getOption(const char *_opt) const
01029 {
01030 QCString *value = 0;
01031 if (parsedOptionList)
01032 {
01033 value = parsedOptionList->find(_opt);
01034 }
01035
01036 if (value)
01037 return (*value);
01038
01039
01040 const char *opt_name;
01041 const char *def;
01042 bool dummy = true;
01043 QCString opt = _opt;
01044 int result = ::findOption( options, opt, opt_name, def, dummy) & ~4;
01045
01046 if (result != 3)
01047 {
01048 fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
01049 fprintf(stderr, "Application requests for getOption(\"%s\") but the \"%s\" option\n",
01050 _opt, _opt);
01051 fprintf(stderr, "has never been specified via addCmdLineOptions( ... )\n\n");
01052
01053 assert( 0 );
01054 exit(255);
01055 }
01056 return QCString(def);
01057 }
01058
01059 QCStringList
01060 KCmdLineArgs::getOptionList(const char *_opt) const
01061 {
01062 QCStringList result;
01063 if (!parsedOptionList)
01064 return result;
01065
01066 while(true)
01067 {
01068 QCString *value = parsedOptionList->take(_opt);
01069 if (!value)
01070 break;
01071 result.prepend(*value);
01072 delete value;
01073 }
01074
01075
01076
01077
01078
01079
01080 for(QCStringList::ConstIterator it=result.begin();
01081 it != result.end();
01082 ++it)
01083 {
01084 parsedOptionList->insert(_opt, new QCString(*it));
01085 }
01086 return result;
01087 }
01088
01089 bool
01090 KCmdLineArgs::isSet(const char *_opt) const
01091 {
01092
01093 const char *opt_name;
01094 const char *def;
01095 bool dummy = true;
01096 QCString opt = _opt;
01097 int result = ::findOption( options, opt, opt_name, def, dummy) & ~4;
01098
01099 if (result == 0)
01100 {
01101 fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
01102 fprintf(stderr, "Application requests for isSet(\"%s\") but the \"%s\" option\n",
01103 _opt, _opt);
01104 fprintf(stderr, "has never been specified via addCmdLineOptions( ... )\n\n");
01105
01106 assert( 0 );
01107 exit(255);
01108 }
01109
01110 QCString *value = 0;
01111 if (parsedOptionList)
01112 {
01113 value = parsedOptionList->find(opt);
01114 }
01115
01116 if (value)
01117 {
01118 if (result == 3)
01119 return true;
01120 else
01121 return ((*value)[0] == 't');
01122 }
01123
01124 if (result == 3)
01125 return false;
01126
01127
01128
01129 return (result == 2);
01130 }
01131
01132 int
01133 KCmdLineArgs::count() const
01134 {
01135 if (!parsedArgList)
01136 return 0;
01137 return parsedArgList->count();
01138 }
01139
01140 const char *
01141 KCmdLineArgs::arg(int n) const
01142 {
01143 if (!parsedArgList || (n >= (int) parsedArgList->count()))
01144 {
01145 fprintf(stderr, "\n\nFAILURE (KCmdLineArgs): Argument out of bounds\n");
01146 fprintf(stderr, "Application requests for arg(%d) without checking count() first.\n",
01147 n);
01148
01149 assert( 0 );
01150 exit(255);
01151 }
01152
01153 return parsedArgList->at(n);
01154 }
01155
01156 KURL
01157 KCmdLineArgs::url(int n) const
01158 {
01159 return makeURL( arg(n) );
01160 }
01161
01162 KURL KCmdLineArgs::makeURL( const char *urlArg )
01163 {
01164 if (*urlArg == '/')
01165 {
01166 KURL result;
01167 result.setPath(QFile::decodeName( urlArg));
01168 return result;
01169 }
01170
01171 if ( !KURL::isRelativeURL( QString::fromLocal8Bit(urlArg) ) )
01172 return KURL(QString::fromLocal8Bit(urlArg));
01173
01174 KURL result;
01175 result.setPath( cwd()+"/"+QFile::decodeName( urlArg ));
01176 result.cleanPath();
01177 return result;
01178 }
01179
01180 void
01181 KCmdLineArgs::addArgument(const char *argument)
01182 {
01183 if (!parsedArgList)
01184 parsedArgList = new KCmdLineParsedArgs;
01185
01186 parsedArgList->append(argument);
01187 }