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(Q_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").
599 arg(about->programName()).arg(about->version()));
601 }
else if ( (::qstrcmp(option,
"license") == 0) )
604 printQ( about->license() );
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.") );
626 if (!about->customAuthorTextEnabled ())
628 if (about->bugAddress().isEmpty() || about->bugAddress() ==
"bugs.pearsoncomputing.net" )
629 printQ( i18n(
"Please use http://bugs.pearsoncomputing.net to report bugs.\n" ) );
631 if( about->authors().count() == 1 && about->authors().first().emailAddress() == about->bugAddress() )
632 printQ( i18n(
"Please report bugs to %1.\n" ).arg( about->authors().first().emailAddress() ) );
634 printQ( i18n(
"Please report bugs to %1.\n" ).arg(about->bugAddress()) );
639 printQ(about->customAuthorPlainText());
644 if ((option[0] ==
'n') && (option[1] ==
'o'))
649 findOption(orig, option, i, enabled, inOptions);
660 usage( i18n(
"Unexpected argument '%1'.").arg(TQString::fromLocal8Bit(argv[i])));
664 appOptions->addArgument(argv[i]);
665 if (everythingAfterArgIsArgs)
679 TDECmdLineArgs::tqt_argc()
684 static int tqt_argc = -1;
692 fprintf(stderr,
"\n\nFAILURE (TDECmdLineArgs):\n");
693 fprintf(stderr,
"Application has not called TDECmdLineArgs::init(...).\n\n");
699 assert(argc >= (args->
count()+1));
700 tqt_argc = args->
count() +1;
710 TDECmdLineArgs::tqt_argv()
715 static char** tqt_argv;
716 if( tqt_argv != NULL )
723 fprintf(stderr,
"\n\nFAILURE (TDECmdLineArgs):\n");
724 fprintf(stderr,
"Application has not called TDECmdLineArgs::init(...).\n\n");
730 tqt_argv =
new char*[ args->
count() + 2 ];
731 tqt_argv[ 0 ] = tqstrdup( appName());
733 for(; i < args->
count(); i++)
735 tqt_argv[i+1] = tqstrdup((
char *) args->
arg(i));
746 if (TDEGlobal::_locale)
749 if (!TDEGlobal::_instance) {
751 (void) instance->
config();
759 assert(TDEGlobal::_locale);
760 TQCString localError = error.local8Bit();
761 if (localError[error.length()-1] ==
'\n')
762 localError = localError.left(error.length()-1);
763 fprintf(stderr,
"%s: %s\n", argv[0], localError.data());
765 TQString tmp = i18n(
"Use --help to get a list of available command line options.");
766 localError = tmp.local8Bit();
767 fprintf(stderr,
"%s: %s\n", argv[0], localError.data());
775 assert(argsList != 0);
778 TQString optionFormatString =
" %1 %2\n";
779 TQString optionFormatStringDef =
" %1 %2 [%3]\n";
780 TQString optionHeaderString = i18n(
"\n%1:\n");
786 if (!(args->id) && (args->options) &&
787 (args->options->
name) && (args->options->
name[0] !=
'+'))
789 usage = i18n(
"[options] ")+usage;
796 usage = i18n(
"[%1-options]").arg(args->name)+
" "+usage;
798 args = argsList->prev();
805 while(option && option->
name)
807 if (option->
name[0] ==
'+')
808 usage = usage + (option->
name+1) +
" ";
809 else if ( option->
name[0] ==
'!' && option->
name[1] ==
'+' )
810 usage = usage + (option->
name+2) +
" ";
816 printQ(i18n(
"Usage: %1 %2\n").arg(argv[0]).arg(usage));
817 printQ(
"\n"+about->shortDescription()+
"\n");
819 printQ(optionHeaderString.arg(i18n(
"Generic options")));
820 printQ(optionFormatString.arg(
"--help", -25).arg(i18n(
"Show help about options")));
822 args = argsList->first();
825 if (args->name && args->id)
827 TQString option = TQString(
"--help-%1").
arg(args->id);
828 TQString desc = i18n(
"Show %1 specific options").arg(args->name);
830 printQ(optionFormatString.arg(option, -25).arg(desc));
832 args = argsList->next();
835 printQ(optionFormatString.arg(
"--help-all",-25).arg(i18n(
"Show all options")));
836 printQ(optionFormatString.arg(
"--author",-25).arg(i18n(
"Show author information")));
837 printQ(optionFormatString.arg(
"-v, --version",-25).arg(i18n(
"Show version information")));
838 printQ(optionFormatString.arg(
"--license",-25).arg(i18n(
"Show license information")));
839 printQ(optionFormatString.arg(
"--", -25).arg(i18n(
"End of options")));
841 args = argsList->first();
843 bool showAll =
id && (::qstrcmp(
id,
"all") == 0);
849 if (!
id && !args->id)
break;
850 if (
id && (::qstrcmp(args->id,
id) == 0))
break;
851 args = argsList->next();
857 bool hasArgs =
false;
858 bool hasOptions =
false;
859 TQString optionsHeader;
861 optionsHeader = optionHeaderString.arg(i18n(
"%1 options").arg(TQString::fromLatin1(args->name)));
863 optionsHeader = i18n(
"\nOptions:\n");
870 while(option && option->
name)
872 TQString description;
873 TQString descriptionRest;
877 if (option->
name[0] ==
':')
882 if (!optionsHeader.endsWith(
"\n"))
883 optionsHeader.append(
"\n");
891 if (option->
name[0] == 0)
896 if (!tmp.endsWith(
"\n"))
908 dl = TQStringList::split(
"\n", description,
true);
909 description = dl.first();
910 dl.remove( dl.begin() );
912 TQCString name = option->
name;
920 printQ(i18n(
"\nArguments:\n"));
925 if ((name[0] ==
'[') && (name[name.length()-1] ==
']'))
926 name = name.mid(1, name.length()-2);
927 printQ(optionFormatString.arg(QString(name), -25)
934 printQ(optionsHeader);
938 if ((name.length() == 1) || (name[1] ==
' '))
951 printQ(optionFormatString.arg(QString(opt), -25)
956 printQ(optionFormatStringDef.arg(QString(opt), -25)
957 .arg(description).arg(option->
def));
962 for(TQStringList::Iterator it = dl.begin();
966 printQ(optionFormatString.arg(
"", -25).arg(*it));
971 args = argsList->next();
972 if (!args || args->name || !args->id)
break;
990 const char *_name,
const char *_id)
991 : options(_options), name(_name), id(_id)
993 parsedOptionList = 0;
995 isQt = (::qstrcmp(
id,
"qt") == 0);
1003 delete parsedOptionList;
1004 delete parsedArgList;
1006 argsList->removeRef(
this);
1012 delete parsedArgList;
1014 delete parsedOptionList;
1015 parsedOptionList = 0;
1022 argsList->setAutoDelete(
true );
1031 TDECmdLineArgs::save( TQDataStream &ds)
const 1034 if (parsedOptionList)
1035 parsedOptionList->save( ds );
1040 parsedArgList->save( ds );
1046 TDECmdLineArgs::load( TQDataStream &ds)
1048 if (!parsedOptionList) parsedOptionList =
new TDECmdLineParsedOptions;
1049 if (!parsedArgList) parsedArgList =
new TDECmdLineParsedArgs;
1051 parsedOptionList->load( ds );
1052 parsedArgList->load( ds );
1054 if (parsedOptionList->count() == 0)
1056 delete parsedOptionList;
1057 parsedOptionList = 0;
1059 if (parsedArgList->count() == 0)
1061 delete parsedArgList;
1067 TDECmdLineArgs::setOption(
const TQCString &opt,
bool enabled)
1072 TQCString
arg =
"-";
1078 if (!parsedOptionList) {
1079 parsedOptionList =
new TDECmdLineParsedOptions;
1080 parsedOptionList->setAutoDelete(
true);
1084 parsedOptionList->replace( opt,
new TQCString(
"t") );
1086 parsedOptionList->replace( opt,
new TQCString(
"f") );
1090 TDECmdLineArgs::setOption(
const TQCString &opt,
const char *value)
1095 TQCString
arg =
"-";
1102 if (arg ==
"-display")
1104 setenv(DISPLAY, value,
true);
1108 if (!parsedOptionList) {
1109 parsedOptionList =
new TDECmdLineParsedOptions;
1110 parsedOptionList->setAutoDelete(
true);
1113 parsedOptionList->insert( opt,
new TQCString(value) );
1119 TQCString *value = 0;
1120 if (parsedOptionList)
1122 value = parsedOptionList->find(_opt);
1129 const char *opt_name;
1132 TQCString opt = _opt;
1133 int result = ::findOption( options, opt, opt_name, def, dummy) & ~4;
1137 fprintf(stderr,
"\n\nFAILURE (TDECmdLineArgs):\n");
1138 fprintf(stderr,
"Application requests for getOption(\"%s\") but the \"%s\" option\n",
1140 fprintf(stderr,
"has never been specified via addCmdLineOptions( ... )\n\n");
1145 return TQCString(def);
1151 QCStringList result;
1152 if (!parsedOptionList)
1157 TQCString *value = parsedOptionList->take(_opt);
1160 result.prepend(*value);
1169 for(QCStringList::ConstIterator it=result.begin();
1173 parsedOptionList->insert(_opt,
new TQCString(*it));
1182 const char *opt_name;
1185 TQCString opt = _opt;
1186 int result = ::findOption( options, opt, opt_name, def, dummy) & ~4;
1190 fprintf(stderr,
"\n\nFAILURE (TDECmdLineArgs):\n");
1191 fprintf(stderr,
"Application requests for isSet(\"%s\") but the \"%s\" option\n",
1193 fprintf(stderr,
"has never been specified via addCmdLineOptions( ... )\n\n");
1199 TQCString *value = 0;
1200 if (parsedOptionList)
1202 value = parsedOptionList->find(opt);
1210 return ((*value)[0] ==
't');
1218 return (result == 2);
1226 return parsedArgList->count();
1232 if (!parsedArgList || (n >= (
int) parsedArgList->count()))
1234 fprintf(stderr,
"\n\nFAILURE (TDECmdLineArgs): Argument out of bounds\n");
1235 fprintf(stderr,
"Application requests for arg(%d) without checking count() first.\n",
1242 return parsedArgList->at(n);
1253 const TQString urlArg = TQFile::decodeName(_urlArg);
1254 TQFileInfo fileInfo(urlArg);
1255 if (!fileInfo.isRelative()) {
1268 return KURL(urlArg);
1272 TDECmdLineArgs::addArgument(
const char *argument)
1275 parsedArgList =
new TDECmdLineParsedArgs;
1277 parsedArgList->append(argument);
1282 {
"tempfile", I18N_NOOP(
"The files/URLs opened by the application will be deleted after use"), 0},
1283 TDECmdLineLastOption
1296 return args->
isSet(
"tempfile" );
Represents and parses a URL.
A class for command-line argument handling.
static void reset()
Reset all option definitions, i.e.
const char * name
The name of the argument as it should be called on the command line and appear in myapp –help...
void clear()
Clear all options and arguments.
static bool isRelativeURL(const TQString &_url)
Tests if a given URL is a relative as opposed to an absolute URL.
Little helper class to clean up static objects that are held as pointer.
This class is used to store information about a program.
static void addCmdLineOptions(const TDECmdLineOptions *options, const char *name=0, const char *id=0, const char *afterId=0)
Add options to your application.
static const char * appName()
Get the appname according to argv[0].
KURL url(int n) const
Read out an argument representing a URL.
const char * description
The text description of the option as should appear in myapp –help.
const char * appName() const
Returns the application's internal name.
KDE_DEPRECATED type * setObject(type *obj, bool isArray=false)
Sets the object to delete and registers the object to be deleted to TDEGlobal.
TQCString getOption(const char *option) const
Read out a string option.
static void usage(const char *id=0)
Print the usage help to stdout and exit.
static void loadAppArgs(TQDataStream &)
Load arguments from a stream.
static TDECmdLineArgs * parsedArgs(const char *id=0)
Access parsed arguments.
void setPath(const TQString &path)
Sets the decoded path of the URL.
static bool isTempFileSet()
static KURL makeURL(const char *urlArg)
Used by url().
void cleanPath(bool cleanDirSeparator=true)
Resolves "." and ".." components in path.
TDEAction * save(const TQObject *recvr, const char *slot, TDEActionCollection *parent, const char *name=0)
static void init(int _argc, char **_argv, const char *_appname, const char *programName, const char *_description, const char *_version, bool noKApp=false)
Initialize class.
TDECmdLineArgs(const TDECmdLineOptions *_options, const char *_name, const char *_id)
Constructor.
const char * def
The default value for the option, if it is not specified on the command line.
TDEConfig * config() const
Returns the general config object ("appnamerc").
static void addTempFileOption()
Add standard option –tempfile.
~TDECmdLineArgs()
Destructor.
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.
QCStringList getOptionList(const char *option) const
Read out all occurrences of a string option.
static void enable_i18n()
Enable i18n to be able to print a translated error message.
static void addCmdLineOptions()
Add Qt and KDE command line options to TDECmdLineArgs.
bool isSet(const char *option) const
Read out a boolean option or check for the presence of string option.
Access to KDE global objects for use in shared libraries.
const char * arg(int n) const
Read out an argument.
Structure that holds command line options.