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" );