*Greatly increased robustness of parsing arguments, error messages should now make sense in most cases.

*Tool specific arguments are now entered before the filename, as intended.

svn-id: r42878
This commit is contained in:
Hampus Nilsson
2009-07-29 02:09:01 +00:00
parent 510596e102
commit 4fe365c5e1
3 changed files with 76 additions and 26 deletions
+3 -3
View File
@@ -757,6 +757,8 @@ bool CompressionTool::processMp3Parms() {
return true;
}
#include <iostream>
bool CompressionTool::processOggParms() {
while (_arguments_parsed < _arguments.size()) {
std::string arg = _arguments[_arguments_parsed];
@@ -766,6 +768,7 @@ bool CompressionTool::processOggParms() {
if (_arguments_parsed >= _arguments.size())
throw ToolException("Could not parse command line options, expected value after -b");
oggparms.nominalBitr = atoi(_arguments[_arguments_parsed].c_str());
std::cout << "Parsed b=" << oggparms.nominalBitr << "\n";
if ((oggparms.nominalBitr % 8) != 0) {
oggparms.nominalBitr -= oggparms.nominalBitr % 8;
@@ -899,8 +902,6 @@ void CompressionTool::parseAudioArguments() {
++_arguments_parsed;
// Need workaround to be sign-correct
int arg = (int)_arguments_parsed;
switch (_format) {
case AUDIO_MP3:
tempEncoded = TEMP_MP3;
@@ -920,7 +921,6 @@ void CompressionTool::parseAudioArguments() {
default: // cannot occur but we check anyway to avoid compiler warnings
throw ToolException("Unknown audio format, should be impossible!");
}
_arguments_parsed = (size_t)arg;
}
std::string CompressionTool::getHelp() const {
+16 -3
View File
@@ -22,6 +22,8 @@
#include <stdarg.h>
#include <iostream>
#include <sstream>
#include "util.h"
#include "tool.h"
@@ -85,9 +87,14 @@ int Tool::run(std::vector<std::string> args) {
// Read tool specific arguments
parseExtraArguments();
if (_arguments.size() && _arguments[_arguments_parsed][0] == '-') {
std::string s = "Possibly ignored option " + _arguments[_arguments_parsed] + ".";
print(s.c_str());
}
// Read input files from CLI
for(ToolInputs::iterator iter = _inputPaths.begin(); iter != _inputPaths.end(); ++iter) {
if(_arguments_parsed > _inputPaths.size()) {
if(_arguments.size() - _arguments_parsed < _inputPaths.size()) {
print("Too few input files!");
return -2;
}
@@ -106,8 +113,14 @@ int Tool::run(std::vector<std::string> args) {
iter->path = in;
}
if(_arguments_parsed < _arguments.size()) {
print("Too many input files!");
// We should have parsed all arguments by now
if(_arguments_parsed < _arguments.size() - _inputPaths.size()) {
std::ostringstream os;
os << "Too many inputs files ( ";
while (_arguments_parsed < _arguments.size())
os << "'" << _arguments[_arguments_parsed++] << "' ";
os << ")\n";
print(os.str().c_str());
return -2;
}
+57 -20
View File
@@ -21,6 +21,7 @@
*/
#include <iostream>
#include <algorithm>
#include "tools_cli.h"
@@ -80,29 +81,64 @@ int ToolsCLI::run(int argc, char *argv[]) {
} else if (option == "--list" || option == "-l") {
printTools();
} else {
// Allow user to the narrow choices
if(option == "compress") {
ToolList choices;
std::deque<std::string>::reverse_iterator reader = arguments.rbegin();
std::deque<std::string>::iterator hint_arg;
std::string infile;
hint_arg = std::find(arguments.begin(), arguments.end(), "compress");
if (hint_arg != arguments.end()) {
type = TOOLTYPE_COMPRESSION;
arguments.pop_front();
} else if(option == "extract") {
type = TOOLTYPE_EXTRACTION;
arguments.pop_front();
} else {
hint_arg = std::find(arguments.begin(), arguments.end(), "extract");
if (hint_arg != arguments.end())
type = TOOLTYPE_EXTRACTION;
}
// Only possible if compress/extract was parsed
if (arguments.empty())
std::cout << "\tExpected more arguments after '" << option << "'\n";
while (reader != arguments.rend()) {
//std::cout << "Checking backarg " << *reader << "\n";
if (hint_arg != arguments.end() && *reader == *hint_arg) {
//std::cout << "It is the hint! begin anew" << "\n";
// It seems hint_arg was an input file, start over but with generic file type
type = TOOLTYPE_ALL;
reader = arguments.rbegin();
hint_arg = arguments.end();
continue;
}
// It must be a filename now
choices = inspectInput(type, *reader);
// If anything matched, we stop
if (choices.size() > 0) {
infile = *reader;
break;
}
++reader;
}
if (hint_arg != arguments.end()) {
// Remove hint as it's not used after this, and can't be in tool CLI
arguments.erase(hint_arg);
// Only possible if compress/extract was parsed
if (arguments.empty())
// compress was the arg removed so...
std::cout << "\tExpected more arguments after '" << option << "'\n";
}
// This should never happen, as args are only removed if we used compress|extract
assert(arguments.empty() == false);
// Find out what tools take this file as input
ToolList choices = inspectInput(type, arguments.front());
Tool *tool = NULL;
if (choices.empty()) {
std::cout << "\tNo tool could parse input file '" << arguments.front() << "', use --list to list all available tools and --tool to force running the correct one.\n";
std::cout << "\tIf you intended to specify tool-specific options, do so AFTER the input file.\n\n";
std::cout << "\tExample: tools_cli monster.sou --vorbis\n";
return 0;
} else if (choices.size() > 1) {
if (infile.size() && infile[0] == '-')
std::cout << "\tWARNING: Input file '" << infile << "' looks like an argument, is this what you wanted?\n";
std::cout << "\tMultiple tools accept this input:\n\n";
// Present a list of possible tools
@@ -111,7 +147,7 @@ int ToolsCLI::run(int argc, char *argv[]) {
std::cout << "\t" << i << ") " << (*choice)->getName() << "\n";
}
std::cout << "Which tool to use: ";
std::cout << "Which tool to use ('q' to abort): ";
i = 0;
while(true) {
@@ -122,13 +158,15 @@ int ToolsCLI::run(int argc, char *argv[]) {
if(std::cin && i >= 1 && (size_t)i < choices.size())
break;
std::cout << "Invalid input, try again: ";
// Clear any error flags
std::cin.clear();
std::string q;
std::cin >> q;
if (q == "q" || q == "exit" || q == "quit" || q == "abort")
return 0;
// Skip invalid input characters
std::cin.ignore(1000, '\n');
std::cout << "Invalid input, try again: ";
}
// Account for the fact arrays start at 0
@@ -152,9 +190,8 @@ void ToolsCLI::printHelp() {
"\tScumm VM Tools master interface\n" <<
"\n" <<
"\tCommon use:\n" <<
"\ttools [--tool <tool name>] [compression options] [-o output directory] [tool args] <input args>\n" <<
"\ttools [extract|compress] <input args> [tool args]\n" <<
"\tNote that on the second form, tool arguments are specified AFTER the input file.\n" <<
"\ttools [--tool <tool name>] [tool-specific options] [-o <output directory>] <input files>\n" <<
"\ttools [tool-specific option] [extract|compress] <input files>\n" <<
"\n" <<
"\tOther Options:\n" <<
"\t--help\tDisplay this text\n" <<