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 #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
00066
00067
00068
00069
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
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
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;
00223
00224 if (id && args->id && (::qstrcmp(id, args->id) == 0))
00225 return;
00226
00227 if (afterId && args->id && (::qstrcmp(afterId, args->id) == 0))
00228 pos = i+1;
00229 }
00230
00231 assert( parsed == false );
00232
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
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;
00267
00268
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
00347
00348
00349
00350
00351
00352
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
00454
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;
00470
00471 p++;
00472 if (result == 1)
00473 {
00474 args->setOption(singleCharOption, enabled);
00475 if (_opt[p])
00476 continue;
00477 else
00478 return;
00479 }
00480 else if (result == 3)
00481 {
00482 if (argument.isEmpty())
00483 {
00484 argument = _opt+p;
00485 }
00486 args->setOption(singleCharOption, (const char*)argument);
00487 return;
00488 }
00489 break;
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)
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
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();
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);
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();
00716
00717 static char** tqt_argv;
00718 if( tqt_argv != NULL )
00719 return &tqt_argv;
00720
00721 TDECmdLineArgs *args = parsedArgs("qt");
00722 assert(args);
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
00748 if (TDEGlobal::_locale)
00749 return;
00750
00751 if (!TDEGlobal::_instance) {
00752 TDEInstance *instance = new TDEInstance(about);
00753 (void) instance->config();
00754
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);
00778
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();
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
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
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
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
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
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
01097 TQCString arg = "-";
01098 arg += opt;
01099 addArgument(arg);
01100 addArgument(value);
01101
01102 #ifdef Q_WS_X11
01103
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
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
01167
01168
01169
01170
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
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;
01217
01218
01219
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()) {
01258 KURL result;
01259 result.setPath(urlArg);
01260 return result;
01261 }
01262
01263 if ( KURL::isRelativeURL(urlArg) || fileInfo.exists() ) {
01264 KURL result;
01265 result.setPath( cwd()+'/'+urlArg );
01266 result.cleanPath();
01267 return result;
01268 }
01269
01270 return KURL(urlArg);
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 }