Beginnings of a simple command line interface

git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@1051 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
twanvl
2008-08-04 18:45:46 +00:00
parent 2fb61eb780
commit 19bfaa0684
7 changed files with 319 additions and 30 deletions
+71
View File
@@ -0,0 +1,71 @@
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2008 Twan van Laarhoven and "coppro" |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <util/error.hpp>
#include <cli/cli_main.hpp>
#include <cli/text_io_handler.hpp>
// ----------------------------------------------------------------------------- : Command line interface
CLISetInterface::CLISetInterface()
: quiet(false)
{
if (!cli.haveConsole()) {
throw Error(_("Can not run command line interface without a console;\nstart MSE with \"mse.com --cli\""));
}
run();
}
void CLISetInterface::run() {
// show welcome logo
if (!quiet) showWelcome();
// loop
running = true;
while (running) {
// show prompt
if (!quiet) {
cli << GRAY << _("> ") << NORMAL;
cli.flush();
}
// read line from stdin
String command = cli.getLine();
handleCommand(command);
}
}
void CLISetInterface::showWelcome() {
cli << _(" ___ \n")
_(" __ __ _ ___ _ ___ _ _ _ |__ \\ \n")
_(" | \\/ |__ _ __ _(_)__ / __|___| |_ | __|__| (_) |_ ___ _ _ ) |\n")
_(" | |\\/| / _` / _` | / _| \\__ | -_) _| | _|/ _` | | _/ _ \\ '_| / / \n")
_(" |_| |_\\__,_\\__, |_\\__| |___|___|\\__| |___\\__,_|_|\\__\\___/_| / /_ \n")
_(" |___/ |____|\n\n");
cli.flush();
}
void CLISetInterface::handleCommand(const String& command) {
if (command.empty()) {
// empty, ignore
} else if (command == _(":q") || command == _(":quit")) {
if (!quiet) {
cli << _("Goodbye\n"); cli.flush();
}
running = false;
} else if (command == _(":?") || command == _(":help")) {
// TODO show help
} else if (command == _("exit") || command == _("quit")) {
cli << _("Use :quit to quit\n"); cli.flush();
} else if (command.GetChar(0) == _(':')) {
cli << _("Unknown command, type :help for help.\n"); cli.flush();
} else {
// execute command
// TODO
cli << _("You said:\n") << command << ENDL; cli.flush();
}
}
+29
View File
@@ -0,0 +1,29 @@
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2008 Twan van Laarhoven and "coppro" |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
#ifndef HEADER_CLI_MAIN
#define HEADER_CLI_MAIN
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
// ----------------------------------------------------------------------------- : Command line interface
class CLISetInterface {
public:
CLISetInterface();
private:
bool quiet;
bool running;
void run();
void showWelcome();
void handleCommand(const String& command);
};
// ----------------------------------------------------------------------------- : EOF
#endif
+103
View File
@@ -0,0 +1,103 @@
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2008 Twan van Laarhoven and "coppro" |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <cli/text_io_handler.hpp>
// ----------------------------------------------------------------------------- : Text I/O handler
const Char* BRIGHT = _("\x1B[1m");
const Char* NORMAL = _("\x1B[0m");
const Char* PARAM = _("\x1B[33m");
const Char* FILE_EXT = _("\x1B[0;1m");
const Char* GRAY = _("\x1B[1;30m");
const Char* RED = _("\x1B[1;31m");
const Char* ENDL = _("\n");
TextIOHandler cli;
void TextIOHandler::init() {
#ifdef __WXMSW__
have_console = false;
escapes = false;
// Detect whether to use console output
// GetStdHandle sometimes returns an invalid handle instead of INVALID_HANDLE_VALUE
// check with GetHandleInformation
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD flags;
bool ok = GetHandleInformation(h,&flags);
if (ok) have_console = true;
// Detect the --color flag, indicating we should allow escapes
if (have_console) {
for (int i = 1 ; i < wxTheApp->argc ; ++i) {
if (String(wxTheApp->argv[i]) == _("--color")) {
escapes = true;
break;
}
}
}
#else
// always use console on *nix (?)
have_console = true;
escapes = true;
#endif
}
bool TextIOHandler::haveConsole() const {
return have_console;
}
void TextIOHandler::flush() {
if (have_console) {
fflush(stdout);
} else if (!buffer.empty()) {
// Show message box
wxMessageBox(buffer, _("Magic Set Editor"), wxOK | wxICON_INFORMATION);
buffer.clear();
}
}
TextIOHandler& TextIOHandler::operator << (const Char* str) {
if (escapes || str[0] != 27) {
if (have_console) {
IF_UNICODE(wprintf,printf)(str);
} else {
buffer += str;
}
}
return *this;
}
TextIOHandler& TextIOHandler::operator << (const String& str) {
if (escapes || str.empty() || str.GetChar(0) != 27) {
if (have_console) {
IF_UNICODE(wprintf,printf)(str.c_str());
} else {
buffer += str;
}
}
return *this;
}
String TextIOHandler::getLine() {
String result;
Char buffer[2048];
while (true) {
if (!IF_UNICODE(fgetws,fgets)(buffer, 2048, stdin)) {
return result; // error
}
result += buffer;
if (result.GetChar(result.size()-1) == _('\n')) {
// drop newline, done
result.resize(result.size() - 1);
return result;
}
}
}
+47
View File
@@ -0,0 +1,47 @@
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2008 Twan van Laarhoven and "coppro" |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
#ifndef HEADER_CLI_TEXT_IO_HANDLER
#define HEADER_CLI_TEXT_IO_HANDLER
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
// ----------------------------------------------------------------------------- : Text I/O handler
// color codes
extern const Char *BRIGHT, *NORMAL, *PARAM, *FILE_EXT, *GRAY, *RED, *ENDL;
/// Command line input / output handler
class TextIOHandler {
public:
void init();
/// Do we have a console to read/write from/to?
bool haveConsole() const;
/// Output text to the console
TextIOHandler& operator << (const Char*);
TextIOHandler& operator << (const String&);
/// Read a line from stdin
String getLine();
/// Flush output
void flush();
private:
bool have_console;
bool escapes;
String buffer; ///< Buffer when not writing to console
};
/// The global TextIOHandler object
extern TextIOHandler cli;
// ----------------------------------------------------------------------------- : EOF
#endif
+12 -6
View File
@@ -41,6 +41,7 @@ struct Transfer {
DWORD WINAPI TransferThread(Transfer*);
BOOL WINAPI HandleCtrlEvent(DWORD type);
void InitEscapeTranslation(HANDLE console);
void PerformEscapeCode(HANDLE console, char command, int argc, int argv[]);
/// The child process
@@ -59,7 +60,7 @@ int main(int argc, char** argv) {
// determine whether we need to wrap console i/o
bool need_redirection = false;
for (int i = 1 ; i < argc ; ++i) {
for (int j = 1 ; j < sizeof(redirect_flags)/sizeof(redirect_flags[0]) ; ++j) {
for (int j = 0 ; j < sizeof(redirect_flags)/sizeof(redirect_flags[0]) ; ++j) {
if (strcmp(argv[i],redirect_flags[j]) == 0) {
need_redirection = true;
goto break_2;
@@ -116,6 +117,7 @@ int main(int argc, char** argv) {
in_real = GetStdHandle(STD_INPUT_HANDLE);
out_real = GetStdHandle(STD_OUTPUT_HANDLE);
err_real = GetStdHandle(STD_ERROR_HANDLE);
InitEscapeTranslation(out_real);
// start threads
Transfer tranfer_in = {in_real, in_mine, false};
@@ -149,9 +151,6 @@ int main(int argc, char** argv) {
return exit_code;
}
// ----------------------------------------------------------------------------- : Running
// ----------------------------------------------------------------------------- : Terminating
/// Handle Ctrl+C
@@ -189,10 +188,10 @@ void CopyFileBufferWithEscape(HANDLE output, char* buffer, DWORD size, bool hand
}
DWORD pos = 0;
while (pos < size) {
// find next escape code, "\27["
// find next escape code, "\x1B["
DWORD next_pos = pos;
while (next_pos < size &&
(buffer[next_pos] != '\27' ||
(buffer[next_pos] != '\x1B' ||
(next_pos + 1 >= size || buffer[next_pos+1] != '['))) ++next_pos;
// copy part before next escape
CopyFileBuffer(output, buffer+pos, next_pos-pos);
@@ -236,6 +235,13 @@ DWORD WINAPI TransferThread(Transfer* transfer) {
WORD original_attributes;
/// Initialization for escape translation
void InitEscapeTranslation(HANDLE console) {
CONSOLE_SCREEN_BUFFER_INFO screen_buffer;
GetConsoleScreenBufferInfo(console, &screen_buffer);
original_attributes = screen_buffer.wAttributes;
}
/// Perform an escape code
void PerformEscapeCode(HANDLE console, char command, int argc, int argv[]) {
switch (command) {