client: add Platform::term_printf

Platform::term_printf is a variant of printf that
on windows dynamically opens console in order to
have visible output during command line processing.
This commit is contained in:
Yaniv Kamay 2010-01-11 19:57:29 +02:00
parent 3c1ff6448d
commit 8ceb531958
8 changed files with 134 additions and 72 deletions

View File

@ -1635,7 +1635,8 @@ const std::string& Application::get_password()
//controller interface end
bool Application::set_channels_security(CmdLineParser& parser, bool on, char *val)
bool Application::set_channels_security(CmdLineParser& parser, bool on, char *val,
const char* arg0)
{
RedPeer::ConnectionOptions::Type option;
option = (on) ? RedPeer::ConnectionOptions::CON_OP_SECURE :
@ -1653,7 +1654,8 @@ bool Application::set_channels_security(CmdLineParser& parser, bool on, char *va
if (!strcmp(val, "all")) {
if ((val = parser.next_argument())) {
std::cout << "\"all\" is exclusive in secure-channels\n";
Platform::term_printf("%s: \"all\" is exclusive in secure-channels\n", arg0);
_exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
return false;
}
PeerConnectionOptMap::iterator iter = _peer_con_opt.begin();
@ -1666,7 +1668,8 @@ bool Application::set_channels_security(CmdLineParser& parser, bool on, char *va
do {
ChannelsNamesMap::iterator iter = channels_names.find(val);
if (iter == channels_names.end()) {
std::cout << "bad channel name \"" << val << "\" in secure-channels\n";
Platform::term_printf("%s: bad channel name \"%s\" in secure-channels\n", arg0, val);
_exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
return false;
}
_peer_con_opt[(*iter).second] = option;
@ -1674,7 +1677,7 @@ bool Application::set_channels_security(CmdLineParser& parser, bool on, char *va
return true;
}
bool Application::set_canvas_option(CmdLineParser& parser, char *val)
bool Application::set_canvas_option(CmdLineParser& parser, char *val, const char* arg0)
{
typedef std::map< std::string, CanvasOption> CanvasNamesMap;
CanvasNamesMap canvas_types;
@ -1688,19 +1691,23 @@ bool Application::set_canvas_option(CmdLineParser& parser, char *val)
canvas_types["gl_pbuff"] = CANVAS_OPTION_OGL_PBUFF;
#endif
_canvas_types.clear();
do {
CanvasNamesMap::iterator iter = canvas_types.find(val);
if (iter == canvas_types.end()) {
std::cout << "bad canvas type \"" << val << "\"\n";
Platform::term_printf("%s: bad canvas type \"%s\"\n", arg0, val);
_exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
return false;
}
_canvas_types.resize(_canvas_types.size() + 1);
_canvas_types[_canvas_types.size() - 1] = (*iter).second;
} while ((val = parser.next_argument()));
return true;
}
bool Application::set_enable_channels(CmdLineParser& parser, bool enable, char *val)
bool Application::set_enable_channels(CmdLineParser& parser, bool enable, char *val,
const char* arg0)
{
typedef std::map< std::string, int> ChannelsNamesMap;
ChannelsNamesMap channels_names;
@ -1713,7 +1720,8 @@ bool Application::set_enable_channels(CmdLineParser& parser, bool enable, char *
if (!strcmp(val, "all")) {
if ((val = parser.next_argument())) {
std::cout << "\"all\" is exclusive\n";
Platform::term_printf("%s: \"all\" is exclusive\n", arg0);
_exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
return false;
}
for (unsigned int i = 0; i < _enabled_channels.size(); i++) {
@ -1725,7 +1733,8 @@ bool Application::set_enable_channels(CmdLineParser& parser, bool enable, char *
do {
ChannelsNamesMap::iterator iter = channels_names.find(val);
if (iter == channels_names.end()) {
std::cout << "bad channel name \"" << val << "\"\n";
Platform::term_printf("%s: bad channel name \"%s\"\n", arg0, val);
_exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
return false;
}
_enabled_channels[(*iter).second] = enable;
@ -1733,6 +1742,12 @@ bool Application::set_enable_channels(CmdLineParser& parser, bool enable, char *
return true;
}
void Application::on_cmd_line_invalid_arg(const char* arg0, const char* what, const char* val)
{
Platform::term_printf("%s: invalid %s value %s\n", arg0, what, val);
_exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
}
void Application::register_channels()
{
if (_enabled_channels[RED_CHANNEL_DISPLAY]) {
@ -1838,16 +1853,14 @@ bool Application::process_cmd_line(int argc, char** argv)
break;
case SPICE_OPT_PORT: {
if ((port = str_to_port(val)) == -1) {
std::cout << "invalid port " << val << "\n";
_exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
on_cmd_line_invalid_arg(argv[0], "port", val);
return false;
}
break;
}
case SPICE_OPT_SPORT: {
if ((sport = str_to_port(val)) == -1) {
std::cout << "invalid secure port " << val << "\n";
_exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
on_cmd_line_invalid_arg(argv[0], "secure port", val);
return false;
}
break;
@ -1855,8 +1868,7 @@ bool Application::process_cmd_line(int argc, char** argv)
case SPICE_OPT_FULL_SCREEN:
if (val) {
if (strcmp(val, "auto-conf")) {
std::cout << "invalid full screen mode " << val << "\n";
_exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
on_cmd_line_invalid_arg(argv[0], "full screen mode", val);
return false;
}
auto_display_res = true;
@ -1867,33 +1879,27 @@ bool Application::process_cmd_line(int argc, char** argv)
password = val;
break;
case SPICE_OPT_SECURE_CHANNELS:
if (!set_channels_security(parser, true, val)) {
if (!set_channels_security(parser, true, val, argv[0])) {
return false;
}
break;
case SPICE_OPT_UNSECURE_CHANNELS:
if (!set_channels_security(parser, false, val)) {
if (!set_channels_security(parser, false, val, argv[0])) {
return false;
}
break;
case SPICE_OPT_ENABLE_CHANNELS:
if (!set_enable_channels(parser, true, val)) {
std::cout << "invalid channels " << val << "\n";
_exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
if (!set_enable_channels(parser, true, val, argv[0])) {
return false;
}
break;
case SPICE_OPT_DISABLE_CHANNELS:
if (!set_enable_channels(parser, false, val)) {
std::cout << "invalid channels " << val << "\n";
_exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
if (!set_enable_channels(parser, false, val, argv[0])) {
return false;
}
break;
case SPICE_OPT_CANVAS_TYPE:
if (!set_canvas_option(parser, val)) {
std::cout << "invalid canvas option " << val << "\n";
_exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
if (!set_canvas_option(parser, val, argv[0])) {
return false;
}
break;
@ -1901,14 +1907,16 @@ bool Application::process_cmd_line(int argc, char** argv)
parser.show_help();
return false;
case CmdLineParser::OPTION_ERROR:
_exit_code = SPICEC_ERROR_CODE_CMD_LINE_ERROR;
return false;
default:
throw Exception("cmd line error");
throw Exception("cmd line error", SPICEC_ERROR_CODE_CMD_LINE_ERROR);
}
}
if (parser.is_set(SPICE_OPT_SECURE_CHANNELS) && !parser.is_set(SPICE_OPT_SPORT)) {
std::cout << "missing --secure-port\n";
Platform::term_printf("%s: missing --secure-port\n", argv[0]);
_exit_code = SPICEC_ERROR_CODE_CMD_LINE_ERROR;
return false;
}
@ -1936,7 +1944,9 @@ bool Application::process_cmd_line(int argc, char** argv)
(*iter).second = RedPeer::ConnectionOptions::CON_OP_SECURE;
continue;
}
std::cout << "missing --port or --sport\n";
Platform::term_printf("%s: missing --port or --sport\n", argv[0]);
_exit_code = SPICEC_ERROR_CODE_CMD_LINE_ERROR;
return false;
}

View File

@ -216,11 +216,12 @@ public:
static int main(int argc, char** argv, const char* version_str);
private:
bool set_channels_security(CmdLineParser& parser, bool on, char *val);
bool set_enable_channels(CmdLineParser& parser, bool enable, char *val);
bool set_canvas_option(CmdLineParser& parser, char *val);
void register_channels();
bool set_channels_security(CmdLineParser& parser, bool on, char *val, const char* arg0);
bool set_enable_channels(CmdLineParser& parser, bool enable, char *val, const char* arg0);
bool set_canvas_option(CmdLineParser& parser, char *val, const char* arg0);
void on_cmd_line_invalid_arg(const char* arg0, const char* what, const char* val);
bool process_cmd_line(int argc, char** argv);
void register_channels();
void abort();
void init_menu();
void unpress_all();

View File

@ -344,7 +344,7 @@ int CmdLineParser::get_option(char** val)
int name_pos = (opt_obj->type == REQUIRED_ARGUMENT) ? optind - 2 : optind - 1;
std::string cmd_name(_argv[name_pos] + 2);
if (cmd_name.find(opt_obj->name) != 0) {
std::cout << _argv[0] << ": invalid option '--" << cmd_name << "'\n";
Platform::term_printf("%s: invalid option '--%s'\n", _argv[0], cmd_name.c_str());
return OPTION_ERROR;
}
#endif
@ -360,11 +360,11 @@ int CmdLineParser::get_option(char** val)
case -1: {
*val = NULL;
if (!_positional_args && optind != _argc) {
std::cout << _argv[0] << ": unexpected positional arguments\n";
Platform::term_printf("%s: unexpected positional arguments\n", _argv[0]);
return OPTION_ERROR;
}
if ((opt_obj = find_missing_opt())) {
std::cout << _argv[0] << ": option --" << opt_obj->name << " is required\n";
Platform::term_printf("%s: option --%s is required\n", _argv[0], opt_obj->name.c_str());
return OPTION_ERROR;
}
_done = true;
@ -378,18 +378,19 @@ int CmdLineParser::get_option(char** val)
#ifdef DISABLE_ABBREVIATE
std::string cmd_name(_argv[optind - 1] + 2);
if (cmd_name.find(opt_obj->name) != 0) {
std::cout << _argv[0] << ": invalid option '--" << cmd_name << "'\n";
Platform::term_printf("%s: invalid option '--%s'\n", _argv[0], cmd_name.c_str());
return OPTION_ERROR;
}
#endif
std::cout << _argv[0] << ": option --" << opt_obj->name << " requires an argument\n";
Platform::term_printf("%s: option --%s requires an argument\n",
_argv[0], opt_obj->name.c_str());
} else if (optopt == 0) {
std::cout << _argv[0] << ": invalid option '" << _argv[optind - 1] << "'\n";
Platform::term_printf("%s: invalid option '%s'\n", _argv[0], _argv[optind - 1]);
} else if ((opt_obj = find((char)optopt))) {
std::cout << _argv[0] << ": option '-" << opt_obj->short_name <<
"' requires an argument\n";
Platform::term_printf("%s: option '-%c' requires an argument\n",
_argv[0], opt_obj->short_name);
} else {
std::cout << _argv[0] << ": invalid option '-" << char(optopt) << "'\n";
Platform::term_printf("%s: invalid option '-%c'\n", _argv[0], char(optopt));
}
return OPTION_ERROR;
default:
@ -447,13 +448,13 @@ void CmdLineParser::show_help()
{
static const int HELP_START_POS = 30;
static const int HELP_WIDTH = 80 - HELP_START_POS;
std::ostringstream os;
std::cout << basename(_argv[0]) << " - " << _description.c_str() << "\n\noptions:\n\n";
os << basename(_argv[0]) << " - " << _description.c_str() << "\n\noptions:\n\n";
Options::iterator iter = _options.begin();
for (; iter != _options.end(); ++iter) {
CmdLineParser::Option* opt = *iter;
std::ostringstream os;
if (opt->short_name) {
os << " -" << opt->short_name << ", ";
@ -516,9 +517,9 @@ void CmdLineParser::show_help()
line.clear();
}
} while (line.size() || std::getline(is, line));
std::cout << os.str();
}
std::cout << "\n";
os << "\n";
Platform::term_printf(os.str().c_str());
}

View File

@ -42,6 +42,7 @@ public:
static void path_append(std::string& path, const std::string& partial_path);
static uint64_t get_process_id();
static uint64_t get_thread_id();
static void term_printf(const char* format, ...);
static void error_beep();
static const MonitorsList& init_monitors();

View File

@ -22,12 +22,6 @@ extern "C" {
#include "pthread.h"
}
//#define OPEN_CONSOLE
#ifdef OPEN_CONSOLE
#include <io.h>
#include <conio.h>
#endif
#include "application.h"
#include "debug.h"
#include "utils.h"
@ -83,23 +77,6 @@ int WINAPI WinMain(HINSTANCE hInstance,
try {
init_version_string();
#ifdef OPEN_CONSOLE
AllocConsole();
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
int hConHandle = _open_osfhandle((intptr_t)h, _O_TEXT);
FILE * fp = _fdopen(hConHandle, "w");
*stdout = *fp;
h = GetStdHandle(STD_INPUT_HANDLE);
hConHandle = _open_osfhandle((intptr_t)h, _O_TEXT);
fp = _fdopen(hConHandle, "r");
*stdin = *fp;
h = GetStdHandle(STD_ERROR_HANDLE);
hConHandle = _open_osfhandle((intptr_t)h, _O_TEXT);
fp = _fdopen(hConHandle, "w");
*stderr = *fp;
#endif
pthread_win32_process_attach_np();
init_winsock();
exit_val = Application::main(__argc, __argv, version_string);
@ -114,11 +91,10 @@ int WINAPI WinMain(HINSTANCE hInstance,
LOG_ERROR("unhandled exception");
exit_val = SPICEC_ERROR_CODE_ERROR;
}
log4cpp::Category::shutdown();
#ifdef OPEN_CONSOLE
_getch();
#endif
pthread_win32_process_detach_np();
return exit_val;
}

View File

@ -18,6 +18,8 @@
#include "common.h"
#include <shlobj.h>
#include <io.h>
#include <conio.h>
#include "platform.h"
#include "win_platform.h"
@ -745,3 +747,65 @@ void WinPlatform::exit_modal_loop()
KillTimer(paltform_win, MODAL_LOOP_TIMER_ID);
modal_loop_active = false;
}
static bool has_console = false;
static void create_console()
{
static Mutex console_mutex;
Lock lock(console_mutex);
if (has_console) {
return;
}
AllocConsole();
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
int hConHandle = _open_osfhandle((intptr_t)h, _O_TEXT);
FILE * fp = _fdopen(hConHandle, "w");
*stdout = *fp;
h = GetStdHandle(STD_INPUT_HANDLE);
hConHandle = _open_osfhandle((intptr_t)h, _O_TEXT);
fp = _fdopen(hConHandle, "r");
*stdin = *fp;
h = GetStdHandle(STD_ERROR_HANDLE);
hConHandle = _open_osfhandle((intptr_t)h, _O_TEXT);
fp = _fdopen(hConHandle, "w");
*stderr = *fp;
has_console = true;
HWND consol_window = GetConsoleWindow();
if (consol_window) {
SetForegroundWindow(consol_window);
}
}
class ConsoleWait {
public:
~ConsoleWait()
{
if (has_console) {
Platform::term_printf("\n\nPress any key to exit...");
_getch();
}
}
} console_wait;
void Platform::term_printf(const char* format, ...)
{
if (!has_console) {
create_console();
}
va_list ap;
va_start(ap, format);
vprintf(format, ap);
va_end(ap);
}

View File

@ -268,6 +268,14 @@ void Platform::yield()
pthread_yield();
}
void Platform::term_printf(const char* format, ...)
{
va_list ap;
va_start(ap, format);
vprintf(format, ap);
va_end(ap);
}
void Platform::set_thread_priority(void* thread, Platform::ThreadPriority in_priority)
{
ASSERT(thread == NULL);

View File

@ -45,6 +45,7 @@
#define SPICEC_ERROR_CODE_VERSION_MISMATCH (-11)
#define SPICEC_ERROR_CODE_PERMISSION_DENIED (-12)
#define SPICEC_ERROR_CODE_INVALID_ARG (-13)
#define SPICEC_ERROR_CODE_CMD_LINE_ERROR (-14)
#endif