21 #include <sys/param.h> 35 #include <tqasciidict.h> 36 #include <tqstrlist.h> 38 #include "kcmdlineargs.h" 39 #include <kaboutdata.h> 41 #include <kapplication.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<KCmdLineArgs>;
59 class KCmdLineParsedOptions :
public TQAsciiDict<TQCString>
62 KCmdLineParsedOptions()
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 KCmdLineParsedArgs :
public TQStrList
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 KCmdLineArgsList:
public TQPtrList<KCmdLineArgs>
110 KCmdLineArgsList() { }
113 KCmdLineArgsList *KCmdLineArgs::argsList = 0;
114 int KCmdLineArgs::argc = 0;
115 char **KCmdLineArgs::argv = 0;
116 char *KCmdLineArgs::mCwd = 0;
119 bool KCmdLineArgs::parsed =
false;
120 bool KCmdLineArgs::ignoreUnknown =
false;
128 const char *_description,
const char *_version,
bool noKApp)
131 new KAboutData(_appname, programName, _version, _description),
137 const char *_description,
const char *_version,
bool noKApp)
140 new KAboutData(_appname, _appname, _version, _description),
145 KCmdLineArgs::initIgnore(
int _argc,
char **_argv,
const char *_appname )
148 new KAboutData(_appname, _appname,
"unknown",
"KDE 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 (KCmdLineArgs):\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 KCmdLineArgsList();
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 KCmdLineArgs::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 KCmdLineArgs::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 KCmdLineArgs::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 KCmdLineArgs::printQ(
const TQString &msg)
539 TQCString localMsg = msg.local8Bit();
540 fprintf(stdout,
"%s", localMsg.data());
544 KCmdLineArgs::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(qVersion()));
597 printQ( TQString(
"KDE: %1\n").arg(KDE_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<KAboutPerson> authors = about->authors();
611 if ( !authors.isEmpty() ) {
613 for (TQValueList<KAboutPerson>::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()
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" ) );
633 if( about->authors().count() == 1 && about->authors().first().emailAddress() == about->bugAddress() )
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()) );
641 printQ(about->customAuthorPlainText());
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 KCmdLineArgs::qt_argc()
686 static int qt_argc = -1;
694 fprintf(stderr,
"\n\nFAILURE (KCmdLineArgs):\n");
695 fprintf(stderr,
"Application has not called KCmdLineArgs::init(...).\n\n");
701 assert(argc >= (args->
count()+1));
702 qt_argc = args->
count() +1;
712 KCmdLineArgs::qt_argv()
717 static char** qt_argv;
718 if( qt_argv != NULL )
725 fprintf(stderr,
"\n\nFAILURE (KCmdLineArgs):\n");
726 fprintf(stderr,
"Application has not called KCmdLineArgs::init(...).\n\n");
732 qt_argv =
new char*[ args->
count() + 2 ];
733 qt_argv[ 0 ] = qstrdup( appName());
735 for(; i < args->
count(); i++)
737 qt_argv[i+1] = qstrdup((
char *) args->
arg(i));
748 if (KGlobal::_locale)
751 if (!KGlobal::_instance) {
753 (void) instance->
config();
761 assert(KGlobal::_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] !=
'+'))
791 usage = i18n(
"[options] ")+usage;
798 usage = i18n(
"[%1-options]").arg(args->name)+
" "+usage;
800 args = argsList->prev();
807 while(option && option->
name)
809 if (option->
name[0] ==
'+')
810 usage = usage + (option->
name+1) +
" ";
811 else if ( option->
name[0] ==
'!' && option->
name[1] ==
'+' )
812 usage = usage + (option->
name+2) +
" ";
818 printQ(i18n(
"Usage: %1 %2\n").arg(argv[0]).arg(usage));
819 printQ(
"\n"+about->shortDescription()+
"\n");
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(QString(name), -25)
936 printQ(optionsHeader);
940 if ((name.length() == 1) || (name[1] ==
' '))
953 printQ(optionFormatString.arg(QString(opt), -25)
958 printQ(optionFormatStringDef.arg(QString(opt), -25)
959 .arg(description).arg(option->
def));
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 KCmdLineArgs::save( TQDataStream &ds)
const 1036 if (parsedOptionList)
1037 parsedOptionList->save( ds );
1042 parsedArgList->save( ds );
1048 KCmdLineArgs::load( TQDataStream &ds)
1050 if (!parsedOptionList) parsedOptionList =
new KCmdLineParsedOptions;
1051 if (!parsedArgList) parsedArgList =
new KCmdLineParsedArgs;
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 KCmdLineArgs::setOption(
const TQCString &opt,
bool enabled)
1074 TQCString
arg =
"-";
1080 if (!parsedOptionList) {
1081 parsedOptionList =
new KCmdLineParsedOptions;
1082 parsedOptionList->setAutoDelete(
true);
1086 parsedOptionList->replace( opt,
new TQCString(
"t") );
1088 parsedOptionList->replace( opt,
new TQCString(
"f") );
1092 KCmdLineArgs::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 KCmdLineParsedOptions;
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 (KCmdLineArgs):\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 (KCmdLineArgs):\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 (KCmdLineArgs): 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 KCmdLineArgs::addArgument(
const char *argument)
1277 parsedArgList =
new KCmdLineParsedArgs;
1279 parsedArgList->append(argument);
1284 {
"tempfile", I18N_NOOP(
"The files/URLs opened by the application will be deleted after use"), 0},
1298 return args->
isSet(
"tempfile" );
Represents and parses a URL.
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.
static void addCmdLineOptions()
Add Qt and KDE command line options to KCmdLineArgs.
static bool isTempFileSet()
~KCmdLineArgs()
Destructor.
static KURL makeURL(const char *urlArg)
Used by url().
static void usage(const char *id=0)
Print the usage help to stdout and exit.
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.
KAction * save(const TQObject *recvr, const char *slot, KActionCollection *parent, const char *name=0)
A class for command-line argument handling.
KConfig * config() const
Returns the general config object ("appnamerc").
static KCmdLineArgs * parsedArgs(const char *id=0)
Access parsed arguments.
static void addTempFileOption()
Add standard option –tempfile.
QCStringList getOptionList(const char *option) const
Read out all occurrences of a string option.
KDE_DEPRECATED type * setObject(type *obj, bool isArray=false)
Sets the object to delete and registers the object to be deleted to KGlobal.
int count() const
Read the number of arguments that aren't options (but, for example, filenames).
static void reset()
Reset all option definitions, i.e.
Structure that holds command line options.
static const char * appName()
Get the appname according to argv[0].
bool isSet(const char *option) const
Read out a boolean option or check for the presence of string option.
void setPath(const TQString &path)
Sets the decoded path of the URL.
Access to KDE global objects for use in shared libraries.
This class is used to store information about a program.
void cleanPath(bool cleanDirSeparator=true)
Resolves "." and ".." components in path.
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 addCmdLineOptions(const KCmdLineOptions *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.
KCmdLineArgs(const KCmdLineOptions *_options, const char *_name, const char *_id)
Constructor.
static void loadAppArgs(TQDataStream &)
Load arguments from a stream.
const char * arg(int n) const
Read out an argument.
const char * appName() const
Returns the application's internal name.
static TQString cwd()
Get the CWD (Current Working Directory) associated with the current command line arguments.
TQCString getOption(const char *option) const
Read out a string option.
void clear()
Clear all options and arguments.
static void enable_i18n()
Enable i18n to be able to print a translated error message.
const char * name
The name of the argument as it should be called on the command line and appear in myapp –help...