21 #include <sys/param.h>
35 #include <tqasciidict.h>
36 #include <tqstrlist.h>
38 #include "tdecmdlineargs.h"
39 #include <tdeaboutdata.h>
41 #include <tdeapplication.h>
42 #include <tdeglobal.h>
43 #include <kstringhandler.h>
44 #include <kstaticdeleter.h>
47 #define DISPLAY "DISPLAY"
48 #elif defined(TQ_WS_QWS)
49 #define DISPLAY "QWS_DISPLAY"
53 #include <win32_utils.h>
56 template class TQAsciiDict<TQCString>;
57 template class TQPtrList<TDECmdLineArgs>;
59 class TDECmdLineParsedOptions :
public TQAsciiDict<TQCString>
62 TDECmdLineParsedOptions()
63 : TQAsciiDict<TQCString>( 7 ) { }
70 TQDataStream&
save( TQDataStream &s)
const
71 {
return TQGDict::write(s); }
73 TQDataStream& load( TQDataStream &s)
74 {
return TQGDict::read(s); }
77 virtual TQDataStream& write( TQDataStream &s, TQPtrCollection::Item data)
const
79 TQCString *str = (TQCString *) data;
84 virtual TQDataStream& read( TQDataStream &s, TQPtrCollection::Item &item)
86 TQCString *str =
new TQCString;
94 class TDECmdLineParsedArgs :
public TQStrList
97 TDECmdLineParsedArgs()
98 : TQStrList( true ) { }
99 TQDataStream&
save( TQDataStream &s)
const
100 {
return TQGList::write(s); }
102 TQDataStream& load( TQDataStream &s)
103 {
return TQGList::read(s); }
107 class TDECmdLineArgsList:
public TQPtrList<TDECmdLineArgs>
110 TDECmdLineArgsList() { }
113 TDECmdLineArgsList *TDECmdLineArgs::argsList = 0;
114 int TDECmdLineArgs::argc = 0;
115 char **TDECmdLineArgs::argv = 0;
116 char *TDECmdLineArgs::mCwd = 0;
119 bool TDECmdLineArgs::parsed =
false;
120 bool TDECmdLineArgs::ignoreUnknown =
false;
128 const char *_description,
const char *_version,
bool noKApp)
131 new TDEAboutData(_appname, programName, _version, _description),
137 const char *_description,
const char *_version,
bool noKApp)
140 new TDEAboutData(_appname, _appname, _version, _description),
145 TDECmdLineArgs::initIgnore(
int _argc,
char **_argv,
const char *_appname )
148 new TDEAboutData(_appname, _appname,
"unknown",
"TDE Application",
false));
149 ignoreUnknown =
true;
155 char **_argv = (
char **) malloc(
sizeof(
char *));
156 _argv[0] = (
char *) ab->
appName();
157 init(1,_argv,ab,
true);
169 fprintf(stderr,
"\n\nFAILURE (TDECmdLineArgs):\n");
170 fprintf(stderr,
"Passing null-pointer to 'argv' is not allowed.\n\n");
178 char *p = strrchr( argv[0],
'/');
185 mCwd = mCwdd.setObject(mCwd,
new char [PATH_MAX+1],
true);
186 (void) getcwd(mCwd, PATH_MAX);
188 win32_slashify(mCwd, PATH_MAX);
196 return TQFile::decodeName(TQCString(mCwd));
207 const char *
id,
const char *afterId)
210 argsList =
new TDECmdLineArgsList();
212 int pos = argsList->count();
214 if (pos &&
id && argsList->last() && !argsList->last()->name)
219 for(args = argsList->first(); args; args = argsList->next(), i++)
221 if (!
id && !args->id)
224 if (
id && args->id && (::qstrcmp(
id, args->id) == 0))
227 if (afterId && args->id && (::qstrcmp(afterId, args->id) == 0))
231 assert( parsed ==
false );
234 argsList->insert(pos, args);
238 TDECmdLineArgs::saveAppArgs( TQDataStream &ds)
247 TQCString qCwd = mCwd;
250 uint
count = argsList ? argsList->count() : 0;
256 for(args = argsList->first(); args; args = argsList->next())
258 ds << TQCString(args->id);
274 for(args = argsList->first(); args; args = argsList->next())
287 mCwd = mCwdd.setObject(mCwd,
new char[qCwd.length()+1],
true);
288 strncpy(mCwd, qCwd.data(), qCwd.length()+1);
298 for(args = argsList->first(); args; args = argsList->next())
315 if ((
id && ::qstrcmp(args->id,
id) == 0) || (!
id && !args->id))
321 args = argsList->next();
327 void TDECmdLineArgs::removeArgs(
const char *
id)
332 if (args->id &&
id && ::qstrcmp(args->id,
id) == 0)
338 args = argsList->next();
356 const char *&opt_name,
const char *&def,
bool &enabled)
360 int len = opt.length();
361 while(options && options->
name)
365 opt_name = options->
name;
366 if ((opt_name[0] ==
':') || (opt_name[0] == 0))
372 if (opt_name[0] ==
'!')
377 if ((opt_name[0] ==
'n') && (opt_name[1] ==
'o'))
382 if (strncmp(opt.data(), opt_name, len) == 0)
395 TQCString nextOption = options->
name;
396 int p = nextOption.find(
' ');
398 nextOption = nextOption.left(p);
399 if (nextOption[0] ==
'!')
400 nextOption = nextOption.mid(1);
401 if (strncmp(nextOption.data(),
"no", 2) == 0)
403 nextOption = nextOption.mid(2);
406 result = findOption(options, nextOption, opt_name, def, enabled);
414 if (opt_name[0] ==
' ')
429 TDECmdLineArgs::findOption(
const char *_opt, TQCString opt,
int &i,
bool _enabled,
bool &moreOptions)
432 const char *opt_name;
435 int j = opt.find(
'=');
438 argument = opt.mid(j+1);
447 result = ::findOption(args->options, opt, opt_name, def, enabled);
449 args = argsList->next();
451 if (!args && (_opt[0] ==
'-') && _opt[1] && (_opt[1] !=
'-'))
458 TQCString singleCharOption =
" ";
459 singleCharOption[0] = _opt[p];
460 args = argsList->first();
464 result = ::findOption(args->options, singleCharOption, opt_name, def, enabled);
466 args = argsList->next();
474 args->setOption(singleCharOption, enabled);
480 else if (result == 3)
482 if (argument.isEmpty())
486 args->setOption(singleCharOption, (
const char*)argument);
495 if (!args || !result)
500 usage( i18n(
"Unknown option '%1'.").
arg(TQString::fromLocal8Bit(_opt)));
503 if ((result & 4) != 0)
516 usage( i18n(
"Unknown option '%1'.").
arg(TQString::fromLocal8Bit(_opt)));
518 if (argument.isEmpty())
524 usage( i18n(
"'%1' missing.").
arg( opt_name));
528 args->setOption(opt, (
const char*)argument);
532 args->setOption(opt, enabled);
537 TDECmdLineArgs::printQ(
const TQString &msg)
539 TQCString localMsg = msg.local8Bit();
540 fprintf(stdout,
"%s", localMsg.data());
544 TDECmdLineArgs::parseAllArgs()
546 bool allowArgs =
false;
547 bool inOptions =
true;
548 bool everythingAfterArgIsArgs =
false;
553 while(option && option->
name)
555 if (option->
name[0] ==
'+')
557 if ( option->
name[0] ==
'!' && option->
name[1] ==
'+' )
560 everythingAfterArgIsArgs =
true;
565 for(
int i = 1; i < argc; i++)
570 if ((argv[i][0] ==
'-') && argv[i][1] && inOptions)
573 const char *option = &argv[i][1];
574 const char *orig = argv[i];
575 if (option[0] ==
'-')
585 if (::qstrcmp(option,
"help") == 0)
589 else if (strncmp(option,
"help-",5) == 0)
593 else if ( (::qstrcmp(option,
"version") == 0) ||
594 (::qstrcmp(option,
"v") == 0))
596 printQ( TQString(
"Qt: %1\n").
arg(tqVersion()));
597 printQ( TQString(
"TDE: %1\n").
arg(TDE_VERSION_STRING));
598 printQ( TQString(
"%1: %2\n").
601 }
else if ( (::qstrcmp(option,
"license") == 0) )
607 }
else if ( ::qstrcmp( option,
"author") == 0 ) {
610 const TQValueList<TDEAboutPerson> authors = about->
authors();
611 if ( !authors.isEmpty() ) {
613 for (TQValueList<TDEAboutPerson>::ConstIterator it = authors.begin(); it != authors.end(); ++it ) {
615 if ( !(*it).emailAddress().isEmpty() )
616 email =
" <" + (*it).emailAddress() +
">";
617 authorlist += TQString(
" ") + (*it).name() + email +
"\n";
619 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 ) );
622 printQ( i18n(
"This application was written by somebody who wants to remain anonymous.") );
629 || about->
bugAddress() ==
"submit@bugs.trinitydesktop.org"
630 || about->
bugAddress() ==
"http://bugs.trinitydesktop.org" )
631 printQ( i18n(
"Please use http://bugs.trinitydesktop.org to report bugs.\n" ) );
634 printQ( i18n(
"Please report bugs to %1.\n" ).
arg( about->
authors().first().emailAddress() ) );
636 printQ( i18n(
"Please report bugs to %1.\n" ).
arg(about->
bugAddress()) );
646 if ((option[0] ==
'n') && (option[1] ==
'o'))
651 findOption(orig, option, i, enabled, inOptions);
662 usage( i18n(
"Unexpected argument '%1'.").
arg(TQString::fromLocal8Bit(argv[i])));
666 appOptions->addArgument(argv[i]);
667 if (everythingAfterArgIsArgs)
681 TDECmdLineArgs::tqt_argc()
686 static int tqt_argc = -1;
694 fprintf(stderr,
"\n\nFAILURE (TDECmdLineArgs):\n");
695 fprintf(stderr,
"Application has not called TDECmdLineArgs::init(...).\n\n");
701 assert(argc >= (args->
count()+1));
702 tqt_argc = args->
count() +1;
712 TDECmdLineArgs::tqt_argv()
717 static char** tqt_argv;
718 if( tqt_argv != NULL )
725 fprintf(stderr,
"\n\nFAILURE (TDECmdLineArgs):\n");
726 fprintf(stderr,
"Application has not called TDECmdLineArgs::init(...).\n\n");
732 tqt_argv =
new char*[ args->
count() + 2 ];
733 tqt_argv[ 0 ] = tqstrdup(
appName());
735 for(; i < args->
count(); i++)
737 tqt_argv[i+1] = tqstrdup((
char *) args->
arg(i));
748 if (TDEGlobal::_locale)
751 if (!TDEGlobal::_instance) {
753 (void) instance->
config();
761 assert(TDEGlobal::_locale);
762 TQCString localError = error.local8Bit();
763 if (localError[error.length()-1] ==
'\n')
764 localError = localError.left(error.length()-1);
765 fprintf(stderr,
"%s: %s\n", argv[0], localError.data());
767 TQString tmp = i18n(
"Use --help to get a list of available command line options.");
768 localError = tmp.local8Bit();
769 fprintf(stderr,
"%s: %s\n", argv[0], localError.data());
777 assert(argsList != 0);
780 TQString optionFormatString =
" %1 %2\n";
781 TQString optionFormatStringDef =
" %1 %2 [%3]\n";
782 TQString optionHeaderString = i18n(
"\n%1:\n");
788 if (!(args->id) && (args->options) &&
789 (args->options->
name) && (args->options->
name[0] !=
'+'))
798 usage = i18n(
"[%1-options]").arg(args->name)+
" "+
usage;
800 args = argsList->prev();
807 while(option && option->
name)
809 if (option->
name[0] ==
'+')
811 else if ( option->
name[0] ==
'!' && option->
name[1] ==
'+' )
818 printQ(i18n(
"Usage: %1 %2\n").
arg(argv[0]).
arg(
usage));
821 printQ(optionHeaderString.arg(i18n(
"Generic options")));
822 printQ(optionFormatString.arg(
"--help", -25).arg(i18n(
"Show help about options")));
824 args = argsList->first();
827 if (args->name && args->id)
829 TQString option = TQString(
"--help-%1").arg(args->id);
830 TQString desc = i18n(
"Show %1 specific options").arg(args->name);
832 printQ(optionFormatString.arg(option, -25).arg(desc));
834 args = argsList->next();
837 printQ(optionFormatString.arg(
"--help-all",-25).arg(i18n(
"Show all options")));
838 printQ(optionFormatString.arg(
"--author",-25).arg(i18n(
"Show author information")));
839 printQ(optionFormatString.arg(
"-v, --version",-25).arg(i18n(
"Show version information")));
840 printQ(optionFormatString.arg(
"--license",-25).arg(i18n(
"Show license information")));
841 printQ(optionFormatString.arg(
"--", -25).arg(i18n(
"End of options")));
843 args = argsList->first();
845 bool showAll =
id && (::qstrcmp(
id,
"all") == 0);
851 if (!
id && !args->id)
break;
852 if (
id && (::qstrcmp(args->id,
id) == 0))
break;
853 args = argsList->next();
859 bool hasArgs =
false;
860 bool hasOptions =
false;
861 TQString optionsHeader;
863 optionsHeader = optionHeaderString.arg(i18n(
"%1 options").arg(TQString::fromLatin1(args->name)));
865 optionsHeader = i18n(
"\nOptions:\n");
872 while(option && option->
name)
874 TQString description;
875 TQString descriptionRest;
879 if (option->
name[0] ==
':')
884 if (!optionsHeader.endsWith(
"\n"))
885 optionsHeader.append(
"\n");
893 if (option->
name[0] == 0)
898 if (!tmp.endsWith(
"\n"))
910 dl = TQStringList::split(
"\n", description,
true);
911 description = dl.first();
912 dl.remove( dl.begin() );
914 TQCString name = option->
name;
922 printQ(i18n(
"\nArguments:\n"));
927 if ((name[0] ==
'[') && (name[name.length()-1] ==
']'))
928 name = name.mid(1, name.length()-2);
929 printQ(optionFormatString.arg(TQString(name), -25)
936 printQ(optionsHeader);
940 if ((name.length() == 1) || (name[1] ==
' '))
953 printQ(optionFormatString.arg(TQString(opt), -25)
958 printQ(optionFormatStringDef.arg(TQString(opt), -25)
964 for(TQStringList::Iterator it = dl.begin();
968 printQ(optionFormatString.arg(
"", -25).arg(*it));
973 args = argsList->next();
974 if (!args || args->name || !args->id)
break;
992 const char *_name,
const char *_id)
993 : options(_options), name(_name), id(_id)
995 parsedOptionList = 0;
997 isQt = (::qstrcmp(
id,
"qt") == 0);
1005 delete parsedOptionList;
1006 delete parsedArgList;
1008 argsList->removeRef(
this);
1014 delete parsedArgList;
1016 delete parsedOptionList;
1017 parsedOptionList = 0;
1024 argsList->setAutoDelete(
true );
1033 TDECmdLineArgs::save( TQDataStream &ds)
const
1036 if (parsedOptionList)
1037 parsedOptionList->save( ds );
1042 parsedArgList->save( ds );
1048 TDECmdLineArgs::load( TQDataStream &ds)
1050 if (!parsedOptionList) parsedOptionList =
new TDECmdLineParsedOptions;
1051 if (!parsedArgList) parsedArgList =
new TDECmdLineParsedArgs;
1053 parsedOptionList->load( ds );
1054 parsedArgList->load( ds );
1056 if (parsedOptionList->count() == 0)
1058 delete parsedOptionList;
1059 parsedOptionList = 0;
1061 if (parsedArgList->count() == 0)
1063 delete parsedArgList;
1069 TDECmdLineArgs::setOption(
const TQCString &opt,
bool enabled)
1074 TQCString
arg =
"-";
1080 if (!parsedOptionList) {
1081 parsedOptionList =
new TDECmdLineParsedOptions;
1082 parsedOptionList->setAutoDelete(
true);
1086 parsedOptionList->replace( opt,
new TQCString(
"t") );
1088 parsedOptionList->replace( opt,
new TQCString(
"f") );
1092 TDECmdLineArgs::setOption(
const TQCString &opt,
const char *value)
1097 TQCString
arg =
"-";
1104 if (
arg ==
"-display")
1106 setenv(DISPLAY, value,
true);
1110 if (!parsedOptionList) {
1111 parsedOptionList =
new TDECmdLineParsedOptions;
1112 parsedOptionList->setAutoDelete(
true);
1115 parsedOptionList->insert( opt,
new TQCString(value) );
1121 TQCString *value = 0;
1122 if (parsedOptionList)
1124 value = parsedOptionList->find(_opt);
1131 const char *opt_name;
1134 TQCString opt = _opt;
1135 int result = ::findOption( options, opt, opt_name, def, dummy) & ~4;
1139 fprintf(stderr,
"\n\nFAILURE (TDECmdLineArgs):\n");
1140 fprintf(stderr,
"Application requests for getOption(\"%s\") but the \"%s\" option\n",
1142 fprintf(stderr,
"has never been specified via addCmdLineOptions( ... )\n\n");
1147 return TQCString(def);
1153 QCStringList result;
1154 if (!parsedOptionList)
1159 TQCString *value = parsedOptionList->take(_opt);
1162 result.prepend(*value);
1171 for(QCStringList::ConstIterator it=result.begin();
1175 parsedOptionList->insert(_opt,
new TQCString(*it));
1184 const char *opt_name;
1187 TQCString opt = _opt;
1188 int result = ::findOption( options, opt, opt_name, def, dummy) & ~4;
1192 fprintf(stderr,
"\n\nFAILURE (TDECmdLineArgs):\n");
1193 fprintf(stderr,
"Application requests for isSet(\"%s\") but the \"%s\" option\n",
1195 fprintf(stderr,
"has never been specified via addCmdLineOptions( ... )\n\n");
1201 TQCString *value = 0;
1202 if (parsedOptionList)
1204 value = parsedOptionList->find(opt);
1212 return ((*value)[0] ==
't');
1220 return (result == 2);
1228 return parsedArgList->count();
1234 if (!parsedArgList || (n >= (
int) parsedArgList->count()))
1236 fprintf(stderr,
"\n\nFAILURE (TDECmdLineArgs): Argument out of bounds\n");
1237 fprintf(stderr,
"Application requests for arg(%d) without checking count() first.\n",
1244 return parsedArgList->at(n);
1255 const TQString urlArg = TQFile::decodeName(_urlArg);
1256 TQFileInfo fileInfo(urlArg);
1257 if (!fileInfo.isRelative()) {
1270 return KURL(urlArg);
1274 TDECmdLineArgs::addArgument(
const char *argument)
1277 parsedArgList =
new TDECmdLineParsedArgs;
1279 parsedArgList->append(argument);
1284 {
"tempfile",
I18N_NOOP(
"The files/URLs opened by the application will be deleted after use"), 0},
1285 TDECmdLineLastOption
1298 return args->
isSet(
"tempfile" );
Little helper class to clean up static objects that are held as pointer.
Represents and parses a URL.
static bool isRelativeURL(const TQString &_url)
Tests if a given URL is a relative as opposed to an absolute URL.
void setPath(const TQString &path)
Sets the decoded path of the URL.
void cleanPath(bool cleanDirSeparator=true)
Resolves "." and ".." components in path.
This class is used to store information about a program.
const TQValueList< TDEAboutPerson > authors() const
Returns a list of authors.
TQString shortDescription() const
Returns a short, translated description.
TQString license() const
Returns the license.
TQString customAuthorPlainText() const
Returns the plain text displayed around the list of authors instead of the default message telling us...
TQString bugAddress() const
Returns the email address for bugs.
TQString version() const
Returns the program's version.
const char * appName() const
Returns the application's internal name.
TQString programName() const
Returns the translated program name.
bool customAuthorTextEnabled() const
Returns whether custom text should be displayed around the list of authors.
static void addCmdLineOptions()
Add Qt and KDE command line options to TDECmdLineArgs.
A class for command-line argument handling.
bool isSet(const char *option) const
Read out a boolean option or check for the presence of string option.
static void enable_i18n()
Enable i18n to be able to print a translated error message.
static const char * appName()
Get the appname according to argv[0].
QCStringList getOptionList(const char *option) const
Read out all occurrences of a string option.
static bool isTempFileSet()
static TDECmdLineArgs * parsedArgs(const char *id=0)
Access parsed arguments.
void clear()
Clear all options and arguments.
static KURL makeURL(const char *urlArg)
Used by url().
static void addCmdLineOptions(const TDECmdLineOptions *options, const char *name=0, const char *id=0, const char *afterId=0)
Add options to your application.
KURL url(int n) const
Read out an argument representing a URL.
static void loadAppArgs(TQDataStream &)
Load arguments from a stream.
TQCString getOption(const char *option) const
Read out a string option.
static void addTempFileOption()
Add standard option –tempfile.
static void reset()
Reset all option definitions, i.e.
TDECmdLineArgs(const TDECmdLineOptions *_options, const char *_name, const char *_id)
Constructor.
const char * arg(int n) const
Read out an argument.
int count() const
Read the number of arguments that aren't options (but, for example, filenames).
static TQString cwd()
Get the CWD (Current Working Directory) associated with the current command line arguments.
static void init(int _argc, char **_argv, const char *_appname, const char *programName, const char *_description, const char *_version, bool noKApp=false)
Initialize class.
static void usage(const char *id=0)
Print the usage help to stdout and exit.
~TDECmdLineArgs()
Destructor.
Access to KDE global objects for use in shared libraries.
TDEConfig * config() const
Returns the general config object ("appnamerc").
#define I18N_NOOP(x)
I18N_NOOP marks a string to be translated without translating it.
TDEAction * save(const TQObject *recvr, const char *slot, TDEActionCollection *parent, const char *name=0)
Structure that holds command line options.
const char * name
The name of the argument as it should be called on the command line and appear in myapp –help.
const char * def
The default value for the option, if it is not specified on the command line.
const char * description
The text description of the option as should appear in myapp –help.