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 if (!about->bugAddress().isEmpty())
00602 {
00603 QString bugReporting = i18n( "Please use http://bugs.kde.org to report bugs, do not mail the authors directly.\n" );
00604 if (about->bugAddress() != "submit@bugs.kde.org")
00605 bugReporting.replace("http://bugs.kde.org", about->bugAddress());
00606 printQ(bugReporting);
00607 }
00608 exit(0);
00609 } else {
00610 if ((option[0] == 'n') && (option[1] == 'o'))
00611 {
00612 option += 2;
00613 enabled = false;
00614 }
00615 findOption(orig, option, i, enabled, inOptions);
00616 }
00617 }
00618 else
00619 {
00620
00621 if (!allowArgs)
00622 {
00623 if (ignoreUnknown)
00624 continue;
00625 enable_i18n();
00626 usage( i18n("Unexpected argument '%1'.").arg( argv[i]));
00627 }
00628 else
00629 {
00630 appOptions->addArgument(argv[i]);
00631 if (everythingAfterArgIsArgs)
00632 inOptions = false;
00633 }
00634 }
00635 }
00636 parsed = true;
00637 }
00638
00644 int *
00645 KCmdLineArgs::qt_argc()
00646 {
00647 if (!argsList)
00648 KApplication::addCmdLineOptions();
00649
00650 KCmdLineArgs *args = parsedArgs("qt");
00651
00652 assert(args);
00653 if (!argv)
00654 {
00655 fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
00656 fprintf(stderr, "Application has not called KCmdLineArgs::init(...).\n\n");
00657
00658 assert( 0 );
00659 exit(255);
00660 }
00661
00662 assert(argc >= (args->count()+1));
00663 argc = args->count() +1;
00664 return &argc;
00665 }
00666
00672 char ***
00673 KCmdLineArgs::qt_argv()
00674 {
00675 if (!argsList)
00676 KApplication::addCmdLineOptions();
00677
00678 KCmdLineArgs *args = parsedArgs("qt");
00679 assert(args);
00680 if (!argv)
00681 {
00682 fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
00683 fprintf(stderr, "Application has not called KCmdLineArgs::init(...).\n\n");
00684
00685 assert( 0 );
00686 exit(255);
00687 }
00688
00689 int i = 0;
00690 for(; i < args->count(); i++)
00691 {
00692 argv[i+1] = (char *) args->arg(i);
00693 }
00694 argv[i+1] = 0;
00695
00696 return &argv;
00697 }
00698
00699 void
00700 KCmdLineArgs::enable_i18n()
00701 {
00702
00703 if (KGlobal::_locale)
00704 return;
00705
00706 if (!KGlobal::_instance) {
00707 KInstance *instance = new KInstance(about);
00708 (void) instance->config();
00709
00710 }
00711 }
00712
00713 void
00714 KCmdLineArgs::usage(const QString &error)
00715 {
00716 assert(KGlobal::_locale);
00717 QCString localError = error.local8Bit();
00718 if (localError[error.length()-1] == '\n')
00719 localError = localError.left(error.length()-1);
00720 fprintf(stderr, "%s: %s\n", argv[0], localError.data());
00721
00722 QString tmp = i18n("Use --help to get a list of available command line options.");
00723 localError = tmp.local8Bit();
00724 fprintf(stderr, "%s: %s\n", argv[0], localError.data());
00725 exit(254);
00726 }
00727
00728 void
00729 KCmdLineArgs::usage(const char *id)
00730 {
00731 enable_i18n();
00732 assert(argsList != 0);
00733
00734
00735 QString optionFormatString = " %1 %2\n";
00736 QString optionFormatStringDef = " %1 %2 [%3]\n";
00737 QString optionHeaderString = i18n("\n%1:\n");
00738 QString tmp;
00739 QString usage;
00740
00741 KCmdLineArgs *args = argsList->last();
00742
00743 if (!(args->id) && (args->options) &&
00744 (args->options->name) && (args->options->name[0] != '+'))
00745 {
00746 usage = i18n("[options] ")+usage;
00747 }
00748
00749 while(args)
00750 {
00751 if (args->name)
00752 {
00753 usage = QString(i18n("[%1-options]")).arg(args->name)+" "+usage;
00754 }
00755 args = argsList->prev();
00756 }
00757
00758 KCmdLineArgs *appOptions = argsList->last();
00759 if (!appOptions->id)
00760 {
00761 const KCmdLineOptions *option = appOptions->options;
00762 while(option && option->name)
00763 {
00764 if (option->name[0] == '+')
00765 usage = usage + (option->name+1) + " ";
00766 else if ( option->name[0] == '!' && option->name[1] == '+' )
00767 usage = usage + (option->name+2) + " ";
00768
00769 option++;
00770 }
00771 }
00772
00773 printQ(i18n("Usage: %1 %2\n").arg(argv[0]).arg(usage));
00774 printQ("\n"+about->shortDescription()+"\n");
00775
00776 printQ(optionHeaderString.arg(i18n("Generic options")));
00777 printQ(optionFormatString.arg("--help", -25).arg(i18n("Show help about options")));
00778
00779 args = argsList->first();
00780 while(args)
00781 {
00782 if (args->name && args->id)
00783 {
00784 QString option = QString("--help-%1").arg(args->id);
00785 QString desc = i18n("Show %1 specific options").arg(args->name);
00786
00787 printQ(optionFormatString.arg(option, -25).arg(desc));
00788 }
00789 args = argsList->next();
00790 }
00791
00792 printQ(optionFormatString.arg("--help-all",-25).arg(i18n("Show all options")));
00793 printQ(optionFormatString.arg("--author",-25).arg(i18n("Show author information")));
00794 printQ(optionFormatString.arg("-v, --version",-25).arg(i18n("Show version information")));
00795 printQ(optionFormatString.arg("--license",-25).arg(i18n("Show license information")));
00796 printQ(optionFormatString.arg("--", -25).arg(i18n("End of options")));
00797
00798 args = argsList->first();
00799
00800 bool showAll = id && (::qstrcmp(id, "all") == 0);
00801
00802 if (!showAll)
00803 {
00804 while(args)
00805 {
00806 if (!id && !args->id) break;
00807 if (id && (::qstrcmp(args->id, id) == 0)) break;
00808 args = argsList->next();
00809 }
00810 }
00811
00812 while(args)
00813 {
00814 bool hasArgs = false;
00815 bool hasOptions = false;
00816 while (args)
00817 {
00818 const KCmdLineOptions *option = args->options;
00819 QCString opt = "";
00820
00821 while(option && option->name)
00822 {
00823 QString description;
00824 QString descriptionRest;
00825 QStringList dl;
00826 if (option->description)
00827 {
00828 description = i18n(option->description);
00829 dl = QStringList::split("\n", description, true);
00830 description = dl.first();
00831 dl.remove( dl.begin() );
00832 }
00833 QCString name = option->name;
00834 if (name[0] == '!')
00835 name = name.mid(1);
00836
00837 if (name[0] == '+')
00838 {
00839 if (!hasArgs)
00840 {
00841 printQ(i18n("\nArguments:\n"));
00842 hasArgs = true;
00843 }
00844
00845 name = name.mid(1);
00846 if ((name[0] == '[') && (name[name.length()-1] == ']'))
00847 name = name.mid(1, name.length()-2);
00848 printQ(optionFormatString.arg(name, -25)
00849 .arg(description));
00850 }
00851 else
00852 {
00853 if (!hasOptions)
00854 {
00855 if (!args->name)
00856 printQ(i18n("\nOptions:\n"));
00857 else if (args->name)
00858 printQ(optionHeaderString.arg(i18n("%1 options").arg(QString::fromLatin1(args->name))));
00859 hasOptions = true;
00860 }
00861
00862 if ((name.length() == 1) || (name[1] == ' '))
00863 name = "-"+name;
00864 else
00865 name = "--"+name;
00866 if (!option->description)
00867 {
00868 opt = name + ", ";
00869 }
00870 else
00871 {
00872 opt = opt + name;
00873 if (!option->def)
00874 {
00875 printQ(optionFormatString.arg(opt, -25)
00876 .arg(description));
00877 }
00878 else
00879 {
00880 printQ(optionFormatStringDef.arg(opt, -25)
00881 .arg(description).arg(option->def));
00882 }
00883 opt = "";
00884 }
00885 }
00886 for(QStringList::Iterator it = dl.begin();
00887 it != dl.end();
00888 it++)
00889 {
00890 printQ(optionFormatString.arg("", -25).arg(*it));
00891 }
00892
00893 option++;
00894 }
00895 args = argsList->next();
00896 if (!args || args->name || !args->id) break;
00897 }
00898 if (!showAll) break;
00899 }
00900
00901 exit(254);
00902 }
00903
00904
00905
00906
00907
00913 KCmdLineArgs::KCmdLineArgs( const KCmdLineOptions *_options,
00914 const char *_name, const char *_id)
00915 : options(_options), name(_name), id(_id)
00916 {
00917 parsedOptionList = 0;
00918 parsedArgList = 0;
00919 isQt = (::qstrcmp(id, "qt") == 0);
00920 }
00921
00925 KCmdLineArgs::~KCmdLineArgs()
00926 {
00927 delete parsedOptionList;
00928 delete parsedArgList;
00929 if (argsList)
00930 {
00931 argsList->removeRef(this);
00932 if (argsList->count() == 0)
00933 {
00934 delete argsList;
00935 argsList = 0;
00936 }
00937 }
00938 }
00939
00940 void
00941 KCmdLineArgs::clear()
00942 {
00943 delete parsedArgList;
00944 parsedArgList = 0;
00945 delete parsedOptionList;
00946 parsedOptionList = 0;
00947 }
00948
00949 void
00950 KCmdLineArgs::save( QDataStream &ds) const
00951 {
00952 uint count = 0;
00953 if (parsedOptionList)
00954 parsedOptionList->save( ds );
00955 else
00956 ds << count;
00957
00958 if (parsedArgList)
00959 parsedArgList->save( ds );
00960 else
00961 ds << count;
00962 }
00963
00964 void
00965 KCmdLineArgs::load( QDataStream &ds)
00966 {
00967 if (!parsedOptionList) parsedOptionList = new KCmdLineParsedOptions;
00968 if (!parsedArgList) parsedArgList = new KCmdLineParsedArgs;
00969
00970 parsedOptionList->load( ds );
00971 parsedArgList->load( ds );
00972
00973 if (parsedOptionList->count() == 0)
00974 {
00975 delete parsedOptionList;
00976 parsedOptionList = 0;
00977 }
00978 if (parsedArgList->count() == 0)
00979 {
00980 delete parsedArgList;
00981 parsedArgList = 0;
00982 }
00983 }
00984
00985 void
00986 KCmdLineArgs::setOption(const QCString &opt, bool enabled)
00987 {
00988 if (isQt)
00989 {
00990
00991 QCString arg = "-";
00992 if( !enabled )
00993 arg += "no";
00994 arg += opt;
00995 addArgument(arg);
00996 }
00997 if (!parsedOptionList) {
00998 parsedOptionList = new KCmdLineParsedOptions;
00999 parsedOptionList->setAutoDelete(true);
01000 }
01001
01002 if (enabled)
01003 parsedOptionList->replace( opt, new QCString("t") );
01004 else
01005 parsedOptionList->replace( opt, new QCString("f") );
01006 }
01007
01008 void
01009 KCmdLineArgs::setOption(const QCString &opt, const char *value)
01010 {
01011 if (isQt)
01012 {
01013
01014 QCString arg = "-";
01015 arg += opt;
01016 addArgument(arg);
01017 addArgument(value);
01018
01019
01020 if (arg == "-display")
01021 {
01022 setenv(DISPLAY, value, true);
01023 }
01024 }
01025 if (!parsedOptionList) {
01026 parsedOptionList = new KCmdLineParsedOptions;
01027 parsedOptionList->setAutoDelete(true);
01028 }
01029
01030 parsedOptionList->insert( opt, new QCString(value) );
01031 }
01032
01033 QCString
01034 KCmdLineArgs::getOption(const char *_opt) const
01035 {
01036 QCString *value = 0;
01037 if (parsedOptionList)
01038 {
01039 value = parsedOptionList->find(_opt);
01040 }
01041
01042 if (value)
01043 return (*value);
01044
01045
01046 const char *opt_name;
01047 const char *def;
01048 bool dummy = true;
01049 QCString opt = _opt;
01050 int result = ::findOption( options, opt, opt_name, def, dummy) & ~4;
01051
01052 if (result != 3)
01053 {
01054 fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
01055 fprintf(stderr, "Application requests for getOption(\"%s\") but the \"%s\" option\n",
01056 _opt, _opt);
01057 fprintf(stderr, "has never been specified via addCmdLineOptions( ... )\n\n");
01058
01059 assert( 0 );
01060 exit(255);
01061 }
01062 return QCString(def);
01063 }
01064
01065 QCStringList
01066 KCmdLineArgs::getOptionList(const char *_opt) const
01067 {
01068 QCStringList result;
01069 if (!parsedOptionList)
01070 return result;
01071
01072 while(true)
01073 {
01074 QCString *value = parsedOptionList->take(_opt);
01075 if (!value)
01076 break;
01077 result.prepend(*value);
01078 delete value;
01079 }
01080
01081
01082
01083
01084
01085
01086 for(QCStringList::ConstIterator it=result.begin();
01087 it != result.end();
01088 ++it)
01089 {
01090 parsedOptionList->insert(_opt, new QCString(*it));
01091 }
01092 return result;
01093 }
01094
01095 bool
01096 KCmdLineArgs::isSet(const char *_opt) const
01097 {
01098
01099 const char *opt_name;
01100 const char *def;
01101 bool dummy = true;
01102 QCString opt = _opt;
01103 int result = ::findOption( options, opt, opt_name, def, dummy) & ~4;
01104
01105 if (result == 0)
01106 {
01107 fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n");
01108 fprintf(stderr, "Application requests for isSet(\"%s\") but the \"%s\" option\n",
01109 _opt, _opt);
01110 fprintf(stderr, "has never been specified via addCmdLineOptions( ... )\n\n");
01111
01112 assert( 0 );
01113 exit(255);
01114 }
01115
01116 QCString *value = 0;
01117 if (parsedOptionList)
01118 {
01119 value = parsedOptionList->find(opt);
01120 }
01121
01122 if (value)
01123 {
01124 if (result == 3)
01125 return true;
01126 else
01127 return ((*value)[0] == 't');
01128 }
01129
01130 if (result == 3)
01131 return false;
01132
01133
01134
01135 return (result == 2);
01136 }
01137
01138 int
01139 KCmdLineArgs::count() const
01140 {
01141 if (!parsedArgList)
01142 return 0;
01143 return parsedArgList->count();
01144 }
01145
01146 const char *
01147 KCmdLineArgs::arg(int n) const
01148 {
01149 if (!parsedArgList || (n >= (int) parsedArgList->count()))
01150 {
01151 fprintf(stderr, "\n\nFAILURE (KCmdLineArgs): Argument out of bounds\n");
01152 fprintf(stderr, "Application requests for arg(%d) without checking count() first.\n",
01153 n);
01154
01155 assert( 0 );
01156 exit(255);
01157 }
01158
01159 return parsedArgList->at(n);
01160 }
01161
01162 KURL
01163 KCmdLineArgs::url(int n) const
01164 {
01165 return makeURL( arg(n) );
01166 }
01167
01168 KURL KCmdLineArgs::makeURL( const char *urlArg )
01169 {
01170 if (*urlArg == '/')
01171 {
01172 KURL result;
01173 result.setPath(QFile::decodeName( urlArg));
01174 return result;
01175 }
01176
01177 if ( !KURL::isRelativeURL( QString::fromLocal8Bit(urlArg) ) )
01178 return KURL(QString::fromLocal8Bit(urlArg));
01179
01180 KURL result;
01181 result.setPath( cwd()+"/"+QFile::decodeName( urlArg ));
01182 result.cleanPath();
01183 return result;
01184 }
01185
01186 void
01187 KCmdLineArgs::addArgument(const char *argument)
01188 {
01189 if (!parsedArgList)
01190 parsedArgList = new KCmdLineParsedArgs;
01191
01192 parsedArgList->append(argument);
01193 }