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 }