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