Commit f83718cd authored by Lisa's avatar Lisa

Second draft: long commands still missing.

parent 75d4631f
......@@ -41,7 +41,7 @@ CmdLine::CmdLine()
AkabeiOption ignore(APM::Ignore, "", "ignore", "Ignores a certain package. Can be used more than once.", true);
AkabeiOption ignoregroup(APM::IgnoreGroup, "", "ignoregroup", "Ignores upgrade of a group", true);
AkabeiOption databaseonly(APM::DatabaseOnly, "k", "dbonly", "Only remove database entries", false);
AkabeiOption removeconfig(APM::RemoveConfig, "n", "nosave", "Also remove configuration files", false);
AkabeiOption removeconfig(APM::RemoveConfig, "n", "save", "Also remove configuration files", false);
AkabeiOption recursive(APM::Recursive, "s", "recursive", "Remove dependencies as well. (-ss includes explicitely installed dependencies)", false);
AkabeiOption rootdir(APM::RootDir, "", "root", "Set a different root dir", true);
AkabeiOption cachedir(APM::CacheDir, "", "cachedir", "Set a different cache dir", true);
......@@ -172,8 +172,13 @@ CmdLine::CmdLine()
* This hash associating command (often the short one) and operation is useful later because
* one command can be associated to more operations and even options
*/
QByteArray command = (op.commandShort.isEmpty()) ? op.commandLong : op.commandShort;
acceptedOperations.insertMulti(command, op);
if (!op.commandShort.isEmpty()) {
acceptedOperations.insertMulti(op.commandShort, op);
}
if (!op.commandLong.isEmpty()) {
acceptedOperations.insertMulti(op.commandLong, op);
}
}
}
......@@ -230,10 +235,17 @@ void AkabeiOperation::set(AkabeiOperation& other)
return;
}
/* This is because sometimes the same operation is checked twice (also due to the hash) */
if (this->name == other.name) {
return;
}
if (this->name == APM::None || this->name == APM::Remove || this->name == APM::Install) {
this->name = other.name;
this->type = other.type;
this->options = other.options;
this->commandLong = other.commandLong;
this->commandShort = other.commandShort;
this->hasFreeArgs = other.hasFreeArgs;
} else if ((this->name == APM::UpdateDatabases && other.name == APM::UpdateSystem) || (this->name == APM::UpdateSystem && other.name == APM::UpdateDatabases)) {
this->name = APM::UpdateDatabaseAndSystem;
......@@ -282,7 +294,6 @@ void CmdLine::parse(int argc, char** argv)
KCmdLineOptions koptions;
/*
* Apparently description is mandatory, otherwise isSet doesn't find the option later
* Adds all the types
*/
koptions.add("D", ki18n("Database"));
......@@ -349,7 +360,7 @@ void CmdLine::parse(int argc, char** argv)
for (QHash<QByteArray, APM::OperationType>::iterator it = typechars.begin(); it != typechars.end(); it++) {
if (args->isSet(it.key())) {
if (type != APM::NoType) {
throw CmdLineException("Multiple operations present.");
throw CmdLineException("multiple types present.");
}
type = it.value();
......@@ -368,6 +379,7 @@ void CmdLine::parse(int argc, char** argv)
* If found, set it as operation.
*/
if (args->isSet(command)) {
qDebug() << "found" << command;
bool found = false;
foreach (AkabeiOperation op, acceptedOperations.values(command)) {
......@@ -394,7 +406,7 @@ void CmdLine::parse(int argc, char** argv)
}
if (m_operation.name == APM::None) {
throw CmdLineException("No operation specified.");
throw CmdLineException("no operation specified.");
}
foreach (AkabeiOption opt, acceptedOptions) {
......@@ -411,7 +423,7 @@ void CmdLine::parse(int argc, char** argv)
checkopts.removeOne(command);
if (!m_operation.isOptionSupported(opt.name)) {
//throw CmdLineException("Invalid option for this operation.");
throw CmdLineException("invalid option for this operation");
}
/*
......@@ -424,14 +436,16 @@ void CmdLine::parse(int argc, char** argv)
* so we're not really sure an error has been made, unless the operation doesn't admit any argument
*/
if (!optargs.isEmpty() && !opt.hasArg && !m_operation.hasFreeArgs) {
throw CmdLineException("This option must not have an argument.");
QString message = "the option \"" + command + "\" must not have an argument.";
throw CmdLineException(message.toUtf8().data());
}
/*
* In this case, we're sure :)
*/
if (optargs.isEmpty() && opt.hasArg) {
throw CmdLineException("Missing argument for this option.");
QString message = "missing argument for the option \"" + command + "\"";
throw CmdLineException(message.toUtf8().data());
}
opt.args = optargs;
......@@ -443,7 +457,9 @@ void CmdLine::parse(int argc, char** argv)
* If that strange command wasn't an option, then it was something wrong
*/
if (!checkopts.isEmpty()) {
throw CmdLineException("Out of context operation.");
qDebug() << "this";
QString command = "the operation \"" + checkops.takeFirst() + "\" is out of context.";
throw CmdLineException(command.toUtf8().data());
}
for (int i = 0; i < args->count(); i++) {
......@@ -451,23 +467,81 @@ void CmdLine::parse(int argc, char** argv)
}
if (!m_freeArgs.isEmpty() && !m_operation.hasFreeArgs) {
throw CmdLineException("Unexpected free arguments.");
throw CmdLineException("unexpected free arguments.");
}
if (m_freeArgs.isEmpty() && m_operation.hasFreeArgs) {
throw CmdLineException("Free arguments required but not present.");
throw CmdLineException("free arguments required but not present.");
}
args->clear(); /* frees up memory */
secondParse(argc, argv);
parsed = true;
}
/*
* This function handles all the parsing which can't be handled using KCmdLineArgs
* In particular, checks if the operation is repeated more than one, which isn't accepted
*/
void CmdLine::secondParse(int argc, char** argv)
{
QStringList cmdline;
for (int i = 1; i < argc; i++) {
QString part = QString::fromAscii(argv[i]);
if (part.size() < 2) {
continue;
}
/* long command */
if (part.at(0) == '-' && part.at(1) == '-') {
cmdline << part.remove(0, 2);
/* short command: takes each letter separately */
} else if (part.at(0) == '-') {
part.remove(0, 1);
/* The only short commands with two letters is treated separately to avoid problems */
if (part.contains("cc")) {
if (part.count("cc") > 1) {
throw CmdLineException("can't accept linked operations.");
} else {
part.remove("cc");
}
}
for (int ch = 0; ch < part.length(); ch++) {
cmdline << QString(part[ch]);
}
}
}
int occurrences = cmdline.count(m_operation.commandLong) + cmdline.count(m_operation.commandShort);
if (occurrences > 1) {
throw CmdLineException("can't accept linked operations.");
}
foreach (AkabeiOption opt, m_options.values()) {
/* The only options allowed to be repeated several times */
if (opt.name == APM::Ignore || opt.name == APM::IgnoreGroup) {
continue;
}
occurrences = cmdline.count(opt.commandLong) + cmdline.count(opt.commandShort);
if (occurrences > 1) {
throw CmdLineException("Can't repeat this option twice!");
}
}
}
APM::OperationType CmdLine::type()
{
if (!parsed) {
throw CmdLineException("Command line not parsed.");
}
qDebug() << m_operation.type;
return m_operation.type;
}
......
......@@ -126,6 +126,8 @@ private:
QHash<QByteArray, APM::OperationType> typechars;
bool parsed;
void secondParse(int argc, char **argv);
public:
CmdLine();
......
......@@ -23,12 +23,11 @@ int main(int argc, char** argv)
try {
cmd.parse(argc, argv);
} catch (CmdLineException& ex) {
qDebug() << "!! Fatal error parsing command line: " << ex.what();
QTextStream err(stderr);
err << "Fatal error parsing command line: " << ex.what() << endl;
return -1;
}
qDebug() << "here";
OperationManager apm(cmd.type(), cmd.operation(), cmd.options(), cmd.freeArgs());
qDebug() << "qui!";
return app.exec();
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment