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