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